diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index f3d4a5f770..acd96b5047 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -17,58 +17,57 @@ 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 + uses: actions/checkout@v6 - 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' - uses: actions/upload-artifact@v4 + if: matrix.cfg.os == 'ubuntu-24.04' + uses: actions/upload-artifact@v7 with: name: draft-snapshot path: source/std.pdf diff --git a/.gitignore b/.gitignore index bcaa1569dd..9286aae13e 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ std-gram.ext tools/sections *.synctex.gz *.synctex* +.check.stamp diff --git a/README.rst b/README.rst index 4ab1c20b2d..c737a81a71 100644 --- a/README.rst +++ b/README.rst @@ -22,7 +22,7 @@ Getting Started on Mac OS X Install the `MacTeX distribution `_. If you are on a slow network, you'll want to get the `BasicTeX package `_ instead, -then run the following command to install the other packages that the draft requires: +then run the following command to install the other packages that the draft requires:: sudo tlmgr install latexmk isodate substr relsize ulem fixme rsfs extract layouts enumitem l3packages l3kernel imakeidx splitindex xstring @@ -30,7 +30,7 @@ then run the following command to install the other packages that the draft requ Getting Started on Debian-based Systems --------------------------------------- -Install the following packages: +Install the following packages:: sudo apt-get install latexmk texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended lmodern @@ -38,7 +38,7 @@ Install the following packages: Getting Started on Fedora ------------------------- -Install the following packages: +Install the following packages:: dnf install latexmk texlive texlive-isodate texlive-relsize texlive-ulem texlive-fixme texlive-extract texlive-l3kernel texlive-l3packages texlive-splitindex texlive-imakeidx @@ -46,7 +46,7 @@ Install the following packages: Getting Started on Arch Linux ----------------------------- -Install the following packages: +Install the following packages:: pacman -S make texlive-latexextra texlive-binextra texlive-plaingeneric texlive-fontsrecommended @@ -59,6 +59,10 @@ See `sample instructions `_ +Alternatively, you can `install WSL `_ +and a Linux distribution, +and follow the instructions for Linux above. + ------------ Instructions ------------ @@ -80,6 +84,22 @@ For example:: make figvirt.pdf +Verifying input and output when making changes +============================================== + +While in the ``source`` directory, +you can check for common mistakes such as misaligned comments with:: + + ../tools/check-source.sh + +After typesetting the document, +you can also check the output for further problems with:: + + ../tools/check-output.sh + +GitHub Actions will also run these checks when you create a pull request, +but it's often faster if you run them locally first. + ---------------- Acknowledgements ---------------- 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/n5015.html b/papers/n5015.html new file mode 100644 index 0000000000..045c98dcae --- /dev/null +++ b/papers/n5015.html @@ -0,0 +1,1926 @@ + + + + + +N5015 + + +

N5015 Editors’ Report:
Programming Languages — C++

+ +

Date: 2025-08-14

+ +

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. +Special thanks to Alisdair Meredith and Jan Schultke +for drafting a lot of motion applications, +to Andreas Krug for ongoing careful reviews, +and to the review committee for finding and fixing many transcription errors +in this rather large amount of added text.

+ +

New papers

+ +
    +
  • N5013 is the C++26 Committee Draft.
  • +
  • N5014 is the +current working draft for C++26. It replaces +N5008.
  • +
  • N5015 is this Editors' Report.
  • +
+ + +

Motions incorporated into working draft

+ +

Notes on motions

+ +

All motions were applied cleanly.

+ +

In CWG Motion 11, +P2843R3 +(“Preprocessing is never undefined”), the text has been reconciled with +earlier changes coming from CWG Motion 1, Issue +CWG3015.

+ +

In LWG Motion 35, +P1317R2 +(“Remove return type deduction in std::apply”), the feature test macro +__cpp_lib_apply was bumped and marked as also being in <type_traits>.

+ +

Several minor phrasing and punctuation improvements have been applied +in subsequent reviews, and some minor errors and oversights in the approved +texts have been fixed in consultation with authors and wording group chairs.

+ +

Core working group polls

+ +

CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues except issues 3013, 3014 and 3020 in +P3752R0 +(Core Language Working Group “ready” Issues for the June, 2025 meeting) to the C++ Working Paper.

+ +

CWG Poll 2. Apply the proposed resolutions of issues 3013, 3014 and 3020 in +P3752R0 +(Core Language Working Group “ready” Issues for the June, 2025 meeting) to the C++ Working Paper.

+ +

CWG Poll 3. Accept as a Defect Report and apply the changes in +P3618R0 +(Allow attaching main to the global module) to the C++ Working Paper.

+ +

CWG Poll 4. Apply the changes in P2996R13 +(Reflection for C++26) to the C++ Working Paper and accept as Defect Reports core issues 2701 and 3026 resolved thereby.

+ +

CWG Poll 5. Apply the changes in P3394R4 +(Annotations for Reflection) to the C++ Working Paper.

+ +

CWG Poll 6. Apply the changes in P3293R3 +(Splicing a base class subobject) to the C++ Working Paper.

+ +

CWG Poll 7. Apply the changes in P3491R3 +(define_static_{string,object,array}) to the C++ Working Paper.

+ +

CWG Poll 8. Apply the changes in P1306R5 +(Expansion Statements) to the C++ Working Paper.

+ +

CWG Poll 9. Apply the changes in P3096R12 +(Function Parameter Reflection in Reflection for C++26) to the C++ Working Paper.

+ +

CWG Poll 10. Apply the changes in +P3533R2 +(constexpr virtual inheritance) to the C++ Working Paper.

+ +

CWG Poll 11. Apply the changes in P2843R3 +(Preprocessing is never undefined) to the C++ Working Paper.

+ +

Library working group polls

+ +

LWG Poll 1. Apply the changes in P3742R0 +(C++ Standard Library Issues to be moved in Sofia, Jun. 2025) to the C++ working paper.

+ +

LWG Poll 2. Apply the changes in P2988R12 +(std::optional<‍T&‍>) to the C++ working paper.

+ +

LWG Poll 3. Apply the changes in P3348R4 +(C++26 should refer to C23 not C17) to the C++ working paper.

+ +

LWG Poll 4. Apply the changes in P3037R6 +(constexpr std::shared_ptr and friends) to the C++ working paper.

+ +

LWG Poll 5. Apply the changes in P3284R4 +(write_env and unstoppable Sender Adaptors) to the C++ working paper.

+ +

LWG Poll 6. Apply the changes in P3179R9 +(Parallel Range Algorithms) to the C++ working paper.

+ +

LWG Poll 7. Apply the changes in P3709R2 +(Reconsider parallel ranges::rotate_copy and ranges::reverse_copy) to the C++ working paper.

+ +

LWG Poll 8. Apply the changes in P3641R0 +(Rename std::observable to std::observable_checkpoint, and add a feature-test macro) to the C++ working paper.

+ +

LWG Poll 9. Apply the changes in P3044R2 +(sub-string_view from string) to the C++ working paper.

+ +

LWG Poll 10. Apply the changes in P2876R3 +(Proposal to extend std::simd with more constructors and accessors) to the C++ working paper.

+ +

LWG Poll 11. Apply the changes in P3480R6 +(std::simd is a range) to the C++ working paper.

+ +

LWG Poll 12. Apply the changes in P2664R11 +(Extend std::simd with permutation API) to the C++ working paper.

+ +

LWG Poll 13. Apply the changes in P3691R1 +(Reconsider naming of the namespace for “std::simd”) to the C++ working paper.

+ +

LWG Poll 14. Apply the changes in P3383R3 +(mdspan.at()) to the C++ working paper.

+ +

LWG Poll 15. Apply the changes in P2927R3 +(Inspecting exception_ptr) to the C++ working paper.

+ +

LWG Poll 16. Apply the changes in P3748R0 +(Inspecting exception_ptr should be constexpr) to the C++ working paper.

+ +

LWG Poll 17. Apply the changes in P2830R10 +(Standardized Constexpr Type Ordering) to the C++ working paper.

+ +

LWG Poll 18. Apply the changes in P3570R2 +(optional variants in sender/receiver) to the C++ working paper.

+ +

LWG Poll 19. Apply the changes in P3481R5 +(std::execution::bulk() issues) to the C++ working paper.

+ +

LWG Poll 20. Apply the changes in P3433R1 +(Allocator Support for Operation States) to the C++ working paper.

+ +

LWG Poll 21. Apply the changes in P3149R11 +(async_scope - Creating scopes for non-sequential concurrency) to the C++ working paper.

+ +

LWG Poll 22. Apply the changes in P3682R0 +(Remove std::execution::split) to the C++ working paper.

+ +

LWG Poll 23. Apply the changes in P2079R10 +(Parallel scheduler) to the C++ working paper.

+ +

LWG Poll 24. Apply the changes in P3557R3 +(High-Quality Sender Diagnostics with Constexpr Exceptions) to the C++ working paper.

+ +

LWG Poll 25. Apply the changes in P3560R2 +(Error Handling in Reflection) to the C++ working paper.

+ +

LWG Poll 26. Apply the changes in P3503R3 +(Make type-erased allocator use in promise and packaged_task consistent) to the C++ working paper.

+ +

LWG Poll 27. Apply the changes in P3008R6 +(Atomic floating-point min/max) to the C++ working paper.

+ +

LWG Poll 28. Apply the changes in P3111R8 +(Atomic Reduction Operations) to the C++ working paper.

+ +

LWG Poll 29. Apply the changes in P3060R3 +(Add std::views::indices(n)) to the C++ working paper.

+ +

LWG Poll 30. Apply the changes in P2319R5 +(Prevent path presentation problems) to the C++ working paper.

+ +

LWG Poll 31. Apply the changes in P3223R2 +(Making std::istream::ignore less surprising) to the C++ working paper.

+ +

LWG Poll 32. Apply the changes in P2781R9 +(std::constant_wrapper) to the C++ working paper.

+ +

LWG Poll 33. Apply the changes in P3697R1 +(Minor additions to C++26 standard library hardening) to the C++ working paper.

+ +

LWG Poll 34. Apply the changes in P3552R3 +(Add a Coroutine Task Type) to the C++ working paper.

+ +

LWG Poll 35. Apply the changes in P1317R2 +(Remove return type deduction in std::apply) 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 N5008 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 2a74dc7bc587c2c64d8886faebc91d68c83626c1
+Author: Vlad Serebrennikov <serebrennikov.vladislav@gmail.com>
+Date:   Mon Mar 17 15:33:35 2025 +0400
+
+    [expr.sub] Add missing cross-references (#7688)
+
+commit cdf6502ac7bf942f6ad32a27254db890c7ae8d3a
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Mar 18 09:35:16 2025 -0400
+
+    [sequences.general] std::hive is a sequence container (#7746)
+
+commit 2a71697913a853b62b8aeda5b68afbdfca756bf2
+Author: salonsro <lucyengine@gmail.com>
+Date:   Tue Mar 18 13:37:49 2025 +0000
+
+    [defns.access] Add cross-reference (#7743)
+
+commit b3f45725c6cb088e26b02a36c51c6e19ce61351e
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Mar 19 13:18:56 2025 +0100
+
+    [basic.contract.eval] Fix typo (#7749)
+
+commit 0bd8d94cc6b693cc3dd25bd32157928b6e02ac8e
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Mar 19 18:43:01 2025 +0100
+
+    [lex.digraph] Swap alternative token representations in table (#7750)
+
+commit 958532b7042b0c12af783a0a2f9e5c8fafc8702c
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Mar 21 09:22:26 2025 +0100
+
+    [hive.operations] Move closing curly bracket in front of comma (#7757)
+
+commit 719601dcb890bf2dbc2330af5846c30a2ef84830
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Oct 27 10:43:51 2024 +0100
+
+    [dcl.init], [depr.atomics.types.operations] Say "with static storage duration"
+
+commit 8b753114c3fe1602e04ca9d1015c14c4a54544af
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Oct 27 10:47:27 2024 +0100
+
+    [thread.condition.nonmember], [futures.promise], [futures.task.members] Say "with thread storage duration"
+
+commit 78bec38978bce1c680ea0a2dd2f8791967148bb8
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Oct 27 10:49:12 2024 +0100
+
+    [expr.prim.id.unqual], [support.start.term] Say "with automatic storage duration"
+
+commit 1dd46d8b87a1a7918d07966d7ef04c0118bee73e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Mar 21 13:02:50 2025 +0000
+
+    [tools] Catch exception of polymorphic type by reference
+
+commit 9caa0dc05cb525c433f7889e190946a325f752ed
+Author: Matthias Kretz <M.Kretz@gsi.de>
+Date:   Sat Mar 22 19:48:08 2025 +0100
+
+    [exec.schedule.from, simd.ctor] Remove incorrect @ escapes (#7759)
+
+commit 2d59c792e2a0228e77a0316d39bde9e51f31d146
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 22 22:37:08 2025 +0100
+
+    [cpp.embed.gen] Fix typo in example
+
+commit 9b8a5e51752efe9edd7a447e96ffab0f3313accc
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Mar 23 10:06:28 2025 +0100
+
+    [range.zip.transform.iterator] Fix typo in index entry. (#7762)
+
+commit 6a4c11e137509beed40ce93dd9d92b7b24e0cbda
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon Mar 24 08:45:47 2025 +0100
+
+    [stopsource.general] Restore accidentally deleted members in class definition (#7766)
+
+    These were removed in error in the application of P2300R10.
+
+commit d51cc9b757a0bbb343244c3aecd546783d08ba83
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Mon Mar 24 16:00:39 2025 +0800
+
+    [range.to.input.view] Add \ref for to_input_view​::​iterator (#7767)
+
+commit 879d51544872d6b8b6f0a845328db26ef5f2ddcb
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Mon Mar 24 16:01:34 2025 +0800
+
+    [range.drop.view] Fix typo (#7768)
+
+commit c4a89e3ca4e34c82f6525a342f08dab1dce63d8c
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Mon Mar 24 22:07:58 2025 +0100
+
+    [alg.rand.generate] Add generate_random to index (#7774)
+
+commit dd233b52569edc8598d575d57ee4634729228acf
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Wed Mar 26 15:26:06 2025 +0800
+
+    [simd.ctor] Fix typos (#7779)
+
+commit ae030b95169a0c828917b72085ac99427c12f0d4
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Wed Mar 26 20:16:02 2025 +0800
+
+    [range.to.input.view] Add namespace wrapping (#7782)
+
+commit 4dd513d0096900ac82090875e2568a971909b2b3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 26 20:48:23 2025 +0100
+
+    [lex.phases] Add cross-reference to [lex.header] (#7763)
+
+commit 3b4c353d381e07b4648671c592b82a1e487425d9
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Mar 27 19:51:39 2025 +0000
+
+    [temp.constr.general] Reorder constraint kinds to match subclause order (#7788)
+
+commit 5ecd4e9e00f64dfc73a75ce667bbaeba2b3b9b61
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Mar 27 20:40:32 2025 +0000
+
+    [temp.variadic] Consistently order template parameter kinds (#7796)
+
+commit 9798c7afb488414dd7e51fbc70dc9182ebafa668
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Mar 27 20:42:50 2025 +0000
+
+    [temp.deduct.type] Consistently order template argument kinds (#7798)
+
+commit 38a0bd47f42bf8c880df1a17e90110ac6a070944
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Mar 28 22:25:40 2025 +0000
+
+    [alg.copy, alg.move] Rename ExecutionPolicy parameters for consistency (#7803)
+
+    This makes them consistent with all other parallel algorithms.
+
+commit ddb98da95204fbd033e4e809e05634513187afb9
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Mar 30 17:53:53 2025 +0200
+
+    [expr.const] Add reference to [dcl.constexpr] for "constexpr destructor" (#7629)
+
+commit d40449a0e50e126a35c555683dc7805f72efa7ef
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Mar 30 16:24:39 2025 +0200
+
+    [range.approximately.sized] Move to before [range.sized]
+
+    This is an unfortunate application of P2846R6.
+
+commit ab81b357785fc5a48df60cbe9a372af4f281a25b
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Sun Mar 23 18:20:35 2025 -0500
+
+    [cpp.predefined] Place the __STDC_EMBED macros in the unconditionally defined paragraph
+
+    The incoming paper did not explicitly specify their placement,
+    but they are clearly meant to be defined unconditionally.
+
+commit 06ffe74abf088e275e4233d2891cc3ebc4664cea
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Mar 31 11:28:14 2025 +0000
+
+    [temp.constr.normal] Rephrase comment in example (#7793)
+
+commit 5b6307e337d50045c3b4109429f4912fe352bce4
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Mar 27 11:26:43 2025 +0000
+
+    [temp.over.link] Remove redundant wording
+
+commit 12b6153dccd2fc2f9ec6a8469d907b47bca57963
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Mar 27 11:26:40 2025 +0000
+
+    [temp.constr.normal] Use "contains (a pack)" instead of "names"
+
+commit 24c7d63df6144f0d718acb882c2c36ec97cd6212
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Mar 31 14:09:51 2025 +0200
+
+    [set.overview] Fix punctuation (#7808)
+
+commit bf5c701a23bcc7f79a459f474455cf0dc9c58de5
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Tue Apr 1 02:28:47 2025 +0800
+
+    [list.erasure, list.erasure] Move long code into codeblock (#7809)
+
+commit 743914c23ff20286507c1c8b201dc040a6f8f178
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Tue Apr 1 15:08:12 2025 +0000
+
+    [temp.dep.constexpr] Fix broken formatting (#7811)
+
+commit 9fd6664ea97cd889cdf529f2d020e6fa6ea13d58
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Apr 4 17:48:11 2025 +0100
+
+    [optional.monadic] Remove stray angle brackets on concept name (#7817)
+
+commit a989431c5a893f9106dc21e9b2dd0a670356d890
+Author: Geng Cheng <xmcgcg@qq.com>
+Date:   Thu Apr 10 17:32:28 2025 +0800
+
+    [polymorphic.general] Fix garbled expression (#7820)
+
+    The applied paper P3019R14 had truncated text.
+
+commit f79a0f6981def4868fc365fb906a8a0551359c7d
+Author: Geng Cheng <xmcgcg@qq.com>
+Date:   Thu Apr 10 18:40:44 2025 +0800
+
+    [polymorphic.asgn] Remove superfluous greater-than sign (#7821)
+
+commit 7f1000d2eca113824d6ac734c5348f332a2d3e1c
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Apr 11 14:10:48 2025 +0200
+
+    [func.bind.partial] Add backslash for throws
+
+commit 8792e5544498d262a821b2175c1fe52fd3a15156
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Sun Apr 13 13:33:06 2025 -0400
+
+    [meta.unary.prop] Comma should be a period (#7832)
+
+commit 317ae891f25d4875651495780b5238869cce825b
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Mon Apr 14 23:20:57 2025 +0800
+
+    [mdspan.layout.left.obs] Add missing noexcept (#7831)
+
+commit 5ec615184220e01fd8f6a817cf6050f3ce039f91
+Author: Geng Cheng <xmcgcg@qq.com>
+Date:   Mon Apr 14 23:25:37 2025 +0800
+
+    [vector.modifiers] Old concepts cannot be “modeled” (#7836)
+
+commit 08b6e70e2c469a4a2d85d5ab49b14f75d57c0d36
+Author: OndrejPopp <50676516+OndrejPopp@users.noreply.github.com>
+Date:   Mon Apr 14 17:27:34 2025 +0200
+
+    [dcl.contract.func] Add missing \br in grammar (#7838)
+
+commit 52c7080115598baddd61b050c707d2a05a5fa2f7
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Apr 22 23:37:19 2025 +0800
+
+    [iterator.synopsis] Apply changes of P2538R1 to the synopsis of `<iterator>` (#7841)
+
+    Remove `incrementable_traits<projected>` and update `projected`.
+
+commit 05300d78dc4fb6ee346d93b381d6a15ed51406f7
+Author: Tsche <2440422+Tsche@users.noreply.github.com>
+Date:   Wed Apr 23 07:21:16 2025 +0200
+
+    [tuple.syn] Fix return type of ignore-type::operator= (#7840)
+
+    This fixes a misapplication of P2968R2, in commit 225eadc4f3676472836397c9c0449f3203ae0a6d.
+
+commit a136094254936f2ae4e8bf1d5c59fff1afca03c7
+Author: A. Jiang <de34@live.cn>
+Date:   Thu May 8 02:58:03 2025 +0800
+
+    [container.adaptors] Avoid naming sorted_{equivalent,unique}_t tag parameters (#7867)
+
+commit b99e22bb3f4e27eae65028aa011d3db08a0793cf
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu May 8 20:53:45 2025 +0200
+
+    [basic.contract.eval] Remove stray closing parenthesis (#7868)
+
+commit 4b1283ba5fabb5392b0faabe9682abc43d449614
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 12 22:32:34 2025 +0200
+
+    [sequence.reqmts] Fix application of P2846R6 for `assign_range`
+
+commit 74a6eed8a7b12041dbdb0dd9c39c433363211894
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue May 13 19:45:22 2025 +0200
+
+    [expr.call] Move period to end end of sentence (#7871)
+
+commit e8a5d8b83a91a0606883042fa3beb3e7b4423d9c
+Author: Geng Cheng <xmcgcg@qq.com>
+Date:   Thu May 15 02:25:17 2025 +0800
+
+    [associative.reqmts.general] Replace undefined "multiple keys" with "equivalent keys" (#7874)
+
+commit 69f81d2bc71ae28694ded6f03a5a2670e916c7d8
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu May 15 08:09:59 2025 +0200
+
+    [dcl.contract.res] Add period to end of sentence
+
+commit 78ea6062c043cc640fe5e72985eb36c279b1e976
+Author: Luc Grosheintz <luc.grosheintz@gmail.com>
+Date:   Thu May 15 23:46:56 2025 +0200
+
+    [mdspan.layout.right.obs] Add missing constexpr to required_span_size (#7872)
+
+commit 6c20db7e4a3300a0274e4ba9eb8c35371d6bc276
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri May 16 15:29:51 2025 +0200
+
+    [class.prop] Remove stray closing parenthesis (#7879)
+
+commit c4a2d197bb3c52d3e84a645bb756b3606e8408fc
+Author: A. Jiang <de34@live.cn>
+Date:   Sat May 17 03:07:18 2025 +0800
+
+    [algorithm.syn] Fix synopsis entries for `ranges::find_last` (#7805)
+
+    P3217R0 updated ranges::find_last, but the synopsis was accidentally left unchanged.
+
+commit d8ab7083603ad16eb74fade44c757760b1f9e9dc
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat May 17 08:57:50 2025 +0200
+
+    [class.mem.general] Remove stray closing parenthesis (#7880)
+
+commit eb112f887bc541c5a21b302ac7d2476c7b5fa5e3
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Mon May 19 09:28:23 2025 +0200
+
+    [hive.operations] Add missing paragraph number (#7882)
+
+commit 0fd10bfb6ca13a61dd1bb77cad3b070d500e1cbc
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue May 20 13:42:28 2025 +0200
+
+    [dcl.fct.def.replace] Remove stray closing parenthesis (#7883)
+
+commit 1abf0915e3aa24ad48a1c2e74d60975a30fa93da
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri May 23 09:13:02 2025 +0200
+
+    [simd.bit] Add period to end of sentence (#7887)
+
+commit cc5b90512ac3deecfcc4e47f5da1910e54d661f9
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Wed May 28 00:18:32 2025 +0800
+
+    [locale.money.put.members] Fix typo (#7896)
+
+commit 782c81f8dfd714f34dced2de882b57d102dbde4c
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Tue May 27 18:35:39 2025 +0200
+
+    [simd.creation] Add commas and improve semantic linebreaks (#7895)
+
+commit a770261ed7dc83ea269e07f4e5936ca65337ddff
+Author: A. Jiang <de34@live.cn>
+Date:   Wed May 28 17:59:55 2025 +0800
+
+    [text.encoding.id] Sort enumerators in ascending order (#7899)
+
+commit cb25f9b182c89e442687fed176150693debc6970
+Author: A. Jiang <de34@live.cn>
+Date:   Sat May 31 04:16:52 2025 +0800
+
+    [projected] `projected` is an alias template after P2538R1 (#7901)
+
+commit b210471e21197f2e0f1655969c2adb9f04f30e02
+Author: Eric Niebler <eniebler@boost.org>
+Date:   Sun Jun 1 09:20:30 2025 -0700
+
+    [execution.syn] Rename template parameter of `schedule_result_t` (#7906)
+
+commit d18bd92fda9c02e3518910824f041ab49fbc1a4b
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Jun 2 05:47:51 2025 +0800
+
+    [tab:headers.cpp.fs] Fix header name for `is_execution_policy(_v)` (#7849)
+
+commit 25e95f5296e2b3c0f378ac5d3ddfdca1e867e9b0
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jun 2 17:52:21 2025 +0200
+
+    [simd.unary] Add \ref for simd.unary (#7908)
+
+commit a3b9cb5bdbec5e2fbf964561ea10dc19a4b042d5
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Mon Jun 2 22:36:05 2025 +0200
+
+    [container.requirements] Simplify Returns specification for try_emplace (#7892)
+
+commit 660ab848b97640764a270220f038f911b1057dfe
+Author: Daniel Krügler <daniel.kruegler@gmail.com>
+Date:   Fri Jun 13 23:44:10 2025 +0200
+
+    [expected.object.cons] Reorder arguments of is_same_v for consistency (#7915)
+
+commit ee9b5bf124495f1473e246f223756a164d42aed9
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Sat Jun 14 02:32:38 2025 -0400
+
+    [meta.trans.other] Fix off-by-one references to [meta.rqmts] (#7914)
+
+commit 57e185f4bde5309d98e22f514d4434a1feea1911
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Mar 24 00:24:04 2025 +0800
+
+    [assertions.assert] Add ISO C reference for standard error stream
+
+commit 4f3e967cdc0befd71b1101e996c22db602ff0fd3
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat May 3 10:25:33 2025 +0200
+
+    [class.temporary] Define "temporary object"
+
+commit 4aa14fe19a9060360436e9ab56d361101212e961
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu May 1 15:56:42 2025 +0100
+
+    [polymorphic.ctor] Owned object must have cv-unqualified object type
+
+commit 6f18c6b9e3634cf2ac40ab0f4d7c9e2e68acee2c
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jun 16 08:42:48 2025 -0700
+
+    [value.error.codes] Remove redundant std qualifications (#7918)
+
+commit 59b1a8ada534fb1491ef3a134e05262baa0b516c
+Author: Eric Niebler <eniebler@boost.org>
+Date:   Tue Jun 17 05:56:42 2025 -0700
+
+    [exec.snd] Fix spelling of exposition-only `query-with-default` function (#7905)
+
+commit 04f4a62af51c7b3e8dad223051dc95a7942194c3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jun 2 22:54:34 2025 +0200
+
+    [basic.def.odr] Rephrase sentence to avoid double-negative
+
+commit ca3694ecf8fd82d896d5bcf011bae7640d5335de
+Author: Eric Niebler <eniebler@boost.org>
+Date:   Tue Jun 17 06:04:08 2025 -0700
+
+    [exec.let] Fix function type name (#7907)
+
+    The specification of `let_value(sndr,fn)` and friends refers to the type of `fn` as "`Fn`". But when introducing the types, we give it the name "`F`". This fixes the inconsistency.
+
+commit dfcc6dd19c0efd93bff47d501fdf6e2d52160a5c
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Mar 27 11:34:57 2025 +0000
+
+    [expr.type] Remove redundant \cvqual
+
+commit 9d20a320e1662deff9abb65b4f7e6e52e66ed732
+Author: Geng Cheng <xmcgcg@qq.com>
+Date:   Tue Jun 17 21:51:41 2025 +0800
+
+    [indirect.asgn] Change "contained value" to "owned object" (#7822)
+
+commit 06e649b10e2d1af29eee739ea0998cb45e65fadc
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Apr 8 17:19:29 2025 +0800
+
+    [string.view] Exposition-only formatting for `data_` and `size_`
+
+commit 9dfb02a3222eed8a02d74c7d80714eeaf3aba10b
+Author: Geng Cheng <xmcgcg@qq.com>
+Date:   Tue Jun 17 21:59:52 2025 +0800
+
+    [time.format] Add commas and clarifying "unless otherwise" (#7697)
+
+    See LWG 4124, which added wording before the text in question that motivates adding "unless otherwise specified".
+
+commit 1f79f7a919432e8eccc90c9ffd21baeb9ea0563c
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Apr 24 15:08:28 2025 +0800
+
+    [exec.util.cmplsig.trans] Drop verbose `add_lvalue_reference_t`
+
+commit 32ec75ea890301b100eac4a63e986a55cd08ea13
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jun 17 17:07:41 2025 +0300
+
+    [indirect, polymorphic] Rename stable lables "asgn" to "assign"
+
+commit da436f8325d978b76eaa18be46e987decc9117c5
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Jun 18 00:47:57 2025 +0800
+
+    [defns.dynamic.type] Say "most derived object" in the example (#6203)
+
+commit 66e15a609b8bec7b4b976b17a5aaf3d65893d31c
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Tue Jun 17 21:48:26 2025 +0500
+
+    [intro.multithread.general] Say "use", not "access" functions (#6503)
+
+commit 7a90fddca19918e03bc10a7a6ef22a970ca381a3
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Jun 18 22:13:59 2025 +0800
+
+    [tab:meta.trans.cv] Simplify wording for add_{const,volatile}
+
+    Wording about reference, function, or top-level cv-qualified types
+    moves to notes, as it is redundant since at least C++11.
+
+commit c156822435acd59433b7fb7f28e83a5765af7e64
+Author: A. Jiang <de34@live.cn>
+Date:   Sun Sep 29 09:11:10 2024 +0800
+
+    [complex.numbers.general] Clarify that the template is primary
+
+    The difference between between "the `complex` template" and "the template named `complex`" (which including program-defined specializations) is obscure. It seems better to cleary say that [complex.numbers.general] only covers the primary template.
+
+commit f457f12ffe04df1af8e6a28e174a5ca2dc59ddaa
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Jun 19 17:32:03 2025 +0800
+
+    [execpol.type] Remove "see below" definition from "is_execution_policy" itemdecl (#7909)
+
+    We already say that it is a Cpp17UnaryTypeTrait with a base characteristic of either true_type or false_type.
+
+commit 446ec2e959f38281786c3f61e83f077459763f92
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Fri Jun 20 02:19:07 2025 -0400
+
+    [inplace.vector] Move reserve, shrink_to_fit from "modifiers" to "capacity" (#7321)
+
+commit c355072152d7c9e364e2a8acf265fdf068942002
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Jun 20 07:50:59 2025 +0200
+
+    [valarray.cassign] Add period at end of "Returns"
+
+commit 3bce8f7f15164dc455240e53acce596eeba97d45
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jun 20 08:01:43 2025 +0100
+
+    [diff.cpp23.strings] Move Clause 27 changes after Clause 23 changes
+
+    The 'Strings' clause was moved before the new 'Text processing' clause,
+    so it's now after the 'Containers' clause. The order of the [diff.cpp23]
+    subclauses should reflect that.
+
+commit ac78ae76c579883a32a9eb5b00346150a41e8e47
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Fri Jun 20 21:02:18 2025 +0100
+
+    [atomics.ref.float] Fix spelling of placeholder
+
+commit a8f807b14c33ca76c790df97ca7d0ddf9746abef
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sun Jun 22 09:12:52 2025 +0200
+
+    [out.ptr] Add period at end of "Returns"
+
+commit 346c6d0dfd608764d697f1a33ef739a4762e0d40
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sat Mar 11 20:53:05 2023 +0000
+
+    [conv.qual] Remove unused definition of 'cv-qualification signature'
+
+commit 0b41c12760d8079ee4c460df6ddecaf220f2dfb6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Jun 22 19:59:47 2025 +0300
+
+    [intro] Special page header before Clause 1 (#6070)
+
+commit 4726d67bf8f22f15dd7f3dcae7b54832dcbbbb91
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Jun 22 17:27:15 2025 +0000
+
+    [dcl.type.auto.deduct] Change "occurrences" to "occurrence" (#7644)
+
+    This appears to be a misapplication of N1984, which contains the wording "Obtain `P` from `T`
+    by replacing the occurrence of `auto` with a new invented type template parameter `U`."
+
+commit a8d96185e4bba7f738e4c2e1f3593a6e55fbbbd8
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jun 23 08:07:06 2025 +0200
+
+    [basic.ios.members] Add period at end of "Returns"
+
+commit 2e12f5e71e56af0ffae0b5a7cd9086d24b72df20
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jun 23 12:48:46 2025 +0100
+
+    [stmt] Move start of subclause-spanning index entries up to \rSec1
+
+    I expect that we forgot to move this when we added the "general"
+    subclauses to remove hanging paragraphs, and thus accidentally caused
+    the index entries to be "misnested".
+
+commit 4f925714c37ed1fe6a5692adcc3ef5fa37964056
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 26 13:25:36 2025 +0200
+
+    [atomics.ref.float] Apply missing changes from P3323R1
+
+    Paper P3323R1 cv-qualified types in atomic and atomic_ref
+    was incompletely applied in commit cd4dbcf2aa6df895a25dbf8c0773dd0fa67ef45d.
+
+commit f9100076b21e277644a793624db7dc96bff29594
+Author: Matthias Kretz <M.Kretz@gsi.de>
+Date:   Fri Jun 27 13:11:39 2025 +0200
+
+    [simd.expos.defn] Fix missing paragraph break (#8028)
+
+commit abe616528d5ff19d25983af7497bcedf0b3d44bb
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Jun 27 13:12:54 2025 +0200
+
+    [iostate.flags] Add period at end of "Returns" (#8026)
+
+Author: Andrew Rogers <32688592+adr26@users.noreply.github.com>
+Date:   Sun Jun 29 11:20:31 2025 +0100
+
+    [container.insert.return] Fix description of insert-return-type (#8030)
+
+    Use the usual phrasing "X is for exposition only" when X is an exposition-only construct.
+
+commit be34ebfac39484ff96f68b46c2418b6fc49c66f4
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jul 2 07:58:52 2025 +0200
+
+    [istream.unformatted] Add period at end of "Returns"
+
+commit f6cd0dcbd082cfd85f87addec007680949cb1de9
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Fri Jul 4 04:27:11 2025 +0800
+
+    [range.join.iterator] Remove spurious return (#8038)
+
+commit 6f2e658a6c5ceaf577480d656bda0417fc98cc1d
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat Jul 5 08:42:54 2025 +0200
+
+    [mem.poly.allocator.mem] Fix typo
+
+commit ce78eced98e3e4dfe99eb409398267e5f00126aa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 25 12:35:16 2025 +0200
+
+    [std,check] Ensure proper placement of \iref
+
+commit ff592bd14ff3abecff33669bda91b658bf9f1023
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 15 09:15:08 2025 +0100
+
+    [diff.cpp23.lex] Fix capitalisation in heading
+
+commit 00102f1c03f81c6004d4d14e50f45e7084eafed0
+Author: Hana Dusíková <hanicka@hanicka.net>
+Date:   Mon Jul 14 11:50:06 2025 +0200
+
+    [container] unify to `friend constexpr` (there were few `constexpr friend`)
+
+commit 502465fc1b2676d1cf2e8565942f6d0446fc6d14
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jul 14 19:46:00 2025 +0200
+
+    [meta.syn] Fix typo
+
+commit c4c5bddac9e7e294c2685e5ae0d294b01d2b1572
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jul 14 20:11:49 2025 +0200
+
+    [meta.reflection.member.queries] Fix typos
+
+commit d3aaeb9da74e029199a3c4fb2c125e3fa8a6273c
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jul 14 19:59:51 2025 +0200
+
+    [meta.reflection.queries] Fix typos
+
+commit 9797d6936ddbb39b89fbfa31ab0bf57c213f8476
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jul 14 20:26:21 2025 +0200
+
+    [meta.reflection.traits] Fix typos
+
+commit a295d0ed2ebb68e3930d208ec5958efd51c6b225
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jul 16 20:23:54 2025 +0200
+
+    [meta.reflection.exception] Fix typo
+
+commit 08e1d9e30210983b2745ebff9b1002ecbf235bbd
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jul 14 20:42:53 2025 +0200
+
+    [meta.reflection.define.aggregate] Fix typos
+
+commit eb0529b7154823f39f1c86ffdfdc1f7f3bcebfaa
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Jul 15 08:48:12 2025 +0200
+
+    [meta.reflection.queries] Fix typo
+
+commit 51904cdf92ea7a8eb5f7f60cfe65233429d9c365
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jul 14 22:13:57 2025 +0200
+
+    [meta.reflection.queries] Add period to end of sentence
+
+commit d25f7d0b0449ffa3d89a4a3270dba8af2fd88719
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Jul 15 11:19:45 2025 +0200
+
+    [optional.ref.ctor] Fix punctuation
+
+commit 916d4f4d78509dced64f02c2616261b588c16941
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jul 14 21:55:02 2025 +0200
+
+    [over.call.func] Add period to end of sentence
+
+commit 7ca1adbf7367735b3657830798132b2fe2539cf7
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Jul 17 15:03:01 2025 +0200
+
+    [alg.partitions] Replace non-existent concept "copy_assignable" concept with "copyable"
+
+commit 5047d04a825a7fc72381ba5596da8c6062f65107
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Jul 15 22:59:04 2025 +0200
+
+    [alg.copy] Add period to end of sentence
+
+commit a5b2951c975588df8652ebc779784cbc84267c22
+Author: Luc Grosheintz <luc.grosheintz@gmail.com>
+Date:   Wed Jun 25 07:19:40 2025 +0200
+
+    [mdspan.layout.leftpad.cons] Add \expected.
+
+    The description of
+
+        template<class LayoutLeftPaddedMapping>
+          constexpr explicit(see below )
+            mapping(const LayoutLeftPaddedMapping& other);
+
+    didn't separate Mandates and Preconditions. This commit adds an
+    \expects to separate the two.
+
+commit e5a30fec15d4a9e6f4425edcf3c6898cc67fe0a3
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Jul 3 12:04:48 2025 +0000
+
+    [temp.constr.concept] Fix example
+
+    * Give all template parameters a unique name for clarity
+    * Replace use a of a reserved identifier
+    * Fix the example's accompanying text, in particular the parameter
+      mapping of the normal form of the concept-id after substitution
+
+commit 103dddccf3a965899c4bcaedab98154792573f24
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Jul 17 15:21:44 2025 +0200
+
+    [exec.task.scheduler] Fix typo
+
+commit 2974816e0b56f79c169f7eee3b24572e0092cd35
+Author: Daniel M. Katz <katzdm@gmail.com>
+Date:   Thu Jul 17 09:39:07 2025 -0400
+
+    [meta.reflection.access.context] Fix typo
+
+commit bd2412ce3b94f7ae3bf9c9e78a97e31181e7c01d
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Jul 17 15:15:16 2025 +0200
+
+    [exec.affine.on, task.promise] Fix typos
+
+commit 1acddcece95e2d7c83db3d8aee89fd4d4689fcd3
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Jul 15 05:05:03 2025 -0400
+
+    [lex.separate] Remove last reference to instantation units
+
+    The term instantiation unit was removed by the reflection paper, P2996.
+
+commit 42e68bf40e4ab7fc8b4a102f6c1d0ba4f6b63faa
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Jul 18 09:12:16 2025 +0200
+
+    [task.promise] Move period to end of sentence
+
+commit c76496316acc434ac06e23191b45b0c228f7331f
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Fri Jul 18 13:09:41 2025 +0200
+
+    [simd.syn] Fix capitalization and code fonts in synopsis comments; reflow declarations (#8093)
+
+commit cdffb3687e537d19197fc9bd24dca0e63ae6c744
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Jul 19 06:02:19 2025 -0400
+
+    [cpp.error] Recommended practice should start it own paragraph
+
+commit ad971231094740ae637c70c468c6e96f3a98a5d3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Jul 20 00:24:52 2025 +0100
+
+    [expr.const] Improve punctuation in list items.
+
+    Striking "and" was a missed edit from P2996R13.
+
+commit 67a20d351cd370def6dede93e1c3703de4b32b70
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Jul 20 01:46:41 2025 +0100
+
+    [temp.res.commit] Add introduction of definition of "type-only context".
+
+    This avoids having to style either of the two subsequent
+    sub-definitions as the main definition.
+
+commit c07c130af2014ee374be9754e9aeba43e564c614
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Jul 20 02:00:56 2025 +0100
+
+    [temp.dep.type] Fix list item continuation after recent addition.
+
+    This edit was missed in the application of P2996R13. The deletion of
+    the original "or" was not indicated in the paper (but is clearly
+    necessary).
+
+commit 0efc6648509b380573345101037eac96f1320645
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 18:07:37 2025 +0100
+
+    [tab:meta.unary.cat] "is_reflection": add xref to [basic.fundamental]
+
+commit 7ceef7e16c3314b178122762184d3d142262de00
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 18:13:32 2025 +0100
+
+    [meta.{syn, reflection.traits}] Rename "swappable_with_type" parameters to type1, type2.
+
+    These functions are symmetric and don't have a "src" and "dst".
+
+commit 12ad8bcaa490d7851cb2ffaff8ac219cd746e039
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 18:22:28 2025 +0100
+
+    [meta.syn] Add missing paragraph 4.
+
+    This was omitted in the application of P2996R13 by accident.
+
+commit 746811a19a222ffb5e9d03008d752bcb10967ce3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 18:27:25 2025 +0100
+
+    [tab:meta.reflection.operators] Fix some operator spellings
+
+commit 6b71747fdd3f38e20ef4bb4257aae64c0f1ec147
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 18:34:11 2025 +0100
+
+    [meta.reflection.names] "below" is "above"
+
+commit 2567873ea47b7f888f45aa4e8264c9cd3310183d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 18:41:04 2025 +0100
+
+    [meta.reflection.queries] Add missing paragraph in is_{const,volatile}.
+
+    This was omitted in the application of P2996R13 by accident.
+
+commit cbc4a1fb6853656f43c962a68396160e07663166
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 18:46:40 2025 +0100
+
+    [meta.reflection.queries] Add missing comma in "function, type".
+
+    This seems to have been a mistake during application of P2996R13.
+
+commit c27dd93b5aee5e3936f56cdf886b2a8f6af77ac5
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 18:50:57 2025 +0100
+
+    [meta.reflection.queries] Add missing "operator function template".
+
+    This seems to have been a mistake during application of P2996R13.
+
+commit b679e4be282c9303dfb41522e16cfe22931b37a0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 21:45:55 2025 +0100
+
+    [meta.reflection.queries] Add missing "Constant When" element of "dealias", converted to "Throws".
+
+    This seems to have been omitted during application of P2996R13 by
+    accident.
+
+commit 0ff0e096921ad25c9133b27ac30d727d0bfd5bc1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 21:30:11 2025 +0100
+
+    [meta.reflection.queries] Fix example
+
+    This seems to have been a mistake during application of P2996R13.
+
+commit 4021cdb12a314b8c3953feb5841342a4ff2b8993
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 21:33:06 2025 +0100
+
+    [meta.reflection.access.context] Fix typos
+
+commit 42a93030c64a87610aa0abb09290a0a11f563c96
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 21:53:08 2025 +0100
+
+    [meta.reflection.member.queries] Fixed font, typo
+
+commit bd0dee79f341012c8b4f12cff8235d874251f45b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 22:10:38 2025 +0100
+
+    [meta.reflection.layout] Delete unintended "value".
+
+    This seems to have been copy-pasted erroneously.
+
+commit 7488f055b98b56bfe598bbd2dd46a4eae4e8171a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 21 22:34:53 2025 +0100
+
+    [expr.ref] Delete extraneous "the".
+
+    Accidentally misapplied from P3293R3.
+
+commit e546fb55893220e63e79a7db777c6af9598dce27
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 22 10:48:03 2025 +0100
+
+    [expr.ref] Add "Otherwise, " to beginning of list items.
+
+    This was requested by P2996R13, but seems to have been missed.
+
+    This edit also covers the new item added by P3293R3.
+
+commit 5a191509d702a6e53947493ac4bc119c6a935c49
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 22 13:18:13 2025 +0100
+
+    [stmt.expand] Add comma before "or" to list item
+
+commit 580a5f6d378f17067749166ca68b2a04c9fdc2de
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Wed Dec 25 16:38:25 2024 +0000
+
+    [temp.deduct.call] Add missing words
+
+commit f8e0a6539254574f7984ff6a8afa1d61daab20c0
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Fri Jul 18 18:37:20 2025 -0400
+
+    [lex.separate] Redistribute second comment
+
+    The second comment in [lex.separate] is both too specific, and not specific
+    enough.  Move the last sentence about use of separately translated TUs to
+    the end of the first note, where it seems most appropriate.  Move the rest
+    to just after the definition of translation unit in phase 7 of translation.
+
+commit 3ce793a1a76e6c1b0ec599ab2d7d1696726c2253
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 22 13:24:01 2025 +0100
+
+    [lex.pptoken] Reorder list items to avoid "or" and "and" at same level
+
+commit 7e6519ecfeffe06254c088259f4e83d36bbd20bd
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 25 00:22:44 2025 +0100
+
+    [meta.reflection.layout] Spell variable "T", not "TR".
+
+    It's unclear whether this was just a typo or an attempt to avoid
+    ambiguity, but there does not seem to be a risk of confusion, and the
+    spelling of the paper ("T") seems fine.
+
+commit 454ba171cb14531639e641cb1200617fbf8d943f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 25 14:31:22 2025 +0100
+
+    [meta.reflection.queries] Delete mistaken "Throws:" element.
+
+    This was added accidentally in
+    b679e4be282c9303dfb41522e16cfe22931b37a0 because I misread the paper.
+
+commit 0922eeef80ee7f80e3edca688686e771a2d510bb
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 25 15:08:25 2025 +0100
+
+    [meta.reflection.extract] Fix typo
+
+commit 5396d899f281c99ee1d9df4ab7eca68d4acfa810
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 25 15:13:58 2025 +0100
+
+    [meta.reflection.extract] Fix mistaken "C" that should be "X C::*".
+
+    This seems to have been a mistake during application of P2996R13.
+
+commit c9e7524ce95bd5e0e659419d7ea3137c7cf464e4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 25 15:31:37 2025 +0100
+
+    [meta.reflection.result] Reorder and reword paragraphs for clarity.
+
+    After the "Constant When" => "Throws" reordering, the definition of
+    the invented variable TCls had moved far from where it was being
+    referenced. This reordering moves it closer, adds a "defined below",
+    and moves the example to the end.
+
+commit d64e4580f78350b635d403602e5064d96979fa55
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 25 15:37:25 2025 +0100
+
+    [meta.reflection.result] Fix "variable" => "template"
+
+    This seems to have been a mistake during application of P2996R13.
+
+commit b36bff07d7f810295e448f7b23f898d2966f5583
+Author: Matthias Kretz <m.kretz@gsi.de>
+Date:   Fri Jul 25 16:39:30 2025 +0200
+
+    [simd.mask.overview] Fix markup; add two missing closing @
+
+commit f5d3c63e7ffa2a7ba1811ab5f2202131379690f8
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Jul 25 23:55:42 2025 +0800
+
+    [xrefdelta] Fix typo in the entry for [re.def] (#8112)
+
+    The contents were moved to [intro.defs], not [intro.refs]. The latter is a typo.
+
+commit 27370ee1e0794bdd2b63c816860ed9c607bddc2a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 25 17:42:27 2025 +0100
+
+    [meta.reflection.define.aggregate] Fix note text and !=/==.
+
+    This seems to have been a mistake during application of P2996R13.
+
+commit 23e63d82a502b483781fc15eb7108d9ed86e16d0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 25 17:44:36 2025 +0100
+
+    [meta.reflection.define.aggregate] Fix typo ("C" should be "D").
+
+    This seems to have been a mistake during application of P2996R13.
+
+commit 1947b90539c268192d6e461208b6b278b3577ec9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 25 17:45:46 2025 +0100
+
+    [meta.reflection.define.aggregate] Fix typos
+
+commit 540773996f700115662dedbf4f315fb7b5c5e947
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Mar 3 13:47:13 2024 +0100
+
+    [handler.functions] Replace 'shall synchronize with' with 'synchronizes with'
+
+commit a75a8de957bc727e29a997f8e447b8b5e6d604ac
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Mar 3 13:49:42 2024 +0100
+
+    [mem.res.global] Replace 'shall synchronize with'; add reference
+
+commit 416219e1bc003e9aaacfbcf5507b7111d3862e9e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 26 00:38:50 2025 +0100
+
+    [tab:meta.reflection.traits] Fix some table entries
+
+commit 150caecf30a1ee455a02310a75d58224821e0220
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 26 01:02:09 2025 +0100
+
+    [tab:meta.reflection.traits] Use subscripts for maths T_1, T_2
+
+commit c6dfde71726d3ac6c14e9c9075aa4037245c40d4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 26 01:02:52 2025 +0100
+
+    [meta.reflection.traits] Use maths variables consistently
+
+    Also removes a comma that should not have been added.
+
+commit 6ef473941e8541c06bde7fda78a58bb7a2ac5d4a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 26 01:08:28 2025 +0100
+
+    [meta.reflection.array] Mended minor mistranscriptions
+
+commit a1283d5704724f202273f9bd5b3311b8e1a1af4a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 26 01:18:26 2025 +0100
+
+    [meta.reflection.queries] Add missing word "unless"
+
+commit 4e6d501c8cf6735b67005124e3eac23907d7222e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 26 01:57:05 2025 +0100
+
+    [meta.reflection.layout] Fix wording of alignment_of.
+
+    The original transcription used some older wording that was not in the
+    most recent (approved) revision of paper (P2996R13).
+
+commit 1e931b0137e3c63977ddf1d98ae43a327b408003
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 26 11:00:47 2025 +0100
+
+    [meta.reflection.queries] Add missing words "function or".
+
+    Those were accidentally omitted in the application of P3096R12.
+
+commit 14c0cdd94516cbea2dd088cdd971a98564591c89
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 26 11:20:12 2025 +0100
+
+    [cfloat.syn] Fix macro definition to be long, not int.
+
+    This was a misapplication of P3348R4.
+    Checked that the C standard also uses long.
+
+commit 9e75be6a40e9fd6dfb3a7683553d1764b1a99c41
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 26 11:25:01 2025 +0100
+
+    [cstdio.syn, cwctype.syn] Fix cross references to C
+
+commit b74580a2faf2e71591e13ad7e1e4671d1c8b640d
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Jul 27 01:47:13 2025 +0200
+
+    [linalg.conj.conjugatedaccessor] Fix incorrect return type of nested_accessor() (#8105)
+
+commit 4eb527d7c35e309391b2d92019410c83a2ed9993
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sun Jul 27 11:02:53 2025 -0400
+
+    [basic.link] All names have linkage
+
+    Given that the last option is "no linkage", the list is exhaustive
+    and should not open readers to questioning what other options
+    might be available if a name merely "can have" linkage.
+
+commit a8d02a9d5da364d3f47f39ba809ac486d4693897
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Jul 27 01:03:21 2025 +0100
+
+    [exec.snd.expos] Remove itemdecl "write-env".
+
+    An omission in the application of P3284R4.
+
+commit 3dcc932d3b28717f5995f26afe9eb851258cf58c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Jul 27 23:43:31 2025 +0100
+
+    [algorithm.syn] Fixed transcription errors in various types
+
+commit 48e73b8d1260317ed0518454f9dbb573aab41a66
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Jul 27 23:52:10 2025 +0100
+
+    [alg.contains] Use codeblock for long return expression
+
+commit b7d39b2974d4861153b2d60dda56fe6c87c5f206
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Jul 27 23:53:30 2025 +0100
+
+    [alg.foreach] Delete mistaken Complexity: element on for_each_n
+
+    This was presumably added via accidental copy-paste in the application
+    of P3179R9.
+
+commit ec837bba81851453902a23f7410faf32ebfd3eda
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Jul 27 23:58:39 2025 +0100
+
+    [alg.searc] Fixed transcription error in template head
+
+commit 4d7eb66ddbd76312d213efad7f997b87ad11a299
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 00:01:53 2025 +0100
+
+    [alg.ends.with] Fixed transcription error in defns of N1 and N2
+
+commit c2e12a963104a77acb7ac0f8573e6116cbb28e92
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 10:40:42 2025 +0100
+
+    [alg.copy] Add missing words.
+
+    Those were accidentally omitted in the application of P3179R9.
+
+commit d764e4f90540d65d5dac01e62ac6ddac81118fda
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 10:44:34 2025 +0100
+
+    [alg.replace] Fixed transcription error in template head
+
+commit e99cd72eca0e0906464506105cc531ad199ed240
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 12:42:02 2025 +0100
+
+    [alg.rotate] Move declaration to the correct itemdecl.
+
+    This was a mistake in the application of P3179R9.
+
+commit d2ed4f73fcdf7af6d8a8207388793ea34e3fa5f2
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 12:49:22 2025 +0100
+
+    [alg.partitions] Fixed some transcription errors
+
+commit 65fe94b7dbf63727cf3633bdc663f90c56bad031
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 13:39:30 2025 +0100
+
+    [alg.merge] Make "E(e1, e2)" explicitly depend on "e1", "e2".
+
+commit 7b25ed6c5f5bb58739b9f0902b4ab3b8a54ca1f4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 13:41:56 2025 +0100
+
+    [set.{union,intersection,difference}] Add missing "of".
+
+    This was mistakenly omitted in the application of P3179R9.
+
+commit 338e6b4647d5ecd42e09e3585213181897982602
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 13:46:21 2025 +0100
+
+    [set.intersection] Fixed transcription errors in return types.
+
+    Declaration error corresponds to 3dcc932d3b28717f5995f26afe9eb851258cf58c.
+
+    The errors in the Returns: follow.
+
+commit 2d72d926277e2e9abb7caec2a0b8018a98bb99e6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 14:00:09 2025 +0100
+
+    [algorithm] Remove unnecessary linebreaks for "requires mergeable"
+
+commit 8421019c09a46f2a76070131bb9b8dbac4e5b962
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 14:00:46 2025 +0100
+
+    [memory.syn] Delete unintended synopsis entry for "destroy_at".
+
+    This seems to have been a mistake in applying P3179R9.
+
+commit b5d77f4458e8ed83dd0968c54651c23c4cb0f68a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 14:39:12 2025 +0100
+
+    [exec.await.as] Delete stray "}"
+
+    Left over from transforming \tcode into codeblock.
+
+commit d91106b48d6b8453694a64bce5a0ef84306b82bf
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 15:04:45 2025 +0100
+
+    [exec.par.scheduler] Fix extent of definitions
+
+    As per P2079R10.
+
+commit b9a314f2d8cac8e1df5f2f828b223faaa413f4ab
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 15:08:11 2025 +0100
+
+    [exec.snd.expos] Fix typo
+
+commit 791ff12c615275f6eb1bd5ccaf0f58a2d0f54031
+Author: Giuseppe D'Angelo <dangelog@users.noreply.github.com>
+Date:   Mon Jul 28 22:14:31 2025 +0200
+
+    [expr.unary.op] Add a note about dereferencing a dangling pointer (#8130)
+
+    Dereferencing a dangling pointer to an object is valid; the resulting
+    lvalue can be used in limited ways as per [basic.life] p8.
+
+    Add a non-normative note linking the two sections.
+
+commit 4e79eb8816aa34b19efcdaeef416ed9850127658
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 22:26:28 2025 +0100
+
+    [exec.schedule.from] Fix placement of declaration of "check-types"
+
+    A misapplication of P3557R3.
+
+commit 511eaa16f93680875878ea7bc74a6c2172237832
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 22:29:12 2025 +0100
+
+    [exec.sync.wait.var] Fix wording
+
+    A misapplication of P3557R3.
+
+commit 9e25d17d0c62cad16531dd752df75e46552412f5
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 22:33:05 2025 +0100
+
+    [meta.reflection.exception] Fix spelling of "u8what"
+
+    A misapplication of P3560R2.
+
+commit 8e05e24e431b4706f2ad3e49731ab0b8d7a52459
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 22:36:58 2025 +0100
+
+    [meta.reflection.traits] Missed edit
+
+    A misapplication of P3560R2.
+
+commit 09a9a4174a1c2fada5e8af38eaa78deaeac9e9cd
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 22:45:18 2025 +0100
+
+    [meta.reflection.layout] Turn "Throws:" element into an "all of the following are required" list.
+
+    This restores the meaning of the multiple sentences, which had become
+    unclear after the "Constant When"-to-"Throws" change.
+
+commit 884d39bd3539dc837d4869144d677697b7247191
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 23:37:01 2025 +0100
+
+    [future.syn] Remove uses_allocator also from header synopsis.
+
+    P3503R3 didn't actually say this, but it is clearly necessary.
+
+commit 38ffbee80ca5a0bf5f83cb134697429797d87d9c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 28 23:39:37 2025 +0100
+
+    [atomics.ref.float] Fix typo
+
+commit fc6df2dbba6ac42837e42c6ce0ea53cd55ac0e2a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 29 00:42:00 2025 +0100
+
+    [macros] Add "see above" macros
+
+commit aaeb987ed4bd09d5d992b20f814f206d63d1c022
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 29 00:42:40 2025 +0100
+
+    [atomics.types.pointer] Fix parameter type (should be "see above")
+
+    A misapplication of P3111R8.
+
+commit 102de3e47d27e47421aefc030a8d7facb0568324
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 29 00:47:08 2025 +0100
+
+    [fs.path.{generic,native}.obs] Escape braces
+
+commit 0c75091a4a5589455c9d18108b8de56c97336985
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 29 00:52:40 2025 +0100
+
+    [version.syn] Add missing "freestanding" to feature-test macro
+
+    A misapplication of P2781R9.
+
+commit d299950f8d2f55f6cde7c43c22eeb3109ff1704c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 29 00:57:04 2025 +0100
+
+    [meta.rel] Move new paragraph to the correct subclause
+
+    A misapplication of P1317R2.
+
+commit df1f3f31d8a5f43ec4cfc235753ddceb4e26353f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 29 12:06:27 2025 +0100
+
+    [task.members] Change template parameter name from "R" to "Rcvr".
+
+    This makes it the same as in the header synopsis.
+
+commit ce7cc9c4b02476489bbfebcd9d9037ccc79e0125
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jul 30 15:18:25 2025 +0100
+
+    [task.state] Fix misplaced \end{itemize}
+
+commit 77ca407d56faafd591638b11102f33ba1b12aec8
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jul 30 15:41:55 2025 +0100
+
+    [basic.splice] The template argument is a parenthesized expression
+
+commit e15c0955b8c8b129000bc99d848fc54eeb82f74f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jul 30 15:33:56 2025 +0100
+
+    [task.promise] Fixes and clarifications in "operator new" spec
+
+    * Change erroneous "Allocator" to "allocator_type". This was
+      a mistake in the paper (a leftover from a previous revision).
+    * Locally defined variables are just typeset as normal code,
+      not as placeholders.
+    * Some commas inserted to separate coordinate subclauses.
+    * Replaced "(if any)" with leading "Oherwise", which seems better
+      in order to avoid seemingly providing two conflicting definitions
+      of alloc.
+    * Replaced "Then PAlloc is ..." with "Let PAlloc be ...", which
+      replaces the (causal vs temporal) ambiguous "then" with the
+      far more common "let" expression.
+
+commit e4a7f6da57891013ed378672c470970d95ea190e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jul 31 15:13:38 2025 +0100
+
+    [basic.fundamental] Delete repeated cross reference.
+
+    We don't seem to make any cross reference more than once per
+    subclause. We can revisit this policy, but for now the change
+    makes the text more consistent in this regard.
+
+commit 718777332db5157c39cbab50148eeb56a02330f3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 1 11:11:24 2025 +0100
+
+    [expr.reflect] Better cross-reference (for "namespace")
+
+commit c521311f5d61d8558a9c141f7a481196299833a4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 1 11:13:48 2025 +0100
+
+    [expr.reflect] Move text out of list item to intended position.
+
+    A mistake in the application of P2996R13.
+
+commit 5d29e6ddde83dcaebb69e5a215d8956dc399f0d7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 1 11:24:47 2025 +0100
+
+    [dcl.typedef] Fix: change semicolon to full stop.
+
+    A miss-edit in the application of P2996R13.
+
+commit b58eef6e11ff142d083979d6a652d56ab20d4ec1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 1 11:28:15 2025 +0100
+
+    [dcl.fct] Fix list continuation.
+
+    A miss-edit in the application of P2996R13.
+
+commit 6f718357e72f5f5e78dd2f212e66f5b0064a179d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 1 11:45:52 2025 +0100
+
+    [dcl.init.general] Insert comma before "or array thereof".
+
+    The comma improves the clarity of the binding of "or array thereof",
+    and was shown in P2996R13, but apparently mistakenly so; it did not
+    exist in the prior wording. But it is clearly important.
+
+commit d2654b6dcf8b30a0546d7afb411cd79c66129a24
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 4 10:21:31 2025 +0100
+
+    [alg.transform] Fix comma that should be a full stop.
+
+commit 6f496bf27bfdf5e48da3cc288c1c538ab993131e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 4 10:44:07 2025 +0100
+
+    [alg.partition] Fix "true" that should be "false".
+
+    A misapplication of P3179R9.
+
+commit 91b4bf8f7a1fb15010b348f3e1552491e01eb396
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 4 10:49:20 2025 +0100
+
+    [alg.merge] Fix some misapplications of P3179R9.
+
+commit 8ff31fafa7a3ec0d9ecc991cb3a98ce2abdd9574
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Aug 5 10:26:58 2025 +0100
+
+    [memory.syn] Fixed misspelled "nothrow-sized-sentinel-for".
+
+    This was a misapplication of P3179R9.
+
+commit e534fb2676e191b4396184abd81e9882f4437e7c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Aug 5 10:30:31 2025 +0100
+
+    [special.mem.concepts] Fixed misspelled "sized_sentinel_for".
+
+    This was a misapplication of P3179R9.
+
+commit c4dd6c83ead14c0081e3009019308c93d5dba55e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Aug 5 12:29:06 2025 +0100
+
+    [exec.sysctxrepl.psb] Fix typo in range expression
+
+    A misapplication of P2079R10.
+
+commit f7361435f9909fd260b775a6346c068d50234d16
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Aug 5 12:31:46 2025 +0100
+
+    [meta.syn] Fix typo "type_underlying_type" => "underlying_type"
+
+    This was an error in P2996R13.
+
+commit 40101948e00579dd6d551d5383303f37cf1eb9a9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Aug 5 12:34:08 2025 +0100
+
+    [tab:meta.reflection.operators] Fix another operator spelling
+
+    Similar to 746811a19a222ffb5e9d03008d752bcb10967ce3,
+    which missed this one.
+
+commit ed5362ea20c80d18be106549267a93dba3b3a7c9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Aug 5 12:37:59 2025 +0100
+
+    [meta.reflection.queries] Fix "r" that should be "T".
+
+    This is a follow-up to 2567873ea47b7f888f45aa4e8264c9cd3310183d,
+    which fixed a missing paragraph, but forgot to make this change.
+
+commit 28c495bef17c305fb8ef6f56b88ae11c6115ccf0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Aug 5 12:42:24 2025 +0100
+
+    [meta.reflection.access.context] Fix mistaken qualifier
+
+    A misapplication of P2079R10.
+
+commit 895e938cfb55d729d016086551f4472621d1722b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Aug 5 12:46:50 2025 +0100
+
+    [meta.reflection.extract] Reinstate "Constant When" wording from P2996R13 regarding similar and function pointer types
+
+    I'm not sure if the mention of function pointer types was dropped
+    in a misguided editorial simplification, but this is not an editorial
+    change. (But we retain the cross-reference which was not in the paper.)
+
+commit c3bd02a2e44c53c8fe7ba5b48a94bacc9186235d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Aug 5 12:55:17 2025 +0100
+
+    [meta.reflection.result] Fix function parameter name
+
+    A misapplication of P2996R13.
+
+ + diff --git a/papers/n5015.md b/papers/n5015.md new file mode 100644 index 0000000000..0cdc3948ec --- /dev/null +++ b/papers/n5015.md @@ -0,0 +1,1784 @@ +# N5015 Editors' Report -- Programming Languages -- C++ + +Date: 2025-08-14 + +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. +Special thanks to Alisdair Meredith and Jan Schultke +for drafting a lot of motion applications, +to Andreas Krug for ongoing careful reviews, +and to the review committee for finding and fixing many transcription errors +in this rather large amount of added text. + +## New papers + + * N5013 is the C++26 Committee Draft. + * [N5014](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5014.pdf) is the + current working draft for C++26. It replaces + [N5008](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5008.pdf). + * N5015 is this Editors' Report. + +## Motions incorporated into working draft + +### Notes on motions + +All motions were applied cleanly. + +In CWG Motion 11, +[P2843R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2843r3.pdf) +("Preprocessing is never undefined"), the text has been reconciled with +earlier changes coming from CWG Motion 1, Issue +[CWG3015](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3752r0.html#3015). + +In LWG Motion 35, +[P1317R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1317r2.pdf) +("Remove return type deduction in `std::apply`"), the feature test macro +`__cpp_lib_apply` was bumped and marked as also being in ``. + +Several minor phrasing and punctuation improvements have been applied +in subsequent reviews, and some minor errors and oversights in the approved +texts have been fixed in consultation with authors and wording group chairs. + +### Core working group polls + +CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues except issues 3013, 3014 and 3020 in +[P3752R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3752r0.html) +(Core Language Working Group "ready" Issues for the June, 2025 meeting) to the C++ Working Paper. + +CWG Poll 2. Apply the proposed resolutions of issues 3013, 3014 and 3020 in +[P3752R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3752r0.html) +(Core Language Working Group "ready" Issues for the June, 2025 meeting) to the C++ Working Paper. + +CWG Poll 3. Accept as a Defect Report and apply the changes in +[P3618R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3618r0.html) +(Allow attaching main to the global module) to the C++ Working Paper. + +CWG Poll 4. Apply the changes in [P2996R13](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2996r13.html) +(Reflection for C++26) to the C++ Working Paper and accept as Defect Reports core issues 2701 and 3026 resolved thereby. + +CWG Poll 5. Apply the changes in [P3394R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3394r4.html) +(Annotations for Reflection) to the C++ Working Paper. + +CWG Poll 6. Apply the changes in [P3293R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3293r3.html) +(Splicing a base class subobject) to the C++ Working Paper. + +CWG Poll 7. Apply the changes in [P3491R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3491r3.html) +(`define_static_{string,object,array}`) to the C++ Working Paper. + +CWG Poll 8. Apply the changes in [P1306R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1306r5.html) +(Expansion Statements) to the C++ Working Paper. + +CWG Poll 9. Apply the changes in [P3096R12](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3096r12.pdf) +(Function Parameter Reflection in Reflection for C++26) to the C++ Working Paper. + +CWG Poll 10. Apply the changes in +[P3533R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3533r2.html) +(constexpr virtual inheritance) to the C++ Working Paper. + +CWG Poll 11. Apply the changes in [P2843R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2843r3.pdf) +(Preprocessing is never undefined) to the C++ Working Paper. + +### Library working group polls + +LWG Poll 1. Apply the changes in [P3742R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3742r0.html) +(C++ Standard Library Issues to be moved in Sofia, Jun. 2025) to the C++ working paper. + +LWG Poll 2. Apply the changes in [P2988R12](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2988r12.pdf) +(`std::optional<‍T&‍>`) to the C++ working paper. + +LWG Poll 3. Apply the changes in [P3348R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3348r4.pdf) +(C++26 should refer to C23 not C17) to the C++ working paper. + +LWG Poll 4. Apply the changes in [P3037R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3037r6.pdf) +`(constexpr std::shared_ptr` and friends) to the C++ working paper. + +LWG Poll 5. Apply the changes in [P3284R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3284r4.html) +(`write_env` and `unstoppable` Sender Adaptors) to the C++ working paper. + +LWG Poll 6. Apply the changes in [P3179R9](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3179r9.html) +(Parallel Range Algorithms) to the C++ working paper. + +LWG Poll 7. Apply the changes in [P3709R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3709r2.html) +(Reconsider parallel `ranges::rotate_copy` and `ranges::reverse_copy`) to the C++ working paper. + +LWG Poll 8. Apply the changes in [P3641R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3641r0.html) +(Rename `std::observable` to `std::observable_checkpoint`, and add a feature-test macro) to the C++ working paper. + +LWG Poll 9. Apply the changes in [P3044R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3044r2.pdf) +(sub-`string_view` from `string`) to the C++ working paper. + +LWG Poll 10. Apply the changes in [P2876R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2876r3.html) +(Proposal to extend `std::simd` with more constructors and accessors) to the C++ working paper. + +LWG Poll 11. Apply the changes in [P3480R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3480r6.pdf) +(`std::simd` is a range) to the C++ working paper. + +LWG Poll 12. Apply the changes in [P2664R11](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2664r11.html) +(Extend `std::simd` with permutation API) to the C++ working paper. + +LWG Poll 13. Apply the changes in [P3691R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3691r1.pdf) +(Reconsider naming of the namespace for "`std::simd`") to the C++ working paper. + +LWG Poll 14. Apply the changes in [P3383R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3383r3.html) +(mdspan.at()) to the C++ working paper. + +LWG Poll 15. Apply the changes in [P2927R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2927r3.html) +(Inspecting `exception_ptr`) to the C++ working paper. + +LWG Poll 16. Apply the changes in [P3748R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3748r0.html) +(Inspecting `exception_ptr` should be constexpr) to the C++ working paper. + +LWG Poll 17. Apply the changes in [P2830R10](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2830r10.html) +(Standardized Constexpr Type Ordering) to the C++ working paper. + +LWG Poll 18. Apply the changes in [P3570R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3570r2.html) +(optional variants in sender/receiver) to the C++ working paper. + +LWG Poll 19. Apply the changes in [P3481R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3481r5.html) +(`std::execution::bulk()` issues) to the C++ working paper. + +LWG Poll 20. Apply the changes in [P3433R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3433r1.pdf) +(Allocator Support for Operation States) to the C++ working paper. + +LWG Poll 21. Apply the changes in [P3149R11](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3149r11.html) +(`async_scope` - Creating scopes for non-sequential concurrency) to the C++ working paper. + +LWG Poll 22. Apply the changes in [P3682R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3682r0.pdf) +(Remove `std::execution::split`) to the C++ working paper. + +LWG Poll 23. Apply the changes in [P2079R10](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2079r10.html) +(Parallel scheduler) to the C++ working paper. + +LWG Poll 24. Apply the changes in [P3557R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3557r3.html) +(High-Quality Sender Diagnostics with Constexpr Exceptions) to the C++ working paper. + +LWG Poll 25. Apply the changes in [P3560R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3560r2.html) +(Error Handling in Reflection) to the C++ working paper. + +LWG Poll 26. Apply the changes in [P3503R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3503r3.html) +(Make type-erased allocator use in `promise` and `packaged_task` consistent) to the C++ working paper. + +LWG Poll 27. Apply the changes in [P3008R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3008r6.html) +(Atomic floating-point min/max) to the C++ working paper. + +LWG Poll 28. Apply the changes in [P3111R8](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3111r8.html) +(Atomic Reduction Operations) to the C++ working paper. + +LWG Poll 29. Apply the changes in [P3060R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3060r3.html) +(Add `std::views::indices(n)`) to the C++ working paper. + +LWG Poll 30. Apply the changes in [P2319R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2319r5.html) +(Prevent path presentation problems) to the C++ working paper. + +LWG Poll 31. Apply the changes in [P3223R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3223r2.html) +(Making `std::istream::ignore` less surprising) to the C++ working paper. + +LWG Poll 32. Apply the changes in [P2781R9](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2781r9.html) +(`std::constant_wrapper`) to the C++ working paper. + +LWG Poll 33. Apply the changes in [P3697R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3697r1.html) +(Minor additions to C++26 standard library hardening) to the C++ working paper. + +LWG Poll 34. Apply the changes in [P3552R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3552r3.html) +(Add a Coroutine Task Type) to the C++ working paper. + +LWG Poll 35. Apply the changes in [P1317R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1317r2.pdf) +(Remove return type deduction in `std::apply`) 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 N5008 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/n5008...n5014). + + commit 2a74dc7bc587c2c64d8886faebc91d68c83626c1 + Author: Vlad Serebrennikov + Date: Mon Mar 17 15:33:35 2025 +0400 + + [expr.sub] Add missing cross-references (#7688) + + commit cdf6502ac7bf942f6ad32a27254db890c7ae8d3a + Author: Alisdair Meredith + Date: Tue Mar 18 09:35:16 2025 -0400 + + [sequences.general] std::hive is a sequence container (#7746) + + commit 2a71697913a853b62b8aeda5b68afbdfca756bf2 + Author: salonsro + Date: Tue Mar 18 13:37:49 2025 +0000 + + [defns.access] Add cross-reference (#7743) + + commit b3f45725c6cb088e26b02a36c51c6e19ce61351e + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Mar 19 13:18:56 2025 +0100 + + [basic.contract.eval] Fix typo (#7749) + + commit 0bd8d94cc6b693cc3dd25bd32157928b6e02ac8e + Author: Jan Schultke + Date: Wed Mar 19 18:43:01 2025 +0100 + + [lex.digraph] Swap alternative token representations in table (#7750) + + commit 958532b7042b0c12af783a0a2f9e5c8fafc8702c + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Mar 21 09:22:26 2025 +0100 + + [hive.operations] Move closing curly bracket in front of comma (#7757) + + commit 719601dcb890bf2dbc2330af5846c30a2ef84830 + Author: Eisenwave + Date: Sun Oct 27 10:43:51 2024 +0100 + + [dcl.init], [depr.atomics.types.operations] Say "with static storage duration" + + commit 8b753114c3fe1602e04ca9d1015c14c4a54544af + Author: Eisenwave + Date: Sun Oct 27 10:47:27 2024 +0100 + + [thread.condition.nonmember], [futures.promise], [futures.task.members] Say "with thread storage duration" + + commit 78bec38978bce1c680ea0a2dd2f8791967148bb8 + Author: Eisenwave + Date: Sun Oct 27 10:49:12 2024 +0100 + + [expr.prim.id.unqual], [support.start.term] Say "with automatic storage duration" + + commit 1dd46d8b87a1a7918d07966d7ef04c0118bee73e + Author: Thomas Köppe + Date: Fri Mar 21 13:02:50 2025 +0000 + + [tools] Catch exception of polymorphic type by reference + + commit 9caa0dc05cb525c433f7889e190946a325f752ed + Author: Matthias Kretz + Date: Sat Mar 22 19:48:08 2025 +0100 + + [exec.schedule.from, simd.ctor] Remove incorrect @ escapes (#7759) + + commit 2d59c792e2a0228e77a0316d39bde9e51f31d146 + Author: Jens Maurer + Date: Sat Mar 22 22:37:08 2025 +0100 + + [cpp.embed.gen] Fix typo in example + + commit 9b8a5e51752efe9edd7a447e96ffab0f3313accc + Author: Eelis + Date: Sun Mar 23 10:06:28 2025 +0100 + + [range.zip.transform.iterator] Fix typo in index entry. (#7762) + + commit 6a4c11e137509beed40ce93dd9d92b7b24e0cbda + Author: timsong-cpp + Date: Mon Mar 24 08:45:47 2025 +0100 + + [stopsource.general] Restore accidentally deleted members in class definition (#7766) + + These were removed in error in the application of P2300R10. + + commit d51cc9b757a0bbb343244c3aecd546783d08ba83 + Author: Hewill Kang + Date: Mon Mar 24 16:00:39 2025 +0800 + + [range.to.input.view] Add \ref for to_input_view​::​iterator (#7767) + + commit 879d51544872d6b8b6f0a845328db26ef5f2ddcb + Author: Hewill Kang + Date: Mon Mar 24 16:01:34 2025 +0800 + + [range.drop.view] Fix typo (#7768) + + commit c4a89e3ca4e34c82f6525a342f08dab1dce63d8c + Author: Jan Schultke + Date: Mon Mar 24 22:07:58 2025 +0100 + + [alg.rand.generate] Add generate_random to index (#7774) + + commit dd233b52569edc8598d575d57ee4634729228acf + Author: Hewill Kang + Date: Wed Mar 26 15:26:06 2025 +0800 + + [simd.ctor] Fix typos (#7779) + + commit ae030b95169a0c828917b72085ac99427c12f0d4 + Author: Hewill Kang + Date: Wed Mar 26 20:16:02 2025 +0800 + + [range.to.input.view] Add namespace wrapping (#7782) + + commit 4dd513d0096900ac82090875e2568a971909b2b3 + Author: Jens Maurer + Date: Wed Mar 26 20:48:23 2025 +0100 + + [lex.phases] Add cross-reference to [lex.header] (#7763) + + commit 3b4c353d381e07b4648671c592b82a1e487425d9 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Mar 27 19:51:39 2025 +0000 + + [temp.constr.general] Reorder constraint kinds to match subclause order (#7788) + + commit 5ecd4e9e00f64dfc73a75ce667bbaeba2b3b9b61 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Mar 27 20:40:32 2025 +0000 + + [temp.variadic] Consistently order template parameter kinds (#7796) + + commit 9798c7afb488414dd7e51fbc70dc9182ebafa668 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Mar 27 20:42:50 2025 +0000 + + [temp.deduct.type] Consistently order template argument kinds (#7798) + + commit 38a0bd47f42bf8c880df1a17e90110ac6a070944 + Author: Jonathan Wakely + Date: Fri Mar 28 22:25:40 2025 +0000 + + [alg.copy, alg.move] Rename ExecutionPolicy parameters for consistency (#7803) + + This makes them consistent with all other parallel algorithms. + + commit ddb98da95204fbd033e4e809e05634513187afb9 + Author: Jan Schultke + Date: Sun Mar 30 17:53:53 2025 +0200 + + [expr.const] Add reference to [dcl.constexpr] for "constexpr destructor" (#7629) + + commit d40449a0e50e126a35c555683dc7805f72efa7ef + Author: Jens Maurer + Date: Sun Mar 30 16:24:39 2025 +0200 + + [range.approximately.sized] Move to before [range.sized] + + This is an unfortunate application of P2846R6. + + commit ab81b357785fc5a48df60cbe9a372af4f281a25b + Author: timsong-cpp + Date: Sun Mar 23 18:20:35 2025 -0500 + + [cpp.predefined] Place the __STDC_EMBED macros in the unconditionally defined paragraph + + The incoming paper did not explicitly specify their placement, + but they are clearly meant to be defined unconditionally. + + commit 06ffe74abf088e275e4233d2891cc3ebc4664cea + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Mar 31 11:28:14 2025 +0000 + + [temp.constr.normal] Rephrase comment in example (#7793) + + commit 5b6307e337d50045c3b4109429f4912fe352bce4 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Mar 27 11:26:43 2025 +0000 + + [temp.over.link] Remove redundant wording + + commit 12b6153dccd2fc2f9ec6a8469d907b47bca57963 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Mar 27 11:26:40 2025 +0000 + + [temp.constr.normal] Use "contains (a pack)" instead of "names" + + commit 24c7d63df6144f0d718acb882c2c36ec97cd6212 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Mar 31 14:09:51 2025 +0200 + + [set.overview] Fix punctuation (#7808) + + commit bf5c701a23bcc7f79a459f474455cf0dc9c58de5 + Author: Hewill Kang + Date: Tue Apr 1 02:28:47 2025 +0800 + + [list.erasure, list.erasure] Move long code into codeblock (#7809) + + commit 743914c23ff20286507c1c8b201dc040a6f8f178 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Tue Apr 1 15:08:12 2025 +0000 + + [temp.dep.constexpr] Fix broken formatting (#7811) + + commit 9fd6664ea97cd889cdf529f2d020e6fa6ea13d58 + Author: Jonathan Wakely + Date: Fri Apr 4 17:48:11 2025 +0100 + + [optional.monadic] Remove stray angle brackets on concept name (#7817) + + commit a989431c5a893f9106dc21e9b2dd0a670356d890 + Author: Geng Cheng + Date: Thu Apr 10 17:32:28 2025 +0800 + + [polymorphic.general] Fix garbled expression (#7820) + + The applied paper P3019R14 had truncated text. + + commit f79a0f6981def4868fc365fb906a8a0551359c7d + Author: Geng Cheng + Date: Thu Apr 10 18:40:44 2025 +0800 + + [polymorphic.asgn] Remove superfluous greater-than sign (#7821) + + commit 7f1000d2eca113824d6ac734c5348f332a2d3e1c + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Apr 11 14:10:48 2025 +0200 + + [func.bind.partial] Add backslash for throws + + commit 8792e5544498d262a821b2175c1fe52fd3a15156 + Author: Arthur O'Dwyer + Date: Sun Apr 13 13:33:06 2025 -0400 + + [meta.unary.prop] Comma should be a period (#7832) + + commit 317ae891f25d4875651495780b5238869cce825b + Author: Hewill Kang + Date: Mon Apr 14 23:20:57 2025 +0800 + + [mdspan.layout.left.obs] Add missing noexcept (#7831) + + commit 5ec615184220e01fd8f6a817cf6050f3ce039f91 + Author: Geng Cheng + Date: Mon Apr 14 23:25:37 2025 +0800 + + [vector.modifiers] Old concepts cannot be “modeled” (#7836) + + commit 08b6e70e2c469a4a2d85d5ab49b14f75d57c0d36 + Author: OndrejPopp <50676516+OndrejPopp@users.noreply.github.com> + Date: Mon Apr 14 17:27:34 2025 +0200 + + [dcl.contract.func] Add missing \br in grammar (#7838) + + commit 52c7080115598baddd61b050c707d2a05a5fa2f7 + Author: A. Jiang + Date: Tue Apr 22 23:37:19 2025 +0800 + + [iterator.synopsis] Apply changes of P2538R1 to the synopsis of `` (#7841) + + Remove `incrementable_traits` and update `projected`. + + commit 05300d78dc4fb6ee346d93b381d6a15ed51406f7 + Author: Tsche <2440422+Tsche@users.noreply.github.com> + Date: Wed Apr 23 07:21:16 2025 +0200 + + [tuple.syn] Fix return type of ignore-type::operator= (#7840) + + This fixes a misapplication of P2968R2, in commit 225eadc4f3676472836397c9c0449f3203ae0a6d. + + commit a136094254936f2ae4e8bf1d5c59fff1afca03c7 + Author: A. Jiang + Date: Thu May 8 02:58:03 2025 +0800 + + [container.adaptors] Avoid naming sorted_{equivalent,unique}_t tag parameters (#7867) + + commit b99e22bb3f4e27eae65028aa011d3db08a0793cf + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu May 8 20:53:45 2025 +0200 + + [basic.contract.eval] Remove stray closing parenthesis (#7868) + + commit 4b1283ba5fabb5392b0faabe9682abc43d449614 + Author: Jens Maurer + Date: Mon May 12 22:32:34 2025 +0200 + + [sequence.reqmts] Fix application of P2846R6 for `assign_range` + + commit 74a6eed8a7b12041dbdb0dd9c39c433363211894 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue May 13 19:45:22 2025 +0200 + + [expr.call] Move period to end end of sentence (#7871) + + commit e8a5d8b83a91a0606883042fa3beb3e7b4423d9c + Author: Geng Cheng + Date: Thu May 15 02:25:17 2025 +0800 + + [associative.reqmts.general] Replace undefined "multiple keys" with "equivalent keys" (#7874) + + commit 69f81d2bc71ae28694ded6f03a5a2670e916c7d8 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu May 15 08:09:59 2025 +0200 + + [dcl.contract.res] Add period to end of sentence + + commit 78ea6062c043cc640fe5e72985eb36c279b1e976 + Author: Luc Grosheintz + Date: Thu May 15 23:46:56 2025 +0200 + + [mdspan.layout.right.obs] Add missing constexpr to required_span_size (#7872) + + commit 6c20db7e4a3300a0274e4ba9eb8c35371d6bc276 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri May 16 15:29:51 2025 +0200 + + [class.prop] Remove stray closing parenthesis (#7879) + + commit c4a2d197bb3c52d3e84a645bb756b3606e8408fc + Author: A. Jiang + Date: Sat May 17 03:07:18 2025 +0800 + + [algorithm.syn] Fix synopsis entries for `ranges::find_last` (#7805) + + P3217R0 updated ranges::find_last, but the synopsis was accidentally left unchanged. + + commit d8ab7083603ad16eb74fade44c757760b1f9e9dc + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat May 17 08:57:50 2025 +0200 + + [class.mem.general] Remove stray closing parenthesis (#7880) + + commit eb112f887bc541c5a21b302ac7d2476c7b5fa5e3 + Author: Jan Schultke + Date: Mon May 19 09:28:23 2025 +0200 + + [hive.operations] Add missing paragraph number (#7882) + + commit 0fd10bfb6ca13a61dd1bb77cad3b070d500e1cbc + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue May 20 13:42:28 2025 +0200 + + [dcl.fct.def.replace] Remove stray closing parenthesis (#7883) + + commit 1abf0915e3aa24ad48a1c2e74d60975a30fa93da + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri May 23 09:13:02 2025 +0200 + + [simd.bit] Add period to end of sentence (#7887) + + commit cc5b90512ac3deecfcc4e47f5da1910e54d661f9 + Author: S. B. Tam + Date: Wed May 28 00:18:32 2025 +0800 + + [locale.money.put.members] Fix typo (#7896) + + commit 782c81f8dfd714f34dced2de882b57d102dbde4c + Author: Jan Schultke + Date: Tue May 27 18:35:39 2025 +0200 + + [simd.creation] Add commas and improve semantic linebreaks (#7895) + + commit a770261ed7dc83ea269e07f4e5936ca65337ddff + Author: A. Jiang + Date: Wed May 28 17:59:55 2025 +0800 + + [text.encoding.id] Sort enumerators in ascending order (#7899) + + commit cb25f9b182c89e442687fed176150693debc6970 + Author: A. Jiang + Date: Sat May 31 04:16:52 2025 +0800 + + [projected] `projected` is an alias template after P2538R1 (#7901) + + commit b210471e21197f2e0f1655969c2adb9f04f30e02 + Author: Eric Niebler + Date: Sun Jun 1 09:20:30 2025 -0700 + + [execution.syn] Rename template parameter of `schedule_result_t` (#7906) + + commit d18bd92fda9c02e3518910824f041ab49fbc1a4b + Author: A. Jiang + Date: Mon Jun 2 05:47:51 2025 +0800 + + [tab:headers.cpp.fs] Fix header name for `is_execution_policy(_v)` (#7849) + + commit 25e95f5296e2b3c0f378ac5d3ddfdca1e867e9b0 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jun 2 17:52:21 2025 +0200 + + [simd.unary] Add \ref for simd.unary (#7908) + + commit a3b9cb5bdbec5e2fbf964561ea10dc19a4b042d5 + Author: Jan Schultke + Date: Mon Jun 2 22:36:05 2025 +0200 + + [container.requirements] Simplify Returns specification for try_emplace (#7892) + + commit 660ab848b97640764a270220f038f911b1057dfe + Author: Daniel Krügler + Date: Fri Jun 13 23:44:10 2025 +0200 + + [expected.object.cons] Reorder arguments of is_same_v for consistency (#7915) + + commit ee9b5bf124495f1473e246f223756a164d42aed9 + Author: Hubert Tong + Date: Sat Jun 14 02:32:38 2025 -0400 + + [meta.trans.other] Fix off-by-one references to [meta.rqmts] (#7914) + + commit 57e185f4bde5309d98e22f514d4434a1feea1911 + Author: A. Jiang + Date: Mon Mar 24 00:24:04 2025 +0800 + + [assertions.assert] Add ISO C reference for standard error stream + + commit 4f3e967cdc0befd71b1101e996c22db602ff0fd3 + Author: Eisenwave + Date: Sat May 3 10:25:33 2025 +0200 + + [class.temporary] Define "temporary object" + + commit 4aa14fe19a9060360436e9ab56d361101212e961 + Author: Jonathan Wakely + Date: Thu May 1 15:56:42 2025 +0100 + + [polymorphic.ctor] Owned object must have cv-unqualified object type + + commit 6f18c6b9e3634cf2ac40ab0f4d7c9e2e68acee2c + Author: Jonathan Wakely + Date: Mon Jun 16 08:42:48 2025 -0700 + + [value.error.codes] Remove redundant std qualifications (#7918) + + commit 59b1a8ada534fb1491ef3a134e05262baa0b516c + Author: Eric Niebler + Date: Tue Jun 17 05:56:42 2025 -0700 + + [exec.snd] Fix spelling of exposition-only `query-with-default` function (#7905) + + commit 04f4a62af51c7b3e8dad223051dc95a7942194c3 + Author: Jens Maurer + Date: Mon Jun 2 22:54:34 2025 +0200 + + [basic.def.odr] Rephrase sentence to avoid double-negative + + commit ca3694ecf8fd82d896d5bcf011bae7640d5335de + Author: Eric Niebler + Date: Tue Jun 17 06:04:08 2025 -0700 + + [exec.let] Fix function type name (#7907) + + The specification of `let_value(sndr,fn)` and friends refers to the type of `fn` as "`Fn`". But when introducing the types, we give it the name "`F`". This fixes the inconsistency. + + commit dfcc6dd19c0efd93bff47d501fdf6e2d52160a5c + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Mar 27 11:34:57 2025 +0000 + + [expr.type] Remove redundant \cvqual + + commit 9d20a320e1662deff9abb65b4f7e6e52e66ed732 + Author: Geng Cheng + Date: Tue Jun 17 21:51:41 2025 +0800 + + [indirect.asgn] Change "contained value" to "owned object" (#7822) + + commit 06e649b10e2d1af29eee739ea0998cb45e65fadc + Author: A. Jiang + Date: Tue Apr 8 17:19:29 2025 +0800 + + [string.view] Exposition-only formatting for `data_` and `size_` + + commit 9dfb02a3222eed8a02d74c7d80714eeaf3aba10b + Author: Geng Cheng + Date: Tue Jun 17 21:59:52 2025 +0800 + + [time.format] Add commas and clarifying "unless otherwise" (#7697) + + See LWG 4124, which added wording before the text in question that motivates adding "unless otherwise specified". + + commit 1f79f7a919432e8eccc90c9ffd21baeb9ea0563c + Author: A. Jiang + Date: Thu Apr 24 15:08:28 2025 +0800 + + [exec.util.cmplsig.trans] Drop verbose `add_lvalue_reference_t` + + commit 32ec75ea890301b100eac4a63e986a55cd08ea13 + Author: Thomas Köppe + Date: Tue Jun 17 17:07:41 2025 +0300 + + [indirect, polymorphic] Rename stable lables "asgn" to "assign" + + commit da436f8325d978b76eaa18be46e987decc9117c5 + Author: A. Jiang + Date: Wed Jun 18 00:47:57 2025 +0800 + + [defns.dynamic.type] Say "most derived object" in the example (#6203) + + commit 66e15a609b8bec7b4b976b17a5aaf3d65893d31c + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Tue Jun 17 21:48:26 2025 +0500 + + [intro.multithread.general] Say "use", not "access" functions (#6503) + + commit 7a90fddca19918e03bc10a7a6ef22a970ca381a3 + Author: A. Jiang + Date: Wed Jun 18 22:13:59 2025 +0800 + + [tab:meta.trans.cv] Simplify wording for add_{const,volatile} + + Wording about reference, function, or top-level cv-qualified types + moves to notes, as it is redundant since at least C++11. + + commit c156822435acd59433b7fb7f28e83a5765af7e64 + Author: A. Jiang + Date: Sun Sep 29 09:11:10 2024 +0800 + + [complex.numbers.general] Clarify that the template is primary + + The difference between between "the `complex` template" and "the template named `complex`" (which including program-defined specializations) is obscure. It seems better to cleary say that [complex.numbers.general] only covers the primary template. + + commit f457f12ffe04df1af8e6a28e174a5ca2dc59ddaa + Author: A. Jiang + Date: Thu Jun 19 17:32:03 2025 +0800 + + [execpol.type] Remove "see below" definition from "is_execution_policy" itemdecl (#7909) + + We already say that it is a Cpp17UnaryTypeTrait with a base characteristic of either true_type or false_type. + + commit 446ec2e959f38281786c3f61e83f077459763f92 + Author: Arthur O'Dwyer + Date: Fri Jun 20 02:19:07 2025 -0400 + + [inplace.vector] Move reserve, shrink_to_fit from "modifiers" to "capacity" (#7321) + + commit c355072152d7c9e364e2a8acf265fdf068942002 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Jun 20 07:50:59 2025 +0200 + + [valarray.cassign] Add period at end of "Returns" + + commit 3bce8f7f15164dc455240e53acce596eeba97d45 + Author: Jonathan Wakely + Date: Fri Jun 20 08:01:43 2025 +0100 + + [diff.cpp23.strings] Move Clause 27 changes after Clause 23 changes + + The 'Strings' clause was moved before the new 'Text processing' clause, + so it's now after the 'Containers' clause. The order of the [diff.cpp23] + subclauses should reflect that. + + commit ac78ae76c579883a32a9eb5b00346150a41e8e47 + Author: timsong-cpp + Date: Fri Jun 20 21:02:18 2025 +0100 + + [atomics.ref.float] Fix spelling of placeholder + + commit a8f807b14c33ca76c790df97ca7d0ddf9746abef + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sun Jun 22 09:12:52 2025 +0200 + + [out.ptr] Add period at end of "Returns" + + commit 346c6d0dfd608764d697f1a33ef739a4762e0d40 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sat Mar 11 20:53:05 2023 +0000 + + [conv.qual] Remove unused definition of 'cv-qualification signature' + + commit 0b41c12760d8079ee4c460df6ddecaf220f2dfb6 + Author: Thomas Köppe + Date: Sun Jun 22 19:59:47 2025 +0300 + + [intro] Special page header before Clause 1 (#6070) + + commit 4726d67bf8f22f15dd7f3dcae7b54832dcbbbb91 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Jun 22 17:27:15 2025 +0000 + + [dcl.type.auto.deduct] Change "occurrences" to "occurrence" (#7644) + + This appears to be a misapplication of N1984, which contains the wording "Obtain `P` from `T` + by replacing the occurrence of `auto` with a new invented type template parameter `U`." + + commit a8d96185e4bba7f738e4c2e1f3593a6e55fbbbd8 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jun 23 08:07:06 2025 +0200 + + [basic.ios.members] Add period at end of "Returns" + + commit 2e12f5e71e56af0ffae0b5a7cd9086d24b72df20 + Author: Thomas Köppe + Date: Mon Jun 23 12:48:46 2025 +0100 + + [stmt] Move start of subclause-spanning index entries up to \rSec1 + + I expect that we forgot to move this when we added the "general" + subclauses to remove hanging paragraphs, and thus accidentally caused + the index entries to be "misnested". + + commit 4f925714c37ed1fe6a5692adcc3ef5fa37964056 + Author: Jens Maurer + Date: Thu Jun 26 13:25:36 2025 +0200 + + [atomics.ref.float] Apply missing changes from P3323R1 + + Paper P3323R1 cv-qualified types in atomic and atomic_ref + was incompletely applied in commit cd4dbcf2aa6df895a25dbf8c0773dd0fa67ef45d. + + commit f9100076b21e277644a793624db7dc96bff29594 + Author: Matthias Kretz + Date: Fri Jun 27 13:11:39 2025 +0200 + + [simd.expos.defn] Fix missing paragraph break (#8028) + + commit abe616528d5ff19d25983af7497bcedf0b3d44bb + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Jun 27 13:12:54 2025 +0200 + + [iostate.flags] Add period at end of "Returns" (#8026) + + Author: Andrew Rogers <32688592+adr26@users.noreply.github.com> + Date: Sun Jun 29 11:20:31 2025 +0100 + + [container.insert.return] Fix description of insert-return-type (#8030) + + Use the usual phrasing "X is for exposition only" when X is an exposition-only construct. + + commit be34ebfac39484ff96f68b46c2418b6fc49c66f4 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jul 2 07:58:52 2025 +0200 + + [istream.unformatted] Add period at end of "Returns" + + commit f6cd0dcbd082cfd85f87addec007680949cb1de9 + Author: Hewill Kang + Date: Fri Jul 4 04:27:11 2025 +0800 + + [range.join.iterator] Remove spurious return (#8038) + + commit 6f2e658a6c5ceaf577480d656bda0417fc98cc1d + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat Jul 5 08:42:54 2025 +0200 + + [mem.poly.allocator.mem] Fix typo + + commit ce78eced98e3e4dfe99eb409398267e5f00126aa + Author: Jens Maurer + Date: Wed Jun 25 12:35:16 2025 +0200 + + [std,check] Ensure proper placement of \iref + + commit ff592bd14ff3abecff33669bda91b658bf9f1023 + Author: Thomas Köppe + Date: Tue Jul 15 09:15:08 2025 +0100 + + [diff.cpp23.lex] Fix capitalisation in heading + + commit 00102f1c03f81c6004d4d14e50f45e7084eafed0 + Author: Hana Dusíková + Date: Mon Jul 14 11:50:06 2025 +0200 + + [container] unify to `friend constexpr` (there were few `constexpr friend`) + + commit 502465fc1b2676d1cf2e8565942f6d0446fc6d14 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jul 14 19:46:00 2025 +0200 + + [meta.syn] Fix typo + + commit c4c5bddac9e7e294c2685e5ae0d294b01d2b1572 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jul 14 20:11:49 2025 +0200 + + [meta.reflection.member.queries] Fix typos + + commit d3aaeb9da74e029199a3c4fb2c125e3fa8a6273c + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jul 14 19:59:51 2025 +0200 + + [meta.reflection.queries] Fix typos + + commit 9797d6936ddbb39b89fbfa31ab0bf57c213f8476 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jul 14 20:26:21 2025 +0200 + + [meta.reflection.traits] Fix typos + + commit a295d0ed2ebb68e3930d208ec5958efd51c6b225 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jul 16 20:23:54 2025 +0200 + + [meta.reflection.exception] Fix typo + + commit 08e1d9e30210983b2745ebff9b1002ecbf235bbd + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jul 14 20:42:53 2025 +0200 + + [meta.reflection.define.aggregate] Fix typos + + commit eb0529b7154823f39f1c86ffdfdc1f7f3bcebfaa + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Jul 15 08:48:12 2025 +0200 + + [meta.reflection.queries] Fix typo + + commit 51904cdf92ea7a8eb5f7f60cfe65233429d9c365 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jul 14 22:13:57 2025 +0200 + + [meta.reflection.queries] Add period to end of sentence + + commit d25f7d0b0449ffa3d89a4a3270dba8af2fd88719 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Jul 15 11:19:45 2025 +0200 + + [optional.ref.ctor] Fix punctuation + + commit 916d4f4d78509dced64f02c2616261b588c16941 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jul 14 21:55:02 2025 +0200 + + [over.call.func] Add period to end of sentence + + commit 7ca1adbf7367735b3657830798132b2fe2539cf7 + Author: Jan Schultke + Date: Thu Jul 17 15:03:01 2025 +0200 + + [alg.partitions] Replace non-existent concept "copy_assignable" concept with "copyable" + + commit 5047d04a825a7fc72381ba5596da8c6062f65107 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Jul 15 22:59:04 2025 +0200 + + [alg.copy] Add period to end of sentence + + commit a5b2951c975588df8652ebc779784cbc84267c22 + Author: Luc Grosheintz + Date: Wed Jun 25 07:19:40 2025 +0200 + + [mdspan.layout.leftpad.cons] Add \expected. + + The description of + + template + constexpr explicit(see below ) + mapping(const LayoutLeftPaddedMapping& other); + + didn't separate Mandates and Preconditions. This commit adds an + \expects to separate the two. + + commit e5a30fec15d4a9e6f4425edcf3c6898cc67fe0a3 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Jul 3 12:04:48 2025 +0000 + + [temp.constr.concept] Fix example + + * Give all template parameters a unique name for clarity + * Replace use a of a reserved identifier + * Fix the example's accompanying text, in particular the parameter + mapping of the normal form of the concept-id after substitution + + commit 103dddccf3a965899c4bcaedab98154792573f24 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Jul 17 15:21:44 2025 +0200 + + [exec.task.scheduler] Fix typo + + commit 2974816e0b56f79c169f7eee3b24572e0092cd35 + Author: Daniel M. Katz + Date: Thu Jul 17 09:39:07 2025 -0400 + + [meta.reflection.access.context] Fix typo + + commit bd2412ce3b94f7ae3bf9c9e78a97e31181e7c01d + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Jul 17 15:15:16 2025 +0200 + + [exec.affine.on, task.promise] Fix typos + + commit 1acddcece95e2d7c83db3d8aee89fd4d4689fcd3 + Author: Alisdair Meredith + Date: Tue Jul 15 05:05:03 2025 -0400 + + [lex.separate] Remove last reference to instantation units + + The term instantiation unit was removed by the reflection paper, P2996. + + commit 42e68bf40e4ab7fc8b4a102f6c1d0ba4f6b63faa + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Jul 18 09:12:16 2025 +0200 + + [task.promise] Move period to end of sentence + + commit c76496316acc434ac06e23191b45b0c228f7331f + Author: Jan Schultke + Date: Fri Jul 18 13:09:41 2025 +0200 + + [simd.syn] Fix capitalization and code fonts in synopsis comments; reflow declarations (#8093) + + commit cdffb3687e537d19197fc9bd24dca0e63ae6c744 + Author: Alisdair Meredith + Date: Sat Jul 19 06:02:19 2025 -0400 + + [cpp.error] Recommended practice should start it own paragraph + + commit ad971231094740ae637c70c468c6e96f3a98a5d3 + Author: Thomas Köppe + Date: Sun Jul 20 00:24:52 2025 +0100 + + [expr.const] Improve punctuation in list items. + + Striking "and" was a missed edit from P2996R13. + + commit 67a20d351cd370def6dede93e1c3703de4b32b70 + Author: Thomas Köppe + Date: Sun Jul 20 01:46:41 2025 +0100 + + [temp.res.commit] Add introduction of definition of "type-only context". + + This avoids having to style either of the two subsequent + sub-definitions as the main definition. + + commit c07c130af2014ee374be9754e9aeba43e564c614 + Author: Thomas Köppe + Date: Sun Jul 20 02:00:56 2025 +0100 + + [temp.dep.type] Fix list item continuation after recent addition. + + This edit was missed in the application of P2996R13. The deletion of + the original "or" was not indicated in the paper (but is clearly + necessary). + + commit 0efc6648509b380573345101037eac96f1320645 + Author: Thomas Köppe + Date: Mon Jul 21 18:07:37 2025 +0100 + + [tab:meta.unary.cat] "is_reflection": add xref to [basic.fundamental] + + commit 7ceef7e16c3314b178122762184d3d142262de00 + Author: Thomas Köppe + Date: Mon Jul 21 18:13:32 2025 +0100 + + [meta.{syn, reflection.traits}] Rename "swappable_with_type" parameters to type1, type2. + + These functions are symmetric and don't have a "src" and "dst". + + commit 12ad8bcaa490d7851cb2ffaff8ac219cd746e039 + Author: Thomas Köppe + Date: Mon Jul 21 18:22:28 2025 +0100 + + [meta.syn] Add missing paragraph 4. + + This was omitted in the application of P2996R13 by accident. + + commit 746811a19a222ffb5e9d03008d752bcb10967ce3 + Author: Thomas Köppe + Date: Mon Jul 21 18:27:25 2025 +0100 + + [tab:meta.reflection.operators] Fix some operator spellings + + commit 6b71747fdd3f38e20ef4bb4257aae64c0f1ec147 + Author: Thomas Köppe + Date: Mon Jul 21 18:34:11 2025 +0100 + + [meta.reflection.names] "below" is "above" + + commit 2567873ea47b7f888f45aa4e8264c9cd3310183d + Author: Thomas Köppe + Date: Mon Jul 21 18:41:04 2025 +0100 + + [meta.reflection.queries] Add missing paragraph in is_{const,volatile}. + + This was omitted in the application of P2996R13 by accident. + + commit cbc4a1fb6853656f43c962a68396160e07663166 + Author: Thomas Köppe + Date: Mon Jul 21 18:46:40 2025 +0100 + + [meta.reflection.queries] Add missing comma in "function, type". + + This seems to have been a mistake during application of P2996R13. + + commit c27dd93b5aee5e3936f56cdf886b2a8f6af77ac5 + Author: Thomas Köppe + Date: Mon Jul 21 18:50:57 2025 +0100 + + [meta.reflection.queries] Add missing "operator function template". + + This seems to have been a mistake during application of P2996R13. + + commit b679e4be282c9303dfb41522e16cfe22931b37a0 + Author: Thomas Köppe + Date: Mon Jul 21 21:45:55 2025 +0100 + + [meta.reflection.queries] Add missing "Constant When" element of "dealias", converted to "Throws". + + This seems to have been omitted during application of P2996R13 by + accident. + + commit 0ff0e096921ad25c9133b27ac30d727d0bfd5bc1 + Author: Thomas Köppe + Date: Mon Jul 21 21:30:11 2025 +0100 + + [meta.reflection.queries] Fix example + + This seems to have been a mistake during application of P2996R13. + + commit 4021cdb12a314b8c3953feb5841342a4ff2b8993 + Author: Thomas Köppe + Date: Mon Jul 21 21:33:06 2025 +0100 + + [meta.reflection.access.context] Fix typos + + commit 42a93030c64a87610aa0abb09290a0a11f563c96 + Author: Thomas Köppe + Date: Mon Jul 21 21:53:08 2025 +0100 + + [meta.reflection.member.queries] Fixed font, typo + + commit bd0dee79f341012c8b4f12cff8235d874251f45b + Author: Thomas Köppe + Date: Mon Jul 21 22:10:38 2025 +0100 + + [meta.reflection.layout] Delete unintended "value". + + This seems to have been copy-pasted erroneously. + + commit 7488f055b98b56bfe598bbd2dd46a4eae4e8171a + Author: Thomas Köppe + Date: Mon Jul 21 22:34:53 2025 +0100 + + [expr.ref] Delete extraneous "the". + + Accidentally misapplied from P3293R3. + + commit e546fb55893220e63e79a7db777c6af9598dce27 + Author: Thomas Köppe + Date: Tue Jul 22 10:48:03 2025 +0100 + + [expr.ref] Add "Otherwise, " to beginning of list items. + + This was requested by P2996R13, but seems to have been missed. + + This edit also covers the new item added by P3293R3. + + commit 5a191509d702a6e53947493ac4bc119c6a935c49 + Author: Thomas Köppe + Date: Tue Jul 22 13:18:13 2025 +0100 + + [stmt.expand] Add comma before "or" to list item + + commit 580a5f6d378f17067749166ca68b2a04c9fdc2de + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Wed Dec 25 16:38:25 2024 +0000 + + [temp.deduct.call] Add missing words + + commit f8e0a6539254574f7984ff6a8afa1d61daab20c0 + Author: Alisdair Meredith + Date: Fri Jul 18 18:37:20 2025 -0400 + + [lex.separate] Redistribute second comment + + The second comment in [lex.separate] is both too specific, and not specific + enough. Move the last sentence about use of separately translated TUs to + the end of the first note, where it seems most appropriate. Move the rest + to just after the definition of translation unit in phase 7 of translation. + + commit 3ce793a1a76e6c1b0ec599ab2d7d1696726c2253 + Author: Thomas Köppe + Date: Tue Jul 22 13:24:01 2025 +0100 + + [lex.pptoken] Reorder list items to avoid "or" and "and" at same level + + commit 7e6519ecfeffe06254c088259f4e83d36bbd20bd + Author: Thomas Köppe + Date: Fri Jul 25 00:22:44 2025 +0100 + + [meta.reflection.layout] Spell variable "T", not "TR". + + It's unclear whether this was just a typo or an attempt to avoid + ambiguity, but there does not seem to be a risk of confusion, and the + spelling of the paper ("T") seems fine. + + commit 454ba171cb14531639e641cb1200617fbf8d943f + Author: Thomas Köppe + Date: Fri Jul 25 14:31:22 2025 +0100 + + [meta.reflection.queries] Delete mistaken "Throws:" element. + + This was added accidentally in + b679e4be282c9303dfb41522e16cfe22931b37a0 because I misread the paper. + + commit 0922eeef80ee7f80e3edca688686e771a2d510bb + Author: Thomas Köppe + Date: Fri Jul 25 15:08:25 2025 +0100 + + [meta.reflection.extract] Fix typo + + commit 5396d899f281c99ee1d9df4ab7eca68d4acfa810 + Author: Thomas Köppe + Date: Fri Jul 25 15:13:58 2025 +0100 + + [meta.reflection.extract] Fix mistaken "C" that should be "X C::*". + + This seems to have been a mistake during application of P2996R13. + + commit c9e7524ce95bd5e0e659419d7ea3137c7cf464e4 + Author: Thomas Köppe + Date: Fri Jul 25 15:31:37 2025 +0100 + + [meta.reflection.result] Reorder and reword paragraphs for clarity. + + After the "Constant When" => "Throws" reordering, the definition of + the invented variable TCls had moved far from where it was being + referenced. This reordering moves it closer, adds a "defined below", + and moves the example to the end. + + commit d64e4580f78350b635d403602e5064d96979fa55 + Author: Thomas Köppe + Date: Fri Jul 25 15:37:25 2025 +0100 + + [meta.reflection.result] Fix "variable" => "template" + + This seems to have been a mistake during application of P2996R13. + + commit b36bff07d7f810295e448f7b23f898d2966f5583 + Author: Matthias Kretz + Date: Fri Jul 25 16:39:30 2025 +0200 + + [simd.mask.overview] Fix markup; add two missing closing @ + + commit f5d3c63e7ffa2a7ba1811ab5f2202131379690f8 + Author: A. Jiang + Date: Fri Jul 25 23:55:42 2025 +0800 + + [xrefdelta] Fix typo in the entry for [re.def] (#8112) + + The contents were moved to [intro.defs], not [intro.refs]. The latter is a typo. + + commit 27370ee1e0794bdd2b63c816860ed9c607bddc2a + Author: Thomas Köppe + Date: Fri Jul 25 17:42:27 2025 +0100 + + [meta.reflection.define.aggregate] Fix note text and !=/==. + + This seems to have been a mistake during application of P2996R13. + + commit 23e63d82a502b483781fc15eb7108d9ed86e16d0 + Author: Thomas Köppe + Date: Fri Jul 25 17:44:36 2025 +0100 + + [meta.reflection.define.aggregate] Fix typo ("C" should be "D"). + + This seems to have been a mistake during application of P2996R13. + + commit 1947b90539c268192d6e461208b6b278b3577ec9 + Author: Thomas Köppe + Date: Fri Jul 25 17:45:46 2025 +0100 + + [meta.reflection.define.aggregate] Fix typos + + commit 540773996f700115662dedbf4f315fb7b5c5e947 + Author: Eisenwave + Date: Sun Mar 3 13:47:13 2024 +0100 + + [handler.functions] Replace 'shall synchronize with' with 'synchronizes with' + + commit a75a8de957bc727e29a997f8e447b8b5e6d604ac + Author: Eisenwave + Date: Sun Mar 3 13:49:42 2024 +0100 + + [mem.res.global] Replace 'shall synchronize with'; add reference + + commit 416219e1bc003e9aaacfbcf5507b7111d3862e9e + Author: Thomas Köppe + Date: Sat Jul 26 00:38:50 2025 +0100 + + [tab:meta.reflection.traits] Fix some table entries + + commit 150caecf30a1ee455a02310a75d58224821e0220 + Author: Thomas Köppe + Date: Sat Jul 26 01:02:09 2025 +0100 + + [tab:meta.reflection.traits] Use subscripts for maths T_1, T_2 + + commit c6dfde71726d3ac6c14e9c9075aa4037245c40d4 + Author: Thomas Köppe + Date: Sat Jul 26 01:02:52 2025 +0100 + + [meta.reflection.traits] Use maths variables consistently + + Also removes a comma that should not have been added. + + commit 6ef473941e8541c06bde7fda78a58bb7a2ac5d4a + Author: Thomas Köppe + Date: Sat Jul 26 01:08:28 2025 +0100 + + [meta.reflection.array] Mended minor mistranscriptions + + commit a1283d5704724f202273f9bd5b3311b8e1a1af4a + Author: Thomas Köppe + Date: Sat Jul 26 01:18:26 2025 +0100 + + [meta.reflection.queries] Add missing word "unless" + + commit 4e6d501c8cf6735b67005124e3eac23907d7222e + Author: Thomas Köppe + Date: Sat Jul 26 01:57:05 2025 +0100 + + [meta.reflection.layout] Fix wording of alignment_of. + + The original transcription used some older wording that was not in the + most recent (approved) revision of paper (P2996R13). + + commit 1e931b0137e3c63977ddf1d98ae43a327b408003 + Author: Thomas Köppe + Date: Sat Jul 26 11:00:47 2025 +0100 + + [meta.reflection.queries] Add missing words "function or". + + Those were accidentally omitted in the application of P3096R12. + + commit 14c0cdd94516cbea2dd088cdd971a98564591c89 + Author: Thomas Köppe + Date: Sat Jul 26 11:20:12 2025 +0100 + + [cfloat.syn] Fix macro definition to be long, not int. + + This was a misapplication of P3348R4. + Checked that the C standard also uses long. + + commit 9e75be6a40e9fd6dfb3a7683553d1764b1a99c41 + Author: Thomas Köppe + Date: Sat Jul 26 11:25:01 2025 +0100 + + [cstdio.syn, cwctype.syn] Fix cross references to C + + commit b74580a2faf2e71591e13ad7e1e4671d1c8b640d + Author: Jan Schultke + Date: Sun Jul 27 01:47:13 2025 +0200 + + [linalg.conj.conjugatedaccessor] Fix incorrect return type of nested_accessor() (#8105) + + commit 4eb527d7c35e309391b2d92019410c83a2ed9993 + Author: Alisdair Meredith + Date: Sun Jul 27 11:02:53 2025 -0400 + + [basic.link] All names have linkage + + Given that the last option is "no linkage", the list is exhaustive + and should not open readers to questioning what other options + might be available if a name merely "can have" linkage. + + commit a8d02a9d5da364d3f47f39ba809ac486d4693897 + Author: Thomas Köppe + Date: Sun Jul 27 01:03:21 2025 +0100 + + [exec.snd.expos] Remove itemdecl "write-env". + + An omission in the application of P3284R4. + + commit 3dcc932d3b28717f5995f26afe9eb851258cf58c + Author: Thomas Köppe + Date: Sun Jul 27 23:43:31 2025 +0100 + + [algorithm.syn] Fixed transcription errors in various types + + commit 48e73b8d1260317ed0518454f9dbb573aab41a66 + Author: Thomas Köppe + Date: Sun Jul 27 23:52:10 2025 +0100 + + [alg.contains] Use codeblock for long return expression + + commit b7d39b2974d4861153b2d60dda56fe6c87c5f206 + Author: Thomas Köppe + Date: Sun Jul 27 23:53:30 2025 +0100 + + [alg.foreach] Delete mistaken Complexity: element on for_each_n + + This was presumably added via accidental copy-paste in the application + of P3179R9. + + commit ec837bba81851453902a23f7410faf32ebfd3eda + Author: Thomas Köppe + Date: Sun Jul 27 23:58:39 2025 +0100 + + [alg.searc] Fixed transcription error in template head + + commit 4d7eb66ddbd76312d213efad7f997b87ad11a299 + Author: Thomas Köppe + Date: Mon Jul 28 00:01:53 2025 +0100 + + [alg.ends.with] Fixed transcription error in defns of N1 and N2 + + commit c2e12a963104a77acb7ac0f8573e6116cbb28e92 + Author: Thomas Köppe + Date: Mon Jul 28 10:40:42 2025 +0100 + + [alg.copy] Add missing words. + + Those were accidentally omitted in the application of P3179R9. + + commit d764e4f90540d65d5dac01e62ac6ddac81118fda + Author: Thomas Köppe + Date: Mon Jul 28 10:44:34 2025 +0100 + + [alg.replace] Fixed transcription error in template head + + commit e99cd72eca0e0906464506105cc531ad199ed240 + Author: Thomas Köppe + Date: Mon Jul 28 12:42:02 2025 +0100 + + [alg.rotate] Move declaration to the correct itemdecl. + + This was a mistake in the application of P3179R9. + + commit d2ed4f73fcdf7af6d8a8207388793ea34e3fa5f2 + Author: Thomas Köppe + Date: Mon Jul 28 12:49:22 2025 +0100 + + [alg.partitions] Fixed some transcription errors + + commit 65fe94b7dbf63727cf3633bdc663f90c56bad031 + Author: Thomas Köppe + Date: Mon Jul 28 13:39:30 2025 +0100 + + [alg.merge] Make "E(e1, e2)" explicitly depend on "e1", "e2". + + commit 7b25ed6c5f5bb58739b9f0902b4ab3b8a54ca1f4 + Author: Thomas Köppe + Date: Mon Jul 28 13:41:56 2025 +0100 + + [set.{union,intersection,difference}] Add missing "of". + + This was mistakenly omitted in the application of P3179R9. + + commit 338e6b4647d5ecd42e09e3585213181897982602 + Author: Thomas Köppe + Date: Mon Jul 28 13:46:21 2025 +0100 + + [set.intersection] Fixed transcription errors in return types. + + Declaration error corresponds to 3dcc932d3b28717f5995f26afe9eb851258cf58c. + + The errors in the Returns: follow. + + commit 2d72d926277e2e9abb7caec2a0b8018a98bb99e6 + Author: Thomas Köppe + Date: Mon Jul 28 14:00:09 2025 +0100 + + [algorithm] Remove unnecessary linebreaks for "requires mergeable" + + commit 8421019c09a46f2a76070131bb9b8dbac4e5b962 + Author: Thomas Köppe + Date: Mon Jul 28 14:00:46 2025 +0100 + + [memory.syn] Delete unintended synopsis entry for "destroy_at". + + This seems to have been a mistake in applying P3179R9. + + commit b5d77f4458e8ed83dd0968c54651c23c4cb0f68a + Author: Thomas Köppe + Date: Mon Jul 28 14:39:12 2025 +0100 + + [exec.await.as] Delete stray "}" + + Left over from transforming \tcode into codeblock. + + commit d91106b48d6b8453694a64bce5a0ef84306b82bf + Author: Thomas Köppe + Date: Mon Jul 28 15:04:45 2025 +0100 + + [exec.par.scheduler] Fix extent of definitions + + As per P2079R10. + + commit b9a314f2d8cac8e1df5f2f828b223faaa413f4ab + Author: Thomas Köppe + Date: Mon Jul 28 15:08:11 2025 +0100 + + [exec.snd.expos] Fix typo + + commit 791ff12c615275f6eb1bd5ccaf0f58a2d0f54031 + Author: Giuseppe D'Angelo + Date: Mon Jul 28 22:14:31 2025 +0200 + + [expr.unary.op] Add a note about dereferencing a dangling pointer (#8130) + + Dereferencing a dangling pointer to an object is valid; the resulting + lvalue can be used in limited ways as per [basic.life] p8. + + Add a non-normative note linking the two sections. + + commit 4e79eb8816aa34b19efcdaeef416ed9850127658 + Author: Thomas Köppe + Date: Mon Jul 28 22:26:28 2025 +0100 + + [exec.schedule.from] Fix placement of declaration of "check-types" + + A misapplication of P3557R3. + + commit 511eaa16f93680875878ea7bc74a6c2172237832 + Author: Thomas Köppe + Date: Mon Jul 28 22:29:12 2025 +0100 + + [exec.sync.wait.var] Fix wording + + A misapplication of P3557R3. + + commit 9e25d17d0c62cad16531dd752df75e46552412f5 + Author: Thomas Köppe + Date: Mon Jul 28 22:33:05 2025 +0100 + + [meta.reflection.exception] Fix spelling of "u8what" + + A misapplication of P3560R2. + + commit 8e05e24e431b4706f2ad3e49731ab0b8d7a52459 + Author: Thomas Köppe + Date: Mon Jul 28 22:36:58 2025 +0100 + + [meta.reflection.traits] Missed edit + + A misapplication of P3560R2. + + commit 09a9a4174a1c2fada5e8af38eaa78deaeac9e9cd + Author: Thomas Köppe + Date: Mon Jul 28 22:45:18 2025 +0100 + + [meta.reflection.layout] Turn "Throws:" element into an "all of the following are required" list. + + This restores the meaning of the multiple sentences, which had become + unclear after the "Constant When"-to-"Throws" change. + + commit 884d39bd3539dc837d4869144d677697b7247191 + Author: Thomas Köppe + Date: Mon Jul 28 23:37:01 2025 +0100 + + [future.syn] Remove uses_allocator also from header synopsis. + + P3503R3 didn't actually say this, but it is clearly necessary. + + commit 38ffbee80ca5a0bf5f83cb134697429797d87d9c + Author: Thomas Köppe + Date: Mon Jul 28 23:39:37 2025 +0100 + + [atomics.ref.float] Fix typo + + commit fc6df2dbba6ac42837e42c6ce0ea53cd55ac0e2a + Author: Thomas Köppe + Date: Tue Jul 29 00:42:00 2025 +0100 + + [macros] Add "see above" macros + + commit aaeb987ed4bd09d5d992b20f814f206d63d1c022 + Author: Thomas Köppe + Date: Tue Jul 29 00:42:40 2025 +0100 + + [atomics.types.pointer] Fix parameter type (should be "see above") + + A misapplication of P3111R8. + + commit 102de3e47d27e47421aefc030a8d7facb0568324 + Author: Thomas Köppe + Date: Tue Jul 29 00:47:08 2025 +0100 + + [fs.path.{generic,native}.obs] Escape braces + + commit 0c75091a4a5589455c9d18108b8de56c97336985 + Author: Thomas Köppe + Date: Tue Jul 29 00:52:40 2025 +0100 + + [version.syn] Add missing "freestanding" to feature-test macro + + A misapplication of P2781R9. + + commit d299950f8d2f55f6cde7c43c22eeb3109ff1704c + Author: Thomas Köppe + Date: Tue Jul 29 00:57:04 2025 +0100 + + [meta.rel] Move new paragraph to the correct subclause + + A misapplication of P1317R2. + + commit df1f3f31d8a5f43ec4cfc235753ddceb4e26353f + Author: Thomas Köppe + Date: Tue Jul 29 12:06:27 2025 +0100 + + [task.members] Change template parameter name from "R" to "Rcvr". + + This makes it the same as in the header synopsis. + + commit ce7cc9c4b02476489bbfebcd9d9037ccc79e0125 + Author: Thomas Köppe + Date: Wed Jul 30 15:18:25 2025 +0100 + + [task.state] Fix misplaced \end{itemize} + + commit 77ca407d56faafd591638b11102f33ba1b12aec8 + Author: Thomas Köppe + Date: Wed Jul 30 15:41:55 2025 +0100 + + [basic.splice] The template argument is a parenthesized expression + + commit e15c0955b8c8b129000bc99d848fc54eeb82f74f + Author: Thomas Köppe + Date: Wed Jul 30 15:33:56 2025 +0100 + + [task.promise] Fixes and clarifications in "operator new" spec + + * Change erroneous "Allocator" to "allocator_type". This was + a mistake in the paper (a leftover from a previous revision). + * Locally defined variables are just typeset as normal code, + not as placeholders. + * Some commas inserted to separate coordinate subclauses. + * Replaced "(if any)" with leading "Oherwise", which seems better + in order to avoid seemingly providing two conflicting definitions + of alloc. + * Replaced "Then PAlloc is ..." with "Let PAlloc be ...", which + replaces the (causal vs temporal) ambiguous "then" with the + far more common "let" expression. + + commit e4a7f6da57891013ed378672c470970d95ea190e + Author: Thomas Köppe + Date: Thu Jul 31 15:13:38 2025 +0100 + + [basic.fundamental] Delete repeated cross reference. + + We don't seem to make any cross reference more than once per + subclause. We can revisit this policy, but for now the change + makes the text more consistent in this regard. + + commit 718777332db5157c39cbab50148eeb56a02330f3 + Author: Thomas Köppe + Date: Fri Aug 1 11:11:24 2025 +0100 + + [expr.reflect] Better cross-reference (for "namespace") + + commit c521311f5d61d8558a9c141f7a481196299833a4 + Author: Thomas Köppe + Date: Fri Aug 1 11:13:48 2025 +0100 + + [expr.reflect] Move text out of list item to intended position. + + A mistake in the application of P2996R13. + + commit 5d29e6ddde83dcaebb69e5a215d8956dc399f0d7 + Author: Thomas Köppe + Date: Fri Aug 1 11:24:47 2025 +0100 + + [dcl.typedef] Fix: change semicolon to full stop. + + A miss-edit in the application of P2996R13. + + commit b58eef6e11ff142d083979d6a652d56ab20d4ec1 + Author: Thomas Köppe + Date: Fri Aug 1 11:28:15 2025 +0100 + + [dcl.fct] Fix list continuation. + + A miss-edit in the application of P2996R13. + + commit 6f718357e72f5f5e78dd2f212e66f5b0064a179d + Author: Thomas Köppe + Date: Fri Aug 1 11:45:52 2025 +0100 + + [dcl.init.general] Insert comma before "or array thereof". + + The comma improves the clarity of the binding of "or array thereof", + and was shown in P2996R13, but apparently mistakenly so; it did not + exist in the prior wording. But it is clearly important. + + commit d2654b6dcf8b30a0546d7afb411cd79c66129a24 + Author: Thomas Köppe + Date: Mon Aug 4 10:21:31 2025 +0100 + + [alg.transform] Fix comma that should be a full stop. + + commit 6f496bf27bfdf5e48da3cc288c1c538ab993131e + Author: Thomas Köppe + Date: Mon Aug 4 10:44:07 2025 +0100 + + [alg.partition] Fix "true" that should be "false". + + A misapplication of P3179R9. + + commit 91b4bf8f7a1fb15010b348f3e1552491e01eb396 + Author: Thomas Köppe + Date: Mon Aug 4 10:49:20 2025 +0100 + + [alg.merge] Fix some misapplications of P3179R9. + + commit 8ff31fafa7a3ec0d9ecc991cb3a98ce2abdd9574 + Author: Thomas Köppe + Date: Tue Aug 5 10:26:58 2025 +0100 + + [memory.syn] Fixed misspelled "nothrow-sized-sentinel-for". + + This was a misapplication of P3179R9. + + commit e534fb2676e191b4396184abd81e9882f4437e7c + Author: Thomas Köppe + Date: Tue Aug 5 10:30:31 2025 +0100 + + [special.mem.concepts] Fixed misspelled "sized_sentinel_for". + + This was a misapplication of P3179R9. + + commit c4dd6c83ead14c0081e3009019308c93d5dba55e + Author: Thomas Köppe + Date: Tue Aug 5 12:29:06 2025 +0100 + + [exec.sysctxrepl.psb] Fix typo in range expression + + A misapplication of P2079R10. + + commit f7361435f9909fd260b775a6346c068d50234d16 + Author: Thomas Köppe + Date: Tue Aug 5 12:31:46 2025 +0100 + + [meta.syn] Fix typo "type_underlying_type" => "underlying_type" + + This was an error in P2996R13. + + commit 40101948e00579dd6d551d5383303f37cf1eb9a9 + Author: Thomas Köppe + Date: Tue Aug 5 12:34:08 2025 +0100 + + [tab:meta.reflection.operators] Fix another operator spelling + + Similar to 746811a19a222ffb5e9d03008d752bcb10967ce3, + which missed this one. + + commit ed5362ea20c80d18be106549267a93dba3b3a7c9 + Author: Thomas Köppe + Date: Tue Aug 5 12:37:59 2025 +0100 + + [meta.reflection.queries] Fix "r" that should be "T". + + This is a follow-up to 2567873ea47b7f888f45aa4e8264c9cd3310183d, + which fixed a missing paragraph, but forgot to make this change. + + commit 28c495bef17c305fb8ef6f56b88ae11c6115ccf0 + Author: Thomas Köppe + Date: Tue Aug 5 12:42:24 2025 +0100 + + [meta.reflection.access.context] Fix mistaken qualifier + + A misapplication of P2079R10. + + commit 895e938cfb55d729d016086551f4472621d1722b + Author: Thomas Köppe + Date: Tue Aug 5 12:46:50 2025 +0100 + + [meta.reflection.extract] Reinstate "Constant When" wording from P2996R13 regarding similar and function pointer types + + I'm not sure if the mention of function pointer types was dropped + in a misguided editorial simplification, but this is not an editorial + change. (But we retain the cross-reference which was not in the paper.) + + commit c3bd02a2e44c53c8fe7ba5b48a94bacc9186235d + Author: Thomas Köppe + Date: Tue Aug 5 12:55:17 2025 +0100 + + [meta.reflection.result] Fix function parameter name + + A misapplication of P2996R13. diff --git a/papers/n5033.html b/papers/n5033.html new file mode 100644 index 0000000000..0886ba768a --- /dev/null +++ b/papers/n5033.html @@ -0,0 +1,2614 @@ + + + + + +N5033 + + +

N5033 Editors’ Report:
Programming Languages — C++

+ +

Date: 2025-12-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

+ +

Acknowledgments

+ +

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. +Special thanks to Alisdair Meredith and Jan Schultke +for drafting a lot of motion applications, +and to Andreas Krug for ongoing careful reviews.

+ +

New papers

+ +
    +
  • N5032 is the +current working draft for C++26. It replaces +N5014.
  • +
  • N5033 is this Editors' Report.
  • +
+ + +

Motions incorporated into working draft

+ +

Notes on motions

+ +

Note the unusual numbering of CWG motions. +In particular, CWG Motion 3a is not associated +with a change to the working draft.

+ +

In LWG Motion 1, the library issue +LWG4300 +had already previously been +applied editorially.

+ +

In LWG Motions 16 and 19, the resolution of +“NB US 227-346 and US 229-347” +in the latter has substantial overlap with paper +P3815R1 +of the former; the changes were reconciled and integrated.

+ +

All other motions were applied cleanly.

+ +

Core working group polls

+ +

CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues +except issues 1670, 2917, 2923, 3005, 3043, 3044, 3045, 3048, 3053, 3061, 3063, 3074, +3082, 3084, 3089, 3092, 3093, 3094, 3095, 3098, 3099, 3101, 3108, 3109, 3110, 3113, +3114, 3115, 3117, and 3118 in +P3921R0 +(Core Language Working Group “ready” Issues for the November, 2025 meeting) to the C++ Working Paper.

+ +

CWG Poll 2. Apply the proposed resolutions of issues +2917, 2923, 3005, 3043, 3044, 3045, 3048, 3053, 3061, 3063, 3074, 3082, 3084, 3089, 3092, +3093, 3094, 3095, 3098, 3099, 3101, 3108, 3109, 3110, 3113, 3114, 3115, 3117, and 3118 in +P3921R0 +(Core Language Working Group “ready” Issues for the November, 2025 meeting) to the C++ Working Paper.

+ +

CWG Poll 2b. Accept as Defect Reports and apply the proposed resolutions of issue 1670 in +P3921R0 +(Core Language Working Group “ready” Issues for the November, 2025 meeting) to the C++ Working Paper.

+ +

CWG Poll 3a. (Not relevant; poll did not pass, and did not propose a change to the working paper.)

+ +

CWG Poll 3b. Apply the changes in +P3920R0 +(Wording for NB comment resolution on trivial relocation) to the C++ Working Paper. +This addresses numerous ballot comments (see paper).

+ +

CWG Poll 4. Accept as a Defect Report and apply the changes in +P3868R1 +(Allow #line before module declarations) to the C++ Working Paper. +This addresses ballot comment US 55-102.

+ +

CWG Poll 5. Apply the changes in +P3684R1 +(Fix erroneous behaviour termination semantics for C++26) to the C++ Working Paper. +This addresses ballot comment GB 02-036.

+ +

Library working group polls

+ +

LWG Poll 1. Apply the changes in +P3905R0 +(C++ Standard Library Ready Issues to be moved in Kona, Nov. 2025) to the C++ working paper.

+ +

LWG Poll 2. Apply the changes in +P3906R0 +(C++ Standard Library Immediate Issues to be moved in Kona, Nov. 2025) to the C++ working paper.

+ +

LWG Poll 3. Apply the changes in +P3016R6 +(Resolve inconsistencies in begin/end for valarray and braced initializer lists) to the C++ working paper.

+ +

LWG Poll 4. Apply the changes in +P3567R2 +(flat_meow fixes) to the C++ working paper.

+ +

LWG Poll 5. Apply the changes in +P3663R3 +(Future-proof submdspan_mapping) to the C++ working paper. +This addresses ballot comments US 66-117 and PL 009.

+ +

LWG Poll 6. Apply the changes in +P3914R0 +(Assorted NB comment resolutions for Kona 2025) to the C++ working paper. +This addresses ballot comments US 160-260, US 209-332, US 228-348, US 263-396, US 265-398, US 266-399, US 112-172, and US 130-193.

+ +

LWG Poll 7. Apply the changes in +P3836R2 +(Make optional<T&> trivially copyable) to the C++ working paper. +This addresses ballot comment US 134-215.

+ +

LWG Poll 8. Apply the changes in +P3860R1 +(Proposed Resolution for NB Comment GB13-309 atomic_ref<T> is not convertible to atomic_ref<const T>) +to the C++ working paper, as a Defect Report for C++20. This addresses ballot comment GB13-309.

+ +

LWG Poll 9. Apply the changes in +P3388R3 +(When Do You Know connect Doesn’t Throw?) to the C++ working paper.

+ +

LWG Poll 10. Apply the changes in +P3774R1 +(Rename std::nontype, and make it broadly useful) to the C++ working paper. +This addresses ballot comments FR-021-218 and FR-019-210.

+ +

LWG Poll 11. Apply the changes in +P3819R0 +(Remove evaluation_exception() from contract-violation handling for C++26) +to the C++ working paper. +This addresses ballot comments NL, US 69-125,GB 04-124.

+ +

LWG Poll 12. Apply the changes in +P3612R1 +(Harmonize proxy-reference operations (LWG 3638 and 4187)) to the C++ working paper.

+ +

LWG Poll 13. Apply the changes in +P3778R0 +(Fix for type_order template definition) to the C++ working paper.

+ +

LWG Poll 14. Apply the changes in +P1789R3 +(Library Support for Expansion Statements) to the C++ working paper. +This addresses ballot comments NC IT-002, FR 007-011-142, CZ 2-143, US 78-144.

+ +

LWG Poll 15. Apply the changes in +P3922R1 +(Missing deduction guide from simd::mask to simd::vec) to the C++ working paper. +This addresses ballot comment DE-287.

+ +

LWG Poll 16. Apply the changes in +P3815R1 +(Add scope_association concept to P3149) to the C++ working paper. +This addresses ballot comments CA-393 and FI-392.

+ +

LWG Poll 17. Apply the changes in +P3878R1 +(Standard library hardening should not use the ‘observe’ semantic) to the C++ working paper. +This addresses ballot comments RU-016, FR-001-014, FR-010-113, US 3-015, and US 61-112.

+ +

LWG Poll 18. Apply the changes in +P3887R1 +(Make when_all a Ronseal Algorithm) to the C++ working paper.

+ +

LWG Poll 19. Apply the changes in +P3923R0 +(Additional NB comment resolutions for Kona 2025) to the C++ working paper. +This addresses ballot comments AT 7-213, US 140-233, US 141-235, US 145-234, +US 147-240, US 164-203, US 126-189, US 227-346, US 229-347, US 221-339, and US 225-341.

+ +

LWG Poll 20. Apply the changes in +P3371R5 +(Fix C++26 by making the rank-1, rank-2, rank-k, and rank-2k updates consistent with the BLAS) +to the C++ working paper. This addresses ballot comment US 168-277.

+ +

LWG Poll 21. Apply the changes in +P3391R2 +(constexpr std::format) to the C++ working paper. +This addresses ballot comment FR 028-271 and US 167-270.

+ +

LWG Poll 22. Apply the changes in +P3913R1 +(Optimize for std::optional in range adaptors) to the C++ working paper. +This addresses ballot comment PL-011.

+ +

National body comment resolution

+ +

A large number of national body comments for the C++26 Committee Draft have been +addressed in this working draft.

+ +

Editorial comments

+ +

All editorial national body comments were addressed before the Kona 2025 meeting:

+ + + + +

Non-editorial comments

+ +

The following national body comments were addressed by the motions approved at the Kona 2025 meeting:

+ + + + +

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 N5008 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 7ff7a571b82550f2d099ad982b010d7749ed51f7
+Author: Dmitriy Sobolev <Dmitriy.Sobolev@intel.com>
+Date:   Thu Aug 14 17:45:59 2025 +0100
+
+    [specialized.algorithms] Fix a typo: iter_difference_t<T> -> iter_difference_t<I> (#8143)
+
+    A misapplication of P3179R9.
+
+commit 4df4951bd456cc473643fa5d434ce5bf789f0f54
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sat Aug 2 13:36:14 2025 +0800
+
+    [locale.operators] Qualify `collate`
+
+commit c4eaf7276f43642b414ba9bd01a9112b6f792ad2
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Fri Aug 1 08:36:53 2025 -0400
+
+    [lex.phases] Identifiers do not have linkage, names do
+
+commit 939c73b400a418643c2e1885137a8baea04943d8
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Aug 14 15:08:44 2025 -0400
+
+    [lex.phases, lex.token] Provide unicode name for control characters (#7404)
+
+commit 8fe775ad322ed8837ec4d4bed55e6074c684930a
+Author: SainoNamkho <23036788+SainoNamkho@users.noreply.github.com>
+Date:   Fri Aug 15 03:51:41 2025 +0800
+
+    [dcl.init.ref] Fix misapplication of CWG2879 (#8147)
+
+commit 2ad9269583a4d62765e94154c7e97624083c21fe
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Aug 15 13:37:12 2025 +0800
+
+    [span.syn] Fix typo of `remove_cvref_t`
+
+commit 51a5bbae2fd449a7217d935ac069187b23fb6d22
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Aug 15 17:05:43 2025 +0800
+
+    [optional.optional.ref.general] Fix reference to [optional.ref.iterators]
+
+    Currently the comment mistakenly refer to [optional.iterators], while [optional.ref.iterators] should be referred to instead.
+
+commit 50930e22025e115d2c24451d4ba289f302020eee
+Author: Frank Birbacher <frank.birbacher@gmail.com>
+Date:   Fri Aug 15 13:08:42 2025 +0200
+
+    [meta.reflection.queries]/4.3 Fix syntax in example (#8152)
+
+    A misapplication of P2996R13.
+
+commit 6a6fb0655eeabbdf526b74e65016e0be5eb6f4b3
+Author: Frank Birbacher <frank.birbacher@gmail.com>
+Date:   Fri Aug 15 13:10:17 2025 +0200
+
+    [meta.reflection.queries]/1 Use info return type (#8153)
+
+    A misapplication of P2996R13.
+
+commit a44930586b09a269fbe5def4d9821239a23b6d6b
+Author: Frank Birbacher <frank.birbacher@gmail.com>
+Date:   Fri Aug 15 13:16:55 2025 +0200
+
+    [hive.cons] Add noexcept to move constructor (#8154)
+
+    The synopsis specifies noexcept for this constructor (and the effects
+    don't invoke behavior that could throw), so the missing noexcept on the
+    \itemdecl looks like an oversight in P0447R28.
+
+commit a3bdbd11810a24fe3edc7aef9dc8ac39e796e303
+Author: Frank Birbacher <frank.birbacher@gmail.com>
+Date:   Fri Aug 15 18:47:33 2025 +0200
+
+    [expr.const] Add splice-specifier to list of converted constant expressions (#8161)
+
+    This is a back-reference, because [expr.splice] refers to here already.
+
+commit d9b6f26dd6f92de0cd4ab3cd94d3a7daa44d3021
+Author: morinmorin <mimomorin@gmail.com>
+Date:   Mon Aug 18 20:04:47 2025 +0900
+
+    [back] Fix journal article entries in bibliography
+
+    This change applies the following corrections.
+    - Corrects misspelling of name to R. Clint Whaley.
+    - Adds missing page numbers.
+
+commit 648267c99a7a226b3a7433335e6136f70676d8d4
+Author: Rageking8 <106309953+Rageking8@users.noreply.github.com>
+Date:   Sat Aug 16 18:43:40 2025 +0800
+
+    [rand.dist.norm.f] Fix typo
+
+commit d13a034038e4956e02a6ab58f56109d109fab591
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Aug 18 16:45:22 2025 +0200
+
+    [unord.set.overview] Add "and" at end of list (#8167)
+
+commit 611d2ecc07a39403311783b5862df6319447eb7f
+Author: Rageking8 <106309953+Rageking8@users.noreply.github.com>
+Date:   Tue Aug 19 04:35:05 2025 +0800
+
+    [simd.syn] Remove duplicate `using simd::abs;` (#8163)
+
+commit 430b1b20565310bea11906ae8eabf746c0f7b8c5
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Aug 19 08:49:07 2025 +0200
+
+    [atomics.types.float] Fix typo
+
+commit 675155b5ab52d101de297a150120dccaedec2735
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 21 14:58:47 2025 +0800
+
+    [stringbuf.members] Remove `// exposition only` from `itemdecl` (#8179)
+
+commit 171454e98de36de7f9f3b7dfea241be79fc96ec7
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 21 13:32:14 2025 +0800
+
+    [locale.facet] Avoid improperly defining `explicit`
+
+commit 41014b4db993215816a2d855d161f7136b59a3db
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Aug 21 14:17:40 2025 +0200
+
+    [multiset.overview] Add "and" at end of list (#8182)
+
+commit 1bccf914e4ec88fd3b2dc4e54c9053f46349176f
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Aug 26 11:57:14 2025 -0400
+
+    [basic.def] Better link do defintion of declaration (#8191)
+
+    The plain text term in this sentence refer to the definition in [basic.pre]
+    and not the grammar production defined in [dcl].
+
+commit e593dc1a1f54d6e22179c26e246ded4e7dcf9588
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Aug 27 22:42:37 2025 +0200
+
+    [exec.counting.scopes.general] Fix typo (#8193)
+
+commit b1093176914ce5ec0be3b2e02e5ff5e3c4f5e3f6
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Aug 28 12:30:14 2025 -0400
+
+    [basic.pre] Clarify that *declaration*s are not declarations (#8187)
+
+    * [basic.pre] Clarify that *declaration*s are not declarations
+
+    The grammar production _declaration_ is distinct from the term "declaration" defined in [basic.pre].
+
+commit 73ba7d1d81f6ef8bf92683c9071f0c4fc8afe7ad
+Author: Rageking8 <tomleetyt@gmail.com>
+Date:   Fri Aug 29 00:31:47 2025 +0800
+
+    [meta] Fix several typos (#8157)
+
+commit 0b4ceb5dc35ebc736bfeb99ae629fdb0622ddf27
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sun Aug 31 19:26:32 2025 +0200
+
+    [tab:meta.unary.prop] Fix punctuation (#8197)
+
+commit bed3aab4b763ee5077d5cab997c020e389fc8092
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Sep 11 21:16:36 2025 +0800
+
+    [lex.phases] Fix typo in "instantiation" (#8223)
+
+commit 8d0144fc2e7ee8a1b38e9a69375fdedc430ec154
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Mon Sep 15 15:23:18 2025 +0800
+
+    [func.wrap.move.class, func.wrap.copy.class] Fix singular and plural in subclause titles (#8232)
+
+commit ed15cb52358664ae8a5b4c1df366dd2056c144e4
+Author: EienMiku <EienMiku@outlook.com>
+Date:   Tue Sep 16 18:43:45 2025 +0800
+
+    [map.overview] Fix typo of constructor of map
+
+commit c85cdf2d0bc4a559d4092575b70025f259a68c22
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sat Sep 27 10:52:22 2025 +0200
+
+    [meta.reflection.define.aggregate] Replace "is_enumeration_type" with "is_enum_type"
+
+    This fixes a wording bug in P2996R13.
+
+commit 020140713799934d623241627c6aaef917e5039d
+Author: Luc Grosheintz <luc.grosheintz@gmail.com>
+Date:   Sat Sep 27 22:26:43 2025 +0200
+
+    [views.multidim] Fix template arguments for submdspan_extents (#8243)
+
+commit 82bf75bc09e4ab5781e4f9149a59a41fe4c8581e
+Author: Luc Grosheintz <luc.grosheintz@gmail.com>
+Date:   Mon Sep 29 20:06:16 2025 +0200
+
+    [mdspan.sub.sub] Fix typos in submdspan effects (#8248)
+
+    The class `mdspan` doesn't have a member `data`, it has `data_handle`
+    (which returns a generalized pointer).
+
+    The `AccessorPolify::offset_policy` is a type alias and therefore needs
+    a preceeding `typename`.
+
+commit 3f8865632f916f52993f342393a016aa2d732792
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Tue Sep 30 04:07:15 2025 +0800
+
+    [simd.mask.comparison] Add missing parameter names (#8262)
+
+commit 9db1d3b6121e092ed89e84ba9a1e45bf2b7504fc
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Wed Oct 1 00:07:58 2025 +0800
+
+    [simd.permute.mask] Fix typo (#8268)
+
+commit 3c0ac909441ced78a097456fbfeec1b83f2da218
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Wed Oct 1 00:04:57 2025 +0800
+
+    [stringstream.members] Add missing param
+
+commit f5c6e4ef5fd303d07a0cd691913a5317164bb5d5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 18:58:19 2025 +0200
+
+    [meta.reflection.names] Fix formatting for 'N'
+
+    Fixes NB US 94-201 (C++26 CD).
+
+commit c6dc1e60202fea04b1d26769479c7063b3f867d1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 19:02:43 2025 +0200
+
+    [meta.reflection.queries] Fix typo in comment in example
+
+    Fixes NB US 96-206 (C++26 CD).
+
+commit eb87240307c7bb80937eda95c3077e41e096550f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 18:39:29 2025 +0200
+
+    [meta.reflection.operators] Remove superfluous 'the'
+
+    Fixes NB US 91-198 (C++26 CD).
+
+commit 7c3eb729ab66113a5ca02c90efce4ef5e944810b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 17:46:51 2025 +0200
+
+    [meta.reflection.member.queries] Remove superfluous 'of'
+
+    Fixes NB US 103-164 (C++23 CD).
+
+commit 9793e558b81c133e1237cd96ce37171f79b63245
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 18:54:11 2025 +0200
+
+    [meta.reflection.operators] Fix table formatting
+
+    Fixes NB US 92-199 (C++26 CD).
+
+commit 0c8df65ab760e827363591f95f127de98771238b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 15:32:15 2025 +0200
+
+    [basic.life] Remove spurious commas
+
+    Fixes NB US 18-035 (C++26 CD).
+
+commit f8d44da79bc497b8a3ab6fc3fce728e40206922a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 17:38:08 2025 +0200
+
+    [meta.syn] Fix phrasing in note
+
+    Fixes NB US 88-163 (C++26 CD).
+
+commit 9add78e448d5900d57f4e15da2f08eaceedab419
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 18:49:55 2025 +0200
+
+    [meta.reflection.define.aggregate] Fix declarations of name-type constructors
+
+    Fixes NB US 123-187 (C++26 CD).
+
+commit 0b085787cb519c8904e951f5fd23e1d4df5b7682
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 22:17:27 2025 +0200
+
+    [exec.snd] Fix cross-references for 'impls-for'
+
+    Fixes NB US 208-333 (C++26 CD).
+
+commit 47992d448b6cb6f31e78d27193853b6dd4783fb0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 23:36:18 2025 +0200
+
+    [execution.syn] Add comments to cross-references in synopsis
+
+    Fixes NB US 200-323 (C++26 CD).
+
+commit 969776f2676316422ae1e7c92718326efa3c357f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 23:54:24 2025 +0200
+
+    [exec.snd.expos] Move specification of default template argument for 'Data'
+
+    Fixes NB US 212-352 (C++26 CD).
+
+commit 5ba4be405536256e4498086dc78e1013e7b06920
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 23:45:05 2025 +0200
+
+    [execution.syn] Add enable_sender to synopsis
+
+    Fixes NB US 199-324 (C++26 CD).
+
+commit 40c2499440d42ac93e889bb7604173f01abb50a7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 22:29:10 2025 +0200
+
+    [exec.write.env] De-bulletize specification of check-types
+
+    Fixes NB US 218-349 (C++26 CD).
+
+commit 7c31fb08d42cb48eb2a5f63ed4406aff8f1eed4a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 15:43:54 2025 +0200
+
+    [temp.variadic] Add separate bullet for annotation-list
+
+    Fixes NB US 51-095 (C++26 CD).
+
+commit 322d38022bb292fbdb6d668af4ecd753eb104a53
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 15:39:10 2025 +0200
+
+    [class.pre] Adjust phrasing around 'identifer'
+
+    Fixes NB CA-083 (C++26 CD).
+
+commit be1585aeff253d6d87e41f08a4e617e96ac0e17a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 12:12:27 2025 +0200
+
+    [meta.reflection.extract] Apply code font to "U"
+
+    Fixes NB US 111-174 (C++26 CD).
+
+commit 9bd9e43f43d669d5fd353fa390818a47a42dad18
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 12:01:45 2025 +0200
+
+    [meta.reflection.layout] Remove incorrect 'of'
+
+    Fixes NB US 108-169 (C++26 CD).
+
+commit a7e6101939985870e128b742c616e5c6da357b2b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 08:23:03 2025 +0200
+
+    [exec.par.scheduler] Use 'has the value' for an expression
+
+    Fixes NB US 262-394 (C++26 CD).
+
+commit 6f3ef53700441dd46c369ab9e4a14e722206ffc6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 08:14:43 2025 +0200
+
+    [dcl.fct.def.replace] Add 'replaceable function' to index
+
+    Also add a label 'term.replaceable.function' for subclause-agnostic
+    cross-referencing.
+
+    Fixes NB US 269-406 (C++26 CD).
+
+commit 9d74d451e7ea2cf09e71f09b9e283047d713eab6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 07:44:02 2025 +0200
+
+    [algorithms.parallel.overloads] Rename subclause title
+
+    Fixes NB US 156-254 (C++26 CD).
+
+commit e70c392421cce818ae5edc0d4fde6d94184b8a4a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 12:18:08 2025 +0200
+
+    [meta.reflection.extract] Remove stray 'T is' and format 'X' in code font
+
+    Fixes NB US 110-171 (C++26 CD).
+
+commit 7c829315eb135f4df6326e35974c41983dc18ffd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 14:14:23 2025 +0200
+
+    [atomics.syn,atomics.ref.pointer] Remove partial specialization atomic_ref<T*>
+
+    A misapplication of paper P3323R1.
+
+    Fixes NB US 194-314 (C++26 CD).
+
+commit 7e30ea001b274cc74dc165e32e3908bd6d13a54a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 14:26:06 2025 +0200
+
+    [atomics.types.int,atomics.types.float] Excise uses of undeclared 'T'
+
+    Fixes NB US 196-315 (C++26 CD).
+
+commit 196df1a7a97c0f11286816baa22d365d202db8ad
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 15:00:21 2025 +0200
+
+    [atomics.ref.generic] Avoid use of undeclared 'T'
+
+    Fixes NB US 192-312 (C++26 CD).
+
+commit 13a5c431dde2bff1ee02fa655806ffaedfc1b70f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 09:42:48 2025 +0200
+
+    [task.promise] Remove trailing semicolons in comments in examples
+
+    Fixes NB US 259-380 (C++26 CD).
+
+commit 0bce45bb287307c828c69fee1942da0c17793a15
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 11:51:29 2025 +0200
+
+    [exec.task.scheduler] Fix punctuation and add 'the'
+
+    Fixes NB US 241-371 (C++26 CD).
+
+commit cd66127ccb165d4d0fcfb1594475a12600986697
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 17:54:17 2025 +0200
+
+    [exec.getcomplsigs] Fix misplaced \end{itemdescr} (#8301)
+
+    Fixes NB US 217-359 (C++26 CD).
+
+commit 122cc4abe30c0cdc39e7f7d4d09222ddfc298292
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 12:49:46 2025 +0200
+
+    [exec.snd.expos] Amend specification for allocator-aware-forward
+
+    Fixes NB US 216-357 (C++26 CD).
+
+commit 63c59140eda9f020f1d516657d2c1ab25c5a2d2d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 12:30:21 2025 +0200
+
+    [meta.reflection.substitute] Add 'in order'
+
+    A misapplication of P2996R13.
+
+    Fixes NB US 115-176 (C++26 CD).
+
+commit e2511592b653984301b7a13559c0e6e06d1243aa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 12:23:48 2025 +0200
+
+    [meta.reflection.substitute] Clarify error message in example
+
+    Fixes US 116-177 (C++26 CD).
+
+commit 42793d0ce36d4fe09a4c7ebdceeadef2e343fee4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 09:38:01 2025 +0200
+
+    [exec.sysctxrepl.psb] Make 'one of the expressions below' more explicit
+
+    Fixes NB US 266-399 (C++26 CD).
+
+commit 776bc2892e2480fb69296cd404fc4bd5136cc44a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 19:51:24 2025 +0200
+
+    [exec.snd] Harmonize subclause titles
+
+    Drop unnecessary 'std::' prefix
+
+    Fixes NB FR-033-335 (C++26 CD).
+
+commit e7e5b69c13ce5c358065fd989d64c4253693d415
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 11:42:14 2025 +0200
+
+    [task.promise] Refer to parameter types of the completion signatures
+
+    Fixes NB US 260-390 (C++26 CD).
+
+commit 600fe56064ee41722607e4c45d56919a1f153b87
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 19:59:38 2025 +0200
+
+    [simd.syn] Compactify presentation of gather/scatter functions
+
+commit bab708de50b834d5144cef2d2fb0872954ca47b9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 18:55:20 2025 +0200
+
+    [simd.traits] Rename subclause heading to 'Type traits'
+
+    The subclause applies to both vecs and masks.
+
+    Fixes NB US 177-284 (C++26 CD).
+
+commit 597cc85b49cfed8daab129fceca2c8d78b58dc6c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 18:07:17 2025 +0200
+
+    [simd.mask.namedconv] folded into [simd.mask.conv]
+
+    Fixes NB US 185-299 (C++26 CD).
+
+commit f3778a37d4a5c40f2ecc64b6ed47e3b8548b1eb6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 19:12:14 2025 +0200
+
+    [simd.complex.access] Move into [simd.class]
+
+    The complex accessors are member functions.
+    Also adjust the subclause heading to fit the new surroundings.
+
+    Fixes NB US 179-293 (C++26 CD).
+
+commit 2dbfcc5c7a759d6fbd6c09ecbc7f4439cc4eb5f5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 18:02:01 2025 +0200
+
+    [simd.mask.nonmembers] Add 'basic_mask' to subclause heading
+
+    Fixes NB US 186-300 (C++26 CD).
+
+commit 95a10a601b3e2c33713724b514b47162fefa73ef
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 11:46:40 2025 +0200
+
+    [task.state] Fix formatting of subclause heading
+
+    Fixes NB US 248-378 (C++26 CD).
+
+commit ae124b4ce071453365f5b89fcb815ee731fdd2f8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 22:37:15 2025 +0200
+
+    [exec.when.all] Fix spelling of 'get_stop_token_t'
+
+    Fixes NB US 223-343 (C++26 CD).
+
+commit b1949378f3174e8177890dac5fff62cc7ffdc0e3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 6 14:08:35 2025 +0200
+
+    [atomics.ref.pointer,atomics.types.pointer] Use 'see above' for fetch_key declaration
+
+    Fixes NB US 198-317 (C++26 CD).
+
+commit bc71d74ab0b0717973cbaf28a4f1931bd42fa848
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 11 10:28:16 2025 +0200
+
+    [exec.cmplsig] Add 'value_types_of_t' to index (#8326)
+
+commit adca52baba9f75d1190cbb9cc7dc7e4c04fa7152
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sun Oct 12 04:38:49 2025 -0400
+
+    [lex.phases] Move dropping whitespace to end of phase 4 (#8117)
+
+    Move the dropping of whitespace to the end of phase 4, after preprocessing directives are deleted.
+
+commit e1d47e006183ef8e2c778587b5fdcf0ce6d15da6
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Oct 16 22:27:11 2025 +0200
+
+    [basic.def] Remove incorrect \grammarterm formatting for "declaration" (#8337)
+
+    Fixes NB US 12-026 (C++26 CD).
+
+commit fb46e16c6ce0d91c6bd21ca497d1823c997d1926
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sat Oct 18 00:33:16 2025 +0200
+
+    [streambuf.virt.put] Replace "effects" with "affects" in footnote (#8329)
+
+    Fixes NB US 188-303 (C++26 CD).
+
+commit 8fc2944d469666f68b595a47b6f2f1d38547b402
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sat Oct 18 13:01:39 2025 +0100
+
+    [meta.type.synop] Remove redundant cast in constant_wrapper declaration (#8218)
+
+    The use of `decltype(cw-fixed-value(X))` instead of just `decltype(X)`
+    is a workaround for a GCC bug: https://gcc.gnu.org/PR117392
+
+    There's no need for the standard to specify it this way.
+
+    Fixes NB US 79-146 (C++26 CD).
+
+commit 05e4d8d991ec3a4d013b90c1317e9f76b68c8532
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 11 10:39:17 2025 +0200
+
+    [simd] Canonicalize subclause headings
+
+    Remove parts redundant with headings of superordinate subclauses.
+
+commit 7fffa1fb521b9432b769e0f83d6a60c732f3cfb8
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Oct 20 16:20:31 2025 +0100
+
+    [vector.bool.pscp] say "vector primary template" (#8351)
+
+    Not primary vector template.
+
+commit c914b3bf857daea1c30ffbb330c0a4e5a44edc70
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Mon Oct 20 17:24:12 2025 +0200
+
+    [meta.reflection.access.context] Remove stray "static" in declaration of "via" (#8272)
+
+    A misapplication of P2996R13.
+
+    Fixes NB US 101-208 (C++26 CD).
+
+commit ca77cdb10021c757b0fbe4d83b5991ac7d935db8
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Oct 20 16:28:59 2025 +0100
+
+    [fs.path.native.obs,fs.path.generic.obs] Qualify std::format (#8350)
+
+    Fixes NB US 190-305 (C++26 CD).
+
+commit 29465f5bec52bbfe1d81cd17c20527c911801447
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Oct 23 21:40:25 2025 +0200
+
+    [linalg.conj.conjugatedaccessor] Fix typos and constructor missing from synopsis (#8106)
+
+commit 0d90bd108f9cba10d206a300a64684a0244004e4
+Author: Hana Dusíková <hanicka@hanicka.net>
+Date:   Fri Oct 24 17:13:42 2025 +0200
+
+    [meta] reflect_constant_array of an empty range returns const array<T,0>
+
+commit cab90b37139473d67cba49397ff6666228ca4db3
+Author: Keith Thompson <Keith.S.Thompson@gmail.com>
+Date:   Fri Oct 24 12:20:54 2025 -0700
+
+    [diff.expr] Remove commentary about good practice in C (#8356)
+
+commit 2f53f313f5b1aac5f9547b39e78863e23ca9c047
+Author: A. Jiang <de34@live.cn>
+Date:   Sun Oct 26 19:22:13 2025 +0800
+
+    [lib] Fix C23 subclause numbers in `\xrefc` and `\IsoC` (#8113)
+
+commit 96fa31012b50a32d96a49fa8060124bcb70e3e5a
+Author: Kilian Henneberger <kilis-mail@web.de>
+Date:   Mon Oct 27 21:39:41 2025 +0100
+
+    [meta.reflection.substitute] Name correct function in comments (#8372)
+
+commit 3ba26a48c7a72f7ed7d17d6380457ff6f985489a
+Author: Matthias Kretz <M.Kretz@gsi.de>
+Date:   Wed Oct 29 22:58:21 2025 +0100
+
+    [simd.math] Add missing return keywords (#8374)
+
+commit 512372387083cdc2d112bfba157c463220b43476
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 1 11:16:35 2025 +0100
+
+    [expr.reflect] Delete sentence from "interpretation" list item that is redundant with the next item.
+
+    The next item already describes the case where R represents a namespace.
+
+commit 03f0c9f631c5e2d70cfe8e8476016771cc7d9d51
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 1 11:57:08 2025 +0100
+
+    [dcl.attr.grammar] Delete redundant "and no alignment-specifier".
+
+    Now that we say "an attribute-list with no attributes", the additional
+    "and no alignment-specifier" is redundant.
+
+commit 2a9a4e3c3757ace0ec8c24ca6f8c31e77f3a8ec5
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 21 09:57:22 2025 +0800
+
+    [expected.object.monadic] Add missing necessary `typename`
+
+commit 617a9f1254bb930c80ad4e5f13fb27ca4e8ded51
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 21 09:57:44 2025 +0800
+
+    [expected.void.monadic] Add missing necessary `typename`
+
+commit 266cb2bc567f00797ca4d0ebc6b425f98f5167bf
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Aug 21 15:16:09 2025 -0400
+
+    [cpp.replace.general] Add a cross-reference to 'see below'
+
+    The 'below' in 'see below' as actually five sublauses away.
+    Adding a cross-reference establishes the link more clearly.
+
+commit 262d37f0b19c91c795fd89872789ca7bcf200a42
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Aug 21 15:23:38 2025 -0400
+
+    [lex.phases] Clarify the sequence of characters for line splicing
+
+commit 6d42e2f96acf42060adcb018053f562a45510671
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Oct 30 08:39:52 2025 -0400
+
+    [basic.pre] Clarify definition of variable (#8186)
+
+    Reorder the positive and negative terms to avoid confusion with the binding of "other than".
+
+commit da231804706780368a6f6becc4d45000b31c19eb
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Aug 23 21:47:47 2025 -0400
+
+    [syntax] Replace plain text with grammar terms where intended
+
+    For the examples of X-seq and X-list forms of specifiaction,
+    ensure that the thing in the sequence or list is the corresponding
+    grammar element rather than a plain text term, as the two are not
+    always synonyms, notably not the case for the cited *declaration*.
+
+commit 1722e1f2b9ddc3b7f172b8f7503eda6e451c3012
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Jun 18 10:04:59 2025 +0800
+
+    [dcl.constexpr], [dcl.init.aggr] A constructor is a member function
+
+commit 494ddd03d3e7272727451126c264cb47ba698030
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Jun 18 10:08:50 2025 +0800
+
+    [expr.call], [expr.const] A constructor is a (member) function
+
+commit 683be0af96d1cfb1fa971cca17b10cf460445cd3
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Jun 18 10:11:23 2025 +0800
+
+    [temp.spec.general], [temp.inst] A member function is a function
+
+commit f7c7befc7f03236ca968c1003f1d65247519a51b
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Jun 18 10:12:09 2025 +0800
+
+    [constexpr.functions] A constructor is a function
+
+commit 729a91c79e408b89329ecdd6345a43c31931da2d
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Jun 18 10:12:51 2025 +0800
+
+    [pairs.pair] A constructor is a member function
+
+commit be930a9c8e7a6ae0e5c37bab6e741a878f046085
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Jun 18 10:15:49 2025 +0800
+
+    [container.reqmts], [flat.map.overview], [flat.multimap.overview], [flat.set.overview], [flat.multiset.overview] A constructor is a member function
+
+commit a81ecaa88443f7e23ef1dddc99a10b4b1488d21b
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Jun 18 10:20:07 2025 +0800
+
+    [diff.cpp17.depr] A constructor is a member function
+
+commit d411b5731711c02cbd140ff25fc514f0ef682817
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Feb 25 17:31:01 2024 +0100
+
+    [container.reqmts] Remove stray semicolon in description of expression
+
+commit 755202dc393ca6e9a87344ec9e810163c3b59d6b
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Jul 22 09:38:31 2025 +0800
+
+    [conv.rank] Update and fix the reference to C23 H.4.3
+
+commit 11b56197263aa8af89596e69e663de3cc873e360
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Jul 22 09:39:34 2025 +0800
+
+    [numerics.c] Use `\xrefc` to refer to C23 7.20
+
+    ... addressing the `%% TODO` comments
+
+commit 4917ad917b62e8065910c3c34ae1cd490747075b
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Jul 22 09:40:19 2025 +0800
+
+    [stdbit.h.syn] Use `\xrefc` to refer to C23 7.18
+
+    ... addressing the `%% TODO` comments
+
+commit 0b6b2b0cde8b878dbbf19b7f514e99be1e23aa87
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Sun Jul 27 23:39:23 2025 +0800
+
+    [range.refinements]  Fix template parameter name
+
+commit acb132bb75c3bedb159b26d151aae1469c68883b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jul 31 16:07:43 2025 +0100
+
+    [expr.prim.lambda.closure] Use "incomplete" instead of "not complete".
+
+    The former is a defined term.
+
+commit 7e9c2b7f29605a3f195f30ef1821a88f55dec950
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Fri Oct 31 01:35:27 2025 +0800
+
+    [const.wrap.class] Add missing namespace std (#8247)
+
+commit fde9d1f6047ed65e52483fa40162b966628162b2
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Oct 26 07:32:34 2025 +0100
+
+    [basic.scope.pdecl], [temp] Replace "expansion statement" with "expansion-statement"
+    Fixes NB US 2-404 (C++26 CD).
+
+commit 887c88157c52a8fb4f1acc3d49b40d4c5ef9af6c
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Oct 24 18:11:27 2025 +0100
+
+    [meta.reflection.layout] change 'entity' to 'construct'
+
+    Fixes NB US 104-165 (C++26 CD).
+
+commit 6042d48bc8467d7f73516e045f440e3b80a0961e
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Oct 21 13:59:35 2025 -0400
+
+    [cpp.pre] Move paragraph introducing preprocessor to first
+
+    The paragraph with no normative text that outlines the broad capabilities
+    of the preprocessor has slippee further down this clause as new text is added.
+    The most appropriate place for introductory text is the first sentence of the
+    introductory clause, so moved accordingly.
+
+commit 41c80d6cb744df0c8c409d3d72228c57fbf9d6cd
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Oct 17 19:19:23 2025 +0100
+
+    [simd.permute.static] use satisfies for satisfaction
+
+    Fixes NB US 182-296 (C++26 CD).
+
+commit a019163776f16b4ed4ac9b7ec22d9b8abcd9314d
+Author: Eisenwave <me@eisenwave.net>
+Date:   Thu Oct 9 11:34:21 2025 +0200
+
+    [class.temporary] Clarify that list of contexts is exhaustive, say "temporary objects"
+    Fixes NB US 19-037 (C++26 CD).
+
+commit 45dca420c08b9ce05b58140bc0572ff65dc24a1f
+Author: Eisenwave <me@eisenwave.net>
+Date:   Thu Oct 9 12:07:28 2025 +0200
+
+    [simd.syn] Reorder declarations to match subclause order
+    Fixes NB US 175-281 (C++26 CD).
+
+commit 2c60d60528470f5c1c7e53c345a77d2b88085483
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Oct 23 06:15:51 2025 +0200
+
+    [diff.expr] Include conversions involving pointers to cv void in the changes
+
+commit 210d61f6d4c10316975c9aa02ebeb2383b225983
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 25 18:22:16 2025 +0200
+
+    [dcl.init.general] Add cross-references for mandatory copy elision
+
+commit bfcdd7250785909bc2fdd9eeb381680129ec9628
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 5 22:25:03 2025 +0200
+
+    [exec.par.scheduler] Move class definition from synopsis
+
+    Fixes NB US 204-321 (C++26 CD).
+
+commit c82d84c417ee6c1e0407162c487a810a2baaa562
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 31 01:44:23 2025 +0100
+
+    [meta.reflection.{layout, annotation}] Harmonize phrasing about complete types (#8347)
+
+    Fixes NB US 107-168 (C++26 CD).
+
+commit 3de77e4c3112eaa54a7cd44ef11ba6a26bff1d00
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 8 13:37:41 2024 +0800
+
+    [class.ctor.general] Remove a dangling paragraph and associated index
+
+    The paragraph was made dangling by P1787R6.
+
+commit 8525f9150a7fe8c63fb593b65b80b09b55f94f30
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Oct 17 19:20:01 2025 +0100
+
+    [simd.permute.mask] clarify list is in ascending order
+
+    Fixes NB US 183-290 (C++26 CD).
+
+commit ffd997cb108c7b3be749ba1abb4ac727117f65ee
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Oct 24 17:53:32 2025 +0100
+
+    [meta.reflection.result] move declaration of TCls earlier
+
+    Fixes NB US 117-178 (C++26 CD).
+
+commit c53c1789779b1f6ccd95d0ab27aca50658830b07
+Author: Jeff Garland <jeff@crystalclearsoftware.com>
+Date:   Thu Oct 30 17:58:13 2025 -0700
+
+    [meta.reflection.extract] Remove second "constexpr if"
+
+    Fixes NB US 113-173 (C++26 CD).
+
+commit 65236d7d5fca9ccc8f3cff2d9c248f02f1f9d5bf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 17:54:14 2025 +0200
+
+    [meta.reflection.layout] Fix phrasing in bulleted list
+
+    Fixes NB US 105-166 (C++26 CD).
+
+commit 088768b5b613a29af165f2c99fe86e8bd918677a
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Sep 3 10:40:42 2025 +0200
+
+    [temp.deduct.general] Replace "nontype template argument" with "constant template argument"
+
+commit 19a9248ff8c5b0008f805e0353b697a5692ea354
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 26 12:53:22 2025 +0100
+
+    [lib] Remove superfluous `typename` in alias declarations
+
+    Also add an automatic check.
+
+    Fixes NB US 64-127 (C++26 CD).
+
+commit 1fcd55fceb8aca33f2e4d82c577aa47e94bb0e93
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 31 10:11:58 2025 +0100
+
+    [exec.sysctxrepl.recvproxy] Create new subclause for receiver proxies
+
+    Fixes NB US 264-397 (C++26 CD).
+
+commit 42129859dd633cd3f497ef9dd80b5d1dd4b35672
+Author: Eisenwave <me@eisenwave.net>
+Date:   Tue Oct 28 19:25:45 2025 +0100
+
+    [concept.regularinvocable], [iterator.concept.winc] Replace "annotation" with "comment"
+    Fixes NB US 71-128 (C++26 CD).
+
+commit 42fad0f0b26d87235bb0cf8524de3f7628150a10
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Oct 31 19:22:56 2025 +0800
+
+    [basic.fundamental] Complete examples for reflections (#8265)
+
+    Fixes NB US 22-042 (C++26 CD).
+
+commit bf6acb1d651f1960f287b8d98b62b1f0092d0a30
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Oct 31 12:05:49 2025 +0000
+
+    [meta.define.static] qualify names from namespace meta
+
+    Within library wording we don't do ADL, only unqualified lookup (as per
+    [contents] p3). This means that all the metafunctions in namespace std
+    need to qualify names from namespace std::meta in order to find them.
+
+    This also fixes the bug that name lookup in the Effects: of
+    define_static_array would find std::extent and not perform ADL to find
+    std::meta::extent, even if ADL was performed here.
+
+commit dfe8e0b2de8df3cd890351055352e742b8ad5a5f
+Author: YexuanXiao <bizwen@nykz.org>
+Date:   Fri Oct 10 00:01:05 2025 +0800
+
+    [meta.type.synop] Indexing the unindexed type aliases and variable templates
+
+commit 69837e72cebb65063a7f63b751e2ab8d70318823
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Fri Oct 31 22:14:47 2025 +0800
+
+    [unord.multiset.overview] Add missing "typename" (#8271)
+
+commit 54d9b47b3fcbb42ec7c24c89a00fa64f7fe4ad4e
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sat Sep 27 11:06:41 2025 +0200
+
+    [concepts.callable.general] Replace "function objects" with "callable types"
+
+commit 7089fb216f5ac4afa9c6e977a31921c2a0eff714
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Fri Oct 31 22:30:04 2025 +0800
+
+    [simd.overview] Remove obsolete "noexcept" (#8250)
+
+    The "noexcept" specifier was removed from the design by P3430R0,
+    but the paper omitted the corresponding change of the synopsis.
+
+commit 7f1926bbb287cccf27d0edccce860badbfc743b2
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Sep 5 19:14:38 2025 +0100
+
+    [flat.map.modifiers] Remove redundancy in 'insert(sorted_unique, i, j)'
+
+    We can specify this in terms of the overload without the `sorted_unique`
+    tag. That is consistent with how the equivalent functions in `flat_set`
+    and `flat_multiset` are specified.
+
+commit 13a33aca7b93142f63c68f426511291dc899032b
+Author: Masaki Moriguchi (a.k.a. Michel Morin) <mimomorin@gmail.com>
+Date:   Sat Nov 1 00:22:21 2025 +0900
+
+    [locale.moneypunct.virtuals] remove redundant backslash-space (#8159)
+
+    TeX already treats a period after uppercase as an acronym (which yields normal spacing).
+
+commit 1ff1e63b14f530389585bcee43401619f7edc139
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Fri Oct 31 16:32:02 2025 +0100
+
+    [optional.optional.{general, ref.general}] Say "object of type optional<T&>" (#8220)
+
+commit daf06c9f3445bd46678dc660e55debbb6feb7d97
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Tue Sep 30 02:17:45 2025 +0800
+
+    [mdspan.accessor.aligned.overview] Remove std:: in example
+
+commit 4bf58f81313e940295281a58d6520f8d9af18a56
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Sep 29 10:11:17 2025 +0800
+
+    [filebuf.virtuals] Add missing `const` to pointer variables
+
+    The fourth parameter of `codecvt::out` and `codecvt::in` are
+    `const C*&`, but _Effects_ use `C*` variables, which makes the call
+    ill-formed.
+
+    The intent seems sufficient clear and we should probably use `const C*`
+    variables in these places.
+
+commit 2e003dac4f1658e3ccbfd22c4e477f7b1d0ec3f1
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Fri Oct 31 16:39:18 2025 +0100
+
+    [{hive,vector}.capacity] Move remarks from Complexity to Remarks element (#8323)
+
+commit 04df25f524e692e0484f04779debcbaf59e83e2d
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Tue Oct 7 20:33:03 2025 +0800
+
+    [allocator.requirements.general] Add namespace std for exposition-only concept
+
+commit 1e54f58f5a5cf0a283b90c0db30fff76d42efb51
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Fri Oct 31 22:08:15 2025 +0100
+
+    [basic.link] Use maths font in defn of direct base class relationship (#8333)
+
+    Fixes NB US 1-405 (C++26 CD).
+
+commit 3b14ec1d5f19882e628bfa09b96eeaeebdb622b7
+Author: Eisenwave <me@eisenwave.net>
+Date:   Thu Oct 9 09:49:44 2025 +0200
+
+    [atomics.types.float] Align parameters in function declarations
+
+    Fixes NB US 197-316 (C++26 CD).
+
+commit 15186e75cb77cc410db4e5343bcd17dd0a3c66ac
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Nov 1 13:32:39 2025 +0800
+
+    [text], [numerics], [exec] Remove remaining `typename` in aliases
+
+commit 5d916dc6cc99a6d548942ebf85fc1551ad4b7a84
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 1 14:37:09 2025 +0100
+
+    [meta.reflection.annotation] Move to before [meta.reflection.extract]
+
+    Fixes NB US 87-156 (C++26 CD).
+
+commit 363c3a545ef54fe35499b26bcf438dbd8f84538d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 4 18:23:56 2025 +0200
+
+    [meta.reflection.array] Integrate subclause into [meta.define.static]
+
+    Fixes NB US 86-157 (C++26 CD).
+    Fixes NB US 119-180 (C++26 CD).
+    Fixes NB US 89-196 (C++26 CD).
+
+commit 7409cb04365a0a2ee19e100f663b1174aa204710
+Author: Vincent X <77327828+ckwastra@users.noreply.github.com>
+Date:   Sat Nov 1 22:14:17 2025 +0800
+
+    [temp.explicit] Fix comment in example (#8225)
+
+commit acee2087d1d72a94ebb5309459c9dae69cedfa5b
+Author: Corentin Jabot <corentinjabot@gmail.com>
+Date:   Sat Nov 1 11:21:06 2025 -0700
+
+    [class.protected] Change "naming class" to "designating class" (#8251)
+
+    The term was changed to "designating class" by P2996
+    (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2996r13.html#pnum_397),
+    and these remaining uses had not been updated accordingly.
+
+commit bbcf99022649b569ad21feb5e3a893d1e907c9a6
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Jul 26 08:05:33 2025 +0200
+
+    [dcl.ptr] Move "See also" from normative paragraph to example
+
+commit c98a54b8a1a641c74c017767092a8d65827267d8
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Jul 26 10:38:11 2025 +0200
+
+    [conv.rank] Add missing hyphen in "floating point"
+
+commit 31c4868b3e3323aa931aeb66cb83c8c1135ccdf7
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Jul 26 10:38:52 2025 +0200
+
+    [diff.cpp03.locale] Add missing hyphen in "floating point"
+
+commit dcfad093c246a09594d401340e195315db61220c
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Jul 26 10:40:00 2025 +0200
+
+    [linalg.reqs.alg] Add missing hyphen in "floating point"
+
+commit 2be3924b5b7249d6d7b085f8a1e4321e7645a54c
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Sep 23 21:45:59 2025 +0800
+
+    [meta.member] Properly introduce intended implicit conversion
+
+    Previously, the `static_assert` the example failed due to deduction
+    failure but not `false` results. This PR makes the template arguments
+    fully specified, which allows intended implicit conversion.
+
+commit 4452e28fde3c647a59fe261a1ced3906b901ca3f
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Aug 26 11:35:55 2025 -0400
+
+    [basic.def] Turn list of examples into a nute
+
+    The list of example side effects should neither be deemed normtaive nor
+    exhaustive (although we will try).  It should be demoted to a note.
+
+commit 77893aadc587df5131c3cf5d8388cbf6f7633c80
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Nov 2 09:19:46 2025 +0100
+
+    [indirect.assign] Replace incorrect "_t" with "_v" in Mandates
+
+commit cc53316dfe22765154a025462261dfd007be7a93
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Mon Nov 3 01:41:03 2025 -0400
+
+    [bit.cast] Adjust cross-reference for definition of consteval-only type (#8391)
+
+commit cedfad4418057ccc2e79eae26d22c0e567e1ce8f
+Author: Eisenwave <me@eisenwave.net>
+Date:   Mon Nov 3 15:25:41 2025 +0100
+
+    [const.wrap.class] Add constant_wrapper to index
+
+commit 749103f9d1fee0d04d4921ae7bb51c1ca47b73cd
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Jul 31 08:53:59 2025 -0400
+
+    [pre] No names in the preprocessor
+
+    The term "name" applies specifically to entities in phase 7
+    of translation.  Macros have macro names, headers are parsed
+    as *header-name*s, etc.
+
+commit 75e3e48524c21e179535177c96c4ad80fe6e7f81
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 3 14:38:09 2025 +0100
+
+    [set.difference] Fix sentence
+
+    A misapplication of P3179R9.
+
+    Fixes NB US 165-264 (C++26 CD).
+
+commit 842616437ca1a6efd0c01ba37bafee3a9fd85967
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 3 15:16:34 2025 +0100
+
+    [meta.reflection] Move examples to the end of their respective section
+
+    Fixes NB US 83-152 (C++26 NB).
+
+commit 1844b9d9d27d39f0cd2c05e1ecc738f11e2c8845
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 3 16:09:06 2025 +0100
+
+    [execution.syn] Reorder entries to match subclause order
+
+    Fixes NB US 201-322 (C++26 CD).
+
+commit 019260f1fabe96078e7b331c41485558c7ea5eee
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 3 14:46:27 2025 +0100
+
+    [const.wrap.class] Remove superfluous parameter in trailing requires clause
+
+    Fixes NB US 80-148 (C++26 CD).
+
+commit ab094f1a706c73c3da3d7bd0061a62ff632cb1ad
+Author: Eisenwave <me@eisenwave.net>
+Date:   Mon Nov 3 18:42:57 2025 +0100
+
+    [cmath.syn] Add fmaximum, fmaximum_num, fminimum, and fminimum_num to index
+
+commit ca8bf9ae97d48ed3a6024511f79d306fd2da83de
+Author: Eisenwave <me@eisenwave.net>
+Date:   Mon Nov 3 18:53:20 2025 +0100
+
+    [basic.fundamental] Use "std::" prefix consistently for library type aliases
+
+commit 726f6860757a35b1037202454f4656195964cfb0
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Nov 4 11:58:41 2025 +0800
+
+    [re.regex.general] Fix indentation for members of `basic_regex` (#8399)
+
+commit f5ab0cbe8b939538427caa7cec139ca59afc186f
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Nov 4 15:11:01 2025 +0100
+
+    [queue.defn] Remove superfluous whitespaces (#8401)
+
+commit 35696224964df56c0e01fe1c1127dc41555d6556
+Author: Eisenwave <me@eisenwave.net>
+Date:   Tue Jun 4 17:11:54 2024 +0200
+
+    [basic.indet] Convert reference to [conv.lval] into note
+
+commit acab9e553267137d6ac25e5568bafce734b70257
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Nov 4 06:31:59 2025 -1000
+
+    [container.adaptors.general] Remove using typename from expos-only alias template
+
+commit ad99d5224a03821bcff46081195fed20f0afee31
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Nov 2 20:57:23 2025 +0100
+
+    [simd] Synchronize synopsis references with subclause headings
+
+    Fixes NB US 181-294 (C++26 CD).
+
+commit 5a445cf41b9deab8412c0d6a8c61a7ff3f41645a
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Tue Nov 4 11:11:23 2025 -1000
+
+    [library] Remove references to typedef-name
+
+    Fixes NB US 62-114 (C++26 CD).
+
+commit a1e15352cc6115024fe5cf92901497a2fad92786
+Author: Damien L-G <dalg24+github@gmail.com>
+Date:   Tue Nov 4 14:42:31 2025 -1000
+
+    [atomics.ref.pointer] Do not refer to T (#8413)
+
+    Fixes NB US 195-313 (C++26 CD).
+
+commit b560873553e304cbc76d8f883f29371d97525aef
+Author: Damien L-G <dalg24@gmail.com>
+Date:   Tue Nov 4 15:56:23 2025 -1000
+
+    [atomics.syn] Simplify synopsis using "mostly freestanding" (#8411)
+
+    Mark the `<atomic>` header `// mostly freestanding`, remove all the
+    `// freestanding` comments, and add `// hosted` comments for
+    `atomic_signed_lock_free` and `atomic_unsigned_lock_free`.
+
+    Fixes NB US 191-307 (C++26 CD).
+
+commit 230067ea57ca080c89010ffac8750a114068f8e3
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Tue Nov 4 15:47:21 2025 -1000
+
+    [exec.snd.expos] Move Remarks into itemdescr
+
+commit a7b71b33710c3fc7e22c6ed169581d242b839f28
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sun Jul 27 11:23:47 2025 -0400
+
+    [dcl.inline] inline specifier is for ODR
+
+    The key use of the inline specifier since C++11, if not before,
+    has been to allow multiple declarations to satisfy the ODR rather
+    than to provide a hint that compilers routinely ignore.
+
+    This change moves but does not change wording, in order to move
+    the comment making the connection with the ODR more prominent
+    than the normative wording suggestings core transformation.
+
+    It might be desirable to demote the normative coding hint to
+    a note, but that goes beyond the remit of a simple editorial
+    chsnge.
+
+commit f731f304049a1b26a0be369ac89988910b6d52ee
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Nov 4 14:37:27 2025 -1000
+
+    [lex.pptoken] Simplify sentences with common cause
+
+commit ba59ef5f76a3d45add0f70322a1dad57109f17d5
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Nov 5 05:43:47 2025 -1000
+
+    [alg.find.first.of] Rename subclause title (#8428)
+
+    Fixes NB US 158-256 (C++26 CD).
+
+commit 6d884babd1e6dc956d795c404525248d31028e46
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Nov 5 16:17:54 2025 +0100
+
+    [expr.const] Unmark introduction of "constant expression" as definition
+
+commit f4c608518c77fad9f28a864c517c442c186037c4
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Nov 6 00:42:50 2025 +0800
+
+    [linalg.transp.layout.transpose] Fix misplaced data members of `layout_transpose::mapping` (#8423)
+
+    The intent is that _`nested-mapping_`_ and _`extents_`_ belong to
+    `layout_transpose::mapping` but not `layout_transpose`. This was a
+    mistake in the original paper P1673R13, confirmed by the author, and
+    it can also be inferred from their usages.
+
+commit c84e2cbcd13536a8083d4b3b1788f1b411a2334e
+Author: Jakub Jelinek <jakub@redhat.com>
+Date:   Wed Nov 5 14:40:13 2025 +0100
+
+    [expr.const] Use different classes for unrelated parts of the example
+
+commit 9f7a711b52aee884594eb4e01cc770ba071fffb0
+Author: Hana Dusíková <hanicka@hanicka.net>
+Date:   Thu Nov 6 03:43:58 2025 +0900
+
+    [class] removing redundant "constexpr-suitable" wording (#8108)
+
+    Constructors and destructors can't be coroutines (since P3533R2),
+    therefore they are always constexpr-suitable, and any wording
+    that states this explicitly is not needed and is removed in this change.
+
+commit ff9797db1da40fff8cf4710c845331e0b56d275b
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Tue Nov 4 16:16:37 2025 -1000
+
+    [task.class] Improve error_types wording
+
+    Fixes NB US 247-377 (C++26 CD).
+
+commit 23c89d40df26c387e5b6bd171189f18d6355b0b3
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Nov 5 22:52:36 2025 -1000
+
+    [cpp.pre] Apply unicode markup (#8410)
+
+commit 2847e62c3440302c3694db06cf4795bbcf3e8951
+Author: Braden Ganetsky <braden.ganetsky@gmail.com>
+Date:   Wed Nov 5 18:07:36 2025 -1000
+
+    [exec.bulk] Fix structured binding presentation
+
+    Fixes NB US 222-340 (C++26 CD).
+
+commit 18c441799049759c5a18afb9b89725ef3d86b977
+Author: Braden Ganetsky <braden.ganetsky@gmail.com>
+Date:   Wed Nov 5 17:54:01 2025 -1000
+
+    [meta.reflection.layout] Reverse logic in specification
+
+    Fixes NB US 106-167 (C++26 CD).
+
+commit 1e37bdba0c01da86b3012f9b4249e242103bea6a
+Author: Eisenwave <me@eisenwave.net>
+Date:   Thu Nov 6 11:48:52 2025 +0100
+
+    [meta.syn] Synchronize reflect_constant/reflect_object parameters with definition
+
+commit 50ded6933a01226babb7f15b95784012a59cb046
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 6 17:48:21 2025 +0100
+
+    [exec.run.loop] Reword references to "count" and "state" (#8307)
+
+    "Count" and "state" are locally defined notions, not actual (exposition-only) variables.
+
+    Fixes NB US 231-361 (C++26 CD).
+
+commit 7693f862e21e36076fef3c190de83751d28103c2
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 6 10:39:41 2025 -1000
+
+    [character.seq.general, time.general] Define STATICALLY-WIDEN in a better place
+
+    The facility is now used from two different places ([time] and
+    [format]) and is now better defined in the library introduction.
+
+commit 76b2c464a2d1e737ab126fb2291b7ea5d483d36e
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Wed Dec 25 16:15:29 2024 +0000
+
+    [tab:cpp17.destructible] Use the correct placeholder in requirement
+
+commit 7ba83f99fd4e060bbb607463eb994b0df49caef4
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Nov 7 01:04:07 2025 +0100
+
+    [{multimap,multiset,set}.overview] Fix typos of constructors (#8237)
+
+commit b931610d0a6116a214b120b20dfd1475593be0cd
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Feb 13 20:32:10 2025 +0000
+
+    [mdspan.layout.{left,right}pad] Fix malformed expression
+
+commit b9571b87d5de5ecdeb83a184efc7585ef6b13429
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 6 14:54:10 2025 -1000
+
+    [func.wrap.ref.class] Fix use of template parameter name "ArgTypes".
+
+    Also use a codeblock to make the code presentation a bit tidier,
+    and add descriptive nouns before symbolic references.
+
+commit a451a97aafaae586df5b4f09df6ec168fb0a31c1
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Nov 2 10:36:06 2025 +0100
+
+    [simd.alg] Avoid the word "shall" in Preconditions
+
+commit bb1af1aeb02eb9bc75e430e25b4143b54eb9fcf4
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat Jul 19 13:39:23 2025 +0200
+
+    [meta.reflection.member.queries] Add commas
+
+commit 17b6a3fa096663954a5737e8d6e0447fc4392da9
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Fri Jul 18 11:39:48 2025 -0400
+
+    [basic.link] Fix cross-reference to translation unit
+
+    Tranalation units are defined in phase 7 of translation,
+    [lex.phases] not [lex.separate].
+
+commit f65ab95e4f443cd0ab467d494513b606301acd98
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 6 16:20:43 2025 -1000
+
+    [utilities] Use "Result:" element in \itemdescrs of types to describe the type.
+
+    This replaces the use of the ad-hoc element "Type:" in three places with "Result:",
+    and adds "Result:" in other cases that didn't have an element at all.
+
+commit 35a6fb8ce7ee7dc95f8930804a23964827c889da
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Nov 7 08:26:54 2025 +0100
+
+    [intro.scope] Modernize by removing overly verbose description
+
+    Fixes NB GB01-013 (C++26 CD).
+
+commit 8d375c7cdc626c252788547f10a060f10cb82dcf
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sun Nov 9 04:44:50 2025 +0100
+
+    [exec.run.loop.members] Remove extraneous period (#8451)
+
+commit f2b0254e2dd7428f1a160a04e1d11c467eb331ca
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Nov 8 17:52:30 2025 -1000
+
+    [mdspan.sub.map.{left,right}] Fix typos: "layout_left" => "layout_right", "_rank" => "rank_"
+
+    This was a misapplication of P2642R6.
+
+    Also improves linebreaking for clarity.
+
+commit fad2722986e8cb9bee11d94fc15afb088b3fa940
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Nov 9 13:09:31 2025 +0000
+
+    [temp.names] Restore braced-init-list in definition of template-argument
+
+    It was unintentionally deleted by commit
+    e3f552ff09eb42cec8ee0590e4b8aa716996b282.
+
+commit 605dcaa51e45a9b55dedea2ab88f593dd590f6a5
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Nov 8 23:31:49 2025 +0100
+
+    [inplace.vector.modifiers] Ensure correct type of returned iterator
+
+commit 99e4ffd66b61fce502e319b4ade56df7373301ef
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Nov 10 23:44:35 2025 +0800
+
+    [dcl.pre] Fix grammatical error in lambda trailing-return-type (#8497)
+
+    This seems to be an error in P2996R13.
+
+commit 15c21a586c5bc67917256d03ce89c9a43e5a4cee
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Sun Nov 9 23:39:45 2025 -0500
+
+    [except.handle] Mark as note: exception object access via handler decl
+
+    The subject paragraph is merely an observation and is redundant as
+    normative text. Make it a note, and strike the end of the last sentence
+    as it creates an impression that the exception object cannot be observed
+    without rethrowing.
+
+commit 2a7f36abe6e93e9c5f750df000ab4ea781580d39
+Author: Luc Grosheintz <luc.grosheintz@gmail.com>
+Date:   Thu Sep 4 15:49:24 2025 +0200
+
+    [mdspan.layout.left.cons] Fix typo in precondition.
+
+    Here `other` is a layout mapping and layout mappings don't have this API
+    to access the `i`th extent. They only have `extents()` to get the
+    std::extents object.
+
+commit 8ee8d2d0292dde2ca72c300177752f4a2e4457df
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Wed Nov 12 17:01:53 2025 +0800
+
+    [cpp.predefined] Sort `__cpp_consteval` before `__cpp_constexpr` (#8504)
+
+commit 9770db7bf288ad56ae98bdabd19935decab9da9f
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Wed Nov 12 17:02:48 2025 +0800
+
+    [version.syn] Sort `__cpp_lib_format_path` before `__cpp_lib_format_ranges` (#8505)
+
+commit ccf746ffbabd5f74dece4a983cd52bd31b999f0a
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Tue Nov 11 01:07:29 2025 -0500
+
+    [class.base.init] Add "direct" for _mem-initializer-id_-named members
+
+    A _mem-initializer-id_ cannot be used to initialize a base class
+    data member from a derived class constructor; therefore, we mean
+    _direct_ non-static data member.
+
+commit e6150e3fa6d6dbbb901b4b7ccc075219d4515d5d
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Mon Nov 10 23:37:24 2025 -0500
+
+    [class.mem.general] Fix data member definition to include anonymous union members
+
+    Anonymous union members are not introduced by _member-declarator_.
+
+    Fixes cplusplus/draft#4939.
+
+commit 4d9edbf31f8ea0cb870fd0512c29756f2c4a292c
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Mon Nov 10 21:40:37 2025 -0500
+
+    [special] Add "direct" when defining "potentially constructed subobjects"
+
+    The definition has "non-static data members". Only the direct ones are
+    intended.
+
+commit 4b9d4f6a4356de8630cd8b0981c6b1960d510230
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Nov 12 19:23:00 2025 +0100
+
+    [optional.ref.assign] Add missing Returns element
+
+commit 784cc65a741dfefc95328b8bc58199bc63ea661b
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Nov 12 19:46:55 2025 +0100
+
+    [cpp.predefined] Sort __cpp_impl_reflection before __cpp_impl_three_way_comparison
+
+commit 2ab6288129c4f3708f728b0f1a492e5d72b5c821
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Nov 10 09:19:20 2025 +0800
+
+    [locale.categories] Index base classes and members of category classes
+
+    Enumerators of each unscoped enumeration type are indexed as members of
+    the enclosing class of the enumeration.
+
+commit 5e49effdce370fd445ce3218f14f37892d1f1629
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Nov 14 09:17:28 2025 +0100
+
+    [range.to.input.iterator] Move closing parentheses after @\exposid
+
+commit 19ad41dbd3446c34da01e3c5ea79ecce539ccd94
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Nov 4 19:08:45 2025 -1000
+
+    [specialized.algorithms] Remove typename after new
+
+    The `typename` keyword is not needed to identify a dependant
+    type in a `new` expression.
+
+commit 2e6b09beb01daad3d87914dfe9a0031de5816013
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Nov 8 23:05:37 2025 +0100
+
+    [cpp.predefined] Update value of __cpp_deduction_guides to 202207L
+
+commit 9ddf7e6d2937028b8c4ca99502d73d7a726ab737
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Nov 12 20:38:34 2025 +0100
+
+    [temp.arg.template] Add missing "template" when referring to template template parameters
+
+commit c097654ed3d7bf7f840c6eb8bfc10cebb74f26ea
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Nov 16 18:47:34 2025 +0100
+
+    [exec.when.all] Reverse the nesting of \exposid and \tcode for impls-for<when_all_t>::complete (#8537)
+
+commit 3e707873fffd713c9daea0bb9e6e3f3a9f5ebcd8
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Nov 16 18:50:16 2025 +0100
+
+    [atomics.types.generic.general] Replace "same_as" with "is_same_v" (#8538)
+
+commit 85128063cd29e93c28555d7a4a3b70b31c7e3337
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Nov 16 22:37:35 2025 +0100
+
+    [numerics.c.ckdint] Add cross-reference to [basic.fundamental] (#8541)
+
+commit 7eacc15f859c44eb8b8f5c955b971e95428cd07b
+Author: Eisenwave <me@eisenwave.net>
+Date:   Mon Nov 17 10:46:10 2025 +0100
+
+    [format.args] Move "Implementations should ..." part into Recommended practice paragraph
+
+commit c6da41e3ade36f51f0f8a9cbb2aebea801ceeac2
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Tue Nov 18 04:31:38 2025 +0800
+
+    [algorithm.syn] Add missing comma (#8551)
+
+commit ff706ad6a5a40831d99984e69c0245aacb9613f7
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Wed Nov 19 10:41:16 2025 +0000
+
+    [class.temporary] Change "class type" to "type"
+
+    Missed edit from P2900R14.
+
+commit 3ddbebd0eddd1b0418523e6a93864ce090d6d674
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Nov 20 22:27:47 2025 +0100
+
+    [linalg.scaled.scaledaccessor] Add scaling_factor and nested_accessor to index (#8549)
+
+commit ebd315d92ab4ddb73d6ad8b30fb131329f4b434d
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Apr 24 11:02:34 2025 +0800
+
+    [lib] Replace uses of `add_meow_t` with plain cv-qualifiers
+
+    ...except for [tab:meta.trans.cv], because the wording change for
+    `add_cv` seems a bit non-trivial, and for the return type of `as_const`,
+    because the the change would affect mangled name.
+
+commit 1175936bde2c81012c7aa3b45b3ece46c32d19ff
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Nov 29 17:21:46 2025 +0800
+
+    [container.node] Exposition-only formatting for node_handle members (#8555)
+
+    Also changes `container_node_type` and `ator_traits` to
+    `container-node-type` and `ator-traits`, respectively.
+
+    Adds missed "is `true`".
+
+commit 5b6fb19cc60d3a1b23e0124dc16a1fd69f33a40b
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sun Nov 30 19:20:43 2025 +0800
+
+    [algorithm.syn] Fix typo (#8572)
+
+commit ca1969050e652308a38d9b2990c980cf3cf654b5
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Tue Dec 2 11:13:11 2025 +0000
+
+    [expr.prim.id.unqual] Remove unused meta-variable (#8574)
+
+commit 417bf3b746747f80bfa9f0ee50547522685cf5da
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Dec 4 00:46:57 2025 +0100
+
+    [cmath.syn] Align function parameters of ellint_3 (#8581)
+
+commit 69fe27f02385f16a7a1070eb66797ee6d5795cb8
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Dec 4 15:07:48 2025 +0000
+
+    [range.slide.view] Fix names of reserve_hint overloads
+
+    Fixes #8585
+
+commit 371d28425eaa09138c3d1cdf34865d44ffc93fa3
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Dec 6 00:39:17 2025 +0700
+
+    [cpp.predefined] Tidy specification of __FILE__ and __LINE__ (#8584)
+
+    Promotes the footnotes to notes and adds cross-references.
+
+commit 940a063808899cde646274a185d7565fc0e09533
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Sun Dec 7 03:01:39 2025 -0400
+
+    [temp.constr.concept] Fix "no diagnostics is" (#8587)
+
+commit 0bb977830decd94822c024aff0e187d77c480f5b
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Wed Dec 10 20:06:58 2025 +0000
+
+    [basic.def.odr] Add punctuation (#8598)
+
+commit 62fc52e4d874d895d5e323421b54cfba1e568857
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Dec 11 21:52:45 2025 +0000
+
+    [basic.lookup.qual.general] Markup definition of "member-qualified name" (#8609)
+
+commit 8b2a7da97bb7779dbb060f7cd62dd9d596626ccd
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Dec 11 21:54:40 2025 +0000
+
+    [basic.lookup.elab] Replace "the" with "an" (#8612)
+
+commit 0bee9a0a02b3f5ed38ff30dc12f59bf378b0f5e5
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Tue Apr 1 14:44:07 2025 +0000
+
+    [temp.constr.concept] Improve phrasing of note
+
+commit 284ffb85f96822d79e89124ef77e548a3f8362fb
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Nov 17 11:29:12 2025 +0800
+
+    [string] Consistently spell return types and types of data members
+
+    Affected sections:
+    - [basic.string.general] Align both overloads of `data`
+    - [basic.string.general] Use `(const_)reference` for consistency with
+    other sequence containers
+    - [string.access] Use `(const_)reference` for consistency with other
+    sequence containers
+    - [string.view.template.general] Use `const charT*` for `data` and a
+    data member, for the consistency with `basic_string`.
+    -[string.view.access] Use `const charT*` for `data` for consistency with
+    `basic_string`
+
+commit 0fa93a34dd25859212a708bbd9b5fb4f7e5d22d9
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sun Nov 2 17:13:39 2025 -1000
+
+    [module.global.frag] Remove irrelevant note about preprocessor
+
+    [module.global.frag] is entirely part of phase 7 of translation,
+    and it makes no sense to talk of preprocessing directive in the
+    grammar term *declaration-seq*.  Strike the note rather than try
+    to turn it into something meaningful.
+
+commit 967ffd74041ba52334bbb3525485bbed0a3bd6cf
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Nov 8 22:46:28 2025 +0100
+
+    [dcl.init.general] Prevent contradiction for initialization of aggregates
+
+commit 99914bdc2d932422d6c5c5e448f8d81e35dc0e97
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Dec 13 18:21:49 2025 +0700
+
+    [cpp.cond] Keywords are not identifiers while preprocessing (#8518)
+
+commit 143f3a692399843796a005508d35096225b39146
+Author: Eisenwave <me@eisenwave.net>
+Date:   Mon Nov 17 08:32:57 2025 +0100
+
+    [numerics.c.ckdint] Remove unnecessary "cv-unqualified"
+
+commit 7acb34c3ce9cffaf30da3935acbb52c38887daea
+Author: Eisenwave <me@eisenwave.net>
+Date:   Mon Nov 17 08:33:47 2025 +0100
+
+    [charconv.syn] Remove unnecessary "cv-unqualified"
+
+commit 1efa5fec0153e3682bc3c8dc99a35281ea11bb1c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 29 11:01:59 2025 +0100
+
+    [expr.add] Simplify phrasing around ptrdiff_t and avoid redundancy
+
+commit 68ea567df58609cab0e41fa805b0cd55db37784c
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Dec 2 23:39:03 2025 +0700
+
+    [lex.literal.kinds] Strike incomplete footnote
+
+    It may be that the notion of literal in C++ and constant in C
+    were at one point close to a 1-1 mapping, but that it not
+    strictly the case any more.  C++ has user-defined literals,
+    in C string-literals are distinct from constants, and C
+    specifies enumerators as literals too.
+
+    Rather thsn clean up the footnote, or make clear that the
+    correspondance is weak, simply strike it.
+
+commit 3280bf769d88e21883e49f3fab41c93322e3a0f8
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Dec 13 18:27:17 2025 +0700
+
+    [intro.memory] Convert footnote on CHAR_BIT into note (#8577)
+
+    The information in the footnote is relevant to the main text.
+
+commit 6c8a056ee7d1fb3aabd9f96c8c9a03c8720e3c28
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Dec 13 18:28:00 2025 +0700
+
+    [lex.string] Remove unused term from the index (#8588)
+
+commit d5b9659a0e7e3fc68914e30ffb3b5528246828f2
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Dec 8 18:18:07 2025 +0000
+
+    [lex] Avoid "shall" when not stating a direct requirement
+
+commit 0598cb129f4160467502bfd7870f285d9124e642
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Dec 13 18:29:51 2025 +0700
+
+    [dcl.type.general] Strike irrelevant footnote (#8578)
+
+    The reference to the "implicit int" rule in C has been out-dated for a long time.
+
+commit 6db574b1f0df2e279ab658bfc57b6929d325ad9b
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Tue Dec 9 23:40:50 2025 +0000
+
+    [basic.scope.contract] Fix typo
+
+commit 21cc64a281ba7167d7c1c596afed63dd9f64ce80
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Tue Dec 9 23:46:38 2025 +0000
+
+    [basic.scope.param] Use "of" when referring to the containing production
+
+commit 6c240f69beeb9dc3164684c583eef03643c40abf
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Tue Dec 9 23:23:57 2025 +0000
+
+    [basic.def.odr] Fix use of undefined term
+
+    Change "function definition scope" to "function parameter scope".
+
+commit 176d615e86a9e796cf14bd6546bfd8804984ee8d
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Dec 11 14:33:03 2025 +0000
+
+    [basic.lookup.argdep] Add missing words
+
+commit a091468825ef477a9d8110085f2963306dee9cfc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Dec 14 13:27:11 2025 +0000
+
+    [meta.define.static] Reword list to produce a proper sentence.
+
+commit 165c05c9203171a12a2f6ad9afdd593b9ac21bd3
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sun Dec 14 19:31:46 2025 +0100
+
+    [version.syn] Sort __cpp_lib_initializer_list before __cpp_lib_inplace_vector
+
+commit 488b2fa35c373b0bd425087bf3658635ac9338a0
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sun Dec 14 22:21:01 2025 +0100
+
+    [mdspan.sub.extents] Fix typo
+
+commit 002e9784d3ebbf94288181573017860f1c3ce065
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Nov 4 15:07:50 2025 -1000
+
+    [lex.pptoken] Turn non-normative text into a note
+
+    The last part of this paragraph is non-normative, so turn it
+    into a note.  Also, the preceding sentence defining whitespace
+    characters is mostly unrelated to the precedingd defintion of
+    preprocessing tokens, so start a new paragraph to more clearly
+    show the comment assoication.
+
+commit c1fcb2b43946acb89857caf29c3cd7a95c568736
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Nov 4 12:36:34 2025 -1000
+
+    [lex.token] Strike mention of whitespace in phase 7
+
+    It is meaningless to talk of whitespace separating tokens
+    in phase 7 as whitespace is discarded at the end of phase 4.
+
+commit 08ab900f50fa30a511d38b1f7faa6715b2749a29
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Dec 2 23:02:35 2025 +0700
+
+    [lex.token] Strike useless footnote
+
+commit dd1c71e10912d1ee91c96d5a0a9f59df3f849863
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Wed Dec 10 11:34:16 2025 +0800
+
+    [expr.prim.id.unqual] Fix misplaced example
+
+commit d2fff2b231512a469b1f503722ad2136f116346c
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat Dec 13 19:53:04 2025 +0100
+
+    [basic.def.odr] Remove duplicate "a"
+
+commit 93914a36c1945d330a7c7d5c4488e1d10e5bbe75
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Dec 14 07:35:31 2025 +0100
+
+    [utility.intcmp] Rephrase integer type constraint of "standard or extended" as "signed or unsigned"
+
+commit 508c4f902d4c65b80b40d7fb1f764b7b18293ef3
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Tue Nov 18 09:08:21 2025 +0100
+
+    [atomics.types.int] Use the terms "character type" and "standard integer type" instead of listing each type
+
+    Revised description of atomic class template specializations.
+
+commit b37dc196a8e4feacd5f5292022bdde90f95d7c4a
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Dec 15 08:54:51 2025 +0100
+
+    [range.reverse.overview] Add indefinite article
+
+commit 8ef4e628d6da638b5a5880df11b1bf1e2185a964
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Dec 15 12:16:12 2025 +0100
+
+    [hive.operations] Fix singular/plural mismatch (#8621)
+
+commit 9a06fbfd9379224c6efb77adab77cc3f9595b63d
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Nov 4 15:48:11 2025 -1000
+
+    [lex.charset] Move reference to glyphs to appropriate place
+
+    The statement that glyphs are used to identify members of the
+    basic character set does not belong separating two sentences
+    introducing and then defining preprocessing tokens.
+
+    Also, we do not *exlusively* use glyphs for this purpose but
+    also directly call out Unicode code points too, so tone down
+    the phrasing to glyphs are *often* used to ...
+
+commit a2289f6652c4b09811dfda76b0e0fd2208c71617
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Dec 15 11:46:12 2025 +0000
+
+    [exec.bulk, exec.spawn.future] Fix escaping and comment alignment
+
+commit 37201bf548ab64a72dee297cef56a67c88326ee3
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Dec 4 11:58:20 2025 +0700
+
+    [cpp.replace.general] Promote footnote to note
+
+    We now have a paragraph where the footnote would be more
+    appropriately attached as a note.
+
+commit 20eff244639825d616061d7155967840c337582e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Dec 15 12:11:55 2025 +0000
+
+    [iterator.range] Turn long sentence listing headers into list
+
+ + diff --git a/papers/n5033.md b/papers/n5033.md new file mode 100644 index 0000000000..2067c41193 --- /dev/null +++ b/papers/n5033.md @@ -0,0 +1,2466 @@ +# N5033 Editors' Report -- Programming Languages -- C++ + +Date: 2025-12-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` + +## Acknowledgments + +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. +Special thanks to Alisdair Meredith and Jan Schultke +for drafting a lot of motion applications, +and to Andreas Krug for ongoing careful reviews. + +## New papers + + * [N5032](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5032.pdf) is the + current working draft for C++26. It replaces + [N5014](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5014.pdf). + * N5033 is this Editors' Report. + +## Motions incorporated into working draft + +### Notes on motions + +Note the unusual numbering of CWG motions. +In particular, CWG Motion 3a is not associated +with a change to the working draft. + +In LWG Motion 1, the library issue +[LWG4300](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html#4300) +had already previously been +applied [editorially](https://github.com/cplusplus/draft/commit/4b9d4f6a4356de8630cd8b0981c6b1960d510230). + +In LWG Motions 16 and 19, the resolution of +[“NB US 227-346 and US 229-347”](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html#us-227-346-and-us-229-347) +in the latter has substantial overlap with paper +[P3815R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3815r1.html) +of the former; the changes were reconciled and integrated. + +All other motions were applied cleanly. + +### Core working group polls + +CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues +except issues 1670, 2917, 2923, 3005, 3043, 3044, 3045, 3048, 3053, 3061, 3063, 3074, +3082, 3084, 3089, 3092, 3093, 3094, 3095, 3098, 3099, 3101, 3108, 3109, 3110, 3113, +3114, 3115, 3117, and 3118 in +[P3921R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) +(Core Language Working Group “ready” Issues for the November, 2025 meeting) to the C++ Working Paper. + +CWG Poll 2. Apply the proposed resolutions of issues +2917, 2923, 3005, 3043, 3044, 3045, 3048, 3053, 3061, 3063, 3074, 3082, 3084, 3089, 3092, +3093, 3094, 3095, 3098, 3099, 3101, 3108, 3109, 3110, 3113, 3114, 3115, 3117, and 3118 in +[P3921R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) +(Core Language Working Group “ready” Issues for the November, 2025 meeting) to the C++ Working Paper. + +CWG Poll 2b. Accept as Defect Reports and apply the proposed resolutions of issue 1670 in +[P3921R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) +(Core Language Working Group “ready” Issues for the November, 2025 meeting) to the C++ Working Paper. + +CWG Poll 3a. (Not relevant; poll did not pass, and did not propose a change to the working paper.) + +CWG Poll 3b. Apply the changes in +[P3920R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) +(Wording for NB comment resolution on trivial relocation) to the C++ Working Paper. +This addresses numerous ballot comments (see paper). + +CWG Poll 4. Accept as a Defect Report and apply the changes in +[P3868R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3868r1.html) +(Allow `#line` before module declarations) to the C++ Working Paper. +This addresses ballot comment US 55-102. + +CWG Poll 5. Apply the changes in +[P3684R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3684r1.pdf) +(Fix erroneous behaviour termination semantics for C++26) to the C++ Working Paper. +This addresses ballot comment GB 02-036. + +### Library working group polls + +LWG Poll 1. Apply the changes in +[P3905R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) +(C++ Standard Library Ready Issues to be moved in Kona, Nov. 2025) to the C++ working paper. + +LWG Poll 2. Apply the changes in +[P3906R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) +(C++ Standard Library Immediate Issues to be moved in Kona, Nov. 2025) to the C++ working paper. + +LWG Poll 3. Apply the changes in +[P3016R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3016r6.html) +(Resolve inconsistencies in `begin`/`end` for `valarray` and braced initializer lists) to the C++ working paper. + +LWG Poll 4. Apply the changes in +[P3567R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3567r2.html) +(`flat_meow` fixes) to the C++ working paper. + +LWG Poll 5. Apply the changes in +[P3663R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3663r3.html) +(Future-proof `submdspan_mapping`) to the C++ working paper. +This addresses ballot comments US 66-117 and PL 009. + +LWG Poll 6. Apply the changes in +[P3914R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3914r0.html) +(Assorted NB comment resolutions for Kona 2025) to the C++ working paper. +This addresses ballot comments US 160-260, US 209-332, US 228-348, US 263-396, US 265-398, US 266-399, US 112-172, and US 130-193. + +LWG Poll 7. Apply the changes in +[P3836R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3836r2.html) +(Make `optional` trivially copyable) to the C++ working paper. +This addresses ballot comment US 134-215. + +LWG Poll 8. Apply the changes in +[P3860R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3860r1.html) +(Proposed Resolution for NB Comment GB13-309 `atomic_ref` is not convertible to `atomic_ref`) +to the C++ working paper, as a Defect Report for C++20. This addresses ballot comment GB13-309. + +LWG Poll 9. Apply the changes in +[P3388R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3388r3.pdf) +(When Do You Know `connect` Doesn’t Throw?) to the C++ working paper. + +LWG Poll 10. Apply the changes in +[P3774R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3774r1.html) +(Rename `std::nontype`, and make it broadly useful) to the C++ working paper. +This addresses ballot comments FR-021-218 and FR-019-210. + +LWG Poll 11. Apply the changes in +[P3819R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3819r0.pdf) +(Remove `evaluation_exception()` from contract-violation handling for C++26) +to the C++ working paper. +This addresses ballot comments NL, US 69-125,GB 04-124. + +LWG Poll 12. Apply the changes in +[P3612R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3612r1.html) +(Harmonize proxy-reference operations (LWG 3638 and 4187)) to the C++ working paper. + +LWG Poll 13. Apply the changes in +[P3778R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3778r0.html) +(Fix for `type_order` template definition) to the C++ working paper. + +LWG Poll 14. Apply the changes in +[P1789R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1789r3.pdf) +(Library Support for Expansion Statements) to the C++ working paper. +This addresses ballot comments NC IT-002, FR 007-011-142, CZ 2-143, US 78-144. + +LWG Poll 15. Apply the changes in +[P3922R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3922r1.pdf) +(Missing deduction guide from simd::mask to simd::vec) to the C++ working paper. +This addresses ballot comment DE-287. + +LWG Poll 16. Apply the changes in +[P3815R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3815r1.html) +(Add `scope_association` concept to P3149) to the C++ working paper. +This addresses ballot comments CA-393 and FI-392. + +LWG Poll 17. Apply the changes in +[P3878R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3878r1.html) +(Standard library hardening should not use the 'observe' semantic) to the C++ working paper. +This addresses ballot comments RU-016, FR-001-014, FR-010-113, US 3-015, and US 61-112. + +LWG Poll 18. Apply the changes in +[P3887R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3887r1.pdf) +(Make `when_all` a Ronseal Algorithm) to the C++ working paper. + +LWG Poll 19. Apply the changes in +[P3923R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) +(Additional NB comment resolutions for Kona 2025) to the C++ working paper. +This addresses ballot comments AT 7-213, US 140-233, US 141-235, US 145-234, +US 147-240, US 164-203, US 126-189, US 227-346, US 229-347, US 221-339, and US 225-341. + +LWG Poll 20. Apply the changes in +[P3371R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3371r5.html) +(Fix C++26 by making the rank-1, rank-2, rank-k, and rank-2k updates consistent with the BLAS) +to the C++ working paper. This addresses ballot comment US 168-277. + +LWG Poll 21. Apply the changes in +[P3391R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3391r2.html) +(constexpr `std::format`) to the C++ working paper. +This addresses ballot comment FR 028-271 and US 167-270. + +LWG Poll 22. Apply the changes in +[P3913R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3913r1.pdf) +(Optimize for `std::optional` in range adaptors) to the C++ working paper. +This addresses ballot comment PL-011. + +## National body comment resolution + +A large number of national body comments for the C++26 Committee Draft have been +addressed in this working draft. + +### Editorial comments + +All editorial national body comments were addressed before the Kona 2025 meeting: + + * CA 083 [322d38022bb292fbdb6d668af4ecd753eb104a53](https://github.com/cplusplus/draft/commit/322d38022bb292fbdb6d668af4ecd753eb104a53) + * FR 033-335 [776bc2892e2480fb69296cd404fc4bd5136cc44a](https://github.com/cplusplus/draft/commit/776bc2892e2480fb69296cd404fc4bd5136cc44a) + * GB 001-013 [35a6fb8ce7ee7dc95f8930804a23964827c889da](https://github.com/cplusplus/draft/commit/35a6fb8ce7ee7dc95f8930804a23964827c889da) + * US 001-405 [1e54f58f5a5cf0a283b90c0db30fff76d42efb51](https://github.com/cplusplus/draft/commit/1e54f58f5a5cf0a283b90c0db30fff76d42efb51) + * US 002-404 [fde9d1f6047ed65e52483fa40162b966628162b2](https://github.com/cplusplus/draft/commit/fde9d1f6047ed65e52483fa40162b966628162b2) + * US 012-026 [e1d47e006183ef8e2c778587b5fdcf0ce6d15da6](https://github.com/cplusplus/draft/commit/e1d47e006183ef8e2c778587b5fdcf0ce6d15da6) + * US 018-035 [0c8df65ab760e827363591f95f127de98771238b](https://github.com/cplusplus/draft/commit/0c8df65ab760e827363591f95f127de98771238b) + * US 019-037 [a019163776f16b4ed4ac9b7ec22d9b8abcd9314d](https://github.com/cplusplus/draft/commit/a019163776f16b4ed4ac9b7ec22d9b8abcd9314d) + * US 022-042 [42fad0f0b26d87235bb0cf8524de3f7628150a10](https://github.com/cplusplus/draft/commit/42fad0f0b26d87235bb0cf8524de3f7628150a10) + * US 051-095 [7c31fb08d42cb48eb2a5f63ed4406aff8f1eed4a](https://github.com/cplusplus/draft/commit/7c31fb08d42cb48eb2a5f63ed4406aff8f1eed4a) + * US 062-114 [5a445cf41b9deab8412c0d6a8c61a7ff3f41645a](https://github.com/cplusplus/draft/commit/5a445cf41b9deab8412c0d6a8c61a7ff3f41645a) + * US 064-127 [19a9248ff8c5b0008f805e0353b697a5692ea354](https://github.com/cplusplus/draft/commit/19a9248ff8c5b0008f805e0353b697a5692ea354) + * US 071-128 [42129859dd633cd3f497ef9dd80b5d1dd4b35672](https://github.com/cplusplus/draft/commit/42129859dd633cd3f497ef9dd80b5d1dd4b35672) + * US 079-146 [8fc2944d469666f68b595a47b6f2f1d38547b402](https://github.com/cplusplus/draft/commit/8fc2944d469666f68b595a47b6f2f1d38547b402) + * US 080-148 [019260f1fabe96078e7b331c41485558c7ea5eee](https://github.com/cplusplus/draft/commit/019260f1fabe96078e7b331c41485558c7ea5eee) + * US 086-157 [363c3a545ef54fe35499b26bcf438dbd8f84538d](https://github.com/cplusplus/draft/commit/363c3a545ef54fe35499b26bcf438dbd8f84538d) + * US 087-156 [5d916dc6cc99a6d548942ebf85fc1551ad4b7a84](https://github.com/cplusplus/draft/commit/5d916dc6cc99a6d548942ebf85fc1551ad4b7a84) + * US 088-163 [f8d44da79bc497b8a3ab6fc3fce728e40206922a](https://github.com/cplusplus/draft/commit/f8d44da79bc497b8a3ab6fc3fce728e40206922a) + * US 089-196 363c3a545ef54fe35499b26bcf438dbd8f84538d (see US 86-157) + * US 091-198 [eb87240307c7bb80937eda95c3077e41e096550f](https://github.com/cplusplus/draft/commit/eb87240307c7bb80937eda95c3077e41e096550f) + * US 092-199 [9793e558b81c133e1237cd96ce37171f79b63245](https://github.com/cplusplus/draft/commit/9793e558b81c133e1237cd96ce37171f79b63245) + * US 094-201 [f5c6e4ef5fd303d07a0cd691913a5317164bb5d5](https://github.com/cplusplus/draft/commit/f5c6e4ef5fd303d07a0cd691913a5317164bb5d5) + * US 096-206 [c6dc1e60202fea04b1d26769479c7063b3f867d1](https://github.com/cplusplus/draft/commit/c6dc1e60202fea04b1d26769479c7063b3f867d1) + * US 101-208 [c914b3bf857daea1c30ffbb330c0a4e5a44edc70](https://github.com/cplusplus/draft/commit/c914b3bf857daea1c30ffbb330c0a4e5a44edc70) + * US 104-165 [887c88157c52a8fb4f1acc3d49b40d4c5ef9af6c](https://github.com/cplusplus/draft/commit/887c88157c52a8fb4f1acc3d49b40d4c5ef9af6c) + * US 105-166 [65236d7d5fca9ccc8f3cff2d9c248f02f1f9d5bf](https://github.com/cplusplus/draft/commit/65236d7d5fca9ccc8f3cff2d9c248f02f1f9d5bf) + * US 106-167 [18c441799049759c5a18afb9b89725ef3d86b977](https://github.com/cplusplus/draft/commit/18c441799049759c5a18afb9b89725ef3d86b977) + * US 107-168 [c82d84c417ee6c1e0407162c487a810a2baaa562](https://github.com/cplusplus/draft/commit/c82d84c417ee6c1e0407162c487a810a2baaa562) + * US 108-169 [9bd9e43f43d669d5fd353fa390818a47a42dad18](https://github.com/cplusplus/draft/commit/9bd9e43f43d669d5fd353fa390818a47a42dad18) + * US 110-171 [e70c392421cce818ae5edc0d4fde6d94184b8a4a](https://github.com/cplusplus/draft/commit/e70c392421cce818ae5edc0d4fde6d94184b8a4a) + * US 111-174 [be1585aeff253d6d87e41f08a4e617e96ac0e17a](https://github.com/cplusplus/draft/commit/be1585aeff253d6d87e41f08a4e617e96ac0e17a) + * US 113-173 [c53c1789779b1f6ccd95d0ab27aca50658830b07](https://github.com/cplusplus/draft/commit/c53c1789779b1f6ccd95d0ab27aca50658830b07) + * US 115-176 [63c59140eda9f020f1d516657d2c1ab25c5a2d2d](https://github.com/cplusplus/draft/commit/63c59140eda9f020f1d516657d2c1ab25c5a2d2d) + * US 117-178 [ffd997cb108c7b3be749ba1abb4ac727117f65ee](https://github.com/cplusplus/draft/commit/ffd997cb108c7b3be749ba1abb4ac727117f65ee) + * US 119-180 363c3a545ef54fe35499b26bcf438dbd8f84538d (see US 86-157) + * US 123-187 [9add78e448d5900d57f4e15da2f08eaceedab419](https://github.com/cplusplus/draft/commit/9add78e448d5900d57f4e15da2f08eaceedab419) + * US 156-254 [9d74d451e7ea2cf09e71f09b9e283047d713eab6](https://github.com/cplusplus/draft/commit/9d74d451e7ea2cf09e71f09b9e283047d713eab6) + * US 158-256 [ba59ef5f76a3d45add0f70322a1dad57109f17d5](https://github.com/cplusplus/draft/commit/ba59ef5f76a3d45add0f70322a1dad57109f17d5) + * US 165-264 [75e3e48524c21e179535177c96c4ad80fe6e7f81](https://github.com/cplusplus/draft/commit/75e3e48524c21e179535177c96c4ad80fe6e7f81) + * US 175-281 [45dca420c08b9ce05b58140bc0572ff65dc24a1f](https://github.com/cplusplus/draft/commit/45dca420c08b9ce05b58140bc0572ff65dc24a1f) + * US 177-284 [bab708de50b834d5144cef2d2fb0872954ca47b9](https://github.com/cplusplus/draft/commit/bab708de50b834d5144cef2d2fb0872954ca47b9) + * US 179-293 [f3778a37d4a5c40f2ecc64b6ed47e3b8548b1eb6](https://github.com/cplusplus/draft/commit/f3778a37d4a5c40f2ecc64b6ed47e3b8548b1eb6) + * US 181-294 [ad99d5224a03821bcff46081195fed20f0afee31](https://github.com/cplusplus/draft/commit/ad99d5224a03821bcff46081195fed20f0afee31) + * US 182-296 [41c80d6cb744df0c8c409d3d72228c57fbf9d6cd](https://github.com/cplusplus/draft/commit/41c80d6cb744df0c8c409d3d72228c57fbf9d6cd) + * US 183-290 [8525f9150a7fe8c63fb593b65b80b09b55f94f30](https://github.com/cplusplus/draft/commit/8525f9150a7fe8c63fb593b65b80b09b55f94f30) + * US 185-299 [597cc85b49cfed8daab129fceca2c8d78b58dc6c](https://github.com/cplusplus/draft/commit/597cc85b49cfed8daab129fceca2c8d78b58dc6c) + * US 186-300 [2dbfcc5c7a759d6fbd6c09ecbc7f4439cc4eb5f5](https://github.com/cplusplus/draft/commit/2dbfcc5c7a759d6fbd6c09ecbc7f4439cc4eb5f5) + * US 188-303 [fb46e16c6ce0d91c6bd21ca497d1823c997d1926](https://github.com/cplusplus/draft/commit/fb46e16c6ce0d91c6bd21ca497d1823c997d1926) + * US 190-305 [ca77cdb10021c757b0fbe4d83b5991ac7d935db8](https://github.com/cplusplus/draft/commit/ca77cdb10021c757b0fbe4d83b5991ac7d935db8) + * US 191-307 [b560873553e304cbc76d8f883f29371d97525aef](https://github.com/cplusplus/draft/commit/b560873553e304cbc76d8f883f29371d97525aef) + * US 192-312 [196df1a7a97c0f11286816baa22d365d202db8ad](https://github.com/cplusplus/draft/commit/196df1a7a97c0f11286816baa22d365d202db8ad) + * US 194-314 [7c829315eb135f4df6326e35974c41983dc18ffd](https://github.com/cplusplus/draft/commit/7c829315eb135f4df6326e35974c41983dc18ffd) + * US 195-313 [a1e15352cc6115024fe5cf92901497a2fad92786](https://github.com/cplusplus/draft/commit/a1e15352cc6115024fe5cf92901497a2fad92786) + * US 196-315 [7e30ea001b274cc74dc165e32e3908bd6d13a54a](https://github.com/cplusplus/draft/commit/7e30ea001b274cc74dc165e32e3908bd6d13a54a) + * US 197-316 [3b14ec1d5f19882e628bfa09b96eeaeebdb622b7](https://github.com/cplusplus/draft/commit/3b14ec1d5f19882e628bfa09b96eeaeebdb622b7) + * US 198-317 [b1949378f3174e8177890dac5fff62cc7ffdc0e3](https://github.com/cplusplus/draft/commit/b1949378f3174e8177890dac5fff62cc7ffdc0e3) + * US 199-324 [5ba4be405536256e4498086dc78e1013e7b06920](https://github.com/cplusplus/draft/commit/5ba4be405536256e4498086dc78e1013e7b06920) + * US 200-323 [47992d448b6cb6f31e78d27193853b6dd4783fb0](https://github.com/cplusplus/draft/commit/47992d448b6cb6f31e78d27193853b6dd4783fb0) + * US 201-322 [1844b9d9d27d39f0cd2c05e1ecc738f11e2c8845](https://github.com/cplusplus/draft/commit/1844b9d9d27d39f0cd2c05e1ecc738f11e2c8845) + * US 204-321 [bfcdd7250785909bc2fdd9eeb381680129ec9628](https://github.com/cplusplus/draft/commit/bfcdd7250785909bc2fdd9eeb381680129ec9628) + * US 208-333 [0b085787cb519c8904e951f5fd23e1d4df5b7682](https://github.com/cplusplus/draft/commit/0b085787cb519c8904e951f5fd23e1d4df5b7682) + * US 212-352 [969776f2676316422ae1e7c92718326efa3c357f](https://github.com/cplusplus/draft/commit/969776f2676316422ae1e7c92718326efa3c357f) + * US 216-357 [122cc4abe30c0cdc39e7f7d4d09222ddfc298292](https://github.com/cplusplus/draft/commit/122cc4abe30c0cdc39e7f7d4d09222ddfc298292) + * US 217-359 [cd66127ccb165d4d0fcfb1594475a12600986697](https://github.com/cplusplus/draft/commit/cd66127ccb165d4d0fcfb1594475a12600986697) + * US 218-349 [40c2499440d42ac93e889bb7604173f01abb50a7](https://github.com/cplusplus/draft/commit/40c2499440d42ac93e889bb7604173f01abb50a7) + * US 222-340 [2847e62c3440302c3694db06cf4795bbcf3e8951](https://github.com/cplusplus/draft/commit/2847e62c3440302c3694db06cf4795bbcf3e8951) + * US 223-343 [ae124b4ce071453365f5b89fcb815ee731fdd2f8](https://github.com/cplusplus/draft/commit/ae124b4ce071453365f5b89fcb815ee731fdd2f8) + * US 231-361 [50ded6933a01226babb7f15b95784012a59cb046](https://github.com/cplusplus/draft/commit/50ded6933a01226babb7f15b95784012a59cb046) + * US 241-371 [0bce45bb287307c828c69fee1942da0c17793a15](https://github.com/cplusplus/draft/commit/0bce45bb287307c828c69fee1942da0c17793a15) + * US 247-377 [ff9797db1da40fff8cf4710c845331e0b56d275b](https://github.com/cplusplus/draft/commit/ff9797db1da40fff8cf4710c845331e0b56d275b) + * US 248-378 [95a10a601b3e2c33713724b514b47162fefa73ef](https://github.com/cplusplus/draft/commit/95a10a601b3e2c33713724b514b47162fefa73ef) + * US 259-380 [13a5c431dde2bff1ee02fa655806ffaedfc1b70f](https://github.com/cplusplus/draft/commit/13a5c431dde2bff1ee02fa655806ffaedfc1b70f) + * US 260-390 [e7e5b69c13ce5c358065fd989d64c4253693d415](https://github.com/cplusplus/draft/commit/e7e5b69c13ce5c358065fd989d64c4253693d415) + * US 262-394 [a7e6101939985870e128b742c616e5c6da357b2b](https://github.com/cplusplus/draft/commit/a7e6101939985870e128b742c616e5c6da357b2b) + * US 264-397 [1fcd55fceb8aca33f2e4d82c577aa47e94bb0e93](https://github.com/cplusplus/draft/commit/1fcd55fceb8aca33f2e4d82c577aa47e94bb0e93) + * US 266-399 [42793d0ce36d4fe09a4c7ebdceeadef2e343fee4](https://github.com/cplusplus/draft/commit/42793d0ce36d4fe09a4c7ebdceeadef2e343fee4) + * US 269-406 [6f3ef53700441dd46c369ab9e4a14e722206ffc6](https://github.com/cplusplus/draft/commit/6f3ef53700441dd46c369ab9e4a14e722206ffc6) + +### Non-editorial comments + +The following national body comments were addressed by the motions approved at the Kona 2025 meeting: + + * AT 003-098 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * AT 004-099 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * AT 004-099 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * AT 007-213 via [LWG Poll 19](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) + * BDS 002-034 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * CA 040 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * CA 041 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * CA 045 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * CA 092 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * CA 104 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * CA 133 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * CA 136 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * CA 137 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * CA 329 via [LWG Poll 9](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3388r3.pdf) + * CA 334 via [LWG Poll 9](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3388r3.pdf) + * CA 393 via [LWG Poll 16](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3815r1.html) + * CN (write-in) via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * CZ 002-143 via [LWG Poll 14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1789r3.pdf) + * DE 285 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * DE 287 via [LWG Poll 15](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3922r1.pdf) + * DE 288 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * DE 297 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * DE 298 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * FI 392 via [LWG Poll 16](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3815r1.html) + * FR 001-014 via [LWG Poll 17](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3878r1.html) + * FR 002-025 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * FR 007-011 via [LWG Poll 14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1789r3.pdf) + * FR 010-113 via [LWG Poll 17](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3878r1.html) + * FR 019-210 via [LWG Poll 10](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3774r1.html) + * FR 021-218 via [LWG Poll 10](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3774r1.html) + * FR 028-271 via [LWG Poll 21](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3391r2.html) + * FR 032-330 via [LWG Poll 9](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3388r3.pdf) + * FR 155 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * GB 002-036 via [CWG Poll 5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3684r1.pdf) + * GB 004-124 via [LWG Poll 11](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3819r0.pdf) + * GB 013-309 via [LWG Poll 8](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3860r1.html) + * IT 002 via [LWG Poll 14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1789r3.pdf) + * NL (write-in) via [LWG Poll 11](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3819r0.pdf) + * PL 005 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * PL 009 via [LWG Poll 5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3663r3.html) + * PL 011 via [LWG Poll 22](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3913r1.pdf) + * RU 016 via [LWG Poll 17](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3878r1.html) + * US 003-015 via[LWG Poll 17](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3878r1.html) + * US 006-020 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 007-019 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 009-024 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * US 010-023 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * US 015-032 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 021-038 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 023-043 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 027-059 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 029-062 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 030-061 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 034-067 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 035-066 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 036-069 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 039-076 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 041-079 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 043-080 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 044-082 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * US 045-081 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * US 046-085 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * US 047-084 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * US 050-091 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 053-097 via [CWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) (mistakenly spelled "US 097" in P3921R0) + * US 055-102 via [CWG Poll 4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3868r1.html) + * US 060-110 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + * US 061-112 via [LWG Poll 17](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3878r1.html) + * US 065-116 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 066-117 via [LWG Poll 5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3663r3.html) + * US 069-125 via [LWG Poll 11](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3819r0.pdf) + * US 073-131 via [CWG Poll 3b](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3920r0.html) + * US 076-139 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 078-144 via [LWG Poll 14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1789r3.pdf) + * US 097-203 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 099-205 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 102-209 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 109-170 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 112-172 via [LWG Poll 6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3914r0.html) + * US 114-175 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 118-179 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 120-181 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 121-182 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 125-188 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 126-189 via [LWG Poll 19](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) + * US 127-190 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 130-193 via [LWG Poll 6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3914r0.html) + * US 134-215 via [LWG Poll 7](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3836r2.html) + * US 140-233 via [LWG Poll 19](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) + * US 141-235 via [LWG Poll 19](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) + * US 145-234 via [LWG Poll 19](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) + * US 147-240 via [LWG Poll 19](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) + * US 154-252 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 155-253 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 159-259 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 160-260 via [LWG Poll 6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3914r0.html) + * US 161-258 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 162-261 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 163-262 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 164-263 via [LWG Poll 19](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) + * US 167-270 via [LWG Poll 21](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3391r2.html) + * US 168-277 via [LWG Poll 20](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3371r5.html) + * US 169-276 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 170-278 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * US 171-274 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * US 172-275 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * US 174-282 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * US 193-311 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 206-325 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 209-332 via [LWG Poll 6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3914r0.html) + * US 211-351 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 214-355 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 215-356 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 219-350 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 220-344 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 221-339 via [LWG Poll 19](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) + * US 224-342 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 225-341 via [LWG Poll 19](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) + * US 227-346 via [LWG Poll 19](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) + * US 228-348 via [LWG Poll 6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3914r0.html) + * US 229-347 via [LWG Poll 19](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3923r0.html) + * US 230-360 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 237-369 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * US 239-367 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 240-370 via [LWG Poll 2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3906r0.html) + * US 243-376 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * US 244-375 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * US 250-389 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * US 251-388 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * US 252-387 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * US 258-381 via [LWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3905r0.html) + * US 263-396 via [LWG Poll 6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3914r0.html) + * US 265-398 via [LWG Poll 6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3914r0.html) + * US 266-399 via [LWG Poll 6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3914r0.html) + * US 267-401 via [CWG Poll 1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3921r0.html) + +## 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 N5008 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/n5014...n5032). + + commit 7ff7a571b82550f2d099ad982b010d7749ed51f7 + Author: Dmitriy Sobolev + Date: Thu Aug 14 17:45:59 2025 +0100 + + [specialized.algorithms] Fix a typo: iter_difference_t -> iter_difference_t (#8143) + + A misapplication of P3179R9. + + commit 4df4951bd456cc473643fa5d434ce5bf789f0f54 + Author: S. B. Tam + Date: Sat Aug 2 13:36:14 2025 +0800 + + [locale.operators] Qualify `collate` + + commit c4eaf7276f43642b414ba9bd01a9112b6f792ad2 + Author: Alisdair Meredith + Date: Fri Aug 1 08:36:53 2025 -0400 + + [lex.phases] Identifiers do not have linkage, names do + + commit 939c73b400a418643c2e1885137a8baea04943d8 + Author: Alisdair Meredith + Date: Thu Aug 14 15:08:44 2025 -0400 + + [lex.phases, lex.token] Provide unicode name for control characters (#7404) + + commit 8fe775ad322ed8837ec4d4bed55e6074c684930a + Author: SainoNamkho <23036788+SainoNamkho@users.noreply.github.com> + Date: Fri Aug 15 03:51:41 2025 +0800 + + [dcl.init.ref] Fix misapplication of CWG2879 (#8147) + + commit 2ad9269583a4d62765e94154c7e97624083c21fe + Author: A. Jiang + Date: Fri Aug 15 13:37:12 2025 +0800 + + [span.syn] Fix typo of `remove_cvref_t` + + commit 51a5bbae2fd449a7217d935ac069187b23fb6d22 + Author: A. Jiang + Date: Fri Aug 15 17:05:43 2025 +0800 + + [optional.optional.ref.general] Fix reference to [optional.ref.iterators] + + Currently the comment mistakenly refer to [optional.iterators], while [optional.ref.iterators] should be referred to instead. + + commit 50930e22025e115d2c24451d4ba289f302020eee + Author: Frank Birbacher + Date: Fri Aug 15 13:08:42 2025 +0200 + + [meta.reflection.queries]/4.3 Fix syntax in example (#8152) + + A misapplication of P2996R13. + + commit 6a6fb0655eeabbdf526b74e65016e0be5eb6f4b3 + Author: Frank Birbacher + Date: Fri Aug 15 13:10:17 2025 +0200 + + [meta.reflection.queries]/1 Use info return type (#8153) + + A misapplication of P2996R13. + + commit a44930586b09a269fbe5def4d9821239a23b6d6b + Author: Frank Birbacher + Date: Fri Aug 15 13:16:55 2025 +0200 + + [hive.cons] Add noexcept to move constructor (#8154) + + The synopsis specifies noexcept for this constructor (and the effects + don't invoke behavior that could throw), so the missing noexcept on the + \itemdecl looks like an oversight in P0447R28. + + commit a3bdbd11810a24fe3edc7aef9dc8ac39e796e303 + Author: Frank Birbacher + Date: Fri Aug 15 18:47:33 2025 +0200 + + [expr.const] Add splice-specifier to list of converted constant expressions (#8161) + + This is a back-reference, because [expr.splice] refers to here already. + + commit d9b6f26dd6f92de0cd4ab3cd94d3a7daa44d3021 + Author: morinmorin + Date: Mon Aug 18 20:04:47 2025 +0900 + + [back] Fix journal article entries in bibliography + + This change applies the following corrections. + - Corrects misspelling of name to R. Clint Whaley. + - Adds missing page numbers. + + commit 648267c99a7a226b3a7433335e6136f70676d8d4 + Author: Rageking8 <106309953+Rageking8@users.noreply.github.com> + Date: Sat Aug 16 18:43:40 2025 +0800 + + [rand.dist.norm.f] Fix typo + + commit d13a034038e4956e02a6ab58f56109d109fab591 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Aug 18 16:45:22 2025 +0200 + + [unord.set.overview] Add "and" at end of list (#8167) + + commit 611d2ecc07a39403311783b5862df6319447eb7f + Author: Rageking8 <106309953+Rageking8@users.noreply.github.com> + Date: Tue Aug 19 04:35:05 2025 +0800 + + [simd.syn] Remove duplicate `using simd::abs;` (#8163) + + commit 430b1b20565310bea11906ae8eabf746c0f7b8c5 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Aug 19 08:49:07 2025 +0200 + + [atomics.types.float] Fix typo + + commit 675155b5ab52d101de297a150120dccaedec2735 + Author: A. Jiang + Date: Thu Aug 21 14:58:47 2025 +0800 + + [stringbuf.members] Remove `// exposition only` from `itemdecl` (#8179) + + commit 171454e98de36de7f9f3b7dfea241be79fc96ec7 + Author: A. Jiang + Date: Thu Aug 21 13:32:14 2025 +0800 + + [locale.facet] Avoid improperly defining `explicit` + + commit 41014b4db993215816a2d855d161f7136b59a3db + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Aug 21 14:17:40 2025 +0200 + + [multiset.overview] Add "and" at end of list (#8182) + + commit 1bccf914e4ec88fd3b2dc4e54c9053f46349176f + Author: Alisdair Meredith + Date: Tue Aug 26 11:57:14 2025 -0400 + + [basic.def] Better link do defintion of declaration (#8191) + + The plain text term in this sentence refer to the definition in [basic.pre] + and not the grammar production defined in [dcl]. + + commit e593dc1a1f54d6e22179c26e246ded4e7dcf9588 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Aug 27 22:42:37 2025 +0200 + + [exec.counting.scopes.general] Fix typo (#8193) + + commit b1093176914ce5ec0be3b2e02e5ff5e3c4f5e3f6 + Author: Alisdair Meredith + Date: Thu Aug 28 12:30:14 2025 -0400 + + [basic.pre] Clarify that *declaration*s are not declarations (#8187) + + * [basic.pre] Clarify that *declaration*s are not declarations + + The grammar production _declaration_ is distinct from the term "declaration" defined in [basic.pre]. + + commit 73ba7d1d81f6ef8bf92683c9071f0c4fc8afe7ad + Author: Rageking8 + Date: Fri Aug 29 00:31:47 2025 +0800 + + [meta] Fix several typos (#8157) + + commit 0b4ceb5dc35ebc736bfeb99ae629fdb0622ddf27 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sun Aug 31 19:26:32 2025 +0200 + + [tab:meta.unary.prop] Fix punctuation (#8197) + + commit bed3aab4b763ee5077d5cab997c020e389fc8092 + Author: A. Jiang + Date: Thu Sep 11 21:16:36 2025 +0800 + + [lex.phases] Fix typo in "instantiation" (#8223) + + commit 8d0144fc2e7ee8a1b38e9a69375fdedc430ec154 + Author: Hewill Kang + Date: Mon Sep 15 15:23:18 2025 +0800 + + [func.wrap.move.class, func.wrap.copy.class] Fix singular and plural in subclause titles (#8232) + + commit ed15cb52358664ae8a5b4c1df366dd2056c144e4 + Author: EienMiku + Date: Tue Sep 16 18:43:45 2025 +0800 + + [map.overview] Fix typo of constructor of map + + commit c85cdf2d0bc4a559d4092575b70025f259a68c22 + Author: Jan Schultke + Date: Sat Sep 27 10:52:22 2025 +0200 + + [meta.reflection.define.aggregate] Replace "is_enumeration_type" with "is_enum_type" + + This fixes a wording bug in P2996R13. + + commit 020140713799934d623241627c6aaef917e5039d + Author: Luc Grosheintz + Date: Sat Sep 27 22:26:43 2025 +0200 + + [views.multidim] Fix template arguments for submdspan_extents (#8243) + + commit 82bf75bc09e4ab5781e4f9149a59a41fe4c8581e + Author: Luc Grosheintz + Date: Mon Sep 29 20:06:16 2025 +0200 + + [mdspan.sub.sub] Fix typos in submdspan effects (#8248) + + The class `mdspan` doesn't have a member `data`, it has `data_handle` + (which returns a generalized pointer). + + The `AccessorPolify::offset_policy` is a type alias and therefore needs + a preceeding `typename`. + + commit 3f8865632f916f52993f342393a016aa2d732792 + Author: Hewill Kang + Date: Tue Sep 30 04:07:15 2025 +0800 + + [simd.mask.comparison] Add missing parameter names (#8262) + + commit 9db1d3b6121e092ed89e84ba9a1e45bf2b7504fc + Author: Hewill Kang + Date: Wed Oct 1 00:07:58 2025 +0800 + + [simd.permute.mask] Fix typo (#8268) + + commit 3c0ac909441ced78a097456fbfeec1b83f2da218 + Author: Hewill Kang + Date: Wed Oct 1 00:04:57 2025 +0800 + + [stringstream.members] Add missing param + + commit f5c6e4ef5fd303d07a0cd691913a5317164bb5d5 + Author: Jens Maurer + Date: Sat Oct 4 18:58:19 2025 +0200 + + [meta.reflection.names] Fix formatting for 'N' + + Fixes NB US 94-201 (C++26 CD). + + commit c6dc1e60202fea04b1d26769479c7063b3f867d1 + Author: Jens Maurer + Date: Sat Oct 4 19:02:43 2025 +0200 + + [meta.reflection.queries] Fix typo in comment in example + + Fixes NB US 96-206 (C++26 CD). + + commit eb87240307c7bb80937eda95c3077e41e096550f + Author: Jens Maurer + Date: Sat Oct 4 18:39:29 2025 +0200 + + [meta.reflection.operators] Remove superfluous 'the' + + Fixes NB US 91-198 (C++26 CD). + + commit 7c3eb729ab66113a5ca02c90efce4ef5e944810b + Author: Jens Maurer + Date: Sat Oct 4 17:46:51 2025 +0200 + + [meta.reflection.member.queries] Remove superfluous 'of' + + Fixes NB US 103-164 (C++23 CD). + + commit 9793e558b81c133e1237cd96ce37171f79b63245 + Author: Jens Maurer + Date: Sat Oct 4 18:54:11 2025 +0200 + + [meta.reflection.operators] Fix table formatting + + Fixes NB US 92-199 (C++26 CD). + + commit 0c8df65ab760e827363591f95f127de98771238b + Author: Jens Maurer + Date: Sat Oct 4 15:32:15 2025 +0200 + + [basic.life] Remove spurious commas + + Fixes NB US 18-035 (C++26 CD). + + commit f8d44da79bc497b8a3ab6fc3fce728e40206922a + Author: Jens Maurer + Date: Sat Oct 4 17:38:08 2025 +0200 + + [meta.syn] Fix phrasing in note + + Fixes NB US 88-163 (C++26 CD). + + commit 9add78e448d5900d57f4e15da2f08eaceedab419 + Author: Jens Maurer + Date: Sat Oct 4 18:49:55 2025 +0200 + + [meta.reflection.define.aggregate] Fix declarations of name-type constructors + + Fixes NB US 123-187 (C++26 CD). + + commit 0b085787cb519c8904e951f5fd23e1d4df5b7682 + Author: Jens Maurer + Date: Sat Oct 4 22:17:27 2025 +0200 + + [exec.snd] Fix cross-references for 'impls-for' + + Fixes NB US 208-333 (C++26 CD). + + commit 47992d448b6cb6f31e78d27193853b6dd4783fb0 + Author: Jens Maurer + Date: Sat Oct 4 23:36:18 2025 +0200 + + [execution.syn] Add comments to cross-references in synopsis + + Fixes NB US 200-323 (C++26 CD). + + commit 969776f2676316422ae1e7c92718326efa3c357f + Author: Jens Maurer + Date: Sat Oct 4 23:54:24 2025 +0200 + + [exec.snd.expos] Move specification of default template argument for 'Data' + + Fixes NB US 212-352 (C++26 CD). + + commit 5ba4be405536256e4498086dc78e1013e7b06920 + Author: Jens Maurer + Date: Sat Oct 4 23:45:05 2025 +0200 + + [execution.syn] Add enable_sender to synopsis + + Fixes NB US 199-324 (C++26 CD). + + commit 40c2499440d42ac93e889bb7604173f01abb50a7 + Author: Jens Maurer + Date: Sat Oct 4 22:29:10 2025 +0200 + + [exec.write.env] De-bulletize specification of check-types + + Fixes NB US 218-349 (C++26 CD). + + commit 7c31fb08d42cb48eb2a5f63ed4406aff8f1eed4a + Author: Jens Maurer + Date: Sat Oct 4 15:43:54 2025 +0200 + + [temp.variadic] Add separate bullet for annotation-list + + Fixes NB US 51-095 (C++26 CD). + + commit 322d38022bb292fbdb6d668af4ecd753eb104a53 + Author: Jens Maurer + Date: Sat Oct 4 15:39:10 2025 +0200 + + [class.pre] Adjust phrasing around 'identifer' + + Fixes NB CA-083 (C++26 CD). + + commit be1585aeff253d6d87e41f08a4e617e96ac0e17a + Author: Jens Maurer + Date: Sun Oct 5 12:12:27 2025 +0200 + + [meta.reflection.extract] Apply code font to "U" + + Fixes NB US 111-174 (C++26 CD). + + commit 9bd9e43f43d669d5fd353fa390818a47a42dad18 + Author: Jens Maurer + Date: Sun Oct 5 12:01:45 2025 +0200 + + [meta.reflection.layout] Remove incorrect 'of' + + Fixes NB US 108-169 (C++26 CD). + + commit a7e6101939985870e128b742c616e5c6da357b2b + Author: Jens Maurer + Date: Sun Oct 5 08:23:03 2025 +0200 + + [exec.par.scheduler] Use 'has the value' for an expression + + Fixes NB US 262-394 (C++26 CD). + + commit 6f3ef53700441dd46c369ab9e4a14e722206ffc6 + Author: Jens Maurer + Date: Sun Oct 5 08:14:43 2025 +0200 + + [dcl.fct.def.replace] Add 'replaceable function' to index + + Also add a label 'term.replaceable.function' for subclause-agnostic + cross-referencing. + + Fixes NB US 269-406 (C++26 CD). + + commit 9d74d451e7ea2cf09e71f09b9e283047d713eab6 + Author: Jens Maurer + Date: Sun Oct 5 07:44:02 2025 +0200 + + [algorithms.parallel.overloads] Rename subclause title + + Fixes NB US 156-254 (C++26 CD). + + commit e70c392421cce818ae5edc0d4fde6d94184b8a4a + Author: Jens Maurer + Date: Sun Oct 5 12:18:08 2025 +0200 + + [meta.reflection.extract] Remove stray 'T is' and format 'X' in code font + + Fixes NB US 110-171 (C++26 CD). + + commit 7c829315eb135f4df6326e35974c41983dc18ffd + Author: Jens Maurer + Date: Sun Oct 5 14:14:23 2025 +0200 + + [atomics.syn,atomics.ref.pointer] Remove partial specialization atomic_ref + + A misapplication of paper P3323R1. + + Fixes NB US 194-314 (C++26 CD). + + commit 7e30ea001b274cc74dc165e32e3908bd6d13a54a + Author: Jens Maurer + Date: Sun Oct 5 14:26:06 2025 +0200 + + [atomics.types.int,atomics.types.float] Excise uses of undeclared 'T' + + Fixes NB US 196-315 (C++26 CD). + + commit 196df1a7a97c0f11286816baa22d365d202db8ad + Author: Jens Maurer + Date: Sun Oct 5 15:00:21 2025 +0200 + + [atomics.ref.generic] Avoid use of undeclared 'T' + + Fixes NB US 192-312 (C++26 CD). + + commit 13a5c431dde2bff1ee02fa655806ffaedfc1b70f + Author: Jens Maurer + Date: Sun Oct 5 09:42:48 2025 +0200 + + [task.promise] Remove trailing semicolons in comments in examples + + Fixes NB US 259-380 (C++26 CD). + + commit 0bce45bb287307c828c69fee1942da0c17793a15 + Author: Jens Maurer + Date: Sun Oct 5 11:51:29 2025 +0200 + + [exec.task.scheduler] Fix punctuation and add 'the' + + Fixes NB US 241-371 (C++26 CD). + + commit cd66127ccb165d4d0fcfb1594475a12600986697 + Author: Jens Maurer + Date: Sun Oct 5 17:54:17 2025 +0200 + + [exec.getcomplsigs] Fix misplaced \end{itemdescr} (#8301) + + Fixes NB US 217-359 (C++26 CD). + + commit 122cc4abe30c0cdc39e7f7d4d09222ddfc298292 + Author: Jens Maurer + Date: Sun Oct 5 12:49:46 2025 +0200 + + [exec.snd.expos] Amend specification for allocator-aware-forward + + Fixes NB US 216-357 (C++26 CD). + + commit 63c59140eda9f020f1d516657d2c1ab25c5a2d2d + Author: Jens Maurer + Date: Sun Oct 5 12:30:21 2025 +0200 + + [meta.reflection.substitute] Add 'in order' + + A misapplication of P2996R13. + + Fixes NB US 115-176 (C++26 CD). + + commit e2511592b653984301b7a13559c0e6e06d1243aa + Author: Jens Maurer + Date: Sun Oct 5 12:23:48 2025 +0200 + + [meta.reflection.substitute] Clarify error message in example + + Fixes US 116-177 (C++26 CD). + + commit 42793d0ce36d4fe09a4c7ebdceeadef2e343fee4 + Author: Jens Maurer + Date: Sun Oct 5 09:38:01 2025 +0200 + + [exec.sysctxrepl.psb] Make 'one of the expressions below' more explicit + + Fixes NB US 266-399 (C++26 CD). + + commit 776bc2892e2480fb69296cd404fc4bd5136cc44a + Author: Jens Maurer + Date: Sat Oct 4 19:51:24 2025 +0200 + + [exec.snd] Harmonize subclause titles + + Drop unnecessary 'std::' prefix + + Fixes NB FR-033-335 (C++26 CD). + + commit e7e5b69c13ce5c358065fd989d64c4253693d415 + Author: Jens Maurer + Date: Sun Oct 5 11:42:14 2025 +0200 + + [task.promise] Refer to parameter types of the completion signatures + + Fixes NB US 260-390 (C++26 CD). + + commit 600fe56064ee41722607e4c45d56919a1f153b87 + Author: Jens Maurer + Date: Sun Oct 5 19:59:38 2025 +0200 + + [simd.syn] Compactify presentation of gather/scatter functions + + commit bab708de50b834d5144cef2d2fb0872954ca47b9 + Author: Jens Maurer + Date: Sun Oct 5 18:55:20 2025 +0200 + + [simd.traits] Rename subclause heading to 'Type traits' + + The subclause applies to both vecs and masks. + + Fixes NB US 177-284 (C++26 CD). + + commit 597cc85b49cfed8daab129fceca2c8d78b58dc6c + Author: Jens Maurer + Date: Sun Oct 5 18:07:17 2025 +0200 + + [simd.mask.namedconv] folded into [simd.mask.conv] + + Fixes NB US 185-299 (C++26 CD). + + commit f3778a37d4a5c40f2ecc64b6ed47e3b8548b1eb6 + Author: Jens Maurer + Date: Sun Oct 5 19:12:14 2025 +0200 + + [simd.complex.access] Move into [simd.class] + + The complex accessors are member functions. + Also adjust the subclause heading to fit the new surroundings. + + Fixes NB US 179-293 (C++26 CD). + + commit 2dbfcc5c7a759d6fbd6c09ecbc7f4439cc4eb5f5 + Author: Jens Maurer + Date: Sun Oct 5 18:02:01 2025 +0200 + + [simd.mask.nonmembers] Add 'basic_mask' to subclause heading + + Fixes NB US 186-300 (C++26 CD). + + commit 95a10a601b3e2c33713724b514b47162fefa73ef + Author: Jens Maurer + Date: Sun Oct 5 11:46:40 2025 +0200 + + [task.state] Fix formatting of subclause heading + + Fixes NB US 248-378 (C++26 CD). + + commit ae124b4ce071453365f5b89fcb815ee731fdd2f8 + Author: Jens Maurer + Date: Sun Oct 5 22:37:15 2025 +0200 + + [exec.when.all] Fix spelling of 'get_stop_token_t' + + Fixes NB US 223-343 (C++26 CD). + + commit b1949378f3174e8177890dac5fff62cc7ffdc0e3 + Author: Jens Maurer + Date: Mon Oct 6 14:08:35 2025 +0200 + + [atomics.ref.pointer,atomics.types.pointer] Use 'see above' for fetch_key declaration + + Fixes NB US 198-317 (C++26 CD). + + commit bc71d74ab0b0717973cbaf28a4f1931bd42fa848 + Author: Jens Maurer + Date: Sat Oct 11 10:28:16 2025 +0200 + + [exec.cmplsig] Add 'value_types_of_t' to index (#8326) + + commit adca52baba9f75d1190cbb9cc7dc7e4c04fa7152 + Author: Alisdair Meredith + Date: Sun Oct 12 04:38:49 2025 -0400 + + [lex.phases] Move dropping whitespace to end of phase 4 (#8117) + + Move the dropping of whitespace to the end of phase 4, after preprocessing directives are deleted. + + commit e1d47e006183ef8e2c778587b5fdcf0ce6d15da6 + Author: Jan Schultke + Date: Thu Oct 16 22:27:11 2025 +0200 + + [basic.def] Remove incorrect \grammarterm formatting for "declaration" (#8337) + + Fixes NB US 12-026 (C++26 CD). + + commit fb46e16c6ce0d91c6bd21ca497d1823c997d1926 + Author: Jan Schultke + Date: Sat Oct 18 00:33:16 2025 +0200 + + [streambuf.virt.put] Replace "effects" with "affects" in footnote (#8329) + + Fixes NB US 188-303 (C++26 CD). + + commit 8fc2944d469666f68b595a47b6f2f1d38547b402 + Author: Jonathan Wakely + Date: Sat Oct 18 13:01:39 2025 +0100 + + [meta.type.synop] Remove redundant cast in constant_wrapper declaration (#8218) + + The use of `decltype(cw-fixed-value(X))` instead of just `decltype(X)` + is a workaround for a GCC bug: https://gcc.gnu.org/PR117392 + + There's no need for the standard to specify it this way. + + Fixes NB US 79-146 (C++26 CD). + + commit 05e4d8d991ec3a4d013b90c1317e9f76b68c8532 + Author: Jens Maurer + Date: Sat Oct 11 10:39:17 2025 +0200 + + [simd] Canonicalize subclause headings + + Remove parts redundant with headings of superordinate subclauses. + + commit 7fffa1fb521b9432b769e0f83d6a60c732f3cfb8 + Author: Jonathan Wakely + Date: Mon Oct 20 16:20:31 2025 +0100 + + [vector.bool.pscp] say "vector primary template" (#8351) + + Not primary vector template. + + commit c914b3bf857daea1c30ffbb330c0a4e5a44edc70 + Author: Jan Schultke + Date: Mon Oct 20 17:24:12 2025 +0200 + + [meta.reflection.access.context] Remove stray "static" in declaration of "via" (#8272) + + A misapplication of P2996R13. + + Fixes NB US 101-208 (C++26 CD). + + commit ca77cdb10021c757b0fbe4d83b5991ac7d935db8 + Author: Jonathan Wakely + Date: Mon Oct 20 16:28:59 2025 +0100 + + [fs.path.native.obs,fs.path.generic.obs] Qualify std::format (#8350) + + Fixes NB US 190-305 (C++26 CD). + + commit 29465f5bec52bbfe1d81cd17c20527c911801447 + Author: Jan Schultke + Date: Thu Oct 23 21:40:25 2025 +0200 + + [linalg.conj.conjugatedaccessor] Fix typos and constructor missing from synopsis (#8106) + + commit 0d90bd108f9cba10d206a300a64684a0244004e4 + Author: Hana Dusíková + Date: Fri Oct 24 17:13:42 2025 +0200 + + [meta] reflect_constant_array of an empty range returns const array + + commit cab90b37139473d67cba49397ff6666228ca4db3 + Author: Keith Thompson + Date: Fri Oct 24 12:20:54 2025 -0700 + + [diff.expr] Remove commentary about good practice in C (#8356) + + commit 2f53f313f5b1aac5f9547b39e78863e23ca9c047 + Author: A. Jiang + Date: Sun Oct 26 19:22:13 2025 +0800 + + [lib] Fix C23 subclause numbers in `\xrefc` and `\IsoC` (#8113) + + commit 96fa31012b50a32d96a49fa8060124bcb70e3e5a + Author: Kilian Henneberger + Date: Mon Oct 27 21:39:41 2025 +0100 + + [meta.reflection.substitute] Name correct function in comments (#8372) + + commit 3ba26a48c7a72f7ed7d17d6380457ff6f985489a + Author: Matthias Kretz + Date: Wed Oct 29 22:58:21 2025 +0100 + + [simd.math] Add missing return keywords (#8374) + + commit 512372387083cdc2d112bfba157c463220b43476 + Author: Thomas Köppe + Date: Fri Aug 1 11:16:35 2025 +0100 + + [expr.reflect] Delete sentence from "interpretation" list item that is redundant with the next item. + + The next item already describes the case where R represents a namespace. + + commit 03f0c9f631c5e2d70cfe8e8476016771cc7d9d51 + Author: Thomas Köppe + Date: Fri Aug 1 11:57:08 2025 +0100 + + [dcl.attr.grammar] Delete redundant "and no alignment-specifier". + + Now that we say "an attribute-list with no attributes", the additional + "and no alignment-specifier" is redundant. + + commit 2a9a4e3c3757ace0ec8c24ca6f8c31e77f3a8ec5 + Author: A. Jiang + Date: Thu Aug 21 09:57:22 2025 +0800 + + [expected.object.monadic] Add missing necessary `typename` + + commit 617a9f1254bb930c80ad4e5f13fb27ca4e8ded51 + Author: A. Jiang + Date: Thu Aug 21 09:57:44 2025 +0800 + + [expected.void.monadic] Add missing necessary `typename` + + commit 266cb2bc567f00797ca4d0ebc6b425f98f5167bf + Author: Alisdair Meredith + Date: Thu Aug 21 15:16:09 2025 -0400 + + [cpp.replace.general] Add a cross-reference to 'see below' + + The 'below' in 'see below' as actually five sublauses away. + Adding a cross-reference establishes the link more clearly. + + commit 262d37f0b19c91c795fd89872789ca7bcf200a42 + Author: Alisdair Meredith + Date: Thu Aug 21 15:23:38 2025 -0400 + + [lex.phases] Clarify the sequence of characters for line splicing + + commit 6d42e2f96acf42060adcb018053f562a45510671 + Author: Alisdair Meredith + Date: Thu Oct 30 08:39:52 2025 -0400 + + [basic.pre] Clarify definition of variable (#8186) + + Reorder the positive and negative terms to avoid confusion with the binding of "other than". + + commit da231804706780368a6f6becc4d45000b31c19eb + Author: Alisdair Meredith + Date: Sat Aug 23 21:47:47 2025 -0400 + + [syntax] Replace plain text with grammar terms where intended + + For the examples of X-seq and X-list forms of specifiaction, + ensure that the thing in the sequence or list is the corresponding + grammar element rather than a plain text term, as the two are not + always synonyms, notably not the case for the cited *declaration*. + + commit 1722e1f2b9ddc3b7f172b8f7503eda6e451c3012 + Author: A. Jiang + Date: Wed Jun 18 10:04:59 2025 +0800 + + [dcl.constexpr], [dcl.init.aggr] A constructor is a member function + + commit 494ddd03d3e7272727451126c264cb47ba698030 + Author: A. Jiang + Date: Wed Jun 18 10:08:50 2025 +0800 + + [expr.call], [expr.const] A constructor is a (member) function + + commit 683be0af96d1cfb1fa971cca17b10cf460445cd3 + Author: A. Jiang + Date: Wed Jun 18 10:11:23 2025 +0800 + + [temp.spec.general], [temp.inst] A member function is a function + + commit f7c7befc7f03236ca968c1003f1d65247519a51b + Author: A. Jiang + Date: Wed Jun 18 10:12:09 2025 +0800 + + [constexpr.functions] A constructor is a function + + commit 729a91c79e408b89329ecdd6345a43c31931da2d + Author: A. Jiang + Date: Wed Jun 18 10:12:51 2025 +0800 + + [pairs.pair] A constructor is a member function + + commit be930a9c8e7a6ae0e5c37bab6e741a878f046085 + Author: A. Jiang + Date: Wed Jun 18 10:15:49 2025 +0800 + + [container.reqmts], [flat.map.overview], [flat.multimap.overview], [flat.set.overview], [flat.multiset.overview] A constructor is a member function + + commit a81ecaa88443f7e23ef1dddc99a10b4b1488d21b + Author: A. Jiang + Date: Wed Jun 18 10:20:07 2025 +0800 + + [diff.cpp17.depr] A constructor is a member function + + commit d411b5731711c02cbd140ff25fc514f0ef682817 + Author: Jan Schultke + Date: Sun Feb 25 17:31:01 2024 +0100 + + [container.reqmts] Remove stray semicolon in description of expression + + commit 755202dc393ca6e9a87344ec9e810163c3b59d6b + Author: A. Jiang + Date: Tue Jul 22 09:38:31 2025 +0800 + + [conv.rank] Update and fix the reference to C23 H.4.3 + + commit 11b56197263aa8af89596e69e663de3cc873e360 + Author: A. Jiang + Date: Tue Jul 22 09:39:34 2025 +0800 + + [numerics.c] Use `\xrefc` to refer to C23 7.20 + + ... addressing the `%% TODO` comments + + commit 4917ad917b62e8065910c3c34ae1cd490747075b + Author: A. Jiang + Date: Tue Jul 22 09:40:19 2025 +0800 + + [stdbit.h.syn] Use `\xrefc` to refer to C23 7.18 + + ... addressing the `%% TODO` comments + + commit 0b6b2b0cde8b878dbbf19b7f514e99be1e23aa87 + Author: Hewill Kang + Date: Sun Jul 27 23:39:23 2025 +0800 + + [range.refinements] Fix template parameter name + + commit acb132bb75c3bedb159b26d151aae1469c68883b + Author: Thomas Köppe + Date: Thu Jul 31 16:07:43 2025 +0100 + + [expr.prim.lambda.closure] Use "incomplete" instead of "not complete". + + The former is a defined term. + + commit 7e9c2b7f29605a3f195f30ef1821a88f55dec950 + Author: Hewill Kang + Date: Fri Oct 31 01:35:27 2025 +0800 + + [const.wrap.class] Add missing namespace std (#8247) + + commit fde9d1f6047ed65e52483fa40162b966628162b2 + Author: Eisenwave + Date: Sun Oct 26 07:32:34 2025 +0100 + + [basic.scope.pdecl], [temp] Replace "expansion statement" with "expansion-statement" + Fixes NB US 2-404 (C++26 CD). + + commit 887c88157c52a8fb4f1acc3d49b40d4c5ef9af6c + Author: Jonathan Wakely + Date: Fri Oct 24 18:11:27 2025 +0100 + + [meta.reflection.layout] change 'entity' to 'construct' + + Fixes NB US 104-165 (C++26 CD). + + commit 6042d48bc8467d7f73516e045f440e3b80a0961e + Author: Alisdair Meredith + Date: Tue Oct 21 13:59:35 2025 -0400 + + [cpp.pre] Move paragraph introducing preprocessor to first + + The paragraph with no normative text that outlines the broad capabilities + of the preprocessor has slippee further down this clause as new text is added. + The most appropriate place for introductory text is the first sentence of the + introductory clause, so moved accordingly. + + commit 41c80d6cb744df0c8c409d3d72228c57fbf9d6cd + Author: Jonathan Wakely + Date: Fri Oct 17 19:19:23 2025 +0100 + + [simd.permute.static] use satisfies for satisfaction + + Fixes NB US 182-296 (C++26 CD). + + commit a019163776f16b4ed4ac9b7ec22d9b8abcd9314d + Author: Eisenwave + Date: Thu Oct 9 11:34:21 2025 +0200 + + [class.temporary] Clarify that list of contexts is exhaustive, say "temporary objects" + Fixes NB US 19-037 (C++26 CD). + + commit 45dca420c08b9ce05b58140bc0572ff65dc24a1f + Author: Eisenwave + Date: Thu Oct 9 12:07:28 2025 +0200 + + [simd.syn] Reorder declarations to match subclause order + Fixes NB US 175-281 (C++26 CD). + + commit 2c60d60528470f5c1c7e53c345a77d2b88085483 + Author: Jan Schultke + Date: Thu Oct 23 06:15:51 2025 +0200 + + [diff.expr] Include conversions involving pointers to cv void in the changes + + commit 210d61f6d4c10316975c9aa02ebeb2383b225983 + Author: Jens Maurer + Date: Sat Oct 25 18:22:16 2025 +0200 + + [dcl.init.general] Add cross-references for mandatory copy elision + + commit bfcdd7250785909bc2fdd9eeb381680129ec9628 + Author: Jens Maurer + Date: Sun Oct 5 22:25:03 2025 +0200 + + [exec.par.scheduler] Move class definition from synopsis + + Fixes NB US 204-321 (C++26 CD). + + commit c82d84c417ee6c1e0407162c487a810a2baaa562 + Author: Jens Maurer + Date: Fri Oct 31 01:44:23 2025 +0100 + + [meta.reflection.{layout, annotation}] Harmonize phrasing about complete types (#8347) + + Fixes NB US 107-168 (C++26 CD). + + commit 3de77e4c3112eaa54a7cd44ef11ba6a26bff1d00 + Author: A. Jiang + Date: Thu Aug 8 13:37:41 2024 +0800 + + [class.ctor.general] Remove a dangling paragraph and associated index + + The paragraph was made dangling by P1787R6. + + commit 8525f9150a7fe8c63fb593b65b80b09b55f94f30 + Author: Jonathan Wakely + Date: Fri Oct 17 19:20:01 2025 +0100 + + [simd.permute.mask] clarify list is in ascending order + + Fixes NB US 183-290 (C++26 CD). + + commit ffd997cb108c7b3be749ba1abb4ac727117f65ee + Author: Jonathan Wakely + Date: Fri Oct 24 17:53:32 2025 +0100 + + [meta.reflection.result] move declaration of TCls earlier + + Fixes NB US 117-178 (C++26 CD). + + commit c53c1789779b1f6ccd95d0ab27aca50658830b07 + Author: Jeff Garland + Date: Thu Oct 30 17:58:13 2025 -0700 + + [meta.reflection.extract] Remove second "constexpr if" + + Fixes NB US 113-173 (C++26 CD). + + commit 65236d7d5fca9ccc8f3cff2d9c248f02f1f9d5bf + Author: Jens Maurer + Date: Sat Oct 4 17:54:14 2025 +0200 + + [meta.reflection.layout] Fix phrasing in bulleted list + + Fixes NB US 105-166 (C++26 CD). + + commit 088768b5b613a29af165f2c99fe86e8bd918677a + Author: Jan Schultke + Date: Wed Sep 3 10:40:42 2025 +0200 + + [temp.deduct.general] Replace "nontype template argument" with "constant template argument" + + commit 19a9248ff8c5b0008f805e0353b697a5692ea354 + Author: Jens Maurer + Date: Sun Oct 26 12:53:22 2025 +0100 + + [lib] Remove superfluous `typename` in alias declarations + + Also add an automatic check. + + Fixes NB US 64-127 (C++26 CD). + + commit 1fcd55fceb8aca33f2e4d82c577aa47e94bb0e93 + Author: Jens Maurer + Date: Fri Oct 31 10:11:58 2025 +0100 + + [exec.sysctxrepl.recvproxy] Create new subclause for receiver proxies + + Fixes NB US 264-397 (C++26 CD). + + commit 42129859dd633cd3f497ef9dd80b5d1dd4b35672 + Author: Eisenwave + Date: Tue Oct 28 19:25:45 2025 +0100 + + [concept.regularinvocable], [iterator.concept.winc] Replace "annotation" with "comment" + Fixes NB US 71-128 (C++26 CD). + + commit 42fad0f0b26d87235bb0cf8524de3f7628150a10 + Author: A. Jiang + Date: Fri Oct 31 19:22:56 2025 +0800 + + [basic.fundamental] Complete examples for reflections (#8265) + + Fixes NB US 22-042 (C++26 CD). + + commit bf6acb1d651f1960f287b8d98b62b1f0092d0a30 + Author: Jonathan Wakely + Date: Fri Oct 31 12:05:49 2025 +0000 + + [meta.define.static] qualify names from namespace meta + + Within library wording we don't do ADL, only unqualified lookup (as per + [contents] p3). This means that all the metafunctions in namespace std + need to qualify names from namespace std::meta in order to find them. + + This also fixes the bug that name lookup in the Effects: of + define_static_array would find std::extent and not perform ADL to find + std::meta::extent, even if ADL was performed here. + + commit dfe8e0b2de8df3cd890351055352e742b8ad5a5f + Author: YexuanXiao + Date: Fri Oct 10 00:01:05 2025 +0800 + + [meta.type.synop] Indexing the unindexed type aliases and variable templates + + commit 69837e72cebb65063a7f63b751e2ab8d70318823 + Author: Hewill Kang + Date: Fri Oct 31 22:14:47 2025 +0800 + + [unord.multiset.overview] Add missing "typename" (#8271) + + commit 54d9b47b3fcbb42ec7c24c89a00fa64f7fe4ad4e + Author: Jan Schultke + Date: Sat Sep 27 11:06:41 2025 +0200 + + [concepts.callable.general] Replace "function objects" with "callable types" + + commit 7089fb216f5ac4afa9c6e977a31921c2a0eff714 + Author: Hewill Kang + Date: Fri Oct 31 22:30:04 2025 +0800 + + [simd.overview] Remove obsolete "noexcept" (#8250) + + The "noexcept" specifier was removed from the design by P3430R0, + but the paper omitted the corresponding change of the synopsis. + + commit 7f1926bbb287cccf27d0edccce860badbfc743b2 + Author: Jonathan Wakely + Date: Fri Sep 5 19:14:38 2025 +0100 + + [flat.map.modifiers] Remove redundancy in 'insert(sorted_unique, i, j)' + + We can specify this in terms of the overload without the `sorted_unique` + tag. That is consistent with how the equivalent functions in `flat_set` + and `flat_multiset` are specified. + + commit 13a33aca7b93142f63c68f426511291dc899032b + Author: Masaki Moriguchi (a.k.a. Michel Morin) + Date: Sat Nov 1 00:22:21 2025 +0900 + + [locale.moneypunct.virtuals] remove redundant backslash-space (#8159) + + TeX already treats a period after uppercase as an acronym (which yields normal spacing). + + commit 1ff1e63b14f530389585bcee43401619f7edc139 + Author: Jan Schultke + Date: Fri Oct 31 16:32:02 2025 +0100 + + [optional.optional.{general, ref.general}] Say "object of type optional" (#8220) + + commit daf06c9f3445bd46678dc660e55debbb6feb7d97 + Author: Hewill Kang + Date: Tue Sep 30 02:17:45 2025 +0800 + + [mdspan.accessor.aligned.overview] Remove std:: in example + + commit 4bf58f81313e940295281a58d6520f8d9af18a56 + Author: A. Jiang + Date: Mon Sep 29 10:11:17 2025 +0800 + + [filebuf.virtuals] Add missing `const` to pointer variables + + The fourth parameter of `codecvt::out` and `codecvt::in` are + `const C*&`, but _Effects_ use `C*` variables, which makes the call + ill-formed. + + The intent seems sufficient clear and we should probably use `const C*` + variables in these places. + + commit 2e003dac4f1658e3ccbfd22c4e477f7b1d0ec3f1 + Author: Jan Schultke + Date: Fri Oct 31 16:39:18 2025 +0100 + + [{hive,vector}.capacity] Move remarks from Complexity to Remarks element (#8323) + + commit 04df25f524e692e0484f04779debcbaf59e83e2d + Author: Hewill Kang + Date: Tue Oct 7 20:33:03 2025 +0800 + + [allocator.requirements.general] Add namespace std for exposition-only concept + + commit 1e54f58f5a5cf0a283b90c0db30fff76d42efb51 + Author: Jan Schultke + Date: Fri Oct 31 22:08:15 2025 +0100 + + [basic.link] Use maths font in defn of direct base class relationship (#8333) + + Fixes NB US 1-405 (C++26 CD). + + commit 3b14ec1d5f19882e628bfa09b96eeaeebdb622b7 + Author: Eisenwave + Date: Thu Oct 9 09:49:44 2025 +0200 + + [atomics.types.float] Align parameters in function declarations + + Fixes NB US 197-316 (C++26 CD). + + commit 15186e75cb77cc410db4e5343bcd17dd0a3c66ac + Author: A. Jiang + Date: Sat Nov 1 13:32:39 2025 +0800 + + [text], [numerics], [exec] Remove remaining `typename` in aliases + + commit 5d916dc6cc99a6d548942ebf85fc1551ad4b7a84 + Author: Jens Maurer + Date: Sat Nov 1 14:37:09 2025 +0100 + + [meta.reflection.annotation] Move to before [meta.reflection.extract] + + Fixes NB US 87-156 (C++26 CD). + + commit 363c3a545ef54fe35499b26bcf438dbd8f84538d + Author: Jens Maurer + Date: Sat Oct 4 18:23:56 2025 +0200 + + [meta.reflection.array] Integrate subclause into [meta.define.static] + + Fixes NB US 86-157 (C++26 CD). + Fixes NB US 119-180 (C++26 CD). + Fixes NB US 89-196 (C++26 CD). + + commit 7409cb04365a0a2ee19e100f663b1174aa204710 + Author: Vincent X <77327828+ckwastra@users.noreply.github.com> + Date: Sat Nov 1 22:14:17 2025 +0800 + + [temp.explicit] Fix comment in example (#8225) + + commit acee2087d1d72a94ebb5309459c9dae69cedfa5b + Author: Corentin Jabot + Date: Sat Nov 1 11:21:06 2025 -0700 + + [class.protected] Change "naming class" to "designating class" (#8251) + + The term was changed to "designating class" by P2996 + (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2996r13.html#pnum_397), + and these remaining uses had not been updated accordingly. + + commit bbcf99022649b569ad21feb5e3a893d1e907c9a6 + Author: Eisenwave + Date: Sat Jul 26 08:05:33 2025 +0200 + + [dcl.ptr] Move "See also" from normative paragraph to example + + commit c98a54b8a1a641c74c017767092a8d65827267d8 + Author: Eisenwave + Date: Sat Jul 26 10:38:11 2025 +0200 + + [conv.rank] Add missing hyphen in "floating point" + + commit 31c4868b3e3323aa931aeb66cb83c8c1135ccdf7 + Author: Eisenwave + Date: Sat Jul 26 10:38:52 2025 +0200 + + [diff.cpp03.locale] Add missing hyphen in "floating point" + + commit dcfad093c246a09594d401340e195315db61220c + Author: Eisenwave + Date: Sat Jul 26 10:40:00 2025 +0200 + + [linalg.reqs.alg] Add missing hyphen in "floating point" + + commit 2be3924b5b7249d6d7b085f8a1e4321e7645a54c + Author: A. Jiang + Date: Tue Sep 23 21:45:59 2025 +0800 + + [meta.member] Properly introduce intended implicit conversion + + Previously, the `static_assert` the example failed due to deduction + failure but not `false` results. This PR makes the template arguments + fully specified, which allows intended implicit conversion. + + commit 4452e28fde3c647a59fe261a1ced3906b901ca3f + Author: Alisdair Meredith + Date: Tue Aug 26 11:35:55 2025 -0400 + + [basic.def] Turn list of examples into a nute + + The list of example side effects should neither be deemed normtaive nor + exhaustive (although we will try). It should be demoted to a note. + + commit 77893aadc587df5131c3cf5d8388cbf6f7633c80 + Author: Eisenwave + Date: Sun Nov 2 09:19:46 2025 +0100 + + [indirect.assign] Replace incorrect "_t" with "_v" in Mandates + + commit cc53316dfe22765154a025462261dfd007be7a93 + Author: Hubert Tong + Date: Mon Nov 3 01:41:03 2025 -0400 + + [bit.cast] Adjust cross-reference for definition of consteval-only type (#8391) + + commit cedfad4418057ccc2e79eae26d22c0e567e1ce8f + Author: Eisenwave + Date: Mon Nov 3 15:25:41 2025 +0100 + + [const.wrap.class] Add constant_wrapper to index + + commit 749103f9d1fee0d04d4921ae7bb51c1ca47b73cd + Author: Alisdair Meredith + Date: Thu Jul 31 08:53:59 2025 -0400 + + [pre] No names in the preprocessor + + The term "name" applies specifically to entities in phase 7 + of translation. Macros have macro names, headers are parsed + as *header-name*s, etc. + + commit 75e3e48524c21e179535177c96c4ad80fe6e7f81 + Author: Jens Maurer + Date: Mon Nov 3 14:38:09 2025 +0100 + + [set.difference] Fix sentence + + A misapplication of P3179R9. + + Fixes NB US 165-264 (C++26 CD). + + commit 842616437ca1a6efd0c01ba37bafee3a9fd85967 + Author: Jens Maurer + Date: Mon Nov 3 15:16:34 2025 +0100 + + [meta.reflection] Move examples to the end of their respective section + + Fixes NB US 83-152 (C++26 NB). + + commit 1844b9d9d27d39f0cd2c05e1ecc738f11e2c8845 + Author: Jens Maurer + Date: Mon Nov 3 16:09:06 2025 +0100 + + [execution.syn] Reorder entries to match subclause order + + Fixes NB US 201-322 (C++26 CD). + + commit 019260f1fabe96078e7b331c41485558c7ea5eee + Author: Jens Maurer + Date: Mon Nov 3 14:46:27 2025 +0100 + + [const.wrap.class] Remove superfluous parameter in trailing requires clause + + Fixes NB US 80-148 (C++26 CD). + + commit ab094f1a706c73c3da3d7bd0061a62ff632cb1ad + Author: Eisenwave + Date: Mon Nov 3 18:42:57 2025 +0100 + + [cmath.syn] Add fmaximum, fmaximum_num, fminimum, and fminimum_num to index + + commit ca8bf9ae97d48ed3a6024511f79d306fd2da83de + Author: Eisenwave + Date: Mon Nov 3 18:53:20 2025 +0100 + + [basic.fundamental] Use "std::" prefix consistently for library type aliases + + commit 726f6860757a35b1037202454f4656195964cfb0 + Author: A. Jiang + Date: Tue Nov 4 11:58:41 2025 +0800 + + [re.regex.general] Fix indentation for members of `basic_regex` (#8399) + + commit f5ab0cbe8b939538427caa7cec139ca59afc186f + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Nov 4 15:11:01 2025 +0100 + + [queue.defn] Remove superfluous whitespaces (#8401) + + commit 35696224964df56c0e01fe1c1127dc41555d6556 + Author: Eisenwave + Date: Tue Jun 4 17:11:54 2024 +0200 + + [basic.indet] Convert reference to [conv.lval] into note + + commit acab9e553267137d6ac25e5568bafce734b70257 + Author: Alisdair Meredith + Date: Tue Nov 4 06:31:59 2025 -1000 + + [container.adaptors.general] Remove using typename from expos-only alias template + + commit ad99d5224a03821bcff46081195fed20f0afee31 + Author: Eisenwave + Date: Sun Nov 2 20:57:23 2025 +0100 + + [simd] Synchronize synopsis references with subclause headings + + Fixes NB US 181-294 (C++26 CD). + + commit 5a445cf41b9deab8412c0d6a8c61a7ff3f41645a + Author: timsong-cpp + Date: Tue Nov 4 11:11:23 2025 -1000 + + [library] Remove references to typedef-name + + Fixes NB US 62-114 (C++26 CD). + + commit a1e15352cc6115024fe5cf92901497a2fad92786 + Author: Damien L-G + Date: Tue Nov 4 14:42:31 2025 -1000 + + [atomics.ref.pointer] Do not refer to T (#8413) + + Fixes NB US 195-313 (C++26 CD). + + commit b560873553e304cbc76d8f883f29371d97525aef + Author: Damien L-G + Date: Tue Nov 4 15:56:23 2025 -1000 + + [atomics.syn] Simplify synopsis using "mostly freestanding" (#8411) + + Mark the `` header `// mostly freestanding`, remove all the + `// freestanding` comments, and add `// hosted` comments for + `atomic_signed_lock_free` and `atomic_unsigned_lock_free`. + + Fixes NB US 191-307 (C++26 CD). + + commit 230067ea57ca080c89010ffac8750a114068f8e3 + Author: timsong-cpp + Date: Tue Nov 4 15:47:21 2025 -1000 + + [exec.snd.expos] Move Remarks into itemdescr + + commit a7b71b33710c3fc7e22c6ed169581d242b839f28 + Author: Alisdair Meredith + Date: Sun Jul 27 11:23:47 2025 -0400 + + [dcl.inline] inline specifier is for ODR + + The key use of the inline specifier since C++11, if not before, + has been to allow multiple declarations to satisfy the ODR rather + than to provide a hint that compilers routinely ignore. + + This change moves but does not change wording, in order to move + the comment making the connection with the ODR more prominent + than the normative wording suggestings core transformation. + + It might be desirable to demote the normative coding hint to + a note, but that goes beyond the remit of a simple editorial + chsnge. + + commit f731f304049a1b26a0be369ac89988910b6d52ee + Author: Alisdair Meredith + Date: Tue Nov 4 14:37:27 2025 -1000 + + [lex.pptoken] Simplify sentences with common cause + + commit ba59ef5f76a3d45add0f70322a1dad57109f17d5 + Author: Alisdair Meredith + Date: Wed Nov 5 05:43:47 2025 -1000 + + [alg.find.first.of] Rename subclause title (#8428) + + Fixes NB US 158-256 (C++26 CD). + + commit 6d884babd1e6dc956d795c404525248d31028e46 + Author: Eisenwave + Date: Wed Nov 5 16:17:54 2025 +0100 + + [expr.const] Unmark introduction of "constant expression" as definition + + commit f4c608518c77fad9f28a864c517c442c186037c4 + Author: A. Jiang + Date: Thu Nov 6 00:42:50 2025 +0800 + + [linalg.transp.layout.transpose] Fix misplaced data members of `layout_transpose::mapping` (#8423) + + The intent is that _`nested-mapping_`_ and _`extents_`_ belong to + `layout_transpose::mapping` but not `layout_transpose`. This was a + mistake in the original paper P1673R13, confirmed by the author, and + it can also be inferred from their usages. + + commit c84e2cbcd13536a8083d4b3b1788f1b411a2334e + Author: Jakub Jelinek + Date: Wed Nov 5 14:40:13 2025 +0100 + + [expr.const] Use different classes for unrelated parts of the example + + commit 9f7a711b52aee884594eb4e01cc770ba071fffb0 + Author: Hana Dusíková + Date: Thu Nov 6 03:43:58 2025 +0900 + + [class] removing redundant "constexpr-suitable" wording (#8108) + + Constructors and destructors can't be coroutines (since P3533R2), + therefore they are always constexpr-suitable, and any wording + that states this explicitly is not needed and is removed in this change. + + commit ff9797db1da40fff8cf4710c845331e0b56d275b + Author: timsong-cpp + Date: Tue Nov 4 16:16:37 2025 -1000 + + [task.class] Improve error_types wording + + Fixes NB US 247-377 (C++26 CD). + + commit 23c89d40df26c387e5b6bd171189f18d6355b0b3 + Author: Alisdair Meredith + Date: Wed Nov 5 22:52:36 2025 -1000 + + [cpp.pre] Apply unicode markup (#8410) + + commit 2847e62c3440302c3694db06cf4795bbcf3e8951 + Author: Braden Ganetsky + Date: Wed Nov 5 18:07:36 2025 -1000 + + [exec.bulk] Fix structured binding presentation + + Fixes NB US 222-340 (C++26 CD). + + commit 18c441799049759c5a18afb9b89725ef3d86b977 + Author: Braden Ganetsky + Date: Wed Nov 5 17:54:01 2025 -1000 + + [meta.reflection.layout] Reverse logic in specification + + Fixes NB US 106-167 (C++26 CD). + + commit 1e37bdba0c01da86b3012f9b4249e242103bea6a + Author: Eisenwave + Date: Thu Nov 6 11:48:52 2025 +0100 + + [meta.syn] Synchronize reflect_constant/reflect_object parameters with definition + + commit 50ded6933a01226babb7f15b95784012a59cb046 + Author: Jens Maurer + Date: Thu Nov 6 17:48:21 2025 +0100 + + [exec.run.loop] Reword references to "count" and "state" (#8307) + + "Count" and "state" are locally defined notions, not actual (exposition-only) variables. + + Fixes NB US 231-361 (C++26 CD). + + commit 7693f862e21e36076fef3c190de83751d28103c2 + Author: Thomas Köppe + Date: Thu Nov 6 10:39:41 2025 -1000 + + [character.seq.general, time.general] Define STATICALLY-WIDEN in a better place + + The facility is now used from two different places ([time] and + [format]) and is now better defined in the library introduction. + + commit 76b2c464a2d1e737ab126fb2291b7ea5d483d36e + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Wed Dec 25 16:15:29 2024 +0000 + + [tab:cpp17.destructible] Use the correct placeholder in requirement + + commit 7ba83f99fd4e060bbb607463eb994b0df49caef4 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Nov 7 01:04:07 2025 +0100 + + [{multimap,multiset,set}.overview] Fix typos of constructors (#8237) + + commit b931610d0a6116a214b120b20dfd1475593be0cd + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Feb 13 20:32:10 2025 +0000 + + [mdspan.layout.{left,right}pad] Fix malformed expression + + commit b9571b87d5de5ecdeb83a184efc7585ef6b13429 + Author: Thomas Köppe + Date: Thu Nov 6 14:54:10 2025 -1000 + + [func.wrap.ref.class] Fix use of template parameter name "ArgTypes". + + Also use a codeblock to make the code presentation a bit tidier, + and add descriptive nouns before symbolic references. + + commit a451a97aafaae586df5b4f09df6ec168fb0a31c1 + Author: Eisenwave + Date: Sun Nov 2 10:36:06 2025 +0100 + + [simd.alg] Avoid the word "shall" in Preconditions + + commit bb1af1aeb02eb9bc75e430e25b4143b54eb9fcf4 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat Jul 19 13:39:23 2025 +0200 + + [meta.reflection.member.queries] Add commas + + commit 17b6a3fa096663954a5737e8d6e0447fc4392da9 + Author: Alisdair Meredith + Date: Fri Jul 18 11:39:48 2025 -0400 + + [basic.link] Fix cross-reference to translation unit + + Tranalation units are defined in phase 7 of translation, + [lex.phases] not [lex.separate]. + + commit f65ab95e4f443cd0ab467d494513b606301acd98 + Author: Thomas Köppe + Date: Thu Nov 6 16:20:43 2025 -1000 + + [utilities] Use "Result:" element in \itemdescrs of types to describe the type. + + This replaces the use of the ad-hoc element "Type:" in three places with "Result:", + and adds "Result:" in other cases that didn't have an element at all. + + commit 35a6fb8ce7ee7dc95f8930804a23964827c889da + Author: Jens Maurer + Date: Fri Nov 7 08:26:54 2025 +0100 + + [intro.scope] Modernize by removing overly verbose description + + Fixes NB GB01-013 (C++26 CD). + + commit 8d375c7cdc626c252788547f10a060f10cb82dcf + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sun Nov 9 04:44:50 2025 +0100 + + [exec.run.loop.members] Remove extraneous period (#8451) + + commit f2b0254e2dd7428f1a160a04e1d11c467eb331ca + Author: Thomas Köppe + Date: Sat Nov 8 17:52:30 2025 -1000 + + [mdspan.sub.map.{left,right}] Fix typos: "layout_left" => "layout_right", "_rank" => "rank_" + + This was a misapplication of P2642R6. + + Also improves linebreaking for clarity. + + commit fad2722986e8cb9bee11d94fc15afb088b3fa940 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Nov 9 13:09:31 2025 +0000 + + [temp.names] Restore braced-init-list in definition of template-argument + + It was unintentionally deleted by commit + e3f552ff09eb42cec8ee0590e4b8aa716996b282. + + commit 605dcaa51e45a9b55dedea2ab88f593dd590f6a5 + Author: Eisenwave + Date: Sat Nov 8 23:31:49 2025 +0100 + + [inplace.vector.modifiers] Ensure correct type of returned iterator + + commit 99e4ffd66b61fce502e319b4ade56df7373301ef + Author: A. Jiang + Date: Mon Nov 10 23:44:35 2025 +0800 + + [dcl.pre] Fix grammatical error in lambda trailing-return-type (#8497) + + This seems to be an error in P2996R13. + + commit 15c21a586c5bc67917256d03ce89c9a43e5a4cee + Author: Hubert Tong + Date: Sun Nov 9 23:39:45 2025 -0500 + + [except.handle] Mark as note: exception object access via handler decl + + The subject paragraph is merely an observation and is redundant as + normative text. Make it a note, and strike the end of the last sentence + as it creates an impression that the exception object cannot be observed + without rethrowing. + + commit 2a7f36abe6e93e9c5f750df000ab4ea781580d39 + Author: Luc Grosheintz + Date: Thu Sep 4 15:49:24 2025 +0200 + + [mdspan.layout.left.cons] Fix typo in precondition. + + Here `other` is a layout mapping and layout mappings don't have this API + to access the `i`th extent. They only have `extents()` to get the + std::extents object. + + commit 8ee8d2d0292dde2ca72c300177752f4a2e4457df + Author: S. B. Tam + Date: Wed Nov 12 17:01:53 2025 +0800 + + [cpp.predefined] Sort `__cpp_consteval` before `__cpp_constexpr` (#8504) + + commit 9770db7bf288ad56ae98bdabd19935decab9da9f + Author: S. B. Tam + Date: Wed Nov 12 17:02:48 2025 +0800 + + [version.syn] Sort `__cpp_lib_format_path` before `__cpp_lib_format_ranges` (#8505) + + commit ccf746ffbabd5f74dece4a983cd52bd31b999f0a + Author: Hubert Tong + Date: Tue Nov 11 01:07:29 2025 -0500 + + [class.base.init] Add "direct" for _mem-initializer-id_-named members + + A _mem-initializer-id_ cannot be used to initialize a base class + data member from a derived class constructor; therefore, we mean + _direct_ non-static data member. + + commit e6150e3fa6d6dbbb901b4b7ccc075219d4515d5d + Author: Hubert Tong + Date: Mon Nov 10 23:37:24 2025 -0500 + + [class.mem.general] Fix data member definition to include anonymous union members + + Anonymous union members are not introduced by _member-declarator_. + + Fixes cplusplus/draft#4939. + + commit 4d9edbf31f8ea0cb870fd0512c29756f2c4a292c + Author: Hubert Tong + Date: Mon Nov 10 21:40:37 2025 -0500 + + [special] Add "direct" when defining "potentially constructed subobjects" + + The definition has "non-static data members". Only the direct ones are + intended. + + commit 4b9d4f6a4356de8630cd8b0981c6b1960d510230 + Author: Eisenwave + Date: Wed Nov 12 19:23:00 2025 +0100 + + [optional.ref.assign] Add missing Returns element + + commit 784cc65a741dfefc95328b8bc58199bc63ea661b + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Nov 12 19:46:55 2025 +0100 + + [cpp.predefined] Sort __cpp_impl_reflection before __cpp_impl_three_way_comparison + + commit 2ab6288129c4f3708f728b0f1a492e5d72b5c821 + Author: A. Jiang + Date: Mon Nov 10 09:19:20 2025 +0800 + + [locale.categories] Index base classes and members of category classes + + Enumerators of each unscoped enumeration type are indexed as members of + the enclosing class of the enumeration. + + commit 5e49effdce370fd445ce3218f14f37892d1f1629 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Nov 14 09:17:28 2025 +0100 + + [range.to.input.iterator] Move closing parentheses after @\exposid + + commit 19ad41dbd3446c34da01e3c5ea79ecce539ccd94 + Author: Alisdair Meredith + Date: Tue Nov 4 19:08:45 2025 -1000 + + [specialized.algorithms] Remove typename after new + + The `typename` keyword is not needed to identify a dependant + type in a `new` expression. + + commit 2e6b09beb01daad3d87914dfe9a0031de5816013 + Author: Eisenwave + Date: Sat Nov 8 23:05:37 2025 +0100 + + [cpp.predefined] Update value of __cpp_deduction_guides to 202207L + + commit 9ddf7e6d2937028b8c4ca99502d73d7a726ab737 + Author: Eisenwave + Date: Wed Nov 12 20:38:34 2025 +0100 + + [temp.arg.template] Add missing "template" when referring to template template parameters + + commit c097654ed3d7bf7f840c6eb8bfc10cebb74f26ea + Author: Jan Schultke + Date: Sun Nov 16 18:47:34 2025 +0100 + + [exec.when.all] Reverse the nesting of \exposid and \tcode for impls-for::complete (#8537) + + commit 3e707873fffd713c9daea0bb9e6e3f3a9f5ebcd8 + Author: Jan Schultke + Date: Sun Nov 16 18:50:16 2025 +0100 + + [atomics.types.generic.general] Replace "same_as" with "is_same_v" (#8538) + + commit 85128063cd29e93c28555d7a4a3b70b31c7e3337 + Author: Jan Schultke + Date: Sun Nov 16 22:37:35 2025 +0100 + + [numerics.c.ckdint] Add cross-reference to [basic.fundamental] (#8541) + + commit 7eacc15f859c44eb8b8f5c955b971e95428cd07b + Author: Eisenwave + Date: Mon Nov 17 10:46:10 2025 +0100 + + [format.args] Move "Implementations should ..." part into Recommended practice paragraph + + commit c6da41e3ade36f51f0f8a9cbb2aebea801ceeac2 + Author: S. B. Tam + Date: Tue Nov 18 04:31:38 2025 +0800 + + [algorithm.syn] Add missing comma (#8551) + + commit ff706ad6a5a40831d99984e69c0245aacb9613f7 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Wed Nov 19 10:41:16 2025 +0000 + + [class.temporary] Change "class type" to "type" + + Missed edit from P2900R14. + + commit 3ddbebd0eddd1b0418523e6a93864ce090d6d674 + Author: Jan Schultke + Date: Thu Nov 20 22:27:47 2025 +0100 + + [linalg.scaled.scaledaccessor] Add scaling_factor and nested_accessor to index (#8549) + + commit ebd315d92ab4ddb73d6ad8b30fb131329f4b434d + Author: A. Jiang + Date: Thu Apr 24 11:02:34 2025 +0800 + + [lib] Replace uses of `add_meow_t` with plain cv-qualifiers + + ...except for [tab:meta.trans.cv], because the wording change for + `add_cv` seems a bit non-trivial, and for the return type of `as_const`, + because the the change would affect mangled name. + + commit 1175936bde2c81012c7aa3b45b3ece46c32d19ff + Author: A. Jiang + Date: Sat Nov 29 17:21:46 2025 +0800 + + [container.node] Exposition-only formatting for node_handle members (#8555) + + Also changes `container_node_type` and `ator_traits` to + `container-node-type` and `ator-traits`, respectively. + + Adds missed "is `true`". + + commit 5b6fb19cc60d3a1b23e0124dc16a1fd69f33a40b + Author: S. B. Tam + Date: Sun Nov 30 19:20:43 2025 +0800 + + [algorithm.syn] Fix typo (#8572) + + commit ca1969050e652308a38d9b2990c980cf3cf654b5 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Tue Dec 2 11:13:11 2025 +0000 + + [expr.prim.id.unqual] Remove unused meta-variable (#8574) + + commit 417bf3b746747f80bfa9f0ee50547522685cf5da + Author: Jan Schultke + Date: Thu Dec 4 00:46:57 2025 +0100 + + [cmath.syn] Align function parameters of ellint_3 (#8581) + + commit 69fe27f02385f16a7a1070eb66797ee6d5795cb8 + Author: Jonathan Wakely + Date: Thu Dec 4 15:07:48 2025 +0000 + + [range.slide.view] Fix names of reserve_hint overloads + + Fixes #8585 + + commit 371d28425eaa09138c3d1cdf34865d44ffc93fa3 + Author: Alisdair Meredith + Date: Sat Dec 6 00:39:17 2025 +0700 + + [cpp.predefined] Tidy specification of __FILE__ and __LINE__ (#8584) + + Promotes the footnotes to notes and adds cross-references. + + commit 940a063808899cde646274a185d7565fc0e09533 + Author: Hubert Tong + Date: Sun Dec 7 03:01:39 2025 -0400 + + [temp.constr.concept] Fix "no diagnostics is" (#8587) + + commit 0bb977830decd94822c024aff0e187d77c480f5b + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Wed Dec 10 20:06:58 2025 +0000 + + [basic.def.odr] Add punctuation (#8598) + + commit 62fc52e4d874d895d5e323421b54cfba1e568857 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Dec 11 21:52:45 2025 +0000 + + [basic.lookup.qual.general] Markup definition of "member-qualified name" (#8609) + + commit 8b2a7da97bb7779dbb060f7cd62dd9d596626ccd + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Dec 11 21:54:40 2025 +0000 + + [basic.lookup.elab] Replace "the" with "an" (#8612) + + commit 0bee9a0a02b3f5ed38ff30dc12f59bf378b0f5e5 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Tue Apr 1 14:44:07 2025 +0000 + + [temp.constr.concept] Improve phrasing of note + + commit 284ffb85f96822d79e89124ef77e548a3f8362fb + Author: A. Jiang + Date: Mon Nov 17 11:29:12 2025 +0800 + + [string] Consistently spell return types and types of data members + + Affected sections: + - [basic.string.general] Align both overloads of `data` + - [basic.string.general] Use `(const_)reference` for consistency with + other sequence containers + - [string.access] Use `(const_)reference` for consistency with other + sequence containers + - [string.view.template.general] Use `const charT*` for `data` and a + data member, for the consistency with `basic_string`. + -[string.view.access] Use `const charT*` for `data` for consistency with + `basic_string` + + commit 0fa93a34dd25859212a708bbd9b5fb4f7e5d22d9 + Author: Alisdair Meredith + Date: Sun Nov 2 17:13:39 2025 -1000 + + [module.global.frag] Remove irrelevant note about preprocessor + + [module.global.frag] is entirely part of phase 7 of translation, + and it makes no sense to talk of preprocessing directive in the + grammar term *declaration-seq*. Strike the note rather than try + to turn it into something meaningful. + + commit 967ffd74041ba52334bbb3525485bbed0a3bd6cf + Author: Eisenwave + Date: Sat Nov 8 22:46:28 2025 +0100 + + [dcl.init.general] Prevent contradiction for initialization of aggregates + + commit 99914bdc2d932422d6c5c5e448f8d81e35dc0e97 + Author: Alisdair Meredith + Date: Sat Dec 13 18:21:49 2025 +0700 + + [cpp.cond] Keywords are not identifiers while preprocessing (#8518) + + commit 143f3a692399843796a005508d35096225b39146 + Author: Eisenwave + Date: Mon Nov 17 08:32:57 2025 +0100 + + [numerics.c.ckdint] Remove unnecessary "cv-unqualified" + + commit 7acb34c3ce9cffaf30da3935acbb52c38887daea + Author: Eisenwave + Date: Mon Nov 17 08:33:47 2025 +0100 + + [charconv.syn] Remove unnecessary "cv-unqualified" + + commit 1efa5fec0153e3682bc3c8dc99a35281ea11bb1c + Author: Jens Maurer + Date: Sat Nov 29 11:01:59 2025 +0100 + + [expr.add] Simplify phrasing around ptrdiff_t and avoid redundancy + + commit 68ea567df58609cab0e41fa805b0cd55db37784c + Author: Alisdair Meredith + Date: Tue Dec 2 23:39:03 2025 +0700 + + [lex.literal.kinds] Strike incomplete footnote + + It may be that the notion of literal in C++ and constant in C + were at one point close to a 1-1 mapping, but that it not + strictly the case any more. C++ has user-defined literals, + in C string-literals are distinct from constants, and C + specifies enumerators as literals too. + + Rather thsn clean up the footnote, or make clear that the + correspondance is weak, simply strike it. + + commit 3280bf769d88e21883e49f3fab41c93322e3a0f8 + Author: Alisdair Meredith + Date: Sat Dec 13 18:27:17 2025 +0700 + + [intro.memory] Convert footnote on CHAR_BIT into note (#8577) + + The information in the footnote is relevant to the main text. + + commit 6c8a056ee7d1fb3aabd9f96c8c9a03c8720e3c28 + Author: Alisdair Meredith + Date: Sat Dec 13 18:28:00 2025 +0700 + + [lex.string] Remove unused term from the index (#8588) + + commit d5b9659a0e7e3fc68914e30ffb3b5528246828f2 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Dec 8 18:18:07 2025 +0000 + + [lex] Avoid "shall" when not stating a direct requirement + + commit 0598cb129f4160467502bfd7870f285d9124e642 + Author: Alisdair Meredith + Date: Sat Dec 13 18:29:51 2025 +0700 + + [dcl.type.general] Strike irrelevant footnote (#8578) + + The reference to the "implicit int" rule in C has been out-dated for a long time. + + commit 6db574b1f0df2e279ab658bfc57b6929d325ad9b + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Tue Dec 9 23:40:50 2025 +0000 + + [basic.scope.contract] Fix typo + + commit 21cc64a281ba7167d7c1c596afed63dd9f64ce80 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Tue Dec 9 23:46:38 2025 +0000 + + [basic.scope.param] Use "of" when referring to the containing production + + commit 6c240f69beeb9dc3164684c583eef03643c40abf + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Tue Dec 9 23:23:57 2025 +0000 + + [basic.def.odr] Fix use of undefined term + + Change "function definition scope" to "function parameter scope". + + commit 176d615e86a9e796cf14bd6546bfd8804984ee8d + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Dec 11 14:33:03 2025 +0000 + + [basic.lookup.argdep] Add missing words + + commit a091468825ef477a9d8110085f2963306dee9cfc + Author: Thomas Köppe + Date: Sun Dec 14 13:27:11 2025 +0000 + + [meta.define.static] Reword list to produce a proper sentence. + + commit 165c05c9203171a12a2f6ad9afdd593b9ac21bd3 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sun Dec 14 19:31:46 2025 +0100 + + [version.syn] Sort __cpp_lib_initializer_list before __cpp_lib_inplace_vector + + commit 488b2fa35c373b0bd425087bf3658635ac9338a0 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sun Dec 14 22:21:01 2025 +0100 + + [mdspan.sub.extents] Fix typo + + commit 002e9784d3ebbf94288181573017860f1c3ce065 + Author: Alisdair Meredith + Date: Tue Nov 4 15:07:50 2025 -1000 + + [lex.pptoken] Turn non-normative text into a note + + The last part of this paragraph is non-normative, so turn it + into a note. Also, the preceding sentence defining whitespace + characters is mostly unrelated to the precedingd defintion of + preprocessing tokens, so start a new paragraph to more clearly + show the comment assoication. + + commit c1fcb2b43946acb89857caf29c3cd7a95c568736 + Author: Alisdair Meredith + Date: Tue Nov 4 12:36:34 2025 -1000 + + [lex.token] Strike mention of whitespace in phase 7 + + It is meaningless to talk of whitespace separating tokens + in phase 7 as whitespace is discarded at the end of phase 4. + + commit 08ab900f50fa30a511d38b1f7faa6715b2749a29 + Author: Alisdair Meredith + Date: Tue Dec 2 23:02:35 2025 +0700 + + [lex.token] Strike useless footnote + + commit dd1c71e10912d1ee91c96d5a0a9f59df3f849863 + Author: S. B. Tam + Date: Wed Dec 10 11:34:16 2025 +0800 + + [expr.prim.id.unqual] Fix misplaced example + + commit d2fff2b231512a469b1f503722ad2136f116346c + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat Dec 13 19:53:04 2025 +0100 + + [basic.def.odr] Remove duplicate "a" + + commit 93914a36c1945d330a7c7d5c4488e1d10e5bbe75 + Author: Jan Schultke + Date: Sun Dec 14 07:35:31 2025 +0100 + + [utility.intcmp] Rephrase integer type constraint of "standard or extended" as "signed or unsigned" + + commit 508c4f902d4c65b80b40d7fb1f764b7b18293ef3 + Author: Jan Schultke + Date: Tue Nov 18 09:08:21 2025 +0100 + + [atomics.types.int] Use the terms "character type" and "standard integer type" instead of listing each type + + Revised description of atomic class template specializations. + + commit b37dc196a8e4feacd5f5292022bdde90f95d7c4a + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Dec 15 08:54:51 2025 +0100 + + [range.reverse.overview] Add indefinite article + + commit 8ef4e628d6da638b5a5880df11b1bf1e2185a964 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Dec 15 12:16:12 2025 +0100 + + [hive.operations] Fix singular/plural mismatch (#8621) + + commit 9a06fbfd9379224c6efb77adab77cc3f9595b63d + Author: Alisdair Meredith + Date: Tue Nov 4 15:48:11 2025 -1000 + + [lex.charset] Move reference to glyphs to appropriate place + + The statement that glyphs are used to identify members of the + basic character set does not belong separating two sentences + introducing and then defining preprocessing tokens. + + Also, we do not *exlusively* use glyphs for this purpose but + also directly call out Unicode code points too, so tone down + the phrasing to glyphs are *often* used to ... + + commit a2289f6652c4b09811dfda76b0e0fd2208c71617 + Author: Thomas Köppe + Date: Mon Dec 15 11:46:12 2025 +0000 + + [exec.bulk, exec.spawn.future] Fix escaping and comment alignment + + commit 37201bf548ab64a72dee297cef56a67c88326ee3 + Author: Alisdair Meredith + Date: Thu Dec 4 11:58:20 2025 +0700 + + [cpp.replace.general] Promote footnote to note + + We now have a paragraph where the footnote would be more + appropriately attached as a note. + + commit 20eff244639825d616061d7155967840c337582e + Author: Thomas Köppe + Date: Mon Dec 15 12:11:55 2025 +0000 + + [iterator.range] Turn long sentence listing headers into list diff --git a/papers/n5047.html b/papers/n5047.html new file mode 100644 index 0000000000..6bb2b38ca2 --- /dev/null +++ b/papers/n5047.html @@ -0,0 +1,1787 @@ + + + + + +N5047 + + +

N5047 Editors’ Report:
Programming Languages — C++

+ +

Date: 2026-05-12

+ +

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

+ +

Acknowledgments

+ +

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. +Special thanks to Jan Schultke for drafting a lot of motion applications, +to Andreas Krug for ongoing careful reviews, +and to Daniel Krügler for an exceptionally thorough review +that spotted many mistakes in the motion applications.

+ +

New papers

+ +
    +
  • N5046 is the +current working draft for C++26. It replaces +N5032.
  • +
  • N5047 is this Editors' Report.
  • +
+ + +

The Draft International Standard that will be sent for the ISO ballot has not +yet been completed, but will include the changes from N5046. As usual, since +N5046 has not yet been approved in a WG21 meeting, it is instead being reviewed +by an editorial review committee that was selected in Croydon, as per WG21 +Poll 3. N5046 includes some, but not all of the review committee’s feedback.

+ +

Motions incorporated into working draft

+ +

Notes on motions

+ +

All motions were applied cleanly.

+ +

Some reconciliation was needed among LWG motions (in particular starting at +motion 28), but paper authors and LWG had already included relevant merging +instructions in the papers.

+ +

The wording of P3980R1 from LWG Motion 29 has been reconciled with intervening +changes from issues LWG 4339 and LWG 4347 from LWG Motion 2.

+ +

Core working group polls

+ +

CWG Poll 1 does not change the working draft.

+ +

CWG Poll 2. Accept as Defect Reports and apply the proposed resolutions of all issues +except issues 3088, 3119, 3122, 3123, 3124, 3131, 3135, 3140, 3141, 3143, 3145, 3149, 3162, and 3172 in +P4160R0 +(Core Language Working Group “ready” Issues for the March, 2026 meeting) to the C++ Working Paper.

+ +

CWG Poll 3. Apply the proposed resolutions of issues +3088, 3119, 3122, 3123, 3124, 3131, 3135, 3140, 3143, 3145, 3149, 3162, and 3172 in +P4160R0 +(Core Language Working Group “ready” Issues for the March, 2026 meeting) to the C++ Working Paper.

+ +

CWG Poll 4. Accept as a Defect Report and apply the changes in +P3924R1 +(Fix inappropriate font choices for “declaration”) to the C++ Working Paper. +This addresses ballot comment US 11-400.

+ +

CWG Poll 5. Accept as a Defect Report and apply the changes in +P4136R2 +(#line is not in line with existing implementation) to the C++ Working Paper. +This addresses ballot comment FR-009-108.

+ +

CWG Poll 6. Accept as a Defect Report and apply the changes in +P4004R1 +(Reconsider CWG 1395 “Partial ordering of variadic templates reconsidered”) to the C++ Working Paper.

+ +

CWG Poll 7. Accept as a Defect Report and apply the changes in +P3865R3 +(Class template argument deduction (CTAD) for type template template parameters) to the C++ Working Paper.

+ +

CWG Poll 8. Apply the changes in +P3598R0 +(CWG 3158 – const-ification of Splice Expressions) to the C++ Working Paper.

+ +

CWG Poll 9. Apply the changes in +P3726R2 +(Adjustments to Union Lifetime Rules) to the C++ Working Paper. +This addresses ballot comment DE 087.

+ +

CWG Poll 10. Accept as a Defect Report and apply the changes in +P4143R0 +(Constant evaluation when?) to the C++ Working Paper. +This partially addresses ballot comment US 33-065.

+ +

CWG Poll 11. Accept as a Defect Report and apply the changes in +P4149R1 +(Define “immediate context”) to the C++ Working Paper. +This addresses ballot comment US 54-100 and core issues 1844 and 2296.

+ +

CWG Poll 12. Accept as a Defect Report and apply the changes in +P3769R1 +(Clarification of placement new deallocation) to the C++ Working Paper.

+ +

CWG Poll 13. Apply the proposed resolution of issue 3141 in +P4160R0 +(Core Language Working Group “ready” Issues for the March, 2026 meeting) to the C++ Working Paper.

+ +

Library working group polls

+ +

LWG Poll 1. Apply the changes in +P4145R0 +(C++ Standard Library Ready Issues to be moved in Croydon, Mar. 2026) to the C++ working paper.

+ +

LWG Poll 2. Apply the changes in +P4146R0 +(C++ Standard Library Immediate Issues to be moved in Croydon, Mar. 2026) to the C++ working paper.

+ +

LWG Poll 3. Apply the changes in +P3690R1 +(Consistency fix: Make simd reductions SIMD-generic) to the C++ working paper. +This addresses ballot comment AT8-279.

+ +

LWG Poll 4. Apply the changes in +P3844R4 +(Reword [simd.math] for consteval conversions) to the C++ working paper. +This addresses ballot comment DE-286.

+ +

LWG Poll 5. Apply the changes in +P3932R0 +(Fix LWG4470: Fix integer-from in [simd]) to the C++ working paper.

+ +

LWG Poll 6. Apply the changes in +P4012R1 +(Value-preserving consteval broadcast to simd::vec) to the C++ working paper. +This addresses ballot comment DE-286.

+ +

LWG Poll 7. Apply the changes in +P3886R0 +(Wording for AT1-057) to the C++ working paper. +This addresses ballot comment AT 1-057.

+ +

LWG Poll 8. Apply the changes in +P3936R1 +(Safer atomic_ref::address (FR-030-310)) to the C++ working paper +and update the value of the __cpp_lib_atomic_ref macro. +This addresses ballot comment FR-030-310.

+ +

LWG Poll 9. Apply the changes in +P4140R0 +(Proposed resolution for US70-126: allow incomplete types in type_order) to the C++ working paper. +This addresses ballot comment US 70-126.

+ +

LWG Poll 10. Apply the changes in +P3373R4 +(Of Operation States and Their Lifetimes) to the C++ working paper. +CA-338.

+ +

LWG Poll 11. Apply the changes in +P3986R1 +(A Wording Strategy for Inlinable Receivers) to the C++ working paper. +This addresses ballot comment CA-318.

+ +

LWG Poll 12. Accept as a Defect Report and apply the changes in +P3059R2 +(Making user-defined constructors of view iterators/sentinels private) to the C++ working paper. +This addresses ballot comment GB 09-257.

+ +

LWG Poll 13. Accept as a Defect Report and apply the changes in +P3725R3 +(Filter View Extensions for Safer Use, Rev 3) to the C++ working paper. +This addresses ballot comments AT9-249, RU-250, DE-251.

+ +

LWG Poll 14. Apply the changes in +P3828R1 +(Rename the to_input view to as_input) to the C++ working paper. +This addresses ballot comment DE-248.

+ +

LWG Poll 15. Apply the changes in +P3795R2 +(Miscellaneous Reflection Cleanup) to the C++ working paper. +This addresses ballot comments US 42-078 and US 85-150 and US 122-184 and US 128-192 and US 95-202 and US 131-195.

+ +

LWG Poll 16. Apply the changes in +P3948R1 +(constant_wrapper is the only tool needed for passing constant expressions +via function arguments) to the C++ working paper. +This addresses ballot comments FR-019-210 and FR-021-218.

+ +

LWG Poll 17. Apply the changes in +P3978R3 +(constant_wrapper should unwrap on call and subscript) to the C++ working paper.

+ +

LWG Poll 18. Apply the changes in +P3961R1 +(Less double indirection in function_ref) to the C++ working paper. +This addresses ballot comment RU-220.

+ +

LWG Poll 19. Apply the changes in +P3981R2 +(Better return types in std::inplace_vector and std::exception_ptr_cast) to the C++ working paper. +This addresses ballot comments PL-006 and US 68-122 and US 150-228 and GB 08-225.

+ +

LWG Poll 20. Apply the changes in +P4022R0 +(Remove try_append_range from inplace_vector for now) to the C++ working paper. +This addresses ballot comment PL-006.

+ +

LWG Poll 21. Apply the changes in +P4037R1 +(Supporting signed char and unsigned char in random number generation) to the C++ working paper. +This addresses ballot comment RU-272.

+ +

LWG Poll 22. Apply the changes in +P3450R1 +(Extend std::is_within_lifetime) to the C++ working paper. +This addresses ballot comment US 82-145.

+ +

LWG Poll 23. Apply the changes in +P3982R2 +(Split strided_slice into extent_slice and range_slice for C++26) to the C++ working paper. +This addresses ballot comment PL-007.

+ +

LWG Poll 24. Apply the changes in +P4144R1 +(Remove span’s initializer_list constructor for C++26) to the C++ working paper.

+ +

LWG Poll 25. Apply the changes in +P3804R2 +(Iterating on parallel_scheduler) to the C++ working paper. +This addresses ballot comment RO 4-395.

+ +

LWG Poll 26. Apply the changes in +P3787R2 +(Adjoints to “Enabling list-initialization for algorithms”: uninitialized_fill) to the C++ working paper. +This addresses ballot comment FR-027-267.

+ +

LWG Poll 27. Apply the changes in +P3842R2 +(A conservative fix for constexpr uncaught_exceptions() and current_exception()) to the C++ working paper. +This addresses ballot comments PL-012 and GB 03-119 and DE-120 and US 67-118 and FI-121.

+ +

LWG Poll 28. Apply the changes in +P3826R5 +(Fix Sender Algorithm Customization) to the C++ working paper. +This addresses ballot comments US 207-328 and US 202-326 and FR-031-219 and FI-331 and CA-358.

+ +

LWG Poll 29. Apply the changes in +P3980R1 +(Task’s Allocator Use) to the C++ working paper. +This addresses ballot comments US 254-385 and US 253-386 and US 255-384 and US 261-391.

+ +

LWG Poll 30. Apply the changes in +P4156R0 +(Rename meta::has_ellipsis_parameter to meta::is_vararg_function) to the C++ working paper. +This addresses ballot comment FR-017-155.

+ +

LWG Poll 31. Apply the changes in +P3953R3 +(Rename std::runtime_format) to the C++ working paper.

+ +

LWG Poll 32. Apply the changes in +P4052R0 +(Renaming saturation arithmetic functions) to the C++ working paper. +This addresses ballot comment FR-026-265.

+ +

LWG Poll 33. Apply the changes in +P3941R4 +(Scheduler Affinity) to the C++ working paper. +This addresses ballot comments US 232-366 and US 233-365 and US 234-364 and US 235-363 and US 236-362.

+ +

LWG Poll 34. Apply the changes in +P3856R8 +(New reflection metafunction - is_structural_type) to the C++ working paper. +This addresses ballot comment US 49-090.

+ +

LWG Poll 35. Apply the changes in +P3927R2 +(task_scheduler support for parallel bulk execution) to the C++ working paper. +This addresses ballot comment US 238-368.

+ +

LWG Poll 36. Apply the changes in +P4151R1 +(Rename affine_on) to the C++ working paper.

+ +

LWG Poll 37. Apply the changes in +P4159R0 +(Make sender_in and receiver_of exposition-only) to the C++ working paper.

+ +

LWG Poll 38. Apply the changes in +P4154R0 +(Renaming various execution things) to the C++ working paper. +This addresses ballot comments US 205-320 and RO 4-395.

+ +

National body comment resolution

+ +

A large number of national body comments for the C++26 Committee Draft have been +addressed in this working draft.

+ +

Editorial comments

+ +

Most editorial national body comments were addressed before the Kona 2025 meeting, +see Editor’s Report N5033 +for the full list.

+ +

A few additional national body comments have since been found editorial +and have now been addressed:

+ + + + +

Non-editorial comments

+ +

The following national body comments were addressed by the motions approved at the Croydon 2026 meeting:

+ + + + +

Editorial changes

+ +

Major editorial changes

+ +

The subclause [expr.const], formerly titled “Constant expressions”, +has been renamed to “Constant evaluation” and its contents have been +divided into smaller subclauses; see commit +98a668efc2ab0bea86dcf9a2d8bf583dddc35e32.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N5008 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 cc2efebb57ea02ea2eac19220c873c158f855859
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Dec 15 15:43:02 2025 +0000
+
+    [basic.start.dynamic] Fix typo (#8654)
+
+commit 3e6cad293e448f7d9f9d859d07b5371b7e054789
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Dec 15 15:47:37 2025 +0000
+
+    [basic.types.general] Improve presentation of comments in example (#8636)
+
+    - put "sizeof" in code font
+    - use a comma after "OK"
+
+commit f6319760f3f6d9a710fdb4be5e54c111abfc1e92
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 16:21:20 2025 +0000
+
+    [basic.link] Modernize wording about type aliases
+
+commit f66f4c675c0c60f822bb24543cd607e14be24a93
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 16:31:25 2025 +0000
+
+    [intro.memory] Update outdated example
+
+commit 176528f688cec22566f1de8286f1c3fae43887ce
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 16:46:10 2025 +0000
+
+    [intro.object] Remove redundant "non-bit-field"
+
+commit 1d9fdb066e95b7be58881f24977a20a51359097c
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 17:40:14 2025 +0000
+
+    [basic.types.general] Remove unused meta-variable
+
+commit 2dbe5a3247b100a6e4cdddab46eda5595d9d3de1
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Dec 15 21:58:39 2025 +0000
+
+    [basic.start.dynamic] Add cross-reference for "interface dependency" (#8653)
+
+commit 166fd7efa129ce139e2a859758410fd7fd0955b3
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Dec 15 20:46:26 2025 +0100
+
+    [exec.scope.concepts] Fix typos
+
+commit d8a8c5ad3b354087a416c02c2059b9ef62534c72
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Apr 25 00:30:02 2024 +0800
+
+    [expos.only.entity] Say typedef-names are declared
+
+    Also use "provided for exposition only" from @W-E-Brown's suggestion.
+
+commit 7fcd646f6d82721e32f5fb5dc11994b8b0cf1d64
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 3 00:37:14 2023 +0800
+
+    [type.descriptions.general] Use "shown" for impl-def types
+
+commit 34c7cffe9e7d1807df4b986e648392bb3a1dfae0
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 3 00:38:04 2023 +0800
+
+    [enumerated.types] Reword enumerated types
+
+    Also mention [re].
+
+commit cc2ecb3a2c85b2e196ca5697287270e9f62878c8
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 3 00:38:45 2023 +0800
+
+    [bitmask.types] Reword bitmask types
+
+commit 03545f10f200193e15d3f0227b289ff037146abf
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Apr 25 00:33:17 2024 +0800
+
+    [extern.types] Use "declared" for C library types
+
+commit d21a84cc95a9a3e619139a1c53d7937474ea03b8
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Jul 28 23:51:45 2023 +0800
+
+    [cstdint.syn] Use "declare" for typedef-names
+
+commit ad83c0b2bc498eac0fc4d97850143581dbfa703c
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Jul 28 23:52:27 2023 +0800
+
+    [stdfloat.syn] Use "declare" for typedef-names
+
+commit 30000d169f5b6db54d7d61ed35aa825fbbdfa70d
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Jul 28 23:58:28 2023 +0800
+
+    [meta.rqmts] Use "declare" for typedef-names
+
+commit c5eac2a7d176110d63e153fa1d5abcee9681943e
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Jul 29 00:02:58 2023 +0800
+
+    [meta.trans.other] Use "declare" for typedef-names
+
+    In the example, it seems a bit verbose to say "declarations and
+    definitions".
+
+commit cbd6e735fdea46f312d27ae802e83766d8dc43f8
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Jul 29 00:03:49 2023 +0800
+
+    [ratio.si] Use "declare" for typedef-names
+
+commit 8210a2cc6ff0bb2a90c9b20cf60ee1d369156c4b
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Jul 29 00:12:12 2023 +0800
+
+    [readable.traits] Use "declare" for typedef-names
+
+commit c5b55216c7a80fe7187bdbc4f5e62b6ef53e6008
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Jul 29 00:14:51 2023 +0800
+
+    [iterator.traits] Use "declare" for typedef-names
+
+commit b892cf9dd9a5d0e8d9046d0e99b72487f3316b51
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Jul 29 00:16:03 2023 +0800
+
+    [std.iterator.tags] Use "declare" for typedef-names
+
+commit 535f5a348bf4eab6c0d71673209bc853103880c2
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 24 00:28:25 2024 +0800
+
+    [const.iterators.types] Avoid "defining" `iterator_category`
+
+    Use "declare" instead.
+
+commit af81d11662c4b7dfb135176c5282788f6e3f50d4
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 24 00:28:58 2024 +0800
+
+    [move.iterator] Avoid "defining" `iterator_category`
+
+    Use "declare" instead.
+
+commit 45a31c6e70f49792ee3650a106ad03a8a95d7e03
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 24 00:29:32 2024 +0800
+
+    [common.iter.types] Avoid "defining" typedef-names
+
+commit 5253ec6c6229c704303d682c4bd1d0e197506716
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 24 00:30:51 2024 +0800
+
+    [range.filter.iterator] Avoid "defining" typedef-names
+
+    Use declared" instead.
+
+commit 251d0c7ef52327f628086e228a244792a467f27c
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 24 00:31:39 2024 +0800
+
+    [range.transform.iterator] Avoid "defining" typedef-names
+
+    Use "declare" instead.
+
+commit 1fa1d4afe6111b03aeec7ced79ed0bf7f6a2569b
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 24 00:32:17 2024 +0800
+
+    [range.join.iterator] Avoid "defining" typedef-names
+
+    Use "declare" instead.
+
+commit 55e740c366d1c691c31fda455f6acfcfe7e60979
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 24 00:33:09 2024 +0800
+
+    [range.join.with.iterator] Avoid "defining" typedef-names
+
+    Use "declare" instead.
+
+commit ff0957c1a71f4b668acf9d316efcb31d59495398
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 24 00:45:09 2024 +0800
+
+    [range.concat.iterator] Avoid "defining" typedef-names
+
+    Use "declare" instead.
+
+commit 293648ef77f2533187a1ca89f9649c21da0c06b1
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 24 00:33:37 2024 +0800
+
+    [range.elements.iterator] Avoid "defining" typedef-names
+
+    Use "declare" instead.
+
+commit ae40e054b0ad38993c52f454862682bcdd3bee14
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 24 00:34:43 2024 +0800
+
+    [range.zip.transform.iterator] Avoid "defining" `iterator_category`
+
+    Use "declare" instead.
+
+commit 20564e2186a5f237f1a89fb0b470eb19f662fe2d
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 24 00:35:44 2024 +0800
+
+    [range.stride.iterator] Avoid "defining" typedef-names
+
+    Use "declare" instead.
+
+commit da9cc238aa051d127e7ea0d196622a161cab77f1
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Oct 17 19:19:03 2024 +0800
+
+    [format.string.std] Use "declare" for typedef-names
+
+commit b77796b42a5d2854a186858d8a36c558ddc18da4
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Jul 29 00:47:45 2023 +0800
+
+    [atomics.alias] Use "declare" for typedef-names
+
+commit ae8e81dfc21ead75c8d4fcfdb75c4638b14a7fdb
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Jul 29 00:48:28 2023 +0800
+
+    [stdatomic.h.syn] Use "declare" for typedef-names
+
+commit 7d4d7f37aa2122fe6e292fcc9520b022fba70d13
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Fri Dec 19 03:50:07 2025 -0400
+
+    [expr.const] Fix typo "with [...]" => "within the evaluation" (#8669)
+
+commit e9fa860d3af7236fbe43d56ffef4abec93b6a0c9
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 23:54:38 2025 +0000
+
+    [basic.contract.eval] Replace "operation" with "evaluation"
+
+commit 4dc76ac3cc9895782b199af745dd42614a7d0327
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Tue Dec 23 01:15:15 2025 +0800
+
+    [flat.multiset.modifiers] Add missing constexpr (#8675)
+
+commit a4fbfa2a689dbd2f0d7a16b29af92dc74574381d
+Author: Andrey Ali Khan Bolshakov <bolsh.andrey@yandex.ru>
+Date:   Tue Dec 23 09:57:57 2025 +0300
+
+    [time.syn] Add missing namespace qualification (#8677)
+
+commit 7abca25d03460cd35e880f29fc7001c69218594a
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Dec 23 13:21:13 2025 -0500
+
+    [expr.new] Precise cross-reference for throwing exceptions (#8681)
+
+commit db380b0d4015eb7d2956e73e59c1c5c26f3651a4
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Dec 29 09:54:10 2025 +0800
+
+    [version.syn] Reformat a comment to avoid splitting `<type_traits>`
+
+    Co-authored-by: Alisdair Meredith <alisdairm@me.com>
+
+commit c59d8c8e9d6fe8adba2142d1344b0e142c9d6ff4
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Dec 29 09:54:36 2025 +0800
+
+    [initializer.list.syn] Drop redundant comments
+
+commit 3dc04f5cda1c8470c0da7c6f9ffcd6d463429ef2
+Author: Hana Dusíková <hanicka@hanicka.net>
+Date:   Fri Jan 2 16:35:49 2026 +0100
+
+    [hive.cons] Fix typo "allocator_traits<alloc>" -> "allocator_traits<Allocator>" (#8689)
+
+commit 7c8a960f3f06d5c565b0976402ce534848926181
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Sat Jan 24 00:52:07 2026 +0800
+
+    [forward.list.overview] Add missing constexpr (#8717)
+
+commit f3b76296f598bc5266e649f8fb0a2c5ef19ae0c3
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jan 26 15:52:54 2026 +0100
+
+    [temp.dep.type] Add period to end of sentence (#8723)
+
+commit 6704d82cd336baaa4f6fe45013c390453991ee86
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Jan 30 21:57:16 2026 +0100
+
+    [except.handle] Add commas (#8727)
+
+commit 16f4265888fd30e59512a21a5391327d6b525de1
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat Jan 31 19:28:43 2026 +0100
+
+    [value.error.codes] Fix indefinite article (#8730)
+
+commit 91156093a76177329a990dfdf38f19dad3531688
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Feb 3 23:19:25 2026 +0100
+
+    [concept.comparisoncommontype] Add period to end of sentence (#8731)
+
+commit 15fc5a2f7106963d8e7904eee03bebe2aaf7a81b
+Author: Giuseppe D'Angelo <dangelog@users.noreply.github.com>
+Date:   Sun Feb 22 20:45:53 2026 +0100
+
+    [alg.remove] Use E(i) for predicate on iterator i (#8760)
+
+    The `E` in the code is actually meant to be a function on an
+    iterator `i`; amend both usages to `E(i)`. This was already done
+    everywhere else (for instance in copy_if or unique_copy).
+
+commit 5b07f42565be7972f2b5d729a740da12c5e6b202
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Feb 24 10:35:57 2026 +0000
+
+    [thread.mutex.requirements.mutex.general] Fix grammar (#8765)
+
+commit 4ce955bd576f6a9d68da494e8b560ca8b9375005
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Feb 24 10:38:03 2026 +0000
+
+    [exec.snd.expos] Fix order of make_obj_using_allocator arguments (#8766)
+
+commit 3f6372b97bcdee30b8591077c8479a56bb50fc67
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Wed Feb 25 15:35:49 2026 -0600
+
+    [const.wrap.class] Add missing this to compound assignment operators (#8758)
+
+    This corrects a misapplication of LWG4383 in commit bdcfe2c9a54ca350e9bfc59227bb0285a59c635d.
+
+commit 8338b7caa5a38ef79e5c2f8316078f6f74d1b8ad
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Mar 5 08:58:29 2026 +0100
+
+    [text.encoding.id] Add colon after "as follows" (#8776)
+
+commit eba89bc9b32d230168571737d6aa86c06329502b
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Dec 22 17:59:19 2025 -0500
+
+    [lex.phases] Make note on the notion of file more prominent
+
+    The notion that when the standard refers to files does not
+    necessarily imply a file in a traditional filing system is
+    more fundamental than its late appearance in the middle of
+    phase 7 of translation.  Move that note right to the top of
+    [lex] where we first talk of storing the program text in
+    source files, where is will be understood even before the
+    phases of translation.
+
+commit 13cad628c5c3883c8fb8dcb4256199b21c13be1d
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Mar 12 08:08:56 2026 +0100
+
+    [istream.unformatted] Add right parenthesis
+
+commit 981d32246c951b18dc816cecfdb3ffbb5d72ad54
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Mar 17 21:04:34 2026 +0100
+
+    [stoptoken.concepts] Remove superfluous \item (#8790)
+
+commit 92b3a22228ffb3db219debace0e5fbe82c592354
+Author: Can <cancagri.dev@gmail.com>
+Date:   Fri Mar 20 10:32:30 2026 +0300
+
+    [utility.intcmp] Fix name of type parameter (#8770)
+
+    Introduced by commit 93914a36c1945d330a7c7d5c4488e1d10e5bbe75 .
+
+commit 11106fc54b79e1ee21805ea77596908ca4f3a8f3
+Author: Abhinav Agarwal <abhinavagarwal07@users.noreply.github.com>
+Date:   Fri Mar 20 10:56:06 2026 -0700
+
+    [mdspan.sub.map.common,mdspan.sub.map.left] Fix S(p)liceSpecifiers typos (#8799)
+
+commit 36ce9cbe82d472997ca9b978e69e64d6ddd99dcd
+Author: Abhinav Agarwal <abhinavagarwal07@users.noreply.github.com>
+Date:   Fri Mar 20 10:56:49 2026 -0700
+
+    [linalg.algs.blas3.rank2k] Add missing \pnum and \effects (#8801)
+
+commit cda7c18d2b83b354bae6001cdf7cb7d3f9203f32
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Mar 21 17:36:47 2026 +0800
+
+    [lib] Replace bad uses of "instantiation" with "specialization" (#8379)
+
+    Affected sections:
+    - [allocator.requirements.general]
+    - [namespace.std]
+    - [pointer.traits.types]
+    - [allocator.traits.types]
+    - [tuple.general]
+    - [format.context]
+    - [numeric.requirements]
+    - [rand.util.canonical]
+    - [thread.req.lockable.timed]
+    - [thread.sharedtimedmutex.requirements.general]
+
+    - In [tuple.general], change "is similar to" to "behaves similarly to"
+    to avoid confusing with "similar types" in the core specification.
+
+commit dc5928bdac7e3301d78c8fae5f4cae655a9a06fb
+Author: A. Jiang <de34@live.cn>
+Date:   Sun Mar 22 14:14:40 2026 +0800
+
+    [vector.bool.fmt][container.adaptors.format] Add missing `constexpr` and other missed edits (#8768)
+
+    Fixes edits from P3391R2 missed by commit cc63c64cba30089a366b024ffc8cc0532b4fb508 .
+
+commit c6fecf491063eef95384e54813812f6c6aaeab6a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Mar 23 11:40:36 2026 +0000
+
+    [expected.object.eq] Add missing negation (misapplied wording).
+
+    The negation was accidentally omitted in the application of P3905R0,
+    approved in Kona 2025 (265b4774c754b36e50bec7a528cbbc87676b0c85).
+
+commit 6913287752040f7adecdac5af60c90e2701a04e0
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Feb 25 15:04:34 2026 +0800
+
+    [format] Consistently add `constexpr` to function descriptions
+
+    P3391R2 only added `constexpr` to synopses but not descriptions for some
+    formatting functions. This PR consistently adds `constexpr` to the
+    descriptions.
+
+commit 45c820b6a9d87b18f3ad5c445c5e61e2ee806a6d
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Tue Dec 16 23:52:12 2025 -0500
+
+    [diff.basic] Use enum example instead of example outdated since C99
+
+    C99 subclause 6.2.7, "Compatible type and composite type", had this
+    sentence:
+    > If one is declared with a tag, the other shall be declared with the
+    > same tag.
+
+commit 3e53098c0ef22b62ab2dd393411141fceeda03bd
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Tue Dec 16 23:57:14 2025 -0500
+
+    [diff.basic] Stop claiming, as harmless, type-based aliasing violations
+
+commit c40c5f03a02c7e0f2564de46aea4ceebb1c799e4
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Fri Feb 13 12:21:45 2026 +0100
+
+    [intro.compliance.general] Mark documentation encouragement as recommended practice
+
+commit d8ff3c08615932a207f956a61ebd6e5805f9a9bd
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 17:15:48 2025 +0000
+
+    [basic.stc.dynamic] Spell out compound type names
+
+commit e70a19ba60ccf3eeed62bf82e4b33584272a1c86
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 26 08:30:31 2026 +0100
+
+    [lex.key] Emphasize that keywords are created in phase 6
+
+    This was overlooked in CWG3094, applied with commit 94055b39a90285d8ae15f8f864a39a328f42a359.
+
+commit 0807a339b8bcae60a9d2285f0a08aab61aeece0d
+Author: Barry Revzin <barry.revzin@gmail.com>
+Date:   Thu Jan 29 07:59:28 2026 -0600
+
+    Clarify pack-index-specifier rules
+
+commit f55d63dcef1640f292451a3efe98f56d4afa2383
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 17:56:03 2025 +0000
+
+    [basic.fundamental] Strike explanatory sentence; touch up note
+
+commit f4d8ecb2aa29122d63e5f56119a83dd4bb2ad3ca
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 18:23:18 2025 +0000
+
+    [basic.extended.fp] Replace "typedef-name" with "type alias"
+
+commit 2efe693eb09f8c6d364c757a82b640e2ced9f107
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Dec 17 14:32:48 2025 +0100
+
+    [intro.refs], [numeric.limits] Remove all references to ISO/IEC 10967-1:2012
+
+commit b54449db95dcdfa8ae4d8221ef55f7fca0f358d9
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 23:06:53 2025 +0000
+
+    [basic.start.static] Improve readability of example
+
+commit cd15f7a88e6390fb31aa766196205e722779d240
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Thu Dec 18 19:41:46 2025 -0500
+
+    [stmt.pre] Streamline decl-specifier restrictions on conditions, etc.
+
+    Avoid an abrupt shift from a mathematical introduction to the
+    specification of additional normative requirements.
+
+    Expresses universal quantification more directly.
+
+commit d3f57042d283c06cdb066eab1fc61661df0fc4de
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sun Jul 23 14:23:21 2023 +0200
+
+    [temp.point] Itemize long conditionals in three paragraphs
+
+commit ecc669c503bb875b65cbd4de3d231a8ac9e4bb70
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Tue Mar 10 15:07:57 2026 +0800
+
+    [meta.syn] Add function parameter names
+
+    These two seem to be the only ones where the function parameter names are omitted in the declaration.
+    Add names to ensure consistency.
+
+commit 98a668efc2ab0bea86dcf9a2d8bf583dddc35e32
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Mar 26 21:57:48 2026 +0100
+
+    [expr.const] Introduce subclauses
+
+commit a2933d5fd4e592bcd8669a51a359c5a850b32de2
+Author: Davis Herring <herring@lanl.gov>
+Date:   Thu Mar 26 21:00:20 2026 +0000
+
+    Refine cross references into [expr.const]
+
+commit 13906dcab8cfb87f880ea444336cbcc37165cd67
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Dec 11 14:14:32 2025 +0000
+
+    [basic.lookup.unqual] Rephrase to avoid incorrect use of term
+
+commit ad94af979e8dfac9ca9af4aa22c66beec7935cfd
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Mar 25 21:05:15 2026 +0800
+
+    [iostream.forward.overview] Add missing mentions of spanbuf and spanstreams
+
+    A follows up to P0448R4.
+
+commit 6a31f94c5ef15fdb592c558cd63b2bd02bd18c8a
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Mar 25 21:05:37 2026 +0800
+
+    [iostream.forward.overview] Say "designate specialization".
+
+    This replaces the imprecise and informal phrase "define instances of
+    class templates".
+
+commit 731cda191b915555c6816912361e431c82e7e2f6
+Author: Matthias Kretz <m.kretz@gsi.de>
+Date:   Tue Nov 4 05:17:01 2025 -1000
+
+    [simd.permute.*] Change M back to V since the wording refers to V
+
+    This was changed editorially by b6e501026e14600fed911183336266c0ebdf5728
+    as part of "2025-06 LWG Motion 13: P3691R1 Reconsider naming of the
+    namespace for std::simd", but turned out not to be a helpful change,
+    because it makes other wording more complex.
+
+    Fixes NB US 180-295 (C++26 CD).
+
+commit 7f3b7c64a18610948bfc5479a90764f4992731bd
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 22:00:24 2025 +0000
+
+    [intro.races] Fix typo
+
+commit e1ee86a3c373c53db7b5d6289457eed620862c76
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Mar 27 13:17:33 2026 +0100
+
+    [simd.syn,simd.permute.mask] Change M::value_type& to V::value_type&
+
+commit 8cef46b15b21d4ab1b96dce04c0d37e511d1ddc2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 6 00:24:35 2025 +0200
+
+    [exec.snd.expos] Reorder specification immediately after declaration
+
+    Fixes NB US 213-353 (C++26 CD).
+
+commit 6fc165022194a0dd3b78287b087e7872c6c88f48
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Mar 27 11:58:32 2026 +0000
+
+    [exec.get.compl.sched] Rename completion-tag to completion-fn-tag and reorder text.
+
+    The renaming avoids a clash with the concept "completion-tag" defined
+    in [exec.snd.expos]. The reordering makes it so that names are defined
+    before they are referenced.
+
+commit deb2a9b40a46062dd76a1bbc968ff5039cb02aaf
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Mar 28 08:56:40 2026 +0000
+
+    [exec.snd.expos] Delete unused expos-only concept "completion-tag".
+
+    Also insert a missing \pnum before the now-split codeblock (see 8cef46b15b21d4ab1b96dce04c0d37e511d1ddc2).
+
+commit fda5e3771f85dfea6d7bd8ade0577e82886addc0
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Fri Mar 20 02:36:07 2026 -0700
+
+    [dcl.struct.bind] Fix tuple-like binding index to use SB_i instead of v_i
+
+    P1061R10 introduced the SB_i notation for post-expansion structured bindings
+    but this sentence was not updated. The rest of the section (p6, p8, and the
+    end of this same paragraph) already uses SB_i.
+
+commit 42f878f50d1356866b5aebe520a3138f707919a0
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Dec 15 00:01:35 2025 +0000
+
+    [basic] Do not hyphenate "potentially evaluated"
+
+commit 70e753882b290ea432e516b75fd924bc687076be
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Dec 15 00:03:46 2025 +0000
+
+    [expr] Do not hyphenate "potentially evaluated"
+
+commit d296b82c70dcf49a7a10a100778ecd6aed4c92c7
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Dec 15 00:04:54 2025 +0000
+
+    [dcl] Do not hyphenate "potentially evaluated"
+
+commit 9ad63b74fae211473235c8fa087d19d392c04728
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Dec 15 00:05:31 2025 +0000
+
+    [temp.over.link] Do not hyphenate "potentially evaluated"
+
+commit 180830c280023ea63165547b937da8265b6bd667
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Apr 3 21:10:21 2026 +0800
+
+    [mdspan.mdspan.cons] Fix typo (`is_nothrow_constructible` => `is_nothrow_constructible_v`)
+
+commit c52c49ab2bcb5770ec2190f3381051442e037157
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Apr 20 01:49:17 2026 +0100
+
+    [task.promise] Delete unused definition of expos-only error-variant.
+
+    The changes from LWG 4339 removed the use of this type alias,
+    but not its definition.
+
+commit ec642cdab87f6f83392196a1600d19d893c17b08
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 12 20:52:51 2026 +0100
+
+    [mdspan.syn] Renamed template parameter from "Slices" to "SliceSpecifiers".
+
+    The latter form is used everywhere else, including in the item's itemdecl.
+
+commit bcb6a56a5d2bef008ed02de89b50acdd7e8b8b1d
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Apr 20 18:47:33 2026 +0200
+
+    [exec.get.domain] Remove extraneous period after list (#8956)
+
+commit 6fd25df420db99ce2607b7ce3741f4d1891d0ceb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 22 19:14:40 2026 +0100
+
+    [temp.deduct.conv] Add comma to structure the sentence
+
+commit 25182503a4a94a3fb56c48c80fca56a713095882
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Apr 16 17:25:53 2026 +0200
+
+    [cpp.pre] Remove confused footnote about 'lines'
+
+commit cd6c5bf4871a80b1e865f85a7e1e104036ce2869
+Author: Jay Ghiron <55773281+Halalaluyafail3@users.noreply.github.com>
+Date:   Mon Apr 20 12:52:13 2026 -0400
+
+    [diff.expr] Update incorrect comment about C (#8933)
+
+    arr2 is a constraint violation in C, rather than being valid.
+
+commit 9909e30038ee608225a67f62b355a60d1a679325
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Thu Apr 16 21:22:13 2026 +0800
+
+    [mdspan.layout.leftpad.obs, mdspan.layout.rightpad.obs] Fix return type of operator()
+
+commit 1651c628caed73f26e120a604eca6798f4da6afc
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Tue Apr 21 04:40:40 2026 +0800
+
+    [linalg] Add period after \returns statement on same line (#8950)
+
+commit 6211dc859a519b7ff5cca0bfbd953f3b4bd73450
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Wed Apr 8 12:19:17 2026 +0800
+
+    [linalg.scaled.scaledaccessor,linalg.conj.conjugatedaccessor] Added missing typename
+
+commit 0a236f9185a2e59c7a49b5439135ee995460bcd6
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Apr 21 20:02:56 2026 +0800
+
+    [numarray] Remove incorrect comments for deleted default constructors (#8962)
+
+commit 1e747bf358e4546e9661c6bcee01a1dd71d2186f
+Author: Tymi <tymi@tymi.org>
+Date:   Tue Apr 21 21:58:09 2026 +0200
+
+    [fs.class.path] Use "typedef-name" instead of "typedef" (#8964)
+
+commit 240dc1f4e197dac0004fb5b171ea7c717fba89c9
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Tue Apr 21 21:51:27 2026 -0500
+
+    [meta.define.static] Move misplaced \end{codeblock}
+
+commit c07075ab7018c7a88d0d254c4c9262d9a6978c94
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Tue Apr 21 22:14:11 2026 -0500
+
+    [meta.define.static] Rephrase sentence to avoid overfull \hbox
+
+commit 259dcba53500aa26b555f1f952382f484a904cd1
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Wed Apr 22 21:46:07 2026 +0800
+
+    [mdspan.syn, mdspan.sub.range.slices] Remove redundant std
+
+commit 3532b45c6d9dd37d3f9f949b8307960b7a53eff0
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Thu Apr 23 00:30:10 2026 +0800
+
+    [mdspan.sub.helpers] Use period for \returns (#8977)
+
+commit e3a17c5b35d7903f85ff136aeaf9000e6b081517
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Apr 23 21:50:58 2026 +0200
+
+    [utility.arg.requirements] Strike redundant text about core language rules (#8987)
+
+commit 3b5d4f6e215c9fad9472ce1d748cf74b90817ad2
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Apr 24 03:58:27 2026 +0800
+
+    [format.arguments, depr.format.arg] Apply `\exposid` consistently (#8971)
+
+    Co-authored-by: Alisdair Meredith <alisdairm@me.com>
+    Co-authored-by: Jonathan Wakely <github@kayari.org>
+    Co-authored-by: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+
+commit 673a0e4fc97da58665e7f69e00b0f70e5924795e
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Apr 24 17:47:21 2026 +0800
+
+    [re.tokiter.general] Fix incorrect `suffix.match` to use `.matched` (#8988)
+
+commit 663b952c59c4b77e233179189f410ce1d952ea59
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Fri Apr 24 12:02:16 2026 -0500
+
+    [meta.define.static] correct note after CWG3141
+
+commit fecad5839345644f30f8b5d9c1043e2a4e666fc8
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 15:30:37 2026 +0100
+
+    [basic.compound] Add missing \grammarterm.
+
+    Misapplication of CWG Motion 1, Issue CWG 2765.
+
+    Addresses editorial review committee feedback.
+
+commit d3128aacb391726a0c15b8649f9c8e2ca199789e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 15:34:23 2026 +0100
+
+    [bit.cast] Update cross-reference into [expr.const] following 98a668efc2ab0bea86dcf9a2d8bf583dddc35e32.
+
+    The editorial change was made after the wording of CWG 2765 was written.
+
+    Addresses editorial review committee feedback.
+
+commit 5c2c9dd250af893345b6dbb28c793d8894d4b3c8
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 15:50:02 2026 +0100
+
+    [expr.prim.splice] Add missing maths font for variable "C".
+
+    Misapplication of P3598R0 in CWG Motion 8.
+
+    Addresses editorial review committee feedback.
+
+commit 8425e4a1c4fa7c928b33c6796b45cfd81d15160a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 16:05:53 2026 +0100
+
+    [lex.phases] Update cross-reference into [expr.const] following 98a668efc2ab0bea86dcf9a2d8bf583dddc35e32.
+
+    The editorial change was made after the wording of P4143R0 was written.
+
+    Addresses editorial review committee feedback.
+
+commit 01296b2d6e73ade37803f9721de7bdad437b4e3b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 16:09:52 2026 +0100
+
+    [temp.inst] Add missing \grammarterm.
+
+    Misapplication of CWG Motion 11, P4149R1.
+
+    Addresses editorial review committee feedback.
+
+commit d5078b039da4e188f5de51682c2219f26b8367f9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 16:20:12 2026 +0100
+
+    [exec.spawn.future] Add missing \exposid.
+
+    Misapplication of LWG Motion 2, Issue LWG 4540.
+
+    Addresses editorial review committee feedback.
+
+commit 89cc24e855b5a89f099859685fc21fb37f03a36c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 16:24:46 2026 +0100
+
+    [algorithm.syn] Remove stray comma.
+
+    This seems to be an error in the wording of LWG 4544 (LWG Motion 2).
+
+    Addresses editorial review committee feedback.
+
+commit 83f5072a59b06575d1108e7f63ef28b00fb4e4b2
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 18:39:03 2026 +0100
+
+    [simd.math] Remove stray '@'s.
+
+    Addresses editorial review committee feedback.
+
+commit ef5f532d2530a733011b0d606dfe69b952c718f6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 18:46:26 2026 +0100
+
+    [simd.math] Remove stray '\' (unintended escaping).
+
+    Addresses editorial review committee feedback.
+
+commit d706f2d4fa89e7bcaa54338b9619ead9add59c67
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 18:49:24 2026 +0100
+
+    [simd.math] Better linebreaking/whitespacing in remquo description.
+
+    Addresses editorial review committee feedback.
+
+commit 9c5becee9a6ca91aad690074069be058f780006f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 21:12:54 2026 +0100
+
+    [simd.expos{,defn}] Fixed template parameter "class T" => "size_t Bytes".
+
+    Misapplication of P3932R0 in LWG Motion 5.
+
+    Addresses editorial review committee feedback.
+
+commit 120d987ce6a376f1d56b84041d8e69aefaa436ec
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 21:21:12 2026 +0100
+
+    [exec.let] Fix misspelled "declval" use.
+
+    Misapplication of P3826R5 in LWG Motion 28.
+
+    Addresses editorial review committee feedback.
+
+commit daffae75c71890ca82c5021404c9a005e8038405
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 21:24:42 2026 +0100
+
+    [exec.let] Add missing '\exposid's.
+
+    Misapplication of P3373R4 in LWG Motion 10.
+
+    Addresses editorial review committee feedback.
+
+commit 39a5cd65c6c2af9a251b8d2d5c7d5e73e86c9fa5
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 22:24:30 2026 +0100
+
+    [dcl.attr.annotation] Add missing "codeblock" environment.
+
+    Misapplication of P3795R2 in LWG Motion 15.
+
+    Addresses editorial review committee feedback.
+
+commit 33a4bec49725127d2e1942f2b074d17242bc0458
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 22:30:48 2026 +0100
+
+    [basic. link] Add "ANN" element to the "data member description sextuple.
+
+    This was missed by P3795R2 in LWG Motion 15, presumably by accident.
+
+    Addresses editorial review committee feedback.
+
+commit f8e7a0665d9919af4b680d60b07dbb322ee1d4cb
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 23:10:01 2026 +0100
+
+    [func.ref.wrap.ctor] Add missing ".value"
+
+    Misapplication of P3948R1 in LWG Motion 16.
+
+    Addresses editorial review committee feedback.
+
+commit d7c02a0f5c21cd235a0ed3921a30b19d75771f2e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 23:36:15 2026 +0100
+
+    [mdspan.sub.overview] Fix missing edits and missing maths font.
+
+    Misapplication of P3982R2 in LWG Motion 23.
+
+    Addresses editorial review committee feedback.
+
+commit 2a8305d4b5bdf40b9e4e602d30a08e5fed6dd87b
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Sun Apr 26 16:10:39 2026 -0700
+
+    [mdspan.sub.map.sliceable] Fix M::extent_type to M::extents_type
+
+    Layout mapping types expose extents_type, not extent_type; the
+    latter is a member of extent_slice. As written, IT and M_rank
+    in the Let clause name an undefined member.
+
+commit 368af317f557650b4d3dcf98379f02ef3d00140e
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sat May 2 07:41:44 2026 +0000
+
+    [basic.def] Mark definition of "redeclaration" as such (#8596)
+
+commit 75b6c6535f5115750bcaa588ded5dfa99eb5fa24
+Author: Guyutongxue <guyutongxue@163.com>
+Date:   Tue Apr 28 16:40:13 2026 +0800
+
+    [algorithm.syn] Add missing semicolon and right angle bracket
+
+commit 25401da54dcf000fa09105a8dc3cdcf788d753d5
+Author: Guyutongxue <guyutongxue@163.com>
+Date:   Tue Apr 28 16:42:37 2026 +0800
+
+    [map.overview] Add missing right angle bracket
+
+commit eaa1458d9832084f56f22d60dde77ed2a95b9b7e
+Author: Guyutongxue <guyutongxue@163.com>
+Date:   Tue Apr 28 16:43:27 2026 +0800
+
+    [exec.snd.expos] Add missing left brace
+
+commit 9e15aa83cc1fd4efb06afdb861ebaf6e05f261bd
+Author: Guyutongxue <guyutongxue@163.com>
+Date:   Tue Apr 28 16:45:11 2026 +0800
+
+    [rand.eng.philox, simd.syn] Fix misplaced right angle bracket, missing comma in `hypot`, `lerp` and `fma`
+
+commit f0c6e9e9af125c133dba0336797e2193d7d2cc2e
+Author: Guyutongxue <guyutongxue@163.com>
+Date:   Tue Apr 28 16:45:45 2026 +0800
+
+    [range.filter.sentinel] Add missing semicolon
+
+commit 0fcd7084a93a5bfbbfe177cd9c6859eeca63439a
+Author: Guyutongxue <guyutongxue@163.com>
+Date:   Tue Apr 28 16:46:20 2026 +0800
+
+    [atomics.types.float] Fix typo of `floating-point-type`
+
+commit 1a12df96659d230a376a3da4a2bae3cfc4cd57cb
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 2 15:39:57 2026 +0100
+
+    [exec.get.compl.{domain,sched}] Replace "it" and long expression with "the expression".
+
+    In e82e850497facd0b9f1e65f4de75b475ddde42ed I had shortened a long
+    expression from the incoming paper in [exec.get.compl.domain] to just
+    "it". In review it was suggested that "the expression" is clearer, and
+    that similar wording in [exec.get.compl.sched] should use the same style.
+
+    (Overall, I think it is easier to understand that the shorter
+    reference refers to the same expression than to have to compare
+    two long expressions and determine that they are equal.)
+
+    Addresses editorial review committee feedback.
+
+commit 65970a5aad6e50048dce1a0b4398d63b8a09ea44
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 2 15:50:08 2026 +0100
+
+    [exec.get.compl.domain]
+
+    Misapplication of P3826R5 in LWG Motion 28.
+
+    Addresses editorial review committee feedback.
+
+commit fa590b2628d9a21d6a12afa5a1d22168cb40b2a3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 2 15:53:50 2026 +0100
+
+    [exec.snd.expos] Fix missing escaping for braces in "{}".
+
+    Misapplication of P3826R5 in LWG Motion 28.
+
+    Addresses editorial review committee feedback.
+
+commit 91e3416490d096cd0c783c1b5b4e922b53a48f4e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 2 15:57:04 2026 +0100
+
+    [exec.domain.default] Delete stray word "sender".
+
+    The deletion was part of the edit instructions of P3826R5 in LWG
+    Motion 28, but was accidentally missed.
+
+    Addresses editorial review committee feedback.
+
+commit 62be1e6b61e0e3701f4062994cb04eb02d27d1be
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 2 16:00:32 2026 +0100
+
+    [exec.snd.transform] Fix "tag2" => "tag".
+
+    Misapplication of P3826R5 in LWG Motion 28.
+
+    Addresses editorial review committee feedback.
+
+commit 9912050ebe526f32ad1cdec47840fae82099b105
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 2 16:04:37 2026 +0100
+
+    [exec.on] Fix missing escaping for braces in "{...}".
+
+    Misapplication of P3826R5 in LWG Motion 28.
+
+    Addresses editorial review committee feedback.
+
+commit e0ca46ae71122c99c0f098212b2990ed41973b05
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 2 16:07:02 2026 +0100
+
+    [exec.on] Fix missing argument "set_value, ".
+
+    Misapplication of P3826R5 in LWG Motion 28, this edit was just missed.
+
+    Addresses editorial review committee feedback.
+
+commit d04267fda5b9a16ce56beb3137c22900019e0e54
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 2 16:14:53 2026 +0100
+
+    [exec.sync.wait.var] Remove vacuous exception.
+
+    The exception that "sndr is evaluated only once" is no longer
+    necessary, since P3826R5 from LWG Motion 28 removed the previous
+    second mention of the subexpression "sndr". Now that there is only one
+    occurrence of "sndr", it does not need saying that it is only
+    evaluated once.
+
+    Addresses editorial review committee feedback.
+
+commit e5f877a4c0542654017c5cd9152d6c1dba7972b4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 2 16:19:51 2026 +0100
+
+    [exec.affine] Add missing '\placeholder'.
+
+    Misapplication of P3941R4 in LWG Motion 33.
+
+    Addresses editorial review committee feedback.
+
+commit 3647c192d9ed47bd653e3575b9dc84107b7cd1fc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 2 16:32:59 2026 +0100
+
+    [exec.{rcvr,snd}.concepts] Add "// exposition only" comments to definitions.
+
+    A missed edit from P4159R0 in LWG Motion 37.
+
+    Addresses editorial review committee feedback.
+
+commit aea0fae459ee3a369e0dc251f674337298433121
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 2 17:13:27 2026 +0100
+
+    [except.terminate] Replace system_context_replaceability with parallel_scheduler_replacement.
+
+    This change is needed for consistency with P4154R0 from LWG Motion 39.
+    Even though that paper didn't ask for this change, that was clearly an
+    oversight.
+
+    Addresses editorial review committee feedback.
+
+commit fb2c3e602417fe8cd33618ff5adb31a86cf9072b
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Mon May 4 10:37:18 2026 -0400
+
+    [expr.const] Definition domain fixes for "usable in constant expressions" (#8670)
+
+    Also improves the indexing.
+
+commit 32816d5c2f94da9252ea604c8e7ee17a0657e03c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 26 16:31:18 2026 +0100
+
+    [simd.{syn,math}] Rename parameters of new overloads of various special maths functions:
+
+    * For comp_ellint_3: from "x, y" to "k, nu"
+    * For cyl_bessel_{i,j,k}: from "x, y" to "nu, x"
+    * For cyl_neumann: from "x, y" to "nu, x"
+    * For ellint_{1,2}: from "x, y" to "k, phi"
+    * For ellint_{1,2}: from "x, y, z" to "k, nu, phi"
+
+    The paper P3844R4 (LWG Motion 4) added those overloads with parameters
+    named differently from the names of the existing overloads, but the
+    latter names seem more appropriate.
+
+    Addresses editorial review committee feedback.
+
+commit 85c6337534d0bdd9cbfa2260609a853e0c40d61f
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 21:54:26 2025 +0000
+
+    [intro.execution] Replace "or" with "and"; clarify wording
+
+commit a383c1ad305a61cbef3e14c698b41f6228e780c3
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Apr 8 04:52:48 2026 +0200
+
+    [basic.extended.fp] Reference C23 instead of "future versions"
+
+commit 87a9fbb3cc85436d876e9c7a79ca1cfbb48ac150
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon May 11 23:46:40 2026 +0100
+
+    [meta.reflection] Remove uninformative "// OK" comments from examples.
+
+    Fixes NB US 84-151 (C++26 CD).
+
+commit 5670e07a0ec4a4a3c6201512d86013507c0a9389
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Sun Apr 26 16:10:54 2026 -0700
+
+[mdspan.sub.map.sliceable] Use lm in sliceable-mapping concept body
+
+The concept body introduces lm (an object of type LayoutMapping) but
+then uses m (an object of type M from the surrounding requirements
+section) in the submdspan_mapping well-formedness check.
+
+commit 738e80f3b19fe9ad73d7a48c382f9584e2f200fd
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue May 12 09:41:32 2026 +0100
+
+    [istream.formatted.arithmetic] remove unnecessary whitespace in codeblocks
+
+commit d2e19cd940eec863a39edee1499e75230725925f
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Tue May 12 03:15:09 2026 -0700
+
+    [linalg.algs.blas2.rank1,linalg.algs.blas2.symherrank1] Restore missing arguments (#8995)
+
+    Fixes a misapplication of P3371R5.
+
+    * [linalg.algs.blas2.rank1] Add missing E in matrix_rank_1_update_c effects
+    * [linalg.algs.blas2.symherrank1] Restore parameters in updating overload
+
+commit 7c2e7f83c4a8af1841f81f798dd9c5db46232e6d
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Sun Apr 26 16:10:17 2026 -0700
+
+    [mdspan.sub.sub] Fix submdspan slice canonicalization
+
+    Two integration errors in the Let clause introduced by P3663R3:
+    - the function parameter pack is named "slices", but the Let clause
+      references an undefined "raw_slices"; rename the parameter to match
+      subextents (mdspan.sub.extents);
+    - src is an mdspan but canonical_slices takes an extents object;
+      pass src.extents() instead of src.
+
+ + diff --git a/papers/n5047.md b/papers/n5047.md new file mode 100644 index 0000000000..51f8a4568f --- /dev/null +++ b/papers/n5047.md @@ -0,0 +1,1639 @@ +# N5047 Editors' Report -- Programming Languages -- C++ + +Date: 2026-05-12 + +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` + +## Acknowledgments + +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. +Special thanks to Jan Schultke for drafting a lot of motion applications, +to Andreas Krug for ongoing careful reviews, +and to Daniel Krügler for an exceptionally thorough review +that spotted many mistakes in the motion applications. + +## New papers + + * [N5046](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/n5046.pdf) is the + current working draft for C++26. It replaces + [N5032](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5032.pdf). + * N5047 is this Editors' Report. + +The Draft International Standard that will be sent for the ISO ballot has not +yet been completed, but will include the changes from N5046. As usual, since +N5046 has not yet been approved in a WG21 meeting, it is instead being reviewed +by an editorial review committee that was selected in Croydon, as per WG21 +Poll 3. N5046 includes some, but not all of the review committee's feedback. + +## Motions incorporated into working draft + +### Notes on motions + +All motions were applied cleanly. + +Some reconciliation was needed among LWG motions (in particular starting at +motion 28), but paper authors and LWG had already included relevant merging +instructions in the papers. + +The wording of P3980R1 from LWG Motion 29 has been reconciled with intervening +changes from issues LWG 4339 and LWG 4347 from LWG Motion 2. + +### Core working group polls + +CWG Poll 1 does not change the working draft. + +CWG Poll 2. Accept as Defect Reports and apply the proposed resolutions of all issues +except issues 3088, 3119, 3122, 3123, 3124, 3131, 3135, 3140, 3141, 3143, 3145, 3149, 3162, and 3172 in +[P4160R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4160r0.html) +(Core Language Working Group "ready" Issues for the March, 2026 meeting) to the C++ Working Paper. + +CWG Poll 3. Apply the proposed resolutions of issues +3088, 3119, 3122, 3123, 3124, 3131, 3135, 3140, 3143, 3145, 3149, 3162, and 3172 in +[P4160R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4160r0.html) +(Core Language Working Group "ready" Issues for the March, 2026 meeting) to the C++ Working Paper. + +CWG Poll 4. Accept as a Defect Report and apply the changes in +[P3924R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3924r1.html) +(Fix inappropriate font choices for "declaration") to the C++ Working Paper. +This addresses ballot comment US 11-400. + +CWG Poll 5. Accept as a Defect Report and apply the changes in +[P4136R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4136r2.pdf) +(`#line` is not in line with existing implementation) to the C++ Working Paper. +This addresses ballot comment FR-009-108. + +CWG Poll 6. Accept as a Defect Report and apply the changes in +[P4004R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4004r1.pdf) +(Reconsider CWG 1395 "Partial ordering of variadic templates reconsidered") to the C++ Working Paper. + +CWG Poll 7. Accept as a Defect Report and apply the changes in +[P3865R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3865r3.pdf) +(Class template argument deduction (CTAD) for type template template parameters) to the C++ Working Paper. + +CWG Poll 8. Apply the changes in +[P3598R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3598r0.pdf) +(CWG 3158 – `const`-ification of Splice Expressions) to the C++ Working Paper. + +CWG Poll 9. Apply the changes in +[P3726R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3726r2.html) +(Adjustments to Union Lifetime Rules) to the C++ Working Paper. +This addresses ballot comment DE 087. + +CWG Poll 10. Accept as a Defect Report and apply the changes in +[P4143R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4143r0.html) +(Constant evaluation when?) to the C++ Working Paper. +This partially addresses ballot comment US 33-065. + +CWG Poll 11. Accept as a Defect Report and apply the changes in +[P4149R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4149r1.html) +(Define "immediate context") to the C++ Working Paper. +This addresses ballot comment US 54-100 and core issues 1844 and 2296. + +CWG Poll 12. Accept as a Defect Report and apply the changes in +[P3769R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3769r1.html) +(Clarification of placement new deallocation) to the C++ Working Paper. + +CWG Poll 13. Apply the proposed resolution of issue 3141 in +[P4160R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4160r0.html) +(Core Language Working Group "ready" Issues for the March, 2026 meeting) to the C++ Working Paper. + +### Library working group polls + +LWG Poll 1. Apply the changes in +[P4145R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4145r0.html) +(C++ Standard Library Ready Issues to be moved in Croydon, Mar. 2026) to the C++ working paper. + +LWG Poll 2. Apply the changes in +[P4146R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) +(C++ Standard Library Immediate Issues to be moved in Croydon, Mar. 2026) to the C++ working paper. + +LWG Poll 3. Apply the changes in +[P3690R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3690r1.pdf) +(Consistency fix: Make `simd` reductions SIMD-generic) to the C++ working paper. +This addresses ballot comment AT8-279. + +LWG Poll 4. Apply the changes in +[P3844R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3844r4.pdf) +(Reword [simd.math] for consteval conversions) to the C++ working paper. +This addresses ballot comment DE-286. + +LWG Poll 5. Apply the changes in +[P3932R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3932r0.pdf) +(Fix LWG4470: Fix integer-from in [simd]) to the C++ working paper. + +LWG Poll 6. Apply the changes in +[P4012R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4012r1.pdf) +(Value-preserving consteval broadcast to `simd::vec`) to the C++ working paper. +This addresses ballot comment DE-286. + +LWG Poll 7. Apply the changes in +[P3886R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3886r0.pdf) +(Wording for AT1-057) to the C++ working paper. +This addresses ballot comment AT 1-057. + +LWG Poll 8. Apply the changes in +[P3936R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3936r1.pdf) +(Safer `atomic_ref::address` (FR-030-310)) to the C++ working paper +and update the value of the `__cpp_lib_atomic_ref` macro. +This addresses ballot comment FR-030-310. + +LWG Poll 9. Apply the changes in +[P4140R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4140r0.html) +(Proposed resolution for US70-126: allow incomplete types in type_order) to the C++ working paper. +This addresses ballot comment US 70-126. + +LWG Poll 10. Apply the changes in +[P3373R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3373r4.pdf) +(Of Operation States and Their Lifetimes) to the C++ working paper. +CA-338. + +LWG Poll 11. Apply the changes in +[P3986R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3986r1.pdf) +(A Wording Strategy for Inlinable Receivers) to the C++ working paper. +This addresses ballot comment CA-318. + +LWG Poll 12. Accept as a Defect Report and apply the changes in +[P3059R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3059r2.html) +(Making user-defined constructors of view iterators/sentinels private) to the C++ working paper. +This addresses ballot comment GB 09-257. + +LWG Poll 13. Accept as a Defect Report and apply the changes in +[P3725R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3725r3.pdf) +(Filter View Extensions for Safer Use, Rev 3) to the C++ working paper. +This addresses ballot comments AT9-249, RU-250, DE-251. + +LWG Poll 14. Apply the changes in +[P3828R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3828r1.pdf) +(Rename the to_input view to as_input) to the C++ working paper. +This addresses ballot comment DE-248. + +LWG Poll 15. Apply the changes in +[P3795R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3795r2.html) +(Miscellaneous Reflection Cleanup) to the C++ working paper. +This addresses ballot comments US 42-078 and US 85-150 and US 122-184 and US 128-192 and US 95-202 and US 131-195. + +LWG Poll 16. Apply the changes in +[P3948R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3948r1.pdf) +(`constant_wrapper` is the only tool needed for passing constant expressions +via function arguments) to the C++ working paper. +This addresses ballot comments FR-019-210 and FR-021-218. + +LWG Poll 17. Apply the changes in +[P3978R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3978r3.pdf) +(`constant_wrapper` should unwrap on call and subscript) to the C++ working paper. + +LWG Poll 18. Apply the changes in +[P3961R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3961r1.html) +(Less double indirection in `function_ref`) to the C++ working paper. +This addresses ballot comment RU-220. + +LWG Poll 19. Apply the changes in +[P3981R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3981r2.html) +(Better return types in `std::inplace_vector` and `std::exception_ptr_cast`) to the C++ working paper. +This addresses ballot comments PL-006 and US 68-122 and US 150-228 and GB 08-225. + +LWG Poll 20. Apply the changes in +[P4022R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4022r0.html) +(Remove `try_append_range` from `inplace_vector` for now) to the C++ working paper. +This addresses ballot comment PL-006. + +LWG Poll 21. Apply the changes in +[P4037R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4037r1.html) +(Supporting `signed char` and `unsigned char` in random number generation) to the C++ working paper. +This addresses ballot comment RU-272. + +LWG Poll 22. Apply the changes in +[P3450R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3450r1.html) +(Extend `std::is_within_lifetime`) to the C++ working paper. +This addresses ballot comment US 82-145. + +LWG Poll 23. Apply the changes in +[P3982R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3982r2.html) +(Split `strided_slice` into `extent_slice` and `range_slice` for C++26) to the C++ working paper. +This addresses ballot comment PL-007. + +LWG Poll 24. Apply the changes in +[P4144R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4144r1.html) +(Remove `span`’s `initializer_list` constructor for C++26) to the C++ working paper. + +LWG Poll 25. Apply the changes in +[P3804R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3804r2.html) +(Iterating on `parallel_scheduler`) to the C++ working paper. +This addresses ballot comment RO 4-395. + +LWG Poll 26. Apply the changes in +[P3787R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3787r2.html) +(Adjoints to "Enabling list-initialization for algorithms": uninitialized_fill) to the C++ working paper. +This addresses ballot comment FR-027-267. + +LWG Poll 27. Apply the changes in +[P3842R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3842r2.pdf) +(A conservative fix for constexpr uncaught_exceptions() and current_exception()) to the C++ working paper. +This addresses ballot comments PL-012 and GB 03-119 and DE-120 and US 67-118 and FI-121. + +LWG Poll 28. Apply the changes in +[P3826R5](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3826r5.html) +(Fix Sender Algorithm Customization) to the C++ working paper. +This addresses ballot comments US 207-328 and US 202-326 and FR-031-219 and FI-331 and CA-358. + +LWG Poll 29. Apply the changes in +[P3980R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3980r1.html) +(Task’s Allocator Use) to the C++ working paper. +This addresses ballot comments US 254-385 and US 253-386 and US 255-384 and US 261-391. + +LWG Poll 30. Apply the changes in +[P4156R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4156r0.html) +(Rename meta::has_ellipsis_parameter to meta::is_vararg_function) to the C++ working paper. +This addresses ballot comment FR-017-155. + +LWG Poll 31. Apply the changes in +[P3953R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3953r3.html) +(Rename `std::runtime_format`) to the C++ working paper. + +LWG Poll 32. Apply the changes in +[P4052R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4052r0.html) +(Renaming saturation arithmetic functions) to the C++ working paper. +This addresses ballot comment FR-026-265. + +LWG Poll 33. Apply the changes in +[P3941R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3941r4.html) +(Scheduler Affinity) to the C++ working paper. +This addresses ballot comments US 232-366 and US 233-365 and US 234-364 and US 235-363 and US 236-362. + +LWG Poll 34. Apply the changes in +[P3856R8](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3856r8.pdf) +(New reflection metafunction - is_structural_type) to the C++ working paper. +This addresses ballot comment US 49-090. + +LWG Poll 35. Apply the changes in +[P3927R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3927r2.html) +(`task_scheduler` support for parallel `bulk` execution) to the C++ working paper. +This addresses ballot comment US 238-368. + +LWG Poll 36. Apply the changes in +[P4151R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4151r1.pdf) +(Rename `affine_on`) to the C++ working paper. + +LWG Poll 37. Apply the changes in +[P4159R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4159r0.html) +(Make `sender_in` and `receiver_of` exposition-only) to the C++ working paper. + +LWG Poll 38. Apply the changes in +[P4154R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4154r0.html) +(Renaming various execution things) to the C++ working paper. +This addresses ballot comments US 205-320 and RO 4-395. + +## National body comment resolution + +A large number of national body comments for the C++26 Committee Draft have been +addressed in this working draft. + +### Editorial comments + +Most editorial national body comments were addressed before the Kona 2025 meeting, +see [Editor’s Report N5033](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5033.html) +for the full list. + +A few additional national body comments have since been found editorial +and have now been addressed: + + * CA 109 will be addressed for the DIS. + * US 084-151 [87a9fbb3cc85436d876e9c7a79ca1cfbb48ac150](https://github.com/cplusplus/draft/commit/87a9fbb3cc85436d876e9c7a79ca1cfbb48ac150) + * US 180-295 [731cda191b915555c6816912361e431c82e7e2f6](https://github.com/cplusplus/draft/commit/731cda191b915555c6816912361e431c82e7e2f6) + * US 213-353 [8cef46b15b21d4ab1b96dce04c0d37e511d1ddc2](https://github.com/cplusplus/draft/commit/8cef46b15b21d4ab1b96dce04c0d37e511d1ddc2) + +### Non-editorial comments + +The following national body comments were addressed by the motions approved at the Croydon 2026 meeting: + + * AT 001-057 via [LWG Poll 7](http://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3886r0.pdf) + * AT 002-089 via [CWG Poll 3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4160r0.html) + * AT 008-279 via [LWG Poll 3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3690r1.pdf) + * AT 009-249 via [LWG Poll 13](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3725r3.pdf) + * CA 318 via [LWG Poll 11](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3986r1.pdf) + * CA 338 via [LWG Poll 10](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3373r4.pdf) + * CA 358 via [LWG Poll 28](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3826r5.html) + * DE 087 via [CWG Poll 9](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3726r2.html) + * DE 120 via [LWG Poll 27](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3842r2.pdf) + * DE 248 via [LWG Poll 14](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3828r1.pdf) + * DE 251 via [LWG Poll 13](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3725r3.pdf) + * FI 121 via [LWG Poll 27](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3842r2.pdf) + * FI 331 via [LWG Poll 28](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3826r5.html) + * FR 003-031 via [CWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4160r0.html) + * FR 009-108 via [CWG Poll 5](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4136r2.pdf) + * FR 017-155 via [LWG Poll 30](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4156r0.html) + * FR 019-210 via [LWG Poll 16](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3948r1.pdf) + * FR 021-218 via [LWG Poll 16](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3948r1.pdf) + * FR 025-246 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * FR 026-265 via [LWG Poll 32](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4052r0.html) + * FR 027-267 via [LWG Poll 26](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3787r2.html) + * FR 030-310 via [LWG Poll 8](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3936r1.pdf) + * FR 031-219 via [LWG Poll 28](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3826r5.html) + * GB 003-119 via [LWG Poll 27](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3842r2.pdf) + * GB 005-129 via [LWG Poll 1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4145r0.html) + * GB 007-223 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * GB 008-225 via [LWG Poll 19](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3981r2.html) + * GB 009-257 via [LWG Poll 12](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3059r2.html) + * GB 011-302 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * PL 006 via [LWG Poll 19](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3981r2.html) and [LWG Poll 20](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4022r0.html) + * PL 007 via [LWG Poll 23](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3982r2.html) + * PL 008 via [LWG Poll 1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4145r0.html) + * PL 012 via [LWG Poll 27](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3842r2.pdf) + * RO 004-395 via [LWG Poll 25](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3804r2.html) + * RO 004-395 via [LWG Poll 38](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4154r0.html) + * RU 220 via [LWG Poll 18](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3961r1.html) + * RU 250 via [LWG Poll 13](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3725r3.pdf) + * RU 268 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * RU 272 via [LWG Poll 21](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4037r1.html) + * US 011-400 via [CWG Poll 4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3924r1.html) + * US 014-029 via [CWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4160r0.html) + * US 017-030 via [CWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4160r0.html) + * US 033-065 via [CWG Poll 10](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4143r0.html) + * US 042-078 via [LWG Poll 15](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3795r2.html) + * US 048-086 via [CWG Poll 9](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3726r2.html) + * US 049-090 via [LWG Poll 34](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3856r8.pdf) + * US 054-100 via [CWG Poll 11](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4149r1.html) + * US 057-105 via [CWG Poll 3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4160r0.html) + * US 067-118 via [LWG Poll 27](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3842r2.pdf) + * US 068-122 via [LWG Poll 19](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3981r2.html) + * US 070-126 via [LWG Poll 9](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4140r0.html) + * US 075-138 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * US 081-149 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * US 082-145 via [LWG Poll 22](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3450r1.html) + * US 085-150 via [LWG Poll 15](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3795r2.html) + * US 095-202 via [LWG Poll 15](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3795r2.html) + * US 100-207 via [LWG Poll 15](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3795r2.html) + * US 122-184 via [LWG Poll 15](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3795r2.html) + * US 128-192 via [LWG Poll 15](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3795r2.html) + * US 131-195 via [LWG Poll 15](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3795r2.html) + * US 135-216 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * US 136-217 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * US 139-232 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * US 142-236 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * US 150-228 via [LWG Poll 19](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3981r2.html) + * US 151-242 via [LWG Poll 1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4145r0.html) + * US 152-243 via [LWG Poll 1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4145r0.html) + * US 157-255 via [LWG Poll 1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4145r0.html) + * US 176-280 via [LWG Poll 1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4145r0.html) + * US 189-304 via [LWG Poll 1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4145r0.html) + * US 202-326 via [LWG Poll 28](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3826r5.html) + * US 205-320 via [LWG Poll 38](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4154r0.html) + * US 207-328 via [LWG Poll 28](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3826r5.html) + * US 232-366 via [LWG Poll 33](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3941r4.html) + * US 233-365 via [LWG Poll 33](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3941r4.html) + * US 234-364 via [LWG Poll 33](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3941r4.html) + * US 235-363 via [LWG Poll 33](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3941r4.html) + * US 236-362 via [LWG Poll 33](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3941r4.html) + * US 238-368 via [LWG Poll 35](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3927r2.html) + * US 242-372 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * US 249-379 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * US 253-386 via [LWG Poll 29](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3980r1.html) + * US 254-385 via [LWG Poll 29](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3980r1.html) + * US 255-384 via [LWG Poll 29](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3980r1.html) + * US 257-382 via [LWG Poll 2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4146r0.html) + * US 261-391 via [LWG Poll 29](http://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3980r1.html) + +## Editorial changes + +### Major editorial changes + +The subclause [expr.const], formerly titled “Constant expressions”, +has been renamed to “Constant evaluation” and its contents have been +divided into smaller subclauses; see commit +[98a668efc2ab0bea86dcf9a2d8bf583dddc35e32](https://github.com/cplusplus/draft/commit/98a668efc2ab0bea86dcf9a2d8bf583dddc35e32). + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N5008 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/n5032...n5046). + + commit cc2efebb57ea02ea2eac19220c873c158f855859 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Dec 15 15:43:02 2025 +0000 + + [basic.start.dynamic] Fix typo (#8654) + + commit 3e6cad293e448f7d9f9d859d07b5371b7e054789 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Dec 15 15:47:37 2025 +0000 + + [basic.types.general] Improve presentation of comments in example (#8636) + + - put "sizeof" in code font + - use a comma after "OK" + + commit f6319760f3f6d9a710fdb4be5e54c111abfc1e92 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 16:21:20 2025 +0000 + + [basic.link] Modernize wording about type aliases + + commit f66f4c675c0c60f822bb24543cd607e14be24a93 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 16:31:25 2025 +0000 + + [intro.memory] Update outdated example + + commit 176528f688cec22566f1de8286f1c3fae43887ce + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 16:46:10 2025 +0000 + + [intro.object] Remove redundant "non-bit-field" + + commit 1d9fdb066e95b7be58881f24977a20a51359097c + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 17:40:14 2025 +0000 + + [basic.types.general] Remove unused meta-variable + + commit 2dbe5a3247b100a6e4cdddab46eda5595d9d3de1 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Dec 15 21:58:39 2025 +0000 + + [basic.start.dynamic] Add cross-reference for "interface dependency" (#8653) + + commit 166fd7efa129ce139e2a859758410fd7fd0955b3 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Dec 15 20:46:26 2025 +0100 + + [exec.scope.concepts] Fix typos + + commit d8a8c5ad3b354087a416c02c2059b9ef62534c72 + Author: A. Jiang + Date: Thu Apr 25 00:30:02 2024 +0800 + + [expos.only.entity] Say typedef-names are declared + + Also use "provided for exposition only" from @W-E-Brown's suggestion. + + commit 7fcd646f6d82721e32f5fb5dc11994b8b0cf1d64 + Author: A. Jiang + Date: Thu Aug 3 00:37:14 2023 +0800 + + [type.descriptions.general] Use "shown" for impl-def types + + commit 34c7cffe9e7d1807df4b986e648392bb3a1dfae0 + Author: A. Jiang + Date: Thu Aug 3 00:38:04 2023 +0800 + + [enumerated.types] Reword enumerated types + + Also mention [re]. + + commit cc2ecb3a2c85b2e196ca5697287270e9f62878c8 + Author: A. Jiang + Date: Thu Aug 3 00:38:45 2023 +0800 + + [bitmask.types] Reword bitmask types + + commit 03545f10f200193e15d3f0227b289ff037146abf + Author: A. Jiang + Date: Thu Apr 25 00:33:17 2024 +0800 + + [extern.types] Use "declared" for C library types + + commit d21a84cc95a9a3e619139a1c53d7937474ea03b8 + Author: A. Jiang + Date: Fri Jul 28 23:51:45 2023 +0800 + + [cstdint.syn] Use "declare" for typedef-names + + commit ad83c0b2bc498eac0fc4d97850143581dbfa703c + Author: A. Jiang + Date: Fri Jul 28 23:52:27 2023 +0800 + + [stdfloat.syn] Use "declare" for typedef-names + + commit 30000d169f5b6db54d7d61ed35aa825fbbdfa70d + Author: A. Jiang + Date: Fri Jul 28 23:58:28 2023 +0800 + + [meta.rqmts] Use "declare" for typedef-names + + commit c5eac2a7d176110d63e153fa1d5abcee9681943e + Author: A. Jiang + Date: Sat Jul 29 00:02:58 2023 +0800 + + [meta.trans.other] Use "declare" for typedef-names + + In the example, it seems a bit verbose to say "declarations and + definitions". + + commit cbd6e735fdea46f312d27ae802e83766d8dc43f8 + Author: A. Jiang + Date: Sat Jul 29 00:03:49 2023 +0800 + + [ratio.si] Use "declare" for typedef-names + + commit 8210a2cc6ff0bb2a90c9b20cf60ee1d369156c4b + Author: A. Jiang + Date: Sat Jul 29 00:12:12 2023 +0800 + + [readable.traits] Use "declare" for typedef-names + + commit c5b55216c7a80fe7187bdbc4f5e62b6ef53e6008 + Author: A. Jiang + Date: Sat Jul 29 00:14:51 2023 +0800 + + [iterator.traits] Use "declare" for typedef-names + + commit b892cf9dd9a5d0e8d9046d0e99b72487f3316b51 + Author: A. Jiang + Date: Sat Jul 29 00:16:03 2023 +0800 + + [std.iterator.tags] Use "declare" for typedef-names + + commit 535f5a348bf4eab6c0d71673209bc853103880c2 + Author: A. Jiang + Date: Wed Apr 24 00:28:25 2024 +0800 + + [const.iterators.types] Avoid "defining" `iterator_category` + + Use "declare" instead. + + commit af81d11662c4b7dfb135176c5282788f6e3f50d4 + Author: A. Jiang + Date: Wed Apr 24 00:28:58 2024 +0800 + + [move.iterator] Avoid "defining" `iterator_category` + + Use "declare" instead. + + commit 45a31c6e70f49792ee3650a106ad03a8a95d7e03 + Author: A. Jiang + Date: Wed Apr 24 00:29:32 2024 +0800 + + [common.iter.types] Avoid "defining" typedef-names + + commit 5253ec6c6229c704303d682c4bd1d0e197506716 + Author: A. Jiang + Date: Wed Apr 24 00:30:51 2024 +0800 + + [range.filter.iterator] Avoid "defining" typedef-names + + Use declared" instead. + + commit 251d0c7ef52327f628086e228a244792a467f27c + Author: A. Jiang + Date: Wed Apr 24 00:31:39 2024 +0800 + + [range.transform.iterator] Avoid "defining" typedef-names + + Use "declare" instead. + + commit 1fa1d4afe6111b03aeec7ced79ed0bf7f6a2569b + Author: A. Jiang + Date: Wed Apr 24 00:32:17 2024 +0800 + + [range.join.iterator] Avoid "defining" typedef-names + + Use "declare" instead. + + commit 55e740c366d1c691c31fda455f6acfcfe7e60979 + Author: A. Jiang + Date: Wed Apr 24 00:33:09 2024 +0800 + + [range.join.with.iterator] Avoid "defining" typedef-names + + Use "declare" instead. + + commit ff0957c1a71f4b668acf9d316efcb31d59495398 + Author: A. Jiang + Date: Wed Apr 24 00:45:09 2024 +0800 + + [range.concat.iterator] Avoid "defining" typedef-names + + Use "declare" instead. + + commit 293648ef77f2533187a1ca89f9649c21da0c06b1 + Author: A. Jiang + Date: Wed Apr 24 00:33:37 2024 +0800 + + [range.elements.iterator] Avoid "defining" typedef-names + + Use "declare" instead. + + commit ae40e054b0ad38993c52f454862682bcdd3bee14 + Author: A. Jiang + Date: Wed Apr 24 00:34:43 2024 +0800 + + [range.zip.transform.iterator] Avoid "defining" `iterator_category` + + Use "declare" instead. + + commit 20564e2186a5f237f1a89fb0b470eb19f662fe2d + Author: A. Jiang + Date: Wed Apr 24 00:35:44 2024 +0800 + + [range.stride.iterator] Avoid "defining" typedef-names + + Use "declare" instead. + + commit da9cc238aa051d127e7ea0d196622a161cab77f1 + Author: A. Jiang + Date: Thu Oct 17 19:19:03 2024 +0800 + + [format.string.std] Use "declare" for typedef-names + + commit b77796b42a5d2854a186858d8a36c558ddc18da4 + Author: A. Jiang + Date: Sat Jul 29 00:47:45 2023 +0800 + + [atomics.alias] Use "declare" for typedef-names + + commit ae8e81dfc21ead75c8d4fcfdb75c4638b14a7fdb + Author: A. Jiang + Date: Sat Jul 29 00:48:28 2023 +0800 + + [stdatomic.h.syn] Use "declare" for typedef-names + + commit 7d4d7f37aa2122fe6e292fcc9520b022fba70d13 + Author: Hubert Tong + Date: Fri Dec 19 03:50:07 2025 -0400 + + [expr.const] Fix typo "with [...]" => "within the evaluation" (#8669) + + commit e9fa860d3af7236fbe43d56ffef4abec93b6a0c9 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 23:54:38 2025 +0000 + + [basic.contract.eval] Replace "operation" with "evaluation" + + commit 4dc76ac3cc9895782b199af745dd42614a7d0327 + Author: Hewill Kang + Date: Tue Dec 23 01:15:15 2025 +0800 + + [flat.multiset.modifiers] Add missing constexpr (#8675) + + commit a4fbfa2a689dbd2f0d7a16b29af92dc74574381d + Author: Andrey Ali Khan Bolshakov + Date: Tue Dec 23 09:57:57 2025 +0300 + + [time.syn] Add missing namespace qualification (#8677) + + commit 7abca25d03460cd35e880f29fc7001c69218594a + Author: Alisdair Meredith + Date: Tue Dec 23 13:21:13 2025 -0500 + + [expr.new] Precise cross-reference for throwing exceptions (#8681) + + commit db380b0d4015eb7d2956e73e59c1c5c26f3651a4 + Author: A. Jiang + Date: Mon Dec 29 09:54:10 2025 +0800 + + [version.syn] Reformat a comment to avoid splitting `` + + Co-authored-by: Alisdair Meredith + + commit c59d8c8e9d6fe8adba2142d1344b0e142c9d6ff4 + Author: A. Jiang + Date: Mon Dec 29 09:54:36 2025 +0800 + + [initializer.list.syn] Drop redundant comments + + commit 3dc04f5cda1c8470c0da7c6f9ffcd6d463429ef2 + Author: Hana Dusíková + Date: Fri Jan 2 16:35:49 2026 +0100 + + [hive.cons] Fix typo "allocator_traits" -> "allocator_traits" (#8689) + + commit 7c8a960f3f06d5c565b0976402ce534848926181 + Author: Hewill Kang + Date: Sat Jan 24 00:52:07 2026 +0800 + + [forward.list.overview] Add missing constexpr (#8717) + + commit f3b76296f598bc5266e649f8fb0a2c5ef19ae0c3 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jan 26 15:52:54 2026 +0100 + + [temp.dep.type] Add period to end of sentence (#8723) + + commit 6704d82cd336baaa4f6fe45013c390453991ee86 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Jan 30 21:57:16 2026 +0100 + + [except.handle] Add commas (#8727) + + commit 16f4265888fd30e59512a21a5391327d6b525de1 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat Jan 31 19:28:43 2026 +0100 + + [value.error.codes] Fix indefinite article (#8730) + + commit 91156093a76177329a990dfdf38f19dad3531688 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Feb 3 23:19:25 2026 +0100 + + [concept.comparisoncommontype] Add period to end of sentence (#8731) + + commit 15fc5a2f7106963d8e7904eee03bebe2aaf7a81b + Author: Giuseppe D'Angelo + Date: Sun Feb 22 20:45:53 2026 +0100 + + [alg.remove] Use E(i) for predicate on iterator i (#8760) + + The `E` in the code is actually meant to be a function on an + iterator `i`; amend both usages to `E(i)`. This was already done + everywhere else (for instance in copy_if or unique_copy). + + commit 5b07f42565be7972f2b5d729a740da12c5e6b202 + Author: Jonathan Wakely + Date: Tue Feb 24 10:35:57 2026 +0000 + + [thread.mutex.requirements.mutex.general] Fix grammar (#8765) + + commit 4ce955bd576f6a9d68da494e8b560ca8b9375005 + Author: Jonathan Wakely + Date: Tue Feb 24 10:38:03 2026 +0000 + + [exec.snd.expos] Fix order of make_obj_using_allocator arguments (#8766) + + commit 3f6372b97bcdee30b8591077c8479a56bb50fc67 + Author: timsong-cpp + Date: Wed Feb 25 15:35:49 2026 -0600 + + [const.wrap.class] Add missing this to compound assignment operators (#8758) + + This corrects a misapplication of LWG4383 in commit bdcfe2c9a54ca350e9bfc59227bb0285a59c635d. + + commit 8338b7caa5a38ef79e5c2f8316078f6f74d1b8ad + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Mar 5 08:58:29 2026 +0100 + + [text.encoding.id] Add colon after "as follows" (#8776) + + commit eba89bc9b32d230168571737d6aa86c06329502b + Author: Alisdair Meredith + Date: Mon Dec 22 17:59:19 2025 -0500 + + [lex.phases] Make note on the notion of file more prominent + + The notion that when the standard refers to files does not + necessarily imply a file in a traditional filing system is + more fundamental than its late appearance in the middle of + phase 7 of translation. Move that note right to the top of + [lex] where we first talk of storing the program text in + source files, where is will be understood even before the + phases of translation. + + commit 13cad628c5c3883c8fb8dcb4256199b21c13be1d + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Mar 12 08:08:56 2026 +0100 + + [istream.unformatted] Add right parenthesis + + commit 981d32246c951b18dc816cecfdb3ffbb5d72ad54 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Mar 17 21:04:34 2026 +0100 + + [stoptoken.concepts] Remove superfluous \item (#8790) + + commit 92b3a22228ffb3db219debace0e5fbe82c592354 + Author: Can + Date: Fri Mar 20 10:32:30 2026 +0300 + + [utility.intcmp] Fix name of type parameter (#8770) + + Introduced by commit 93914a36c1945d330a7c7d5c4488e1d10e5bbe75 . + + commit 11106fc54b79e1ee21805ea77596908ca4f3a8f3 + Author: Abhinav Agarwal + Date: Fri Mar 20 10:56:06 2026 -0700 + + [mdspan.sub.map.common,mdspan.sub.map.left] Fix S(p)liceSpecifiers typos (#8799) + + commit 36ce9cbe82d472997ca9b978e69e64d6ddd99dcd + Author: Abhinav Agarwal + Date: Fri Mar 20 10:56:49 2026 -0700 + + [linalg.algs.blas3.rank2k] Add missing \pnum and \effects (#8801) + + commit cda7c18d2b83b354bae6001cdf7cb7d3f9203f32 + Author: A. Jiang + Date: Sat Mar 21 17:36:47 2026 +0800 + + [lib] Replace bad uses of "instantiation" with "specialization" (#8379) + + Affected sections: + - [allocator.requirements.general] + - [namespace.std] + - [pointer.traits.types] + - [allocator.traits.types] + - [tuple.general] + - [format.context] + - [numeric.requirements] + - [rand.util.canonical] + - [thread.req.lockable.timed] + - [thread.sharedtimedmutex.requirements.general] + + - In [tuple.general], change "is similar to" to "behaves similarly to" + to avoid confusing with "similar types" in the core specification. + + commit dc5928bdac7e3301d78c8fae5f4cae655a9a06fb + Author: A. Jiang + Date: Sun Mar 22 14:14:40 2026 +0800 + + [vector.bool.fmt][container.adaptors.format] Add missing `constexpr` and other missed edits (#8768) + + Fixes edits from P3391R2 missed by commit cc63c64cba30089a366b024ffc8cc0532b4fb508 . + + commit c6fecf491063eef95384e54813812f6c6aaeab6a + Author: Thomas Köppe + Date: Mon Mar 23 11:40:36 2026 +0000 + + [expected.object.eq] Add missing negation (misapplied wording). + + The negation was accidentally omitted in the application of P3905R0, + approved in Kona 2025 (265b4774c754b36e50bec7a528cbbc87676b0c85). + + commit 6913287752040f7adecdac5af60c90e2701a04e0 + Author: A. Jiang + Date: Wed Feb 25 15:04:34 2026 +0800 + + [format] Consistently add `constexpr` to function descriptions + + P3391R2 only added `constexpr` to synopses but not descriptions for some + formatting functions. This PR consistently adds `constexpr` to the + descriptions. + + commit 45c820b6a9d87b18f3ad5c445c5e61e2ee806a6d + Author: Hubert Tong + Date: Tue Dec 16 23:52:12 2025 -0500 + + [diff.basic] Use enum example instead of example outdated since C99 + + C99 subclause 6.2.7, "Compatible type and composite type", had this + sentence: + > If one is declared with a tag, the other shall be declared with the + > same tag. + + commit 3e53098c0ef22b62ab2dd393411141fceeda03bd + Author: Hubert Tong + Date: Tue Dec 16 23:57:14 2025 -0500 + + [diff.basic] Stop claiming, as harmless, type-based aliasing violations + + commit c40c5f03a02c7e0f2564de46aea4ceebb1c799e4 + Author: Jan Schultke + Date: Fri Feb 13 12:21:45 2026 +0100 + + [intro.compliance.general] Mark documentation encouragement as recommended practice + + commit d8ff3c08615932a207f956a61ebd6e5805f9a9bd + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 17:15:48 2025 +0000 + + [basic.stc.dynamic] Spell out compound type names + + commit e70a19ba60ccf3eeed62bf82e4b33584272a1c86 + Author: Jens Maurer + Date: Thu Feb 26 08:30:31 2026 +0100 + + [lex.key] Emphasize that keywords are created in phase 6 + + This was overlooked in CWG3094, applied with commit 94055b39a90285d8ae15f8f864a39a328f42a359. + + commit 0807a339b8bcae60a9d2285f0a08aab61aeece0d + Author: Barry Revzin + Date: Thu Jan 29 07:59:28 2026 -0600 + + Clarify pack-index-specifier rules + + commit f55d63dcef1640f292451a3efe98f56d4afa2383 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 17:56:03 2025 +0000 + + [basic.fundamental] Strike explanatory sentence; touch up note + + commit f4d8ecb2aa29122d63e5f56119a83dd4bb2ad3ca + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 18:23:18 2025 +0000 + + [basic.extended.fp] Replace "typedef-name" with "type alias" + + commit 2efe693eb09f8c6d364c757a82b640e2ced9f107 + Author: Eisenwave + Date: Wed Dec 17 14:32:48 2025 +0100 + + [intro.refs], [numeric.limits] Remove all references to ISO/IEC 10967-1:2012 + + commit b54449db95dcdfa8ae4d8221ef55f7fca0f358d9 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 23:06:53 2025 +0000 + + [basic.start.static] Improve readability of example + + commit cd15f7a88e6390fb31aa766196205e722779d240 + Author: Hubert Tong + Date: Thu Dec 18 19:41:46 2025 -0500 + + [stmt.pre] Streamline decl-specifier restrictions on conditions, etc. + + Avoid an abrupt shift from a mathematical introduction to the + specification of additional normative requirements. + + Expresses universal quantification more directly. + + commit d3f57042d283c06cdb066eab1fc61661df0fc4de + Author: Eisenwave + Date: Sun Jul 23 14:23:21 2023 +0200 + + [temp.point] Itemize long conditionals in three paragraphs + + commit ecc669c503bb875b65cbd4de3d231a8ac9e4bb70 + Author: Hewill Kang + Date: Tue Mar 10 15:07:57 2026 +0800 + + [meta.syn] Add function parameter names + + These two seem to be the only ones where the function parameter names are omitted in the declaration. + Add names to ensure consistency. + + commit 98a668efc2ab0bea86dcf9a2d8bf583dddc35e32 + Author: Jens Maurer + Date: Thu Mar 26 21:57:48 2026 +0100 + + [expr.const] Introduce subclauses + + commit a2933d5fd4e592bcd8669a51a359c5a850b32de2 + Author: Davis Herring + Date: Thu Mar 26 21:00:20 2026 +0000 + + Refine cross references into [expr.const] + + commit 13906dcab8cfb87f880ea444336cbcc37165cd67 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Dec 11 14:14:32 2025 +0000 + + [basic.lookup.unqual] Rephrase to avoid incorrect use of term + + commit ad94af979e8dfac9ca9af4aa22c66beec7935cfd + Author: A. Jiang + Date: Wed Mar 25 21:05:15 2026 +0800 + + [iostream.forward.overview] Add missing mentions of spanbuf and spanstreams + + A follows up to P0448R4. + + commit 6a31f94c5ef15fdb592c558cd63b2bd02bd18c8a + Author: A. Jiang + Date: Wed Mar 25 21:05:37 2026 +0800 + + [iostream.forward.overview] Say "designate specialization". + + This replaces the imprecise and informal phrase "define instances of + class templates". + + commit 731cda191b915555c6816912361e431c82e7e2f6 + Author: Matthias Kretz + Date: Tue Nov 4 05:17:01 2025 -1000 + + [simd.permute.*] Change M back to V since the wording refers to V + + This was changed editorially by b6e501026e14600fed911183336266c0ebdf5728 + as part of "2025-06 LWG Motion 13: P3691R1 Reconsider naming of the + namespace for std::simd", but turned out not to be a helpful change, + because it makes other wording more complex. + + Fixes NB US 180-295 (C++26 CD). + + commit 7f3b7c64a18610948bfc5479a90764f4992731bd + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 22:00:24 2025 +0000 + + [intro.races] Fix typo + + commit e1ee86a3c373c53db7b5d6289457eed620862c76 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Mar 27 13:17:33 2026 +0100 + + [simd.syn,simd.permute.mask] Change M::value_type& to V::value_type& + + commit 8cef46b15b21d4ab1b96dce04c0d37e511d1ddc2 + Author: Jens Maurer + Date: Mon Oct 6 00:24:35 2025 +0200 + + [exec.snd.expos] Reorder specification immediately after declaration + + Fixes NB US 213-353 (C++26 CD). + + commit 6fc165022194a0dd3b78287b087e7872c6c88f48 + Author: Thomas Köppe + Date: Fri Mar 27 11:58:32 2026 +0000 + + [exec.get.compl.sched] Rename completion-tag to completion-fn-tag and reorder text. + + The renaming avoids a clash with the concept "completion-tag" defined + in [exec.snd.expos]. The reordering makes it so that names are defined + before they are referenced. + + commit deb2a9b40a46062dd76a1bbc968ff5039cb02aaf + Author: Thomas Köppe + Date: Sat Mar 28 08:56:40 2026 +0000 + + [exec.snd.expos] Delete unused expos-only concept "completion-tag". + + Also insert a missing \pnum before the now-split codeblock (see 8cef46b15b21d4ab1b96dce04c0d37e511d1ddc2). + + commit fda5e3771f85dfea6d7bd8ade0577e82886addc0 + Author: Abhinav Agarwal + Date: Fri Mar 20 02:36:07 2026 -0700 + + [dcl.struct.bind] Fix tuple-like binding index to use SB_i instead of v_i + + P1061R10 introduced the SB_i notation for post-expansion structured bindings + but this sentence was not updated. The rest of the section (p6, p8, and the + end of this same paragraph) already uses SB_i. + + commit 42f878f50d1356866b5aebe520a3138f707919a0 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Dec 15 00:01:35 2025 +0000 + + [basic] Do not hyphenate "potentially evaluated" + + commit 70e753882b290ea432e516b75fd924bc687076be + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Dec 15 00:03:46 2025 +0000 + + [expr] Do not hyphenate "potentially evaluated" + + commit d296b82c70dcf49a7a10a100778ecd6aed4c92c7 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Dec 15 00:04:54 2025 +0000 + + [dcl] Do not hyphenate "potentially evaluated" + + commit 9ad63b74fae211473235c8fa087d19d392c04728 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Dec 15 00:05:31 2025 +0000 + + [temp.over.link] Do not hyphenate "potentially evaluated" + + commit 180830c280023ea63165547b937da8265b6bd667 + Author: S. B. Tam + Date: Fri Apr 3 21:10:21 2026 +0800 + + [mdspan.mdspan.cons] Fix typo (`is_nothrow_constructible` => `is_nothrow_constructible_v`) + + commit c52c49ab2bcb5770ec2190f3381051442e037157 + Author: Thomas Köppe + Date: Mon Apr 20 01:49:17 2026 +0100 + + [task.promise] Delete unused definition of expos-only error-variant. + + The changes from LWG 4339 removed the use of this type alias, + but not its definition. + + commit ec642cdab87f6f83392196a1600d19d893c17b08 + Author: Thomas Köppe + Date: Sun Apr 12 20:52:51 2026 +0100 + + [mdspan.syn] Renamed template parameter from "Slices" to "SliceSpecifiers". + + The latter form is used everywhere else, including in the item's itemdecl. + + commit bcb6a56a5d2bef008ed02de89b50acdd7e8b8b1d + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Apr 20 18:47:33 2026 +0200 + + [exec.get.domain] Remove extraneous period after list (#8956) + + commit 6fd25df420db99ce2607b7ce3741f4d1891d0ceb + Author: Jens Maurer + Date: Sun Feb 22 19:14:40 2026 +0100 + + [temp.deduct.conv] Add comma to structure the sentence + + commit 25182503a4a94a3fb56c48c80fca56a713095882 + Author: Jens Maurer + Date: Thu Apr 16 17:25:53 2026 +0200 + + [cpp.pre] Remove confused footnote about 'lines' + + commit cd6c5bf4871a80b1e865f85a7e1e104036ce2869 + Author: Jay Ghiron <55773281+Halalaluyafail3@users.noreply.github.com> + Date: Mon Apr 20 12:52:13 2026 -0400 + + [diff.expr] Update incorrect comment about C (#8933) + + arr2 is a constraint violation in C, rather than being valid. + + commit 9909e30038ee608225a67f62b355a60d1a679325 + Author: Hewill Kang + Date: Thu Apr 16 21:22:13 2026 +0800 + + [mdspan.layout.leftpad.obs, mdspan.layout.rightpad.obs] Fix return type of operator() + + commit 1651c628caed73f26e120a604eca6798f4da6afc + Author: Hewill Kang + Date: Tue Apr 21 04:40:40 2026 +0800 + + [linalg] Add period after \returns statement on same line (#8950) + + commit 6211dc859a519b7ff5cca0bfbd953f3b4bd73450 + Author: Hewill Kang + Date: Wed Apr 8 12:19:17 2026 +0800 + + [linalg.scaled.scaledaccessor,linalg.conj.conjugatedaccessor] Added missing typename + + commit 0a236f9185a2e59c7a49b5439135ee995460bcd6 + Author: A. Jiang + Date: Tue Apr 21 20:02:56 2026 +0800 + + [numarray] Remove incorrect comments for deleted default constructors (#8962) + + commit 1e747bf358e4546e9661c6bcee01a1dd71d2186f + Author: Tymi + Date: Tue Apr 21 21:58:09 2026 +0200 + + [fs.class.path] Use "typedef-name" instead of "typedef" (#8964) + + commit 240dc1f4e197dac0004fb5b171ea7c717fba89c9 + Author: timsong-cpp + Date: Tue Apr 21 21:51:27 2026 -0500 + + [meta.define.static] Move misplaced \end{codeblock} + + commit c07075ab7018c7a88d0d254c4c9262d9a6978c94 + Author: timsong-cpp + Date: Tue Apr 21 22:14:11 2026 -0500 + + [meta.define.static] Rephrase sentence to avoid overfull \hbox + + commit 259dcba53500aa26b555f1f952382f484a904cd1 + Author: Hewill Kang + Date: Wed Apr 22 21:46:07 2026 +0800 + + [mdspan.syn, mdspan.sub.range.slices] Remove redundant std + + commit 3532b45c6d9dd37d3f9f949b8307960b7a53eff0 + Author: Hewill Kang + Date: Thu Apr 23 00:30:10 2026 +0800 + + [mdspan.sub.helpers] Use period for \returns (#8977) + + commit e3a17c5b35d7903f85ff136aeaf9000e6b081517 + Author: Jens Maurer + Date: Thu Apr 23 21:50:58 2026 +0200 + + [utility.arg.requirements] Strike redundant text about core language rules (#8987) + + commit 3b5d4f6e215c9fad9472ce1d748cf74b90817ad2 + Author: A. Jiang + Date: Fri Apr 24 03:58:27 2026 +0800 + + [format.arguments, depr.format.arg] Apply `\exposid` consistently (#8971) + + Co-authored-by: Alisdair Meredith + Co-authored-by: Jonathan Wakely + Co-authored-by: Johel Ernesto Guerrero Peña + + commit 673a0e4fc97da58665e7f69e00b0f70e5924795e + Author: A. Jiang + Date: Fri Apr 24 17:47:21 2026 +0800 + + [re.tokiter.general] Fix incorrect `suffix.match` to use `.matched` (#8988) + + commit 663b952c59c4b77e233179189f410ce1d952ea59 + Author: timsong-cpp + Date: Fri Apr 24 12:02:16 2026 -0500 + + [meta.define.static] correct note after CWG3141 + + commit fecad5839345644f30f8b5d9c1043e2a4e666fc8 + Author: Thomas Köppe + Date: Sun Apr 26 15:30:37 2026 +0100 + + [basic.compound] Add missing \grammarterm. + + Misapplication of CWG Motion 1, Issue CWG 2765. + + Addresses editorial review committee feedback. + + commit d3128aacb391726a0c15b8649f9c8e2ca199789e + Author: Thomas Köppe + Date: Sun Apr 26 15:34:23 2026 +0100 + + [bit.cast] Update cross-reference into [expr.const] following 98a668efc2ab0bea86dcf9a2d8bf583dddc35e32. + + The editorial change was made after the wording of CWG 2765 was written. + + Addresses editorial review committee feedback. + + commit 5c2c9dd250af893345b6dbb28c793d8894d4b3c8 + Author: Thomas Köppe + Date: Sun Apr 26 15:50:02 2026 +0100 + + [expr.prim.splice] Add missing maths font for variable "C". + + Misapplication of P3598R0 in CWG Motion 8. + + Addresses editorial review committee feedback. + + commit 8425e4a1c4fa7c928b33c6796b45cfd81d15160a + Author: Thomas Köppe + Date: Sun Apr 26 16:05:53 2026 +0100 + + [lex.phases] Update cross-reference into [expr.const] following 98a668efc2ab0bea86dcf9a2d8bf583dddc35e32. + + The editorial change was made after the wording of P4143R0 was written. + + Addresses editorial review committee feedback. + + commit 01296b2d6e73ade37803f9721de7bdad437b4e3b + Author: Thomas Köppe + Date: Sun Apr 26 16:09:52 2026 +0100 + + [temp.inst] Add missing \grammarterm. + + Misapplication of CWG Motion 11, P4149R1. + + Addresses editorial review committee feedback. + + commit d5078b039da4e188f5de51682c2219f26b8367f9 + Author: Thomas Köppe + Date: Sun Apr 26 16:20:12 2026 +0100 + + [exec.spawn.future] Add missing \exposid. + + Misapplication of LWG Motion 2, Issue LWG 4540. + + Addresses editorial review committee feedback. + + commit 89cc24e855b5a89f099859685fc21fb37f03a36c + Author: Thomas Köppe + Date: Sun Apr 26 16:24:46 2026 +0100 + + [algorithm.syn] Remove stray comma. + + This seems to be an error in the wording of LWG 4544 (LWG Motion 2). + + Addresses editorial review committee feedback. + + commit 83f5072a59b06575d1108e7f63ef28b00fb4e4b2 + Author: Thomas Köppe + Date: Sun Apr 26 18:39:03 2026 +0100 + + [simd.math] Remove stray '@'s. + + Addresses editorial review committee feedback. + + commit ef5f532d2530a733011b0d606dfe69b952c718f6 + Author: Thomas Köppe + Date: Sun Apr 26 18:46:26 2026 +0100 + + [simd.math] Remove stray '\' (unintended escaping). + + Addresses editorial review committee feedback. + + commit d706f2d4fa89e7bcaa54338b9619ead9add59c67 + Author: Thomas Köppe + Date: Sun Apr 26 18:49:24 2026 +0100 + + [simd.math] Better linebreaking/whitespacing in remquo description. + + Addresses editorial review committee feedback. + + commit 9c5becee9a6ca91aad690074069be058f780006f + Author: Thomas Köppe + Date: Sun Apr 26 21:12:54 2026 +0100 + + [simd.expos{,defn}] Fixed template parameter "class T" => "size_t Bytes". + + Misapplication of P3932R0 in LWG Motion 5. + + Addresses editorial review committee feedback. + + commit 120d987ce6a376f1d56b84041d8e69aefaa436ec + Author: Thomas Köppe + Date: Sun Apr 26 21:21:12 2026 +0100 + + [exec.let] Fix misspelled "declval" use. + + Misapplication of P3826R5 in LWG Motion 28. + + Addresses editorial review committee feedback. + + commit daffae75c71890ca82c5021404c9a005e8038405 + Author: Thomas Köppe + Date: Sun Apr 26 21:24:42 2026 +0100 + + [exec.let] Add missing '\exposid's. + + Misapplication of P3373R4 in LWG Motion 10. + + Addresses editorial review committee feedback. + + commit 39a5cd65c6c2af9a251b8d2d5c7d5e73e86c9fa5 + Author: Thomas Köppe + Date: Sun Apr 26 22:24:30 2026 +0100 + + [dcl.attr.annotation] Add missing "codeblock" environment. + + Misapplication of P3795R2 in LWG Motion 15. + + Addresses editorial review committee feedback. + + commit 33a4bec49725127d2e1942f2b074d17242bc0458 + Author: Thomas Köppe + Date: Sun Apr 26 22:30:48 2026 +0100 + + [basic. link] Add "ANN" element to the "data member description sextuple. + + This was missed by P3795R2 in LWG Motion 15, presumably by accident. + + Addresses editorial review committee feedback. + + commit f8e7a0665d9919af4b680d60b07dbb322ee1d4cb + Author: Thomas Köppe + Date: Sun Apr 26 23:10:01 2026 +0100 + + [func.ref.wrap.ctor] Add missing ".value" + + Misapplication of P3948R1 in LWG Motion 16. + + Addresses editorial review committee feedback. + + commit d7c02a0f5c21cd235a0ed3921a30b19d75771f2e + Author: Thomas Köppe + Date: Sun Apr 26 23:36:15 2026 +0100 + + [mdspan.sub.overview] Fix missing edits and missing maths font. + + Misapplication of P3982R2 in LWG Motion 23. + + Addresses editorial review committee feedback. + + commit 2a8305d4b5bdf40b9e4e602d30a08e5fed6dd87b + Author: Abhinav Agarwal + Date: Sun Apr 26 16:10:39 2026 -0700 + + [mdspan.sub.map.sliceable] Fix M::extent_type to M::extents_type + + Layout mapping types expose extents_type, not extent_type; the + latter is a member of extent_slice. As written, IT and M_rank + in the Let clause name an undefined member. + + commit 368af317f557650b4d3dcf98379f02ef3d00140e + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sat May 2 07:41:44 2026 +0000 + + [basic.def] Mark definition of "redeclaration" as such (#8596) + + commit 75b6c6535f5115750bcaa588ded5dfa99eb5fa24 + Author: Guyutongxue + Date: Tue Apr 28 16:40:13 2026 +0800 + + [algorithm.syn] Add missing semicolon and right angle bracket + + commit 25401da54dcf000fa09105a8dc3cdcf788d753d5 + Author: Guyutongxue + Date: Tue Apr 28 16:42:37 2026 +0800 + + [map.overview] Add missing right angle bracket + + commit eaa1458d9832084f56f22d60dde77ed2a95b9b7e + Author: Guyutongxue + Date: Tue Apr 28 16:43:27 2026 +0800 + + [exec.snd.expos] Add missing left brace + + commit 9e15aa83cc1fd4efb06afdb861ebaf6e05f261bd + Author: Guyutongxue + Date: Tue Apr 28 16:45:11 2026 +0800 + + [rand.eng.philox, simd.syn] Fix misplaced right angle bracket, missing comma in `hypot`, `lerp` and `fma` + + commit f0c6e9e9af125c133dba0336797e2193d7d2cc2e + Author: Guyutongxue + Date: Tue Apr 28 16:45:45 2026 +0800 + + [range.filter.sentinel] Add missing semicolon + + commit 0fcd7084a93a5bfbbfe177cd9c6859eeca63439a + Author: Guyutongxue + Date: Tue Apr 28 16:46:20 2026 +0800 + + [atomics.types.float] Fix typo of `floating-point-type` + + commit 1a12df96659d230a376a3da4a2bae3cfc4cd57cb + Author: Thomas Köppe + Date: Sat May 2 15:39:57 2026 +0100 + + [exec.get.compl.{domain,sched}] Replace "it" and long expression with "the expression". + + In e82e850497facd0b9f1e65f4de75b475ddde42ed I had shortened a long + expression from the incoming paper in [exec.get.compl.domain] to just + "it". In review it was suggested that "the expression" is clearer, and + that similar wording in [exec.get.compl.sched] should use the same style. + + (Overall, I think it is easier to understand that the shorter + reference refers to the same expression than to have to compare + two long expressions and determine that they are equal.) + + Addresses editorial review committee feedback. + + commit 65970a5aad6e50048dce1a0b4398d63b8a09ea44 + Author: Thomas Köppe + Date: Sat May 2 15:50:08 2026 +0100 + + [exec.get.compl.domain] + + Misapplication of P3826R5 in LWG Motion 28. + + Addresses editorial review committee feedback. + + commit fa590b2628d9a21d6a12afa5a1d22168cb40b2a3 + Author: Thomas Köppe + Date: Sat May 2 15:53:50 2026 +0100 + + [exec.snd.expos] Fix missing escaping for braces in "{}". + + Misapplication of P3826R5 in LWG Motion 28. + + Addresses editorial review committee feedback. + + commit 91e3416490d096cd0c783c1b5b4e922b53a48f4e + Author: Thomas Köppe + Date: Sat May 2 15:57:04 2026 +0100 + + [exec.domain.default] Delete stray word "sender". + + The deletion was part of the edit instructions of P3826R5 in LWG + Motion 28, but was accidentally missed. + + Addresses editorial review committee feedback. + + commit 62be1e6b61e0e3701f4062994cb04eb02d27d1be + Author: Thomas Köppe + Date: Sat May 2 16:00:32 2026 +0100 + + [exec.snd.transform] Fix "tag2" => "tag". + + Misapplication of P3826R5 in LWG Motion 28. + + Addresses editorial review committee feedback. + + commit 9912050ebe526f32ad1cdec47840fae82099b105 + Author: Thomas Köppe + Date: Sat May 2 16:04:37 2026 +0100 + + [exec.on] Fix missing escaping for braces in "{...}". + + Misapplication of P3826R5 in LWG Motion 28. + + Addresses editorial review committee feedback. + + commit e0ca46ae71122c99c0f098212b2990ed41973b05 + Author: Thomas Köppe + Date: Sat May 2 16:07:02 2026 +0100 + + [exec.on] Fix missing argument "set_value, ". + + Misapplication of P3826R5 in LWG Motion 28, this edit was just missed. + + Addresses editorial review committee feedback. + + commit d04267fda5b9a16ce56beb3137c22900019e0e54 + Author: Thomas Köppe + Date: Sat May 2 16:14:53 2026 +0100 + + [exec.sync.wait.var] Remove vacuous exception. + + The exception that "sndr is evaluated only once" is no longer + necessary, since P3826R5 from LWG Motion 28 removed the previous + second mention of the subexpression "sndr". Now that there is only one + occurrence of "sndr", it does not need saying that it is only + evaluated once. + + Addresses editorial review committee feedback. + + commit e5f877a4c0542654017c5cd9152d6c1dba7972b4 + Author: Thomas Köppe + Date: Sat May 2 16:19:51 2026 +0100 + + [exec.affine] Add missing '\placeholder'. + + Misapplication of P3941R4 in LWG Motion 33. + + Addresses editorial review committee feedback. + + commit 3647c192d9ed47bd653e3575b9dc84107b7cd1fc + Author: Thomas Köppe + Date: Sat May 2 16:32:59 2026 +0100 + + [exec.{rcvr,snd}.concepts] Add "// exposition only" comments to definitions. + + A missed edit from P4159R0 in LWG Motion 37. + + Addresses editorial review committee feedback. + + commit aea0fae459ee3a369e0dc251f674337298433121 + Author: Thomas Köppe + Date: Sat May 2 17:13:27 2026 +0100 + + [except.terminate] Replace system_context_replaceability with parallel_scheduler_replacement. + + This change is needed for consistency with P4154R0 from LWG Motion 39. + Even though that paper didn't ask for this change, that was clearly an + oversight. + + Addresses editorial review committee feedback. + + commit fb2c3e602417fe8cd33618ff5adb31a86cf9072b + Author: Hubert Tong + Date: Mon May 4 10:37:18 2026 -0400 + + [expr.const] Definition domain fixes for "usable in constant expressions" (#8670) + + Also improves the indexing. + + commit 32816d5c2f94da9252ea604c8e7ee17a0657e03c + Author: Thomas Köppe + Date: Sun Apr 26 16:31:18 2026 +0100 + + [simd.{syn,math}] Rename parameters of new overloads of various special maths functions: + + * For comp_ellint_3: from "x, y" to "k, nu" + * For cyl_bessel_{i,j,k}: from "x, y" to "nu, x" + * For cyl_neumann: from "x, y" to "nu, x" + * For ellint_{1,2}: from "x, y" to "k, phi" + * For ellint_{1,2}: from "x, y, z" to "k, nu, phi" + + The paper P3844R4 (LWG Motion 4) added those overloads with parameters + named differently from the names of the existing overloads, but the + latter names seem more appropriate. + + Addresses editorial review committee feedback. + + commit 85c6337534d0bdd9cbfa2260609a853e0c40d61f + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 21:54:26 2025 +0000 + + [intro.execution] Replace "or" with "and"; clarify wording + + commit a383c1ad305a61cbef3e14c698b41f6228e780c3 + Author: Jan Schultke + Date: Wed Apr 8 04:52:48 2026 +0200 + + [basic.extended.fp] Reference C23 instead of "future versions" + + commit 87a9fbb3cc85436d876e9c7a79ca1cfbb48ac150 + Author: Thomas Köppe + Date: Mon May 11 23:46:40 2026 +0100 + + [meta.reflection] Remove uninformative "// OK" comments from examples. + + Fixes NB US 84-151 (C++26 CD). + + commit 5670e07a0ec4a4a3c6201512d86013507c0a9389 + Author: Abhinav Agarwal + Date: Sun Apr 26 16:10:54 2026 -0700 + + [mdspan.sub.map.sliceable] Use lm in sliceable-mapping concept body + + The concept body introduces lm (an object of type LayoutMapping) but + then uses m (an object of type M from the surrounding requirements + section) in the submdspan_mapping well-formedness check. + + commit 738e80f3b19fe9ad73d7a48c382f9584e2f200fd + Author: Jonathan Wakely + Date: Tue May 12 09:41:32 2026 +0100 + + [istream.formatted.arithmetic] remove unnecessary whitespace in codeblocks + + commit d2e19cd940eec863a39edee1499e75230725925f + Author: Abhinav Agarwal + Date: Tue May 12 03:15:09 2026 -0700 + + [linalg.algs.blas2.rank1,linalg.algs.blas2.symherrank1] Restore missing arguments (#8995) + + Fixes a misapplication of P3371R5. + + * [linalg.algs.blas2.rank1] Add missing E in matrix_rank_1_update_c effects + * [linalg.algs.blas2.symherrank1] Restore parameters in updating overload + + commit 7c2e7f83c4a8af1841f81f798dd9c5db46232e6d + Author: Abhinav Agarwal + Date: Sun Apr 26 16:10:17 2026 -0700 + + [mdspan.sub.sub] Fix submdspan slice canonicalization + + Two integration errors in the Let clause introduced by P3663R3: + - the function parameter pack is named "slices", but the Let clause + references an undefined "raw_slices"; rename the parameter to match + subextents (mdspan.sub.extents); + - src is an mdspan but canonical_slices takes an extents object; + pass src.extents() instead of src. diff --git a/papers/n5051.html b/papers/n5051.html new file mode 100644 index 0000000000..cc95fa0df4 --- /dev/null +++ b/papers/n5051.html @@ -0,0 +1,278 @@ + + + + + +N5051 + + +

N5051 Editors’ Report:
Programming Languages — C++

+ +

Date: 2026-06-01

+ +

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

+ +

Acknowledgments

+ +

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

+ +
    +
  • N5050 is +the current working draft, the final draft for C++26 and the initial draft +for C++29. It replaces +N5046, +and it forms the basis of the Draft International Standard for C++26.
  • +
  • N5051 is this Editors' Report.
  • +
+ + +

Editorial changes

+ +

There have not been any motions from WG21 since the last working draft. This +revision incorporates the final changes requested by the editorial review +committee in preparation of the Draft International Standard (DIS) ballot, +as well as other editorial changes. (Most of the feedback from the editorial +review committee had already been incorporated into N5046.)

+ +

The value of the macro __cplusplus has been updated to 202603L.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N5046 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 6cfb658c1a4063a7ad10c51c9dc66c41b48f37f5
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sun Dec 14 17:49:10 2025 +0000
+
+    [basic.fundamental] Replace "denotes" with "is"
+
+commit 16464ed251f392be9104c676b1f785277256563d
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed May 13 12:37:50 2026 +0200
+
+    [optional.optional.ref.general] Remove redundant access-specifier (#9019)
+
+commit 960fa626322150501f559405e85fa571f93be3c0
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu May 14 12:52:21 2026 +0200
+
+    [meta.reflection.queries] Add comma in comment in example (#9020)
+
+commit 116068174ea9b50ee2a520667b7ac9daa49aca23
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu May 14 23:57:20 2026 +0200
+
+    [tab:text.summary] Sort "Text encodings identification" (28.4) before "Formatting" (28.5) (#9021)
+
+commit 06c1c7c7e6c2a1e9c7be87c253da0f54f116de56
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu May 21 08:09:21 2026 +0200
+
+    [tab:headers.cpp.fs] Sort "Contract-violation handling" (17.10) before "Initializer lists" (17.11) (#9030)
+
+commit 98098f41575381688e78cd86dba9f02d9146ac5b
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Mon May 25 07:33:53 2026 +0200
+
+    [cstdlib.syn] Align comment after declaration of abs (#9034)
+
+commit d2dc5b32da8ce80eeed9689a6ec7461e26ecc66a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue May 26 21:03:21 2026 +0100
+
+    [obj.lifetime] Reinstate phrasing "aggregate type".
+
+    This wording is in the approved paper P3726R2 from CWG Motion 9,
+    but was changed editorially to just "aggregate" under the assumption
+    that "aggregate type" is not a defined term. However, this seems
+    misguided; we use both the terms "aggregate type" and "class type",
+    even though the defined terms are just "aggregate" and "class".
+    It seems generally to improve clarity to refer to a "type", and here
+    in particular as we are talking about an "implicit-lifetime type".
+
+    Addresses editorial review committee feedback.
+
+commit cd878f8c120cecf302fa4d075a421d0a6b83a78c
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed May 27 13:55:52 2026 +0200
+
+    [container.requirements] Reword Result specifications (#6824)
+
+commit 79710b5b927398a2cb976a64e07f02e7131eddee
+Author: Eisenwave <me@eisenwave.net>
+Date:   Thu Nov 6 15:53:12 2025 +0100
+
+    [meta.define.static] Use "character type" in Mandates
+
+commit aa60c8f958534f1af7a9c0ac3e5dea9f96373aa0
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sun May 31 13:05:31 2026 +0800
+
+    [meta.reflection.access.queries] Index `has_inaccessible_bases` (#9044)
+
+commit b94e738abfb7382b7e1238158e58f7975ee0c1d2
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Apr 27 11:48:10 2026 +0800
+
+    [time] Cleanup exposition-only names
+
+    Editorial notes:
+      * Apply `\exposid` to all exposition-only members in [time].
+      * For _`local-time-format-t`_ and _`STATICALLY-WIDEN`_, change uses of
+        `\placeholder` to `\exposid`.
+      * Rename some members of `hh_mm_ss`, `zoned_time`, and
+        _`local-time-format-t`_ in the style of either _`name_`_ or
+        _`kebab-case`_.
+
+commit c9ea2121cd6eb28d2161c9d4956d7886c93e967e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jun 1 16:11:39 2026 +0100
+
+    [mem.res.pool.ctor] Reword awkward "calls will be fewer" in note
+
+    It seems much simpler to just say "there will be fewer calls".
+
+ + diff --git a/papers/n5051.md b/papers/n5051.md new file mode 100644 index 0000000000..3a17043807 --- /dev/null +++ b/papers/n5051.md @@ -0,0 +1,137 @@ +# N5051 Editors' Report -- Programming Languages -- C++ + +Date: 2026-06-01 + +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` + +## Acknowledgments + +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 + + * [N5050](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/n5050.pdf) is + the current working draft, the final draft for C++26 and the initial draft + for C++29. It replaces + [N5046](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5046.pdf), + and it forms the basis of the Draft International Standard for C++26. + * N5051 is this Editors' Report. + +### Editorial changes + +There have not been any motions from WG21 since the last working draft. This +revision incorporates the final changes requested by the editorial review +committee in preparation of the Draft International Standard (DIS) ballot, +as well as other editorial changes. (Most of the feedback from the editorial +review committee had already been incorporated into N5046.) + +The value of the macro `__cplusplus` has been updated to `202603L`. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N5046 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/n5046...n5050). + + commit 6cfb658c1a4063a7ad10c51c9dc66c41b48f37f5 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sun Dec 14 17:49:10 2025 +0000 + + [basic.fundamental] Replace "denotes" with "is" + + commit 16464ed251f392be9104c676b1f785277256563d + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed May 13 12:37:50 2026 +0200 + + [optional.optional.ref.general] Remove redundant access-specifier (#9019) + + commit 960fa626322150501f559405e85fa571f93be3c0 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu May 14 12:52:21 2026 +0200 + + [meta.reflection.queries] Add comma in comment in example (#9020) + + commit 116068174ea9b50ee2a520667b7ac9daa49aca23 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu May 14 23:57:20 2026 +0200 + + [tab:text.summary] Sort "Text encodings identification" (28.4) before "Formatting" (28.5) (#9021) + + commit 06c1c7c7e6c2a1e9c7be87c253da0f54f116de56 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu May 21 08:09:21 2026 +0200 + + [tab:headers.cpp.fs] Sort "Contract-violation handling" (17.10) before "Initializer lists" (17.11) (#9030) + + commit 98098f41575381688e78cd86dba9f02d9146ac5b + Author: Jan Schultke + Date: Mon May 25 07:33:53 2026 +0200 + + [cstdlib.syn] Align comment after declaration of abs (#9034) + + commit d2dc5b32da8ce80eeed9689a6ec7461e26ecc66a + Author: Thomas Köppe + Date: Tue May 26 21:03:21 2026 +0100 + + [obj.lifetime] Reinstate phrasing "aggregate type". + + This wording is in the approved paper P3726R2 from CWG Motion 9, + but was changed editorially to just "aggregate" under the assumption + that "aggregate type" is not a defined term. However, this seems + misguided; we use both the terms "aggregate type" and "class type", + even though the defined terms are just "aggregate" and "class". + It seems generally to improve clarity to refer to a "type", and here + in particular as we are talking about an "implicit-lifetime type". + + Addresses editorial review committee feedback. + + commit cd878f8c120cecf302fa4d075a421d0a6b83a78c + Author: Jan Schultke + Date: Wed May 27 13:55:52 2026 +0200 + + [container.requirements] Reword Result specifications (#6824) + + commit 79710b5b927398a2cb976a64e07f02e7131eddee + Author: Eisenwave + Date: Thu Nov 6 15:53:12 2025 +0100 + + [meta.define.static] Use "character type" in Mandates + + commit aa60c8f958534f1af7a9c0ac3e5dea9f96373aa0 + Author: S. B. Tam + Date: Sun May 31 13:05:31 2026 +0800 + + [meta.reflection.access.queries] Index `has_inaccessible_bases` (#9044) + + commit b94e738abfb7382b7e1238158e58f7975ee0c1d2 + Author: A. Jiang + Date: Mon Apr 27 11:48:10 2026 +0800 + + [time] Cleanup exposition-only names + + Editorial notes: + * Apply `\exposid` to all exposition-only members in [time]. + * For _`local-time-format-t`_ and _`STATICALLY-WIDEN`_, change uses of + `\placeholder` to `\exposid`. + * Rename some members of `hh_mm_ss`, `zoned_time`, and + _`local-time-format-t`_ in the style of either _`name_`_ or + _`kebab-case`_. + + commit c9ea2121cd6eb28d2161c9d4956d7886c93e967e + Author: Thomas Köppe + Date: Mon Jun 1 16:11:39 2026 +0100 + + [mem.res.pool.ctor] Reword awkward "calls will be fewer" in note + + It seems much simpler to just say "there will be fewer calls". diff --git a/papers/n5055.html b/papers/n5055.html new file mode 100644 index 0000000000..f69ae15339 --- /dev/null +++ b/papers/n5055.html @@ -0,0 +1,639 @@ + + + + + +N5055 + + +

N5055 Editors’ Report:
Programming Languages — C++

+ +

Date: 2026-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

+ +

Acknowledgments

+ +

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. +Special thanks to Daniel Hannon and Jan Schultke for drafting +many of the motion applications, and to Andreas Krug +for continuous, impeccably spaced vigilance.

+ +

New papers

+ +
    +
  • N5054 is +the current working draft for C++29. It replaces +N5050.
  • +
  • N5055 is this Editors' Report.
  • +
+ + +

Note that N5050 was not approved at any meeting. The last approved working draft +was N5046. For the purposes of approval of N5054, please consider both +this editors' report +together with the previous one, +N5051.

+ +

Motions incorporated into working draft

+ +

Notes on motions

+ +

All motions were applied cleanly.

+ +

Undefined behaviour and IFNDR

+ +

CWG Motion 2 created two new Annexes that list undefined behaviour and IFNDR, +respectively, and that add references to those annexes throughout the Standard.

+ +

Several subsequent motions affect wording related to undefined behaviour. +No changes have been made to those motions nor to the new annexes, and the new +references have merely been retained as-is when possible. This means that the +material in the annexes will need updating to reflect the changes from the +current set of motions. Paper authors are planning to present that update at the +next meeting.

+ +

In the future, papers are expected to update the UB/IFNDR annexes as part of +their proposed wording (similar to how we handle feature test macros now).

+ +

Multiple feature test macro increments

+ +

Three LWG motions about bitwise operations set or incremented the same feature +test macros, so that we now present two sets of values:

+ +
    +
  • LWG Motion 11 (P3793R2, “Better shifting”), bumped +__cpp_lib_bitops and added __cpp_lib_simd_bitops, +both to the value 202606L.
  • +
  • LWG Motion 14 (P3104R6, “Bit permutations”), bumped +__cpp_lib_bitops again, using 202607L.
  • +
  • LWG Motion 15 (P3772R2, “std::simd overloads for bit permutations”), +bumped __cpp_lib_simd_bitops again, using 202607L.
  • +
+ + +

Core working group polls

+ +

CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues in +P4271R0 +(Core Language Working Group “ready” Issues for the June, 2026 meeting) to the C++ Working Paper.

+ +

CWG Poll 2. Apply the changes in +P3596R3 +(Undefined Behavior and IFNDR Annexes) to the C++ Working Paper.

+ +

CWG Poll 3. Apply the changes in +P2287R6 +(Designated-initializers for Base Classes) to the C++ Working Paper.

+ +

CWG Poll 4. Accept as a Defect Report and apply the changes in +P3899R3 +(Clarify the behavior of floating-point overflow) to the C++ Working Paper.

+ +

CWG Poll 5. Apply the changes in +P3668R4 +(Defaulting Postfix Increment and Decrement Operations) to the C++ Working Paper.

+ +

CWG Poll 6. Apply the changes in +P2953R5 +(Adding restrictions to defaulted assignment operator functions) to the C++ Working Paper.

+ +

CWG Poll 7. Accept as a Defect Report and apply the changes in +P2434R5 +(Nondeterministic pointer provenance) to the C++ Working Paper.

+ +

CWG Poll 8. Accept as a Defect Report and apply the changes in +P3347R6 +(Invalid Pointer Operations) to the C++ Working Paper.

+ +

CWG Poll 9. Accept as a Defect Report and apply the changes in +P3658R1 +(Adjust identifier following new Unicode recommendations) to the C++ Working Paper.

+ +

CWG Poll 10. Accept as a Defect Report and apply the changes in +P3950R1 +(return_value & return_void Are Not Mutually Exclusive) to the C++ Working Paper.

+ +

CWG Poll 11. Accept as a Defect Report and apply the changes in +P3733R1 +(More named universal character escapes) to the C++ Working Paper.

+ +

CWG Poll 12. Accept as a Defect Report and apply the changes in +P3847R1 +(Lexical order for lambdas) to the C++ Working Paper.

+ +

CWG Poll 13. Accept as a Defect Report and apply the changes in +P2243R0 +(Language linkage for templates) to the C++ Working Paper.

+ +

CWG Poll 14. Apply the changes in +P3424R2 +(Deallocation Functions with Throwing Exception Specification Are Ill-formed) +to the C++ Working Paper.

+ +

CWG Poll 15. Apply the changes in +P3822R2 +(Conditional noexcept specifiers in compound requirements) to the C++ Working Paper.

+ +

CWG Poll 16. Apply the changes in +P3097R3 +(Contracts for C++: Virtual functions) to the C++ Working Paper.

+ +

CWG Poll 17. Accept as a Defect Report and Apply the changes in +P4101R1 +(Consteval-only Values for C++26) to the C++ Working Paper.

+ +

CWG Poll 18. Accept as a Defect Report and Apply the changes in +P2414R12 +(Pointer lifetime-end zap proposed solutions) to the C++ Working Paper.

+ +

CWG Poll 19. Apply the changes in +P3670R4 +(Pack Indexing for Template Names) to the C++ Working Paper.

+ +

CWG Poll 20. Apply the changes in +P3540R3 +(#embed offset parameter) to the C++ Working Paper.

+ +

Library working group polls

+ +

LWG Poll 1. Apply the changes in +P4258R0 +(C++ Standard Library Ready Issues to be moved in Brno, Jun. 2026) +to the C++ working paper.

+ +

LWG Poll 2. Apply the changes in +P3319R6 +(Add an iota object for SIMD (and more)) to the C++ working paper.

+ +

LWG Poll 3. Apply the changes in +P3798R1 +(The unexpected in std::expected) to the C++ working paper.

+ +

LWG Poll 4. Apply the changes in +P3052R2 +(view_interface::at()) to the C++ working paper.

+ +

LWG Poll 5. Apply the changes in +P4206R0 +(Revert string support in std::constant_wrapper) to the C++ working paper.

+ +

LWG Poll 6. Apply the changes in +P3395R6 +(Fix encoding issues and add a formatter for std::error_code) +to the C++ working paper.

+ +

LWG Poll 7. Apply the changes in +P3505R4 +(Fix the default floating-point representation in std::format) +to the C++ working paper.

+ +

LWG Poll 8. Apply the changes in +P3154R3 +(Deprecating signed character types in iostreams) to the C++ working paper.

+ +

LWG Poll 9. Apply the changes in +P3428R4 +(Hazard Pointer Batches) to the C++ working paper.

+ +

LWG Poll 10. Apply the changes in +P3248R5 +(Require [u]intptr_t) to the C++ working paper.

+ +

LWG Poll 11. Apply the changes in +P3793R2 +(Better shifting) to the C++ working paper.

+ +

LWG Poll 12. Apply the changes in +P3242R4 +(Copy and fill for mdspan) to the C++ working paper.

+ +

LWG Poll 13. Apply the changes in +P3692R4 +(How to Avoid OOTA Without Really Trying) to the C++ working paper.

+ +

LWG Poll 14. Apply the changes in +P3104R6 +(Bit permutations) to the C++ working paper.

+ +

LWG Poll 15. Apply the changes in +P3772R2 +(std::simd overloads for bit permutations) to the C++ working paper.

+ +

LWG Poll 16. Apply the changes in +P3091R6 +(Better Lookups for map, unordered_map, and flat_map) +to the C++ working paper.

+ +

LWG Poll 17. Apply the changes in +P3125R6 +(constexpr pointer tagging) to the C++ working paper.

+ +

LWG Poll 18. Apply the changes in +P2019R9 +(Thread attributes) to the C++ working paper.

+ +

LWG Poll 19. Apply the changes in +P3785R1 +(Library Wording Changes for Defaulted Postfix Increment and Decrement Operations) +to the C++ working paper.

+ +

Editorial changes

+ +

There were no major editorial changes.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N5046 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 3af45b9af76876c306da46aab5742d2525c11dc9
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Jun 2 12:33:47 2026 +0100
+
+    [global.functions] remove Effects: element inside note
+
+commit e74b6e52877565e776bf07a03d477cdb8a71377c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jun 8 14:46:17 2026 +0200
+
+    [expr.const.i{nit,mm}] Add xrefs for "manifestly constant-evaluated"
+
+    After the "constant expressions" reorganisation the definition is now
+    in a different subclause.
+
+commit 2bc04798c9afc9c1541ad30da9ccb735d4734734
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Jun 9 10:22:39 2026 +0100
+
+    [future.syn] more formal wording for "enum values"
+
+commit 69cd34e38fd3db2047a0104f1f9fdb3ff63ca9e9
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jun 10 08:21:36 2026 +0200
+
+    [mdspan.layout.leftpad] Fix indentation (#9060)
+
+commit f47fd460571f7fffcf3737c1b1c37f3f44ce6600
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Jun 11 12:17:15 2026 +0800
+
+    [diff.cpp03.dcl.dcl] Use "unnamed" in lieu of "anonymous" for namespace (#9061)
+
+commit 377e9deaef6dd5538fbb13e2689e5c69b986bea3
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Sat Jun 13 05:38:18 2026 +0800
+
+    [range.filter.view] Add missing template keyword (#9064)
+
+commit 2baf431a385434a469a739f6a127aa1f827bd042
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Tue Jun 16 10:36:49 2026 -0700
+
+    [mdspan.sub.helpers] Fix swapped offset/extent in canonical-slice (#9139)
+
+commit e66aa58e49b508f94917d3e6ec766e70fc924638
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Mon Jun 15 22:23:27 2026 -0700
+
+    [linalg.algs.blas1.iamax] Fix return type of vector_idx_abs_max
+
+    The declarations use extents_type (a std::extents shape type), but the
+    Returns clause specifies a scalar index of type size_type. Replace
+    extents_type with size_type in [linalg.syn] and [linalg.algs.blas1.iamax].
+
+commit 14ed707bc605912e37e79feabcfe5f227c5994d1
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Wed Jun 17 06:18:34 2026 -0700
+
+    [func.wrap.ref.ctor] Restore class T in constant_wrapper constructor head (#9144)
+
+    Fixes a misapplication of P3948R1 (from LWG Motion 16 of the Croydon, 2026 meeting).
+
+commit c870a79c89b3c6545c9e88533d089bd524c91b15
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Jun 20 18:33:44 2026 +0200
+
+    [check] Also diagnose \tcode{\exposid{kebap-case}}, i.e. hyphenated identifiers
+
+commit 2c8ec6d3306e1a1ea32083d38af003779777d8a7
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Jun 20 18:19:37 2026 +0200
+
+    [over.built] Add commas after "e.g."
+
+commit 71cbce1f42adf27b6329ce2a17e37d7a9c2721d5
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Sat Jun 20 22:01:56 2026 -0700
+
+    [dcl.contract.func] Fix placeholder and IFNDR comment (#9156)
+
+commit 2d6dec456cd7a6e227e2dcac9f647f6ff05f206c
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Sat Jun 20 22:02:46 2026 -0700
+
+    [exec.when.all] Fix receiver parameter name (#9158)
+
+commit 368b3b200ca326d48d944d28787550fa1abcb0bf
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Sat Jun 20 22:03:55 2026 -0700
+
+    [mdspan.sub] Fix S::extend_type typo (#9157)
+
+commit 24d1b7ea63537ffedc8fdd956132842783b8a465
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Fri Jul 3 13:15:22 2026 -0700
+
+    [basic.life] Add cross-reference to [obj.lifetime] (#9169)
+
+commit f7649bdf0c982275fc40b1c118a1f28ea18c843e
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Tue Jun 16 21:15:15 2026 -0700
+
+    [simd.math,simd.reductions] Fix two undeclared identifiers in std::simd
+
+    Two adjacent std::simd specifications name an identifier introduced
+    nowhere in the enclosing itemdescr:
+
+    - [simd.math]: the exposition-only modf-vec helper sizes its staging
+      array with Ret::size(), but the only Let-bound vector type here is V;
+      Ret is a leftover from frexp-vec (where Ret is bound). Use V::size().
+
+    - [simd.reductions]: masked reduce_max returns
+      numeric_limits<V::value_type>::lowest(), but its template head only
+      introduces T and Abi (no V). Use numeric_limits<T>::lowest(), matching
+      masked reduce_min and scalar reduce_max.
+
+commit b6da2bc53d2eab59c2379720aa3270ac360b70a6
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Wed Jun 17 08:30:37 2026 -0700
+
+    [simd.reductions] Name x and mask parameters in masked reduce_min/reduce_max
+
+    The masked reduce_min and reduce_max declarations leave both parameters
+    unnamed, but their Returns elements refer to x and mask. Name the
+    parameters x and mask so the declarations match their descriptions.
+
+commit c85c406386d9899f13d19704be1143087809256a
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jul 15 09:06:51 2026 +0200
+
+    [diff.cpp26.basic] Fix typo
+
+commit f8bcc253ba73193857594c76f3e1b9ceb2ba227f
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jul 15 07:40:35 2026 +0200
+
+    [uaxid.def.general] Fix typo
+
+commit 66bdb78b4ad58c83f1dda36e97ed504246523a8e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jul 15 12:17:57 2026 +0100
+
+    [exec.as.awaitable] Reinstate missing word "where".
+
+    Misapplication of LWG4359 in LWG Motion 1 (P4258R0).
+
+commit c8ac6a609fd13b56032ff02c19c533d8bfcc6cf8
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jul 15 12:36:34 2026 +0100
+
+    [basic.types.trivial] Fix bad implementation-defined grammar.
+
+commit 46ab66c3570ee53255c3a508610ab36b8fe30c6d
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Jul 16 08:29:43 2026 +0200
+
+    [mdspan.copy] Fix singular/plural mismatch
+
+commit 57b9fadb00c9f69457dac69d598c87088b6de99f
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jul 13 13:24:50 2026 +0200
+
+    [basic.contract.handler] Move period to end of sentence
+
+commit ccc221f5a77a8c222c35708ad7e48800842f06a7
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Jul 15 21:34:34 2026 +0200
+
+    [syserr.fmt] Replace \unicode with \ucode to render U+FFFD
+
+commit d14c10e0c06b3ed7e6317ce5178a3ceeca09e617
+Author: Eisenwave <me@eisenwave.net>
+Date:   Thu Jul 16 06:39:23 2026 +0200
+
+    [ub:expr.call.different.type] Add missing apostrophe inside "functions"
+
+commit f028afea499b07bd6c8b7d0eaec218af57e32d2d
+Author: Eisenwave <me@eisenwave.net>
+Date:   Thu Jul 16 06:37:41 2026 +0200
+
+    [ub:conv.fpint.float.not.represented] Add comma after "undefined behavior" in comment
+
+commit 40a6c36d53e7bca517a1a5146c3a20b6f99466b5
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Thu Jul 16 05:36:14 2026 -0700
+
+    [exec.let] Fix missing parentheses (#9143)
+
+    Misapplication of P3826R5.
+
+commit ca7bc9714a7324ecad9f66d743682831f238cac7
+Author: A. Jiang <de34@live.cn>
+Date:   Wed May 27 22:17:43 2026 +0800
+
+    [numarray] Move [valarray.range] to suitable place and level
+
+    For the sake of consistency with the synopsis of `valarray` (after the
+    modifications from P3016R6), [valarray.cassign] should be placed between
+    [valarray.cassign] and [valarray.members]. Moreover, it should be in
+    level `\rSec3` now.
+
+commit 19f519eb7ea6248ee63c6728933726d52d4e2e55
+Author: Daniel Hannon <hello111f@gmail.com>
+Date:   Sun Jun 21 13:41:12 2026 +0100
+
+    [vector.capacity] vector::reserve is tutorial-like
+
+commit a87774f445ac54493c4128c99d1a23ee22a5f22b
+Author: Abhinav Agarwal <abhinavagarwal1996@gmail.com>
+Date:   Sun Jun 21 15:43:24 2026 -0700
+
+    [exec.stopped.opt] Add transform_sender tag
+
+commit 379893062773fdbc4ceaf667715807e2edc48108
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Sun Jun 14 16:04:04 2026 +0800
+
+    [range.join.view, range.join.with.view]
+
+    Make the comment more smooth.
+
+commit e253e0e33ffd6040ae03dc233e207ea6c0a108e2
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jul 16 14:27:07 2026 +0100
+
+    [charconv.to.chars] remove std:: qualification
+
+commit b2028659e07292300cac09a7de94f9f1723dc346
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jul 16 13:06:10 2026 +0100
+
+    [thread.{thread.constr,jthread.cons}] Move the "existence of $i$ to Mandates:.
+
+    This change separates the local notational definitions from the
+    requirement whose violation makes the program ill-formed: the latter
+    should probably appear in one of the standard Elements rather than in
+    a rogue paragraph.
+
+commit f63180f933371e39612b0c1d6b71ba243be9d7b8
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jul 15 17:34:28 2026 +0100
+
+    [bit.permute] Create notation for the popcount of the first n bits.
+
+    This avoids having to put a complex expression into sub- and
+    superscripts in the definitions of "expand" and "compress".
+
+    We itemize the definitions for improved legibility.
+
+ + diff --git a/papers/n5055.md b/papers/n5055.md new file mode 100644 index 0000000000..d47e81b5e9 --- /dev/null +++ b/papers/n5055.md @@ -0,0 +1,495 @@ +# N5055 Editors' Report -- Programming Languages -- C++ + +Date: 2026-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` + +## Acknowledgments + +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. +Special thanks to Daniel Hannon and Jan Schultke for drafting +many of the motion applications, and to Andreas Krug +for continuous, impeccably spaced vigilance. + +## New papers + + * [N5054](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/n5054.pdf) is + the current working draft for C++29. It replaces + [N5050](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/n5050.pdf). + * N5055 is this Editors' Report. + +Note that N5050 was not approved at any meeting. The last approved working draft +was N5046. For the purposes of approval of N5054, please consider both +[this editors' report](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/n5055.html) +together with the previous one, +[N5051](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/n5051.html). + +## Motions incorporated into working draft + +### Notes on motions + +All motions were applied cleanly. + +#### Undefined behaviour and IFNDR + +CWG Motion 2 created two new Annexes that list undefined behaviour and IFNDR, +respectively, and that add references to those annexes throughout the Standard. + +Several subsequent motions affect wording related to undefined behaviour. +No changes have been made to those motions nor to the new annexes, and the new +references have merely been retained as-is when possible. This means that the +material in the annexes will need updating to reflect the changes from the +current set of motions. Paper authors are planning to present that update at the +next meeting. + +In the future, papers are expected to update the UB/IFNDR annexes as part of +their proposed wording (similar to how we handle feature test macros now). + +#### Multiple feature test macro increments + +Three LWG motions about bitwise operations set or incremented the same feature +test macros, so that we now present two sets of values: + +* LWG Motion 11 (P3793R2, "Better shifting"), bumped + `__cpp_lib_bitops` and added `__cpp_lib_simd_bitops`, + both to the value `202606L`. +* LWG Motion 14 (P3104R6, "Bit permutations"), bumped + `__cpp_lib_bitops` again, using `202607L`. +* LWG Motion 15 (P3772R2, "std::simd overloads for bit permutations"), + bumped `__cpp_lib_simd_bitops` again, using `202607L`. + +### Core working group polls + +CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues in +[P4271R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4271r0.html) +(Core Language Working Group "ready" Issues for the June, 2026 meeting) to the C++ Working Paper. + +CWG Poll 2. Apply the changes in +[P3596R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3596r3.pdf) +(Undefined Behavior and IFNDR Annexes) to the C++ Working Paper. + +CWG Poll 3. Apply the changes in +[P2287R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p2287r6.html) +(Designated-initializers for Base Classes) to the C++ Working Paper. + +CWG Poll 4. Accept as a Defect Report and apply the changes in +[P3899R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3899r3.html) +(Clarify the behavior of floating-point overflow) to the C++ Working Paper. + +CWG Poll 5. Apply the changes in +[P3668R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3668r4.html) +(Defaulting Postfix Increment and Decrement Operations) to the C++ Working Paper. + +CWG Poll 6. Apply the changes in +[P2953R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p2953r5.html) +(Adding restrictions to defaulted assignment operator functions) to the C++ Working Paper. + +CWG Poll 7. Accept as a Defect Report and apply the changes in +[P2434R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p2434r5.html) +(Nondeterministic pointer provenance) to the C++ Working Paper. + +CWG Poll 8. Accept as a Defect Report and apply the changes in +[P3347R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3347r6.pdf) +(Invalid Pointer Operations) to the C++ Working Paper. + +CWG Poll 9. Accept as a Defect Report and apply the changes in +[P3658R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3658r1.pdf) +(Adjust _identifier_ following new Unicode recommendations) to the C++ Working Paper. + +CWG Poll 10. Accept as a Defect Report and apply the changes in +[P3950R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3950r1.pdf) +(`return_value` & `return_void` Are Not Mutually Exclusive) to the C++ Working Paper. + +CWG Poll 11. Accept as a Defect Report and apply the changes in +[P3733R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3733r1.html) +(More named universal character escapes) to the C++ Working Paper. + +CWG Poll 12. Accept as a Defect Report and apply the changes in +[P3847R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3847r1.html) +(Lexical order for lambdas) to the C++ Working Paper. + +CWG Poll 13. Accept as a Defect Report and apply the changes in +[P2243R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2243r0.html) +(Language linkage for templates) to the C++ Working Paper. + +CWG Poll 14. Apply the changes in +[P3424R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3424r2.pdf) +(Deallocation Functions with Throwing Exception Specification Are Ill-formed) +to the C++ Working Paper. + +CWG Poll 15. Apply the changes in +[P3822R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3822r2.html) +(Conditional noexcept specifiers in compound requirements) to the C++ Working Paper. + +CWG Poll 16. Apply the changes in +[P3097R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3097r3.pdf) +(Contracts for C++: Virtual functions) to the C++ Working Paper. + +CWG Poll 17. Accept as a Defect Report and Apply the changes in +[P4101R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4101r1.html) +(Consteval-only Values for C++26) to the C++ Working Paper. + +CWG Poll 18. Accept as a Defect Report and Apply the changes in +[P2414R12](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p2414r12.pdf) +(Pointer lifetime-end zap proposed solutions) to the C++ Working Paper. + +CWG Poll 19. Apply the changes in +[P3670R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3670r4.pdf) +(Pack Indexing for Template Names) to the C++ Working Paper. + +CWG Poll 20. Apply the changes in +[P3540R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3540r3.html) +(`#embed` offset parameter) to the C++ Working Paper. + +### Library working group polls + +LWG Poll 1. Apply the changes in +[P4258R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4258r0.html) +(C++ Standard Library Ready Issues to be moved in Brno, Jun. 2026) +to the C++ working paper. + +LWG Poll 2. Apply the changes in +[P3319R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3319r6.pdf) +(Add an `iota` object for SIMD (and more)) to the C++ working paper. + +LWG Poll 3. Apply the changes in +[P3798R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3798r1.html) +(The unexpected in `std::expected`) to the C++ working paper. + +LWG Poll 4. Apply the changes in +[P3052R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3052r2.html) +(`view_interface::at()`) to the C++ working paper. + +LWG Poll 5. Apply the changes in +[P4206R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4206r0.html) +(Revert string support in `std::constant_wrapper`) to the C++ working paper. + +LWG Poll 6. Apply the changes in +[P3395R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3395r6.html) +(Fix encoding issues and add a formatter for `std::error_code`) +to the C++ working paper. + +LWG Poll 7. Apply the changes in +[P3505R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3505r4.html) +(Fix the default floating-point representation in `std::format`) +to the C++ working paper. + +LWG Poll 8. Apply the changes in +[P3154R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3154r3.html) +(Deprecating signed character types in iostreams) to the C++ working paper. + +LWG Poll 9. Apply the changes in +[P3428R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3428r4.pdf) +(Hazard Pointer Batches) to the C++ working paper. + +LWG Poll 10. Apply the changes in +[P3248R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3248r5.html) +(Require [`u`]`intptr_t`) to the C++ working paper. + +LWG Poll 11. Apply the changes in +[P3793R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3793r2.html) +(Better shifting) to the C++ working paper. + +LWG Poll 12. Apply the changes in +[P3242R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3242r4.html) +(Copy and fill for `mdspan`) to the C++ working paper. + +LWG Poll 13. Apply the changes in +[P3692R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3692r4.pdf) +(How to Avoid OOTA Without Really Trying) to the C++ working paper. + +LWG Poll 14. Apply the changes in +[P3104R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3104r6.html) +(Bit permutations) to the C++ working paper. + +LWG Poll 15. Apply the changes in +[P3772R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3772r2.html) +(`std::simd` overloads for bit permutations) to the C++ working paper. + +LWG Poll 16. Apply the changes in +[P3091R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3091r6.html) +(Better Lookups for `map`, `unordered_map`, and `flat_map`) +to the C++ working paper. + +LWG Poll 17. Apply the changes in +[P3125R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3125r6.html) +(constexpr pointer tagging) to the C++ working paper. + +LWG Poll 18. Apply the changes in +[P2019R9](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p2019r9.pdf) +(Thread attributes) to the C++ working paper. + +LWG Poll 19. Apply the changes in +[P3785R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3785r1.html) +(Library Wording Changes for Defaulted Postfix Increment and Decrement Operations) +to the C++ working paper. + +### Editorial changes + +There were no major editorial changes. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N5046 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/n5050...n5054). + + commit 3af45b9af76876c306da46aab5742d2525c11dc9 + Author: Jonathan Wakely + Date: Tue Jun 2 12:33:47 2026 +0100 + + [global.functions] remove Effects: element inside note + + commit e74b6e52877565e776bf07a03d477cdb8a71377c + Author: Thomas Köppe + Date: Mon Jun 8 14:46:17 2026 +0200 + + [expr.const.i{nit,mm}] Add xrefs for "manifestly constant-evaluated" + + After the "constant expressions" reorganisation the definition is now + in a different subclause. + + commit 2bc04798c9afc9c1541ad30da9ccb735d4734734 + Author: Jonathan Wakely + Date: Tue Jun 9 10:22:39 2026 +0100 + + [future.syn] more formal wording for "enum values" + + commit 69cd34e38fd3db2047a0104f1f9fdb3ff63ca9e9 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jun 10 08:21:36 2026 +0200 + + [mdspan.layout.leftpad] Fix indentation (#9060) + + commit f47fd460571f7fffcf3737c1b1c37f3f44ce6600 + Author: A. Jiang + Date: Thu Jun 11 12:17:15 2026 +0800 + + [diff.cpp03.dcl.dcl] Use "unnamed" in lieu of "anonymous" for namespace (#9061) + + commit 377e9deaef6dd5538fbb13e2689e5c69b986bea3 + Author: Hewill Kang + Date: Sat Jun 13 05:38:18 2026 +0800 + + [range.filter.view] Add missing template keyword (#9064) + + commit 2baf431a385434a469a739f6a127aa1f827bd042 + Author: Abhinav Agarwal + Date: Tue Jun 16 10:36:49 2026 -0700 + + [mdspan.sub.helpers] Fix swapped offset/extent in canonical-slice (#9139) + + commit e66aa58e49b508f94917d3e6ec766e70fc924638 + Author: Abhinav Agarwal + Date: Mon Jun 15 22:23:27 2026 -0700 + + [linalg.algs.blas1.iamax] Fix return type of vector_idx_abs_max + + The declarations use extents_type (a std::extents shape type), but the + Returns clause specifies a scalar index of type size_type. Replace + extents_type with size_type in [linalg.syn] and [linalg.algs.blas1.iamax]. + + commit 14ed707bc605912e37e79feabcfe5f227c5994d1 + Author: Abhinav Agarwal + Date: Wed Jun 17 06:18:34 2026 -0700 + + [func.wrap.ref.ctor] Restore class T in constant_wrapper constructor head (#9144) + + Fixes a misapplication of P3948R1 (from LWG Motion 16 of the Croydon, 2026 meeting). + + commit c870a79c89b3c6545c9e88533d089bd524c91b15 + Author: Eisenwave + Date: Sat Jun 20 18:33:44 2026 +0200 + + [check] Also diagnose \tcode{\exposid{kebap-case}}, i.e. hyphenated identifiers + + commit 2c8ec6d3306e1a1ea32083d38af003779777d8a7 + Author: Eisenwave + Date: Sat Jun 20 18:19:37 2026 +0200 + + [over.built] Add commas after "e.g." + + commit 71cbce1f42adf27b6329ce2a17e37d7a9c2721d5 + Author: Abhinav Agarwal + Date: Sat Jun 20 22:01:56 2026 -0700 + + [dcl.contract.func] Fix placeholder and IFNDR comment (#9156) + + commit 2d6dec456cd7a6e227e2dcac9f647f6ff05f206c + Author: Abhinav Agarwal + Date: Sat Jun 20 22:02:46 2026 -0700 + + [exec.when.all] Fix receiver parameter name (#9158) + + commit 368b3b200ca326d48d944d28787550fa1abcb0bf + Author: Abhinav Agarwal + Date: Sat Jun 20 22:03:55 2026 -0700 + + [mdspan.sub] Fix S::extend_type typo (#9157) + + commit 24d1b7ea63537ffedc8fdd956132842783b8a465 + Author: Abhinav Agarwal + Date: Fri Jul 3 13:15:22 2026 -0700 + + [basic.life] Add cross-reference to [obj.lifetime] (#9169) + + commit f7649bdf0c982275fc40b1c118a1f28ea18c843e + Author: Abhinav Agarwal + Date: Tue Jun 16 21:15:15 2026 -0700 + + [simd.math,simd.reductions] Fix two undeclared identifiers in std::simd + + Two adjacent std::simd specifications name an identifier introduced + nowhere in the enclosing itemdescr: + + - [simd.math]: the exposition-only modf-vec helper sizes its staging + array with Ret::size(), but the only Let-bound vector type here is V; + Ret is a leftover from frexp-vec (where Ret is bound). Use V::size(). + + - [simd.reductions]: masked reduce_max returns + numeric_limits::lowest(), but its template head only + introduces T and Abi (no V). Use numeric_limits::lowest(), matching + masked reduce_min and scalar reduce_max. + + commit b6da2bc53d2eab59c2379720aa3270ac360b70a6 + Author: Abhinav Agarwal + Date: Wed Jun 17 08:30:37 2026 -0700 + + [simd.reductions] Name x and mask parameters in masked reduce_min/reduce_max + + The masked reduce_min and reduce_max declarations leave both parameters + unnamed, but their Returns elements refer to x and mask. Name the + parameters x and mask so the declarations match their descriptions. + + commit c85c406386d9899f13d19704be1143087809256a + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jul 15 09:06:51 2026 +0200 + + [diff.cpp26.basic] Fix typo + + commit f8bcc253ba73193857594c76f3e1b9ceb2ba227f + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jul 15 07:40:35 2026 +0200 + + [uaxid.def.general] Fix typo + + commit 66bdb78b4ad58c83f1dda36e97ed504246523a8e + Author: Thomas Köppe + Date: Wed Jul 15 12:17:57 2026 +0100 + + [exec.as.awaitable] Reinstate missing word "where". + + Misapplication of LWG4359 in LWG Motion 1 (P4258R0). + + commit c8ac6a609fd13b56032ff02c19c533d8bfcc6cf8 + Author: Thomas Köppe + Date: Wed Jul 15 12:36:34 2026 +0100 + + [basic.types.trivial] Fix bad implementation-defined grammar. + + commit 46ab66c3570ee53255c3a508610ab36b8fe30c6d + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Jul 16 08:29:43 2026 +0200 + + [mdspan.copy] Fix singular/plural mismatch + + commit 57b9fadb00c9f69457dac69d598c87088b6de99f + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jul 13 13:24:50 2026 +0200 + + [basic.contract.handler] Move period to end of sentence + + commit ccc221f5a77a8c222c35708ad7e48800842f06a7 + Author: Eisenwave + Date: Wed Jul 15 21:34:34 2026 +0200 + + [syserr.fmt] Replace \unicode with \ucode to render U+FFFD + + commit d14c10e0c06b3ed7e6317ce5178a3ceeca09e617 + Author: Eisenwave + Date: Thu Jul 16 06:39:23 2026 +0200 + + [ub:expr.call.different.type] Add missing apostrophe inside "functions" + + commit f028afea499b07bd6c8b7d0eaec218af57e32d2d + Author: Eisenwave + Date: Thu Jul 16 06:37:41 2026 +0200 + + [ub:conv.fpint.float.not.represented] Add comma after "undefined behavior" in comment + + commit 40a6c36d53e7bca517a1a5146c3a20b6f99466b5 + Author: Abhinav Agarwal + Date: Thu Jul 16 05:36:14 2026 -0700 + + [exec.let] Fix missing parentheses (#9143) + + Misapplication of P3826R5. + + commit ca7bc9714a7324ecad9f66d743682831f238cac7 + Author: A. Jiang + Date: Wed May 27 22:17:43 2026 +0800 + + [numarray] Move [valarray.range] to suitable place and level + + For the sake of consistency with the synopsis of `valarray` (after the + modifications from P3016R6), [valarray.cassign] should be placed between + [valarray.cassign] and [valarray.members]. Moreover, it should be in + level `\rSec3` now. + + commit 19f519eb7ea6248ee63c6728933726d52d4e2e55 + Author: Daniel Hannon + Date: Sun Jun 21 13:41:12 2026 +0100 + + [vector.capacity] vector::reserve is tutorial-like + + commit a87774f445ac54493c4128c99d1a23ee22a5f22b + Author: Abhinav Agarwal + Date: Sun Jun 21 15:43:24 2026 -0700 + + [exec.stopped.opt] Add transform_sender tag + + commit 379893062773fdbc4ceaf667715807e2edc48108 + Author: Hewill Kang + Date: Sun Jun 14 16:04:04 2026 +0800 + + [range.join.view, range.join.with.view] + + Make the comment more smooth. + + commit e253e0e33ffd6040ae03dc233e207ea6c0a108e2 + Author: Jonathan Wakely + Date: Thu Jul 16 14:27:07 2026 +0100 + + [charconv.to.chars] remove std:: qualification + + commit b2028659e07292300cac09a7de94f9f1723dc346 + Author: Thomas Köppe + Date: Thu Jul 16 13:06:10 2026 +0100 + + [thread.{thread.constr,jthread.cons}] Move the "existence of $i$ to Mandates:. + + This change separates the local notational definitions from the + requirement whose violation makes the program ill-formed: the latter + should probably appear in one of the standard Elements rather than in + a rogue paragraph. + + commit f63180f933371e39612b0c1d6b71ba243be9d7b8 + Author: Thomas Köppe + Date: Wed Jul 15 17:34:28 2026 +0100 + + [bit.permute] Create notation for the popcount of the first n bits. + + This avoids having to put a complex expression into sub- and + superscripts in the definitions of "expand" and "compress". + + We itemize the definitions for improved legibility. diff --git a/papers/wd-index.md b/papers/wd-index.md index 8b21e73321..7d8589afab 100644 --- a/papers/wd-index.md +++ b/papers/wd-index.md @@ -53,3 +53,9 @@ * [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 + * [N5014](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5014.pdf) 2025-08 C++ Working Draft + * [N5032](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5032.pdf) 2025-12 C++ Working Draft + * [N5046](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/n5046.pdf) 2026-05 C++ Working Draft + * [N5050](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/n5050.pdf) 2026-06 C++ Working Draft + * [N5054](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/n5054.pdf) 2026-07 C++ Working Draft diff --git a/source/Makefile b/source/Makefile index d4a2ff4064..25fdcf505c 100644 --- a/source/Makefile +++ b/source/Makefile @@ -30,3 +30,12 @@ clean-examples: rm -f $(EXAMPLES) examples: $(EXAMPLES) + +check: .check.stamp + +.check.stamp: ../tools/check-source.sh *.tex + @echo "Running tools/check-source.sh" + @../tools/check-source.sh + @touch $@ + +.PHONY: default refresh refresh full quiet clean-figures figures clean-examples examples check diff --git a/source/algorithms.tex b/source/algorithms.tex index cea87802e5..95b1a81873 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -231,6 +231,17 @@ for (auto tmp = b; tmp != a; ++tmp) --n; return n; \end{codeblock} +For each iterator \tcode{i} and sentinel \tcode{s} +produced from a range \tcode{r}, +the semantics of \tcode{s - i} +are the same as those of an expression that +has the same type, value, and value category +as \tcode{ranges::distance(i, s)}. +\begin{note} +The implementation can use \tcode{ranges::distance(r)} +when that produces the same value as \tcode{ranges::\-distance(i, s)}. +This can be more efficient for sized ranges. +\end{note} \pnum In the description of the algorithms, @@ -249,10 +260,18 @@ \pnum Overloads of algorithms that take \libconcept{range} arguments\iref{range.range} -behave as if they are implemented by calling \tcode{ranges::begin} and -\tcode{ranges::end} on the \libconcept{range}(s) and +behave as if they are implemented by dispatching to the overload in namespace \tcode{ranges} -that takes separate iterator and sentinel arguments. +that takes separate iterator and sentinel arguments, +where for each range argument \tcode{r} +\begin{itemize} +\item + a corresponding iterator argument is initialized with \tcode{ranges::begin(r)} and +\item + a corresponding sentinel argument is initialized with \tcode{ranges::end(r)}, + or \tcode{ranges::begin(r) + N} + where \tcode{N} is equal to \tcode{ranges::distance(r)}. +\end{itemize} \pnum The well-formedness and behavior of a call to an algorithm with @@ -272,23 +291,29 @@ \pnum A \defn{parallel algorithm} is a function template listed in this document -with a template parameter named \tcode{ExecutionPolicy}. +with a template parameter named \tcode{ExecutionPolicy} +or constrained by the following exposition-only concept: +\begin{codeblock} +template + concept @\defexposconcept{execution-policy}@ = is_execution_policy_v>; // \expos +\end{codeblock} +Such a template parameter is termed an \defnadj{execution policy}{template parameter}. \pnum -Parallel algorithms access objects indirectly accessible via their arguments +A parallel algorithm accesses objects indirectly accessible via its arguments by invoking the following functions: \begin{itemize} \item - All operations of the categories of the iterators or \tcode{mdspan} types + All operations of the categories of the iterators, sentinels, or \tcode{mdspan} types that the algorithm is instantiated with. \item Operations on those sequence elements that are required by its specification. \item - User-provided function objects + User-provided invocable objects to be applied during the execution of the algorithm, if required by the specification. \item - Operations on those function objects required by the specification. + Operations on those invocable objects required by the specification. \begin{note} See~\ref{algorithms.requirements}. \end{note} @@ -315,7 +340,8 @@ A standard library function is \defn{vectorization-unsafe} if it is specified to synchronize with another function invocation, or another function invocation is specified to synchronize with it, -and if it is not a memory allocation or deallocation function. +and if it is not a memory allocation or deallocation function +or lock-free atomic modify-write operation\iref{atomics.order}. \begin{note} Implementations must ensure that internal synchronization inside standard library functions does not prevent forward progress @@ -344,7 +370,8 @@ \pnum Unless otherwise specified, -function objects passed into parallel algorithms as objects of type +invocable objects passed into parallel algorithms as objects of a type +denoted by a template parameter named \tcode{Predicate}, \tcode{BinaryPredicate}, \tcode{Compare}, @@ -352,8 +379,11 @@ \tcode{BinaryOperation}, \tcode{BinaryOperation1}, \tcode{BinaryOperation2}, -\tcode{BinaryDivideOp}, and -the operators used by the analogous overloads to these parallel algorithms +\tcode{BinaryDivideOp}, or +constrained by a concept +whose semantic requirements include +that the type models \libconcept{regular_invocable} +and the operators used by the analogous overloads to these parallel algorithms that are formed by an invocation with the specified default predicate or operation (where applicable) shall not directly or indirectly modify objects via their arguments, @@ -362,10 +392,9 @@ \rSec2[algorithms.parallel.exec]{Effect of execution policies on algorithm execution} \pnum -Parallel algorithms have -template parameters named \tcode{ExecutionPolicy}\iref{execpol} -which describe the manner in which the execution of these algorithms may be -parallelized and the manner in which they apply the element access functions. +An execution policy template parameter describes +the manner in which the execution of a parallel algorithm may be +parallelized and the manner in which it applies the element access functions. \pnum If an object is modified by an element access function, @@ -565,31 +594,31 @@ \pnum During the execution of a parallel algorithm, if the invocation of an element access function exits via an uncaught exception, -the behavior is determined by the \tcode{ExecutionPolicy}. +the behavior is determined by the execution policy. -\rSec2[algorithms.parallel.overloads]{\tcode{ExecutionPolicy} algorithm overloads} +\rSec2[algorithms.parallel.overloads]{Parallel algorithm overloads} \pnum Parallel algorithms are algorithm overloads. Each parallel algorithm overload -has an additional template type parameter named \tcode{ExecutionPolicy}, -which is the first template parameter. -Additionally, each parallel algorithm overload -has an additional function parameter of type \tcode{ExecutionPolicy\&\&}, -which is the first function parameter. +has an additional function parameter $P$ of type \tcode{T\&\&} +as the first function parameter, +where \tcode{T} is the execution policy template parameter. \begin{note} Not all algorithms have parallel algorithm overloads. \end{note} \pnum Unless otherwise specified, -the semantics of \tcode{ExecutionPolicy} algorithm overloads -are identical to their overloads without. +the semantics of calling a parallel algorithm overload are identical to +calling the corresponding algorithm overload without the parameter $P$, +using all but the first argument. \pnum Unless otherwise specified, -the complexity requirements of \tcode{ExecutionPolicy} algorithm overloads -are relaxed from the complexity requirements of the overloads without +the complexity requirements of a parallel algorithm overload +are relaxed from the complexity requirements of the corresponding overload +without the parameter $P$ as follows: when the guarantee says ``at most \placeholder{expr}'' or ``exactly \placeholder{expr}'' @@ -598,8 +627,10 @@ the complexity of the algorithm shall be \bigoh{\placeholder{expr}}. \pnum -Parallel algorithms shall not participate in overload resolution unless -\tcode{is_execution_policy_v>} is \tcode{true}. +A parallel algorithm +with a template parameter named \tcode{ExecutionPolicy} +shall not participate in overload resolution unless +that template parameter satisfies \exposconcept{execution-policy}. \rSec2[execpol]{Execution policies} @@ -640,7 +671,7 @@ \indexlibraryglobal{is_execution_policy}% \begin{itemdecl} -template struct is_execution_policy { @\seebelow@ }; +template struct is_execution_policy; \end{itemdecl} \begin{itemdescr} @@ -753,9 +784,11 @@ \indexlibraryglobal{seq}% \indexlibraryglobal{par}% \indexlibraryglobal{par_unseq}% +\indexlibraryglobal{unseq}% \indexlibrarymember{execution}{seq}% \indexlibrarymember{execution}{par}% \indexlibrarymember{execution}{par_unseq}% +\indexlibrarymember{execution}{unseq}% \begin{itemdecl} inline constexpr execution::sequenced_policy execution::seq{ @\unspec@ }; inline constexpr execution::parallel_policy execution::par{ @\unspec@ }; @@ -772,6 +805,7 @@ \indexheader{algorithm}% \begin{codeblock} +// mostly freestanding #include // see \ref{initializer.list.syn} namespace std { @@ -810,7 +844,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 { @@ -820,13 +854,20 @@ template<@\libconcept{input_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr bool all_of(R&& r, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + bool all_of(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + bool all_of(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // freestanding-deleted } // \ref{alg.any.of}, any of 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 { @@ -836,13 +877,20 @@ template<@\libconcept{input_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr bool any_of(R&& r, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + bool any_of(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + bool any_of(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // freestanding-deleted } // \ref{alg.none.of}, none of 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 { @@ -852,6 +900,13 @@ template<@\libconcept{input_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr bool none_of(R&& r, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + bool none_of(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + bool none_of(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // freestanding-deleted } // \ref{alg.contains}, contains @@ -866,6 +921,17 @@ @\libconcept{indirect_binary_predicate}@, Proj>, const T*> constexpr bool contains(R&& r, const T& value, Proj proj = {}); + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + bool contains(Ep&& exec, I first, S last, const T& value, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires + @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + bool contains(Ep&& exec, R&& r, const T& value, Proj proj = {}); // freestanding-deleted + template<@\libconcept{forward_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{forward_iterator}@ I2, @\libconcept{sentinel_for}@ S2, class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> @@ -877,18 +943,30 @@ requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> constexpr bool contains_subrange(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + bool contains_subrange(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + bool contains_subrange(Ep&& exec, R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, + Proj2 proj2 = {}); // freestanding-deleted } // \ref{alg.foreach}, for each 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 { template - using for_each_result = in_fun_result; + using @\libglobal{for_each_result}@ = in_fun_result; template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirectly_unary_invocable}@> Fun> @@ -898,22 +976,36 @@ @\libconcept{indirectly_unary_invocable}@, Proj>> Fun> constexpr for_each_result, Fun> for_each(R&& r, Fun f, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirectly_unary_invocable}@> Fun> + I for_each(Ep&& exec, I first, S last, Fun f, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirectly_unary_invocable}@, Proj>> Fun> + borrowed_iterator_t + for_each(Ep&& exec, R&& r, Fun f, Proj proj = {}); // freestanding-deleted } 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 { template - using for_each_n_result = in_fun_result; + using @\libglobal{for_each_n_result}@ = in_fun_result; template<@\libconcept{input_iterator}@ I, class Proj = identity, @\libconcept{indirectly_unary_invocable}@> Fun> constexpr for_each_n_result for_each_n(I first, iter_difference_t n, Fun f, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, class Proj = identity, + @\libconcept{indirectly_unary_invocable}@> Fun> + I for_each_n(Ep&& exec, I first, iter_difference_t n, Fun f, + Proj proj = {}); // freestanding-deleted } // \ref{alg.find}, find @@ -922,21 +1014,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); @@ -951,6 +1043,18 @@ projected, Proj>, const T*> constexpr borrowed_iterator_t find(R&& r, const T& value, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + I find(Ep&& exec, I first, S last, const T& value, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + borrowed_iterator_t + find(Ep&& exec, R&& r, const T& value, Proj proj = {}); // freestanding-deleted + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr I find_if(I first, S last, Pred pred, Proj proj = {}); @@ -958,6 +1062,15 @@ @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr borrowed_iterator_t find_if(R&& r, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + I find_if(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + borrowed_iterator_t + find_if(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // freestanding-deleted + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr I find_if_not(I first, S last, Pred pred, Proj proj = {}); @@ -965,29 +1078,76 @@ @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr borrowed_iterator_t find_if_not(R&& r, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + I find_if_not(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + borrowed_iterator_t + find_if_not(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // freestanding-deleted } // \ref{alg.find.last}, find last namespace ranges { - 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 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 find_last(R&& r, const T& value, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + subrange + find_last(Ep&& exec, I first, S last, const T& value, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires + @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + borrowed_subrange_t + find_last(Ep&& exec, R&& r, const T& value, Proj proj = {}); // freestanding-deleted + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr subrange find_last_if(I first, S last, Pred pred, Proj proj = {}); template<@\libconcept{forward_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr borrowed_subrange_t find_last_if(R&& r, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + subrange + find_last_if(Ep&& exec, I first, S last, Pred pred, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + borrowed_subrange_t + find_last_if(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // freestanding-deleted + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr subrange find_last_if_not(I first, S last, Pred pred, Proj proj = {}); template<@\libconcept{forward_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr borrowed_subrange_t find_last_if_not(R&& r, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + subrange + find_last_if_not(Ep&& exec, I first, S last, Pred pred, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + borrowed_subrange_t + find_last_if_not(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // freestanding-deleted } // \ref{alg.find.end}, find end @@ -1002,13 +1162,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); @@ -1026,9 +1186,23 @@ constexpr borrowed_subrange_t find_end(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + subrange + find_end(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + borrowed_subrange_t + find_end(Ep&& exec, R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } - // \ref{alg.find.first.of}, find first + // \ref{alg.find.first.of}, find first of template constexpr InputIterator find_first_of(InputIterator first1, InputIterator last1, @@ -1040,13 +1214,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); @@ -1063,6 +1237,19 @@ constexpr borrowed_iterator_t find_first_of(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + I1 find_first_of(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + borrowed_iterator_t + find_first_of(Ep&& exec, R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } // \ref{alg.adjacent.find}, adjacent find @@ -1075,11 +1262,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); @@ -1094,6 +1281,18 @@ projected, Proj>> Pred = ranges::equal_to> constexpr borrowed_iterator_t adjacent_find(R&& r, Pred pred = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_binary_predicate}@, + projected> Pred = ranges::equal_to> + I adjacent_find(Ep&& exec, I first, S last, Pred pred = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_binary_predicate}@, Proj>, + projected, Proj>> Pred = ranges::equal_to> + borrowed_iterator_t + adjacent_find(Ep&& exec, R&& r, Pred pred = {}, Proj proj = {}); // freestanding-deleted } // \ref{alg.count}, count @@ -1101,16 +1300,16 @@ constexpr typename iterator_traits::difference_type count(InputIterator first, InputIterator last, const T& value); template::value_type> + class T = iterator_traits::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 { @@ -1125,6 +1324,19 @@ projected, Proj>, const T*> constexpr range_difference_t count(R&& r, const T& value, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + iter_difference_t + count(Ep&& exec, I first, S last, const T& value, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + range_difference_t + count(Ep&& exec, R&& r, const T& value, Proj proj = {}); // freestanding-deleted + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr iter_difference_t @@ -1133,6 +1345,15 @@ @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr range_difference_t count_if(R&& r, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + iter_difference_t + count_if(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + range_difference_t + count_if(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // freestanding-deleted } // \ref{alg.mismatch}, mismatch @@ -1155,31 +1376,31 @@ 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); namespace ranges { template - using mismatch_result = in_in_result; + using @\libglobal{mismatch_result}@ = in_in_result; template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> @@ -1193,6 +1414,20 @@ constexpr mismatch_result, borrowed_iterator_t> mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + mismatch_result + mismatch(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + mismatch_result, borrowed_iterator_t> + mismatch(Ep&& exec, R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } // \ref{alg.equal}, equal @@ -1210,21 +1445,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); @@ -1241,6 +1476,18 @@ requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> constexpr bool equal(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + bool equal(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + bool equal(Ep&& exec, R1&& r1, R2&& r2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } // \ref{alg.is.permutation}, is permutation @@ -1287,13 +1534,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); @@ -1312,6 +1559,20 @@ constexpr borrowed_subrange_t search(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + subrange + search(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + borrowed_subrange_t + search(Ep&& exec, R1&& r1, R2&& r2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } 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); @@ -1352,6 +1613,20 @@ constexpr borrowed_subrange_t search_n(R&& r, range_difference_t count, const T& value, Pred pred = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Pred = ranges::equal_to, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirectly_comparable}@ + subrange + search_n(Ep&& exec, I first, S last, iter_difference_t count, + const T& value, Pred pred = {}, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Pred = ranges::equal_to, + class Proj = identity, class T = projected_value_t, Proj>> + requires @\libconcept{indirectly_comparable}@, const T*, Pred, Proj> + borrowed_subrange_t + search_n(Ep&& exec, R&& r, range_difference_t count, + const T& value, Pred pred = {}, Proj proj = {}); // freestanding-deleted } template @@ -1371,6 +1646,19 @@ constexpr bool starts_with(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + bool starts_with(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, + @\exposconcept{sized-random-access-range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + bool starts_with(Ep&& exec, R1&& r1, R2&& r2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + // \ref{alg.ends.with}, ends with template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> @@ -1387,6 +1675,19 @@ constexpr bool ends_with(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + bool ends_with(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, + @\exposconcept{sized-random-access-range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + bool ends_with(Ep&& exec, R1&& r1, R2&& r2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + // \ref{alg.fold}, fold template class @\exposid{flipped}@ { // \expos @@ -1444,7 +1745,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> @@ -1452,9 +1753,9 @@ constexpr auto fold_right_last(R&& r, F f); template - using fold_left_with_iter_result = in_value_result; + using @\libglobal{fold_left_with_iter_result}@ = in_value_result; template - using fold_left_first_with_iter_result = in_value_result; + using @\libglobal{fold_left_first_with_iter_result}@ = in_value_result; template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class T = iter_value_t, @\exposconcept{indirectly-binary-left-foldable}@ F> @@ -1481,13 +1782,13 @@ 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); namespace ranges { template - using copy_result = in_out_result; + using @\libglobal{copy_result}@ = in_out_result; template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O> requires @\libconcept{indirectly_copyable}@ @@ -1497,6 +1798,16 @@ requires @\libconcept{indirectly_copyable}@, O> constexpr copy_result, O> copy(R&& r, O result); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS> + requires @\libconcept{indirectly_copyable}@ + copy_result + copy(Ep&& exec, I first, S last, O result, OutS result_last); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR> + requires @\libconcept{indirectly_copyable}@, iterator_t> + copy_result, borrowed_iterator_t> + copy(Ep&& exec, R&& r, OutR&& result_r); // freestanding-deleted } template @@ -1504,18 +1815,25 @@ 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); namespace ranges { template - using copy_n_result = in_out_result; + using @\libglobal{copy_n_result}@ = in_out_result; template<@\libconcept{input_iterator}@ I, @\libconcept{weakly_incrementable}@ O> requires @\libconcept{indirectly_copyable}@ constexpr copy_n_result copy_n(I first, iter_difference_t n, O result); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{random_access_iterator}@ O, + @\libconcept{sized_sentinel_for}@ OutS> + requires @\libconcept{indirectly_copyable}@ + copy_n_result + copy_n(Ep&& exec, I first, iter_difference_t n, O result, + OutS result_last); // freestanding-deleted } template @@ -1523,13 +1841,13 @@ 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); namespace ranges { template - using copy_if_result = in_out_result; + using @\libglobal{copy_if_result}@ = in_out_result; template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> @@ -1541,6 +1859,21 @@ requires @\libconcept{indirectly_copyable}@, O> constexpr copy_if_result, O> copy_if(R&& r, O result, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_copyable}@ + copy_if_result + copy_if(Ep&& exec, I first, S last, O result, OutS result_last, + Pred pred, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, iterator_t> + copy_if_result, borrowed_iterator_t> + copy_if(Ep&& exec, R&& r, OutR&& result_r, Pred pred, + Proj proj = {}); // freestanding-deleted } template @@ -1550,7 +1883,7 @@ namespace ranges { template - using copy_backward_result = in_out_result; + using @\libglobal{copy_backward_result}@ = in_out_result; template<@\libconcept{bidirectional_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{bidirectional_iterator}@ I2> requires @\libconcept{indirectly_copyable}@ @@ -1568,13 +1901,13 @@ 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); namespace ranges { template - using move_result = in_out_result; + using @\libglobal{move_result}@ = in_out_result; template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O> requires @\libconcept{indirectly_movable}@ @@ -1584,6 +1917,16 @@ requires @\libconcept{indirectly_movable}@, O> constexpr move_result, O> move(R&& r, O result); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS> + requires @\libconcept{indirectly_movable}@ + move_result + move(Ep&& exec, I first, S last, O result, OutS result_last); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR> + requires @\libconcept{indirectly_movable}@, iterator_t> + move_result, borrowed_iterator_t> + move(Ep&& exec, R&& r, OutR&& result_r); // freestanding-deleted } template @@ -1593,7 +1936,7 @@ namespace ranges { template - using move_backward_result = in_out_result; + using @\libglobal{move_backward_result}@ = in_out_result; template<@\libconcept{bidirectional_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{bidirectional_iterator}@ I2> requires @\libconcept{indirectly_movable}@ @@ -1610,13 +1953,13 @@ 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); namespace ranges { template - using swap_ranges_result = in_in_result; + using @\libglobal{swap_ranges_result}@ = in_in_result; template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2> requires @\libconcept{indirectly_swappable}@ @@ -1626,6 +1969,16 @@ requires @\libconcept{indirectly_swappable}@, iterator_t> constexpr swap_ranges_result, borrowed_iterator_t> swap_ranges(R1&& r1, R2&& r2); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2> + requires @\libconcept{indirectly_swappable}@ + swap_ranges_result + swap_ranges(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2> + requires @\libconcept{indirectly_swappable}@, iterator_t> + swap_ranges_result, borrowed_iterator_t> + swap_ranges(Ep&& exec, R1&& r1, R2&& r2); // freestanding-deleted } template @@ -1645,20 +1998,20 @@ 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); namespace ranges { template - using unary_transform_result = in_out_result; + using @\libglobal{unary_transform_result}@ = in_out_result; template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O, @\libconcept{copy_constructible}@ F, class Proj = identity> @@ -1671,24 +2024,59 @@ constexpr unary_transform_result, O> transform(R&& r, O result, F op, Proj proj = {}); + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + @\libconcept{copy_constructible}@ F, class Proj = identity> + requires @\libconcept{indirectly_writable}@>> + unary_transform_result + transform(Ep&& exec, I first1, S last1, O result, OutS result_last, + F op, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + @\libconcept{copy_constructible}@ F, class Proj = identity> + requires @\libconcept{indirectly_writable}@, + indirect_result_t, Proj>>> + unary_transform_result, borrowed_iterator_t> + transform(Ep&& exec, R&& r, OutR&& result_r, F op, Proj proj = {}); // freestanding-deleted + template - using binary_transform_result = in_in_out_result; + using @\libglobal{binary_transform_result}@ = in_in_out_result; template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, @\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 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + @\libconcept{copy_constructible}@ F, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_writable}@, + projected>> + binary_transform_result + transform(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + O result, OutS result_last, + F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, @\libconcept{copy_constructible}@ F, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_writable}@, + indirect_result_t, Proj1>, + projected, Proj2>>> + binary_transform_result, borrowed_iterator_t, + borrowed_iterator_t> + transform(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, + F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } // \ref{alg.replace}, replace @@ -1697,7 +2085,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); namespace ranges { template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, - class T1 = projected_value_t, class T2 = T1> + class T1 = projected_value_t, class T2 = iter_value_t> requires @\libconcept{indirectly_writable}@ && @\libconcept{indirect_binary_predicate}@, const T1*> constexpr I replace(I first, S last, const T1& old_value, const T2& new_value, Proj proj = {}); template<@\libconcept{input_range}@ R, class Proj = identity, - class T1 = projected_value_t, Proj>, class T2 = T1> + class T1 = projected_value_t, Proj>, class T2 = range_value_t> requires @\libconcept{indirectly_writable}@, const T2&> && @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> constexpr borrowed_iterator_t replace(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + class T1 = projected_value_t, class T2 = iter_value_t> + requires @\libconcept{indirectly_writable}@ && + @\libconcept{indirect_binary_predicate}@, const T1*> + I replace(Ep&& exec, I first, S last, + const T1& old_value, const T2& new_value, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T1 = projected_value_t, Proj>, class T2 = range_value_t> + requires @\libconcept{indirectly_writable}@, const T2&> && + @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> + borrowed_iterator_t + replace(Ep&& exec, R&& r, const T1& old_value, const T2& new_value, + Proj proj = {}); // freestanding-deleted + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, - class T = projected_value_t, + class T = iter_value_t, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{indirectly_writable}@ constexpr I replace_if(I first, S last, Pred pred, const T& new_value, Proj proj = {}); - template<@\libconcept{input_range}@ R, class Proj = identity, class T = projected_value_t, + template<@\libconcept{input_range}@ R, class Proj = identity, class T = range_value_t, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> requires @\libconcept{indirectly_writable}@, const T&> constexpr borrowed_iterator_t replace_if(R&& r, Pred pred, const T& new_value, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = iter_value_t, + @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_writable}@ + I replace_if(Ep&& exec, I first, S last, Pred pred, + const T& new_value, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = range_value_t, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_writable}@, const T&> + borrowed_iterator_t + replace_if(Ep&& exec, R&& r, Pred pred, const T& new_value, + Proj proj = {}); // freestanding-deleted } template @@ -1741,7 +2160,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); @@ -1752,14 +2171,14 @@ 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); namespace ranges { template - using replace_copy_result = in_out_result; + using @\libglobal{replace_copy_result}@ = in_out_result; template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class O, class Proj = identity, @@ -1780,10 +2199,31 @@ replace_copy(R&& r, O result, const T1& old_value, const T2& new_value, Proj proj = {}); + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + class Proj = identity, + class T1 = projected_value_t, class T2 = iter_value_t> + requires @\libconcept{indirectly_copyable}@ && + @\libconcept{indirect_binary_predicate}@, const T1*> && + @\libconcept{indirectly_writable}@ + replace_copy_result + replace_copy(Ep&& exec, I first, S last, O result, OutS result_last, const T1& old_value, + const T2& new_value, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class Proj = identity, class T1 = projected_value_t, Proj>, + class T2 = range_value_t> + requires @\libconcept{indirectly_copyable}@, iterator_t> && + @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> && + @\libconcept{indirectly_writable}@, const T2&> + replace_copy_result, borrowed_iterator_t> + replace_copy(Ep&& exec, R&& r, OutR&& result_r, const T1& old_value, const T2& new_value, + Proj proj = {}); // freestanding-deleted + template - using replace_copy_if_result = in_out_result; + using @\libglobal{replace_copy_if_result}@ = in_out_result; - template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class O, class T = iter_value_t + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class O, class T = iter_value_t, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{indirectly_copyable}@ && @\libconcept{output_iterator}@ constexpr replace_copy_if_result @@ -1795,6 +2235,22 @@ constexpr replace_copy_if_result, O> replace_copy_if(R&& r, O result, Pred pred, const T& new_value, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class T = iter_value_t, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_copyable}@ && @\libconcept{indirectly_writable}@ + replace_copy_if_result + replace_copy_if(Ep&& exec, I first, S last, O result, OutS result_last, + Pred pred, const T& new_value, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class T = range_value_t, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, iterator_t> && + @\libconcept{indirectly_writable}@, const T&> + replace_copy_if_result, borrowed_iterator_t> + replace_copy_if(Ep&& exec, R&& r, OutR&& result_r, Pred pred, const T& new_value, + Proj proj = {}); // freestanding-deleted } // \ref{alg.fill}, fill @@ -1802,14 +2258,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 { @@ -1822,6 +2278,17 @@ template> requires @\libconcept{output_iterator}@ constexpr O fill_n(O first, iter_difference_t n, const T& value); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ S, + class T = iter_value_t> + requires @\libconcept{indirectly_writable}@ + O fill(Ep&& exec, O first, S last, const T& value); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class T = range_value_t> + requires @\libconcept{indirectly_writable}@, const T&> + borrowed_iterator_t fill(Ep&& exec, R&& r, const T& value); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ O, class T = iter_value_t> + requires @\libconcept{indirectly_writable}@ + O fill_n(Ep&& exec, O first, iter_difference_t n, const T& value); // freestanding-deleted } // \ref{alg.generate}, generate @@ -1829,13 +2296,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 { @@ -1856,14 +2323,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); @@ -1879,6 +2346,21 @@ projected, Proj>, const T*> constexpr borrowed_subrange_t remove(R&& r, const T& value, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{permutable}@ && + @\libconcept{indirect_binary_predicate}@, const T*> + subrange remove(Ep&& exec, I first, S last, const T& value, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{permutable}@> && + @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + borrowed_subrange_t + remove(Ep&& exec, R&& r, const T& value, Proj proj = {}); // freestanding-deleted + template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr subrange remove_if(I first, S last, Pred pred, Proj proj = {}); @@ -1887,6 +2369,17 @@ requires @\libconcept{permutable}@> constexpr borrowed_subrange_t remove_if(R&& r, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{permutable}@ + subrange + remove_if(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{permutable}@> + borrowed_subrange_t + remove_if(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // freestanding-deleted } 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 @@ -1907,13 +2400,13 @@ 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); namespace ranges { template - using remove_copy_result = in_out_result; + using @\libglobal{remove_copy_result}@ = in_out_result; template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O, class Proj = identity, class T = projected_value_t> @@ -1929,8 +2422,25 @@ constexpr remove_copy_result, O> remove_copy(R&& r, O result, const T& value, Proj proj = {}); + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirectly_copyable}@ && + @\libconcept{indirect_binary_predicate}@, const T*> + remove_copy_result + remove_copy(Ep&& exec, I first, S last, O result, OutS result_last, const T& value, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class Proj = identity, class T = projected_value_t, Proj>> + requires @\libconcept{indirectly_copyable}@, iterator_t> && + @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + remove_copy_result, borrowed_iterator_t> + remove_copy(Ep&& exec, R&& r, OutR&& result_r, const T& value, + Proj proj = {}); // freestanding-deleted + template - using remove_copy_if_result = in_out_result; + using @\libglobal{remove_copy_if_result}@ = in_out_result; template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> @@ -1942,6 +2452,21 @@ requires @\libconcept{indirectly_copyable}@, O> constexpr remove_copy_if_result, O> remove_copy_if(R&& r, O result, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_copyable}@ + remove_copy_if_result + remove_copy_if(Ep&& exec, I first, S last, O result, OutS result_last, Pred pred, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, iterator_t> + remove_copy_if_result, borrowed_iterator_t> + remove_copy_if(Ep&& exec, R&& r, OutR&& result_r, Pred pred, + Proj proj = {}); // freestanding-deleted } // \ref{alg.unique}, unique @@ -1951,10 +2476,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); @@ -1967,6 +2492,18 @@ requires @\libconcept{permutable}@> constexpr borrowed_subrange_t unique(R&& r, C comp = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_equivalence_relation}@> C = ranges::equal_to> + requires @\libconcept{permutable}@ + subrange unique(Ep&& exec, I first, S last, C comp = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_equivalence_relation}@, Proj>> C = ranges::equal_to> + requires @\libconcept{permutable}@> + borrowed_subrange_t + unique(Ep&& exec, R&& r, C comp = {}, Proj proj = {}); // freestanding-deleted } template @@ -1979,19 +2516,19 @@ 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); namespace ranges { template - using unique_copy_result = in_out_result; + using @\libglobal{unique_copy_result}@ = in_out_result; template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O, class Proj = identity, @\libconcept{indirect_equivalence_relation}@> C = ranges::equal_to> @@ -2009,13 +2546,28 @@ @\libconcept{indirectly_copyable_storable}@, O>) constexpr unique_copy_result, O> unique_copy(R&& r, O result, C comp = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Proj = identity, + @\libconcept{indirect_equivalence_relation}@> C = ranges::equal_to> + requires @\libconcept{indirectly_copyable}@ + unique_copy_result + unique_copy(Ep&& exec, I first, S last, O result, OutS result_last, C comp = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class Proj = identity, + @\libconcept{indirect_equivalence_relation}@, Proj>> C = ranges::equal_to> + requires @\libconcept{indirectly_copyable}@, iterator_t> + unique_copy_result, borrowed_iterator_t> + unique_copy(Ep&& exec, R&& r, OutR&& result_r, C comp = {}, + Proj proj = {}); // freestanding-deleted } // \ref{alg.reverse}, reverse 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 { @@ -2025,6 +2577,13 @@ template<@\libconcept{bidirectional_range}@ R> requires @\libconcept{permutable}@> constexpr borrowed_iterator_t reverse(R&& r); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S> + requires @\libconcept{permutable}@ + I reverse(Ep&& exec, I first, S last); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R> + requires @\libconcept{permutable}@> + borrowed_iterator_t reverse(Ep&& exec, R&& r); // freestanding-deleted } template @@ -2033,13 +2592,15 @@ 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); namespace ranges { template - using reverse_copy_result = in_out_result; + using @\libglobal{reverse_copy_result}@ = in_out_result; + template + using @\libglobal{reverse_copy_truncated_result}@ = in_in_out_result; template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O> requires @\libconcept{indirectly_copyable}@ @@ -2049,6 +2610,17 @@ requires @\libconcept{indirectly_copyable}@, O> constexpr reverse_copy_result, O> reverse_copy(R&& r, O result); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS> + requires @\libconcept{indirectly_copyable}@ + reverse_copy_truncated_result + reverse_copy(Ep&& exec, I first, S last, O result, + OutS result_last); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR> + requires @\libconcept{indirectly_copyable}@, iterator_t> + reverse_copy_truncated_result, borrowed_iterator_t> + reverse_copy(Ep&& exec, R&& r, OutR&& result_r); // freestanding-deleted } // \ref{alg.rotate}, rotate @@ -2057,7 +2629,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); @@ -2068,6 +2640,15 @@ template<@\libconcept{forward_range}@ R> requires @\libconcept{permutable}@> constexpr borrowed_subrange_t rotate(R&& r, iterator_t middle); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S> + requires @\libconcept{permutable}@ + subrange + rotate(Ep&& exec, I first, I middle, S last); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R> + requires @\libconcept{permutable}@> + borrowed_subrange_t + rotate(Ep&& exec, R&& r, iterator_t middle); // freestanding-deleted } template @@ -2076,13 +2657,15 @@ 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); namespace ranges { template - using rotate_copy_result = in_out_result; + using @\libglobal{rotate_copy_result}@ = in_out_result; + template + using @\libglobal{rotate_copy_truncated_result}@ = in_in_out_result; template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O> requires @\libconcept{indirectly_copyable}@ @@ -2092,6 +2675,18 @@ requires @\libconcept{indirectly_copyable}@, O> constexpr rotate_copy_result, O> rotate_copy(R&& r, iterator_t middle, O result); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS> + requires @\libconcept{indirectly_copyable}@ + rotate_copy_truncated_result + rotate_copy(Ep&& exec, I first, I middle, S last, O result, // freestanding-deleted + OutS result_last); + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR> + requires @\libconcept{indirectly_copyable}@, iterator_t> + rotate_copy_truncated_result, borrowed_iterator_t> + rotate_copy(Ep&& exec, R&& r, iterator_t middle, // freestanding-deleted + OutR&& result_r); } // \ref{alg.random.sample}, sample @@ -2139,7 +2734,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); @@ -2149,6 +2744,15 @@ template<@\libconcept{forward_range}@ R> requires @\libconcept{permutable}@> constexpr borrowed_subrange_t shift_left(R&& r, range_difference_t n); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S> + requires @\libconcept{permutable}@ + subrange + shift_left(Ep&& exec, I first, S last, iter_difference_t n); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R> + requires @\libconcept{permutable}@> + borrowed_subrange_t + shift_left(Ep&& exec, R&& r, range_difference_t n); // freestanding-deleted } template @@ -2157,7 +2761,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); @@ -2167,6 +2771,15 @@ template<@\libconcept{forward_range}@ R> requires @\libconcept{permutable}@> constexpr borrowed_subrange_t shift_right(R&& r, range_difference_t n); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S> + requires @\libconcept{permutable}@ + subrange + shift_right(Ep&& exec, I first, S last, iter_difference_t n); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R> + requires @\libconcept{permutable}@> + borrowed_subrange_t + shift_right(Ep&& exec, R&& r, range_difference_t n); // freestanding-deleted } // \ref{alg.sorting}, sorting and related operations @@ -2177,10 +2790,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); @@ -2194,18 +2807,28 @@ requires @\libconcept{sortable}@, Comp, Proj> constexpr borrowed_iterator_t sort(R&& r, Comp comp = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@ + I sort(Ep&& exec, I first, S last, Comp comp = {}, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + borrowed_iterator_t + sort(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // freestanding-deleted } 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); @@ -2213,11 +2836,22 @@ 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<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@ + I stable_sort(Ep&& exec, I first, S last, Comp comp = {}, + Proj proj = {}); // hosted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + borrowed_iterator_t + stable_sort(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // hosted } template @@ -2227,11 +2861,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); @@ -2246,6 +2880,18 @@ constexpr borrowed_iterator_t partial_sort(R&& r, iterator_t middle, Comp comp = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@ + I partial_sort(Ep&& exec, I first, I middle, S last, Comp comp = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + borrowed_iterator_t + partial_sort(Ep&& exec, R&& r, iterator_t middle, Comp comp = {}, + Proj proj = {}); // freestanding-deleted } template @@ -2261,14 +2907,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, @@ -2276,7 +2922,7 @@ namespace ranges { template - using partial_sort_copy_result = in_out_result; + using @\libglobal{partial_sort_copy_result}@ = in_out_result; template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{random_access_iterator}@ I2, @\libconcept{sentinel_for}@ S2, @@ -2295,6 +2941,25 @@ constexpr partial_sort_copy_result, borrowed_iterator_t> partial_sort_copy(R1&& r, R2&& result_r, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_copyable}@ && @\libconcept{sortable}@ && + @\libconcept{indirect_strict_weak_order}@, projected> + partial_sort_copy_result + partial_sort_copy(Ep&& exec, I1 first, S1 last, I2 result_first, S2 result_last, + Comp comp = {}, Proj1 proj1 = {}, + Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_copyable}@, iterator_t> && + @\libconcept{sortable}@, Comp, Proj2> && + @\libconcept{indirect_strict_weak_order}@, Proj1>, + projected, Proj2>> + partial_sort_copy_result, borrowed_iterator_t> + partial_sort_copy(Ep&& exec, R1&& r, R2&& result_r, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } template @@ -2303,10 +2968,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); @@ -2317,6 +2982,15 @@ template<@\libconcept{forward_range}@ R, class Proj = identity, @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr bool is_sorted(R&& r, Comp comp = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + bool is_sorted(Ep&& exec, I first, S last, Comp comp = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + bool is_sorted(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // freestanding-deleted } template @@ -2328,11 +3002,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); @@ -2344,7 +3018,17 @@ @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr borrowed_iterator_t is_sorted_until(R&& r, Comp comp = {}, Proj proj = {}); - } + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + I is_sorted_until(Ep&& exec, I first, S last, Comp comp = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + borrowed_iterator_t + is_sorted_until(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // freestanding-deleted + } // \ref{alg.nth.element}, Nth element template @@ -2354,11 +3038,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); @@ -2372,6 +3056,18 @@ requires @\libconcept{sortable}@, Comp, Proj> constexpr borrowed_iterator_t nth_element(R&& r, iterator_t nth, Comp comp = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@ + I nth_element(Ep&& exec, I first, I nth, S last, Comp comp = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + borrowed_iterator_t + nth_element(Ep&& exec, R&& r, iterator_t nth, Comp comp = {}, + Proj proj = {}); // freestanding-deleted } // \ref{alg.binary.search}, binary search @@ -2434,7 +3130,7 @@ namespace ranges { template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, - class T = projected_value_t, @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> constexpr subrange equal_range(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); @@ -2474,7 +3170,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 { @@ -2484,6 +3180,14 @@ template<@\libconcept{input_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr bool is_partitioned(R&& r, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + bool is_partitioned(Ep&& exec, I first, S last, Pred pred, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + bool is_partitioned(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // freestanding-deleted } template @@ -2491,7 +3195,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); @@ -2506,15 +3210,26 @@ requires @\libconcept{permutable}@> constexpr borrowed_subrange_t partition(R&& r, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{permutable}@ + subrange + partition(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{permutable}@> + borrowed_subrange_t + partition(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // freestanding-deleted } 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); @@ -2522,11 +3237,25 @@ 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<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{permutable}@ + subrange + stable_partition(Ep&& exec, I first, S last, Pred pred, + Proj proj = {}); // hosted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{permutable}@> + borrowed_subrange_t + stable_partition(Ep&& exec, R&& r, Pred pred, Proj proj = {}); // hosted } 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); namespace ranges { template - using partition_copy_result = in_out_out_result; + using @\libglobal{partition_copy_result}@ = in_out_out_result; template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O1, @\libconcept{weakly_incrementable}@ O2, @@ -2561,6 +3290,26 @@ @\libconcept{indirectly_copyable}@, O2> constexpr partition_copy_result, O1, O2> partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O1, @\libconcept{sized_sentinel_for}@ OutS1, + @\libconcept{random_access_iterator}@ O2, @\libconcept{sized_sentinel_for}@ OutS2, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_copyable}@ && @\libconcept{indirectly_copyable}@ + partition_copy_result + partition_copy(Ep&& exec, I first, S last, O1 out_true, OutS1 last_true, + O2 out_false, OutS2 last_false, Pred pred, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, + @\exposconcept{sized-random-access-range}@ OutR1, @\exposconcept{sized-random-access-range}@ OutR2, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, iterator_t> && + @\libconcept{indirectly_copyable}@, iterator_t> + partition_copy_result, borrowed_iterator_t, + borrowed_iterator_t> + partition_copy(Ep&& exec, R&& r, OutR1&& out_true_r, OutR2&& out_false_r, Pred pred, + Proj proj = {}); // freestanding-deleted } template @@ -2593,21 +3342,21 @@ 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); namespace ranges { template - using merge_result = in_in_out_result; + using @\libglobal{merge_result}@ = in_in_out_result; template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, @\libconcept{weakly_incrementable}@ O, class Comp = ranges::less, class Proj1 = identity, @@ -2622,23 +3371,39 @@ constexpr merge_result, borrowed_iterator_t, O> merge(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + merge_result + merge(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, O result, OutS result_last, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, iterator_t, Comp, Proj1, Proj2> + merge_result, borrowed_iterator_t, borrowed_iterator_t> + merge(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } 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); @@ -2647,12 +3412,24 @@ 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 + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@ + I inplace_merge(Ep&& exec, I first, I middle, S last, Comp comp = {}, + Proj proj = {}); // hosted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + borrowed_iterator_t + inplace_merge(Ep&& exec, R&& r, iterator_t middle, Comp comp = {}, + Proj proj = {}); // hosted } // \ref{alg.set.operations}, set operations @@ -2664,12 +3441,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); @@ -2687,6 +3464,20 @@ projected, Proj2>> Comp = ranges::less> constexpr bool includes(R1&& r1, R2&& r2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, projected> Comp = + ranges::less> + bool includes(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, Proj1>, + projected, Proj2>> Comp = ranges::less> + bool includes(Ep&& exec, R1&& r1, R2&& r2, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } template @@ -2696,27 +3487,27 @@ 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); namespace ranges { template - using set_union_result = in_in_out_result; + using @\libglobal{set_union_result}@ = in_in_out_result; template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, @\libconcept{weakly_incrementable}@ O, class Comp = ranges::less, @@ -2731,6 +3522,24 @@ constexpr set_union_result, borrowed_iterator_t, O> set_union(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + set_union_result + set_union(Ep&& exec, I1 first1, S1 last1, + I2 first2, S2 last2, O result, OutS result_last, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, iterator_t, Comp, Proj1, Proj2> + set_union_result, borrowed_iterator_t, + borrowed_iterator_t> + set_union(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } template @@ -2746,21 +3555,21 @@ 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); namespace ranges { template - using set_intersection_result = in_in_out_result; + using @\libglobal{set_intersection_result}@ = in_in_out_result; template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, @\libconcept{weakly_incrementable}@ O, class Comp = ranges::less, @@ -2775,6 +3584,24 @@ constexpr set_intersection_result, borrowed_iterator_t, O> set_intersection(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + set_intersection_result + set_intersection(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + O result, OutS result_last, Comp comp = {}, Proj1 proj1 = {}, + Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, iterator_t, Comp, Proj1, Proj2> + set_intersection_result, borrowed_iterator_t, + borrowed_iterator_t> + set_intersection(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } template @@ -2790,21 +3617,23 @@ 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); namespace ranges { template - using set_difference_result = in_out_result; + using @\libglobal{set_difference_result}@ = in_out_result; + template + using @\libglobal{set_difference_truncated_result}@ = in_in_out_result; template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, @\libconcept{weakly_incrementable}@ O, class Comp = ranges::less, @@ -2819,6 +3648,24 @@ constexpr set_difference_result, O> set_difference(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + set_difference_truncated_result + set_difference(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + O result, OutS result_last, Comp comp = {}, Proj1 proj1 = {}, + Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, iterator_t, Comp, Proj1, Proj2> + set_difference_truncated_result, borrowed_iterator_t, + borrowed_iterator_t> + set_difference(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } template @@ -2834,21 +3681,21 @@ 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); namespace ranges { template - using set_symmetric_difference_result = in_in_out_result; + using @\libglobal{set_symmetric_difference_result}@ = in_in_out_result; template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, @\libconcept{weakly_incrementable}@ O, class Comp = ranges::less, @@ -2865,6 +3712,24 @@ borrowed_iterator_t, O> set_symmetric_difference(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + set_symmetric_difference_result + set_symmetric_difference(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + O result, OutS result_last, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, iterator_t, Comp, Proj1, Proj2> + set_symmetric_difference_result, borrowed_iterator_t, + borrowed_iterator_t> + set_symmetric_difference(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } // \ref{alg.heap.operations}, heap operations @@ -2946,10 +3811,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); @@ -2960,6 +3825,15 @@ template<@\libconcept{random_access_range}@ R, class Proj = identity, @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + bool is_heap(Ep&& exec, I first, S last, Comp comp = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + bool is_heap(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // freestanding-deleted } template @@ -2971,11 +3845,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); @@ -2987,6 +3861,16 @@ @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr borrowed_iterator_t is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + I is_heap_until(Ep&& exec, I first, S last, Comp comp = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + borrowed_iterator_t + is_heap_until(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // freestanding-deleted } // \ref{alg.min.max}, minimum and maximum @@ -3010,6 +3894,11 @@ requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> constexpr range_value_t min(R&& r, Comp comp = {}, Proj proj = {}); + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> + range_value_t + min(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // freestanding-deleted } template constexpr const T& max(const T& a, const T& b); @@ -3032,6 +3921,11 @@ requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> constexpr range_value_t max(R&& r, Comp comp = {}, Proj proj = {}); + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> + range_value_t + max(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // freestanding-deleted } template constexpr pair minmax(const T& a, const T& b); @@ -3044,7 +3938,7 @@ namespace ranges { template - using minmax_result = min_max_result; + using @\libglobal{minmax_result}@ = min_max_result; template> Comp = ranges::less> @@ -3059,6 +3953,11 @@ requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> constexpr minmax_result> minmax(R&& r, Comp comp = {}, Proj proj = {}); + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> + minmax_result> + minmax(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // freestanding-deleted } template @@ -3067,10 +3966,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); @@ -3082,6 +3981,17 @@ @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr borrowed_iterator_t min_element(R&& r, Comp comp = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + I min_element(Ep&& exec, I first, S last, Comp comp = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + borrowed_iterator_t + min_element(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // freestanding-deleted } template @@ -3090,10 +4000,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); @@ -3105,6 +4015,17 @@ @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr borrowed_iterator_t max_element(R&& r, Comp comp = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + I max_element(Ep&& exec, I first, S last, Comp comp = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + borrowed_iterator_t + max_element(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // freestanding-deleted } template @@ -3115,16 +4036,16 @@ 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 { template - using minmax_element_result = min_max_result; + using @\libglobal{minmax_element_result}@ = min_max_result; template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> @@ -3134,6 +4055,17 @@ @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr minmax_element_result> minmax_element(R&& r, Comp comp = {}, Proj proj = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + minmax_element_result + minmax_element(Ep&& exec, I first, S last, Comp comp = {}, + Proj proj = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + minmax_element_result> + minmax_element(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); // freestanding-deleted } // \ref{alg.clamp}, bounded value @@ -3161,13 +4093,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); @@ -3187,6 +4119,21 @@ constexpr bool lexicographical_compare(R1&& r1, R2&& r2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, + projected> Comp = ranges::less> + bool lexicographical_compare(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Comp comp = {}, Proj1 proj1 = {}, + Proj2 proj2 = {}); // freestanding-deleted + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, Proj1>, + projected, Proj2>> Comp = ranges::less> + bool lexicographical_compare(Ep&& exec, R1&& r1, R2&& r2, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); // freestanding-deleted } // \ref{alg.three.way}, three-way comparison algorithms @@ -3211,7 +4158,7 @@ namespace ranges { template - using next_permutation_result = in_found_result; + using @\libglobal{next_permutation_result}@ = in_found_result; template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, class Proj = identity> @@ -3234,7 +4181,7 @@ namespace ranges { template - using prev_permutation_result = in_found_result; + using @\libglobal{prev_permutation_result}@ = in_found_result; template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, class Proj = identity> @@ -3260,9 +4207,9 @@ \begin{codeblock} namespace std::ranges { template - struct in_fun_result { - [[no_unique_address]] I in; - [[no_unique_address]] F fun; + struct @\libglobal{in_fun_result}@ { + [[no_unique_address]] I @\libmember{in}{in_fun_result}@; + [[no_unique_address]] F @\libmember{fun}{in_fun_result}@; template requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ @@ -3278,9 +4225,9 @@ }; template - struct in_in_result { - [[no_unique_address]] I1 in1; - [[no_unique_address]] I2 in2; + struct @\libglobal{in_in_result}@ { + [[no_unique_address]] I1 @\libmember{in1}{in_in_result}@; + [[no_unique_address]] I2 @\libmember{in2}{in_in_result}@; template requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ @@ -3296,9 +4243,9 @@ }; template - struct in_out_result { - [[no_unique_address]] I in; - [[no_unique_address]] O out; + struct @\libglobal{in_out_result}@ { + [[no_unique_address]] I @\libmember{in}{in_out_result}@; + [[no_unique_address]] O @\libmember{out}{in_out_result}@; template requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ @@ -3314,10 +4261,10 @@ }; template - struct in_in_out_result { - [[no_unique_address]] I1 in1; - [[no_unique_address]] I2 in2; - [[no_unique_address]] O out; + struct @\libglobal{in_in_out_result}@ { + [[no_unique_address]] I1 @\libmember{in1}{in_in_out_result}@; + [[no_unique_address]] I2 @\libmember{in2}{in_in_out_result}@; + [[no_unique_address]] O @\libmember{out}{in_in_out_result}@; template requires @\libconcept{convertible_to}@ && @@ -3337,10 +4284,10 @@ }; template - struct in_out_out_result { - [[no_unique_address]] I in; - [[no_unique_address]] O1 out1; - [[no_unique_address]] O2 out2; + struct @\libglobal{in_out_out_result}@ { + [[no_unique_address]] I @\libmember{in}{in_out_out_result}@; + [[no_unique_address]] O1 @\libmember{out1}{in_out_out_result}@; + [[no_unique_address]] O2 @\libmember{out2}{in_out_out_result}@; template requires @\libconcept{convertible_to}@ && @@ -3360,9 +4307,9 @@ }; template - struct min_max_result { - [[no_unique_address]] T min; - [[no_unique_address]] T max; + struct @\libglobal{min_max_result}@ { + [[no_unique_address]] T @\libmember{min}{min_max_result}@; + [[no_unique_address]] T @\libmember{max}{min_max_result}@; template requires @\libconcept{convertible_to}@ @@ -3378,9 +4325,9 @@ }; template - struct in_found_result { - [[no_unique_address]] I in; - bool found; + struct @\libglobal{in_found_result}@ { + [[no_unique_address]] I @\libmember{in}{in_found_result}@; + bool @\libmember{found}{in_found_result}@; template requires @\libconcept{convertible_to}@ @@ -3395,9 +4342,9 @@ }; template - struct in_value_result { - [[no_unique_address]] I in; - [[no_unique_address]] T value; + struct @\libglobal{in_value_result}@ { + [[no_unique_address]] I @\libmember{in}{in_value_result}@; + [[no_unique_address]] T @\libmember{value}{in_value_result}@; template requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ @@ -3413,9 +4360,9 @@ }; template - struct out_value_result { - [[no_unique_address]] O out; - [[no_unique_address]] T value; + struct @\libglobal{out_value_result}@ { + [[no_unique_address]] O @\libmember{out}{out_value_result}@; + [[no_unique_address]] T @\libmember{value}{out_value_result}@; template requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ @@ -3450,6 +4397,13 @@ template<@\libconcept{input_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr bool ranges::all_of(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + bool ranges::all_of(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + bool ranges::all_of(Ep&& exec, R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -3490,6 +4444,13 @@ template<@\libconcept{input_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr bool ranges::any_of(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + bool ranges::any_of(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + bool ranges::any_of(Ep&& exec, R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -3530,6 +4491,13 @@ template<@\libconcept{input_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + bool ranges::none_of(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + bool ranges::none_of(Ep&& exec, R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -3573,6 +4541,24 @@ \tcode{ranges::find(std::move(first), last, value, proj) != last}. \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + bool ranges::contains(Ep&& exec, I first, S last, const T& value, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires + @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + bool ranges::contains(Ep&& exec, R&& r, const T& value, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{ranges::find(std::forward(exec), first, last, value, proj) != last}. +\end{itemdescr} + \indexlibraryglobal{contains_subrange}% \begin{itemdecl} template<@\libconcept{forward_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @@ -3591,7 +4577,33 @@ \begin{itemdescr} \pnum \returns -\tcode{first2 == last2 || !ranges::search(first1, last1, first2, last2, pred, proj1, proj2).empty()}. +\begin{codeblock} +first2 == last2 || !ranges::search(first1, last1, first2, last2, + pred, proj1, proj2).empty() +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + bool ranges::contains_subrange(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + bool ranges::contains_subrange(Ep&& exec, R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +first2 == last2 || !ranges::search(std::forward(exec), first1, last1, + first2, last2, pred, proj1, proj2).empty() +\end{codeblock} \end{itemdescr} \rSec2[alg.foreach]{For each} @@ -3717,6 +4729,54 @@ \end{note} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirectly_unary_invocable}@> Fun> + I ranges::for_each(Ep&& exec, I first, S last, Fun f, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirectly_unary_invocable}@, Proj>> Fun> + borrowed_iterator_t + ranges::for_each(Ep&& exec, R&& r, Fun f, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Calls \tcode{invoke(f, invoke(proj, *i))} +for every iterator \tcode{i} +in the range \range{first}{last}. +\begin{note} +If the result of \tcode{invoke(proj, *i)} is a mutable reference, +\tcode{f} can apply non-constant functions. +\end{note} + +\pnum +\returns +\tcode{last}. + +\pnum +\complexity +Applies \tcode{f} and \tcode{proj} exactly \tcode{last - first} times. + +\pnum +\remarks +\begin{itemize} +\item + If \tcode{f} returns a result, the result is ignored. +\item + Implementations do not have the freedom granted under \ref{algorithms.parallel.exec} + to make arbitrary copies of elements from the input sequence. +\item + \tcode{f} may modify objects via its arguments\iref{algorithms.parallel.user}. +\end{itemize} +\begin{note} +Does not return a copy of its \tcode{Fun} parameter, +since parallelization often does not permit +efficient state accumulation. +\end{note} +\end{itemdescr} + \indexlibraryglobal{for_each_n}% \begin{itemdecl} template @@ -3833,6 +4893,49 @@ \end{note} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, class Proj = identity, + @\libconcept{indirectly_unary_invocable}@> Fun> + I ranges::for_each_n(Ep&& exec, I first, iter_difference_t n, Fun f, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{n >= 0} is \tcode{true}. + +\pnum +\effects +Calls \tcode{invoke(f, invoke(proj, *i))} +for every iterator \tcode{i} +in the range \range{first}{first + n}. +\begin{note} +If the result of \tcode{invoke(proj, *i)} is a mutable reference, +\tcode{f} can apply non-constant functions. +\end{note} + +\pnum +\returns +\tcode{first + n}. + +\pnum +\remarks +\begin{itemize} +\item + If \tcode{f} returns a result, the result is ignored. +\item + Implementations do not have the freedom granted under \ref{algorithms.parallel.exec} + to make arbitrary copies of elements from the input sequence. +\item + \tcode{f} may modify objects via its arguments\iref{algorithms.parallel.user}. +\end{itemize} +\begin{note} +Does not return a copy of its \tcode{Fun} parameter, +since parallelization often does not permit +efficient state accumulation. +\end{note} +\end{itemdescr} + \rSec2[alg.find]{Find} \indexlibraryglobal{find}% @@ -3870,6 +4973,17 @@ requires @\libconcept{indirect_binary_predicate}@, Proj>, const T*> constexpr borrowed_iterator_t ranges::find(R&& r, const T& value, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + I ranges::find(Ep&& exec, I first, S last, const T& value, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + borrowed_iterator_t ranges::find(Ep&& exec, R&& r, const T& value, Proj proj = {}); + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr I ranges::find_if(I first, S last, Pred pred, Proj proj = {}); @@ -3877,6 +4991,14 @@ @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr borrowed_iterator_t ranges::find_if(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + I ranges::find_if(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + borrowed_iterator_t ranges::find_if(Ep&& exec, R&& r, Pred pred, Proj proj = {}); + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr I ranges::find_if_not(I first, S last, Pred pred, Proj proj = {}); @@ -3884,6 +5006,13 @@ @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr borrowed_iterator_t ranges::find_if_not(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + I ranges::find_if_not(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + borrowed_iterator_t ranges::find_if_not(Ep&& exec, R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -3922,18 +5051,46 @@ 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<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + subrange ranges::find_last(Ep&& exec, I first, S last, const T& value, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires + @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + borrowed_subrange_t ranges::find_last(Ep&& exec, R&& r, const T& value, Proj proj = {}); + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr subrange ranges::find_last_if(I first, S last, Pred pred, Proj proj = {}); template<@\libconcept{forward_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr borrowed_subrange_t ranges::find_last_if(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + subrange ranges::find_last_if(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + borrowed_subrange_t ranges::find_last_if(Ep&& exec, R&& r, Pred pred, Proj proj = {}); + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr subrange ranges::find_last_if_not(I first, S last, Pred pred, Proj proj = {}); template<@\libconcept{forward_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr borrowed_subrange_t ranges::find_last_if_not(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + subrange ranges::find_last_if_not(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + borrowed_subrange_t ranges::find_last_if_not(Ep&& exec, R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -4001,6 +5158,20 @@ constexpr borrowed_subrange_t ranges::find_end(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + subrange + ranges::find_end(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + borrowed_subrange_t + ranges::find_end(Ep&& exec, R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -4046,7 +5217,7 @@ applications of the corresponding predicate and any projections. \end{itemdescr} -\rSec2[alg.find.first.of]{Find first} +\rSec2[alg.find.first.of]{Find first of} \indexlibraryglobal{find_first_of}% \begin{itemdecl} @@ -4087,6 +5258,19 @@ ranges::find_first_of(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + I1 ranges::find_first_of(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + borrowed_iterator_t + ranges::find_first_of(Ep&& exec, R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -4113,7 +5297,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} @@ -4147,6 +5331,17 @@ @\libconcept{indirect_binary_predicate}@, Proj>, projected, Proj>> Pred = ranges::equal_to> constexpr borrowed_iterator_t ranges::adjacent_find(R&& r, Pred pred = {}, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_binary_predicate}@, + projected> Pred = ranges::equal_to> + I ranges::adjacent_find(Ep&& exec, I first, S last, Pred pred = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_binary_predicate}@, Proj>, + projected, Proj>> Pred = ranges::equal_to> + borrowed_iterator_t + ranges::adjacent_find(Ep&& exec, R&& r, Pred pred = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -4168,13 +5363,13 @@ \pnum \complexity -For the overloads with no \tcode{ExecutionPolicy}, +For the non-parallel algorithm overloads, exactly \[ \min(\tcode{(i - first) + 1}, \ \tcode{(last - first) - 1}) \] applications of the corresponding predicate, where \tcode{i} is \tcode{adjacent_find}'s return value. -For the overloads with an \tcode{ExecutionPolicy}, -\bigoh{\tcode{last - first}} applications of the corresponding predicate, -and no more than twice as many applications of any projection. +For the parallel algorithm overloads, +\bigoh{\tcode{last - first}} applications of the corresponding predicate. +No more than twice as many applications of any projection. \end{itemdescr} \rSec2[alg.count]{Count} @@ -4208,6 +5403,18 @@ requires @\libconcept{indirect_binary_predicate}@, Proj>, const T*> constexpr range_difference_t ranges::count(R&& r, const T& value, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + iter_difference_t + ranges::count(Ep&& exec, I first, S last, const T& value, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + range_difference_t ranges::count(Ep&& exec, R&& r, const T& value, Proj proj = {}); + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr iter_difference_t @@ -4216,6 +5423,15 @@ @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr range_difference_t ranges::count_if(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + iter_difference_t + ranges::count_if(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + range_difference_t + ranges::count_if(Ep&& exec, R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -4309,12 +5525,26 @@ constexpr ranges::mismatch_result, borrowed_iterator_t> ranges::mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); -\end{itemdecl} + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + ranges::mismatch_result + ranges::mismatch(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + ranges::mismatch_result, borrowed_iterator_t> + ranges::mismatch(Ep&& exec, R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} \begin{itemdescr} \pnum Let \tcode{last2} be \tcode{first2 + (last1 - first1)} -for the overloads with no parameter \tcode{last2} or \tcode{r2}. +for the overloads in namespace \tcode{std} with no parameter \tcode{last2}. \pnum Let $E$ be: @@ -4399,6 +5629,18 @@ requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> constexpr bool ranges::equal(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + bool ranges::equal(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + bool ranges::equal(Ep&& exec, R1&& r1, R2&& r2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -4407,7 +5649,7 @@ \begin{itemize} \item \tcode{last2} be \tcode{first2 + (last1 - first1)} - for the overloads with no parameter \tcode{last2} or \tcode{r2}; + for the overloads in namespace \tcode{std} with no parameter \tcode{last2}; \item \tcode{pred} be \tcode{equal_to\{\}} for the overloads with no parameter \tcode{pred}; @@ -4442,27 +5684,19 @@ and \tcode{last1 - first1 != last2 - first2} for the overloads in namespace \tcode{std}; \item - the types of \tcode{first1}, \tcode{last1}, \tcode{first2}, and \tcode{last2} - pairwise model \libconcept{sized_sentinel_for}\iref{iterator.concept.sizedsentinel} + the types of \tcode{first1}, \tcode{last1}, \tcode{first2}, and \tcode{last2} + pairwise model \libconcept{sized_sentinel_for}\iref{iterator.concept.sizedsentinel} and \tcode{last1 - first1 != last2 - first2} - for the first overload in namespace \tcode{ranges}, + for the first and third overloads in namespace \tcode{ranges}, or \item \tcode{R1} and \tcode{R2} each model \libconcept{sized_range} and \tcode{ranges::distance(r1) != ranges::distance(r2)} - for the second overload in namespace \tcode{ranges}, + for the second and fourth overloads in namespace \tcode{ranges}, \end{itemize} then no applications of the corresponding predicate and each projection; -otherwise, -\begin{itemize} -\item - For the overloads with no \tcode{ExecutionPolicy}, - at most $\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ - applications of the corresponding predicate and any projections. -\item - For the overloads with an \tcode{ExecutionPolicy}, - \bigoh{\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})} - applications of the corresponding predicate. -\end{itemize} +otherwise, at most +\[ \min(\tcode{last1 - first1}, \ \tcode{last2 - first2}) \] +applications of the corresponding predicate and any projections. \end{itemdescr} \rSec2[alg.is.permutation]{Is permutation} @@ -4606,7 +5840,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: @@ -4635,6 +5869,20 @@ constexpr borrowed_subrange_t ranges::search(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + subrange + ranges::search(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + borrowed_subrange_t + ranges::search(Ep&& exec, R1&& r1, R2&& r2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -4644,7 +5892,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 @@ -4705,9 +5953,9 @@ \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 condition $E$ is true. +the condition $E$ is \tcode{true}. Returns \tcode{last} if no such iterator is found. \pnum @@ -4730,13 +5978,27 @@ constexpr borrowed_subrange_t ranges::search_n(R&& r, range_difference_t count, const T& value, Pred pred = {}, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Pred = ranges::equal_to, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirectly_comparable}@ + subrange + ranges::search_n(Ep&& exec, I first, S last, iter_difference_t count, + const T& value, Pred pred = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Pred = ranges::equal_to, + class Proj = identity, class T = projected_value_t, Proj>> + requires @\libconcept{indirectly_comparable}@, const T*, Pred, Proj> + borrowed_subrange_t + ranges::search_n(Ep&& exec, R&& r, range_difference_t count, + const T& value, Pred pred = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \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)}. @@ -4790,6 +6052,30 @@ \end{codeblock} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + bool ranges::starts_with(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, + @\exposconcept{sized-random-access-range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + bool ranges::starts_with(Ep&& exec, R1&& r1, R2&& r2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +ranges::mismatch(std::forward(exec), std::move(first1), last1, std::move(first2), + last2, pred, proj1, proj2).in2 == last2 +\end{codeblock} +\end{itemdescr} + \rSec2[alg.ends.with]{Ends with} \indexlibraryglobal{ends_with}% @@ -4810,13 +6096,36 @@ \pnum \returns -\tcode{false} if $\tcode{N1} < \tcode{N2}$, otherwise +\tcode{false} if $\tcode{N1} < \tcode{N2}$, otherwise: \begin{codeblock} ranges::equal(std::move(first1) + (N1 - N2), last1, std::move(first2), last2, pred, proj1, proj2) \end{codeblock} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + bool ranges::ends_with(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{N1} be \tcode{last1 - first1} and +\tcode{N2} be \tcode{last2 - first2}. + +\pnum +\returns +\tcode{false} if $\tcode{N1} < \tcode{N2}$, otherwise: +\begin{codeblock} +ranges::equal(std::forward(exec), std::move(first1) + (N1 - N2), last1, + std::move(first2), last2, pred, proj1, proj2) +\end{codeblock} +\end{itemdescr} + \begin{itemdecl} template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> @@ -4834,13 +6143,37 @@ \pnum \returns -\tcode{false} if $\tcode{N1} < \tcode{N2}$, otherwise +\tcode{false} if $\tcode{N1} < \tcode{N2}$, otherwise: \begin{codeblock} ranges::equal(views::drop(ranges::ref_view(r1), N1 - static_cast(N2)), r2, pred, proj1, proj2) \end{codeblock} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, + @\exposconcept{sized-random-access-range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + bool ranges::ends_with(Ep&& exec, R1&& r1, R2&& r2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{N1} be \tcode{ranges::distance(r1)} and +\tcode{N2} be \tcode{ranges::distance(r2)}. + +\pnum +\returns +\tcode{false} if $\tcode{N1} < \tcode{N2}$, otherwise: +\begin{codeblock} +ranges::equal(std::forward(exec), + views::drop(ranges::ref_view(r1), N1 - static_cast(N2)), + r2, pred, proj1, proj2) +\end{codeblock} +\end{itemdescr} + \rSec2[alg.fold]{Fold} \indexlibraryglobal{fold_left}% @@ -5059,31 +6392,53 @@ \indexlibraryglobal{copy}% \begin{itemdecl} template - ForwardIterator2 copy(ExecutionPolicy&& policy, + ForwardIterator2 copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS> + requires @\libconcept{indirectly_copyable}@ + ranges::copy_result + ranges::copy(Ep&& exec, I first, S last, O result, OutS result_last); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR> + requires @\libconcept{indirectly_copyable}@, iterator_t> + ranges::copy_result, borrowed_iterator_t> + ranges::copy(Ep&& exec, R&& r, OutR&& result_r); \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{result_last} be \tcode{result + (last - first)} +for the overload in namespace \tcode{std}. + +\pnum +Let $N$ be $\min(\tcode{last - first}, \ \tcode{result_last - result})$. + \pnum \expects -The ranges \range{first}{last} and \range{result}{result + (last - first)} +The ranges \range{first}{last} and \range{result}{result + $N$} do not overlap. \pnum \effects -Copies elements in the range \range{first}{last} -into the range \range{result}{result + (last - first)}. -For each non-negative integer \tcode{n < (last - first)}, -performs \tcode{*(result + n) = *(first + n)}. +Copies elements in the range \range{first}{first + $N$} +into the range \range{result}{result + $N$}. +For each non-negative integer $n < N$, +performs \tcode{*(result + $n$) = *(first + $n$)}. \pnum \returns -\tcode{result + (last - first)}. +\begin{itemize} +\item + \tcode{result + $N$} for the overload in namespace \tcode{std}. +\item + \tcode{\{first + $N$, result + $N$\}} for the overloads in namespace \tcode{ranges}. +\end{itemize} \pnum \complexity -Exactly \tcode{last - first} assignments. +Exactly $N$ assignments. \end{itemdescr} \indexlibraryglobal{copy_n}% @@ -5100,11 +6455,24 @@ requires @\libconcept{indirectly_copyable}@ constexpr ranges::copy_n_result ranges::copy_n(I first, iter_difference_t n, O result); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{random_access_iterator}@ O, + @\libconcept{sized_sentinel_for}@ OutS> + requires @\libconcept{indirectly_copyable}@ + ranges::copy_n_result + ranges::copy_n(Ep&& exec, I first, iter_difference_t n, O result, OutS result_last); \end{itemdecl} \begin{itemdescr} \pnum -Let $N$ be $\max(0, \tcode{n})$. +Let $M$ be $\max(0, \ \tcode{n})$. + +\pnum +Let \tcode{result_last} be \tcode{result + $M$} +for the overloads with no parameter \tcode{result_last}. + +\pnum +Let $N$ be $\min(\tcode{result_last - result}, M)$. \pnum \mandates @@ -5153,38 +6521,67 @@ requires @\libconcept{indirectly_copyable}@, O> constexpr ranges::copy_if_result, O> ranges::copy_if(R&& r, O result, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_copyable}@ + ranges::copy_if_result + ranges::copy_if(Ep&& exec, I first, S last, O result, OutS result_last, + Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, iterator_t> + ranges::copy_if_result, borrowed_iterator_t> + ranges::copy_if(Ep&& exec, R&& r, OutR&& result_r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum -Let $E$ be: +Let $E(\tcode{i})$ be: \begin{itemize} \item \tcode{bool(pred(*i))} for the overloads in namespace \tcode{std}; \item \tcode{bool(invoke(pred, invoke(proj, *i)))} - for the overloads in namespace \tcode{ranges}, + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +Let: +\begin{itemize} +\item + $M$ be the number of iterators \tcode{i} in the range \range{first}{last} + for which the condition $E(\tcode{i})$ holds; +\item + \tcode{result_last} be \tcode{result + $M$} + for the overloads with no parameter \tcode{result_last} or \tcode{result_r}; +\item + $N$ be $\min(M, \ \tcode{result_last - result})$. \end{itemize} -and $N$ be the number of iterators \tcode{i} in the range \range{first}{last} -for which the condition $E$ holds. \pnum \expects -The ranges \range{first}{last} and \range{result}{result + (last - first)} +The ranges \range{first}{last} and \range{result}{result + $N$} do not overlap. \begin{note} -For the overload with an \tcode{ExecutionPolicy}, -there might be a performance cost +For the parallel algorithm overload in namespace \tcode{std}, +there can be a performance cost if \tcode{iterator_traits::value_type} -is not \oldconcept{\-Move\-Constructible} (\tref{cpp17.moveconstructible}). +does not meet the \oldconcept{\-Move\-Constructible} (\tref{cpp17.moveconstructible}) requirements. +For the parallel algorithm overloads in namespace \tcode{ranges}, +there can be a performance cost +if \tcode{iter_value_t} does not model \libconcept{move_constructible}. \end{note} \pnum \effects -Copies all of the elements referred to +Copies the first $N$ elements referred to by the iterator \tcode{i} in the range \range{first}{last} -for which $E$ is \tcode{true}. +for which $E(\tcode{i})$ is \tcode{true} +into the range \range{result}{result + $N$}. \pnum \returns @@ -5194,12 +6591,19 @@ for the overloads in namespace \tcode{std}. \item \tcode{\{last, result + $N$\}} - for the overloads in namespace \tcode{ranges}. + for the overloads in namespace \tcode{ranges}, if $N$ is equal to $M$. +\item + Otherwise, \tcode{\{j, result_last\}} + for the overloads in namespace \tcode{ranges}, + where \tcode{j} is the iterator in \range{first}{last} + for which $E(\tcode{j})$ holds + and there are exactly $N$ iterators \tcode{i} + in \range{first}{j} for which $E(\tcode{i})$ holds. \end{itemize} \pnum \complexity -Exactly \tcode{last - first} applications +At most \tcode{last - first} applications of the corresponding predicate and any projection. \pnum @@ -5281,7 +6685,7 @@ \begin{itemdescr} \pnum -Let $E$ be +Let $E(n)$ be \begin{itemize} \item \tcode{std::move(*(first + $n$))} @@ -5301,7 +6705,7 @@ Moves elements in the range \range{first}{last} into the range \range{result}{result + $N$} starting from \tcode{first} and proceeding to \tcode{last}. -For each non-negative integer $n < N$, performs \tcode{*(result + $n$) = $E$}. +For each non-negative integer $n < N$, performs \tcode{*(result + $n$) = $E(n)$}. \pnum \returns @@ -5322,14 +6726,39 @@ \indexlibrary{\idxcode{move}!algorithm}% \begin{itemdecl} template - ForwardIterator2 move(ExecutionPolicy&& policy, + ForwardIterator2 move(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS> + requires @\libconcept{indirectly_movable}@ + ranges::move_result + ranges::move(Ep&& exec, I first, S last, O result, OutS result_last); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR> + requires @\libconcept{indirectly_movable}@, iterator_t> + ranges::move_result, borrowed_iterator_t> + ranges::move(Ep&& exec, R&& r, OutR&& result_r); \end{itemdecl} \begin{itemdescr} \pnum -Let $N$ be \tcode{last - first}. +Let $E(n)$ be: +\begin{itemize} +\item + \tcode{std::move(*(first + $n$))} + for the overload in namespace \tcode{std}; +\item + \tcode{ranges::iter_move(first + $n$)} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +Let \tcode{result_last} be \tcode{result + (last - first)} +for the overloads in namespace \tcode{std}. + +\pnum +Let $N$ be $\min(\tcode{last - first}, \ \tcode{result_last - result})$. \pnum \expects @@ -5338,14 +6767,21 @@ \pnum \effects -Moves elements in the range \range{first}{last} +Moves elements in the range \range{first}{first + $N$} into the range \range{result}{result + $N$}. For each non-negative integer $n < N$, -performs \tcode{*(result + $n$) = std::\brk{}move(*(first + $n$))}. +performs \tcode{*(result + $n$) = $E(n)$}. \pnum \returns -\tcode{result + $N$}. +\begin{itemize} +\item + \tcode{result + $N$} + for the overload in namespace \tcode{std}. +\item + \tcode{\{first + $N$, result + $N$\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} \pnum \complexity @@ -5371,7 +6807,7 @@ \begin{itemdescr} \pnum -Let $E$ be +Let $E(n)$ be \begin{itemize} \item \tcode{std::move(*(last - $n$))} @@ -5396,7 +6832,7 @@ when \tcode{last} is in the range \range{result - $N$}{result}. \end{footnote} For each positive integer $n \le N$, -performs \tcode{*(result - $n$) = $E$}. +performs \tcode{*(result - $n$) = $E(n)$}. \pnum \returns @@ -5421,7 +6857,7 @@ template constexpr ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); // freestanding + ForwardIterator2 first2); template ForwardIterator2 swap_ranges(ExecutionPolicy&& exec, @@ -5436,6 +6872,16 @@ requires @\libconcept{indirectly_swappable}@, iterator_t> constexpr ranges::swap_ranges_result, borrowed_iterator_t> ranges::swap_ranges(R1&& r1, R2&& r2); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2> + requires @\libconcept{indirectly_swappable}@ + ranges::swap_ranges_result + ranges::swap_ranges(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2> + requires @\libconcept{indirectly_swappable}@, iterator_t> + ranges::swap_ranges_result, borrowed_iterator_t> + ranges::swap_ranges(Ep&& exec, R1&& r1, R2&& r2); \end{itemdecl} \begin{itemdescr} @@ -5444,7 +6890,8 @@ \begin{itemize} \item \tcode{last2} be \tcode{first2 + (last1 - first1)} - for the overloads with no parameter named \tcode{last2}; + for the overloads in namespace \tcode{std} + with no parameter named \tcode{last2}; \item $M$ be $\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$. \end{itemize} @@ -5541,21 +6988,57 @@ requires @\libconcept{indirectly_writable}@, Proj>>> constexpr ranges::unary_transform_result, O> ranges::transform(R&& r, O result, F op, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + @\libconcept{copy_constructible}@ F, class Proj = identity> + requires @\libconcept{indirectly_writable}@>> + ranges::unary_transform_result + ranges::transform(Ep&& exec, I first1, S last1, O result, OutS result_last, + F op, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + @\libconcept{copy_constructible}@ F, class Proj = identity> + requires @\libconcept{indirectly_writable}@, + indirect_result_t, Proj>>> + ranges::unary_transform_result, borrowed_iterator_t> + ranges::transform(Ep&& exec, R&& r, OutR&& result_r, F op, Proj proj = {}); + template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, @\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 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + @\libconcept{copy_constructible}@ F, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_writable}@, + projected>> + ranges::binary_transform_result + ranges::transform(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + O result, OutS result_last, + F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, @\libconcept{copy_constructible}@ F, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_writable}@, + indirect_result_t, Proj1>, + projected, Proj2>>> + ranges::binary_transform_result, borrowed_iterator_t, + borrowed_iterator_t> + ranges::transform(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, + F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -5565,13 +7048,19 @@ \setlength{\emergencystretch}{1em} \item \tcode{last2} be \tcode{first2 + (last1 - first1)} - for the overloads with parameter \tcode{first2} + for the overloads in namespace \tcode{std} + with parameter \tcode{first2} but no parameter \tcode{last2}; \item - $N$ be \tcode{last1 - first1} for unary transforms, or + $M$ be \tcode{last1 - first1} for unary transforms, or $\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ for binary transforms; \item - $E$ be + \tcode{result_last} be \tcode{result + $M$} + for the overloads with no parameter \tcode{result_last} or \tcode{result_r}; +\item + $N$ be $\min(M, \ \tcode{result_last - result})$; +\item + $E(\tcode{i})$ be \begin{itemize} \item \tcode{op(*(first1 + (i - result)))} @@ -5590,6 +7079,9 @@ \pnum \expects +For parallel algorithm overloads +\tcode{op} and \tcode{binary_op} satisfy the requirements +specified in \ref{algorithms.parallel.user}. \tcode{op} and \tcode{binary_op} do not invalidate iterators or subranges, nor modify elements in the ranges \begin{itemize} @@ -5605,7 +7097,7 @@ \effects Assigns through every iterator \tcode{i} in the range \range{result}{result + $N$} -a new corresponding value equal to $E$. +a new corresponding value equal to $E(\tcode{i})$. \pnum \returns @@ -5625,7 +7117,7 @@ \complexity Exactly $N$ applications of \tcode{op} or \tcode{binary_op}, and any projections. -This requirement also applies to the overload with an \tcode{ExecutionPolicy}. +This requirement also applies to the parallel algorithm overloads. \pnum \remarks @@ -5657,32 +7149,61 @@ Predicate pred, const T& new_value); template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, - class T1 = projected_value_t, class T2 = T1> + class T1 = projected_value_t, class T2 = iter_value_t> requires @\libconcept{indirectly_writable}@ && @\libconcept{indirect_binary_predicate}@, const T1*> constexpr I ranges::replace(I first, S last, const T1& old_value, const T2& new_value, Proj proj = {}); template<@\libconcept{input_range}@ R, class Proj = identity, - class T1 = projected_value_t, Proj>, class T2 = T1> + class T1 = projected_value_t, Proj>, class T2 = range_value_t> requires @\libconcept{indirectly_writable}@, const T2&> && @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> constexpr borrowed_iterator_t ranges::replace(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T1 = projected_value_t, class T2 = iter_value_t> + requires @\libconcept{indirectly_writable}@ && + @\libconcept{indirect_binary_predicate}@, const T1*> + I ranges::replace(Ep&& exec, I first, S last, + const T1& old_value, const T2& new_value, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T1 = projected_value_t, Proj>, class T2 = range_value_t> + requires @\libconcept{indirectly_writable}@, const T2&> && + @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> + borrowed_iterator_t + ranges::replace(Ep&& exec, R&& r, const T1& old_value, const T2& new_value, + Proj proj = {}); + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, - class T = projected_value_t, + class T = iter_value_t, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{indirectly_writable}@ constexpr I ranges::replace_if(I first, S last, Pred pred, const T& new_value, Proj proj = {}); -template<@\libconcept{input_range}@ R, class Proj = identity, class T = projected_value_t, Proj>, +template<@\libconcept{input_range}@ R, class Proj = identity, class T = range_value_t, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> requires @\libconcept{indirectly_writable}@, const T&> constexpr borrowed_iterator_t ranges::replace_if(R&& r, Pred pred, const T& new_value, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = iter_value_t, + @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_writable}@ + I ranges::replace_if(Ep&& exec, I first, S last, Pred pred, + const T& new_value, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = range_value_t, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_writable}@, const T&> + borrowed_iterator_t + ranges::replace_if(Ep&& exec, R&& r, Pred pred, const T& new_value, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum -Let $E$ be +Let $E(\tcode{i})$ be \begin{itemize} \item \tcode{bool(*i == old_value)} for \tcode{replace}; \item \tcode{bool(pred(*i))} for \tcode{replace_if}; @@ -5690,7 +7211,6 @@ \item \tcode{bool(invoke(pred, invoke(proj, *i)))} for \tcode{ranges::replace_if}. \end{itemize} - \pnum \mandates \tcode{new_value} is writable\iref{iterator.requirements.general} to \tcode{first}. @@ -5699,7 +7219,7 @@ \effects Substitutes elements referred by the iterator \tcode{i} in the range \range{first}{last} with \tcode{new_value}, -when $E$ is \tcode{true}. +when $E(\tcode{i})$ is \tcode{true}. \pnum \returns @@ -5756,6 +7276,27 @@ ranges::replace_copy(R&& r, O result, const T1& old_value, const T2& new_value, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + class Proj = identity, + class T1 = projected_value_t, class T2 = iter_value_t> + requires @\libconcept{indirectly_copyable}@ && + @\libconcept{indirect_binary_predicate}@, const T1*> && + @\libconcept{indirectly_writable}@ + ranges::replace_copy_result + ranges::replace_copy(Ep&& exec, I first, S last, O result, OutS result_last, + const T1& old_value, const T2& new_value, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class Proj = identity, class T1 = projected_value_t, Proj>, + class T2 = range_value_t> + requires @\libconcept{indirectly_copyable}@, iterator_t> && + @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> && + @\libconcept{indirectly_writable}@, const T2&> + ranges::replace_copy_result, borrowed_iterator_t> + ranges::replace_copy(Ep&& exec, R&& r, OutR&& result_r, const T1& old_value, + const T2& new_value, Proj proj = {}); + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S,class O, class T = iter_value_t, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{indirectly_copyable}@ && @\libconcept{output_iterator}@ @@ -5768,12 +7309,28 @@ constexpr ranges::replace_copy_if_result, O> ranges::replace_copy_if(R&& r, O result, Pred pred, const T& new_value, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class T = iter_value_t, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_copyable}@ && @\libconcept{indirectly_writable}@ + ranges::replace_copy_if_result + ranges::replace_copy_if(Ep&& exec, I first, S last, O result, OutS result_last, + Pred pred, const T& new_value, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class T = range_value_t, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, iterator_t> && + @\libconcept{indirectly_writable}@ + ranges::replace_copy_if_result, borrowed_iterator_t> + ranges::replace_copy_if(Ep&& exec, R&& r, OutR&& result_r, Pred pred, const T& new_value, + Proj proj = {}); \end{itemdecl} \begin{itemdescr} \setlength{\emergencystretch}{1.5em} \pnum -Let $E$ be +Let $E(\tcode{i})$ be \begin{itemize} \item \tcode{bool(*(first + (i - result)) == old_value)} for \tcode{replace_copy}; @@ -5785,6 +7342,16 @@ for \tcode{ranges::replace_\-copy_if}. \end{itemize} +\pnum +Let: +\begin{itemize} +\item + \tcode{result_last} be \tcode{result + (last - first)} + for the overloads with no parameter \tcode{result_last} or \tcode{result_r}; +\item + $N$ be $\min(\tcode{last - first}, \ \tcode{result_last - result})$. +\end{itemize} + \pnum \mandates The results of the expressions \tcode{*first} and \tcode{new_value} @@ -5792,16 +7359,16 @@ \pnum \expects -The ranges \range{first}{last} and \range{result}{result + (last - first)} +The ranges \range{first}{last} and \range{result}{result + $N$} do not overlap. \pnum \effects Assigns through every iterator \tcode{i} -in the range \range{result}{result + (last - first)} +in the range \range{result}{result + $N$} a new corresponding value \begin{itemize} -\item \tcode{new_value} if $E$ is \tcode{true} or +\item \tcode{new_value} if $E(\tcode{i})$ is \tcode{true} or \item \tcode{*(first + (i - result))} otherwise. \end{itemize} @@ -5809,16 +7376,16 @@ \returns \begin{itemize} \item - \tcode{result + (last - first)} + \tcode{result + $N$} for the overloads in namespace \tcode{std}. \item - \tcode{\{last, result + (last - first)\}} + \tcode{\{first + $N$, result + $N$\}} for the overloads in namespace \tcode{ranges}. \end{itemize} \pnum \complexity -Exactly \tcode{last - first} applications +Exactly $N$ applications of the corresponding predicate and any projection. \end{itemdescr} @@ -5850,6 +7417,17 @@ template> requires @\libconcept{output_iterator}@ constexpr O ranges::fill_n(O first, iter_difference_t n, const T& value); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ S, + class T = iter_value_t> + requires @\libconcept{indirectly_writable}@ + O ranges::fill(Ep&& exec, O first, S last, const T& value); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class T = range_value_t> + requires @\libconcept{indirectly_writable}@, const T&> + borrowed_iterator_t fill(Ep&& exec, R&& r, const T& value); +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ O, class T = iter_value_t> + requires @\libconcept{indirectly_writable}@ + O ranges::fill_n(Ep&& exec, O first, iter_difference_t n, const T& value); \end{itemdecl} \begin{itemdescr} @@ -5930,6 +7508,11 @@ \pnum \complexity Exactly $N$ evaluations of \tcode{gen()} and assignments. + +\pnum +\remarks +\tcode{gen} may modify objects via its arguments +for parallel algorithm overloads\iref{algorithms.parallel.user}. \end{itemdescr} \rSec2[alg.remove]{Remove} @@ -5964,6 +7547,21 @@ @\libconcept{indirect_binary_predicate}@, Proj>, const T*> constexpr borrowed_subrange_t ranges::remove(R&& r, const T& value, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{permutable}@ && + @\libconcept{indirect_binary_predicate}@, const T*> + subrange + ranges::remove(Ep&& exec, I first, S last, const T& value, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{permutable}@> && + @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + borrowed_subrange_t + ranges::remove(Ep&& exec, R&& r, const T& value, Proj proj = {}); + template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> constexpr subrange ranges::remove_if(I first, S last, Pred pred, Proj proj = {}); @@ -5972,11 +7570,22 @@ requires @\libconcept{permutable}@> constexpr borrowed_subrange_t ranges::remove_if(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{permutable}@ + subrange + ranges::remove_if(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{permutable}@> + borrowed_subrange_t + ranges::remove_if(Ep&& exec, R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum -Let $E$ be +Let $E(\tcode{i})$ be \begin{itemize} \item \tcode{bool(*i == value)} for \tcode{remove}; \item \tcode{bool(pred(*i))} for \tcode{remove_if}; @@ -5993,7 +7602,7 @@ \pnum \effects Eliminates all the elements referred to by iterator \tcode{i} -in the range \range{first}{last} for which $E$ holds. +in the range \range{first}{last} for which $E(\tcode{i})$ holds. \pnum \returns @@ -6060,6 +7669,23 @@ @\libconcept{indirect_binary_predicate}@, Proj>, const T*> constexpr ranges::remove_copy_result, O> ranges::remove_copy(R&& r, O result, const T& value, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirectly_copyable}@ && + @\libconcept{indirect_binary_predicate}@, const T*> + ranges::remove_copy_result + ranges::remove_copy(Ep&& exec, I first, S last, O result, OutS result_last, + const T& value, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class Proj = identity, class T = projected_value_t, Proj>> + requires @\libconcept{indirectly_copyable}@, iterator_t> && + @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + ranges::remove_copy_result, borrowed_iterator_t> + ranges::remove_copy(Ep&& exec, R&& r, OutR&& result_r, const T& value, Proj proj = {}); + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{indirectly_copyable}@ @@ -6070,11 +7696,25 @@ requires @\libconcept{indirectly_copyable}@, O> constexpr ranges::remove_copy_if_result, O> ranges::remove_copy_if(R&& r, O result, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_copyable}@ + ranges::remove_copy_if_result + ranges::remove_copy_if(Ep&& exec, I first, S last, O result, OutS result_last, + Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, iterator_t> + ranges::remove_copy_if_result, borrowed_iterator_t> + ranges::remove_copy_if(Ep&& exec, R&& r, OutR&& result_r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum -Let $E$ be +Let $E(\tcode{i})$ be \begin{itemize} \item \tcode{bool(*i == value)} for \tcode{remove_copy}; \item \tcode{bool(pred(*i))} for \tcode{remove_copy_if}; @@ -6083,8 +7723,17 @@ \end{itemize} \pnum -Let $N$ be the number of elements in \range{first}{last} -for which $E$ is \tcode{false}. +Let: +\begin{itemize} +\item + $M$ be the number of iterators \tcode{i} in \range{first}{last} + for which $E(\tcode{i})$ is \tcode{false}; +\item + \tcode{result_last} be \tcode{result + $M$} + for the overloads with no parameter \tcode{result_last} or \tcode{result_r}; +\item + $N$ be $\min(M, \ \tcode{result_last - result})$. +\end{itemize} \pnum \mandates @@ -6092,30 +7741,46 @@ \pnum \expects -The ranges \range{first}{last} and \range{result}{result + (last - first)} +The ranges \range{first}{last} and \range{result}{result + $N$} do not overlap. \begin{note} -For the overloads with an \tcode{ExecutionPolicy}, -there might be a performance cost +For the parallel algorithm overloads in namespace \tcode{std}, +there can be a performance cost if \tcode{iterator_traits::value_type} does not meet the \oldconcept{\-Move\-Constructible} (\tref{cpp17.moveconstructible}) requirements. +For the parallel algorithm overloads in namespace \tcode{ranges}, +there can be a performance cost +if \tcode{iter_value_t} does not model \libconcept{move_constructible}. \end{note} \pnum \effects -Copies all the elements referred to by the iterator \tcode{i} -in the range \range{first}{last} for which $E$ is \tcode{false}. +Copies the first $N$ elements referred to by the iterator \tcode{i} +in the range \range{first}{last} for which $E(\tcode{i})$ is \tcode{false} +into the range \range{result}{result + $N$}. \pnum \returns \begin{itemize} -\item \tcode{result + $N$}, for the algorithms in namespace \tcode{std}. -\item \tcode{\{last, result + $N$\}}, for the algorithms in namespace \tcode{ranges}. +\item + \tcode{result + $N$}, + for the algorithms in namespace \tcode{std}. +\item + \tcode{\{last, result + $N$\}}, + for the algorithms in namespace \tcode{ranges}, + if $N$ is equal to $M$. +\item + Otherwise, \tcode{\{j, result_last\}}, + for the algorithms in namespace \tcode{ranges}, + where \tcode{j} is the iterator in \range{first}{last} + for which $E(\tcode{j})$ is \tcode{false} + and there are exactly $N$ iterators \tcode{i} in \range{first}{j} + for which $E(\tcode{i})$ is \tcode{false}. \end{itemize} \pnum \complexity -Exactly \tcode{last - first} applications +At most \tcode{last - first} applications of the corresponding predicate and any projection. \pnum @@ -6149,15 +7814,27 @@ requires @\libconcept{permutable}@> constexpr borrowed_subrange_t ranges::unique(R&& r, C comp = {}, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_equivalence_relation}@> C = ranges::equal_to> + requires @\libconcept{permutable}@ + subrange ranges::unique(Ep&& exec, I first, S last, C comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_equivalence_relation}@, Proj>> C = ranges::equal_to> + requires @\libconcept{permutable}@> + borrowed_subrange_t ranges::unique(Ep&& exec, R&& r, C comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{pred} be \tcode{equal_to\{\}} for the overloads with no parameter \tcode{pred}, and -let $E$ be +let $E(\tcode{i})$ be \begin{itemize} \setlength{\emergencystretch}{1em} +\item + \tcode{false} if \tcode{i} is equal to \tcode{first}; otherwise \item \tcode{bool(pred(*(i - 1), *i))} for the overloads in namespace \tcode{std}; @@ -6175,10 +7852,9 @@ \pnum \effects -For a nonempty range, eliminates all but the first element -from every consecutive group of equivalent elements referred to -by the iterator \tcode{i} in the range \range{first + 1}{last} -for which $E$ is \tcode{true}. +Eliminates all elements referred to +by the iterator \tcode{i} in the range \range{first}{last} +for which $E(\tcode{i})$ is \tcode{true}. \pnum \returns @@ -6235,23 +7911,52 @@ @\libconcept{indirectly_copyable_storable}@, O>) constexpr ranges::unique_copy_result, O> ranges::unique_copy(R&& r, O result, C comp = {}, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Proj = identity, + @\libconcept{indirect_equivalence_relation}@> C = ranges::equal_to> + requires @\libconcept{indirectly_copyable}@ + ranges::unique_copy_result + ranges::unique_copy(Ep&& exec, I first, S last, O result, OutS result_last, + C comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR, + class Proj = identity, + @\libconcept{indirect_equivalence_relation}@, Proj>> C = ranges::equal_to> + requires @\libconcept{indirectly_copyable}@, iterator_t> + ranges::unique_copy_result, borrowed_iterator_t> + ranges::unique_copy(Ep&& exec, R&& r, OutR&& result_r, C comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{pred} be \tcode{equal_to\{\}} for the overloads in namespace \tcode{std} with no parameter \tcode{pred}, and -let $E$ be +let $E(\tcode{i})$ be \begin{itemize} \setlength{\emergencystretch}{1em} \item - \tcode{bool(pred(*i, *(i - 1)))} + \tcode{false} if \tcode{i} is equal to \tcode{first}; otherwise +\item + \tcode{bool(pred(*(i - 1), *i))} for the overloads in namespace \tcode{std}; \item - \tcode{bool(invoke(comp, invoke(proj, *i), invoke(proj, *(i - 1))))} + \tcode{bool(invoke(comp, invoke(proj, *(i - 1)), invoke(proj, *i)))} for the overloads in namespace \tcode{ranges}. \end{itemize} +\pnum +Let: +\begin{itemize} +\item + $M$ be the number of iterators \tcode{i} in the range \range{first}{last} + for which $E(\tcode{i})$ is \tcode{false}; +\item + \tcode{result_last} be \tcode{result + $M$} + for the overloads with no parameter \tcode{result_last} or \tcode{result_r}; +\item + $N$ be $\min(M, \ \tcode{result_last - result})$. +\end{itemize} + \pnum \mandates \tcode{*first} is writable\iref{iterator.requirements.general} to \tcode{result}. @@ -6260,7 +7965,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 + $N$} do not overlap. \item For the overloads in namespace \tcode{std}: @@ -6281,31 +7986,47 @@ Otherwise, \tcode{T} meets both the \oldconcept{CopyConstructible} (\tref{cpp17.copyconstructible}) and \oldconcept{CopyAssignable} requirements. - \begin{note} - For the overloads with an \tcode{ExecutionPolicy}, - there might be a performance cost - if the value type of \tcode{ForwardIterator1} does not meet both the - \oldconcept{CopyConstructible} and \oldconcept{CopyAssignable} requirements. - \end{note} \end{itemize} \end{itemize} +\begin{note} +For the parallel algorithm overloads in namespace \tcode{std}, +there can be a performance cost +if the value type of \tcode{ForwardIterator1} does not meet both the +\oldconcept{CopyConstructible} and \oldconcept{CopyAssignable} requirements. +For the parallel algorithm overloads in namespace \tcode{ranges}, +there can be a performance cost if \tcode{iter_value_t} +does not model \libconcept{copyable}. +\end{note} \pnum \effects -Copies only the first element from every consecutive group of equal elements +Copies only the first $N$ elements referred to by the iterator \tcode{i} in the range \range{first}{last} -for which $E$ holds. +for which $E(\tcode{i})$ is \tcode{false} +into the range \range{result}{result + $N$}. \pnum \returns \begin{itemize} -\item \tcode{result + $N$} for the overloads in namespace \tcode{std}. -\item \tcode{\{last, result + $N$\}} for the overloads in namespace \tcode{ranges}. +\item + \tcode{result + $N$} + for the overloads in namespace \tcode{std}. +\item + \tcode{\{last, result + $N$\}} + for the overloads in namespace \tcode{ranges}, + if $N$ is equal to $M$. +\item + Otherwise, \tcode{\{j, result_last\}} + for the overloads in namespace \tcode{ranges}, + where \tcode{j} is the iterator in \range{first}{last} + for which $E(\tcode{j})$ is \tcode{false} + and there are exactly $N$ iterators \tcode{i} in \range{first}{j} + for which $E(\tcode{i})$ is \tcode{false}. \end{itemize} \pnum \complexity -Exactly \tcode{last - first - 1} applications +At most \tcode{last - first - 1} applications of the corresponding predicate and no more than twice as many applications of any projection. \end{itemdescr} @@ -6326,6 +8047,13 @@ template<@\libconcept{bidirectional_range}@ R> requires @\libconcept{permutable}@> constexpr borrowed_iterator_t ranges::reverse(R&& r); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S> + requires @\libconcept{permutable}@ + I ranges::reverse(Ep&& exec, I first, S last); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R> + requires @\libconcept{permutable}@> + borrowed_iterator_t ranges::reverse(Ep&& exec, R&& r); \end{itemdecl} \begin{itemdescr} @@ -6403,6 +8131,46 @@ Exactly $N$ assignments. \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS> + requires @\libconcept{indirectly_copyable}@ + ranges::reverse_copy_truncated_result + ranges::reverse_copy(Ep&& exec, I first, S last, O result, + OutS result_last); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR> + requires @\libconcept{indirectly_copyable}@, iterator_t> + ranges::reverse_copy_truncated_result, borrowed_iterator_t> + ranges::reverse_copy(Ep&& exec, R&& r, OutR&& result_r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $N$ be $\min(\tcode{last - first}, \ \tcode{result_last - result})$, +and let \exposid{NEW_FIRST} be \tcode{first + (last - first) - $N$}. + +\pnum +\expects +The ranges \range{first}{last} and \range{result}{result + $N$} +do not overlap. + +\pnum +\effects +Copies the range \range{\exposid{NEW_FIRST}}{last} +to the range \range{result}{result + $N$} +such that for every non-negative integer $i < N$ +the following assignment takes place: +\tcode{*(result + $N$ - 1 - $i$) = *(\exposid{NEW_FIRST} + $i$)}. + +\pnum +\returns +\tcode{\{last, \exposid{NEW_FIRST}, result + $N$\}}. + +\pnum +\complexity +Exactly $N$ assignments. +\end{itemdescr} + \rSec2[alg.rotate]{Rotate} \indexlibraryglobal{rotate}% @@ -6417,6 +8185,9 @@ template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S> constexpr subrange ranges::rotate(I first, I middle, S last); +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S> + requires @\libconcept{permutable}@ + subrange ranges::rotate(Ep&& exec, I first, I middle, S last); \end{itemdecl} \begin{itemdescr} @@ -6468,6 +8239,22 @@ \tcode{return ranges::rotate(ranges::begin(r), middle, ranges::end(r));} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R> + requires @\libconcept{permutable}@> + borrowed_subrange_t ranges::rotate(Ep&& exec, R&& r, iterator_t middle); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ranges::rotate(std::forward(exec), ranges::begin(r), middle, + ranges::begin(r) + ranges::distance(r)); +\end{codeblock} +\end{itemdescr} + \indexlibraryglobal{rotate_copy}% \begin{itemdecl} template @@ -6517,6 +8304,50 @@ Exactly $N$ assignments. \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS> + requires @\libconcept{indirectly_copyable}@ + ranges::rotate_copy_truncated_result + ranges::rotate_copy(Ep&& exec, I first, I middle, S last, O result, OutS result_last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $M$ be \tcode{last - first} +and $N$ be $\min(M, \ \tcode{result_last - result})$. + +\pnum +\expects +\range{first}{middle} and \range{middle}{last} +are valid ranges. +The ranges \range{first}{last} and \range{result}{result + $N$} +do not overlap. + +\pnum +\effects +Copies the range \range{first}{last} +to the range \range{result}{result + $N$} +such that for each non-negative integer $i < N$ +the following assignment takes place: +\tcode{*(result + $i$) = *(first + ($i$ + (middle - first)) \% $M$)}. + +\pnum +\returns +\begin{itemize} +\item + \tcode{\{middle + $N$, first, result + $N$\}} + if $N$ is less than \tcode{last - middle}. +\item + Otherwise, + \tcode{\{last, first + ($N$ + (middle - first)) \% $M$, result + $N$\}}. +\end{itemize} + +\pnum +\complexity +Exactly $N$ assignments. +\end{itemdescr} + \begin{itemdecl} template<@\libconcept{forward_range}@ R, @\libconcept{weakly_incrementable}@ O> requires @\libconcept{indirectly_copyable}@, O> @@ -6533,6 +8364,25 @@ \end{codeblock} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, @\exposconcept{sized-random-access-range}@ OutR> + requires @\libconcept{indirectly_copyable}@, iterator_t> + ranges::rotate_copy_truncated_result, borrowed_iterator_t> + ranges::rotate_copy(Ep&& exec, R&& r, iterator_t middle, OutR&& result_r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ranges::rotate_copy(std::forward(exec), ranges::begin(r), middle, + ranges::begin(r) + ranges::distance(r), + ranges::begin(result_r), + ranges::begin(result_r) + ranges::distance(result_r)); +\end{codeblock} +\end{itemdescr} + \rSec2[alg.random.sample]{Sample} \indexlibraryglobal{sample}% @@ -6687,7 +8537,16 @@ constexpr subrange ranges::shift_left(I first, S last, iter_difference_t n); template<@\libconcept{forward_range}@ R> requires @\libconcept{permutable}@> - constexpr borrowed_subrange_t ranges::shift_left(R&& r, range_difference_t n) + constexpr borrowed_subrange_t ranges::shift_left(R&& r, range_difference_t n); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S> + requires @\libconcept{permutable}@ + subrange + ranges::shift_left(Ep&& exec, I first, S last, iter_difference_t n); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R> + requires @\libconcept{permutable}@> + borrowed_subrange_t + ranges::shift_left(Ep&& exec, R&& r, range_difference_t n); \end{itemdecl} \begin{itemdescr} @@ -6704,7 +8563,7 @@ from position \tcode{first + n + i} into position \tcode{first + i} for each non-negative integer \tcode{i < (last - first) - n}. -For the overloads without an \tcode{ExecutionPolicy} template parameter, +For the non-parallel algorithm overloads, does so in order starting from \tcode{i = 0} and proceeding to \tcode{i = (last - first) - n - 1}. @@ -6713,6 +8572,7 @@ Let \exposid{NEW_LAST} be \tcode{first + (last - first - n)} if \tcode{n < last - first}, otherwise \tcode{first}. +Returns: \begin{itemize} \item \exposid{NEW_LAST} for the overloads in namespace \tcode{std}. @@ -6742,6 +8602,15 @@ template<@\libconcept{forward_range}@ R> requires @\libconcept{permutable}@> constexpr borrowed_subrange_t ranges::shift_right(R&& r, range_difference_t n); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S> + requires @\libconcept{permutable}@ + subrange + ranges::shift_right(Ep&& exec, I first, S last, iter_difference_t n); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R> + requires @\libconcept{permutable}@> + borrowed_subrange_t + ranges::shift_right(Ep&& exec, R&& r, range_difference_t n); \end{itemdecl} \begin{itemdescr} @@ -6764,11 +8633,10 @@ from \tcode{i = (last - first) - n - 1} and proceeding to \tcode{i = 0} if \begin{itemize} \item -for the overload in namespace \tcode{std} -without an \tcode{ExecutionPolicy} template parameter, -\tcode{Forward\-Iterator} meets the \oldconcept{BidirectionalIterator} requirements, +for the non-parallel algorithm overload in namespace \tcode{std}, +\tcode{Forward\-Iterator} meets the \oldconcept{\-Bi\-directional\-Iterator} requirements, \item -for the overloads in namespace \tcode{ranges}, +for the non-parallel algorithm overloads in namespace \tcode{ranges}, \tcode{I} models \libconcept{bidirectional_iterator}. \end{itemize} @@ -6776,6 +8644,7 @@ \returns Let \exposid{NEW_FIRST} be \tcode{first + n} if \tcode{n < last - first}, otherwise \tcode{last}. +Returns: \begin{itemize} \item \exposid{NEW_FIRST} for the overloads in namespace \tcode{std}. @@ -6911,6 +8780,15 @@ requires @\libconcept{sortable}@, Comp, Proj> constexpr borrowed_iterator_t ranges::sort(R&& r, Comp comp = {}, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@ + I ranges::sort(Ep&& exec, I first, S last, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + borrowed_iterator_t ranges::sort(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -6969,6 +8847,16 @@ requires @\libconcept{sortable}@, Comp, Proj> constexpr borrowed_iterator_t ranges::stable_sort(R&& r, Comp comp = {}, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@ + I ranges::stable_sort(Ep&& exec, I first, S last, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + borrowed_iterator_t + ranges::stable_sort(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7038,6 +8926,10 @@ requires @\libconcept{sortable}@ constexpr I ranges::partial_sort(I first, I middle, S last, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@ + I ranges::partial_sort(Ep&& exec, I first, I middle, S last, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7092,6 +8984,26 @@ \end{codeblock} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + borrowed_iterator_t + ranges::partial_sort(Ep&& exec, R&& r, iterator_t middle, Comp comp = {}, + Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ranges::partial_sort(std::forward(exec), ranges::begin(r), middle, + ranges::begin(r) + ranges::distance(r), + comp, proj); +\end{codeblock} +\end{itemdescr} + \rSec3[partial.sort.copy]{\tcode{partial_sort_copy}} \indexlibraryglobal{partial_sort_copy}% @@ -7140,6 +9052,25 @@ constexpr ranges::partial_sort_copy_result, borrowed_iterator_t> ranges::partial_sort_copy(R1&& r, R2&& result_r, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_copyable}@ && @\libconcept{sortable}@ && + @\libconcept{indirect_strict_weak_order}@, projected> + ranges::partial_sort_copy_result + ranges::partial_sort_copy(Ep&& exec, I1 first, S1 last, I2 result_first, S2 result_last, + Comp comp = {}, Proj1 proj1 = {}, + Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_copyable}@, iterator_t> && + @\libconcept{sortable}@, Comp, Proj2> && + @\libconcept{indirect_strict_weak_order}@, Proj1>, + projected, Proj2>> + ranges::partial_sort_copy_result, borrowed_iterator_t> + ranges::partial_sort_copy(Ep&& exec, R1&& r, R2&& result_r, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -7280,6 +9211,25 @@ \tcode{return ranges::is_sorted_until(first, last, comp, proj) == last;} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + bool ranges::is_sorted(Ep&& exec, I first, S last, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + bool ranges::is_sorted(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ranges::is_sorted_until(std::forward(exec), first, last, comp, proj) == last; +\end{codeblock} +\end{itemdescr} + \indexlibraryglobal{is_sorted_until}% \begin{itemdecl} template @@ -7307,6 +9257,16 @@ @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr borrowed_iterator_t ranges::is_sorted_until(R&& r, Comp comp = {}, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + I ranges::is_sorted_until(Ep&& exec, I first, S last, Comp comp = {}, + Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + borrowed_iterator_t + ranges::is_sorted_until(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7351,6 +9311,10 @@ requires @\libconcept{sortable}@ constexpr I ranges::nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@ + I ranges::nth_element(Ep&& exec, I first, I nth, S last, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7386,8 +9350,8 @@ \pnum \complexity -For the overloads with no \tcode{ExecutionPolicy}, linear on average. -For the overloads with an \tcode{ExecutionPolicy}, \bigoh{N} applications of +For the non-parallel algorithm overloads, linear on average. +For the parallel algorithm overloads, \bigoh{N} applications of the predicate, and \bigoh{N \log N} swaps, where $N = \tcode{last - first}$. \end{itemdescr} @@ -7407,6 +9371,25 @@ \end{codeblock} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + borrowed_iterator_t + ranges::nth_element(Ep&& exec, R&& r, iterator_t nth, Comp comp = {}, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ranges::nth_element(std::forward(exec), ranges::begin(r), nth, + ranges::begin(r) + ranges::distance(r), + comp, proj); +\end{codeblock} +\end{itemdescr} + \rSec2[alg.binary.search]{Binary search} \rSec3[alg.binary.search.general]{General} @@ -7565,7 +9548,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}. @@ -7632,7 +9615,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}. @@ -7665,6 +9648,13 @@ template<@\libconcept{input_range}@ R, class Proj = identity, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> constexpr bool ranges::is_partitioned(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + bool ranges::is_partitioned(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + bool ranges::is_partitioned(Ep&& exec, R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7691,8 +9681,7 @@ partition(ForwardIterator first, ForwardIterator last, Predicate pred); template ForwardIterator - partition(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, Predicate pred); + partition(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> @@ -7703,6 +9692,15 @@ requires @\libconcept{permutable}@> constexpr borrowed_subrange_t ranges::partition(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{permutable}@ + subrange ranges::partition(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{permutable}@> + borrowed_subrange_t ranges::partition(Ep&& exec, R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7739,7 +9737,7 @@ Let $N = \tcode{last - first}$: \begin{itemize} \item - For the overload with no \tcode{ExecutionPolicy}, + For the non-parallel algorithm overloads, exactly $N$ applications of the predicate and projection. At most $N / 2$ swaps if the type of \tcode{first} meets the \oldconcept{BidirectionalIterator} requirements @@ -7748,7 +9746,7 @@ for the overloads in namespace \tcode{ranges}, and at most $N$ swaps otherwise. \item - For the overload with an \tcode{ExecutionPolicy}, + For the parallel algorithm overloads, \bigoh{N \log N} swaps and \bigoh{N} applications of the predicate. \end{itemize} @@ -7773,6 +9771,17 @@ @\libconcept{indirect_unary_predicate}@, Proj>> Pred> requires @\libconcept{permutable}@> constexpr borrowed_subrange_t ranges::stable_partition(R&& r, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{permutable}@ + subrange + ranges::stable_partition(Ep&& exec, I first, S last, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{permutable}@> + borrowed_subrange_t + ranges::stable_partition(Ep&& exec, R&& r, Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7814,11 +9823,12 @@ Let $N$ = \tcode{last - first}: \begin{itemize} \item - For the overloads with no \tcode{ExecutionPolicy}, at most $N \log_2 N$ swaps, + For the non-parallel algorithm overloads, + at most $N \log_2 N$ swaps, but only \bigoh{N} swaps if there is enough extra memory. Exactly $N$ applications of the predicate and projection. \item - For the overload with an \tcode{ExecutionPolicy}, + For the parallel algorithm overloads, \bigoh{N \log N} swaps and \bigoh{N} applications of the predicate. \end{itemize} \end{itemdescr} @@ -7849,6 +9859,25 @@ @\libconcept{indirectly_copyable}@, O2> constexpr ranges::partition_copy_result, O1, O2> ranges::partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + @\libconcept{random_access_iterator}@ O1, @\libconcept{sized_sentinel_for}@ OutS1, + @\libconcept{random_access_iterator}@ O2, @\libconcept{sized_sentinel_for}@ OutS2, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_copyable}@ && @\libconcept{indirectly_copyable}@ + ranges::partition_copy_result + ranges::partition_copy(Ep&& exec, I first, S last, O1 out_true, OutS1 last_true, + O2 out_false, OutS2 last_false, Pred pred, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, + @\exposconcept{sized-random-access-range}@ OutR1, @\exposconcept{sized-random-access-range}@ OutR2, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, iterator_t> && + @\libconcept{indirectly_copyable}@, iterator_t> + ranges::partition_copy_result, borrowed_iterator_t, + borrowed_iterator_t> + ranges::partition_copy(Ep&& exec, R&& r, OutR1&& out_true_r, OutR2&& out_false_r, + Pred pred, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -7857,6 +9886,45 @@ for the overloads with no parameter named \tcode{proj} and let $E(x)$ be \tcode{bool(invoke(\brk{}pred, invoke(proj, $x$)))}. +\pnum +For the overloads with no parameters +\tcode{last_true}, \tcode{last_false}, \tcode{out_true_r}, or \tcode{out_false_r}, +let +\begin{itemize} +\item + $M$ be the number of iterators \tcode{i} in \range{first}{last} + for which $E(\tcode{*i})$ is \tcode{true}, + and $K$ be \tcode{last - first - $M$}; +\item + \tcode{last_true} be \tcode{out_true + $M$}, and + \tcode{last_false} be \tcode{out_false + $K$}. +\end{itemize} + +\pnum +For the overloads with parameters +\tcode{last_true}, \tcode{last_false}, \tcode{out_true_r}, or \tcode{out_false_r}, +let $M$ be \tcode{last_true - out_true} +and $K$ be \tcode{last_false - out_false}. + +\pnum +Let: +\begin{itemize} +\item + \tcode{i1} be the iterator in \range{first}{last} + for which $E(\tcode{*i1})$ is \tcode{true} + and there are exactly $M$ iterators \tcode{j} in \range{first}{\tcode{i1}} + for which $E(\tcode{*j})$ is \tcode{true}, + or \tcode{last} if no such iterator exists; +\item + \tcode{i2} be the iterator in \range{first}{last} + for which $E(\tcode{*i2})$ is \tcode{false} + and there are exactly $K$ iterators \tcode{j} in \range{first}{\tcode{i2}} + for which $E(\tcode{*j})$ is \tcode{false}, + or \tcode{last} if no such iterator exists; +\item + $N$ be $\min(\tcode{i1 - first}, \ \tcode{i2 - first})$. +\end{itemize} + \pnum \mandates For the overloads in namespace \tcode{std}, @@ -7869,31 +9937,36 @@ The input range and output ranges do not overlap. \begin{note} -For the overload with an \tcode{ExecutionPolicy}, -there might be a performance cost if \tcode{first}'s value type +For the parallel algorithm overload in namespace \tcode{std}, +there can be a performance cost if \tcode{first}'s value type does not meet the \oldconcept{CopyConstructible} requirements. +For the parallel algorithm overloads in namespace \tcode{ranges}, +there can be a performance cost if \tcode{first}'s value type +does not model \libconcept{copy_constructible}. \end{note} \pnum \effects -For each iterator \tcode{i} in \range{first}{last}, -copies \tcode{*i} to the output range beginning with \tcode{out_true} -if \tcode{$E(\tcode{*i})$} is \tcode{true}, or -to the output range beginning with \tcode{out_false} otherwise. +For each iterator \tcode{i} in \range{first}{first + $N$}, +copies \tcode{*i} to the output range \range{out_true}{last_true} +if $E(\tcode{*i})$ is \tcode{true}, or +to the output range \range{out_false}{last_false} otherwise. \pnum \returns -Let \tcode{o1} be the end of the output range beginning at \tcode{out_true}, -and \tcode{o2} the end of the output range beginning at \tcode{out_false}. -Returns +Let $Q$ be the number of elements copied +into the output range \range{out_true}{last_true}, +and $V$ be the number of elements copied +into the output range \range{out_false}{last_false}. +Returns: \begin{itemize} -\item \tcode{\{o1, o2\}} for the overloads in namespace \tcode{std}. -\item \tcode{\{last, o1, o2\}} for the overloads in namespace \tcode{ranges}. +\item \tcode{\{out_true + $Q$, out_false + $V$\}} for the overloads in namespace \tcode{std}. +\item \tcode{\{first + $N$, out_true + $Q$, out_false + $V$\}} for the overloads in namespace \tcode{ranges}. \end{itemize} \pnum \complexity -Exactly \tcode{last - first} applications of \tcode{pred} and \tcode{proj}. +At most \tcode{last - first} applications of \tcode{pred} and \tcode{proj}. \end{itemdescr} \indexlibraryglobal{partition_point}% @@ -7980,15 +10053,56 @@ constexpr ranges::merge_result, borrowed_iterator_t, O> ranges::merge(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + ranges::merge_result + ranges::merge(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, O result, OutS result_last, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, iterator_t, Comp, Proj1, Proj2> + ranges::merge_result, borrowed_iterator_t, borrowed_iterator_t> + ranges::merge(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} \pnum -Let $N$ be \tcode{(last1 - first1) + (last2 - first2)}. -Let \tcode{comp} be \tcode{less\{\}}, -\tcode{proj1} be \tcode{identity\{\}}, and -\tcode{proj2} be \tcode{identity\{\}}, -for the overloads with no parameters by those names. +Let: +\begin{itemize} +\item + $N$ be: + \begin{itemize} + \item + \tcode{(last1 - first1) + (last2 - first2)} + for the overloads with no parameter \tcode{result_last} or \tcode{result_r}; + \item + $\min(\tcode{(last1 - first1) + (last2 - first2)}, \ \tcode{result_last - result})$ + for the overloads with parameters \tcode{result_last} or \tcode{result_r}; + \end{itemize} +\item + \tcode{comp} be \tcode{less\{\}}, + \tcode{proj1} be \tcode{identity\{\}}, and + \tcode{proj2} be \tcode{identity\{\}}, + for the overloads with no parameters by those names; +\item + $E$ be \tcode{bool(invoke(comp, invoke(proj2, e2), invoke(proj1, e1)))}; +\item + $K$ be the smallest integer in \range{0}{last1 - first1} + such that for the element \tcode{e1} in the position \tcode{first1 + $K$} + there are at least $N - K$ elements \tcode{e2} + in \range{first2}{last2} for which $E$ holds, + and be equal to \tcode{last1 - first1} + if no such integer exists. + \begin{note} + \tcode{first1 + $K$} points to the position past the last element to be copied. + \end{note} +\end{itemize} \pnum \expects @@ -7999,25 +10113,24 @@ \pnum \effects -Copies all the elements of the two ranges \range{first1}{last1} and -\range{first2}{last2} into the range \range{result}{result_last}, -where \tcode{result_last} is \tcode{result + $N$}. +Copies the first $K$ elements of the range \range{first1}{last1} +and the first $N - K$ elements of the range \range{first2}{last2} +into the range \range{result}{result + $N$}. If an element \tcode{a} precedes \tcode{b} in an input range, \tcode{a} is copied into the output range before \tcode{b}. If \tcode{e1} is an element of \range{first1}{last1} and \tcode{e2} of \range{first2}{last2}, -\tcode{e2} is copied into the output range before \tcode{e1} if and only if -\tcode{bool(invoke(comp, invoke(proj2, e2), invoke(proj1, e1)))} -is \tcode{true}. +\tcode{e2} is copied into the output range before \tcode{e1} +if and only if $E$ is \tcode{true}. \pnum \returns \begin{itemize} \item - \tcode{result_last} + \tcode{result + $N$} for the overloads in namespace \tcode{std}. \item - \tcode{\{last1, last2, result_last\}} + \tcode{\{first1 + $K$, first2 + $N$ - $K$, result + $N$\}} for the overloads in namespace \tcode{ranges}. \end{itemize} @@ -8025,10 +10138,11 @@ \complexity \begin{itemize} \item - For the overloads with no \tcode{ExecutionPolicy}, + For the non-parallel algorithm overloads, at most $N - 1$ comparisons and applications of each projection. \item - For the overloads with an \tcode{ExecutionPolicy}, \bigoh{N} comparisons. + For the parallel algorithm overloads, + \bigoh{N} comparisons and applications of each projection. \end{itemize} \pnum @@ -8062,6 +10176,10 @@ class Proj = identity> requires @\libconcept{sortable}@ constexpr I ranges::inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@ + I ranges::inplace_merge(Ep&& exec, I first, I middle, S last, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -8097,8 +10215,8 @@ Let $N = \tcode{last - first}$: \begin{itemize} \item - For the overloads with no \tcode{ExecutionPolicy}, and - if enough additional memory is available, exactly $N - 1$ comparisons. + For the non-parallel algorithm overloads, and + if enough additional memory is available, at most $N - 1$ comparisons. \item Otherwise, \bigoh{N \log N} comparisons. \end{itemize} @@ -8125,6 +10243,26 @@ \end{codeblock} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + borrowed_iterator_t + ranges::inplace_merge(Ep&& exec, R&& r, iterator_t middle, Comp comp = {}, + Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ranges::inplace_merge(std::forward(exec), ranges::begin(r), middle, + ranges::begin(r) + ranges::distance(r), + comp, proj); +\end{codeblock} +\end{itemdescr} + \rSec2[alg.set.operations]{Set operations on sorted structures} \rSec3[alg.set.operations.general]{General} @@ -8172,6 +10310,20 @@ projected, Proj2>> Comp = ranges::less> constexpr bool ranges::includes(R1&& r1, R2&& r2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, projected> Comp = + ranges::less> + bool ranges::includes(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, Proj1>, + projected, Proj2>> Comp = ranges::less> + bool ranges::includes(Ep&& exec, R1&& r1, R2&& r2, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -8245,13 +10397,42 @@ constexpr ranges::set_union_result, borrowed_iterator_t, O> ranges::set_union(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + ranges::set_union_result + ranges::set_union(Ep&& exec, I1 first1, S1 last1, + I2 first2, S2 last2, O result, OutS result_last, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, iterator_t, Comp, Proj1, Proj2> + ranges::set_union_result, borrowed_iterator_t, + borrowed_iterator_t> + ranges::set_union(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} \pnum -Let \tcode{comp} be \tcode{less\{\}}, -and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} -for the overloads with no parameters by those names. +Let: +\begin{itemize} +\item + \tcode{comp} be \tcode{less\{\}}, + and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} + for the overloads with no parameters by those names; +\item + $M$ be the number of elements in the sorted union (see below); +\item + \tcode{result_last} be \tcode{result + $M$} + for the overloads with no parameter \tcode{result_last} or \tcode{result_r}; +\item + $N$ be $\min(M, \ \tcode{result_last - result})$. +\end{itemize} \pnum \expects @@ -8263,18 +10444,35 @@ \effects Constructs a sorted union of the elements from the two ranges; that is, the set of elements that are present in one or both of the ranges. +If \range{first1}{last1} contains $m$ elements +that are equivalent to each other and +\range{first2}{last2} contains $n$ elements that are equivalent to them, +then all $m$ elements from the first range +are included in the union, in order, and +then the final $\max(n - m, 0)$ elements from the second range +are included in the union, in order. +If, of those elements, $k$ elements from the first range +are copied to the output range, +then the first $\min(k, n)$ elements from the second range +are considered \term{skipped}. +Copies the first $N$ elements of the sorted union +to the range \range{result}{result + $N$}. \pnum \returns -Let \tcode{result_last} be the end of the constructed range. -Returns \begin{itemize} \item \tcode{result_last} for the overloads in namespace \tcode{std}. \item - \tcode{\{last1, last2, result_last\}} - for the overloads in namespace \tcode{ranges}. + \tcode{\{last1, last2, result + $N$\}} + for the overloads in namespace \tcode{ranges}, + if $N$ is equal to $M$. +\item + Otherwise, \tcode{\{first1 + $A$, first2 + $B$, result_last\}} + for the overloads in namespace \tcode{ranges}, + where $A$ and $B$ are the numbers of copied or skipped elements + in \range{first1}{last1} and \range{first2}{last2}, respectively. \end{itemize} \pnum @@ -8285,14 +10483,6 @@ \pnum \remarks Stable\iref{algorithm.stable}. -If \range{first1}{last1} contains $m$ elements -that are equivalent to each other and -\range{first2}{last2} contains $n$ elements -that are equivalent to them, -then all $m$ elements from the first range -are copied to the output range, in order, and -then the final $\max(n - m, 0)$ elements from the second range -are copied to the output range, in order. \end{itemdescr} \rSec3[set.intersection]{\tcode{set_intersection}} @@ -8340,13 +10530,42 @@ constexpr ranges::set_intersection_result, borrowed_iterator_t, O> ranges::set_intersection(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + ranges::set_intersection_result + ranges::set_intersection(Ep&& exec, I1 first1, S1 last1, + I2 first2, S2 last2, O result, OutS result_last, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, iterator_t, Comp, Proj1, Proj2> + ranges::set_intersection_result, borrowed_iterator_t, + borrowed_iterator_t> + ranges::set_intersection(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} \pnum -Let \tcode{comp} be \tcode{less\{\}}, -and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} -for the overloads with no parameters by those names. +Let: +\begin{itemize} +\item + \tcode{comp} be \tcode{less\{\}}, + and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} + for the overloads with no parameters by those names; +\item + $M$ be the number of elements in the sorted intersection (see below); +\item + \tcode{result_last} be \tcode{result + $M$} + for the overloads with no parameter \tcode{result_last} or \tcode{result_r}; +\item + $N$ be $\min(M, \ \tcode{result_last - result})$. +\end{itemize} \pnum \expects @@ -8358,18 +10577,36 @@ \effects Constructs a sorted intersection of the elements from the two ranges; that is, the set of elements that are present in both of the ranges. +If \range{first1}{last1} contains $m$ elements +that are equivalent to each other and +\range{first2}{last2} contains $n$ elements +that are equivalent to them, +the first $\min(m, n)$ elements from the first range +are included in the sorted intersection. +If, of those elements, $k$ elements from the first range +are copied to the output range, +then the first $k$ elements from the second range +are considered \defn{skipped}. +A non-copied element is also considered skipped +if it compares less than the $\min(M, N + 1)^\text{th}$ element +of the sorted intersection. +Copies the first $N$ elements of the sorted intersection +to the range \range{result}{result + $N$}. \pnum \returns -Let \tcode{result_last} be the end of the constructed range. -Returns \begin{itemize} \item \tcode{result_last} for the overloads in namespace \tcode{std}. \item - \tcode{\{last1, last2, result_last\}} - for the overloads in namespace \tcode{ranges}. + \tcode{\{last1, last2, result + $N$\}} + for the non-parallel algorithm overloads in namespace \tcode{ranges}. +\item + Otherwise, \tcode{\{first1 + $A$, first2 + $B$, result + $N$\}} + for the parallel algorithm overloads in namespace \tcode{ranges}, + where $A$ and $B$ are the numbers of copied or skipped elements + in \range{first1}{last1} and \range{first2}{last2}, respectively. \end{itemize} \pnum @@ -8380,12 +10617,6 @@ \pnum \remarks Stable\iref{algorithm.stable}. -If \range{first1}{last1} contains $m$ elements -that are equivalent to each other and -\range{first2}{last2} contains $n$ elements -that are equivalent to them, -the first $\min(m, n)$ elements -are copied from the first range to the output range, in order. \end{itemdescr} \rSec3[set.difference]{\tcode{set_difference}} @@ -8433,13 +10664,42 @@ constexpr ranges::set_difference_result, O> ranges::set_difference(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + ranges::set_difference_truncated_result + ranges::set_difference(Ep&& exec, I1 first1, S1 last1, + I2 first2, S2 last2, O result, OutS result_last, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, iterator_t, Comp, Proj1, Proj2> + ranges::set_difference_truncated_result, borrowed_iterator_t, + borrowed_iterator_t> + ranges::set_difference(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} \pnum -Let \tcode{comp} be \tcode{less\{\}}, -and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} -for the overloads with no parameters by those names. +Let: +\begin{itemize} +\item + \tcode{comp} be \tcode{less\{\}}, + and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} + for the overloads with no parameters by those names; +\item + $M$ be the number of elements in the sorted difference (see below); +\item + \tcode{result_last} be \tcode{result + $M$} + for the overloads with no parameter \tcode{result_last} or \tcode{result_r}; +\item + $N$ be $\min(M, \ \tcode{result_last - result})$. +\end{itemize} \pnum \expects @@ -8449,22 +10709,45 @@ \pnum \effects -Copies the elements of the range \range{first1}{last1} -which are not present in the range \range{first2}{last2} -to the range beginning at \tcode{result}. -The elements in the constructed range are sorted. +Constructs a sorted difference between the elements from the two ranges; +that is, the set of elements that are present +in the range \range{first1}{last1} but not \range{first2}{last2}. +If \range{first1}{last1} contains $m$ elements +that are equivalent to each other and +\range{first2}{last2} contains $n$ elements +that are equivalent to them, +the last $\max(m - n, 0)$ elements from \range{first1}{last1} +are included in the sorted difference, in order. +Of those equivalent elements, +the first $\min(m, n)$ elements in both ranges +are considered \defn{skipped}. +An element from the second range is also considered skipped +if it compares less than the $\min(N + 1, M)^\text{th}$ element +of the sorted difference. +Copies the first $N$ elements of the sorted difference +to the range \range{result}{result + $N$}. \pnum \returns -Let \tcode{result_last} be the end of the constructed range. -Returns \begin{itemize} \item \tcode{result_last} for the overloads in namespace \tcode{std}. \item - \tcode{\{last1, result_last\}} - for the overloads in namespace \tcode{ranges}. + \tcode{\{last1, result + $N$\}} + for the non-parallel overloads in namespace \tcode{ranges}. +\item + For the parallel algorithm overloads in namespace \tcode{ranges}: + \begin{itemize} + \item + \tcode{\{last1, first2 + $B$, result + $N$\}}, + if $N$ is equal to $M$, + where $B$ is the number of skipped elements in \range{first2}{last2}. + \item + Otherwise, \tcode{\{first1 + $A$, first2 + $B$, result_last\}}, + where $A$ and $B$ are the numbers of copied or skipped elements + in \range{first1}{last1} and \range{first2}{last2}, respectively. + \end{itemize} \end{itemize} \pnum @@ -8474,12 +10757,7 @@ \pnum \remarks -If \range{first1}{last1} contains $m$ elements -that are equivalent to each other and -\range{first2}{last2} contains $n$ elements -that are equivalent to them, -the last $\max(m - n, 0)$ elements from \range{first1}{last1} -are copied to the output range, in order. +Stable\iref{algorithm.stable}. \end{itemdescr} \rSec3[set.symmetric.difference]{\tcode{set_symmetric_difference}} @@ -8529,13 +10807,42 @@ borrowed_iterator_t, O> ranges::set_symmetric_difference(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + @\libconcept{random_access_iterator}@ O, @\libconcept{sized_sentinel_for}@ OutS, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + ranges::set_symmetric_difference_result + ranges::set_symmetric_difference(Ep&& exec, I1 first1, S1 last1, + I2 first2, S2 last2, O result, OutS result_last, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + @\exposconcept{sized-random-access-range}@ OutR, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, iterator_t, Comp, Proj1, Proj2> + ranges::set_symmetric_difference_result, borrowed_iterator_t, + borrowed_iterator_t> + ranges::set_symmetric_difference(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} \pnum -Let \tcode{comp} be \tcode{less\{\}}, -and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} -for the overloads with no parameters by those names. +Let: +\begin{itemize} +\item + \tcode{comp} be \tcode{less\{\}}, + and \tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} + for the overloads with no parameters by those names; +\item + $M$ be the number of elements in the sorted symmetric difference (see below); +\item + \tcode{result_last} be \tcode{result + $M$} + for the overloads with no parameter \tcode{result_last} or \tcode{result_r}; +\item + $N$ be $\min(M, \ \tcode{result_last - result})$. +\end{itemize} \pnum \expects @@ -8545,24 +10852,40 @@ \pnum \effects -Copies the elements of the range \range{first1}{last1} -that are not present in the range \range{first2}{last2}, -and the elements of the range \range{first2}{last2} -that are not present in the range \range{first1}{last1} -to the range beginning at \tcode{result}. -The elements in the constructed range are sorted. +Constructs a sorted symmetric difference of the elements from the two ranges; +that is, the set of elements that are present +in exactly one of \range{first1}{last1} and \range{first2}{last2}. +If \range{first1}{last1} contains $m$ elements +that are equivalent to each other and +\range{first2}{last2} contains $n$ elements +that are equivalent to them, +then $|m - n|$ of those elements are included in the symmetric difference: +the last $m - n$ of these elements from \range{first1}{last1}, +in order, if $m > n$, and +the last $n - m$ of these elements from \range{first2}{last2}, +in order, if $m < n$. +If $N < M$, a non-copied element is considered \term{skipped} +if it compares less than or equivalent to the $(N + 1)^\text{th}$ element +of the sorted symmetric difference, +unless it is from the same range as that element and does not precede it. +Copies the first $N$ elements of the sorted symmetric difference +to the range \range{result}{result + $N$}. \pnum \returns -Let \tcode{result_last} be the end of the constructed range. -Returns \begin{itemize} \item \tcode{result_last} for the overloads in namespace \tcode{std}. \item - \tcode{\{last1, last2, result_last\}} - for the overloads in namespace \tcode{ranges}. + \tcode{\{last1, last2, result + $N$\}} + for the overloads in namespace \tcode{ranges}, + if $N$ is equal to $M + K$. +\item + Otherwise, \tcode{\{first1 + $A$, first2 + $B$, result_last\}} + for the overloads in namespace \tcode{ranges}, + where $A$ and $B$ are the numbers of copied or skipped elements + in \range{first1}{last1} and \range{first2}{last2}, respectively. \end{itemize} \pnum @@ -8573,14 +10896,6 @@ \pnum \remarks Stable\iref{algorithm.stable}. -If \range{first1}{last1} contains $m$ elements -that are equivalent to each other and -\range{first2}{last2} contains $n$ elements -that are equivalent to them, -then $|m - n|$ of those elements shall be copied to the output range: -the last $m - n$ of these elements from \range{first1}{last1} if $m > n$, and -the last $n - m$ of these elements from \range{first2}{last2} if $m < n$. -In either case, the elements are copied in order. \end{itemdescr} \rSec2[alg.heap.operations]{Heap operations} @@ -8905,6 +11220,25 @@ \tcode{return ranges::is_heap_until(first, last, comp, proj) == last;} \end{itemdescr} +\begin{itemdecl} +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + bool ranges::is_heap(Ep&& exec, I first, S last, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + bool ranges::is_heap(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ranges::is_heap_until(std::forward(exec), first, last, comp, proj) == last; +\end{codeblock} +\end{itemdescr} + \indexlibraryglobal{is_heap_until}% \begin{itemdecl} template @@ -8932,6 +11266,15 @@ @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr borrowed_iterator_t ranges::is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + I ranges::is_heap_until(Ep&& exec, I first, S last, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + borrowed_iterator_t + ranges::is_heap_until(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -9003,6 +11346,11 @@ requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> constexpr range_value_t ranges::min(R&& r, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> + range_value_t + ranges::min(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -9081,6 +11429,11 @@ requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> constexpr range_value_t ranges::max(R&& r, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> + range_value_t + ranges::max(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -9162,6 +11515,11 @@ requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> constexpr ranges::minmax_result> ranges::minmax(R&& r, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + requires @\libconcept{indirectly_copyable_storable}@, range_value_t*> + ranges::minmax_result> + ranges::minmax(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -9217,6 +11575,16 @@ @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr borrowed_iterator_t ranges::min_element(R&& r, Comp comp = {}, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + I ranges::min_element(Ep&& exec, I first, S last, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + borrowed_iterator_t + ranges::min_element(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -9264,6 +11632,16 @@ @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr borrowed_iterator_t ranges::max_element(R&& r, Comp comp = {}, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + I ranges::max_element(Ep&& exec, I first, S last, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + borrowed_iterator_t + ranges::max_element(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} @@ -9314,6 +11692,16 @@ @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> constexpr ranges::minmax_element_result> ranges::minmax_element(R&& r, Comp comp = {}, Proj proj = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, + class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + ranges::minmax_element_result + ranges::minmax_element(Ep&& exec, I first, S last, Comp comp = {}, Proj proj = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + ranges::minmax_element_result> + ranges::minmax_element(Ep&& exec, R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} @@ -9422,6 +11810,20 @@ constexpr bool ranges::lexicographical_compare(R1&& r1, R2&& r2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + +template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I1, @\libconcept{sized_sentinel_for}@ S1, + @\libconcept{random_access_iterator}@ I2, @\libconcept{sized_sentinel_for}@ S2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, + projected> Comp = ranges::less> + bool ranges::lexicographical_compare(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R1, @\exposconcept{sized-random-access-range}@ R2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, Proj1>, + projected, Proj2>> Comp = ranges::less> + bool ranges::lexicographical_compare(Ep&& exec, R1&& r1, R2&& r2, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); \end{itemdecl} \begin{itemdescr} @@ -9641,6 +12043,7 @@ \indexheader{numeric}% \begin{codeblock} +// mostly freestanding namespace std { // \ref{accumulate}, accumulate template @@ -9660,13 +12063,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 @@ -9694,19 +12097,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); @@ -9731,13 +12134,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); @@ -9756,19 +12159,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); @@ -9782,7 +12185,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); @@ -9803,14 +12206,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); @@ -9826,13 +12229,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); @@ -9842,7 +12245,7 @@ namespace ranges { template - using iota_result = out_value_result; + using @\libglobal{iota_result}@ = out_value_result; template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ T> requires @\libconcept{indirectly_writable}@ @@ -9868,15 +12271,15 @@ // \ref{numeric.sat}, saturation arithmetic template - constexpr T add_sat(T x, T y) noexcept; // freestanding + constexpr T saturating_add(T x, T y) noexcept; template - constexpr T sub_sat(T x, T y) noexcept; // freestanding + constexpr T saturating_sub(T x, T y) noexcept; template - constexpr T mul_sat(T x, T y) noexcept; // freestanding + constexpr T saturating_mul(T x, T y) noexcept; template - constexpr T div_sat(T x, T y) noexcept; // freestanding + constexpr T saturating_div(T x, T y) noexcept; template - constexpr T saturate_cast(U x) noexcept; // freestanding + constexpr T saturating_cast(U x) noexcept; } \end{codeblock} @@ -9894,24 +12297,24 @@ \indexlibrary{generalized_noncommutative_sum@\tcode{\placeholder{GENERALIZED_NONCOMMUTATIVE_SUM}}}% \pnum -Define \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, ..., aN)} +Define \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, $\dotsc$, aN)} as follows: \begin{itemize} \item \tcode{a1} when \tcode{N} is \tcode{1}, otherwise \item -\tcode{op(\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, ..., aK),} \\ -\tcode{\phantom{op(}\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, aM, ..., aN))} +\tcode{op(\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, a1, $\dotsc$, aK),} \\ +\tcode{\phantom{op(}\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, aM, $\dotsc$, aN))} for any \tcode{K} where $1 < \mathtt{K}+1 = \mathtt{M} \leq \mathtt{N}$. \end{itemize} \indexlibrary{generalized_sum@\tcode{\placeholder{GENERALIZED_SUM}}}% \pnum -Define \tcode{\placeholdernc{GENERALIZED_SUM}(op, a1, ..., aN)} as -\tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, b1, ..., bN)}, -where -\tcode{b1, ..., bN} may be any permutation of \tcode{a1, ..., aN}. +Define \tcode{\placeholdernc{GENERALIZED_SUM}(op, a1, $\dotsc$, aN)} as +\tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(op, b1, $\dotsc$, bN)}, +\linebreak{}where +\tcode{b1, $\dotsc$, bN} may be any permutation of \tcode{a1, $\dotsc$, aN}. \rSec2[accumulate]{Accumulate} @@ -10059,7 +12462,7 @@ \pnum \returns -\tcode{\placeholdernc{GENERALIZED_SUM}(binary_op, init, *i, ...)} +\tcode{\placeholdernc{GENERALIZED_SUM}(binary_op, init, *i, $\dotsc$)} for every \tcode{i} in \range{first}{last}. \pnum @@ -10201,7 +12604,7 @@ \pnum \returns \begin{codeblock} -@\placeholdernc{GENERALIZED_SUM}@(binary_op1, init, binary_op2(*i, *(first2 + (i - first1))), ...) +@\placeholdernc{GENERALIZED_SUM}@(binary_op1, init, binary_op2(*i, *(first2 + (i - first1))), @$\dotsc$@) \end{codeblock} for every iterator \tcode{i} in \range{first1}{last1}. @@ -10250,7 +12653,7 @@ \pnum \returns \begin{codeblock} -@\placeholdernc{GENERALIZED_SUM}@(binary_op, init, unary_op(*i), ...) +@\placeholdernc{GENERALIZED_SUM}@(binary_op, init, unary_op(*i), @$\dotsc$@) \end{codeblock} for every iterator \tcode{i} in \range{first}{last}. @@ -10403,7 +12806,7 @@ assigns through \tcode{result + K} the value of: \begin{codeblock} @\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}@( - binary_op, init, *(first + 0), *(first + 1), ..., *(first + K - 1)) + binary_op, init, *(first + 0), *(first + 1), @$\dotsc$@, *(first + K - 1)) \end{codeblock} \pnum @@ -10527,10 +12930,10 @@ \begin{itemize} \item \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op, - init, *(first + 0), *(first + 1), ..., *(first + K))}\\if \tcode{init} is provided, or + init, *(first + 0), *(first + 1), $\dotsc$, *(first + K))}\\if \tcode{init} is provided, or \item \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op, - *(first + 0), *(first + 1), ..., *(first + K))}\\otherwise. + *(first + 0), *(first + 1), $\dotsc$, *(first + K))}\\otherwise. \end{itemize} \pnum @@ -10604,7 +13007,7 @@ \begin{codeblock} @\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}@( binary_op, init, - unary_op(*(first + 0)), unary_op(*(first + 1)), ..., unary_op(*(first + K - 1))) + unary_op(*(first + 0)), unary_op(*(first + 1)), @$\dotsc$@, unary_op(*(first + K - 1))) \end{codeblock} \pnum @@ -10704,10 +13107,10 @@ assigns through \tcode{result + K} the value of \begin{itemize} \item - \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op, init,\\\phantom{\tcode{\ \ \ \ }}unary_op(*(first + 0)), unary_op(*(first + 1)), ..., unary_op(*(first + K)))}\\ + \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op, init,\\\phantom{\tcode{\ \ \ \ }}unary_op(*(first + 0)), unary_op(*(first + 1)), $\dotsc$, unary_op(*(first + K)))}\\ if \tcode{init} is provided, or \item - \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op,\\\phantom{\tcode{\ \ \ \ }}unary_op(*(first + 0)), unary_op(*(first + 1)), ..., unary_op(*(first + K)))}\\ + \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op,\\\phantom{\tcode{\ \ \ \ }}unary_op(*(first + 0)), unary_op(*(first + 1)), $\dotsc$, unary_op(*(first + K)))}\\ otherwise. \end{itemize} @@ -10818,7 +13221,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 @@ -10964,7 +13367,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{T} is an arithmetic type other than \tcode{bool}. +\tcode{T} is an arithmetic type other than \cv{}~\tcode{bool}. \pnum \returns @@ -11020,10 +13423,10 @@ is performed as a mathematical operation with infinite range and then it is determined whether the mathematical result fits into the result type. -\indexlibraryglobal{add_sat}% +\indexlibraryglobal{saturating_add}% \begin{itemdecl} template - constexpr T add_sat(T x, T y) noexcept; + constexpr T saturating_add(T x, T y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -11038,10 +13441,10 @@ whichever is closer to the value of $\tcode{x} + \tcode{y}$. \end{itemdescr} -\indexlibraryglobal{sub_sat}% +\indexlibraryglobal{saturating_sub}% \begin{itemdecl} template - constexpr T sub_sat(T x, T y) noexcept; + constexpr T saturating_sub(T x, T y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -11056,10 +13459,10 @@ whichever is closer to the value of $\tcode{x} - \tcode{y}$. \end{itemdescr} -\indexlibraryglobal{mul_sat}% +\indexlibraryglobal{saturating_mul}% \begin{itemdecl} template - constexpr T mul_sat(T x, T y) noexcept; + constexpr T saturating_mul(T x, T y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -11074,10 +13477,10 @@ whichever is closer to the value of $\tcode{x} \times \tcode{y}$. \end{itemdescr} -\indexlibraryglobal{div_sat}% +\indexlibraryglobal{saturating_div}% \begin{itemdecl} template - constexpr T div_sat(T x, T y) noexcept; + constexpr T saturating_div(T x, T y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -11099,15 +13502,15 @@ \remarks A function call expression that violates the precondition in the \Fundescx{Preconditions} element -is not a core constant expression\iref{expr.const}. +is not a core constant expression\iref{expr.const.core}. \end{itemdescr} \rSec3[numeric.sat.cast]{Casting} -\indexlibraryglobal{saturate_cast}% +\indexlibraryglobal{saturating_cast}% \begin{itemdecl} template - constexpr R saturate_cast(T x) noexcept; + constexpr R saturating_cast(T x) noexcept; \end{itemdecl} \begin{itemdescr} @@ -11156,7 +13559,7 @@ } template - decltype(auto) @\exposid{deref-move}@(I& it) { + constexpr decltype(auto) @\exposid{deref-move}@(I& it) { if constexpr (is_lvalue_reference_v) return std::move(*it); else @@ -11212,6 +13615,26 @@ \end{note} \end{itemdescr} +\begin{itemdecl} +template +concept @\defexposconcept{nothrow-sized-sentinel-for}@ = // \expos + @\exposconcept{nothrow-sentinel-for}@ && + @\libconcept{sized_sentinel_for}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Types \tcode{S} and \tcode{I} model \exposconcept{nothrow-sized-sentinel-for} +only if no exceptions are thrown from the \tcode{-} operator +for valid values of type \tcode{I} and \tcode{S}. + +\pnum +\begin{note} +This concept allows some \libconcept{sized_sentinel_for}\iref{iterator.concept.sizedsentinel} +operations to throw exceptions. +\end{note} +\end{itemdescr} + \begin{itemdecl} template concept @\defexposconcept{nothrow-input-range}@ = // \expos @@ -11250,6 +13673,68 @@ @\exposconcept{nothrow-forward-iterator}@>; \end{itemdecl} +\begin{itemdecl} +template +concept @\defexposconcept{nothrow-bidirectional-iterator}@ = // \expos + @\exposconcept{nothrow-forward-iterator}@ && + @\libconcept{bidirectional_iterator}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +A type \tcode{I} models \exposconcept{nothrow-bidirectional-iterator} +only if no exceptions are thrown from decrementing valid iterators. +\begin{note} +This concept allows some \libconcept{bidirectional_iterator}\iref{iterator.concept.bidir} +operations to throw exceptions. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +template +concept @\defexposconcept{nothrow-bidirectional-range}@ = // \expos + @\exposconcept{nothrow-forward-range}@ && + @\exposconcept{nothrow-bidirectional-iterator}@>; +\end{itemdecl} + +\begin{itemdecl} +template +concept @\defexposconcept{nothrow-random-access-iterator}@ = // \expos + @\exposconcept{nothrow-bidirectional-iterator}@ && + @\libconcept{random_access_iterator}@ && + @\exposconcept{nothrow-sized-sentinel-for}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +A type \tcode{I} models \exposconcept{nothrow-random-access-iterator} +only if no exceptions are thrown from comparisons of valid iterators, +or the \tcode{-}, \tcode{+}, \tcode{-=}, \tcode{+=}, \tcode{[]} operators +on valid values of type \tcode{I} and \tcode{iter_difference_t}. +\begin{note} +This concept allows some \libconcept{random_access_iterator}\iref{iterator.concept.random.access} +operations to throw exceptions. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +template +concept @\defexposconcept{nothrow-random-access-range}@ = // \expos + @\exposconcept{nothrow-bidirectional-range}@ && + @\exposconcept{nothrow-random-access-iterator}@>; + +template +concept @\defexposconcept{nothrow-sized-random-access-range}@ = // \expos + @\exposconcept{nothrow-random-access-range}@ && @\libconcept{sized_range}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +A type \tcode{R} models \exposconcept{nothrow-sized-random-access-range} +only if no exceptions are thrown from the call to \tcode{ranges::size} +on an object of type \tcode{R}. +\end{itemdescr} + \rSec2[uninitialized.construct.default]{\tcode{uninitialized_default_construct}} \indexlibraryglobal{uninitialized_default_construct}% @@ -11265,8 +13750,7 @@ Equivalent to: \begin{codeblock} for (; first != last; ++first) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type; + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type; \end{codeblock} \end{itemdescr} @@ -11306,8 +13790,7 @@ Equivalent to: \begin{codeblock} for (; n > 0; (void)++first, --n) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type; + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type; return first; \end{codeblock} \end{itemdescr} @@ -11346,8 +13829,7 @@ Equivalent to: \begin{codeblock} for (; first != last; ++first) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type(); + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type(); \end{codeblock} \end{itemdescr} @@ -11387,8 +13869,7 @@ Equivalent to: \begin{codeblock} for (; n > 0; (void)++first, --n) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type(); + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type(); return first; \end{codeblock} \end{itemdescr} @@ -11431,8 +13912,7 @@ Equivalent to: \begin{codeblock} for (; first != last; ++result, (void)++first) - ::new (@\placeholdernc{voidify}@(*result)) - typename iterator_traits::value_type(*first); + ::new (@\placeholdernc{voidify}@(*result)) iterator_traits::value_type(*first); \end{codeblock} \pnum @@ -11487,8 +13967,7 @@ Equivalent to: \begin{codeblock} for (; n > 0; ++result, (void)++first, --n) - ::new (@\placeholdernc{voidify}@(*result)) - typename iterator_traits::value_type(*first); + ::new (@\placeholdernc{voidify}@(*result)) iterator_traits::value_type(*first); \end{codeblock} \pnum @@ -11542,7 +14021,7 @@ \begin{codeblock} for (; first != last; (void)++result, ++first) ::new (@\placeholdernc{voidify}@(*result)) - typename iterator_traits::value_type(@\exposid{deref-move}@(first)); + iterator_traits::value_type(@\exposid{deref-move}@(first)); return result; \end{codeblock} \end{itemdescr} @@ -11602,7 +14081,7 @@ \begin{codeblock} for (; n > 0; ++result, (void)++first, --n) ::new (@\placeholdernc{voidify}@(*result)) - typename iterator_traits::value_type(@\exposid{deref-move}@(first)); + iterator_traits::value_type(@\exposid{deref-move}@(first)); return {first, result}; \end{codeblock} \end{itemdescr} @@ -11643,7 +14122,8 @@ \indexlibraryglobal{uninitialized_fill}% \begin{itemdecl} -template +template::value_type> constexpr void uninitialized_fill(NoThrowForwardIterator first, NoThrowForwardIterator last, const T& x); \end{itemdecl} @@ -11654,18 +14134,17 @@ Equivalent to: \begin{codeblock} for (; first != last; ++first) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type(x); + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type(x); \end{codeblock} \end{itemdescr} \indexlibraryglobal{uninitialized_fill}% \begin{itemdecl} namespace ranges { - template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S, class T> + template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S, class T = iter_value_t> requires @\libconcept{constructible_from}@, const T&> constexpr I uninitialized_fill(I first, S last, const T& x); - template<@\exposconcept{nothrow-forward-range}@ R, class T> + template<@\exposconcept{nothrow-forward-range}@ R, class T = range_value_t> requires @\libconcept{constructible_from}@, const T&> constexpr borrowed_iterator_t uninitialized_fill(R&& r, const T& x); } @@ -11684,7 +14163,8 @@ \indexlibraryglobal{uninitialized_fill_n}% \begin{itemdecl} -template +template::value_type> constexpr NoThrowForwardIterator uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); \end{itemdecl} @@ -11695,8 +14175,7 @@ Equivalent to: \begin{codeblock} for (; n--; ++first) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type(x); + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type(x); return first; \end{codeblock} \end{itemdescr} @@ -11704,7 +14183,7 @@ \indexlibraryglobal{uninitialized_fill_n}% \begin{itemdecl} namespace ranges { - template<@\exposconcept{nothrow-forward-iterator}@ I, class T> + template<@\exposconcept{nothrow-forward-iterator}@ I, class T = iter_value_t> requires @\libconcept{constructible_from}@, const T&> constexpr I uninitialized_fill_n(I first, iter_difference_t n, const T& x); } @@ -11861,10 +14340,11 @@ \rSec2[alg.rand.generate]{\tcode{generate_random}} +\indexlibraryglobal{generate_random}% \begin{itemdecl} template requires @\libconcept{output_range}@> && @\libconcept{uniform_random_bit_generator}@> -constexpr borrowed_iterator_t ranges::generate_random(R&& r, G&& g); + constexpr borrowed_iterator_t ranges::generate_random(R&& r, G&& g); \end{itemdecl} \begin{itemdescr} @@ -11903,10 +14383,11 @@ \end{note} \end{itemdescr} +\indexlibraryglobal{generate_random}% \begin{itemdecl} template> O, @\libconcept{sentinel_for}@ S> requires @\libconcept{uniform_random_bit_generator}@> -constexpr O ranges::generate_random(O first, S last, G&& g); + constexpr O ranges::generate_random(O first, S last, G&& g); \end{itemdecl} \begin{itemdescr} @@ -11918,12 +14399,13 @@ \end{codeblock} \end{itemdescr} +\indexlibraryglobal{generate_random}% \begin{itemdecl} template requires @\libconcept{output_range}@> && @\libconcept{invocable}@ && @\libconcept{uniform_random_bit_generator}@> && is_arithmetic_v> -constexpr borrowed_iterator_t ranges::generate_random(R&& r, G&& g, D&& d); + constexpr borrowed_iterator_t ranges::generate_random(R&& r, G&& g, D&& d); \end{itemdecl} \begin{itemdescr} @@ -11954,7 +14436,7 @@ \pnum \returns -\tcode{ranges::end(r)} +\tcode{ranges::end(r)}. \pnum \remarks @@ -11969,11 +14451,12 @@ \end{note} \end{itemdescr} +\indexlibraryglobal{generate_random}% \begin{itemdecl} template> O, @\libconcept{sentinel_for}@ S> requires @\libconcept{invocable}@ && @\libconcept{uniform_random_bit_generator}@> && is_arithmetic_v> -constexpr O ranges::generate_random(O first, S last, G&& g, D&& d); + constexpr O ranges::generate_random(O first, S last, G&& g, D&& d); \end{itemdecl} \begin{itemdescr} @@ -11996,10 +14479,14 @@ \indexlibraryglobal{bsearch}% \indexlibraryglobal{qsort}% \begin{itemdecl} -void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, +void* bsearch(const void* key, void* base, size_t nmemb, size_t size, @\placeholder{c-compare-pred}@* compar); -void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, +void* bsearch(const void* key, void* base, size_t nmemb, size_t size, @\placeholder{compare-pred}@* compar); +const void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, + @\placeholder{c-compare-pred}@* compar); +const void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, + @\placeholder{compare-pred}@* compar); void qsort(void* base, size_t nmemb, size_t size, @\placeholder{c-compare-pred}@* compar); void qsort(void* base, size_t nmemb, size_t size, @\placeholder{compare-pred}@* compar); \end{itemdecl} @@ -12019,4 +14506,4 @@ Any exception thrown by \tcode{compar}\iref{res.on.exception.handling}. \end{itemdescr} -\xrefc{7.22.5} +\xrefc{7.24.6} diff --git a/source/back.tex b/source/back.tex index 90d1cfbb4b..03939906da 100644 --- a/source/back.tex +++ b/source/back.tex @@ -7,10 +7,6 @@ \bibitem{iso4217} ISO 4217:2015, \doccite{Codes for the representation of currencies} -\bibitem{iso10967-1} - 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{}} @@ -83,13 +79,13 @@ \bibitem{blas-std} 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, and R.\ Client Whaley, + Roldan Pozo, Karin Remington, and R.\ Clint Whaley, \doccite{An Updated Set of Basic Linear Algebra Subprograms (BLAS)}. - ACM Trans.\ Math.\ Soft., Vol.\ 28, Issue 2, 2002. + ACM Trans.\ Math.\ Soft., Vol.\ 28, Issue 2, pp.\ 135--151, 2002. \bibitem{flynn-taxonomy} Michael J.\ Flynn, \doccite{Very High-Speed Computing Systems}. - Proceedings of the IEEE, Vol.\ 54, Issue 12, 1966. + Proceedings of the IEEE, Vol.\ 54, Issue 12, pp.\ 1901--1909, 1966. \end{thebibliography} % FIXME: For unknown reasons, hanging paragraphs are not indented within our @@ -110,9 +106,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} { diff --git a/source/basic.tex b/source/basic.tex index d4d063f74a..34f3deae72 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,38 @@ \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 +\begin{itemize} +\item an \grammarterm{identifier} token\iref{lex.token, lex.name} other than + \begin{itemize} + \item + the \grammarterm{identifier} of a + \grammarterm{label}\iref{stmt.label} or + \grammarterm{literal-operator-id}\iref{over.literal}, + \item + the \grammarterm{identifier} following a \keyword{goto} in a + \grammarterm{jump-statement}\iref{stmt.jump.general}, + \item + any \grammarterm{identifier} in a + \grammarterm{module-name}\iref{module.unit} or + \grammarterm{attribute-token}\iref{dcl.attr.grammar}, or + \end{itemize} +\item a \grammarterm{conversion-function-id}\iref{class.conv.fct}, +\item an \grammarterm{operator-function-id}\iref{over.oper}, or +\item a \grammarterm{literal-operator-id}\iref{over.literal}. +\end{itemize} \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 +78,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 +90,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 @@ -82,25 +113,12 @@ implicit declaration of an injected-class-name\iref{class.pre}. \end{itemize} \begin{note} +The term declaration is not a synonym for the grammar non-terminal \grammarterm{declaration}\iref{dcl.pre}. +\end{note} +\begin{note} 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 -A \defn{variable} is introduced by the -declaration of -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 -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, -or the \tcode{*\keyword{this}} object\iref{expr.prim.this}. \pnum \begin{note} @@ -112,16 +130,50 @@ \end{note} \pnum -Two names are \defnx{the same}{name!same} if +A \defn{variable} is introduced by the +declaration $D$ of \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. +\item +a reference other than a non-static data member or +\item +an object, \end{itemize} +where $D$ is not the \grammarterm{parameter-declaration} of +a \grammarterm{template-parameter}. + +\pnum +An \defn{entity} is a +variable, +structured binding, +result binding, +function, +enumerator, +type, +type alias, +non-static data member, +bit-field, +template, +namespace, +namespace alias, +template parameter, +function parameter, or +\grammarterm{init-capture}. +The \defnadj{underlying}{entity} of an entity is that entity +unless otherwise specified. +A name \defnx{denotes}{denote} the underlying entity of +the entity declared by each declaration that introduces the name. +\begin{note} +Type aliases and namespace aliases have underlying entities +that are distinct from themselves. +\end{note} + +\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 \indextext{translation unit!name and}% @@ -137,15 +189,18 @@ \indextext{declaration!definition versus}% \indextext{declaration}% \indextext{declaration!name}% -A declaration\iref{dcl.dcl} may (re)introduce +A declaration\iref{basic.pre} 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}. -A declaration may also have effects including: +A declaration of an entity $X$ is +a \defn{redeclaration} of $X$ +if another declaration of $X$ is reachable from it\iref{module.reach}; +otherwise, it is a \defnadj{first}{declaration}. + +\begin{note} +A declaration can also have effects including: \begin{itemize} \item a static assertion\iref{dcl.pre}, \item controlling template instantiation\iref{temp.explicit}, @@ -153,11 +208,12 @@ \item use of attributes\iref{dcl.attr}, and \item nothing (in the case of an \grammarterm{empty-declaration}). \end{itemize} +\end{note} \pnum \indextext{declaration!function}% \indextext{definition}% -Each entity declared by a \grammarterm{declaration} is +Each entity declared by a declaration is also \defnx{defined}{define} by that declaration unless: \begin{itemize} \item @@ -173,8 +229,7 @@ Appearing inside the brace-enclosed \grammarterm{declaration-seq} in a \grammarterm{linkage-specification} does not affect whether a declaration is a definition. -\end{footnote} -\iref{dcl.link} +\end{footnote}\iref{dcl.link} and neither an \grammarterm{initializer} nor a \grammarterm{function-body}, \item @@ -210,12 +265,15 @@ \item it is an \grammarterm{alias-declaration}\iref{dcl.typedef}, \item it is -a -\grammarterm{using-declaration}\iref{namespace.udecl}, +a \grammarterm{namespace-alias-definition}\iref{namespace.alias}, +\item it is +a \grammarterm{using-declaration}\iref{namespace.udecl}, \item it is a \grammarterm{deduction-guide}\iref{temp.deduct.guide}, \item it is a \grammarterm{static_assert-declaration}\iref{dcl.pre}, +\item it is +a \grammarterm{consteval-block-declaration}, \item it is an \grammarterm{attribute-declaration}\iref{dcl.pre}, @@ -234,7 +292,7 @@ \item it is an explicit instantiation declaration\iref{temp.explicit}, or \item it is -an explicit specialization\iref{temp.expl.spec} whose +an \grammarterm{explicit-specialization}\iref{temp.expl.spec} whose \grammarterm{declaration} is not a definition. \end{itemize} A declaration is said to be a \defn{definition} of each entity that it defines. @@ -253,7 +311,6 @@ int X::y = 1; // defines \tcode{X::y} enum { up, down }; // defines \tcode{up} and \tcode{down} namespace N { int d; } // defines \tcode{N} and \tcode{N::d} -namespace N1 = N; // defines \tcode{N1} X anX; // defines \tcode{anX} \end{codeblock} @@ -264,6 +321,7 @@ int f(int); // declares \tcode{f} struct S; // declares \tcode{S} typedef int Int; // declares \tcode{Int} +namespace N1 = N; // declares \tcode{N1} extern X anotherX; // declares \tcode{anotherX} using N::d; // declares \tcode{d} \end{codeblock} @@ -357,15 +415,17 @@ The set of \defn{potential results} of an expression $E$ is defined as follows: \begin{itemize} -\item If $E$ is an -\grammarterm{id-expression}\iref{expr.prim.id}, the set +\item If $E$ is +an \grammarterm{id-expression}\iref{expr.prim.id} or +a \grammarterm{splice-expression}\iref{expr.prim.splice}, the set contains only $E$. \item If $E$ is a subscripting operation\iref{expr.sub} with an array operand, the set contains the potential results of that operand. \item If $E$ is a class member access expression\iref{expr.ref} of the form -$E_1$ \tcode{.} \opt{\keyword{template}} $E_2$ -naming a non-static data member, +$E_1$ \tcode{.} \opt{\keyword{template}} $E_2$, +where $E_2$ designates a non-static data member or +a direct base class relationship, the set contains the potential results of $E_1$. \item If $E$ is a class member access expression naming a static data member, @@ -384,17 +444,21 @@ \item Otherwise, the set is empty. \end{itemize} \begin{note} -This set is a (possibly-empty) set of \grammarterm{id-expression}{s}, +This set is a (possibly-empty) set of +\grammarterm{id-expression}{s} and \grammarterm{splice-expression}s, each of which is either $E$ or a subexpression of $E$. \begin{example} In the following example, the set of potential results of the initializer of \tcode{n} contains the first \tcode{S::x} subexpression, but not the second \tcode{S::x} subexpression. +The set of potential results of the initializer of \tcode{o} contains +the subexpression \tcode{[:\caret\caret S::x:]}. \begin{codeblock} struct S { static const int x = 0; }; const int &f(const int &r); int n = b ? (1, S::x) // \tcode{S::x} is not odr-used here : f(S::x); // \tcode{S::x} is odr-used here, so a definition is required +int o = [:^^S::x:]; \end{codeblock} \end{example} \end{note} @@ -409,10 +473,11 @@ of an overload set\iref{basic.lookup,over.match,over.over} in an overload resolution performed as part of forming that expression or conversion, - unless it is a pure virtual function and either - the expression is not an \grammarterm{id-expression} naming the function with - an explicitly qualified name or - the expression forms a pointer to member\iref{expr.unary.op}. + and either + it is not a pure virtual function or + the expression is an \grammarterm{id-expression} naming the function with + an explicitly qualified name + that does not form a pointer to member\iref{expr.unary.op}. \begin{note} This covers taking the address of functions\iref{conv.func,expr.unary.op}, @@ -441,33 +506,35 @@ \pnum \label{term.odr.use}% A variable is named by an expression -if the expression is an \grammarterm{id-expression} that denotes it. +if the expression is an \grammarterm{id-expression} or +\grammarterm{splice-expression}\iref{expr.prim.splice} +that designates it. A variable \tcode{x} that is named by a -potentially-evaluated expression $N$ +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 +that is usable in constant expressions at $P$\iref{expr.const.init}, or \item $N$ is an element of the set of potential results of an expression $E$, where \begin{itemize} \item $E$ is a discarded-value expression\iref{expr.context} -to which the lvalue-to-rvalue conversion is not applied or +to which the lvalue-to-rvalue conversion is not applied, or \item \tcode{x} is a non-volatile object that is usable in constant expressions at $P$ and -has no mutable subobjects 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 +whose object expression has non-volatile-qualified type, or \item the lvalue-to-rvalue conversion\iref{conv.lval} is applied to $E$ and -$E$ has non-volatile-qualified non-class type +$E$ has non-volatile-qualified non-class type. \end{itemize} \end{itemize} \end{itemize} @@ -498,10 +565,15 @@ \end{example} \pnum -A structured binding is odr-used if it appears as a potentially-evaluated expression. +A structured binding is named by an expression +if that expression is either an \grammarterm{id-expression} or +a \grammarterm{splice-expression} +that designates that structured binding. +A structured binding is odr-used +if it is named by a potentially evaluated expression. \pnum -\tcode{*\keyword{this}} is odr-used if \keyword{this} appears as a potentially-evaluated expression +\tcode{*\keyword{this}} is odr-used if \keyword{this} appears as a potentially evaluated expression (including as the result of any implicit transformation to a class member access expression\iref{expr.prim.id.general}). @@ -509,7 +581,7 @@ A virtual member function is odr-used if it is not pure. A function is odr-used if it is named by -a potentially-evaluated expression or conversion. +a potentially evaluated expression or conversion. A non-placement allocation or deallocation function for a class is odr-used by the definition of a constructor of that class. A non-placement deallocation function for a class is odr-used by the @@ -544,10 +616,11 @@ for each intervening scope\iref{basic.scope.scope} 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: +within the innermost enclosing class or non-lambda function parameter scope), +either \begin{itemize} -\item the intervening scope is a block scope, or +\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 @@ -565,9 +638,9 @@ \begin{example} \begin{codeblock} void f(int n) { - [] { n = 1; }; // error: \tcode{n} is not odr-usable due to intervening lambda-expression + [] { n = 1; }; // error: \tcode{n} is not odr-usable due to intervening \grammarterm{lambda-expression} struct A { - void f() { n = 2; } // error: \tcode{n} is not odr-usable due to intervening function definition scope + void f() { n = 2; } // error: \tcode{n} is not odr-usable due to intervening function parameter scope }; void g(int = n); // error: \tcode{n} is not odr-usable due to intervening function parameter scope [=](int k = n) {}; // error: \tcode{n} is not odr-usable due to being @@ -601,7 +674,7 @@ \pnum Every program shall contain at least one definition of every function or variable that is odr-used in that program -outside of a discarded statement\iref{stmt.if}; no diagnostic required. +outside of a discarded statement\iref{stmt.if}; no diagnostic required\ifndrdef{basic.def.odr.minimum.one.def}. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see~\ref{class.default.ctor}, \ref{class.copy.ctor}, @@ -674,7 +747,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 @@ -683,18 +756,29 @@ \end{note} \pnum -For any definable item \tcode{D} with definitions in multiple translation units, +If a definable item \tcode{D} is defined in a translation unit +by an injected declaration $X$\iref{expr.const.reflect} and +another translation unit contains a definition of \tcode{D}, +that definition shall be an injected declaration +having the same characteristic sequence as $X$; +a diagnostic is required only if \tcode{D} is attached to a named module and +a prior definition is reachable +at the point where a later definition occurs\ifndrdef{basic.def.odr.injected.match}. + +\pnum +For any other definable item \tcode{D} with definitions in multiple translation units, \begin{itemize} \item -if \tcode{D} is a non-inline non-templated function or variable, or +if \tcode{D} is a non-inline non-templated function or variable\ifndrdef{basic.def.odr.maximum.one.def}, or \item if the definitions in different translation units -do not satisfy the following requirements, +do not satisfy the following requirements\ifndrdef{basic.def.odr.definition.matches}, \end{itemize} the program is ill-formed; a diagnostic is required only if the definable item is attached to a named module and -a prior definition is reachable at the point where a later definition occurs. +a prior definition is reachable +at the point where a later definition occurs. Given such an item, for all definitions of \tcode{D}, or, if \tcode{D} is an unnamed enumeration, @@ -709,7 +793,7 @@ is considered to consist of the sequence of tokens of the corresponding \grammarterm{lambda-expression}. \item In each such definition, corresponding names, looked up -according to~\ref{basic.lookup}, shall refer to the same entity, after +according to~\ref{basic.lookup}, shall denote the same entity, after overload resolution\iref{over.match} and after matching of partial template specializations\iref{temp.spec.partial.match}, except that a name can refer to \begin{itemize} @@ -717,7 +801,7 @@ a non-volatile const object with internal or no linkage if the object \begin{itemize} \item has the same literal type in all definitions of \tcode{D}, -\item is initialized with a constant expression\iref{expr.const}, +\item is initialized with a constant expression\iref{expr.const.const}, \item is not odr-used in any definition of \tcode{D}, and \item has the same value in all definitions of \tcode{D}, \end{itemize} @@ -725,7 +809,7 @@ \item a reference with internal or no linkage initialized with a constant expression such that -the reference refers to the same entity in all definitions of \tcode{D}. +the reference refers to the same object or function in all definitions of \tcode{D}. \end{itemize} \item In each such definition, except within @@ -754,11 +838,17 @@ \item In each such definition, a default argument used by an (implicit or explicit) function call or a default template argument used by an (implicit or explicit) -\grammarterm{template-id} or \grammarterm{simple-template-id} +\grammarterm{template-id}, +\grammarterm{simple-template-id}, or +\grammarterm{splice-specialization-specifier} is treated as if its token sequence were present in the definition of \tcode{D}; that is, the default argument or default template argument is subject to the requirements described in this paragraph (recursively). + +\item In each such definition, +corresponding \grammarterm{reflect-expression}s\iref{expr.reflect} +compute equivalent values\iref{expr.eq}. \end{itemize} \pnum @@ -869,7 +959,7 @@ reachable unnamed enumeration definition in the same scope that have the same first enumerator name and do not have typedef names for linkage purposes\iref{dcl.enum}, -those unnamed enumeration types shall be the same; no diagnostic required. +those unnamed enumeration types shall be the same; no diagnostic required\ifndrdef{basic.def.odr.unnamed.enum.same.type}. \indextext{one-definition rule|)} \rSec1[basic.scope]{Scope}% @@ -884,9 +974,12 @@ every other scope $S$ is introduced by a declaration, \grammarterm{parameter-declaration-clause}, -\grammarterm{statement}, or \grammarterm{handler} +\grammarterm{statement}, +\grammarterm{handler}, +\grammarterm{lambda-expression}, 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. @@ -911,6 +1004,9 @@ Any names (re)introduced by a declaration are \defnx{bound}{name!bound} to it in its target scope. \end{itemize} +The \defnadj{host}{scope} of a declaration is +the inhabited scope if that scope is a block scope and +the target scope otherwise. An entity \defnx{belongs}{entity!belong} to a scope $S$ if $S$ is the target scope of a declaration of the entity. \begin{note} @@ -923,7 +1019,7 @@ Corresponding declarations with appropriate linkage declare the same entity\iref{basic.link}. \item -The declaration in a \grammarterm{template-declaration} +The \grammarterm{declaration} of a \grammarterm{template-declaration} inhabits the same scope as the \grammarterm{template-declaration}. \item Friend declarations and @@ -933,8 +1029,8 @@ 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}. @@ -991,7 +1087,7 @@ \item either is a \grammarterm{using-declarator}, or \item -one declares a type (not a \grammarterm{typedef-name}) and the other declares a +one declares a type (not a type alias) and the other declares a variable, non-static data member other than of an anonymous union\iref{class.union.anon}, enumerator, @@ -1062,7 +1158,7 @@ if its name is \tcode{_} (\unicode{005f}{low line}) and it declares \begin{itemize} \item -a variable with automatic storage duration, +a variable, other than a function parameter, with automatic storage duration, \item a structured binding %FIXME: "and" is strange below; maybe reword to something like: @@ -1071,6 +1167,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? @@ -1263,6 +1361,9 @@ The locus of a \grammarterm{for-range-declaration} of a range-based \keyword{for} statement\iref{stmt.ranged} is immediately after the \grammarterm{for-range-initializer}. +The locus of a \grammarterm{for-range-declaration} +of an \grammarterm{expansion-statement}\iref{stmt.expand} +is immediately after the \grammarterm{expansion-initializer}. \pnum The locus of a \grammarterm{template-parameter} is immediately after it. @@ -1276,6 +1377,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}. @@ -1319,7 +1424,7 @@ Each \begin{itemize} \item -selection or iteration statement\iref{stmt.select,stmt.iter}, +selection, iteration, or expansion statement\iref{stmt.select,stmt.iter,stmt.expand}, \item substatement of such a statement, \item @@ -1356,8 +1461,8 @@ \grammarterm{compound-statement} of a \grammarterm{lambda-expression}, \grammarterm{function-body}, or \grammarterm{function-try-block}, \item -substatement of a selection or iteration statement -that is not itself a selection or iteration statement, or +substatement of a selection, iteration, or expansion statement +that is not itself a selection, iteration, or expansion statement, or \item \grammarterm{handler} of a \grammarterm{function-try-block} \end{itemize} @@ -1408,7 +1513,7 @@ \item If $P$ is associated with a \grammarterm{lambda-declarator}, its scope extends to the end of the \grammarterm{compound-statement} -in the \grammarterm{lambda-expression}. +of the \grammarterm{lambda-expression}. \item If $P$ is associated with a \grammarterm{requirement-parameter-list}, its scope extends to the end of the \grammarterm{requirement-body} of the \grammarterm{requires-expression}. @@ -1491,7 +1596,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}. @@ -1511,6 +1620,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 postcondition assertion\iref{expr.prim.lambda}, +\end{itemize} +the program is ill-formed. + \indextext{scope|)} \rSec1[basic.lookup]{Name lookup}% @@ -1547,7 +1680,12 @@ used in further processing. \pnum -A program point $P$ is said to follow +There is a \defnadj{program}{point} +before the first token of the translation unit, +at least one between every pair of adjacent tokens, and +at least one after the last token of the translation unit. + +A program point $P$ is said to \defnx{follow}{follow!program point} any declaration in the same translation unit whose locus\iref{basic.scope.pdecl} is before $P$. \begin{note} @@ -1614,7 +1752,7 @@ In certain contexts, only certain kinds of declarations are included. After any such restriction, any declarations of classes or enumerations are discarded if any other declarations are found. \begin{note} -A type (but not a \grammarterm{typedef-name} or template) +A type (but not a type alias or template) is therefore hidden by any other entity in its scope. \end{note} \indextext{type-only!lookup|see{lookup, type-only}}% @@ -1622,8 +1760,8 @@ only declarations of types and templates whose specializations are types are considered; furthermore, if declarations -of a \grammarterm{typedef-name} and of the type to which it refers are found, -the declaration of the \grammarterm{typedef-name} is discarded +of a type alias and of its underlying entity are found, +the declaration of the type alias is discarded instead of the type declaration. \rSec2[class.member.lookup]{Member name lookup}% @@ -1702,7 +1840,7 @@ If it is an invalid set, the program is ill-formed. If it differs from the result of a search in $T$ for $M$ in a complete-class context\iref{class.mem} of $T$, -the program is ill-formed, no diagnostic required. +the program is ill-formed, no diagnostic required\ifndrdef{class.member.lookup.name.refers.diff.decl}. \begin{example} \begin{codeblock} struct A { int x; }; // S(x,A) = \{ \{ \tcode{A::x} \}, \{ \tcode{A} \} \} @@ -1952,7 +2090,8 @@ \pnum In a friend declaration \grammarterm{declarator} whose \grammarterm{declarator-id} is a \grammarterm{qualified-id} -whose lookup context\iref{basic.lookup.qual} is a class or namespace $S$, +whose \grammarterm{nested-name-specifier} +designates a class or namespace $S$\iref{expr.prim.id.qual}, lookup for an unqualified name that appears after the \grammarterm{declarator-id} performs a search in the scope associated with $S$. @@ -2012,7 +2151,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} @@ -2037,7 +2176,7 @@ rules apply. In some cases a name followed by \tcode{<} is treated as a \grammarterm{template-name} -even though name lookup did not find a \grammarterm{template-name} +even though name lookup did not find the declaration of a template (see \ref{temp.names}). For example, \begin{codeblock} @@ -2080,14 +2219,23 @@ 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. The set of entities is determined in the following way: \begin{itemize} -\item If \tcode{T} is a fundamental type, its associated set of +\item If \tcode{T} is \tcode{std::meta::info}\iref{meta.syn}, +its associated set of entities is the singleton containing +the enumeration type \tcode{std::meta::operators}\iref{meta.reflection.operators}. +\begin{note} +The \tcode{std::meta::info} type is a type alias, +so an explicit rule is needed to associate calls +whose arguments are reflections with the namespace \tcode{std::meta}. +\end{note} + +\item If \tcode{T} is any other fundamental type, its associated set of entities is empty. \item If \tcode{T} is a class type (including unions), @@ -2100,11 +2248,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} @@ -2135,19 +2286,19 @@ 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 the innermost enclosing non-inline namespaces for its associated entities as well as every element of the inline namespace set\iref{namespace.def} of those namespaces. -Argument-dependent lookup finds -all declarations of functions and function templates that +Argument-dependent lookup for a name $N$ finds +all declarations of functions and function templates named $N$ that \begin{itemize} \item -are found by a search of any associated namespace, or +are found by a search for $N$ in any associated namespace, or \item are declared as a friend\iref{class.friend} of any class with a reachable definition in the set of associated entities, or @@ -2158,7 +2309,7 @@ have the same innermost enclosing non-inline namespace scope as a declaration of an associated entity attached to \tcode{M}\iref{basic.link}. \end{itemize} -If the lookup is for a dependent name\iref{temp.dep,temp.dep.candidate}, +If $N$ is a dependent name\iref{temp.dep,temp.dep.candidate}, the above lookup is also performed from each point in the instantiation context\iref{module.context} of the lookup, additionally ignoring any declaration that @@ -2210,7 +2361,7 @@ \pnum \begin{note} -The associated namespace can include namespaces +The set of associated namespaces can include namespaces already considered by ordinary unqualified lookup. \end{note} \begin{example} @@ -2242,8 +2393,14 @@ followed by a \tcode{::} scope resolution operator considers only namespaces, types, and templates whose specializations are types. -If a name, \grammarterm{template-id}, or \grammarterm{computed-type-specifier} +If a +name, +\grammarterm{template-id}, +\grammarterm{splice-scope-specifier}, or +\grammarterm{computed-type-specifier} is followed by a \tcode{::}, +it shall either be +a dependent \grammarterm{splice-scope-specifier}\iref{temp.dep.splice} or it shall designate a namespace, class, enumeration, or dependent type, and the \tcode{::} is never interpreted as a complete \grammarterm{nested-name-specifier}. @@ -2272,7 +2429,7 @@ \indextext{scope resolution operator|see{operator, scope resolution}}% \pnum -A member-qualified name is +A \defnadj{member-qualified}{name} is the (unique) component name\iref{expr.prim.id.unqual}, if any, of \begin{itemize} \item @@ -2292,6 +2449,7 @@ \item a \grammarterm{typename-specifier}, \item a \grammarterm{qualified-namespace-specifier}, or \item a \grammarterm{nested-name-specifier}, +\grammarterm{reflection-name}, \grammarterm{elaborated-type-specifier}, or \grammarterm{class-or-decltype} that has a \grammarterm{nested-name-specifier}\iref{expr.prim.id.qual}. @@ -2425,13 +2583,13 @@ \end{footnote} \begin{itemize} \item -if the search finds the injected-class-name of \tcode{C}\iref{class.pre}, or +if the search finds the injected-class-name of $C$\iref{class.pre}, or \item if $N$ is dependent and is the terminal name of a \grammarterm{using-declarator}\iref{namespace.udecl} that names a constructor, \end{itemize} -$N$ is instead considered to name the constructor of class \tcode{C}. +$N$ is instead considered to name the constructor of class $C$. Such a constructor name shall be used only in the \grammarterm{declarator-id} of a (friend) declaration of a constructor or in a \grammarterm{using-declaration}. @@ -2636,7 +2794,7 @@ \end{note} \pnum -If the terminal name of the \grammarterm{elaborated-type-specifier} +If the terminal name of an \grammarterm{elaborated-type-specifier} is a qualified name, lookup for it is type-only. If the name lookup does not find a previously declared \grammarterm{type-name}, @@ -2686,14 +2844,79 @@ only namespace names are considered.% \indextext{lookup!name|)}% +\rSec1[basic.splice]{Splice specifiers} +\indextext{splice|(}% + +\begin{bnf} +\nontermdef{splice-specifier}\br + \terminal{[:} constant-expression \terminal{:]} +\end{bnf} + +\begin{bnf} +\nontermdef{splice-specialization-specifier}\br + splice-specifier \terminal{<} \opt{template-argument-list} \terminal{>} +\end{bnf} + +\pnum +The \grammarterm{constant-expression} of a \grammarterm{splice-specifier} +shall be a converted constant expression of +type \tcode{std::meta::info}\iref{expr.const.const}. +A \grammarterm{splice-specifier} +whose converted \grammarterm{constant-expression} represents +a construct $X$ is said to \defn{designate} either +\begin{itemize} +\item the underlying entity of $X$ if $X$ is an entity\iref{basic.pre}, or +\item $X$ otherwise. +\end{itemize} +\begin{note} +A \grammarterm{splice-specifier} is dependent +if the converted \grammarterm{constant-expression} is +value-dependent\iref{temp.dep.splice}. +\end{note} + +\pnum +A non-dependent \grammarterm{splice-specifier} of +a \grammarterm{splice-specialization-specifier} shall designate a template. + +\pnum +\begin{note} +A \tcode{<} following a \grammarterm{splice-specifier} is interpreted as +the delimiter of a \grammarterm{template-argument-list} +when the \grammarterm{splice-specifier} is preceded by +the keyword \keyword{template} or the keyword \keyword{typename}, or +when it appears in a type-only context\iref{temp.names}. +\begin{example} +\begin{codeblock} +constexpr int v = 1; +template struct TCls { + static constexpr int s = V + 1; +}; + +using alias = [:^^TCls:]<([:^^v:])>; + // OK, a \grammarterm{splice-specialization-specifier} with a parenthesized \grammarterm{splice-expression} as a template argument + +static_assert(alias::s == 2); + +auto o1 = [:^^TCls:]<([:^^v:])>(); // error: < means less than +auto o2 = typename [:^^TCls:]<([:^^v:])>(); // OK, \tcode{o2} is an object of type \tcode{TCls<1>} + +consteval int bad_splice(std::meta::info v) { + return [:v:]; // error: \tcode{v} is not constant +} +\end{codeblock} +\end{example} +\end{note} +\indextext{splice|)} + \rSec1[basic.link]{Program and linkage}% \indextext{linkage|(} \pnum \indextext{program}% -A \defn{program} consists of one or more translation units\iref{lex.separate} -linked together. A translation unit consists -of a sequence of declarations. +\indextext{linking}% +A \defn{program} consists of one or more translation units\iref{lex.phases} +that are translated and linked together. +A translation unit consists of a sequence of declarations. \begin{bnf} \nontermdef{translation-unit}\br @@ -2703,7 +2926,7 @@ \pnum \indextext{translation unit}% -A name can have +A name has \defnadj{external}{linkage}, \defnadj{module}{linkage}, \defnadj{internal}{linkage}, or @@ -2856,13 +3079,13 @@ \item they appear in the same translation unit, or \item -they both declare names with module linkage and are attached to the same module, or +they both declare type aliases or namespace aliases that have the same underlying entity, or \item -they both declare names with external linkage. +they both declare names with module or external linkage and are attached to the same module. \end{itemize} \begin{note} -There are other circumstances in which declarations declare the same entity% -\iref{dcl.link,temp.type,temp.spec.partial}. +There are other circumstances in which declarations declare +the same entity\iref{dcl.link,temp.type,temp.spec.partial}. \end{note} \pnum @@ -2875,9 +3098,11 @@ \end{note} \pnum -If two declarations of an entity are -attached to different modules, the program is ill-formed; -no diagnostic is required if neither is reachable from the other. +\begin{note} +If two declarations correspond but are +attached to different modules, the program is ill-formed +if one precedes the other\iref{basic.scope.scope}. +\end{note} \begin{example} \begin{codeblocktu}{\tcode{"decls.h"}} int f(); // \#1, attached to the global module @@ -2889,15 +3114,15 @@ #include "decls.h" export module M; export using ::f; // OK, does not declare an entity, exports \#1 -int g(); // error: matches \#2, but attached to \tcode{M} +int g(); // error: corresponds to \#2, but attached to \tcode{M} export int h(); // \#3 export int k(); // \#4 \end{codeblocktu} \begin{codeblocktu}{Other translation unit} import M; -static int h(); // error: matches \#3 -int k(); // error: matches \#4 +static int h(); // error: conflicts with \#3 +int k(); // error: conflicts with \#4 \end{codeblocktu} \end{example} As a consequence of these rules, @@ -2939,11 +3164,12 @@ If one declares $E$ to be a concept, the other shall do so. \end{itemize} Types are compared after all adjustments of types (during which -typedefs\iref{dcl.typedef} are replaced by their definitions); +type aliases\iref{dcl.typedef} are replaced by the types they denote); declarations for an array object can specify array types that differ by the presence or absence of a major array bound\iref{dcl.array}. -No diagnostic is required if neither declaration is reachable from the other. +No diagnostic is required +if neither declaration is reachable from the other\ifndrdef{basic.link.consistent.types}. \begin{example} \begin{codeblock} int f(int x, int x); // error: different entities for \tcode{x} @@ -2968,6 +3194,16 @@ \item $D$ contains a \grammarterm{lambda-expression} whose closure type is $E$, \item +$D$ contains +a \grammarterm{reflect-expression} or a \grammarterm{splice-specifier} +that, respectively, represents or designates $E$, +\item +$D$ is an injected declaration\iref{expr.const.reflect} +whose characteristic sequence contains a reflection +that represents +a data member description ($T$, $N$, $A$, $W$, $\mathit{NUA}$, $\mathit{ANN}$)\iref{class.mem.general} +for which $T$ is $E$, +\item $E$ is not a function or function template and $D$ contains an \grammarterm{id-expression}, \grammarterm{type-specifier}, @@ -3016,7 +3252,7 @@ An entity is \defnx{TU-local}{TU-local!entity} if it is \begin{itemize} \item -a type, function, variable, or template that +a type, type alias, namespace, namespace alias, function, variable, or template that \begin{itemize} \item has a name with internal linkage, or @@ -3048,14 +3284,30 @@ A value or object is \defnx{TU-local}{TU-local!value or object} if either \begin{itemize} \item +it is of TU-local type, +\item it is, or is a pointer to, -a TU-local function or the object associated with a TU-local variable, or +a TU-local function or the object associated with a TU-local variable, \item it is an object of class or array type and any of its subobjects or any of the objects or functions to which its non-static data members of reference type refer -is TU-local and is usable in constant expressions. +is TU-local and is usable in constant expressions, or +\item +it is a reflection value\iref{basic.fundamental} that represents +\begin{itemize} +\item +an entity, value, or object that is TU-local, +\item +an annotation\iref{dcl.attr.annotation}, +\item +a direct base class relationship $(D, B)$\iref{class.derived.general} +for which either $D$ or $B$ is TU-local, or +\item +a data member description $(T, N, A, W, \mathit{NUA}, \mathit{ANN})$\iref{class.mem.general} +for which $T$ is TU-local. +\end{itemize} \end{itemize} \pnum @@ -3105,6 +3357,16 @@ void adl(double); inline void h(auto x) { adl(x); } // OK, but certain specializations are exposures + +constexpr std::meta::info r1 = ^^g<0>; // OK +namespace N2 { + static constexpr std::meta::info r2 = ^^g<1>; // OK, \tcode{r2} is TU-local +} +constexpr std::meta::info r3 = ^^f; // error: \tcode{r3} is an exposure of \tcode{f} + +constexpr auto ctx = std::meta::access_context::current(); +constexpr std::meta::info r4 = + std::meta::members_of(^^N2, ctx)[0]; // error: \tcode{r4} is an exposure of \tcode{N2::r2} \end{codeblocktu} \begin{codeblocktu}{Translation unit \#2} module A; @@ -3137,11 +3399,10 @@ UTF-8 encoding form and is composed of a contiguous sequence of bits, -\begin{footnote} -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}. +\begin{note} +See the macro \libmacro{CHAR_BIT} in the header \libheaderref{climits}. +\end{note} The memory available to a \Cpp{} program consists of one or more sequences of contiguous bytes. Every byte has a unique address. @@ -3193,9 +3454,9 @@ }; \end{codeblock} contains four separate memory locations: The member \tcode{a} and bit-fields -\tcode{d} and \tcode{e.ee} are each separate memory locations, and can be +\tcode{d} and \tcode{e.ee} each occupy separate memory locations, and can be modified concurrently without interfering with each other. The bit-fields -\tcode{b} and \tcode{c} together constitute the fourth memory location. The +\tcode{b} and \tcode{c} together occupy the fourth memory location. The bit-fields \tcode{b} and \tcode{c} cannot be concurrently modified, but \tcode{b} and \tcode{a}, for example, can be. \end{example} @@ -3246,7 +3507,7 @@ An object that is not a subobject of any other object is called a \defn{complete object}. If an object is created -in storage associated with a member subobject or array element \placeholder{e} +in storage associated with a subobject \placeholder{e} (which may or may not be within its lifetime), the created object is a subobject of \placeholder{e}'s containing object if @@ -3256,8 +3517,12 @@ \item the storage for the new object exactly overlays the storage location associated with \placeholder{e}, and \item +\placeholder{e} is not a potentially-overlapping subobject, and +\item the new object is of the same type as \placeholder{e} (ignoring cv-qualification). \end{itemize} +In this case, \placeholder{e} and the created object are +\defnadjx{corresponding direct}{subobjects}{subobject}. \pnum \indextext{object!providing storage for}% @@ -3378,9 +3643,16 @@ \pnum An object is a \defnadj{potentially non-unique}{object} if it is -a string literal object\iref{lex.string}, -the backing array of an initializer list\iref{dcl.init.ref}, or -a subobject thereof. +\begin{itemize} +\item + a string literal object\iref{lex.string}, +\item + the backing array of an initializer list\iref{dcl.init.ref}, or +\item + a template parameter object of array type\iref{meta.define.static}, or +\item + a subobject thereof. +\end{itemize} \pnum \indextext{most derived object!bit-field}% @@ -3393,18 +3665,18 @@ may have the same address if \begin{itemize} \item one is nested within the other, -\item at least one is a subobject of zero size and they are not of similar types\iref{conv.qual}, +\item +they are both nested within some complete object $o$, +exactly one is a subobject of $o$, and the subobject is of zero size, +\item +they are both subobjects of the same complete object, +at least one is a subobject of zero size, and +they are not of similar types\iref{conv.qual}, or \item they are both potentially non-unique objects; \end{itemize} otherwise, they have distinct addresses and occupy disjoint bytes of storage. -\begin{footnote} -Under the ``as-if'' rule an -implementation is allowed to store two objects at the same machine address or -not store an object at all if the program cannot observe the -difference\iref{intro.execution}. -\end{footnote} \begin{example} \begin{codeblock} static const char test1 = 'x'; @@ -3420,10 +3692,76 @@ const bool b5 = r != &test1; // always \tcode{true} \end{codeblock} \end{example} -The address of a non-bit-field subobject of zero size is +The address of a subobject of zero size is the address of an unspecified byte of storage occupied by the complete object of that subobject. +\pnum +A \defnadj{union elemental}{subobject} +\indextext{union!elemental subobject|see{subobject, union elemental}} +is a direct member of a union or +an element of an array that is a union elemental subobject. +An \defnx{inactive union elemental subobject}{subobject!union elemental!inactive} +\indextext{inactive union elemental subobject|see{subobject, union elemental, inactive}} +\indextext{union!inactive elemental subobject|see{subobject, union elemental, inactive}} +is a union elemental subobject that is not within its lifetime. + +\pnum +The \defnx{constituent values}{constituent value} of an object $o$ are +\begin{itemize} +\item +if $o$ has scalar type, the value of $o$; +\item +otherwise, the constituent values of any direct subobjects of $o$ +other than inactive union elemental subobjects. +\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 elemental subobjects. +\end{itemize} +\begin{example} +\begin{codeblock} +struct A { + struct X { + int i; + int j; + }; + + struct Y { + X x1; + X x2; + }; + + union { + int i; + int arr[4]; + Y y; + }; +}; + +constexpr A v1; // OK, no constituent values +constexpr A v2{.i=1}; // OK, the constituent values are \tcode{\{v2.i\}} +constexpr A v3 = []{ + A a; + std::start_lifetime(a.arr); // OK, \tcode{arr} is now the active element of the union + new (&a.arr[1]) int(1); + a.arr[2] = 2; + return a; +}(); // OK, the constituent values are \tcode{\{v3.arr[1], v3.arr[2]\}} +constexpr A v4 = []{ + A a; + a.y.x1.i = 1; + a.y.x2.j = 2; + return a; +}(); // error: the constituent values include \tcode{v4.y.x1.j} and \tcode{v4.y.x2.i} + // which have erroneous value +\end{codeblock} +\end{example} + \pnum Some operations are described as \defnx{implicitly creating objects}{object!implicit creation} @@ -3433,7 +3771,7 @@ zero or more objects of implicit-lifetime types\iref{term.implicit.lifetime.type} in its specified region of storage if doing so would result in the program having defined behavior. -If no such set of objects would give the program defined behavior, +If no such set of objects would give the program defined behavior\ubdef{intro.object.implicit.create}, the behavior of the program is undefined. If multiple such sets of objects would give the program defined behavior, it is unspecified which such set of objects is created. @@ -3451,7 +3789,7 @@ and produce a pointer value that points to that object, if that value would result in the program having defined behavior. If no such pointer value would give the program defined behavior, -the behavior of the program is undefined. +the behavior of the program is undefined\ubdef{intro.object.implicit.pointer}. If multiple such pointer values would give the program defined behavior, it is unspecified which such pointer value is produced. @@ -3488,8 +3826,8 @@ implicitly creates objects in the returned region of storage and returns a pointer to a suitable created object. \begin{note} -Some functions in the \Cpp{} standard library implicitly create objects% -\iref{obj.lifetime,c.malloc,mem.res.public,bit.cast,cstring.syn}. +Some functions in the \Cpp{} standard library implicitly create +objects\iref{obj.lifetime,c.malloc,mem.res.public,bit.cast,cstring.syn}. \end{note} \indextext{object model|)} @@ -3502,10 +3840,10 @@ 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}. +using the \grammarterm{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. +is undefined behavior\ubdef{basic.align.object.alignment}. \pnum A \defnadj{fundamental}{alignment} is represented by an alignment @@ -3562,8 +3900,8 @@ 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}. +The type \tcode{\keyword{unsigned} \keyword{char}} can be used as +the element type of an array providing aligned storage\iref{dcl.align}. \end{note} \pnum @@ -3607,13 +3945,14 @@ \item storage with the proper alignment and size for type \tcode{T} is obtained, and \item its initialization (if any) is complete - (including vacuous initialization)\iref{dcl.init}, + (including vacuous initialization)\iref{dcl.init,class.base.init}, \end{itemize} except that if the object is a union member or subobject thereof, its lifetime only begins if that union member is the initialized member in the union\iref{dcl.init.aggr,class.base.init}, or as described in -\ref{class.union}, \ref{class.copy.ctor}, and \ref{class.copy.assign}, +\ref{class.union}, \ref{class.copy.ctor}, \ref{class.copy.assign}, +and \ref{obj.lifetime}, and except as described in \ref{allocator.members}. The lifetime of an object \placeholder{o} of type \tcode{T} ends when: \begin{itemize} @@ -3682,9 +4021,8 @@ \begin{footnote} For example, before the dynamic initialization of an object with static storage duration\iref{basic.start.dynamic}. - \end{footnote} -or, after the lifetime of an object has ended and before the storage +or after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that represents the address of the storage location where the object will be or was located may be used but only in limited ways. @@ -3695,27 +4033,20 @@ 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}, + the pointer is used as the operand of a \grammarterm{delete-expression}\ubdef{lifetime.outside.pointer.delete}, \item the pointer is used to access a non-static data member or call a - non-static member function of the object, or + non-static member function of the object\ubdef{lifetime.outside.pointer.member}, or \item - the pointer is implicitly converted\iref{conv.ptr} to a pointer - to a virtual base class, or -\item - the pointer is used as the operand of a - \keyword{static_cast}\iref{expr.static.cast}, except when the conversion - is to pointer to \cv{}~\keyword{void}, or to pointer to \cv{}~\keyword{void} - and subsequently to pointer to - \cv{}~\keyword{char}, - \cv{}~\tcode{\keyword{unsigned} \keyword{char}}, or - \cv{}~\tcode{std::byte}\iref{cstddef.syn}, or + the pointer is converted\iref{conv.ptr,expr.static.cast} to a pointer + to a virtual base class\ubdef{lifetime.outside.pointer.virtual} or + to a base class thereof, or \item the pointer is used as the operand of a - \keyword{dynamic_cast}\iref{expr.dynamic.cast}. + \keyword{dynamic_cast}\iref{expr.dynamic.cast}\ubdef{lifetime.outside.pointer.dynamic.cast}. \end{itemize} \begin{example} \begin{codeblock} @@ -3749,7 +4080,7 @@ \pnum Similarly, before the lifetime of an object has started but after the -storage which the object will occupy has been allocated or, after the +storage which the object will occupy has been allocated or after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. @@ -3758,14 +4089,14 @@ 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 -\item the glvalue is bound to a reference to a virtual base class\iref{dcl.init.ref}, or +\item the glvalue is used to access the object\ubdef{lifetime.outside.glvalue.access}, or +\item the glvalue is used to call a non-static member function of the object\ubdef{lifetime.outside.glvalue.member}, or +\item the glvalue is bound to a reference to a virtual base class\iref{dcl.init.ref}\ubdef{lifetime.outside.glvalue.virtual}, or \item the glvalue is used as the operand of a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or as the operand of -\keyword{typeid}. +\keyword{typeid}\ubdef{lifetime.outside.glvalue.dynamic.cast}. \end{itemize} \begin{note} @@ -3775,22 +4106,24 @@ \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 either \begin{itemize} +\item +$o_1$ and $o_2$ are complete objects for which: +\begin{itemize} +\item $o_1$ is not const, \item the storage that $o_2$ occupies exactly overlays the storage that $o_1$ occupied, and - \item $o_1$ and $o_2$ are of the same type -(ignoring the top-level cv-qualifiers), and - -\item $o_1$ is not a const, complete object, and - -\item neither $o_1$ nor $o_2$ -is a potentially-overlapping subobject\iref{intro.object}, and +(ignoring the top-level cv-qualifiers), or +\end{itemize} -\item either $o_1$ and $o_2$ are both complete objects, or -$o_1$ and $o_2$ are direct subobjects of objects $p_1$ and $p_2$, respectively, -and $p_1$ is transparently replaceable by $p_2$. +\item +$o_1$ and $o_2$ are corresponding direct subobjects\iref{intro.object} for which: +\begin{itemize} +\item the complete object of $o_1$ is not const or +\item $o_1$ is a mutable member subobject or a subobject thereof. +\end{itemize} \end{itemize} \pnum @@ -3848,7 +4181,7 @@ \end{footnote} and another object of the original type does not occupy that same storage location when the implicit destructor call takes -place, the behavior of the program is undefined. This is true +place, the behavior of the program is undefined\ubdef{original.type.implicit.destructor}. This is true even if the block is exited with an exception. \begin{example} \begin{codeblock} @@ -3868,7 +4201,7 @@ Creating a new object within the storage that a const, complete object with static, thread, or automatic storage duration occupies, or within the storage that such a const object used to occupy before -its lifetime ended, results in undefined behavior. +its lifetime ended, results in undefined behavior\ubdef{creating.within.const.complete.obj}. \begin{example} \begin{codeblock} struct B { @@ -3907,23 +4240,32 @@ \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, -the object has an erroneous value\iref{conv.lval}. +the object has an erroneous value. +\begin{note} +Lvalue-to-rvalue conversion has undefined behavior +if the erroneous value of an object is not valid for its type\iref{conv.lval}. +\end{note} \begin{note} Objects with static or thread storage duration are zero-initialized, see~\ref{basic.start.static}. \end{note} \pnum +If any operand of a built-in operator that produces a prvalue +is evaluated, +is not a discarded-value expression\iref{expr.context}, and +produces an erroneous value, +then the value produced by that operator is erroneous. Except in the following cases, if an indeterminate value is produced by an evaluation, -the behavior is undefined, and +the behavior is undefined\ubdef{basic.indet.value}, and if an erroneous value is produced by an evaluation, the behavior is erroneous and -the result of the evaluation is the value so produced but is not erroneous: +the result of the evaluation is that erroneous value: \begin{itemize} \item If an indeterminate or erroneous value of @@ -3949,7 +4291,7 @@ 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 @@ -3961,7 +4303,7 @@ that object is initialized to an indeterminate value or that erroneous value, respectively. \item - If an indeterminate value of + If an indeterminate or erroneous value of unsigned ordinary character type or \tcode{std::byte} type is produced by the evaluation of the initialization expression when initializing an object of \tcode{std::byte} type, @@ -4153,13 +4495,8 @@ \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{term.replaceable.function}. +The following allocation and deallocation functions\iref{support.dynamic} are implicitly declared in global scope in each translation unit of a program. @@ -4212,7 +4549,7 @@ does not satisfy the semantic constraints specified in~\ref{basic.stc.dynamic.allocation} and~\ref{basic.stc.dynamic.deallocation}, -the behavior is undefined. +the behavior is undefined\ubdef{basic.stc.alloc.dealloc.constraint}. \indextext{storage duration!dynamic|)} @@ -4222,7 +4559,7 @@ \indextext{function!allocation}% An allocation function that is not a class member function shall belong to the global scope and not have a name with internal linkage. -The return type shall be \tcode{\keyword{void}*}. The first +The return type shall be ``pointer to \keyword{void}''. The first parameter shall have type \tcode{std::size_t}\iref{support.types}. The first parameter shall not have an associated default argument\iref{dcl.fct.default}. The value of the first parameter @@ -4252,7 +4589,7 @@ \tcode{p0} represents the address of a block of storage disjoint from the storage for any other object accessible to the caller. The effect of indirecting through a pointer -returned from a request for zero size is undefined. +returned from a request for zero size is undefined\ubdef{basic.stc.alloc.zero.dereference}. \begin{footnote} The intent is to have \tcode{\keyword{operator} \keyword{new}()} implementable by @@ -4310,11 +4647,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} @@ -4339,11 +4678,13 @@ \pnum \indextext{\idxcode{delete}!overloading and}% Each deallocation function shall return \keyword{void}. +A deallocation function shall not have +a potentially throwing exception specification\iref{except.spec}. If the function is a destroying operator delete declared in class type \tcode{C}, -the type of its first parameter shall be \tcode{C*}; +the type of its first parameter shall be ``pointer to \tcode{C}''; otherwise, the type of its first -parameter shall be \tcode{\keyword{void}*}. A deallocation function may have more +parameter shall be ``pointer to \keyword{void}''. A deallocation function may have more than one parameter. \indextext{deallocation function!usual}% A \defn{usual deallocation function} is a deallocation function @@ -4373,7 +4714,6 @@ signature. \pnum -If a deallocation function terminates by throwing an exception, the behavior is undefined. The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect. @@ -4387,17 +4727,16 @@ \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 +A \defnadj{temporary}{object} is an object 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). +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}, @@ -4480,24 +4819,44 @@ \end{example} \pnum -When an object of class type \tcode{X} -is passed to or returned from a potentially-evaluated function call, -if \tcode{X} has at least one eligible copy or move constructor\iref{special}, -each such constructor is trivial, +When an object of type \tcode{X} +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 @@ -4521,8 +4880,8 @@ \pnum \indextext{initializer!temporary and declarator}% \indextext{temporary!order of destruction of}% -There are five contexts in which temporaries are destroyed at a different -point than the end of the full-expression. +Temporary objects are destroyed at a different point +than the end of the full-expression in the following contexts: The first context is when a default constructor is called to initialize an element of an array with no corresponding initializer\iref{dcl.init}. The second context is when a copy constructor is called to copy an element of @@ -4555,7 +4914,9 @@ \item a class member access\iref{expr.ref} using the \tcode{.} operator where the left operand is one of these expressions and - the right operand designates a non-static data member of non-reference type, + the right operand designates + a non-static data member\iref{class.mem.general} of non-reference type or + a direct base class relationship\iref{class.derived.general}, \item a pointer-to-member operation\iref{expr.mptr.oper} using the \tcode{.*} operator where the left operand is one of these expressions and @@ -4573,6 +4934,15 @@ to a glvalue that refers to the object designated by the operand, or to its complete object or a subobject thereof, +\item + an explicit type conversion (functional notation)\iref{expr.type.conv} + to a reference type whose initializer is a \grammarterm{braced-init-list} + where the reference is + \begin{itemize} + \item bound directly to the glvalue result of one of these expressions + (necessarily the sole element of the \grammarterm{braced-init-list}) or + \item bound to the result of a temporary materialization conversion, + \end{itemize} \item a conditional expression\iref{expr.cond} that is a glvalue where the second or third operand is one of these expressions, or @@ -4598,7 +4968,7 @@ covered above. \begin{example} \begin{codeblock} -const int& x = (const int&)1; // temporary for value 1 has same lifetime as x +const int& x = (const int&)1; // temporary for value \tcode{1} has same lifetime as \tcode{x} \end{codeblock} \end{example} \end{note} @@ -4641,14 +5011,33 @@ \pnum The fourth context is when a temporary object -is created in the \grammarterm{for-range-initializer} of a range-based \keyword{for} statement. +is created in the \grammarterm{for-range-initializer} of +a range-based \keyword{for} statement. If such a temporary object would otherwise be destroyed at the end of the \grammarterm{for-range-initializer} full-expression, 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 +The fifth context is when a temporary object is created in an element $E$ +of the \grammarterm{expansion-init-list} +of an enumerating expansion statement\iref{stmt.expand}. +If such a temporary object would otherwise be destroyed +at the end of the full-expression of $E$, +the object persists for the lifetime of the \grammarterm{for-range-declaration} +initialized from $E$. + +\pnum +The sixth context is when a temporary object is created +in the \grammarterm{expansion-initializer} +of an iterating or destructuring expansion statement. +If such a temporary object would otherwise be destroyed +at the end of that \grammarterm{expansion-initializer}, +the object persists for the lifetime of the reference +initialized by the \grammarterm{expansion-initializer}, if any. + +\pnum +The seventh 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 @@ -4783,57 +5172,6 @@ or functions\iref{dcl.fct}. \end{note} -\pnum -\indextext{object!byte copying and|(}% -\indextext{type!trivially copyable}% -For any object (other than a potentially-overlapping subobject) of trivially copyable type -\tcode{T}, whether or not the object holds a valid value of type -\tcode{T}, the underlying bytes\iref{intro.memory} making up the -object can be copied into an array of -\keyword{char}, -\tcode{\keyword{unsigned} \keyword{char}}, or -\tcode{std::byte}\iref{cstddef.syn}. -\begin{footnote} -By using, for example, the library -functions\iref{headers} \tcode{std::memcpy} or \tcode{std::memmove}. -\end{footnote} -If the content of that array -is copied back into the object, the object shall -subsequently hold its original value. -\begin{example} -\begin{codeblock} -constexpr std::size_t N = sizeof(T); -char buf[N]; -T obj; // \tcode{obj} initialized to its original value -std::memcpy(buf, &obj, N); // between these two calls to \tcode{std::memcpy}, \tcode{obj} might be modified -std::memcpy(&obj, buf, N); // at this point, each subobject of \tcode{obj} of scalar type holds its original value -\end{codeblock} -\end{example} - -\pnum -For two distinct objects \tcode{obj1} and \tcode{obj2} -of trivially copyable type \tcode{T}, -where neither \tcode{obj1} nor \tcode{obj2} is a potentially-overlapping subobject, -if the underlying bytes\iref{intro.memory} making up -\tcode{obj1} are copied into \tcode{obj2}, -\begin{footnote} -By using, for example, -the library functions\iref{headers} \tcode{std::memcpy} or \tcode{std::memmove}. -\end{footnote} - \tcode{obj2} shall subsequently hold the same value as -\tcode{obj1}. -\begin{example} -\begin{codeblock} -T* t1p; -T* t2p; - // provided that \tcode{t2p} points to an initialized object ... -std::memcpy(t1p, t2p, sizeof(T)); - // at this point, every subobject of trivially copyable type in \tcode{*t1p} contains - // the same value as the corresponding subobject in \tcode{*t2p} -\end{codeblock} -\end{example} -\indextext{object!byte copying and|)} - \pnum \label{term.object.representation}% The \defnx{object representation}{representation!object} @@ -4847,7 +5185,7 @@ in the object representation of \tcode{T} that participate in representing a value of type \tcode{T}. The object and value representation of -a non-bit-field complete object of type \tcode{T} are +a non-bit-field complete object are the bytes and bits, respectively, of the object corresponding to the object and value representation of its type. The object representation of a bit-field object is @@ -4860,10 +5198,6 @@ Bits in the object representation of a type or object that are not part of the value representation are \defn{padding bits}. -For trivially copyable types, the value representation is -a set of bits in the object representation that determines a -\defn{value}, which is one discrete element of an -\impldef{values of a trivially copyable type} set of values. \begin{footnote} The intent is that the memory model of \Cpp{} is compatible with that of the C programming language. @@ -4910,7 +5244,7 @@ \begin{codeblock} class X; // \tcode{X} is an incomplete type extern X* xp; // \tcode{xp} is a pointer to an incomplete type -extern int arr[]; // the type of arr is incomplete +extern int arr[]; // the type of \tcode{arr} is incomplete typedef int UNKA[]; // \tcode{UNKA} is an incomplete type UNKA* arrp; // \tcode{arrp} is a pointer to an incomplete type UNKA** arrpp; @@ -4918,7 +5252,7 @@ void foo() { xp++; // error: \tcode{X} is incomplete arrp++; // error: incomplete type - arrpp++; // OK, sizeof \tcode{UNKA*} is known + arrpp++; // OK, \tcode{sizeof(UNKA*)} is known } struct X { int i; }; // now \tcode{X} is a complete type @@ -4926,8 +5260,8 @@ X x; void bar() { - xp = &x; // OK; type is ``pointer to \tcode{X}'' - arrp = &arr; // OK; qualification conversion\iref{conv.qual} + xp = &x; // OK, type is ``pointer to \tcode{X}'' + arrp = &arr; // OK, qualification conversion\iref{conv.qual} xp++; // OK, \tcode{X} is complete arrp++; // error: \tcode{UNKA} can't be completed } @@ -4952,7 +5286,7 @@ \label{term.scalar.type}% Arithmetic types\iref{basic.fundamental}, enumeration types, pointer types, pointer-to-member types\iref{basic.compound}, -\tcode{std::nullptr_t}, +\tcode{std::meta::\brk{}info}, \tcode{std::nullptr_t}, and cv-qualified\iref{basic.type.qualifier} versions of these types are collectively called @@ -4983,7 +5317,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}, @@ -5016,7 +5350,87 @@ layout-compatible enumerations\iref{dcl.enum}, or layout-compatible standard-layout class types\iref{class.mem}. -\rSec2[basic.fundamental]{Fundamental types} +\rSec2[basic.types.trivial]{Trivially copyable types} + +\pnum +Each trivially copyable type \tcode{T} has an +\impldef{values of a trivially copyable type} +set of discrete \defnx{values}{value}. +\indextext{value!representation}% +Each possible value representation of an object of type \tcode{T} +corresponds to a distinct +\impldef{subset of values of a trivially copyable type + to which a value representation corresponds} +subset of this set. +The union of these subsets is the set of values; +for scalar types other than object pointer types, +each such subset contains no more than one value. +Certain operations cause an object to +\indextext{object!acquiring a value representation}% +\indextext{value!representation!aquire}% +\defn{acquire} a value representation, +in which case the object's value +is replaced with an unspecified member of the corresponding subset that +would result in the program having defined behavior, if any. + +\pnum +\begin{note} +A single subset for a pointer type +can contain pointers to multiple objects +in each of several regions of storage whose durations are disjoint. +\end{note} + +\pnum +\indextext{object!byte copying and|(}% +\indextext{type!trivially copyable}% +If an object of such a type \tcode{T} +is not a potentially-overlapping subobject, +whether or not the object holds a valid value of type +\tcode{T}, the underlying bytes\iref{intro.memory} making up the +object can be copied into an array of +\keyword{char}, +\tcode{\keyword{unsigned} \keyword{char}}, or +\tcode{std::byte}\iref{cstddef.syn}. +\begin{footnote} +By using, for example, the library +functions\iref{headers} \tcode{std::memcpy} or \tcode{std::memmove}. +\end{footnote} +If the content of that array +is copied back into the object, +the object acquires its original value representation. +\begin{example} +\begin{codeblock} +constexpr std::size_t N = sizeof(T); +char buf[N]; +T obj; // \tcode{obj} initialized to its original value +std::memcpy(buf, &obj, N); // between these two calls to \tcode{std::memcpy}, \tcode{obj} might be modified +std::memcpy(&obj, buf, N); // at this point, each subobject of \tcode{obj} of scalar type holds its original value +\end{codeblock} +\end{example} + +\pnum +For two distinct such objects \tcode{obj1} and \tcode{obj2}, +if the underlying bytes\iref{intro.memory} making up +\tcode{obj1} are copied into \tcode{obj2}, +\begin{footnote} +By using, for example, +the library functions\iref{headers} \tcode{std::memcpy} or \tcode{std::memmove}. +\end{footnote} + \tcode{obj2} acquires the value representation of +\tcode{obj1}. +\begin{example} +\begin{codeblock} +T* t1p; +T* t2p; + // provided that \tcode{t2p} points to an initialized object ... +std::memcpy(t1p, t2p, sizeof(T)); + // at this point, every subobject of trivially copyable type in \tcode{*t1p} contains + // the same value as the corresponding subobject in \tcode{*t2p} +\end{codeblock} +\end{example} +\indextext{object!byte copying and|)} + +\rSec2[basic.fundamental]{Fundamental types} \pnum \indextext{type!implementation-defined \tcode{sizeof}}% @@ -5036,13 +5450,8 @@ \defnadjx{signed integer}{types}{type}. The range of representable values for a signed integer type is $-2^{N-1}$ to $2^{N-1}-1$ (inclusive), -where \placeholder{N} is called the \defn{width} of the type. +where $N$ is called the \defn{width} of the type. \indextext{integral type!implementation-defined \tcode{sizeof}}% -\begin{note} -Plain \tcode{int}s are intended to have -the natural width suggested by the architecture of the execution environment; -the other signed integer types are provided to meet special needs. -\end{note} \pnum \indextext{type!\idxcode{unsigned}}% @@ -5061,7 +5470,7 @@ there exists a corresponding \defnadj{extended unsigned integer}{type}. The standard and extended unsigned integer types are collectively called \defnadjx{unsigned integer}{types}{type}. -An unsigned integer type has the same width \placeholder{N} +An unsigned integer type has the same width $N$ as the corresponding signed integer type. \indextext{arithmetic!\idxcode{unsigned}}% The range of representable values for the unsigned type is @@ -5107,7 +5516,7 @@ The width of each standard signed integer type shall not be less than the values specified in \tref{basic.fundamental.width}. The value representation of a signed or unsigned integer type -comprises $N$ bits, where N is the respective width. +comprises $N$ bits, where $N$ is the respective width. Each set of values for any padding bits\iref{basic.types.general} in the object representation are alternative representations of the value specified by the value representation. @@ -5117,7 +5526,7 @@ \end{note} \begin{note} The signed and unsigned integer types satisfy -the constraints given in \IsoC{} 5.2.4.2.1. +the constraints given in \IsoC{} 5.3.5.3.2. \end{note} Except as specified above, the width of a signed or unsigned integer type is @@ -5184,7 +5593,7 @@ \indextext{\idxcode{char8_t}|see{type, \tcode{char8_t}}}% \indextext{type!\idxcode{char8_t}}% \indextext{type!underlying!\idxcode{char8_t}}% -Type \keyword{char8_t} denotes a distinct type +Type \keyword{char8_t} is a distinct type whose underlying type is \tcode{\keyword{unsigned} \keyword{char}}. \indextext{\idxcode{char16_t}|see{type, \tcode{char16_t}}}% \indextext{\idxcode{char32_t}|see{type, \tcode{char32_t}}}% @@ -5192,8 +5601,8 @@ \indextext{type!\idxcode{char32_t}}% \indextext{type!underlying!\idxcode{char16_t}}% \indextext{type!underlying!\idxcode{char32_t}}% -Types \keyword{char16_t} and \keyword{char32_t} denote distinct types -whose underlying types are \tcode{uint_least16_t} and \tcode{uint_least32_t}, +Types \keyword{char16_t} and \keyword{char32_t} are distinct types +whose underlying types are \tcode{std::uint_least16_t} and \tcode{std::uint_least32_t}, respectively, in \libheaderref{cstdint}. \pnum @@ -5272,13 +5681,14 @@ in that type through the most positive finite floating-point number representable in that type. In addition, if negative infinity is representable in a type, -the range of that type is extended to all negative real numbers; +the range of representable values of that type is extended to all negative real numbers; likewise, if positive infinity is representable in a type, -the range of that type is extended to all positive real numbers. +the range of representable values of that type is extended to all positive real numbers. \begin{note} Since negative and positive infinity are representable in \IsoFloatUndated{} formats, -all real numbers lie within the range of representable values of +all real numbers (but not infinity or NaN) +lie within the range of representable values of a floating-point type adhering to \IsoFloatUndated{}. \end{note} @@ -5298,15 +5708,16 @@ \indextext{type!\idxcode{void}}% 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. -An expression of type \cv{}~\keyword{void} shall -be used only as +an empty set of values. +\begin{note} +An expression of type \cv{}~\keyword{void} can be used as \begin{itemize} -\item an expression statement\iref{stmt.expr}, -\item the expression in a \keyword{return} statement\iref{stmt.return} +\item the \grammarterm{expression} of an expression statement\iref{stmt.expr}, +\item the operand of 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 operand of a parenthesized expression\iref{expr.prim.paren}, +\item a requirement in a \grammarterm{requires-expression}\iref{expr.prim.req.general}, \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}, @@ -5314,13 +5725,113 @@ \item the operand of an explicit conversion to type \cv{}~\keyword{void}\iref{expr.type.conv,expr.static.cast,expr.cast}. \end{itemize} +\end{note} \pnum The types denoted by \cv~\tcode{std::nullptr_t} are distinct types. 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}*)}. +The size\iref{expr.sizeof} and alignment requirement\iref{basic.align} of +the type \tcode{std::nullptr_t} are those of +the type ``pointer to \keyword{void}''. +\begin{note} +The value representation can comprise no bits\iref{conv.lval}. +\end{note} + +\pnum +A value of type \tcode{std::meta::info} is called a \defn{reflection}. +There exists a unique \defnadj{null}{reflection}; +every other reflection is a representation of +\begin{itemize} +\item a value of scalar type\iref{temp.param}, +\item an object with static storage duration\iref{basic.stc}, +\item a variable\iref{basic.pre}, +\item a structured binding\iref{dcl.struct.bind}, +\item a function\iref{dcl.fct}, +\item a function parameter, +\item an enumerator\iref{dcl.enum}, +\item an annotation\iref{dcl.attr.grammar}, +\item a type alias\iref{dcl.typedef}, +\item a type\iref{basic.types}, +\item a class member\iref{class.mem}, +\item an unnamed bit-field\iref{class.bit}, +\item a class template\iref{temp.pre}, +\item a function template, +\item a variable template, +\item an alias template\iref{temp.alias}, +\item a concept\iref{temp.concept}, +\item a namespace alias\iref{namespace.alias}, +\item a namespace\iref{basic.namespace.general}, +\item a direct base class relationship\iref{class.derived.general}, or +\item a data member description\iref{class.mem.general}. +\end{itemize} +A reflection is said to \defn{represent} the corresponding construct. +\begin{note} +A reflection of a value can be produced by library functions such as +\tcode{std::meta::constant_of} and \tcode{std::meta::reflect_constant}. +\end{note} +\begin{example} +\begin{codeblock} +int arr[] = {1, 2, 3}; +auto [a1, a2, a3] = arr; +[[=1]] void fn(int n); +enum Enum { A }; +using Alias = int; +struct B {}; +struct S : B { + int mem; + int : 0; +}; +template struct TCls {}; +template void TFn(); +template int TVar; +template using TAlias = TCls; +template concept Concept = requires { true; }; +namespace NS {}; +namespace NSAlias = NS; + +constexpr auto ctx = std::meta::access_context::current(); + +constexpr auto r1 = std::meta::reflect_constant(42); // represents \tcode{int} value of \tcode{42} +constexpr auto r2 = std::meta::reflect_object(arr[1]); // represents \tcode{int} object +constexpr auto r3 = ^^arr; // represents a variable +constexpr auto r4 = ^^a3; // represents a structured binding +constexpr auto r5 = ^^fn; // represents a function +constexpr auto r6 = std::meta::parameters_of(^^fn)[0]; // represents a function parameter +constexpr auto r7 = ^^Enum::A; // represents an enumerator +constexpr auto r8 = std::meta::annotations_of(^^fn)[0]; // represents an annotation +constexpr auto r9 = ^^Alias; // represents a type alias +constexpr auto r10 = ^^S; // represents a type +constexpr auto r11 = ^^S::mem; // represents a class member +constexpr auto r12 = std::meta::members_of(^^S, ctx)[1]; // represents an unnamed bit-field +constexpr auto r13 = ^^TCls; // represents a class template +constexpr auto r14 = ^^TFn; // represents a function template +constexpr auto r15 = ^^TVar; // represents a variable template +constexpr auto r16 = ^^TAlias; // represents an alias template +constexpr auto r17 = ^^Concept; // represents a concept +constexpr auto r18 = ^^NSAlias; // represents a namespace alias +constexpr auto r19 = ^^NS; // represents a namespace +constexpr auto r20 = std::meta::bases_of(^^S, ctx)[0]; // represents a direct base class relationship +constexpr auto r21 = + std::meta::data_member_spec(^^int, {.name="member"}); // represents a data member description +\end{codeblock} +\end{example} + +\pnum +\recommended +Implementations should not represent other constructs +specified in this document, such as +\grammarterm{using-declarator}s, +partial template specializations, +attributes, placeholder types, +statements, or +expressions, +as values of type \tcode{std::meta::info}. +\begin{note} +Future revisions of this document can specify semantics for reflections +representing any such constructs. +\end{note} \pnum \indextext{type!fundamental}% @@ -5337,8 +5848,8 @@ If the implementation supports an extended floating-point type\iref{basic.fundamental} whose properties are specified by 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, +then the type alias \tcode{std::float16_t} +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}. @@ -5347,8 +5858,8 @@ If the implementation supports an extended floating-point type whose properties are specified by 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, +then the type alias \tcode{std::float32_t} +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. @@ -5356,8 +5867,8 @@ If the implementation supports an extended floating-point type whose properties are specified by 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, +then the type alias \tcode{std::float64_t} +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. @@ -5365,8 +5876,8 @@ If the implementation supports an extended floating-point type whose properties are specified by 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, +then the type alias \tcode{std::float128_t} +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. @@ -5378,8 +5889,8 @@ 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, +the type alias \tcode{std::bfloat16_t} +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. @@ -5409,11 +5920,11 @@ \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 +with the interchange floating types \tcode{_Float16}, \tcode{_Float32}, \tcode{_Float64}, and \tcode{_Float128} -defined in ISO/IEC TS 18661-3 and with future versions of \IsoCUndated{}. +defined in \IsoC{} H.2.2. \rSec2[basic.compound]{Compound types} @@ -5545,23 +6056,63 @@ alignment requirement. \end{note} +\pnum +A pointer value +pointing to a potentially non-unique object $O$\iref{intro.object} is +\indextext{value!associated with an evaluation}% +\defn{associated with} the evaluation of +\begin{itemize} +\item +the \grammarterm{string-literal}\iref{lex.string} that resulted in the string literal object, +\item +the initializer list\iref{dcl.init.list} that resulted in the backing array, +or +\item +the initialization of +the template parameter object\iref{temp.arg.nontype, meta.define.static} +\end{itemize} +that is $O$ or of which $O$ is a subobject. +\begin{note} +A pointer value obtained by pointer arithmetic\iref{expr.add} +from a pointer value associated with an evaluation $E$ +is also associated with $E$. +\end{note} + +\pnum +If an evaluation produces or causes an object +to have\iref{basic.types.trivial} a pointer value +to or past the end of an object $O$ and +happens before the beginning of the duration +of the region of storage for $O$, +the behavior is undefined. +\begin{note} +Relaxed atomic operations\iref{atomics.order} can produce such values. +Conversions from integers avoid producing them\iref{expr.reinterpret.cast}. +\end{note} + \pnum 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 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$. +$E$ happens after the beginning +and 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 -$P$ is not valid in the context of $E$, -then the behavior is undefined if $E$ is -an indirection\iref{expr.unary.op} or -an invocation of a deallocation function\iref{basic.stc.dynamic.deallocation}, -and \impldef{invalid pointer value in the context of an evaluation} otherwise. -\begin{footnote} -Some implementations might define that -copying such a pointer value causes a system-generated runtime fault. -\end{footnote} +$P$ is not valid in the context of $E$: +\begin{itemize} +\item If $E$ is an indirection\iref{expr.unary.op}, +the behavior is undefined\ubdef{basic.compound.invalid.pointer}. +\item If $E$ either +\begin{itemize} +\item is a boolean conversion\iref{conv.bool} or +\item is performed by +a unary \tcode{+}, additive, three-way comparison, relational, or equality +operator\iref{expr.compound}, +\end{itemize} +the behavior is \impldef{invalid pointer value in the context of an evaluation}. +\end{itemize} + \begin{note} $P$ can be valid in the context of $E$ even if it points to a type unrelated to that of $O$ or @@ -5739,8 +6290,8 @@ Every integer type has an \term{integer conversion rank} defined as follows: \begin{itemize} -\item No two signed integer types other than \keyword{char} and \tcode{\keyword{signed} -\keyword{char}} (if \keyword{char} is signed) have the same rank, even if they have +\item No two signed integer types +have the same rank, even if they have the same representation. \item The rank of a signed integer type is greater than the rank @@ -5758,18 +6309,12 @@ \item The rank of any standard integer type is greater than the rank of any extended integer type with the same width. -\item The rank of \keyword{char} equals the rank of \tcode{\keyword{signed} \keyword{char}} -and \tcode{\keyword{unsigned} \keyword{char}}. - \item The rank of \tcode{bool} is less than the rank of all -standard integer types. +other integer types. \item -\indextext{type!\idxcode{wchar_t}}% -\indextext{type!\idxcode{char16_t}}% -\indextext{type!\idxcode{char32_t}}% -The ranks of \keyword{char8_t}, \keyword{char16_t}, \keyword{char32_t}, and -\keyword{wchar_t} equal the ranks of their underlying +The ranks of the character types +equal the ranks of their corresponding underlying types\iref{basic.fundamental}. \item The rank of any extended signed integer type relative to another @@ -5794,7 +6339,7 @@ defined as follows: \begin{itemize} \item -The rank of a floating point type \tcode{T} is greater than +The rank of a floating-point type \tcode{T} is greater than the rank of any floating-point type whose set of values is a proper subset of the set of values of \tcode{T}. \item @@ -5813,12 +6358,12 @@ has a rank equal to the rank of \keyword{double}. \begin{tailnote} The treatment of \tcode{std::float64_t} differs from -that of the analoguous \tcode{_Float64} in C, +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). +have the same set of values (see \IsoC{} H.4.3). \end{tailnote} \end{itemize} \begin{note} @@ -5903,9 +6448,9 @@ \item if $E$ is a function call\iref{expr.call} or implicitly invokes a function, the constituent expressions of each default argument\iref{dcl.fct.default} -used in the call, or +used in the call, and \item -if $E$ creates an aggregate object\iref{dcl.init.aggr}, +if $E$ performs aggregate initialization\iref{dcl.init.aggr}, the constituent expressions of each default member initializer\iref{class.mem} used in the initialization. \end{itemize} @@ -5934,9 +6479,9 @@ \item an unevaluated operand\iref{expr.context}, \item -a \grammarterm{constant-expression}\iref{expr.const}, +a \grammarterm{constant-expression}\iref{expr.const.core}, \item -an immediate invocation\iref{expr.const}, +an immediate invocation\iref{expr.const.imm}, \item an \grammarterm{init-declarator}\iref{dcl.decl} (including such introduced by a structured binding\iref{dcl.struct.bind}) or @@ -5945,7 +6490,9 @@ \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. @@ -5999,12 +6546,14 @@ \pnum \indextext{value computation|(}% -Reading an object designated by a \keyword{volatile} -glvalue\iref{basic.lval}, modifying an object, calling a library I/O -function, or calling a function that does any of those operations are -all -\defn{side effects}, which are changes in the state of the execution -environment. \defnx{Evaluation}{evaluation} of an expression (or a +Reading an object designated by a \keyword{volatile} glvalue\iref{basic.lval}, +modifying an object, +producing an injected declaration\iref{expr.const.reflect}, +calling a library I/O function, or +calling a function that does any of those operations +are all \defn{side effects}, +which are changes in the state of the execution or translation environment. +\defnx{Evaluation}{evaluation} of an expression (or a subexpression) in general includes both value computations (including determining the identity of an object for glvalue evaluation and fetching a value previously assigned to an object for prvalue evaluation) and @@ -6072,7 +6621,7 @@ The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. -The behavior is undefined if +The behavior is undefined\iref{intro.multithread}\ubdef{intro.execution.unsequenced.modification} if \begin{itemize} \item \indextext{side effects}% @@ -6116,11 +6665,18 @@ \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. +the postfix expression designating \placeholder{f} +are sequenced before +every precondition assertion of the function call\iref{expr.call}, +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 the function call. + +\pnum For each \begin{itemize} \item function invocation, @@ -6128,8 +6684,8 @@ \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) +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} @@ -6142,6 +6698,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. @@ -6151,6 +6708,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.% @@ -6167,6 +6726,17 @@ signal handler is usually unsequenced with respect to the rest of the program. \end{note} +\pnum +During the evaluation of an expression +as a core constant expression\iref{expr.const.core}, +evaluations of operands of individual operators and +of subexpressions of individual expressions +that are otherwise either unsequenced or indeterminately sequenced +are evaluated in lexical order. +For a function call\iref{expr.call}, +any default arguments used are evaluated in the order as if +an argument were present for the corresponding parameter. + \rSec2[intro.multithread]{Multi-threaded executions and data races} \rSec3[intro.multithread.general]{General} @@ -6184,7 +6754,7 @@ new thread, not by the creating thread. \end{note} Every thread in a program can -potentially access every object and function in a program. +potentially use every object and function in a program. \begin{footnote} An object with automatic or thread storage duration\iref{basic.stc} is associated with @@ -6251,7 +6821,7 @@ 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 @@ -6307,122 +6877,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$ \defn{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 @@ -6435,7 +6900,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 @@ -6444,7 +6909,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 @@ -6455,7 +6920,7 @@ \item $A$ happens before $B$ and \item there is no other \indextext{side effects}% -side effect $X$ to $M$ such that $A$ +side effect $X$ on $M$ such that $A$ happens before $X$ and $X$ happens before $B$. \end{itemize} @@ -6567,7 +7032,7 @@ and neither happens before the other, except for the special case for signal handlers described below. Any such data race results in undefined -behavior. +behavior\ubdef{intro.races.data}. \begin{note} It can be shown that programs that correctly use mutexes and \tcode{memory_order::seq_cst} operations to prevent all data races and use no @@ -6587,7 +7052,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 @@ -6625,14 +7091,15 @@ \rSec3[intro.progress]{Forward progress} \pnum -The implementation may assume that any thread will eventually do one of the -following: +The implementation may assume\ubdef{intro.progress.stops} that any thread +will eventually do one of the following: \begin{itemize} \item terminate, \item invoke the function \tcode{std::this_thread::yield}\iref{thread.thread.this}, \item make a call to a library I/O function, \item perform an access through a volatile glvalue, -\item perform a synchronization operation or an atomic operation, or +\item perform an atomic or synchronization operation +other than an atomic modify-write operation\iref{atomics.order}, or \item continue execution of a trivial infinite loop\iref{stmt.iter.general}. \end{itemize} \begin{note} @@ -6689,9 +7156,10 @@ an \defn{execution step}: \begin{itemize} \item termination of the thread of execution, -\item performing an access through a volatile glvalue, or -\item completion of a call to a library I/O function, a - synchronization operation, or an atomic operation. +\item performing an access through a volatile glvalue, +\item completion of a call to a library I/O function, or +\item completion of an atomic or synchronization operation +other than an atomic modify-write operation\iref{atomics.order}. \end{itemize} \pnum @@ -6705,13 +7173,6 @@ observable behavior of the abstract machine. \end{example} -\pnum -\begin{note} -Because of this and the preceding requirement regarding what threads of execution -have to perform eventually, it follows that no thread of execution can execute -forever without an execution step occurring. -\end{note} - \pnum A thread of execution \defnx{makes progress}{make progress!thread} when an execution step occurs or a @@ -6864,8 +7325,13 @@ \indextext{\idxcode{main} function!implementation-defined parameters to}% An implementation shall allow both \begin{itemize} -\item a function of \tcode{()} returning \keyword{int} and -\item a function of \tcode{(\keyword{int}}, pointer to pointer to \tcode{\keyword{char})} returning \keyword{int} +\item +an ``optionally \tcode{noexcept} function of +\tcode{()} returning \keyword{int}'' and +\item +an ``optionally \tcode{noexcept} function of +\tcode{(\keyword{int}}, pointer to pointer to \tcode{\keyword{char})} +returning \keyword{int}'' \end{itemize} \indextext{\idxcode{argc}}% \indextext{\idxcode{argv}}% @@ -6878,7 +7344,7 @@ arguments passed to the program from the environment in which the program is run. If \tcode{argc} is nonzero these arguments shall be supplied in -\tcode{argv[0]} through \tcode{argv[argc-1]} as pointers to the initial +\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 an \ntmbs{} that represents the name used to @@ -6897,7 +7363,7 @@ \keyword{inline}, \keyword{static}, \keyword{constexpr}, or \keyword{consteval} is ill-formed. The function \tcode{main} shall not be a coroutine\iref{dcl.fct.def.coroutine}. The \tcode{main} function shall not be declared with a -\grammarterm{linkage-specification}\iref{dcl.link}. +\grammarterm{linkage-specification}\iref{dcl.link} other than \tcode{"C++"}. A program that declares \begin{itemize} \item @@ -6930,14 +7396,15 @@ objects with automatic storage duration\iref{class.dtor}. If \tcode{std::exit} is invoked during the destruction of an object with static or thread storage duration, the program has undefined -behavior. +behavior\ubdef{basic.start.main.exit.during.destruction}. \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} @@ -6958,7 +7425,7 @@ \indextext{initialization!constant}% \defnx{Constant initialization}{constant initialization} is performed if a variable with static or thread storage duration -is constant-initialized\iref{expr.const}. +is constant-initialized\iref{expr.const.init}. \indextext{initialization!zero-initialization}% If constant initialization is not performed, a variable with static storage duration\iref{basic.stc.static} or thread storage @@ -6996,16 +7463,18 @@ object \tcode{obj2} potentially requiring dynamic initialization and defined later in the same translation unit, it is unspecified whether the value of \tcode{obj2} used will be the value of the fully initialized \tcode{obj2} (because \tcode{obj2} was statically -initialized) or will be the value of \tcode{obj2} merely zero-initialized. For example, +initialized) or will be the value of \tcode{obj2} merely zero-initialized. For example: \begin{codeblock} inline double fd() { return 1.0; } extern double d1; -double d2 = d1; // unspecified: - // either statically initialized to \tcode{0.0} or - // dynamically initialized to \tcode{0.0} if \tcode{d1} is - // dynamically initialized, or \tcode{1.0} otherwise -double d1 = fd(); // either initialized statically or dynamically to \tcode{1.0} +double d2 = d1; +double d1 = fd(); \end{codeblock} +Both \tcode{d1} and \tcode{d2} can be initialized +either statically or dynamically. +If \tcode{d1} is initialized statically and \tcode{d2} dynamically, +both variables are initialized to \tcode{1.0}; +in all other cases, \tcode{d2} is initialized to \tcode{0.0}. \end{note} \rSec3[basic.start.dynamic]{Dynamic initialization of non-block variables} @@ -7030,13 +7499,14 @@ \begin{itemize} \item \tcode{D} appears in the same translation unit as \tcode{E}, or \item the translation unit containing \tcode{E} -has an interface dependency on the translation unit containing \tcode{D}, +has an interface dependency\iref{module.import} +on the translation unit containing \tcode{D}, \end{itemize} in either case prior to \tcode{E}. \pnum Dynamic initialization of non-block variables \tcode{V} and \tcode{W} -with static storage duration are ordered as follows: +with static storage duration is ordered as follows: \begin{itemize} \item If \tcode{V} and \tcode{W} have ordered initialization and @@ -7165,6 +7635,7 @@ the initialization associated with the entity for thread \placeholder{t} is sequenced before the first non-initialization odr-use by \placeholder{t} of any non-inline variable with thread storage duration +and dynamic initialization defined in the same translation unit as the variable to be initialized. It is \impldef{threads and program points at which deferred dynamic initialization is performed} in which threads and at which points in the program such deferred dynamic initialization occurs. @@ -7182,7 +7653,7 @@ \indextext{program!termination|(}% \indextext{object!destructor static}% \indextext{\idxcode{main} function!return from}% -Constructed objects\iref{dcl.init} +Constructed complete objects\iref{dcl.init} with static storage duration are destroyed and functions registered with \tcode{std::atexit} are called as part of a call to @@ -7196,34 +7667,74 @@ \end{note} \pnum -Constructed objects with thread storage duration within a given thread +Constructed complete objects with thread storage duration within a given thread are destroyed as a result of returning from the initial function of that thread and as a result of that thread calling \tcode{std::exit}. -The destruction of all constructed objects with thread storage -duration within that thread strongly happens before destroying +The destruction of those constructed objects +is sequenced before releasing the storage for +any object with thread storage duration within that thread\iref{basic.stc.thread}. +The destruction of those constructed objects +strongly happens before destroying any object with static storage duration. \pnum -If the completion of the constructor or dynamic initialization of an object with static -storage duration strongly happens before that of another, the completion of the destructor -of the second is sequenced before the initiation of the destructor of the first. -If the completion of the constructor or dynamic initialization of an object with thread -storage duration is sequenced before that of another, the completion of the destructor -of the second is sequenced before the initiation of the destructor of the first. +The destruction of a complete object with thread storage duration within a given thread +and having constant destruction\iref{expr.const.defns} +is sequenced after the destruction of any other complete object +with thread storage duration within the thread. +The destruction of a complete object with static storage duration +and having constant destruction +is sequenced after the destruction of any other complete object +with static storage duration +and after any call to a function passed to \tcode{std::atexit}. +The sequencing rules in the remainder of this subclause +apply only to complete objects not having constant destruction. + +\pnum +If the deemed construction\iref{dcl.init.general} of a complete object with static +storage duration strongly happens before that of another, the completion of the destruction +of the second is sequenced before the initiation of the destruction of the first. +If the deemed construction of a complete object with thread +storage duration is sequenced before that of another, the completion of the destruction +of the second is sequenced before the initiation of the destruction of the first. If an object is initialized statically, the object is destroyed in the same order as if -the object was dynamically initialized. For an object of array or class -type, all subobjects of that object are destroyed before any block -variable with static storage duration initialized during the construction -of the subobjects is destroyed. +the object was dynamically initialized. If the destruction of an object with static or thread storage duration exits via an exception, the function \tcode{std::terminate} is called\iref{except.terminate}. +\begin{example} +In the following program, +the elements of \tcode{a} are destroyed, +followed by \tcode{dt}, and +finally by the two \tcode{Btemp} objects: +\begin{codeblock} +struct DTemp { ~DTemp(); }; +struct Temp { + ~Temp() { + static DTemp dt; + } +}; +struct BTemp { + ~BTemp(); +}; +struct A { + const BTemp &tb; + ~A(); +}; +A a[] = { (Temp(), BTemp()), BTemp() }; + +int main() {} +\end{codeblock} +If the array \tcode{a} were an object with automatic storage duration, +the \tcode{Btemp} temporaries would be destroyed +as each element of the array is destroyed\iref{class.temporary}. +\end{example} \pnum If a function contains a block variable of static or thread storage duration that has been destroyed and the function is called during the destruction of an object with static or -thread storage duration, the program has undefined behavior if the flow of control +thread storage duration, the program has undefined behavior\ubdef{basic.start.term.use.after.destruction} if the flow of control passes through the definition of the previously destroyed block variable. \begin{note} Likewise, the behavior is undefined @@ -7234,12 +7745,13 @@ \pnum \indextext{\idxcode{atexit}}% \indexlibraryglobal{atexit}% -If the completion of the initialization of an object with static storage +If the deemed construction of a complete object with static storage duration strongly happens before a call to \tcode{std::atexit}~(see \libheader{cstdlib}, \ref{support.start.term}), the call to the function passed to -\tcode{std::atexit} is sequenced before the call to the destructor for the object. If a -call to \tcode{std::atexit} strongly happens before the completion of the initialization of -an object with static storage duration, the call to the destructor for the +\tcode{std::atexit} is sequenced before the initiation of the destruction of the object. +If a call to \tcode{std::atexit} strongly happens before the deemed construction of +a complete object with static storage duration, +the completion of the destruction of the object is sequenced before the call to the function passed to \tcode{std::atexit}. If a call to \tcode{std::atexit} strongly happens before another call to \tcode{std::atexit}, the call to the function passed to the second \tcode{std::atexit} call is sequenced before @@ -7269,3 +7781,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\ifndrdef{basic.contract.vastart.contract.predicate}. + +\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 evaluation +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.defns} +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.defns}, +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 evaluation +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{term.replaceable.function}. +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\ifndrdef{basic.contract.handler.replacing.nonreplaceable}. + +\indextext{contract assertion|)} diff --git a/source/classes.tex b/source/classes.tex index 18838fd601..56eadd3be1 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,7 +46,12 @@ \end{bnf} \begin{bnf} -\nontermdef{class-virt-specifier}\br +\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} \end{bnf} @@ -120,12 +125,12 @@ \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}, and a colon or left brace, +the identifier is interpreted as a \grammarterm{class-property-specifier}. \begin{example} \begin{codeblock} struct A; @@ -140,6 +145,11 @@ \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 +160,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}). @@ -257,7 +267,7 @@ \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 @@ -459,6 +469,7 @@ using-declaration\br using-enum-declaration\br static_assert-declaration\br + consteval-block-declaration\br template-declaration\br explicit-specialization\br deduction-guide\br @@ -475,8 +486,8 @@ \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} @@ -527,6 +538,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 @@ -544,13 +561,14 @@ \end{note} \pnum -A \grammarterm{member-declaration} does not declare new members of the class +A \grammarterm{member-declaration} does not itself declare new members of the class if it is \begin{itemize} \item a friend declaration\iref{class.friend}, \item a \grammarterm{deduction-guide}\iref{temp.deduct.guide}, \item a \grammarterm{template-declaration} whose \grammarterm{declaration} is one of the above, \item a \grammarterm{static_assert-declaration}, +\item a \grammarterm{consteval-block-declaration}, \item a \grammarterm{using-declaration}\iref{namespace.udecl}, or \item an \grammarterm{empty-declaration}. \end{itemize} @@ -562,10 +580,14 @@ shall either declare at least one member name of the class or declare at least one unnamed bit-field. +A \defnx{user-declared}{entity!user-declared} +\indextext{user-declared entity|see{entity, user-declared}} +entity is a direct member or a friend that, in either case, +is declared by a \grammarterm{member-declaration}. \pnum -A \defn{data member} is a non-function member introduced by a -\grammarterm{member-declarator}. +A \defn{data member} is either a non-function member introduced by a +\grammarterm{member-declarator} or an anonymous union member. A \defn{member function} is a member that is a function. Nested types are classes\iref{class.name,class.nest} and enumerations\iref{dcl.enum} declared in the class and arbitrary types @@ -584,10 +606,21 @@ Any other data member or member function is a \defnadj{non-static}{member} (a \defnadj{non-static}{data member} or \defnadj{non-static}{member function}\iref{class.mfct.non.static}, respectively). -\begin{note} -A non-static data member of non-reference -type is a member subobject of a class object\iref{intro.object}. -\end{note} + +\pnum +Every object of class type has a unique member subobject +corresponding to each of its direct non-static data members. +If any non-static data member of a class \tcode{C} is of reference type, +then let \tcode{D} be an invented class +that is identical to \tcode{C} +except that each non-static member of \tcode{D} corresponding to +a member of \tcode{C} of type ``reference to \tcode{T}'' +instead has type ``pointer to \tcode{T}''. +Every member subobject of a complete object of type \tcode{C} +has the same size, alignment, and offset +as that of the corresponding subobject of a complete object of type \tcode{D}. +The size and alignment of \tcode{C} are the same as +the size and alignment of \tcode{D}. \pnum A member shall not be declared twice in the @@ -618,7 +651,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. @@ -687,7 +721,7 @@ shall not directly or indirectly cause the implicit definition of a defaulted default constructor for the enclosing class or the exception specification of that constructor. -An immediate invocation\iref{expr.const} that +An immediate invocation\iref{expr.const.imm} that is a potentially-evaluated subexpression\iref{intro.execution} of a default member initializer is neither evaluated nor checked for whether it @@ -896,6 +930,52 @@ pointer-interconvertible\iref{basic.compound,expr.static.cast}. \end{note} +\pnum +A \defnadj{data member}{description} is +a sextuple ($T$, $N$, $A$, $W$, $\mathit{NUA}$, $\mathit{ANN}$) +describing the potential declaration of a non-static data member where +\begin{itemize} +\item $T$ is a type, +\item $N$ is an \grammarterm{identifier} or $\bot$, +\item $A$ is an alignment or $\bot$, +\item $W$ is a bit-field width or $\bot$, +\item $\mathit{NUA}$ is a boolean value, and +\item $\mathit{ANN}$ is a sequence of reflections +representing either values or template parameter objects. +\end{itemize} +Two data member descriptions are equal +if each of their respective components are +the same entity, +the same identifier, +the same value, +the same sequence, or +both $\bot$. +\begin{note} +The components of a data member description describe a data member such that +\begin{itemize} +\item +its type is specified using the type given by $T$, +\item +it is declared with the name given by $N$ +if $N$ is not $\bot$ and is otherwise unnamed, +\item +it is declared with the \grammarterm{alignment-specifier}\iref{dcl.align} +given by \tcode{alignas($A$)} +if $A$ is not $\bot$ and +is otherwise declared without an \grammarterm{alignment-specifier}, +\item +it is a bit-field\iref{class.bit} with the width given by $W$ +if $W$ is not $\bot$ and is otherwise not a bit-field, and +\item +it is declared with +the attribute \tcode{[[no_unique_address]]}\iref{dcl.attr.nouniqueaddr} +if $\mathit{NUA}$ is true and is otherwise declared without that attribute. +\end{itemize} +Data member descriptions are represented by reflections\iref{basic.fundamental} +returned by \tcode{std::meta::data_member_spec}\iref{meta.reflection.define.aggregate} and +can be reified as data members of a class using \tcode{std::meta::define_aggregate}. +\end{note} + \rSec2[class.mfct]{Member functions}% \indextext{member function!class} @@ -1070,7 +1150,7 @@ \end{itemize} \pnum -For a class, its non-static data members, its non-virtual direct base classes, +For a class, its direct non-static data members, its non-virtual direct base classes, and, if the class is not abstract\iref{class.abstract}, its virtual base classes are called its \term{potentially constructed subobjects}. @@ -1144,10 +1224,6 @@ \begin{note} For initialization of objects of class type see~\ref{class.init}. \end{note} - -\pnum -\indextext{object!unnamed}% -An object created in this way is unnamed. \begin{note} \ref{class.temporary} describes the lifetime of temporary objects. \end{note} @@ -1207,8 +1283,9 @@ 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 or constructor template for class -\tcode{X}, +If a class does not have +a user-declared constructor or constructor template, +and the class is not an anonymous union, a non-explicit constructor having no parameters is implicitly declared as defaulted\iref{dcl.fct.def}. An implicitly-declared default constructor is an @@ -1220,51 +1297,45 @@ \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 +\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 multidimensional 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 multidimensional 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}, +\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 multidimensional 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 \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} @@ -1279,9 +1350,7 @@ \grammarterm{compound-statement}. If that user-written default constructor would be ill-formed, the program is ill-formed. -If that user-written default constructor would be constexpr-suitable\iref{dcl.constexpr}, -the implicitly-defined -default constructor is \keyword{constexpr}. +The implicitly-defined default constructor is constexpr. Before the defaulted default constructor for a class is implicitly defined, all the non-user-provided default constructors for its base classes and @@ -1433,14 +1502,15 @@ \end{example} \pnum -If the class definition does not explicitly declare a copy constructor, +If the class does not have a user-declared copy constructor +and the class is not an anonymous union, a non-explicit one is declared \defnx{implicitly}{constructor!copy!implicitly declared}. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defaulted\iref{dcl.fct.def}. The latter case is deprecated if the class has a user-declared copy assignment -operator or a user-declared destructor \iref{depr.impldec}. +operator or a user-declared destructor\iref{depr.impldec}. \pnum The implicitly-declared copy constructor for a class @@ -1473,10 +1543,13 @@ \pnum \indextext{constructor!move!implicitly declared}% -If the definition of a class \tcode{X} does not explicitly declare -a move constructor, a non-explicit one will be +If a class \tcode{X} does not have +a user-declared move constructor, a non-explicit one will be implicitly declared as defaulted if and only if \begin{itemize} +\item +\tcode{X} is not an anonymous union, + \item \tcode{X} does not have a user-declared copy constructor, @@ -1531,6 +1604,17 @@ an rvalue which can use the copy constructor instead. \end{note} +\pnum +\begin{note} +A \grammarterm{using-declaration} in a derived class \tcode{C} that +names a constructor from a base class +never suppresses the implicit declaration of +a copy/move constructor of \tcode{C}, +even if the base class constructor would be +a copy or move constructor +if declared as a member of \tcode{C}. +\end{note} + \pnum \indextext{constructor!copy!trivial}% \indextext{constructor!move!trivial}% @@ -1547,7 +1631,8 @@ and no virtual base classes\iref{class.mi}, and \item -the constructor selected to copy/move each direct base class subobject is trivial, and +the constructor selected to copy/move each direct base class subobject +is a direct member of that base class and is trivial, and \item for each non-static data member of @@ -1565,9 +1650,7 @@ The copy/move constructor is implicitly defined even if the implementation elided its odr-use\iref{term.odr.use,class.temporary}. \end{note} -If an implicitly-defined\iref{dcl.fct.def.default} constructor would be constexpr-suitable\iref{dcl.constexpr}, -the implicitly-defined -constructor is \keyword{constexpr}. +The implicitly-defined\iref{dcl.fct.def.default} constructor is constexpr. \pnum Before the defaulted copy/move constructor for a class is @@ -1652,8 +1735,8 @@ \tcode{X} only has a copy assignment operator with a non-object parameter of type \tcode{X\&}, -an expression of type const -\tcode{X} +an expression of type +\tcode{const X} cannot be assigned to an object of type \tcode{X}. \begin{example} @@ -1672,14 +1755,15 @@ \end{note} \pnum -If the class definition does not explicitly declare a copy assignment operator, +If the class does not have a user-declared copy assignment operator +and the class is not an anonymous union, one is declared \defnx{implicitly}{assignment operator!copy!implicitly declared}. -If the class definition declares a move +If the class has a user-declared move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defaulted\iref{dcl.fct.def}. The latter case is deprecated if the class has a user-declared copy constructor -or a user-declared destructor \iref{depr.impldec}. +or a user-declared destructor\iref{depr.impldec}. The implicitly-declared copy assignment operator for a class \tcode{X} will have the form @@ -1726,6 +1810,9 @@ move assignment operator, one will be implicitly declared as defaulted if and only if \begin{itemize} +\item +\tcode{X} is not an anonymous union, + \item \tcode{X} does not have a user-declared copy constructor, @@ -1786,9 +1873,8 @@ \item a direct non-static data member of class type \tcode{M} (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 - assignment operator, + that cannot be copied/moved because overload resolution\iref{over.match}, + as applied to find \tcode{M}'s corresponding assignment operator, 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. \end{itemize} @@ -1804,7 +1890,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 +1917,7 @@ and no virtual base classes\iref{class.mi}, and \item the assignment operator selected to copy/move each direct -base class subobject is trivial, and +base class subobject is a direct member of that base class and is trivial, and \item for each non-static data member of @@ -1844,7 +1930,7 @@ \defnx{non-trivial}{assignment operator!copy!non-trivial}. \pnum -An implicitly-defined\iref{dcl.fct.def.default} copy/move assignment operator is \keyword{constexpr}. +An implicitly-defined\iref{dcl.fct.def.default} copy/move assignment operator is constexpr. \pnum Before the defaulted copy/move assignment operator for a class is @@ -1961,7 +2047,8 @@ \indextext{generated destructor|see{destructor, default}}% \indextext{destructor!default}% If a class has no user-declared -prospective destructor, +prospective destructor +and the class is not an anonymous union, a prospective destructor is implicitly declared as defaulted\iref{dcl.fct.def}. An implicitly-declared prospective destructor is an @@ -1974,7 +2061,8 @@ \end{codeblock} \pnum -At the end of the definition of a class, +At the end of the definition of a class +other than an anonymous union, overload resolution is performed among the prospective destructors declared in that class with an empty argument list @@ -2022,25 +2110,40 @@ A defaulted destructor for a class \tcode{X} is defined as deleted if \begin{itemize} -\item any potentially constructed subobject has class type - \tcode{M} (or possibly multidimensional 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} @@ -2048,8 +2151,7 @@ \defnx{non-trivial}{destructor!non-trivial}. \pnum -A defaulted destructor is a constexpr destructor -if it is constexpr-suitable\iref{dcl.constexpr}. +A defaulted destructor is a constexpr destructor. \pnum Before a @@ -2233,7 +2335,7 @@ \pnum Once a destructor is invoked for an object, the object's lifetime ends; -the behavior is undefined if the destructor is invoked +the behavior is undefined\ubdef{class.dtor.no.longer.exists} if the destructor is invoked for an object whose lifetime has ended\iref{basic.life}. \begin{example} If the destructor for an object with automatic storage duration is explicitly invoked, @@ -2315,8 +2417,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} @@ -2367,13 +2467,6 @@ \end{example} \end{note} -\pnum -\begin{note} -A non-explicit copy/move constructor\iref{class.copy.ctor}, -including one implicitly declared, -is a converting constructor. -\end{note} - \rSec3[class.conv.fct]{Conversion functions}% \indextext{function!conversion}% \indextext{fundamental type conversion|see{conversion, user-defined}}% @@ -2551,7 +2644,6 @@ \begin{example} \begin{codeblock} struct S { - operator auto() const { return 10; } // OK template operator auto() const { return 1.2; } // error: conversion function template }; @@ -2677,7 +2769,7 @@ its declaration in the class definition can specify a \grammarterm{brace-or-equal-initializer} in which every \grammarterm{initializer-clause} that is an \grammarterm{assignment-expression} -is a constant expression\iref{expr.const}. +is a constant expression\iref{expr.const.const}. The member shall still be defined in a namespace scope if it is odr-used\iref{term.odr.use} in the program and the namespace scope definition shall not contain an \grammarterm{initializer}. @@ -3063,12 +3155,12 @@ 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 +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} @@ -3081,11 +3173,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} @@ -3117,7 +3209,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 @@ -3193,12 +3285,16 @@ an \defnx{anonymous union member}{member!anonymous union} if it is a non-static data member or an \defnx{anonymous union variable}{variable!anonymous union} otherwise. +Each object of such an unnamed type shall be such an unnamed object. \indextext{access control!anonymous \tcode{union}}% \indextext{restriction!anonymous \tcode{union}}% Each \grammarterm{member-declaration} in the \grammarterm{member-specification} -of an anonymous union shall either define one or more public non-static data members or +of an anonymous union shall define one or more public non-static data members, +be an \grammarterm{empty-declaration}, or be a \grammarterm{static_assert-declaration}. -Nested types, anonymous unions, and functions +Nested types +(including closure types\iref{expr.prim.lambda.closure} and anonymous unions) +and functions shall not be declared within an anonymous union. The names of the members of an anonymous union are bound in the scope inhabited by the union declaration. @@ -3401,7 +3497,12 @@ The class denoted by the \grammarterm{class-or-decltype} of a \grammarterm{base-specifier} is called a \defnadj{direct}{base class} -for the class being defined. +for the class being defined; +for each such \grammarterm{base-specifier}, +the corresponding \defnadj{direct base class}{relationship} +is the ordered pair (\tcode{D}, \tcode{B}) +where \tcode{D} is the class being defined and +\tcode{B} is the direct base class. \indextext{base class}% \indextext{derivation|see{inheritance}}% The lookup for the component name of @@ -3905,7 +4006,7 @@ \indextext{definition!virtual function}% A virtual function declared in a class shall be defined, or declared pure\iref{class.abstract} in that class, or both; no diagnostic is -required\iref{basic.def.odr}. +required\iref{basic.def.odr}\ifndrdef{class.virtual.pure.or.defined}. \indextext{friend!\tcode{virtual} and}% \pnum @@ -4020,10 +4121,9 @@ \indextext{function!virtual|)} \pnum -A \keyword{consteval} virtual function shall not override -a virtual function that is not \keyword{consteval}. -A \keyword{consteval} virtual function shall not be overridden by -a virtual function that is not \keyword{consteval}. +A non-immediate virtual function shall not be overridden by an immediate virtual function. +An immediate virtual function shall not be overridden by +a non-immediate virtual function. \rSec2[class.abstract]{Abstract classes}% @@ -4138,7 +4238,7 @@ \indextext{virtual function call!undefined pure}% the effect of making a virtual call\iref{class.virtual} to a pure virtual function directly or indirectly for the object being created (or -destroyed) from such a constructor (or destructor) is undefined.% +destroyed) from such a constructor (or destructor) is undefined\ubdef{class.abstract.pure.virtual}.% \indextext{derived class|)} \rSec1[class.access]{Member access control}% @@ -4232,9 +4332,10 @@ \end{codeblock} \end{example} \begin{note} -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. +Because access control applies to the declarations named, +if access control is applied to a type alias, +only the accessibility of the typedef or alias declaration itself is considered. +The accessibility of the underlying entity is not considered. \begin{example} \begin{codeblock} class A { @@ -4278,8 +4379,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; @@ -4287,8 +4388,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 { }; @@ -4625,10 +4726,18 @@ to a pointer to a private or protected immediate base class of \tcode{X}. \end{note} -The access to a member is affected by the class in which the member is -named. -This naming class is -the class in whose scope name lookup performed a search that found the member. +An expression $E$ that designates a member \tcode{m} +has a \defnadj{designating}{class} +that affects the access to \tcode{m}. +This designating class is either +\begin{itemize} +\item +the innermost class of which \tcode{m} is directly a member +if $E$ is a \grammarterm{splice-expression} or +\item +the class in whose scope name lookup performed a search +that found \tcode{m} otherwise. +\end{itemize} \begin{note} This class can be explicit, e.g., when a \grammarterm{qualified-id} @@ -4640,7 +4749,7 @@ \grammarterm{qualified-id} are used to name the member (as in \tcode{p->T::m}), -the class naming the member is the class denoted by the +the class designating the member is the class designated by the \grammarterm{nested-name-specifier} of the \grammarterm{qualified-id} @@ -4651,11 +4760,13 @@ \tcode{m} is accessible at the point \placeholder{R} -when named in class +when designated in class \tcode{N} if \begin{itemize} \item +\tcode{m} is designated by a \grammarterm{splice-expression}, or +\item \tcode{m} as a member of \tcode{N} @@ -4697,7 +4808,7 @@ \tcode{m} is accessible at \placeholder{R} -when named in class +when designated in class \tcode{B}. \begin{example} \begin{codeblock} @@ -4723,10 +4834,10 @@ left operand (considered as a pointer in the ``\tcode{.}'' operator case) cannot be implicitly converted to a -pointer to the naming class of the right operand. +pointer to the designating class of the right operand. \begin{note} This requirement is in addition to the requirement that -the member be accessible as named. +the member be accessible as designated. \end{note} \rSec2[class.friend]{Friends}% @@ -4827,7 +4938,7 @@ class X2 { friend Ct; // OK, \tcode{class C} is a friend friend D; // error: \tcode{D} not found - friend class D; // OK, elaborated-type-specifier declares new class + friend class D; // OK, \grammarterm{elaborated-type-specifier} declares new class }; template class R { @@ -5001,7 +5112,8 @@ \pnum An additional access check beyond those described earlier in \ref{class.access} is applied when a non-static data member or non-static member function is a -protected member of its naming class\iref{class.access.base}. +protected member of its designating class\iref{class.access.base} +and is not designated by a \grammarterm{splice-expression}. \begin{footnote} This additional check does not apply to other members, @@ -5010,9 +5122,11 @@ As described earlier, access to a protected member is granted because the reference occurs in a friend or direct member of some class \tcode{C}. If the access is to form a pointer to member\iref{expr.unary.op}, the -\grammarterm{nested-name-specifier} shall denote \tcode{C} or a class derived from -\tcode{C}. All other accesses involve a (possibly implicit) object -expression\iref{expr.ref}. In this case, the class of the object expression shall be +\grammarterm{nested-name-specifier} shall designate \tcode{C} or a class derived from +\tcode{C}. +Otherwise, if the access involves a (possibly implicit) +object expression\iref{expr.prim.id.general,expr.ref}, +the class of the object expression shall be \tcode{C} or a class derived from \tcode{C}. \begin{example} \begin{codeblock} @@ -5034,10 +5148,10 @@ pb->i = 1; // error p1->i = 2; // error p2->i = 3; // OK (access through a \tcode{D2}) - p2->B::i = 4; // OK (access through a \tcode{D2}, even though naming class is \tcode{B}) + p2->B::i = 4; // OK (access through a \tcode{D2}, even though designating class is \tcode{B}) int B::* pmi_B = &B::i; // error int B::* pmi_B2 = &D2::i; // OK (type of \tcode{\&D2::i} is \tcode{int B::*}) - B::j = 5; // error: not a friend of naming class \tcode{B} + B::j = 5; // error: not a friend of designating class \tcode{B} D2::j = 6; // OK (because refers to static member) } @@ -5223,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} @@ -5265,9 +5379,9 @@ Here, \tcode{x.i} -is initialized with 99, +is initialized with \tcode{99}, \tcode{x.f} -is initialized with 88.8, and +is initialized with \tcode{88.8}, and \tcode{complex::complex(double)} is called for the initialization of \tcode{x.c}. @@ -5348,7 +5462,7 @@ Unless the \grammarterm{mem-initializer-id} names the constructor's class, -a non-static data member of the constructor's class, or +a direct non-static data member of the constructor's class, or a direct or virtual base of that class, the \grammarterm{mem-initializer} @@ -5409,7 +5523,7 @@ The target constructor is selected by overload resolution. Once the target constructor returns, the body of the delegating constructor is executed. If a constructor delegates to itself directly or indirectly, -the program is ill-formed, no diagnostic required. +the program is ill-formed, no diagnostic required\ifndrdef{class.base.init.delegate.itself}. \begin{example} \begin{codeblock} struct C { @@ -5505,8 +5619,6 @@ class, thus its constructors never initialize virtual base classes, therefore the corresponding \grammarterm{mem-initializer}{s} can be omitted. \end{note} -An attempt to initialize more than one non-static data member of a union renders the -program ill-formed. \indextext{initialization!const member}% \indextext{initialization!reference member}% \begin{note} @@ -5542,6 +5654,18 @@ \end{codeblock} \end{example} +\pnum +An attempt to initialize more than one non-static data member of a union renders the +program ill-formed. + +\pnum +An object's initialization is considered complete when +a non-delegating constructor for that object returns. +\begin{note} +Therefore, an object's lifetime can begin\iref{basic.life} +before all delegating constructors have completed. +\end{note} + \pnum If a given non-static data member has both a default member initializer and a \grammarterm{mem-initializer}, the initialization specified by the @@ -5704,18 +5828,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\ubdef{class.base.init.mem.fun}. \begin{example} \begin{codeblock} class A { @@ -5912,9 +6045,10 @@ \indextext{destruction!member access}% For an object with a non-trivial constructor, referring to any non-static member or base class of the object before the constructor begins execution results in -undefined behavior. For an object with a non-trivial destructor, referring to +undefined behavior\ubdef{class.cdtor.before.ctor}. +For an object with a non-trivial destructor, referring to any non-static member or base class of the object after the destructor finishes -execution results in undefined behavior. +execution results in undefined behavior\ubdef{class.cdtor.after.dtor}. \begin{example} \begin{codeblock} struct X { int i; }; @@ -5948,12 +6082,13 @@ \end{example} \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 +During the initialization of an object, +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; @@ -5998,7 +6133,7 @@ indirectly derive from \tcode{B} shall have started and the destruction of these classes shall not have -completed, otherwise the conversion results in undefined behavior. +completed, otherwise the conversion results in undefined behavior\ubdef{class.cdtor.convert.pointer}. To form a pointer to (or access the value of) a direct non-static member of an object \tcode{obj}, @@ -6006,7 +6141,7 @@ \tcode{obj} shall have started and its destruction shall not have completed, otherwise the computation of the pointer value (or accessing the member -value) results in undefined behavior. +value) results in undefined behavior\ubdef{class.cdtor.form.pointer}. \begin{example} \begin{codeblock} struct A { }; @@ -6038,6 +6173,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 @@ -6047,7 +6185,7 @@ and the object expression refers to the complete object of \tcode{x} or one of that object's base class subobjects but not \tcode{x} or one of its base class subobjects, the behavior -is undefined. +is undefined\ubdef{class.cdtor.virtual.not.x}. \begin{example} \begin{codeblock} struct V { @@ -6104,7 +6242,7 @@ \tcode{typeid} refers to the object under construction or destruction and the static type of the operand is neither the constructor or destructor's class nor one of its -bases, the behavior is undefined. +bases, the behavior is undefined\ubdef{class.cdtor.typeid}. \pnum \indextext{construction!dynamic cast and}% @@ -6129,7 +6267,7 @@ the operand is not a pointer to or object of the constructor or destructor's own class or one of its bases, the \keyword{dynamic_cast} -results in undefined behavior. +results in undefined behavior\ubdef{class.cdtor.dynamic.cast}. \begin{example} \begin{codeblock} struct V { @@ -6234,7 +6372,7 @@ \end{itemize} Copy elision is not permitted where an expression is evaluated in a context -requiring a constant expression\iref{expr.const} +requiring a constant expression\iref{expr.const.const} and in constant initialization\iref{basic.start.static}. \begin{note} It is possible that copy elision is performed @@ -6270,7 +6408,7 @@ } constexpr A a; // well-formed, \tcode{a.p} points to \tcode{a} -constexpr A b = g(); // error: \tcode{b.p} would be dangling\iref{expr.const} +constexpr A b = g(); // error: \tcode{b.p} would be dangling\iref{expr.const.const} void h() { A c = g(); // well-formed, \tcode{c.p} can point to \tcode{c} or be dangling @@ -6481,11 +6619,11 @@ \end{note} \pnum -The direct base class subobjects of \tcode{C}, +The direct base class subobjects of an object \tcode{x} of class \tcode{C}, in the order of their declaration in the \grammarterm{base-specifier-list} of \tcode{C}, -followed by the non-static data members of \tcode{C}, +followed by the direct member subobjects of \tcode{x}, in the order of their declaration in the \grammarterm{member-specification} of \tcode{C}, -form a list of subobjects. +form a list of subobjects for \tcode{x}. In that list, any subobject of array type is recursively expanded to the sequence of its elements, in the order of increasing subscript. Let $\tcode{x}_i$ be an lvalue denoting the $i^\text{th}$ element @@ -6551,7 +6689,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 23ba5e4f8d..f5910a9dd3 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -1,6 +1,87 @@ %!TEX root = std.tex \infannex{diff}{Compatibility} +\rSec1[diff.cpp26]{\Cpp{} and ISO \CppXXVI{}} + +\rSec2[diff.cpp26.general]{General} + +\pnum +\indextext{summary!compatibility with ISO \CppXXVI{}}% +Subclause \ref{diff.cpp26} lists the differences between \Cpp{} and +ISO \CppXXVI{}, +by the chapters of this document. + +\rSec2[diff.cpp26.basic]{\ref*{basic}: basics} + +\diffref{basic.stc.dynamic.deallocation} +\change +Potentially throwing exception specifications +on deallocation functions are ill-formed. +\rationale +Removes potential undefined behavior. +\effect +Valid \CppXXVI{} code that declares a deallocation function +with a potentially throwing exception specification +becomes ill-formed. +\begin{example} +\begin{codeblock} +struct T { + void operator delete(void *) noexcept(false); // ill-formed; previously well-formed +}; +\end{codeblock} +\end{example} + +\rSec2[diff.cpp26.dcl]{\ref*{dcl}: declarations} + +\diffref{dcl.init} +\change +Support for designated initialization of base classes of aggregates. +\rationale +New functionality. +\effect +Some valid \CppXXVI{} code may fail to compile. +\begin{example} +\begin{codeblock} +struct A { int a; }; +struct B : A { int b; }; + +void f(A); // \#1 +void f(B); // \#2 + +void g() { + f({.a=1}); // ambiguous between \#1 and \#2; previously called \#1 +} +\end{codeblock} +\end{example} + +\diffref{dcl.fct.def.default} +\change +It is no longer valid +for explicitly defaulted assignment operators to have a +\grammarterm{cv-qualifier-seq} or \tcode{\&\&} \grammarterm{ref-qualifier}, or +for an explicitly defaulted move assignment operator +to have a parameter of type ``reference to \tcode{T}'' +where \tcode{T} is cv-qualified. +\rationale +Removal of rarely-used and confusing feature. +\effect +A valid \CppXXVI{} program +which uses these features on an explicitly defaulted assignment operator +is ill-formed. +\begin{example} +\begin{codeblock} +struct S { + S& operator=(const S&) && = default; // ill-formed; previously well-formed +}; +struct T { + T& operator=(const T&) const = default; // ill-formed; previously well-formed but deleted +}; +struct U { + U& operator=(const U&&) = default; // ill-formed; previously well-formed but deleted +}; +\end{codeblock} +\end{example} + \rSec1[diff.cpp23]{\Cpp{} and ISO \CppXXIII{}} \rSec2[diff.cpp23.general]{General} @@ -11,7 +92,40 @@ ISO \CppXXIII{}, by the chapters of this document. -\rSec2[diff.cpp23.expr]{\ref{expr}: expressions} +\rSec2[diff.cpp23.lex]{\ref*{lex}: lexical conventions} + +\diffref{lex.operators} +\change +New operator \tcode{\caret\caret}. +\rationale +Required for new features. +\effect +Valid \CppXXIII{} code that contains two consecutive \tcode{\caret} tokens +can be ill-formed in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +struct C { int operator^(int); }; +int operator^(int (C::*p)(int), C); +int i = &C::operator^^C{}; // ill-formed; previously well-formed +\end{codeblock} +\end{example} + +\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} \change @@ -72,7 +186,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp23.dcl.dcl]{\ref*{dcl}: declarations} \diffref{dcl.init.list} \change @@ -109,13 +223,30 @@ template void g(T... ptr[1]); int main() { - f(nullptr, nullptr); // ill-formed, previously \tcode{void f(int [1], double [1])} + f(nullptr, nullptr); // ill-formed, + // previously \tcode{void f(int [1], double [1])} g(nullptr, nullptr); // ok } \end{codeblock} \end{example} -\rSec2[diff.cpp23.temp]{\ref{temp}: templates} +\diffref{dcl.attr.grammar} +\change +New token \tcode{:]}. +\rationale +Required for new features. +\effect +Valid \CppXXIII{} code that contained an \grammarterm{attribute-specifier} +with an \grammarterm{attribute-using-prefix} +but no attributes and no whitespace is ill-formed in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +struct [[using CC:]] C; // ill-formed; previously well-formed +struct [[using DD: ]] D; // OK +\end{codeblock} +\end{example} + +\rSec2[diff.cpp23.temp]{\ref*{temp}: templates} \diffref{temp.constr} \change @@ -173,7 +304,24 @@ type deductions from \#2 and \#3 both succeed. \end{example} -\rSec2[diff.cpp23.library]{\ref{library}: library introduction} +\rSec2[diff.cpp23.cpp]{\ref*{cpp}: preprocessing directives} + +\diffref{cpp.replace.general} +\change +Additional restrictions on macro names. +\rationale +Avoid hard to diagnose or non-portable constructs. +\effect +Keywords, +names of identifiers with special meaning\iref{lex.name}, +and (unless otherwise specified) \grammarterm{attribute-token}{s} +specified in \ref{dcl.attr} +may not be used as macro names. +For example, valid \CppXXIII{} code that +defines \tcode{post} or \tcode{pre} as macros +is invalid in this revision of \Cpp{}. + +\rSec2[diff.cpp23.library]{\ref*{library}: library introduction} \diffref{headers} \change @@ -182,17 +330,34 @@ 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{meta}, \libheaderref{rcu}, -\libheaderref{simd}, and +\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{}. -\rSec2[diff.cpp23.strings]{\ref{strings}: strings library} +\rSec2[diff.cpp23.mem]{\ref*{mem}: memory management library} + +\diffref{c.malloc} +\change +Calling \tcode{realloc} with a non-null pointer and zero size +has erroneous behavior. +\rationale +The C standard library does not define this behavior. +\effect +Valid \CppXXIII{} code that calls \tcode{realloc} +with a non-null pointer and a size of zero is erroneous and may change behavior. + +\rSec2[diff.cpp23.strings]{\ref*{strings}: strings library} \diffref{string.conversions} \change @@ -211,33 +376,29 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp23.containers]{\ref{containers}: containers library} +\rSec2[diff.cpp23.io]{\ref*{input.output}: input/output library} -\diffref{span.overview} +\diffref{istream.unformatted} \change -\tcode{span} is constructible from \tcode{initializer_list}. +Overloaded \tcode{std::basic_istream::ignore}. \rationale -Permit passing a braced initializer list to a function taking \tcode{span}. +Allow \tcode{char} values to be used as delimiters. \effect -Valid \CppXXIII{} code that relies on the lack of this constructor -may refuse to compile, or change behavior in this revision of \Cpp{}. +Calls to \tcode{istream::ignore} with a second argument of \tcode{char} type +can change behavior. +Calls to \tcode{istream::ignore} with a second argument that is neither +\tcode{int} nor \tcode{char} type can become ill-formed. \begin{example} \begin{codeblock} -void one(pair); // \#1 -void one(span); // \#2 -void t1() { one({1, 2}); } // ambiguous between \#1 and \#2; previously called \#1 - -void two(span); -void t2() { two({{1, 2}}); } // ill-formed; previously well-formed - -void *a[10]; -int x = span{a, 0}.size(); // \tcode{x} is \tcode{2}; previously \tcode{0} -any b[10]; -int y = span{b, b + 10}.size(); // \tcode{y} is \tcode{2}; previously \tcode{10} +std::istringstream in("\xF0\x9F\xA4\xA1 Clown Face"); +in.ignore(100, '\xA1'); // ignore up to \tcode{'\textbackslash{}xA1'} delimiter, + // previously might have ignored to EOF +in.ignore(100, -1L); // ambiguous overload, + // previously equivalent to \tcode{(int)-1L} \end{codeblock} \end{example} -\rSec2[diff.cpp23.depr]{\ref{depr}: compatibility features} +\rSec2[diff.cpp23.depr]{\ref*{depr}: compatibility features} \nodiffref \change @@ -350,9 +511,11 @@ in addition to those listed above, by the chapters of this document. -\rSec2[diff.cpp20.lex]{\ref{lex}: lexical conventions} +\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 @@ -379,7 +542,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp20.expr]{\ref{expr}: expressions} +\rSec2[diff.cpp20.expr]{\ref*{expr}: expressions} \diffref{expr.prim.id.unqual} \change @@ -411,7 +574,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp20.stmt]{\ref{stmt.stmt}: statements} +\rSec2[diff.cpp20.stmt]{\ref*{stmt}: statements} \diffref{stmt.ranged} \change @@ -435,7 +598,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp20.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp20.dcl]{\ref*{dcl}: declarations} \diffref{dcl.init.string} \change @@ -466,7 +629,36 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp20.temp]{\ref{temp}: templates} +\rSec2[diff.cpp20.over]{\ref*{over}: overloading} + +\diffref{over.match.class.deduct} +\change +Deducing class template arguments from inherited constructors. +\rationale +Making class template argument deduction consistent with construction. +\effect +Valid ISO \CppXX{} code may become ill-formed or change meaning +in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +template +struct B { + B(T); +}; + +template +struct D : B { + D(T); + using B::B; + T m = "a"; // \#1 +}; + +D d(""); // ill-formed at \#1 (\tcode{T} deduced as \tcode{const char}); + // previously well-formed (\tcode{T} deduced as \tcode{const char*}) +\end{codeblock} +\end{example} + +\rSec2[diff.cpp20.temp]{\ref*{temp}: templates} \diffref{temp.deduct.type} \change @@ -486,7 +678,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp20.library]{\ref{library}: library introduction} +\rSec2[diff.cpp20.library]{\ref*{library}: library introduction} \diffref{headers} \change @@ -508,7 +700,7 @@ Valid \CppXX{} code that \tcode{\#include}{s} headers with these names may be invalid in this revision of \Cpp{}. -\rSec2[diff.cpp20.concepts]{\ref{concepts}: concepts library} +\rSec2[diff.cpp20.concepts]{\ref*{concepts}: concepts library} \diffref{cmp.concept,concept.equalitycomparable,concept.totallyordered} \change @@ -537,7 +729,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp20.memory]{\ref{mem}: memory management library} +\rSec2[diff.cpp20.memory]{\ref*{mem}: memory management library} \diffref{allocator.traits.general} \change @@ -551,7 +743,7 @@ that partially or explicitly specializes \tcode{allocator_traits} is ill-formed with no diagnostic required in this revision of \Cpp{}. -\rSec2[diff.cpp20.utilities]{\ref{utilities}: general utilities library} +\rSec2[diff.cpp20.utilities]{\ref*{utilities}: general utilities library} \diffref{format} \change @@ -627,7 +819,7 @@ Valid \CppXX{} code that instantiated the removed specialization can become ill-formed. -\rSec2[diff.cpp20.strings]{\ref{strings}: strings library} +\rSec2[diff.cpp20.strings]{\ref*{strings}: strings library} \diffref{string.classes} \change @@ -651,7 +843,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp20.containers]{\ref{containers}: containers library} +\rSec2[diff.cpp20.containers]{\ref*{containers}: containers library} \diffref{associative.reqmts,unord.req} \change @@ -675,7 +867,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp20.thread]{\ref{thread}: concurrency support library} +\rSec2[diff.cpp20.thread]{\ref*{thread}: concurrency support library} \diffref{thread.barrier} \change @@ -721,7 +913,7 @@ in addition to those listed above, by the chapters of this document. -\rSec2[diff.cpp17.lex]{\ref{lex}: lexical conventions} +\rSec2[diff.cpp17.lex]{\ref*{lex}: lexical conventions} \diffref{lex.pptoken,module.unit,module.import,cpp.pre,cpp.module,cpp.import} \change @@ -783,7 +975,7 @@ prevent unintended dynamic initialization\iref{dcl.constinit}. \item The \keyword{co_await}, \keyword{co_yield}, and \keyword{co_return} keywords are added -to enable the definition of coroutines \iref{dcl.fct.def.coroutine}. +to enable the definition of coroutines\iref{dcl.fct.def.coroutine}. \item The \tcode{requires} keyword is added to introduce constraints through a \grammarterm{requires-clause}\iref{temp.pre} @@ -853,7 +1045,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp17.basic]{\ref{basic}: basics} +\rSec2[diff.cpp17.basic]{\ref*{basic}: basics} \diffref{basic.life} \change @@ -888,7 +1080,7 @@ no longer provides any ``happens before'' guarantees, even in the absence of intervening stores by another thread. -\rSec2[diff.cpp17.expr]{\ref{expr}: expressions} +\rSec2[diff.cpp17.expr]{\ref*{expr}: expressions} \diffref{expr.prim.lambda.capture} \change @@ -902,7 +1094,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 @@ -1003,7 +1195,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp17.class]{\ref{class}: classes} +\rSec2[diff.cpp17.class]{\ref*{class}: classes} \diffref{class.ctor,class.conv.fct} \change @@ -1094,7 +1286,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp17.over]{\ref{over}: overloading} +\rSec2[diff.cpp17.over]{\ref*{over}: overloading} \diffref{over.match.oper} \change @@ -1153,7 +1345,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp17.temp]{\ref{temp}: templates} +\rSec2[diff.cpp17.temp]{\ref*{temp}: templates} \diffref{temp.names} \change @@ -1186,7 +1378,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp17.except]{\ref{except}: exception handling} +\rSec2[diff.cpp17.except]{\ref*{except}: exception handling} \diffref{except.spec} \change @@ -1207,7 +1399,7 @@ a different token sequence in each case. \end{note} -\rSec2[diff.cpp17.library]{\ref{library}: library introduction} +\rSec2[diff.cpp17.library]{\ref*{library}: library introduction} \diffref{headers} \change @@ -1265,7 +1457,7 @@ can simply be removed. \end{itemize} -\rSec2[diff.cpp17.containers]{\ref{containers}: containers library} +\rSec2[diff.cpp17.containers]{\ref*{containers}: containers library} \diffref{forward.list,list} \change @@ -1278,7 +1470,7 @@ Translation units compiled against this version of \Cpp{} may be incompatible with translation units compiled against \CppXVII{}, either failing to link or having undefined behavior. -\rSec2[diff.cpp17.iterators]{\ref{iterators}: iterators library} +\rSec2[diff.cpp17.iterators]{\ref*{iterators}: iterators library} \diffref{iterator.traits} \change @@ -1291,7 +1483,7 @@ A valid \CppXVII{} program that relies on the presence of the typedefs may fail to compile, or have different behavior. -\rSec2[diff.cpp17.alg.reqs]{\ref{algorithms}: algorithms library} +\rSec2[diff.cpp17.alg.reqs]{\ref*{algorithms}: algorithms library} \diffref{algorithms.requirements} \change @@ -1305,7 +1497,7 @@ algorithms not explicitly specified to allow such in this version of \Cpp{} may fail to compile or have undefined behavior. -\rSec2[diff.cpp17.input.output]{\ref{input.output}: input/output library} +\rSec2[diff.cpp17.input.output]{\ref*{input.output}: input/output library} \diffref{istream.extractors} \change @@ -1380,7 +1572,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp17.depr]{\ref{depr}: compatibility features} +\rSec2[diff.cpp17.depr]{\ref*{depr}: compatibility features} \nodiffref \change @@ -1461,7 +1653,7 @@ Remove deprecated type traits. \rationale The traits had unreliable or awkward interfaces. The \tcode{is_literal_type} -trait provided no way to detect which subset of constructors and member +trait provided no way to detect which subset of member functions of a type were declared \keyword{constexpr}. The \tcode{result_of} trait had a surprising syntax that did not directly support function types. It has been superseded by the \tcode{invoke_result} trait. @@ -1481,7 +1673,7 @@ in addition to those listed above, by the chapters of this document. -\rSec2[diff.cpp14.lex]{\ref{lex}: lexical conventions} +\rSec2[diff.cpp14.lex]{\ref*{lex}: lexical conventions} \diffref{lex.phases} \indextext{trigraph sequence}% @@ -1493,8 +1685,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} @@ -1515,7 +1708,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp14.expr]{\ref{expr}: expressions} +\rSec2[diff.cpp14.expr]{\ref*{expr}: expressions} \diffref{expr.post.incr,expr.pre.incr} \change @@ -1541,7 +1734,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}% @@ -1612,7 +1805,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp14.class]{\ref{class}: classes} +\rSec2[diff.cpp14.class]{\ref*{class}: classes} \diffref{class.inhctor.init} \change @@ -1641,16 +1834,16 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp14.temp]{\ref{temp}: templates} +\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{}. @@ -1665,7 +1858,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp14.except]{\ref{except}: exception handling} +\rSec2[diff.cpp14.except]{\ref*{except}: exception handling} \diffref{except.spec} \change @@ -1688,7 +1881,7 @@ and it is unspecified whether stack unwinding is performed prior to such a call. -\rSec2[diff.cpp14.library]{\ref{library}: library introduction} +\rSec2[diff.cpp14.library]{\ref*{library}: library introduction} \diffref{headers} \change @@ -1722,7 +1915,7 @@ Valid \CppXIV{} code that uses such a top-level namespace, e.g., \tcode{std2}, may be invalid in this revision of \Cpp{}. -\rSec2[diff.cpp14.utilities]{\ref{utilities}: general utilities library} +\rSec2[diff.cpp14.utilities]{\ref*{utilities}: general utilities library} \diffref{func.wrap} \change @@ -1752,7 +1945,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp14.string]{\ref{strings}: strings library} +\rSec2[diff.cpp14.string]{\ref*{strings}: strings library} \diffref{basic.string} \change @@ -1776,7 +1969,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp14.containers]{\ref{containers}: containers library} +\rSec2[diff.cpp14.containers]{\ref*{containers}: containers library} \diffref{associative.reqmts} \change @@ -1806,7 +1999,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp14.depr]{\ref{depr}: compatibility features} +\rSec2[diff.cpp14.depr]{\ref*{depr}: compatibility features} \nodiffref \change @@ -1850,7 +2043,7 @@ in addition to those listed above, by the chapters of this document. -\rSec2[diff.cpp11.lex]{\ref{lex}: lexical conventions} +\rSec2[diff.cpp11.lex]{\ref*{lex}: lexical conventions} \diffref{lex.ppnumber} \change @@ -1872,7 +2065,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp11.basic]{\ref{basic}: basics} +\rSec2[diff.cpp11.basic]{\ref*{basic}: basics} \diffref{basic.stc.dynamic.deallocation} \change @@ -1892,7 +2085,7 @@ program is ill-formed, as it was for class member allocation functions and deallocation functions\iref{expr.new}. -\rSec2[diff.cpp11.expr]{\ref{expr}: expressions} +\rSec2[diff.cpp11.expr]{\ref*{expr}: expressions} \diffref{expr.cond} \change @@ -1927,7 +2120,7 @@ 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 @@ -1973,7 +2166,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp11.library]{\ref{library}: library introduction} +\rSec2[diff.cpp11.library]{\ref*{library}: library introduction} \diffref{headers} \change @@ -1985,7 +2178,7 @@ Valid \CppXI{} code that \tcode{\#include}{s} a header with that name may be invalid in this revision of \Cpp{}. -\rSec2[diff.cpp11.input.output]{\ref{input.output}: input/output library} +\rSec2[diff.cpp11.input.output]{\ref*{input.output}: input/output library} \diffref{c.files} \change @@ -2007,7 +2200,7 @@ in addition to those listed above, by the chapters of this document. -\rSec2[diff.cpp03.lex]{\ref{lex}: lexical conventions} +\rSec2[diff.cpp03.lex]{\ref*{lex}: lexical conventions} \diffref{lex.pptoken} \change @@ -2075,7 +2268,7 @@ Certain integer literals larger than can be represented by \tcode{long} could change from an unsigned integer type to \tcode{signed long long}. -\rSec2[diff.cpp03.expr]{\ref{expr}: expressions} +\rSec2[diff.cpp03.expr]{\ref*{expr}: expressions} \diffref{conv.ptr} \change @@ -2169,7 +2362,7 @@ \end{codeblock} \end{example} -\rSec2[diff.cpp03.dcl.dcl]{\ref{dcl.dcl}: declarations} +\rSec2[diff.cpp03.dcl.dcl]{\ref*{dcl}: declarations} \diffref{dcl.spec} \change @@ -2202,7 +2395,7 @@ \diffref{dcl.link} \change -Names declared in an anonymous namespace +Names declared in an unnamed namespace changed from external linkage to internal linkage; language linkage applies to names with external linkage only. \rationale @@ -2222,7 +2415,7 @@ in this revision of \Cpp{}, violating the one-definition rule. \end{example} -\rSec2[diff.cpp03.class]{\ref{class}: classes} +\rSec2[diff.cpp03.class]{\ref*{class}: classes} \diffref{class.default.ctor,class.dtor,class.copy.ctor,class.copy.assign} \change @@ -2246,7 +2439,7 @@ (without calling \tcode{std::unexpected}) if their exception specification is non-throwing. -\rSec2[diff.cpp03.temp]{\ref{temp}: templates} +\rSec2[diff.cpp03.temp]{\ref*{temp}: templates} \diffref{temp.param} \change @@ -2288,7 +2481,7 @@ A valid \CppIII{} program can get a different result in this revision of \Cpp{}. -\rSec2[diff.cpp03.library]{\ref{library}: library introduction} +\rSec2[diff.cpp03.library]{\ref*{library}: library introduction} \pnum \textbf{Affected:} \ref{library} -- \ref{\lastlibchapter} @@ -2358,18 +2551,18 @@ \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}: +\rSec2[diff.cpp03.language.support]{\ref*{support}: language support library} \diffref{new.delete.single} @@ -2386,7 +2579,7 @@ because the exception specification of \tcode{throw(std::bad_alloc)} was removed. -\rSec2[diff.cpp03.diagnostics]{\ref{diagnostics}: diagnostics library} +\rSec2[diff.cpp03.diagnostics]{\ref*{diagnostics}: diagnostics library} \diffref{errno} \change @@ -2398,7 +2591,7 @@ \tcode{errno} being the same across threads may change behavior in this revision of \Cpp{}. -\rSec2[diff.cpp03.utilities]{\ref{utilities}: general utilities library} +\rSec2[diff.cpp03.utilities]{\ref*{utilities}: general utilities library} \diffref{refwrap,arithmetic.operations,comparisons,logical.operations,bitwise.operations} \change @@ -2412,7 +2605,7 @@ \tcode{unary_function} or \tcode{binary_function} may fail to compile in this revision of \Cpp{}. -\rSec2[diff.cpp03.strings]{\ref{strings}: strings library} +\rSec2[diff.cpp03.strings]{\ref*{strings}: strings library} \diffref{string.classes} \change @@ -2434,7 +2627,7 @@ Some \keyword{const} member functions, such as \tcode{data} and \tcode{c_str}, no longer invalidate iterators. -\rSec2[diff.cpp03.containers]{\ref{containers}: containers library} +\rSec2[diff.cpp03.containers]{\ref*{containers}: containers library} \diffref{container.requirements} \change @@ -2526,7 +2719,7 @@ by value, and an additional overload of \tcode{resize} has been added. Valid \CppIII{} code that uses this function may fail to compile with this revision of \Cpp{}. -\rSec2[diff.cpp03.algorithms]{\ref{algorithms}: algorithms library} +\rSec2[diff.cpp03.algorithms]{\ref*{algorithms}: algorithms library} \diffref{algorithms.general} \change @@ -2540,7 +2733,7 @@ \tcode{std::remove_if} may leave the tail of the input sequence with a different set of values than previously. -\rSec2[diff.cpp03.numerics]{\ref{numerics}: numerics library} +\rSec2[diff.cpp03.numerics]{\ref*{numerics}: numerics library} \diffref{complex.numbers} \change @@ -2552,17 +2745,17 @@ binary representation of the required template specializations of \tcode{std::complex} may not be compatible with this revision of \Cpp{}. -\rSec2[diff.cpp03.locale]{\ref{localization}: localization library} +\rSec2[diff.cpp03.locale]{\ref*{localization}: localization library} \diffref{facet.num.get.virtuals} \change -The \tcode{num_get} facet recognizes hexadecimal floating point values. +The \tcode{num_get} facet recognizes hexadecimal floating-point values. \rationale Required by new feature. \effect Valid \CppIII{} code may have different behavior in this revision of \Cpp{}. -\rSec2[diff.cpp03.input.output]{\ref{input.output}: input/output library} +\rSec2[diff.cpp03.input.output]{\ref*{input.output}: input/output library} \diffref{istream.sentry,ostream.sentry,iostate.flags} \change @@ -2625,11 +2818,11 @@ in addition to those listed above, by the chapters of this document. -\rSec2[diff.lex]{\ref{lex}: lexical conventions} +\rSec2[diff.lex]{\ref*{lex}: lexical conventions} \diffref{lex.key} \change -New Keywords\\ +New keywords.\\ New keywords are added to \Cpp{}; see \ref{lex.key}. \rationale @@ -2730,11 +2923,11 @@ Programs that have a legitimate reason to treat string literal objects as potentially modifiable memory are probably rare. -\rSec2[diff.basic]{\ref{basic}: basics} +\rSec2[diff.basic]{\ref*{basic}: basics} \diffref{basic.def} \change -\Cpp{} does not have ``tentative definitions'' as in C.\\ +\Cpp{} does not have ``tentative definitions'' as in C. \begin{example} At file scope, \begin{codeblock} @@ -2825,11 +3018,10 @@ \diffref{basic.types} \change -C allows ``compatible types'' in several places, \Cpp{} does not.\\ +C allows mixing between ``compatible types'' in several places where \Cpp{} does not.\\ For example, -otherwise-identical \keyword{struct} types with different tag names -are ``compatible'' in C but are distinctly different types -in \Cpp{}. +enumerated types are ``compatible'' with their underlying types in C but, in \Cpp{}, +enumerations are types distinct from their underlying types. \rationale Stricter type checking is essential for \Cpp{}. \effect @@ -2837,19 +3029,19 @@ \difficulty Semantic transformation. The ``typesafe linkage'' mechanism will find many, but not all, -of such problems. -Those problems not found by typesafe linkage will continue to -function properly, +such problems. +Some cases are allowed by \Cpp{} according to the ``layout compatibility rules'' of this document. \howwide Common. -\rSec2[diff.expr]{\ref{expr}: expressions} +\rSec2[diff.expr]{\ref*{expr}: expressions} \diffref{conv.ptr} \change -Converting \tcode{\keyword{void}*} to a pointer-to-object type requires casting. +Converting a prvalue of type ``pointer to \cv{} \tcode{void}'' +to a pointer-to-object type requires casting. \begin{example} \begin{codeblock} char a[10]; @@ -2859,7 +3051,7 @@ } \end{codeblock} -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} @@ -2878,10 +3070,7 @@ \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 C translators will give a warning -if the cast is not used. +Common. \diffref{expr.arith.conv} \change @@ -2914,6 +3103,43 @@ \howwide Uncommon. +\diffref{expr.arith.conv} +\change +The usual arithmetic conversions differ, between C and \Cpp{}, +in the treatment of enumeration types with no fixed underlying type. +In \Cpp{}, values of such types are not specified +as converting to the underlying type of the enumeration +as part of the usual arithmetic conversions. +Instead, integral promotions\iref{conv.prom} +based on the values of the enumeration\iref{dcl.enum} are applied. +\rationale +Avoids the difference that can arise in C +when replacing an enumeration constant in +an expression with a cast of the same enumeration constant +to the enumeration type. +Allows \Cpp{} to treat an enumerator with behavior +like that of \keyword{int} +even while giving the enumerator the type of its enumeration. +\effect +Changes to semantics of well-defined feature. +Some C expressions that have a dependence upon +the implementation-defined +underlying type of affected enumeration types +will yield different results +(as they would if a different underlying type +is chosen by the C implementation). +\begin{example} +\begin{codeblock} +typedef enum { E0 } E; // the underlying type of \tcode{E} can be \tcode{unsigned int} +static_assert(((E)E0 - 1 < 0) == (E0 - 1 < 0), "Must pass for C++"); +\end{codeblock} +The \tcode{static_assert} may fail in C. +\end{example} +\difficulty +Programs must add explicit casts to the underlying type. +\howwide +Rare. + \diffref{expr.post.incr,expr.pre.incr} \change Decrement operator is not allowed with \keyword{bool} operand. @@ -2925,6 +3151,33 @@ (for instance, via the C typedef in \libheaderref{stdbool.h}) is ill-formed in \Cpp{}. +\diffref{expr.unary.op} +\change +In certain contexts, +taking the address of a dereferenced null or past-the-end pointer value +is well-defined in C (and yields the original pointer value), +but results in undefined behavior in \Cpp{}. +\begin{example} +\begin{codeblock} +void f() { + char *p = nullptr; + char *p2 = &*p; // well-defined in C, undefined behavior in \Cpp{} + char *p3 = &p[0]; // well-defined in C, undefined behavior in \Cpp{} + int a[5]; + int *q = &a[5]; // well-defined in C, undefined behavior in \Cpp{} +} +\end{codeblock} +\end{example} +\rationale +Consistent treatment of lvalues in \Cpp{}. +\effect +Well-formed and well-defined C code exhibits undefined behavior in \Cpp{}. +\difficulty +Syntactic transformation to pointer arithmetic +and possible addition of a check for null pointer values. +\howwide +Occasionally. + \diffref{expr.sizeof,expr.cast} \change In \Cpp{}, types can only be defined in declarations, not in expressions.\\ @@ -2962,14 +3215,14 @@ \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++ +int same = arr1 == arr2; // valid C, ill-formed \Cpp{} +int idem = arr1 == +arr2; // valid \Cpp{}, constraint violation in C \end{codeblock} \end{example} \howwide Rare. -\diffref{expr.cond,expr.ass,expr.comma} +\diffref{expr.cond,expr.assign,expr.comma} \indextext{conversion!lvalue-to-rvalue}% \indextext{rvalue!lvalue conversion to}% \indextext{lvalue}% @@ -2999,7 +3252,7 @@ \howwide Rare. -\rSec2[diff.stat]{\ref{stmt.stmt}: statements} +\rSec2[diff.stat]{\ref*{stmt}: statements} \diffref{stmt.switch,stmt.goto} \change @@ -3047,7 +3300,25 @@ 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.pre} +\change +In \Cpp{}, no declaration of a variable can have \cv{} \tcode{void} type. +In C, this is allowed, unless the declaration is a definition. +\begin{example} +\begin{codeblock} +extern void x; // valid C, invalid in \Cpp{} +\end{codeblock} +\end{example} +\rationale +Stricter type checking in \Cpp{}. +\effect +Deletion of semantically well-defined feature. +\difficulty +Syntactic transformation. +\howwide +Seldom. \diffref{dcl.stc} \change @@ -3315,14 +3586,15 @@ \diffref{dcl.enum} \change -In \Cpp{}, the type of an enumerator is its enumeration. In C, the type of an enumerator is \keyword{int}. +In \Cpp{}, the type of an enumerator is its enumeration. In C, the type of an enumerator is an integer type. \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)@ */ +void f() { + auto x = A; + int *p = &x; // valid C, invalid \Cpp{} +} \end{codeblock} \end{example} @@ -3334,10 +3606,6 @@ Semantic transformation. \howwide Seldom. -The only time this affects existing C code is when the size of an -enumerator is taken. -Taking the size of an enumerator is not a -common C coding practice. \diffref{dcl.align} \change @@ -3362,7 +3630,7 @@ \howwide Seldom. -\rSec2[diff.class]{\ref{class}: classes} +\rSec2[diff.class]{\ref*{class}: classes} \diffref{class.name} [see also \ref{dcl.typedef}] \change @@ -3540,7 +3808,7 @@ \howwide Seldom. -\rSec2[diff.cpp]{\ref{cpp}: preprocessing directives} +\rSec2[diff.cpp]{\ref*{cpp}: preprocessing directives} \diffref{cpp.predefined} \change @@ -3590,12 +3858,12 @@ \rSec2[diff.mods.to.definitions]{Modifications to definitions} -\rSec3[diff.char16]{Types \tcode{char16_t} and \tcode{char32_t}} +\rSec3[diff.char16]{Types \tcode{char8_t}, \tcode{char16_t}, and \tcode{char32_t}} \pnum -The types \keyword{char16_t} and \keyword{char32_t} +The types \keyword{char8_t}, \keyword{char16_t}, and \keyword{char32_t} are distinct types rather than typedefs to existing integral types. -The tokens \keyword{char16_t} and \keyword{char32_t} +The tokens \keyword{char8_t}, \keyword{char16_t}, and \keyword{char32_t} are keywords in \Cpp{}\iref{lex.key}. They do not appear as macro or type names defined in \libheaderref{cuchar}. @@ -3612,14 +3880,6 @@ \libheaderref{cstdlib}, or \libheaderref{cwchar}. -\rSec3[diff.header.assert.h]{Header \tcode{}} -\indexhdr{assert.h}% - -\pnum -The token \keyword{static_assert} is a keyword in \Cpp{}. -It does not appear as a macro name defined -in \libheaderref{cassert}. - \rSec3[diff.header.iso646.h]{Header \tcode{}} \pnum @@ -3640,21 +3900,6 @@ and are not introduced as macros by \libheaderref{iso646.h}. -\rSec3[diff.header.stdalign.h]{Header \tcode{}} - -\pnum -The token \keyword{alignas} is a keyword in \Cpp{}\iref{lex.key}, -and is not introduced as a macro -by \libheaderref{stdalign.h}. - -\rSec3[diff.header.stdbool.h]{Header \tcode{}} - -\pnum -The tokens \keyword{bool}, \keyword{true}, and \keyword{false} -are keywords in \Cpp{}\iref{lex.key}, -and are not introduced as macros -by \libheaderref{stdbool.h}. - \rSec3[diff.null]{Macro \tcode{NULL}} \pnum @@ -3704,7 +3949,7 @@ \pnum Header \libheaderref{cstddef} declares the names \tcode{nullptr_t}, \tcode{byte}, and \tcode{to_integer}, -and the operators and operator templates in \iref{support.types.byteops}, +and the operators and operator templates in~\ref{support.types.byteops}, in addition to the names declared in \libheaderrefx{stddef.h}{support.c.headers} in the C standard library. diff --git a/source/concepts.tex b/source/concepts.tex index 4d848e8fd6..d1e15a6e1a 100644 --- a/source/concepts.tex +++ b/source/concepts.tex @@ -1033,7 +1033,7 @@ \item \tcode{\exposid{CONVERT_TO_LVALUE}(u1)} equals \tcode{\exposid{CONVERT_TO_LVALUE}(u2)} -if and only if \tcode{u1} equals \tcode{u2} +if and only if \tcode{u1} equals \tcode{u2}. \end{itemize} \rSec2[concept.equalitycomparable]{Concept \cname{equality_comparable}} @@ -1222,8 +1222,8 @@ \rSec2[concepts.callable.general]{General} \pnum -The concepts in \ref{concepts.callable} describe the requirements on function -objects\iref{function.objects} and their arguments. +The concepts in \ref{concepts.callable} describe the requirements on +callable types\iref{func.def} and their arguments. \rSec2[concept.invocable]{Concept \cname{invocable}} @@ -1261,8 +1261,8 @@ equality-preserving\iref{concepts.equality} and shall not modify the function object or the arguments. \begin{note} -This requirement supersedes the annotation in the definition of -\libconcept{invocable}. +This requirement supersedes the ``not required to be equality-preserving'' comment +in the definition of \libconcept{invocable}. \end{note} \pnum diff --git a/source/config.tex b/source/config.tex index 5b17f161ed..8a0495e359 100644 --- a/source/config.tex +++ b/source/config.tex @@ -2,8 +2,8 @@ %%-------------------------------------------------- %% Version numbers \newcommand{\docno}{Dxxxx} -\newcommand{\prevdocno}{N5001} -\newcommand{\cppver}{202302L} +\newcommand{\prevdocno}{N5054} +\newcommand{\cppver}{202603L} %% Release date \newcommand{\reldate}{\today} diff --git a/source/containers.tex b/source/containers.tex index 6f72fc0686..727e239cd0 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -20,8 +20,8 @@ \ref{container.requirements} & Requirements & \\ \rowsep \ref{sequences} & Sequence containers & \tcode{}, \tcode{}, \tcode{}, - \tcode{}, \\ & & - \tcode{}, \tcode{} \\ \rowsep + \tcode{}, \\ & & + \tcode{}, \tcode{}, \tcode{} \\ \rowsep \ref{associative} & Associative containers & \tcode{}, \tcode{} \\ \rowsep \ref{unord} & Unordered associative containers & @@ -112,8 +112,10 @@ \indexlibrarymemberx{array}{#1}% \indexlibrarymemberx{deque}{#1}% \indexlibrarymemberx{forward_list}{#1}% +\indexlibrarymemberx{hive}{#1}% \indexlibrarymemberx{list}{#1}% \indexlibrarymemberx{vector}{#1}% +\indexlibrarymemberx{inplace_vector}{#1}% \indexlibrarymemberx{map}{#1}% \indexlibrarymemberx{set}{#1}% \indexlibrarymemberx{multiset}{#1}% @@ -141,7 +143,7 @@ \begin{itemdescr} \pnum \result -\tcode{T} +\tcode{T}. \pnum \expects @@ -157,7 +159,7 @@ \begin{itemdescr} \pnum \result -\tcode{T\&} +\tcode{T\&}. \end{itemdescr} \indexcont{const_reference}% @@ -168,7 +170,7 @@ \begin{itemdescr} \pnum \result -\tcode{const T\&} +\tcode{const T\&}. \end{itemdescr} \indexcont{iterator}% @@ -229,7 +231,7 @@ \begin{itemdescr} \pnum \ensures -\tcode{u.empty()} +\tcode{u.empty()}. \pnum \complexity @@ -272,7 +274,7 @@ \indexcont{operator=}% \begin{itemdecl} -t = v; +t = v \end{itemdecl} \begin{itemdescr} @@ -338,8 +340,8 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; -\tcode{const_iterator} for constant \tcode{b}. +\tcode{const_iterator} if \tcode{b} is of type \tcode{const X}; +\tcode{iterator} otherwise. \pnum \returns @@ -358,8 +360,8 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; -\tcode{const_iterator} for constant \tcode{b}. +\tcode{const_iterator} if \tcode{b} is of type \tcode{const X}; +\tcode{iterator} otherwise. \pnum \returns @@ -382,7 +384,7 @@ \pnum \returns -\tcode{const_cast(b).begin()} +\tcode{const_cast(b).begin()}. \pnum \complexity @@ -401,7 +403,7 @@ \pnum \returns -\tcode{const_cast(b).end()} +\tcode{const_cast(b).end()}. \pnum \complexity @@ -426,7 +428,26 @@ 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{inplace_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} @@ -442,7 +463,7 @@ \pnum \returns -\tcode{equal(c.begin(), c.end(), b.begin(), b.end())} +\tcode{equal(c.begin(), c.end(), b.begin(), b.end())}. \begin{note} The algorithm \tcode{equal} is defined in \ref{alg.equal}. @@ -457,7 +478,26 @@ \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{inplace_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} @@ -604,7 +644,7 @@ allocator argument, then the allocator type must support value-initialization. \end{note} A copy of this allocator is used for any memory allocation and element construction -performed, by these constructors and by all member functions, +performed, by these constructors and by all other member functions, during the lifetime of each container object or until the allocator is replaced. The allocator may be replaced only via assignment or \tcode{swap()}. Allocator replacement is performed by @@ -727,8 +767,10 @@ \indexlibrarymisc{\idxcode{#1}}{reversible containers}% \indexlibrarymemberx{array}{#1}% \indexlibrarymemberx{deque}{#1}% +\indexlibrarymemberx{hive}{#1}% \indexlibrarymemberx{list}{#1}% \indexlibrarymemberx{vector}{#1}% +\indexlibrarymemberx{inplace_vector}{#1}% \indexlibrarymemberx{map}{#1}% \indexlibrarymemberx{set}{#1}% \indexlibrarymemberx{multiset}{#1}% @@ -784,12 +826,12 @@ \begin{itemdescr} \pnum \result -\tcode{reverse_iterator}; -\tcode{const_reverse_iterator} for constant \tcode{a}. +\tcode{const_reverse_iterator} if \tcode{a} is of type \tcode{const X}; +\tcode{reverse_iterator} otherwise. \pnum \returns -\tcode{reverse_iterator(end())} +\tcode{reverse_iterator(end())}. \pnum \complexity @@ -804,12 +846,12 @@ \begin{itemdescr} \pnum \result -\tcode{reverse_iterator}; -\tcode{const_reverse_iterator} for constant \tcode{a}. +\tcode{const_reverse_iterator} if \tcode{a} is of type \tcode{const X}; +\tcode{reverse_iterator} otherwise. \pnum \returns -\tcode{reverse_iterator(begin())} +\tcode{reverse_iterator(begin())}. \pnum \complexity @@ -905,7 +947,7 @@ \pnum \returns \tcode{lexicographical_compare_three_way(a.begin(), a.end(), -b.begin(), b.end(),\newline \exposidnc{synth-three-way})} +b.begin(), b.end(),\newline \exposidnc{synth-three-way})}. \begin{note} The algorithm \tcode{lexicographical_compare_three_way} is defined in \ref{algorithms}. @@ -962,11 +1004,11 @@ \item \tcode{T} is \defnx{\oldconcept{MoveInsertable} into \tcode{X}} {\oldconceptname{MoveInsertable} into X@\oldconcept{MoveInsertable} into \tcode{X}} -means that the following expression -is well-formed: +means that the expression \begin{codeblock} allocator_traits::construct(m, p, rv) \end{codeblock} +is well-formed and its evaluation causes the following postcondition to hold: The value of \tcode{*p} is equivalent to the value of \tcode{rv} before the evaluation. \begin{note} @@ -977,10 +1019,11 @@ \tcode{T} is \defnx{\oldconcept{CopyInsertable} into \tcode{X}} {\oldconceptname{CopyInsertable} into X@\oldconcept{CopyInsertable} into \tcode{X}} means that, in addition to \tcode{T} being \oldconcept{MoveInsertable} into -\tcode{X}, the following expression is well-formed: +\tcode{X}, the expression \begin{codeblock} allocator_traits::construct(m, p, v) \end{codeblock} +is well-formed and its evaluation causes the following postcondition to hold: The value of \tcode{v} is unchanged and is equivalent to \tcode{*p}. @@ -1038,6 +1081,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}% @@ -1063,7 +1107,7 @@ \begin{itemdescr} \pnum \result -\tcode{A} +\tcode{A}. \pnum \mandates @@ -1078,7 +1122,7 @@ \begin{itemdescr} \pnum \result -\tcode{A} +\tcode{A}. \pnum \complexity @@ -1129,7 +1173,7 @@ \pnum \ensures -\tcode{u == t}, \tcode{u.get_allocator() == m} +\tcode{u == t}, \tcode{u.get_allocator() == m}. \pnum \complexity @@ -1235,7 +1279,7 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \effects @@ -1279,8 +1323,11 @@ \tcode{vector}, \tcode{inplace_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 +\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, @@ -1309,7 +1356,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}}, @@ -1322,7 +1369,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 @@ -1343,6 +1390,7 @@ \indexlibrarymemberx{forward_list}{#1}% \indexlibrarymemberx{list}{#1}% \indexlibrarymemberx{vector}{#1}% +\indexlibrarymemberx{inplace_vector}{#1}% } \pnum @@ -1384,7 +1432,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 @@ -1403,7 +1451,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 @@ -1411,6 +1462,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 more than a single reallocation. + \pnum \ensures \tcode{distance(begin(), end()) == ranges::distance(rg)} is \tcode{true}. @@ -1578,7 +1635,7 @@ \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 @@ -1675,7 +1732,7 @@ \pnum \effects -Erases the elements in the range \tcode{[q1, q2)}. +Erases the elements in the range \range{q1}{q2}. \pnum \returns @@ -1692,7 +1749,7 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \effects @@ -1718,7 +1775,7 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \expects @@ -1732,7 +1789,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}, @@ -1748,12 +1805,15 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \mandates \tcode{\libconcept{assignable_from}>} is modeled. +For \tcode{inplace_vector}, +if \tcode{ranges::size(rg)} is a constant expression, +then $\tcode{ranges::size(rg)} \le \tcode{a.max_size()}$. \pnum \expects @@ -1761,7 +1821,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. @@ -1773,6 +1836,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} @@ -1792,7 +1861,7 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \expects @@ -1859,11 +1928,16 @@ \begin{itemdescr} \pnum \result -\tcode{reference; const_reference} for constant \tcode{a}. +\tcode{const_reference} if \tcode{a} is of type \tcode{const X}; +\tcode{reference} otherwise. + +\pnum +\hardexpects +\tcode{a.empty()} is \tcode{false}. \pnum \returns -\tcode{*a.begin()} +\tcode{*a.begin()}. \pnum \remarks @@ -1884,7 +1958,12 @@ \begin{itemdescr} \pnum \result -\tcode{reference; const_reference} for constant \tcode{a}. +\tcode{const_reference} if \tcode{a} is of type \tcode{const X}; +\tcode{reference} otherwise. + +\pnum +\hardexpects +\tcode{a.empty()} is \tcode{false}. \pnum \effects @@ -1913,7 +1992,7 @@ \begin{itemdescr} \pnum \result -\tcode{reference} +\tcode{reference}. \pnum \expects @@ -1943,7 +2022,7 @@ \begin{itemdescr} \pnum \result -\tcode{reference} +\tcode{reference}. \pnum \expects @@ -1976,7 +2055,7 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \expects @@ -2001,7 +2080,7 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \expects @@ -2026,7 +2105,7 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \expects @@ -2062,7 +2141,7 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \expects @@ -2089,7 +2168,7 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \expects @@ -2116,7 +2195,7 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \expects @@ -2147,10 +2226,10 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum -\expects +\hardexpects \tcode{a.empty()} is \tcode{false}. \pnum @@ -2172,10 +2251,10 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum -\expects +\hardexpects \tcode{a.empty()} is \tcode{false}. \pnum @@ -2199,7 +2278,12 @@ \begin{itemdescr} \pnum \result -\tcode{reference; const_reference} for constant \tcode{a} +\tcode{const_reference} if \tcode{a} is of type \tcode{const X}; +\tcode{reference} otherwise. + +\pnum +\hardexpects +\tcode{n < a.size()} is \tcode{true}. \pnum \effects @@ -2222,11 +2306,12 @@ \begin{itemdescr} \pnum \result -\tcode{reference; const_reference} for constant \tcode{a} +\tcode{const_reference} if \tcode{a} is of type \tcode{const X}; +\tcode{reference} otherwise. \pnum \returns -\tcode{*(a.begin() + n)} +\tcode{*(a.begin() + n)}. \pnum \throws @@ -2301,37 +2386,37 @@ using allocator_type = @\seebelownc{}@; private: - using container_node_type = @\unspecnc@; // \expos - using ator_traits = allocator_traits; // \expos + using @\exposid{container-node-type}@ = @\unspecnc@; // \expos + using @\exposid{ator-traits}@ = allocator_traits; // \expos - typename ator_traits::template - rebind_traits::pointer ptr_; // \expos - optional alloc_; // \expos + typename @\exposid{ator-traits}@::template + rebind_traits<@\exposid{container-node-type}@>::pointer @\exposid{ptr_}@; // \expos + optional @\exposid{alloc_}@; // \expos 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}@() noexcept : @\exposid{ptr_}@(), @\exposid{alloc_}@() {} + 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; - 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}@&) - noexcept(ator_traits::propagate_on_container_swap::value || - ator_traits::is_always_equal::value); + constexpr void swap(@\placeholdernc{node-handle}@&) + noexcept(@\exposid{ator-traits}@::propagate_on_container_swap::value || + @\exposid{ator-traits}@::is_always_equal::value); - friend void swap(@\placeholdernc{node-handle}@& x, @\placeholdernc{node-handle}@& y) noexcept(noexcept(x.swap(y))) { + friend constexpr void swap(@\placeholdernc{node-handle}@& x, @\placeholdernc{node-handle}@& y) noexcept(noexcept(x.swap(y))) { x.swap(y); } }; @@ -2340,47 +2425,48 @@ \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} \pnum \effects Constructs a \exposid{node-handle} object initializing -\tcode{ptr_} with \tcode{nh.ptr_}. Move constructs \tcode{alloc_} with -\tcode{nh.alloc_}. Assigns \keyword{nullptr} to \tcode{nh.ptr_} and assigns -\tcode{nullopt} to \tcode{nh.alloc_}. +\exposid{ptr_} with \tcode{nh.\exposid{ptr_}}. Move constructs \exposid{alloc_} with +\tcode{nh.\exposid{alloc_}}. Assigns \keyword{nullptr} to \tcode{nh.\exposid{ptr_}} and assigns +\tcode{nullopt} to \tcode{nh.\exposid{alloc_}}. \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} \pnum \expects -Either \tcode{!alloc_}, or -\tcode{ator_traits::propagate_on_container_move_assignment::\-value} -is \tcode{true}, or \tcode{alloc_ == nh.alloc_}. +Either \tcode{!\exposid{alloc_}} is \tcode{true}, or +\tcode{\exposidnc{ator-traits}::propagate_on_container_move_assign\-ment::value} +is \tcode{true}, or \tcode{\exposid{alloc_} == nh.\exposid{alloc_}} is \tcode{true}. \pnum \effects \begin{itemize} \item -If \tcode{ptr_ != nullptr}, destroys the \tcode{value_type} -subobject in the \tcode{container_node_type} object pointed to by \tcode{ptr_} -by calling \tcode{ator_traits::destroy}, then deallocates \tcode{ptr_} by -calling \tcode{ator_traits::template rebind_traits::deallocate}. +If \tcode{\exposid{ptr_} != nullptr} is \tcode{true}, destroys the \tcode{value_type} +subobject in the \exposid{container-node-type} object pointed to by \exposid{ptr_} +by calling \tcode{\exposid{ator-traits}::destroy}, then deallocates \exposid{ptr_} by +calling \tcode{\exposid{ator-\-traits}::template rebind_traits<\exposid{container-node-type}>::deallocate}. \item -Assigns \tcode{nh.ptr_} to \tcode{ptr_}. +Assigns \tcode{nh.\exposid{ptr_}} to \exposid{ptr_}. \item -If \tcode{!alloc\textunderscore} or \tcode{ator_traits::propagate_on_container_move_assignment::value} +If \tcode{!\exposid{alloc_}} is \tcode{true} or +\tcode{\exposid{ator-traits}::propagate_on_container_move_assignment::value} is \tcode{true}, \linebreak -move assigns \tcode{nh.alloc_} to \tcode{alloc_}. +move assigns \tcode{nh.\exposid{alloc_}} to \exposid{alloc_}. \item Assigns -\keyword{nullptr} to \tcode{nh.ptr_} and assigns \tcode{nullopt} to -\tcode{nh.alloc_}. +\keyword{nullptr} to \tcode{nh.\exposid{ptr_}} and assigns \tcode{nullopt} to +\tcode{nh.\exposid{alloc_}}. \end{itemize} \pnum @@ -2395,22 +2481,22 @@ \rSec3[container.node.dtor]{Destructor} \begin{itemdecl} -~@\placeholdernc{node-handle}@(); +constexpr ~@\placeholdernc{node-handle}@(); \end{itemdecl} \begin{itemdescr} \pnum \effects -If \tcode{ptr_ != nullptr}, destroys the \tcode{value_type} subobject -in the \tcode{container_node_type} object pointed to by \tcode{ptr_} by calling -\tcode{ator_traits::destroy}, then deallocates \tcode{ptr_} by calling -\tcode{ator_traits::template rebind_traits::deallocate}. +If \tcode{\exposid{ptr_} != nullptr} is \tcode{true}, destroys the \tcode{value_type} subobject +in the \exposid{container-node-type} object pointed to by \exposid{ptr_} by calling +\tcode{\exposid{ator-traits}::destroy}, then deallocates \exposid{ptr_} by calling +\tcode{\exposid{ator-\-traits}::template rebind_traits<\exposid{container-node-type}>::deallocate}. \end{itemdescr} \rSec3[container.node.observers]{Observers} \begin{itemdecl} -value_type& value() const; +constexpr value_type& value() const; \end{itemdecl} \begin{itemdescr} @@ -2421,7 +2507,7 @@ \pnum \returns A reference to the \tcode{value_type} subobject in the -\tcode{container_node_type} object pointed to by \tcode{ptr_}. +\exposid{container-node-type} object pointed to by \exposid{ptr_}. \pnum \throws @@ -2440,8 +2526,8 @@ \pnum \returns A non-const reference to the \tcode{key_type} member of the -\tcode{value_type} subobject in the \tcode{contain\-er_node_type} object -pointed to by \tcode{ptr_}. +\tcode{value_type} subobject in the \exposid{contain\-er-node-type} object +pointed to by \exposid{ptr_}. \pnum \throws @@ -2453,7 +2539,7 @@ \end{itemdescr} \begin{itemdecl} -mapped_type& mapped() const; +constexpr mapped_type& mapped() const; \end{itemdecl} \begin{itemdescr} @@ -2464,17 +2550,16 @@ \pnum \returns A reference to the \tcode{mapped_type} member of the -\tcode{value_type} subobject in the \tcode{container_node_type} object -pointed to by \tcode{ptr_}. +\tcode{value_type} subobject in the \exposid{container-\-node-type} object +pointed to by \exposid{ptr_}. \pnum \throws Nothing. \end{itemdescr} - \begin{itemdecl} -allocator_type get_allocator() const; +constexpr allocator_type get_allocator() const; \end{itemdecl} \begin{itemdescr} @@ -2484,7 +2569,7 @@ \pnum \returns -\tcode{*alloc_}. +\tcode{*\exposid{alloc_}}. \pnum \throws @@ -2492,45 +2577,45 @@ \end{itemdescr} \begin{itemdecl} -explicit operator bool() const noexcept; +constexpr explicit operator bool() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{ptr_ != nullptr}. +\tcode{\exposid{ptr_} != nullptr}. \end{itemdescr} \begin{itemdecl} -bool empty() const noexcept; +constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{ptr_ == nullptr}. +\tcode{\exposid{ptr_} == nullptr}. \end{itemdescr} \rSec3[container.node.modifiers]{Modifiers} \begin{itemdecl} -void swap(@\placeholdernc{node-handle}@& nh) - noexcept(ator_traits::propagate_on_container_swap::value || - ator_traits::is_always_equal::value); +constexpr void swap(@\placeholdernc{node-handle}@& nh) + noexcept(@\exposid{ator-traits}@::propagate_on_container_swap::value || + @\exposid{ator-traits}@::is_always_equal::value); \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{!alloc_}, or \tcode{!nh.alloc_}, or -\tcode{ator_traits::propagate_on_container_swap::value} is \tcode{true}, -or \tcode{alloc_ == nh.alloc_}. +\tcode{!\exposid{alloc_}} is \tcode{true}, or \tcode{!nh.\exposid{alloc_}}, or +\tcode{\exposid{ator-traits}::propagate_on_container_swap::\-value} is \tcode{true}, +or \tcode{\exposid{alloc_} == nh.\exposid{alloc_}} is \tcode{true}. \pnum \effects -Calls \tcode{swap(ptr_, nh.ptr_)}. If \tcode{!alloc_}, or -\tcode{!nh.alloc_}, or \tcode{ator_traits::propagate_on_container_swap::value} -is \tcode{true} calls \tcode{swap(alloc_, nh.alloc_)}. +Calls \tcode{swap(\exposid{ptr_}, nh.\exposid{ptr_})}. If \tcode{!\exposid{alloc_}} is \tcode{true}, or +\tcode{!nh.\exposid{alloc_}} is \tcode{true}, or \tcode{\exposid{ator-traits}::\-propagate_on_container_swap::value} +is \tcode{true} calls \tcode{swap(\exposid{alloc_}, nh.\exposid{alloc_})}. \end{itemdescr} \rSec2[container.insert.return]{Insert return type} @@ -2551,7 +2636,7 @@ \end{codeblock} \pnum -The name \exposid{insert-return-type} is exposition only. +The name \exposid{insert-return-type} is for exposition only. \exposid{insert-return-type} has the template parameters, data members, and special members specified above. It has no base classes or members other than those specified. @@ -2667,7 +2752,7 @@ when \tcode{X} supports unique keys, \item \tcode{a_eq} denotes a value of type \tcode{X} -when \tcode{X} supports multiple keys, +when \tcode{X} supports equivalent keys, \item \tcode{a_tran} denotes a value of type \tcode{X} or \tcode{const X} when the \grammarterm{qualified-id} @@ -2690,7 +2775,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 @@ -3168,8 +3253,7 @@ \pnum \returns -An iterator pointing to the element -with the key equivalent to the newly inserted element. +The iterator returned by \tcode{emplace}. \pnum \complexity @@ -3535,7 +3619,7 @@ \pnum \expects -\tcode{a.get_allocator() == a2.get_allocator()}. +\tcode{a.get_allocator() == a2.get_allocator()} is \tcode{true}. \pnum \effects @@ -3550,7 +3634,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}. @@ -3712,7 +3797,8 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. +\tcode{const_iterator} if \tcode{b} is of type \tcode{const X}; +\tcode{iterator} otherwise. \pnum \returns @@ -3732,7 +3818,8 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. +\tcode{const_iterator} if \tcode{a_tran} is of type \tcode{const X}; +\tcode{iterator} otherwise. \pnum \returns @@ -3822,7 +3909,8 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. +\tcode{const_iterator} if \tcode{b} is of type \tcode{const X}; +\tcode{iterator} otherwise. \pnum \returns @@ -3842,7 +3930,8 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. +\tcode{const_iterator} if \tcode{a_tran} is of type \tcode{const X}; +\tcode{iterator} otherwise. \pnum \returns @@ -3863,7 +3952,8 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. +\tcode{const_iterator} if \tcode{b} is of type \tcode{const X}; +\tcode{iterator} otherwise. \pnum \returns @@ -3883,7 +3973,8 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. +\tcode{const_iterator} if \tcode{a_tran} is of type \tcode{const X}; +\tcode{iterator} otherwise. \pnum \returns @@ -3904,8 +3995,9 @@ \begin{itemdescr} \pnum \result -\tcode{pair}; -\tcode{pair} for constant \tcode{b}. +\tcode{pair} +if \tcode{b} is of type \tcode{const X}; +\tcode{pair} otherwise. \pnum \effects @@ -3924,8 +4016,9 @@ \begin{itemdescr} \pnum \result -\tcode{pair}; -\tcode{pair} for constant \tcode{a_tran}. +\tcode{pair} +if \tcode{a_tran} is of type \tcode{const X}; +\tcode{pair} otherwise. \pnum \effects @@ -4179,7 +4272,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}}, @@ -4191,7 +4284,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 @@ -4869,26 +4962,16 @@ \result \tcode{iterator} -\pnum -\expects -\tcode{value_type} is -\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. - \pnum \effects -Equivalent to \tcode{a.emplace(std::forward(args)...)}. - -\pnum -\returns -An iterator pointing to the element -with the key equivalent to the newly inserted element. -The \tcode{const_iterator} \tcode{p} is a hint +Equivalent to \tcode{a.emplace(std::forward(args)...)}, +except that the \tcode{const_iterator} \tcode{p} is a hint pointing to where the search should start. Implementations are permitted to ignore the hint. \pnum -\complexity -Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. +\returns +The iterator returned by \tcode{emplace}. \end{itemdescr} \indexunordmem{insert}% @@ -5003,7 +5086,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 @@ -5366,7 +5449,7 @@ \pnum \effects -Erases all elements in the range \tcode{[q1, q2)}. +Erases all elements in the range \range{q1}{q2}. \pnum \returns @@ -5409,7 +5492,8 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. +\tcode{const_iterator} if \tcode{b} is of type \tcode{const X}; +\tcode{iterator} otherwise. \pnum \returns @@ -5429,7 +5513,8 @@ \begin{itemdescr} \pnum \result -\tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. +\tcode{const_iterator} if \tcode{a_tran} is of type \tcode{const X}; +\tcode{iterator} otherwise. \pnum \returns @@ -5510,8 +5595,9 @@ \begin{itemdescr} \pnum \result -\tcode{pair}; -\tcode{pair} for constant \tcode{b}. +\tcode{pair} +if \tcode{b} is of type \tcode{const X}; +\tcode{pair} otherwise. \pnum \returns @@ -5531,8 +5617,9 @@ \begin{itemdescr} \pnum \result -\tcode{pair}; -\tcode{pair} for constant \tcode{a_tran}. +\tcode{pair} +if \tcode{a_tran} is of type \tcode{const X}; +\tcode{pair} otherwise. \pnum \returns @@ -5602,7 +5689,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 @@ -5625,7 +5712,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 @@ -5650,7 +5737,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 @@ -5669,11 +5756,12 @@ \begin{itemdescr} \pnum \result -\tcode{local_iterator}; \tcode{const_local_iterator} for constant \tcode{b}. +\tcode{const_local_iterator} if \tcode{b} is of type \tcode{const X}; +\tcode{local_iterator} otherwise. \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,11 +5781,12 @@ \begin{itemdescr} \pnum \result -\tcode{local_iterator}; \tcode{const_local_iterator} for constant \tcode{b}. +\tcode{const_local_iterator} if \tcode{b} is of type \tcode{const X}; +\tcode{local_iterator} otherwise. \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 @@ -5720,7 +5809,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 @@ -5744,7 +5833,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 @@ -5903,7 +5992,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. @@ -5986,6 +6075,7 @@ \libheaderref{array}, \libheaderref{deque}, \libheaderrefx{forward_list}{forward.list.syn}, +\libheaderref{hive}, \libheaderrefx{inplace_vector}{inplace.vector.syn}, \libheaderref{list}, and \libheaderref{vector} @@ -5996,7 +6086,7 @@ \begin{codeblock} template - using @\placeholdernc{iter-value-type}@ = typename iterator_traits::value_type; // \expos + using @\placeholdernc{iter-value-type}@ = iterator_traits::value_type; // \expos \end{codeblock} \rSec2[array.syn]{Header \tcode{} synopsis} @@ -6014,7 +6104,7 @@ template constexpr bool operator==(const array& x, const array& y); template - constexpr @\placeholder{synth-three-way-result}@ + constexpr @\exposid{synth-three-way-result}@ operator<=>(const array& x, const array& y); // \ref{array.special}, specialized algorithms @@ -6149,8 +6239,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 @@ -6268,10 +6358,6 @@ In the case that \tcode{N == 0}, \tcode{begin() == end() ==} unique value. The return value of \tcode{data()} is unspecified. -\pnum -The effect of calling \tcode{front()} or \tcode{back()} for a zero-sized array is -undefined. - \pnum Member function \tcode{swap()} shall have a non-throwing exception specification. @@ -6380,21 +6466,21 @@ template> class deque; template - bool operator==(const deque& x, const deque& y); + constexpr bool operator==(const deque& x, const deque& y); template - @\placeholder{synth-three-way-result}@ operator<=>(const deque& x, - @\itcorr@ const deque& y); + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const deque& x, const deque& y); template - void swap(deque& x, deque& y) + constexpr void swap(deque& x, deque& y) noexcept(noexcept(x.swap(y))); // \ref{deque.erasure}, erasure template - typename deque::size_type + constexpr typename deque::size_type erase(deque& c, const U& value); template - typename deque::size_type + constexpr typename deque::size_type erase_if(deque& c, Predicate pred); namespace pmr { @@ -6430,6 +6516,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> @@ -6438,8 +6528,8 @@ // types using value_type = T; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = @\impdefx{type of \tcode{deque::size_type}}@; // see \ref{container.requirements} @@ -6450,97 +6540,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; + 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; - 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{deque.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); - 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>> @@ -6557,7 +6648,7 @@ \indexlibraryctor{deque}% \begin{itemdecl} -explicit deque(const Allocator&); +constexpr explicit deque(const Allocator&); \end{itemdecl} \begin{itemdescr} @@ -6574,7 +6665,7 @@ \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} @@ -6594,7 +6685,7 @@ \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} @@ -6617,7 +6708,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} @@ -6637,7 +6728,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} @@ -6655,7 +6746,7 @@ \indexlibrarymember{resize}{deque}% \begin{itemdecl} -void resize(size_type sz); +constexpr void resize(size_type sz); \end{itemdecl} \begin{itemdescr} @@ -6672,7 +6763,7 @@ \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} @@ -6689,7 +6780,7 @@ \indexlibrarymember{shrink_to_fit}{deque}% \begin{itemdecl} -void shrink_to_fit(); +constexpr void shrink_to_fit(); \end{itemdecl} \begin{itemdescr} @@ -6731,27 +6822,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} @@ -6787,10 +6878,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} @@ -6823,7 +6914,7 @@ \indexlibrarymember{erase}{deque}% \begin{itemdecl} template - typename deque::size_type + constexpr typename deque::size_type erase(deque& c, const U& value); \end{itemdecl} @@ -6842,7 +6933,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} @@ -6870,21 +6961,23 @@ template> class forward_list; template - bool operator==(const forward_list& x, const forward_list& y); + constexpr 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); + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const forward_list& x, + const forward_list& y); template - void swap(forward_list& x, forward_list& y) + constexpr void swap(forward_list& x, forward_list& y) noexcept(noexcept(x.swap(y))); // \ref{forward.list.erasure}, erasure template - typename forward_list::size_type + constexpr typename forward_list::size_type erase(forward_list& c, const U& value); template - typename forward_list::size_type + constexpr typename forward_list::size_type erase_if(forward_list& c, Predicate pred); namespace pmr { @@ -6931,6 +7024,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> @@ -6939,8 +7036,8 @@ // types using value_type = T; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = @\impdefx{type of \tcode{forward_list::size_type}}@; // see \ref{container.requirements} @@ -6949,105 +7046,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 - 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, - const_iterator first, const_iterator last); - 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); - - size_type unique(); - template 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); - - void sort(); - template void sort(Compare comp); - - void reverse() noexcept; + 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); + constexpr void splice_after(const_iterator position, forward_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(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); + + constexpr void sort(); + template constexpr void sort(Compare comp); + + constexpr void reverse() noexcept; }; template>> @@ -7071,7 +7171,7 @@ \indexlibraryctor{forward_list}% \begin{itemdecl} -explicit forward_list(const Allocator&); +constexpr explicit forward_list(const Allocator&); \end{itemdecl} \begin{itemdescr} @@ -7086,7 +7186,7 @@ \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} @@ -7106,7 +7206,7 @@ \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} @@ -7126,7 +7226,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} @@ -7142,7 +7242,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} @@ -7161,9 +7261,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} @@ -7186,8 +7286,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} @@ -7213,7 +7313,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} @@ -7225,8 +7325,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} @@ -7238,7 +7338,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} @@ -7252,7 +7352,7 @@ \indexlibrarymember{pop}{forward_list}% \begin{itemdecl} -void pop_front(); +constexpr void pop_front(); \end{itemdecl} \begin{itemdescr} @@ -7263,7 +7363,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} @@ -7284,7 +7384,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} @@ -7305,7 +7405,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} @@ -7328,7 +7428,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} @@ -7353,7 +7454,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} @@ -7377,7 +7478,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} @@ -7390,7 +7491,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} @@ -7413,7 +7514,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} @@ -7436,7 +7537,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} @@ -7459,7 +7560,7 @@ \indexlibrarymember{resize}{forward_list}% \begin{itemdecl} -void resize(size_type sz); +constexpr void resize(size_type sz); \end{itemdecl} \begin{itemdescr} @@ -7475,7 +7576,7 @@ \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} @@ -7493,7 +7594,7 @@ \indexlibrarymember{clear}{forward_list}% \begin{itemdecl} -void clear() noexcept; +constexpr void clear() noexcept; \end{itemdecl} \begin{itemdescr} @@ -7524,8 +7625,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} @@ -7555,8 +7656,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} @@ -7587,10 +7688,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} @@ -7618,8 +7719,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} @@ -7651,8 +7752,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} @@ -7690,10 +7791,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} @@ -7734,8 +7835,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} @@ -7756,7 +7857,7 @@ \indexlibrarymember{reverse}{forward_list}% \begin{itemdecl} -void reverse() noexcept; +constexpr void reverse() noexcept; \end{itemdecl} \begin{itemdescr} @@ -7775,20 +7876,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, [\&](const auto\& elem) -> bool \{ 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} @@ -7798,79 +7902,1221 @@ Equivalent to: \tcode{return c.remove_if(pred);} \end{itemdescr} -\rSec2[list.syn]{Header \tcode{} synopsis} +\rSec2[hive.syn]{Header \tcode{} synopsis} -\indexheader{list}% +\indexheader{hive}% \begin{codeblock} -#include // see \ref{compare.syn} #include // see \ref{initializer.list.syn} +#include // see \ref{compare.syn} namespace std { - // \ref{list}, class template \tcode{list} - template> class list; + 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) {} + }; - template - bool operator==(const list& x, const list& y); - template - @\placeholder{synth-three-way-result}@ operator<=>(const list& x, - @\itcorr@ const list& y); + // \ref {hive}, class template \tcode{hive} + template> class hive; template - void swap(list& x, list& y) + void swap(hive& x, hive& y) noexcept(noexcept(x.swap(y))); - // \ref{list.erasure}, erasure template - typename list::size_type - erase(list& c, const U& value); + typename hive::size_type + erase(hive& c, const U& value); + template - typename list::size_type - erase_if(list& c, Predicate pred); + typename hive::size_type + erase_if(hive& c, Predicate pred); namespace pmr { template - using list = std::list>; + using hive = std::hive>; } } \end{codeblock} -\rSec2[list]{Class template \tcode{list}} +\rSec2[hive]{Class template \tcode{hive}} -\rSec3[list.overview]{Overview} +\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\iref{hive.modifiers} position is determined by the container, and insertion +may re-use the memory locations of erased elements. +\begin{note} +Construction and assignment are not considered to involve insertion operations. +\end{note} \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 passed to +a \tcode{hive} constructor or \tcode{reshape} +are not within hard limits, or +if the specified minimum limit is greater than the specified maximum limit, +the behavior is erroneous and the effects are +\impldef{effects of invalid \tcode{hive} limits}. +\begin{tailnote} +This condition can be checked using \tcode{is_within_hard_limits}. +\end{tailnote} +\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 @\libglobal{hive}@ { + public: + // types + using value_type = T; + using allocator_type = Allocator; + using pointer = allocator_traits::pointer; + using const_pointer = 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 + hive(InputIterator first, InputIterator last, hive_limits block_limits, + const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + 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> + void assign_range(R&& rg); + void assign(size_type n, const T& t); + void assign(initializer_list); + 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{hive.capacity}, capacity + bool empty() const noexcept; + size_type size() const noexcept; + size_type max_size() const noexcept; + 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; + static constexpr bool is_within_hard_limits(hive_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 insert_range(R&& rg); + template + void insert(InputIterator first, InputIterator last); + void insert(size_type n, const T& x); + + iterator erase(const_iterator position); + iterator erase(const_iterator first, const_iterator last); + void swap(hive&) noexcept(@\seebelow@); + void clear() noexcept; + + // \ref{hive.operations}, hive operations + void splice(hive& x); + void splice(hive&& x); + template> + size_type unique(BinaryPredicate binary_pred = BinaryPredicate()); + + template> + void sort(Compare comp = Compare()); + + iterator get_iterator(const_pointer p) noexcept; + const_iterator get_iterator(const_pointer p) const noexcept; + + private: + hive_limits @\exposid{current-limits}@ = @\impdef@; // \expos + }; + + template>> + hive(InputIterator, InputIterator, Allocator = Allocator()) + -> hive<@\exposid{iter-value-type}@, Allocator>; + + template>> + hive(InputIterator, InputIterator, hive_limits, Allocator = Allocator()) + -> hive<@\exposid{iter-value-type}@, Allocator>; + + template>> + hive(from_range_t, R&&, Allocator = Allocator()) + -> hive, Allocator>; + + template>> + hive(from_range_t, R&&, hive_limits, Allocator = Allocator()) + -> hive, Allocator>; +} +\end{codeblock} + +\rSec3[hive.cons]{Constructors, copy, and assignment} + +\indexlibraryctor{hive}% +\begin{itemdecl} +constexpr explicit hive(const Allocator&) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{hive}, using the specified allocator. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{hive}% +\begin{itemdecl} +constexpr hive(hive_limits block_limits, const Allocator&); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{hive}, using the specified allocator. +Initializes \exposid{current-limits} with \tcode{block_limits}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{hive}% +\begin{itemdecl} +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{DefaultInsertable} into \tcode{hive}. + +\pnum +\effects +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}. +\end{itemdescr} + +\indexlibraryctor{hive}% +\begin{itemdecl} +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 +\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{n}. +\end{itemdescr} + +\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> + 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{hive} object equal to 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} + +\indexlibraryctor{hive}% +\begin{itemdecl} +hive(const hive& x); +hive(const hive& x, const type_identity_t& alloc); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{hive}. + +\pnum +\effects +Constructs a \tcode{hive} object equal to \tcode{x}. +If the second overload is called, uses \tcode{alloc}. +Initializes \exposid{current-limits} with \tcode{x.\exposid{current-limits}}. + +\pnum +\complexity +Linear in \tcode{x.size()}. +\end{itemdescr} + +\indexlibraryctor{hive}% +\begin{itemdecl} +hive(hive&& x) noexcept; +hive(hive&& x, const type_identity_t& alloc); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +For the second overload, +when \tcode{allocator_traits::is_always_equal::\-value} is \tcode{false}, +\tcode{T} meets the \oldconcept{MoveInsertable} requirements. + +\pnum +\effects +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}. + +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. + +\pnum +\ensures +\tcode{x.empty()} is \tcode{true}. +The relative order of the elements of \tcode{*this} +is the same as that of the elements of \tcode{x} prior to the call. + +\pnum +\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} + +\indexlibraryctor{hive}% +\begin{itemdecl} +hive(initializer_list il, const Allocator& = Allocator()); +hive(initializer_list il, hive_limits block_limits, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{hive}. + +\pnum +\effects +Constructs a \tcode{hive} object equal to \tcode{il}, +using the specified allocator. +If the second overload is called, +also initializes \exposid{current-limits} with \tcode{block_limits}. + +\pnum +\complexity +Linear in \tcode{il.size()}. +\end{itemdescr} + +\indexlibrarymember{operator=}{hive}% +\begin{itemdecl} +hive& operator=(const hive& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{hive} and +\oldconcept{CopyAssignable}. + +\pnum +\effects +All elements in \tcode{*this} are either copy-assigned to, or destroyed. +All elements in \tcode{x} are copied into \tcode{*this}, +maintaining their relative order. +\begin{note} +\exposid{current-limits} is unchanged. +\end{note} + +\pnum +\complexity +Linear in \tcode{size() + x.size()}. +\end{itemdescr} + +\indexlibrarymember{operator=}{hive}% +\begin{itemdecl} +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 +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 +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 +\ensures +\tcode{x.empty()} is \tcode{true}. +The relative order of the elements of \tcode{*this} +is the same as that of the elements of \tcode{x} prior to this call. + +\pnum +\complexity +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} + +\rSec3[hive.capacity]{Capacity} + +\indexlibrarymember{capacity}{hive}% +\begin{itemdecl} +size_type capacity() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The total number of elements that \tcode{*this} can hold +without requiring allocation of more element blocks. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibrarymember{reserve}{hive}% +\begin{itemdecl} +void reserve(size_type n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{n <= capacity()} is \tcode{true}, there are no effects. +Otherwise increases \tcode{capacity()} by allocating reserved blocks. + +\pnum +\ensures +\tcode{capacity() >= n} is \tcode{true}. + +\pnum +\throws +\tcode{length_error} if +satisfying the postcondition +would cause \tcode{capacity()} to exceed \tcode{max_size()}, +as well as any exceptions thrown by the allocator. + +\pnum +\complexity +Linear in the number of reserved blocks allocated. + +\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{shrink_to_fit}{hive}% +\begin{itemdecl} +void shrink_to_fit(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{hive}. + +\pnum +\effects +\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, +if \tcode{n >= capacity()} is \tcode{true}, +there are no effects; +otherwise, \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 +\exposid{current-limits}. + +\pnum +\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 +Constant. +\end{itemdescr} + +\indexlibrarymember{block_capacity_hard_limits}{hive}% +\begin{itemdecl} +static constexpr hive_limits block_capacity_hard_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 hard limits. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibrarymember{is_within_hard_limits}{hive}% +\begin{itemdecl} +static constexpr bool is_within_hard_limits(hive_limits lim) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{hl} be \tcode{block_capacity_hard_limits()}. + +\pnum +\returns +\tcode{hl.min <= lim.min \&\& lim.min <= lim.max \&\& lim.max <= hl.max}. +\end{itemdescr} + +\indexlibrarymember{reshape}{hive}% +\begin{itemdecl} +void reshape(hive_limits block_limits); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{hive}. + +\pnum +\effects +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 +Linear in the number of element blocks in \tcode{*this}. +If reallocation happens, also linear in the number of elements reallocated. + +\pnum +\remarks +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} + +\rSec3[hive.modifiers]{Modifiers} + +\indexlibrarymember{emplace}{hive}% +\begin{itemdecl} +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 +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 +Constant. Exactly one object of type \tcode{T} is constructed. + +\pnum +\remarks +Invalidates the past-the-end iterator. +\end{itemdescr} + +\indexlibrarymember{insert}{hive}% +\begin{itemdecl} +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 +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 +Linear in the number of elements inserted. +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} +void insert(size_type n, const T& x); +\end{itemdecl} + +\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 + void insert(InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{insert_range(ranges::subrange(first, last))}. +\end{itemdescr} + +\indexlibrarymember{erase}{hive}% +\begin{itemdecl} +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 +Exchanges the contents, \tcode{capacity()}, and \exposid{current-limits} +of \tcode{*this} with that of \tcode{x}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\rSec3[hive.operations]{Operations} + +\pnum +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 +\expects +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. + +\pnum +\effects +If \tcode{addressof(x) == this} is \tcode{true}, +the behavior is erroneous and there are no effects. +If an exception is thrown, +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 +\throws +\tcode{length_error} if any of \tcode{x}'s active blocks +are not within the bounds of \exposid{current-limits}, +as well as any exceptions thrown by the allocator. + +\pnum +\complexity +Linear in the sum of +all element blocks in \tcode{x} plus all element blocks in \tcode{*this}. + +\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\iref{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, [&](const auto& elem) -> bool { 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(); i != c.end(); ) { + 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 @\exposid{synth-three-way-result}@ + operator<=>(const list& x, 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\iref{iterator.requirements.general}. \begin{codeblock} namespace std { @@ -7880,8 +9126,8 @@ // types using value_type = T; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = 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} @@ -7892,113 +9138,116 @@ 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()); + 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 - list(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr list(InputIterator first, InputIterator last, 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) + 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); - list& operator=(initializer_list); + constexpr 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; // 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; + 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; - 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{list.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); + 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 - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr 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 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> - void prepend_range(R&& rg); - void pop_front(); - void push_back(const T& x); - void push_back(T&& x); + 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> - void append_range(R&& rg); - void pop_back(); + constexpr void append_range(R&& rg); + constexpr 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); + 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 - 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 il); + constexpr iterator insert_range(const_iterator position, R&& rg); + constexpr iterator insert(const_iterator position, initializer_list il); - 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; + 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 - 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); - - size_type remove(const T& value); - template size_type remove_if(Predicate pred); - - size_type unique(); + 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 - size_type unique(BinaryPredicate binary_pred); + constexpr size_type unique(BinaryPredicate binary_pred); - void merge(list& x); - void merge(list&& x); - template void merge(list& x, Compare comp); - template void merge(list&& x, Compare comp); + 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); - void sort(); - template void sort(Compare comp); + constexpr void sort(); + template constexpr void sort(Compare comp); - void reverse() noexcept; + constexpr void reverse() noexcept; }; template>> @@ -8022,13 +9271,13 @@ \indexlibraryctor{list}% \begin{itemdecl} -explicit list(const Allocator&); +constexpr explicit list(const Allocator&); \end{itemdecl} \begin{itemdescr} \pnum \effects -Constructs an empty list, using the specified allocator. +Constructs an empty \tcode{list}, using the specified allocator. \pnum \complexity @@ -8037,7 +9286,7 @@ \indexlibraryctor{list}% \begin{itemdecl} -explicit list(size_type n, const Allocator& = Allocator()); +constexpr explicit list(size_type n, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -8058,7 +9307,7 @@ \indexlibraryctor{list}% \begin{itemdecl} -list(size_type n, const T& value, const Allocator& = Allocator()); +constexpr list(size_type n, const T& value, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -8085,7 +9334,7 @@ \indexlibraryctor{list}% \begin{itemdecl} template - list(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr list(InputIterator first, InputIterator last, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -8105,7 +9354,7 @@ \indexlibraryctor{list}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@ R> - list(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr list(from_range_t, R&& rg, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -8122,7 +9371,7 @@ \indexlibrarymember{resize}{list}% \begin{itemdecl} -void resize(size_type sz); +constexpr void resize(size_type sz); \end{itemdecl} \begin{itemdescr} @@ -8146,7 +9395,7 @@ \indexlibrarymember{resize}{list}% \begin{itemdecl} -void resize(size_type sz, const T& c); +constexpr void resize(size_type sz, const T& c); \end{itemdecl} \begin{itemdescr} @@ -8174,27 +9423,27 @@ \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); +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} @@ -8215,11 +9464,11 @@ \indexlibrarymember{erase}{list}% \begin{itemdecl} -iterator erase(const_iterator position); -iterator erase(const_iterator first, const_iterator last); -void pop_front(); -void pop_back(); -void clear() noexcept; +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} @@ -8269,8 +9518,8 @@ \indexlibrarymember{splice}{list}% \begin{itemdecl} -void splice(const_iterator position, list& x); -void splice(const_iterator position, list&& x); +constexpr void splice(const_iterator position, list& x); +constexpr void splice(const_iterator position, list&& x); \end{itemdecl} \begin{itemdescr} @@ -8308,8 +9557,8 @@ \indexlibrarymember{splice}{list}% \begin{itemdecl} -void splice(const_iterator position, list& x, const_iterator i); -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 i); \end{itemdecl} \begin{itemdescr} @@ -8354,16 +9603,16 @@ \indexlibrarymember{splice}{list}% \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); +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 -\tcode{[first, last)} is a valid range in \tcode{x}. +\range{first}{last} is a valid range in \tcode{x}. \tcode{position} is not an iterator in the range \range{first}{last}. \pnum @@ -8397,8 +9646,8 @@ \indexlibrarymember{remove}{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} @@ -8432,8 +9681,8 @@ \indexlibrarymember{unique}{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} @@ -8470,10 +9719,10 @@ \indexlibrarymember{merge}{list}% \begin{itemdecl} -void merge(list& x); -void merge(list&& x); -template void merge(list& x, Compare comp); -template void merge(list&& x, Compare comp); +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} @@ -8514,7 +9763,7 @@ \indexlibrarymember{reverse}{list}% \begin{itemdecl} -void reverse() noexcept; +constexpr void reverse() noexcept; \end{itemdecl} \begin{itemdescr} @@ -8546,8 +9795,7 @@ \complexity Approximately $N \log N$ -comparisons, where -\tcode{N == size()}. +comparisons, where $N$ is \tcode{size()}. \pnum \remarks @@ -8560,20 +9808,23 @@ \begin{itemdecl} template typename list::size_type - erase(list& c, const U& value); + constexpr erase(list& c, const U& value); \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return erase_if(c, [\&](const auto\& elem) -> bool \{ 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}{list}% \begin{itemdecl} template typename list::size_type - erase_if(list& c, Predicate pred); + constexpr erase_if(list& c, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -8596,8 +9847,8 @@ 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); + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const vector& x, const vector& y); template constexpr void swap(vector& x, vector& y) @@ -8675,8 +9926,8 @@ // types using value_type = T; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = 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} @@ -8881,7 +10132,8 @@ \tcode{first} and \tcode{last}) -and no reallocations if iterators \tcode{first} and \tcode{last} are of forward, bidirectional, or random access categories. +and no reallocations if +\tcode{InputIterator} meets the \oldconcept{ForwardIterator} requirements. It makes order $N$ calls to the copy constructor of @@ -8908,9 +10160,18 @@ 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 + +\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} @@ -8944,9 +10205,6 @@ \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()} @@ -8972,11 +10230,11 @@ \pnum \complexity -It does not change the size of the sequence and takes at most linear -time in the size of the sequence. +Linear in the size of the sequence. \pnum \remarks +The size of the sequence is not changed. 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} @@ -9095,8 +10353,8 @@ \indexlibrarymember{data}{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} @@ -9161,6 +10419,21 @@ 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}% @@ -9258,13 +10531,17 @@ // bit reference class @\libmember{reference}{vector}@ { public: - constexpr reference(const reference&) = default; + constexpr reference(const reference& x) noexcept; 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 operator bool() const noexcept; constexpr void flip() noexcept; // flips the bit + + friend constexpr void swap(reference x, reference y) noexcept; + friend constexpr void swap(reference x, bool& y) noexcept; + friend constexpr void swap(bool& x, reference y) noexcept; }; // construct/copy/destroy @@ -9350,7 +10627,6 @@ 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; }; @@ -9358,53 +10634,115 @@ \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. +Unless described below, all operations have the same requirements and +semantics as the \tcode{vector} primary 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 a reference to a single bit in the sequence. + +\indexlibraryctor{vector::reference}% +\begin{itemdecl} +constexpr reference::reference(const reference& x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{*this} to refer to the same bit as \tcode{x}. +\end{itemdescr} + +\indexlibrarydtor{vector::reference}% +\begin{itemdecl} +constexpr reference::~reference(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +None. +\end{itemdescr} + +\indexlibrarymember{operator=}{vector::reference}% +\begin{itemdecl} +constexpr reference& reference::operator=(bool x) noexcept; +constexpr reference& reference::operator=(const reference& x) noexcept; +constexpr const reference& reference::operator=(bool x) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Sets the bit referred to by \tcode{*this} when \tcode{bool(x)} is \tcode{true}, +and clears it otherwise. \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. +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator bool}{vector::reference}% +\begin{itemdecl} +constexpr reference::operator bool() const noexcept; +\end{itemdecl} +\begin{itemdescr} \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. +\returns +\tcode{true} if the value of the bit referred to by \tcode{*this} is one, +\tcode{false} otherwise. +\end{itemdescr} -\indexlibrarymember{flip}{vector}% +\indexlibrarymember{flip}{vector::reference}% \begin{itemdecl} -constexpr void flip() noexcept; +constexpr void reference::flip() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Replaces each element in the container with its complement. +Equivalent to \tcode{*this = !*this}. \end{itemdescr} -\indexlibrarymember{swap}{vector}% +\indexlibrarymember{swap}{vector::reference}% \begin{itemdecl} -static constexpr void swap(reference x, reference y) noexcept; +constexpr void swap(reference x, reference y) noexcept; +constexpr void swap(reference x, bool& y) noexcept; +constexpr void swap(bool& x, reference y) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Exchanges the contents of \tcode{x} and \tcode{y} as if by: +Exchanges the values denoted by \tcode{x} and \tcode{y} as if by: \begin{codeblock} bool b = x; x = y; y = b; \end{codeblock} +\end{itemdescr} + + + +\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} \begin{itemdecl} @@ -9448,7 +10786,7 @@ parse(ParseContext& ctx); template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(const T& ref, FormatContext& ctx) const; }; } @@ -9469,7 +10807,7 @@ \indexlibrarymember{format}{formatter}% \begin{itemdecl} template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(const T& ref, FormatContext& ctx) const; \end{itemdecl} @@ -9534,13 +10872,6 @@ \tcode{inplace_vector::const_iterator} meet the constexpr iterator requirements. -\pnum -For any $\tcode{N} > 0$, -if \tcode{T} is not trivially copyable or -\tcode{is_trivially_default_constructible_v} is \tcode{false}, -then no \tcode{inplace_vector} member functions -are usable in constant expressions. - \pnum Any member function of \tcode{inplace_vector} that would cause the size to exceed \tcode{N} @@ -9639,7 +10970,7 @@ constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; - // \ref{inplace.vector.capacity}, size/capacity + // \ref{inplace.vector.capacity}, capacity constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; static constexpr size_type max_size() noexcept; @@ -9673,11 +11004,9 @@ constexpr void pop_back(); 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); + constexpr optional try_emplace_back(Args&&... args); + constexpr optional try_push_back(const T& x); + constexpr optional try_push_back(T&& x); template constexpr reference unchecked_emplace_back(Args&&... args); @@ -9704,16 +11033,21 @@ is_nothrow_move_constructible_v)); constexpr void clear() noexcept; - constexpr friend bool operator==(const inplace_vector& x, + friend constexpr 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) + friend constexpr auto + operator<=>(const inplace_vector& x, const inplace_vector& y) + requires requires (const T t) { @\exposid{synth-three-way}@(t, t); } + { + return lexicographical_compare_three_way(x.begin(), x.end(), y.begin(), y.end(), + @\exposid{synth-three-way}@); + } + friend constexpr 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} \rSec3[inplace.vector.cons]{Constructors} @@ -9779,6 +11113,11 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +If \tcode{ranges::size(rg)} is a constant expression, +then $\tcode{ranges::size(rg)} \le \tcode{N}$. + \pnum \effects Constructs an \tcode{inplace_vector} with @@ -9789,7 +11128,7 @@ Linear in \tcode{ranges::distance(rg)}. \end{itemdescr} -\rSec3[inplace.vector.capacity]{Size and capacity} +\rSec3[inplace.vector.capacity]{Capacity} \indexlibrarymember{capacity}{inplace_vector}% \indexlibrarymember{max_size}{inplace_vector}% @@ -9850,6 +11189,32 @@ If an exception is thrown, there are no effects on \tcode{*this}. \end{itemdescr} +\indexlibrarymember{reserve}{inplace_vector}% +\begin{itemdecl} +static constexpr void reserve(size_type n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +None. + +\pnum +\throws +\tcode{bad_alloc} if \tcode{n > capacity()} is \tcode{true}. +\end{itemdescr} + +\indexlibrarymember{shrink_to_fit}{inplace_vector}% +\begin{itemdecl} +static constexpr void shrink_to_fit() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +None. +\end{itemdescr} + \rSec3[inplace.vector.data]{Data} \indexlibrarymember{data}{inplace_vector}% @@ -9951,9 +11316,9 @@ \indexlibrarymember{try_push_back}{inplace_vector}% \begin{itemdecl} template - constexpr pointer try_emplace_back(Args&&... args); -constexpr pointer try_push_back(const T& x); -constexpr pointer try_push_back(T&& x); + constexpr optional try_emplace_back(Args&&... args); +constexpr optional try_push_back(const T& x); +constexpr optional try_push_back(T&& x); \end{itemdecl} \begin{itemdescr} @@ -9979,8 +11344,8 @@ \pnum \returns -\keyword{nullptr} if \tcode{size() == capacity()} is \tcode{true}, -otherwise \tcode{addressof(back())}. +\keyword{nullopt} if \tcode{size() == capacity()} is \tcode{true}, +otherwise \tcode{optional(in_place, back())}. \pnum \throws @@ -9995,44 +11360,6 @@ If an exception is thrown, there are no effects on \tcode{*this}. \end{itemdescr} -\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} - -\begin{itemdescr} -\pnum -\expects -\tcode{value_type} is \oldconcept{EmplaceConstructible} -into \tcode{inplace_vector} from\\\tcode{*ranges::begin(rg)}. - -\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. - -\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. - -\pnum -\complexity -Linear in the number of elements inserted. - -\pnum -\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 @@ -10067,32 +11394,6 @@ \tcode{return *try_push_back(std::forward(x));} \end{itemdescr} -\indexlibrarymember{reserve}{inplace_vector}% -\begin{itemdecl} -static constexpr void reserve(size_type n); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -None. - -\pnum -\throws -\tcode{bad_alloc} if \tcode{n > capacity()} is \tcode{true}. -\end{itemdescr} - -\indexlibrarymember{shrink_to_fit}{inplace_vector}% -\begin{itemdecl} -static constexpr void shrink_to_fit() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -None. -\end{itemdescr} - \indexlibrarymember{erase}{inplace_vector}% \indexlibrarymember{pop_back}{inplace_vector}% \begin{itemdecl} @@ -10119,6 +11420,26 @@ equal to the number of elements after the erased elements. \end{itemdescr} +\indexlibrarymember{swap}{inplace_vector}% +\begin{itemdecl} +constexpr void swap(inplace_vector& x) noexcept( + N == 0 || (is_nothrow_swappable_v && is_nothrow_move_constructible_v)); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} meets the \oldconcept{MoveConstructible} requirements. +Let $M$ be \tcode{min(size(), x.size())}. +For each non-negative integer $n < M$, +\tcode{(*this)[$n$]} is swappable +with \tcode{x[$n$]}\iref{swappable.requirements}. + +\pnum +\effects +Exchanges the contents of \tcode{*this} and \tcode{x}. +\end{itemdescr} + \rSec3[inplace.vector.erasure]{Erasure} \indexlibrarymember{erase}{inplace_vector}% @@ -10171,27 +11492,27 @@ The following exposition-only alias templates may appear in deduction guides for associative containers: \begin{codeblock} template - using @\placeholder{iter-value-type}@ = - typename iterator_traits::value_type; // \expos + using @\placeholder{iter-value-type}@ = iterator_traits::value_type; // \expos template - using @\placeholder{iter-key-type}@ = remove_const_t< + using @\placeholder{iter-key-type}@ = remove_cvref_t< tuple_element_t<0, @\exposid{iter-value-type}@>>; // \expos template - using @\placeholder{iter-mapped-type}@ = - tuple_element_t<1, @\exposid{iter-value-type}@>; // \expos + using @\placeholder{iter-mapped-type}@ = remove_cvref_t< + tuple_element_t<1, @\exposid{iter-value-type}@>>; // \expos template using @\placeholder{iter-to-alloc-type}@ = pair< - add_const_t>>, - tuple_element_t<1, @\exposid{iter-value-type}@>>; // \expos + const @\exposid{iter-key-type}@, + @\exposid{iter-mapped-type}@>; // \expos template using @\exposid{range-key-type}@ = - remove_const_t::first_type>; // \expos + remove_cvref_t>>; // \expos template - using @\exposid{range-mapped-type}@ = typename ranges::range_value_t::second_type; // \expos + using @\exposid{range-mapped-type}@ = + remove_cvref_t>>; // \expos template using @\exposid{range-to-alloc-type}@ = - pair::first_type>, - typename ranges::range_value_t::second_type>; // \expos + pair, + @\exposid{range-mapped-type}@>; // \expos \end{codeblock} \rSec2[associative.map.syn]{Header \tcode{} synopsis} @@ -10208,21 +11529,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 @\exposid{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} @@ -10231,21 +11552,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 @\exposid{synth-three-way-result}@> operator<=>(const multimap& x, const multimap& y); template - void swap(multimap& x, - multimap& y) + 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 { @@ -10275,7 +11596,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} @@ -10304,6 +11625,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} @@ -10318,8 +11643,8 @@ using value_type = pair; using key_compare = Compare; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = @\impdefx{type of \tcode{map::size_type}}@; // see \ref{container.requirements} @@ -10334,174 +11659,179 @@ class value_compare { 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); - 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(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); + constexpr map(const map& x); + constexpr map(map&& x); + constexpr explicit map(const 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 - 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; + constexpr optional lookup(const key_type& x); + constexpr optional lookup(const key_type& x) const; + template constexpr optional lookup(const K& x); + template constexpr optional lookup(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>, @@ -10509,7 +11839,7 @@ map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator()) -> map<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, Compare, Allocator>; - template, + template>, class Allocator = allocator<@\exposid{range-to-alloc-type}@>> map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) -> map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Compare, Allocator>; @@ -10540,7 +11870,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} @@ -10558,8 +11888,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} @@ -10583,7 +11913,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} @@ -10603,7 +11934,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} @@ -10614,7 +11945,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} @@ -10625,7 +11956,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} @@ -10641,8 +11972,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} @@ -10662,8 +11993,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} @@ -10690,14 +12021,43 @@ Logarithmic. \end{itemdescr} +\indexlibrarymember{lookup}{map}% +\begin{itemdecl} +constexpr optional lookup(const key_type& x); +constexpr optional lookup(const key_type& x) const; +template constexpr optional lookup(const K& x); +template constexpr optional lookup(const K& x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +For the third and fourth overloads, +the \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. + +\pnum +\expects +The expression \tcode{find(x)} is well-formed and has well-defined behavior. + +\pnum +\returns +\tcode{find(x)->second} if \tcode{contains(x)} is \tcode{true}, +otherwise \tcode{nullopt}. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + \rSec3[map.modifiers]{Modifiers} \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} @@ -10715,9 +12075,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} @@ -10753,9 +12113,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} @@ -10791,9 +12151,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} @@ -10840,9 +12200,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} @@ -10880,9 +12240,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} @@ -10920,9 +12280,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} @@ -10971,7 +12331,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} @@ -11041,6 +12401,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} @@ -11055,8 +12419,8 @@ using value_type = pair; using key_compare = Compare; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = @\impdefx{type of \tcode{multimap::size_type}}@; // see \ref{container.requirements} @@ -11070,141 +12434,140 @@ class value_compare { 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 - 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>, @@ -11244,7 +12607,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} @@ -11262,9 +12625,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} @@ -11289,7 +12651,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} @@ -11309,8 +12672,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} @@ -11331,7 +12694,7 @@ \begin{itemdecl} template typename multimap::size_type - erase_if(multimap& c, Predicate pred); + constexpr erase_if(multimap& c, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -11364,20 +12727,21 @@ class set; template - bool operator==(const set& x, - const set& y); + constexpr bool operator==(const set& x, + const set& y); template - @\placeholder{synth-three-way-result}@ operator<=>(const set& x, - @\itcorr@ const set& y); + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const set& x, + const set& y); template - void swap(set& x, - set& y) + constexpr void swap(set& x, + set& y) noexcept(noexcept(x.swap(y))); // \ref{set.erasure}, erasure for \tcode{set} template - typename set::size_type + constexpr typename set::size_type erase_if(set& c, Predicate pred); // \ref{multiset}, class template \tcode{multiset} @@ -11385,20 +12749,21 @@ class multiset; template - bool operator==(const multiset& x, - const multiset& y); + constexpr bool operator==(const multiset& x, + const multiset& y); template - @\placeholder{synth-three-way-result}@ operator<=>(const multiset& x, - @\itcorr@ const multiset& y); + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const multiset& x, + const multiset& y); template - void swap(multiset& x, - multiset& y) + constexpr void swap(multiset& x, + multiset& y) noexcept(noexcept(x.swap(y))); // \ref{multiset.erasure}, erasure for \tcode{multiset} template - typename multiset::size_type + constexpr typename multiset::size_type erase_if(multiset& c, Predicate pred); namespace pmr { @@ -11429,7 +12794,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} @@ -11456,6 +12821,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, @@ -11468,8 +12837,8 @@ using value_type = Key; using value_compare = Compare; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = @\impdefx{type of \tcode{set::size_type}}@; // see \ref{container.requirements} @@ -11482,130 +12851,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 - 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} @@ -11686,7 +13057,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} @@ -11706,7 +13078,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} @@ -11731,8 +13103,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} @@ -11789,7 +13161,7 @@ A \tcode{multiset} 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 an allocator-aware container\iref{container.alloc.reqmts}, and of an associative container\iref{associative.reqmts}. \tcode{multiset} also provides most operations described in~\ref{associative.reqmts} @@ -11815,6 +13187,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, @@ -11827,8 +13203,8 @@ using value_type = Key; using value_compare = Compare; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = @\impdefx{type of \tcode{multiset::size_type}}@; // see \ref{container.requirements} @@ -11840,129 +13216,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 - 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} @@ -12043,7 +13420,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} @@ -12064,7 +13442,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} @@ -12130,31 +13508,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 { @@ -12209,6 +13587,11 @@ are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator}, \tcode{const_iterator}, +\tcode{local_iterator}, and \tcode{const_local_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_map}% \begin{codeblock} namespace std { @@ -12226,8 +13609,8 @@ using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = @\impdefx{type of \tcode{unordered_map::size_type}}@; // see \ref{container.requirements} @@ -12241,193 +13624,197 @@ 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@, - 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(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(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, - const allocator_type& a) + 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, - const allocator_type& a) + 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 - 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; + constexpr optional lookup(const key_type& k); + constexpr optional lookup(const key_type& k) const; + template constexpr optional lookup(const K& k); + template constexpr optional lookup(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} @@ -12574,7 +13957,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} @@ -12586,7 +13969,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} @@ -12598,7 +13981,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} @@ -12615,8 +13998,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} @@ -12632,8 +14015,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} @@ -12656,12 +14039,43 @@ if \tcode{find(k) == end()} is \tcode{true}. \end{itemdescr} +\indexlibrarymember{lookup}{unordered_map}% +\begin{itemdecl} +constexpr optional lookup(const key_type& k); +constexpr optional lookup(const key_type& k) const; +template constexpr optional lookup(const K& k); +template constexpr optional lookup(const K& k) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +For the third and fourth overloads, +the \grammarterm{qualified-id}s +\tcode{Hash::is_transparent} and \linebreak +\tcode{Pred::is_transparent} +are valid and denote types. + +\pnum +\expects +The expression \tcode{find(k)} is well-formed and has well-defined behavior. + +\pnum +\returns +\tcode{find(k)->second} if \tcode{contains(k)} is \tcode{true}, +otherwise \tcode{nullopt}. + +\pnum +\complexity +Average case constant, worst case linear in \tcode{size()}. +\end{itemdescr} + \rSec3[unord.map.modifiers]{Modifiers} \indexlibrarymember{unordered_map}{insert}% \begin{itemdecl} template - pair insert(P&& obj); + constexpr pair insert(P&& obj); \end{itemdecl} \begin{itemdescr} @@ -12678,7 +14092,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} @@ -12695,9 +14109,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} @@ -12733,9 +14147,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} @@ -12771,9 +14185,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} @@ -12820,9 +14234,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} @@ -12860,9 +14274,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} @@ -12900,9 +14314,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} @@ -12951,7 +14365,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} @@ -13004,6 +14418,11 @@ that are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator}, \tcode{const_iterator}, +\tcode{local_iterator}, and \tcode{const_local_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_multimap}% \begin{codeblock} namespace std { @@ -13021,8 +14440,8 @@ using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = @\impdefx{type of \tcode{unordered_multimap::size_type}}@; // see \ref{container.requirements} @@ -13035,162 +14454,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) - : 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, - 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) + template<@\exposconcept{container-compatible-range}@ R> + 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> + 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) { } + 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, - const allocator_type& a) + 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 - 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} @@ -13340,7 +14752,7 @@ \indexlibrarymember{unordered_multimap}{insert}% \begin{itemdecl} template - iterator insert(P&& obj); + constexpr iterator insert(P&& obj); \end{itemdecl} \begin{itemdescr} @@ -13356,7 +14768,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} @@ -13375,7 +14787,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} @@ -13421,31 +14833,31 @@ class unordered_multiset; template - bool operator==(const unordered_set& a, - const unordered_set& b); + constexpr bool operator==(const unordered_set& a, + const unordered_set& b); template - bool operator==(const unordered_multiset& a, - const unordered_multiset& b); + constexpr bool operator==(const unordered_multiset& a, + const unordered_multiset& b); template - void swap(unordered_set& x, - unordered_set& y) + constexpr void swap(unordered_set& x, + unordered_set& y) noexcept(noexcept(x.swap(y))); template - void swap(unordered_multiset& x, - unordered_multiset& y) + constexpr 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 + constexpr 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 + constexpr typename unordered_multiset::size_type erase_if(unordered_multiset& c, Predicate pred); namespace pmr { @@ -13482,7 +14894,7 @@ \pnum An \tcode{unordered_set} meets all of the requirements of a container\iref{container.reqmts}, -of an allocator-aware container\iref{container.alloc.reqmts}, +of an allocator-aware container\iref{container.alloc.reqmts}, and of an unordered associative container\iref{unord.req}. It provides the operations described in the preceding requirements table for unique keys; that is, an \tcode{unordered_set} supports the \tcode{a_uniq} operations in that table, @@ -13497,6 +14909,11 @@ are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator}, \tcode{const_iterator}, +\tcode{local_iterator}, and \tcode{const_local_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_set}% \begin{codeblock} namespace std { @@ -13512,8 +14929,8 @@ using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = @\impdefx{type of \tcode{unordered_set::size_type}}@; // see \ref{container.requirements} @@ -13527,161 +14944,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) - : unordered_set(f, l, n, hf, key_equal(), a) { } - unordered_set(initializer_list il, size_type n, 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) { } + 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 - 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>, class Allocator = allocator>> unordered_set(from_range_t, R&&, typename @\seebelow@::size_type = @\seebelow@, -Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) -> unordered_set, Hash, Pred, Allocator>; template, @@ -13755,11 +15170,10 @@ \indexlibraryctor{unordered_set}% \begin{itemdecl} -unordered_set() : unordered_set(size_type(@\seebelow@)) { } -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() : unordered_set(size_type(@\seebelow@)) { } +constexpr explicit unordered_set(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -13780,22 +15194,19 @@ \indexlibraryctor{unordered_set}% \begin{itemdecl} 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} @@ -13820,7 +15231,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} @@ -13845,8 +15256,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} @@ -13919,6 +15330,11 @@ are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator}, \tcode{const_iterator}, +\tcode{local_iterator}, and \tcode{const_local_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_multiset}% \begin{codeblock} namespace std { @@ -13934,8 +15350,8 @@ using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename allocator_traits::pointer; - using const_pointer = typename allocator_traits::const_pointer; + using pointer = allocator_traits::pointer; + using const_pointer = allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = @\impdefx{type of \tcode{unordered_multiset::size_type}}@; // see \ref{container.requirements} @@ -13948,168 +15364,165 @@ 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) - : unordered_multiset(f, l, n, hf, key_equal(), 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, - const allocator_type& a) + 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 - 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>, class Pred = equal_to<@\placeholder{iter-value-type}@>, class Allocator = allocator<@\placeholder{iter-value-type}@>> - unordered_multiset(InputIterator, InputIterator, @\seebelow@::size_type = @\seebelow@, + unordered_multiset(InputIterator, InputIterator, typename @\seebelow@::size_type = @\seebelow@, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) -> unordered_multiset<@\placeholder{iter-value-type}@, Hash, Pred, Allocator>; @@ -14176,11 +15589,10 @@ \indexlibraryctor{unordered_multiset}% \begin{itemdecl} -unordered_multiset() : unordered_multiset(size_type(@\seebelow@)) { } -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() : unordered_multiset(size_type(@\seebelow@)) { } +constexpr explicit unordered_multiset(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -14201,22 +15613,19 @@ \indexlibraryctor{unordered_multiset}% \begin{itemdecl} 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} @@ -14241,7 +15650,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} @@ -14335,8 +15744,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 @@ -14356,8 +15765,7 @@ may appear in deduction guides for container adaptors: \begin{codeblock} template - using @\exposid{alloc-rebind}@ = // \expos - typename allocator_traits::template rebind_alloc; + using @\exposid{alloc-rebind}@ = allocator_traits::template rebind_alloc; // \expos \end{codeblock} \rSec2[queue.syn]{Header \tcode{} synopsis} @@ -14372,23 +15780,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>; @@ -14396,20 +15805,27 @@ template Container> struct formatter, charT>; + template + constexpr bool enable_nonlocking_formatter_optimization> = false; + // \ref{priority.queue}, class template \tcode{priority_queue} template, class Compare = less> class priority_queue; template - void swap(priority_queue& x, - priority_queue& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(priority_queue& x, + priority_queue& y) noexcept(noexcept(x.swap(y))); template struct uses_allocator, Alloc>; // \ref{container.adaptors.format}, formatter specialization for \tcode{priority_queue} template Container, class Compare> struct formatter, charT>; + + template + constexpr bool + enable_nonlocking_formatter_optimization> = false; } \end{codeblock} @@ -14438,45 +15854,45 @@ template> class queue { public: - using value_type = typename Container::value_type; - using reference = typename Container::reference; - using const_reference = typename Container::const_reference; - using size_type = typename Container::size_type; - using container_type = Container; + using value_type = Container::value_type; + using reference = Container::reference; + using const_reference = Container::const_reference; + using size_type = Container::size_type; + using container_type = Container; protected: 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&); - - 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); } }; @@ -14511,7 +15927,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -explicit queue(const Container& cont); +constexpr explicit queue(const Container& cont); \end{itemdecl} \begin{itemdescr} @@ -14522,7 +15938,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -explicit queue(Container&& cont); +constexpr explicit queue(Container&& cont); \end{itemdecl} \begin{itemdescr} @@ -14534,7 +15950,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} template - queue(InputIterator first, InputIterator last); + constexpr queue(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -14547,7 +15963,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} @@ -14564,7 +15980,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template explicit queue(const Alloc& a); +template constexpr explicit queue(const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14575,7 +15991,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} @@ -14587,7 +16003,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} @@ -14599,7 +16015,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} @@ -14611,7 +16027,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template queue(queue&& q, const Alloc& a); +template constexpr queue(queue&& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14624,7 +16040,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} @@ -14639,7 +16055,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} @@ -14654,7 +16070,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} @@ -14670,7 +16086,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} @@ -14682,7 +16098,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} @@ -14694,7 +16110,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} @@ -14706,7 +16122,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} @@ -14718,7 +16134,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} @@ -14730,8 +16146,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} @@ -14743,7 +16158,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} @@ -14758,7 +16173,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} @@ -14801,10 +16217,10 @@ class Compare = less> class priority_queue { public: - using value_type = typename Container::value_type; - using reference = typename Container::reference; - using const_reference = typename Container::const_reference; - using size_type = typename Container::size_type; + using value_type = Container::value_type; + using reference = Container::reference; + using const_reference = Container::const_reference; + using size_type = Container::size_type; using container_type = Container; using value_compare = Compare; @@ -14813,51 +16229,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&); - 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); } }; @@ -14915,8 +16334,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} @@ -14938,7 +16357,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} @@ -14958,9 +16377,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} @@ -14984,7 +16405,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} @@ -15007,7 +16428,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} @@ -15018,7 +16439,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} @@ -15030,7 +16451,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} @@ -15044,7 +16465,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} @@ -15057,7 +16478,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} @@ -15069,7 +16490,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} @@ -15082,7 +16503,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} @@ -15099,7 +16520,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} @@ -15116,8 +16538,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} @@ -15133,8 +16555,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} @@ -15151,7 +16573,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} @@ -15165,7 +16587,7 @@ \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} @@ -15181,7 +16603,7 @@ \indexlibrarymember{push}{priority_queue}% \begin{itemdecl} -void push(const value_type& x); +constexpr void push(const value_type& x); \end{itemdecl} \begin{itemdescr} @@ -15196,7 +16618,7 @@ \indexlibrarymember{push}{priority_queue}% \begin{itemdecl} -void push(value_type&& x); +constexpr void push(value_type&& x); \end{itemdecl} \begin{itemdescr} @@ -15212,7 +16634,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} @@ -15231,7 +16653,7 @@ \indexlibrarymember{emplace}{priority_queue}% \begin{itemdecl} -template void emplace(Args&&... args); +template constexpr void emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -15244,10 +16666,9 @@ \end{codeblock} \end{itemdescr} - \indexlibrarymember{pop}{priority_queue}% \begin{itemdecl} -void pop(); +constexpr void pop(); \end{itemdecl} \begin{itemdescr} @@ -15265,8 +16686,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} @@ -15292,29 +16713,33 @@ template> class stack; template - bool operator==(const stack& x, const stack& y); + constexpr bool operator==(const stack& x, const stack& y); template - bool operator!=(const stack& x, const stack& y); + constexpr bool operator!=(const stack& x, const stack& y); template - bool operator< (const stack& x, const stack& y); + constexpr bool operator< (const stack& x, const stack& y); template - bool operator> (const stack& x, const stack& y); + constexpr bool operator> (const stack& x, const stack& y); template - bool operator<=(const stack& x, const stack& y); + constexpr bool operator<=(const stack& x, const stack& y); template - bool operator>=(const stack& x, const stack& y); + constexpr bool operator>=(const stack& x, const stack& y); template - compare_three_way_result_t + constexpr compare_three_way_result_t operator<=>(const stack& x, const stack& y); template - void swap(stack& x, stack& y) noexcept(noexcept(x.swap(y))); + 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>; + + template + constexpr bool enable_nonlocking_formatter_optimization> = false; } \end{codeblock} @@ -15345,44 +16770,45 @@ template> class stack { public: - using value_type = typename Container::value_type; - using reference = typename Container::reference; - using const_reference = typename Container::const_reference; - using size_type = typename Container::size_type; + using value_type = Container::value_type; + using reference = Container::reference; + using const_reference = Container::const_reference; + using size_type = Container::size_type; using container_type = Container; protected: 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&); - - 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); } }; @@ -15417,7 +16843,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -explicit stack(const Container& cont); +constexpr explicit stack(const Container& cont); \end{itemdecl} \begin{itemdescr} @@ -15428,7 +16854,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -explicit stack(Container&& cont); +constexpr explicit stack(Container&& cont); \end{itemdecl} \begin{itemdescr} @@ -15440,7 +16866,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} template - stack(InputIterator first, InputIterator last); + constexpr stack(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -15453,7 +16879,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} @@ -15470,7 +16896,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template explicit stack(const Alloc& a); +template constexpr explicit stack(const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15481,7 +16907,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} @@ -15493,7 +16919,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} @@ -15505,7 +16931,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} @@ -15517,7 +16943,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template stack(stack&& s, const Alloc& a); +template constexpr stack(stack&& s, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15530,7 +16956,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} @@ -15545,7 +16971,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} @@ -15560,7 +16986,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} @@ -15576,7 +17002,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} @@ -15588,7 +17014,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} @@ -15600,7 +17026,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} @@ -15612,7 +17038,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} @@ -15624,7 +17050,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} @@ -15636,7 +17062,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} @@ -15648,7 +17074,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} @@ -15663,7 +17089,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} @@ -15700,7 +17127,7 @@ // \ref{flat.map.erasure}, erasure for \tcode{flat_map} template - typename flat_map::size_type + constexpr typename flat_map::size_type erase_if(flat_map& c, Predicate pred); // \ref{flat.multimap}, class template \tcode{flat_multimap} @@ -15719,7 +17146,7 @@ // \ref{flat.multimap.erasure}, erasure for \tcode{flat_multimap} template - typename flat_multimap::size_type + constexpr typename flat_multimap::size_type erase_if(flat_multimap& c, Predicate pred); } \end{codeblock} @@ -15794,7 +17221,9 @@ \pnum If any member function in \ref{flat.map.defn} exits via an exception -the invariants are restored. +the invariants of the object argument are restored. +For the move constructor and move assignment operator, +the invariants of both arguments are restored. \begin{note} This can result in the \tcode{flat_map} being emptied. \end{note} @@ -15825,13 +17254,17 @@ containers of different sizes is undefined. \pnum -The effect of calling a constructor or member function +The effect of calling a member function that takes a \tcode{sorted_unique_t} argument with a container, containers, or 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.map.defn]{Definition} \begin{codeblock} @@ -15858,11 +17291,11 @@ class value_compare { private: - key_compare @\exposid{comp}@; // \expos - value_compare(key_compare c) : @\exposid{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 { + constexpr bool operator()(const_reference x, const_reference y) const { return @\exposid{comp}@(x.first, y.first); } }; @@ -15873,225 +17306,243 @@ }; // \ref{flat.map.cons}, constructors - flat_map() : flat_map(key_compare()) { } + constexpr flat_map() : flat_map(key_compare()) { } - explicit flat_map(const key_compare& comp) + constexpr flat_map(const flat_map&); + constexpr flat_map(flat_map&&); + constexpr flat_map& operator=(const flat_map&); + constexpr flat_map& operator=(flat_map&&); + + constexpr explicit flat_map(const key_compare& comp) : @\exposid{c}@(), @\exposid{compare}@(comp) { } - 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()); - flat_map(sorted_unique_t, 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 - flat_map(InputIterator first, InputIterator last, const key_compare& comp = key_compare()) + constexpr flat_map(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } template - flat_map(sorted_unique_t s, InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) - : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(s, first, last); } + 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, R&& rg) + 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)); } - flat_map(initializer_list il, const key_compare& comp = key_compare()) - : flat_map(il.begin(), il.end(), comp) { } + constexpr flat_map(initializer_list il, const key_compare& comp = key_compare()) + : flat_map(il.begin(), il.end(), comp) { } - flat_map(sorted_unique_t s, initializer_list il, - const key_compare& comp = key_compare()) - : flat_map(s, il.begin(), il.end(), comp) { } + 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 - explicit flat_map(const Alloc& a); + constexpr explicit flat_map(const Alloc& a); template - flat_map(const key_compare& comp, const Alloc& a); + constexpr flat_map(const key_compare& comp, const Alloc& a); template - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Alloc& a); + constexpr flat_map(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const Alloc& a); template - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + constexpr flat_map(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); template - flat_map(sorted_unique_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const Alloc& a); + constexpr flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); template - flat_map(sorted_unique_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + 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 - flat_map(const flat_map&, const Alloc& a); + constexpr flat_map(const flat_map&, const Alloc& a); template - flat_map(flat_map&&, const Alloc& a); + constexpr flat_map(flat_map&&, const Alloc& a); template - flat_map(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a); template - flat_map(InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_map(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template - flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const Alloc& a); template - flat_map(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + 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> - flat_map(from_range_t, R&& rg, const Alloc& a); + constexpr flat_map(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template - flat_map(initializer_list il, const Alloc& a); + constexpr flat_map(initializer_list il, const Alloc& a); template - flat_map(initializer_list il, const key_compare& comp, const Alloc& a); + constexpr flat_map(initializer_list il, const key_compare& comp, + const Alloc& a); template - flat_map(sorted_unique_t, initializer_list il, const Alloc& a); + constexpr flat_map(sorted_unique_t, initializer_list il, const Alloc& a); template - flat_map(sorted_unique_t, initializer_list il, - const key_compare& comp, const Alloc& a); + constexpr flat_map(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); - flat_map& operator=(initializer_list); + 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 - 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; + constexpr optional lookup(const key_type& x); + constexpr optional lookup(const key_type& x) const; + template constexpr optional lookup(const K& x); + template constexpr optional lookup(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); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(sorted_unique_t, 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); + constexpr 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); + 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_map& y) noexcept; - void clear() noexcept; + constexpr void swap(flat_map& y) noexcept(@\seebelow@); + 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 @\exposid{c}@.keys; } - const mapped_container_type& values() const noexcept { return @\exposid{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; - - size_type count(const key_type& x) const; - template size_type count(const K& x) const; - - bool contains(const key_type& x) const; - template 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; - - 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; - - 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; + 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); + friend constexpr bool operator==(const flat_map& x, const flat_map& y); - friend @\exposid{synth-three-way-result}@ + friend constexpr @\exposid{synth-three-way-result}@ operator<=>(const flat_map& x, const flat_map& y); - friend void swap(flat_map& x, flat_map& y) noexcept + friend constexpr void swap(flat_map& x, flat_map& y) noexcept(noexcept(x.swap(y))) { x.swap(y); } private: @@ -16099,8 +17550,8 @@ key_compare @\exposid{compare}@; // \expos struct @\exposid{key-equiv}@ { // \expos - @\exposid{key-equiv}@(key_compare c) : comp(c) { } - bool operator()(const_reference x, const_reference y) const { + 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; @@ -16164,10 +17615,10 @@ template> flat_map(sorted_unique_t, initializer_list>, Compare = Compare()) - -> flat_map; + -> flat_map; template + class Allocator> struct uses_allocator, Allocator> : bool_constant && uses_allocator_v> { }; @@ -16183,8 +17634,8 @@ \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} @@ -16213,8 +17664,8 @@ \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()); +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} @@ -16240,11 +17691,11 @@ \indexlibraryctor{flat_map}% \begin{itemdecl} template - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Alloc& a); + constexpr flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const Alloc& a); template - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + 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} @@ -16264,19 +17715,19 @@ \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 Alloc& a); + constexpr flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& 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 Alloc& a); + 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 \effects -Equivalent to \tcode{flat_map(s, key_cont, mapped_cont)} and -\tcode{flat_map(s, key_cont, \linebreak{}mapped_cont, comp)}, respectively, +Equivalent to \tcode{flat_map(sorted_unique, key_cont, mapped_cont)} and +\tcode{flat_map(sorted_unique, 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}. @@ -16288,35 +17739,36 @@ \indexlibraryctor{flat_map}% \begin{itemdecl} template - explicit flat_map(const Alloc& a); + constexpr explicit flat_map(const Alloc& a); template - flat_map(const key_compare& comp, const Alloc& a); + constexpr flat_map(const key_compare& comp, const Alloc& a); template - flat_map(const flat_map&, const Alloc& a); + constexpr flat_map(const flat_map&, const Alloc& a); template - flat_map(flat_map&&, const Alloc& a); + constexpr flat_map(flat_map&&, const Alloc& a); template - flat_map(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a); template - flat_map(InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); + constexpr flat_map(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); template - flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); template - flat_map(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + 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> - flat_map(from_range_t, R&& rg, const Alloc& a); + constexpr flat_map(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template - flat_map(initializer_list il, const Alloc& a); + constexpr flat_map(initializer_list il, const Alloc& a); template - flat_map(initializer_list il, const key_compare& comp, const Alloc& a); + constexpr flat_map(initializer_list il, const key_compare& comp, const Alloc& a); template - flat_map(sorted_unique_t, initializer_list il, const Alloc& a); + constexpr flat_map(sorted_unique_t, initializer_list il, const Alloc& a); template - flat_map(sorted_unique_t, initializer_list il, - const key_compare& comp, const Alloc& a); + constexpr flat_map(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -16331,7 +17783,7 @@ \indexlibrarymember{size}{flat_map}% \begin{itemdecl} -size_type size() const noexcept; +constexpr size_type size() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16342,7 +17794,7 @@ \indexlibrarymember{max_size}{flat_map}% \begin{itemdecl} -size_type max_size() const noexcept; +constexpr size_type max_size() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16355,7 +17807,7 @@ \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} @@ -16366,7 +17818,7 @@ \indexlibrarymember{operator[]}{flat_map}% \begin{itemdecl} -mapped_type& operator[](key_type&& x); +constexpr mapped_type& operator[](key_type&& x); \end{itemdecl} \begin{itemdescr} @@ -16377,7 +17829,7 @@ \indexlibrarymember{operator[]}{flat_map}% \begin{itemdecl} -template mapped_type& operator[](K&& x); +template constexpr mapped_type& operator[](K&& x); \end{itemdecl} \begin{itemdescr} @@ -16393,8 +17845,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} @@ -16415,8 +17867,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} @@ -16444,11 +17896,40 @@ Logarithmic. \end{itemdescr} +\indexlibrarymember{lookup}{flat_map}% +\begin{itemdecl} +constexpr optional lookup(const key_type& x); +constexpr optional lookup(const key_type& x) const; +template constexpr optional lookup(const K& x); +template constexpr optional lookup(const K& x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +For the third and fourth overloads, +the \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. + +\pnum +\expects +The expression \tcode{find(x)} is well-formed and has well-defined behavior. + +\pnum +\returns +\tcode{find(x)->second} if \tcode{contains(x)} is \tcode{true}, +otherwise \tcode{nullopt}. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + \rSec3[flat.map.modifiers]{Modifiers} \indexlibrarymember{emplace}{flat_map}% \begin{itemdecl} -template pair emplace(Args&&... args); +template constexpr pair emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -16481,8 +17962,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} @@ -16500,7 +17981,7 @@ \indexlibrarymember{insert}{flat_map}% \begin{itemdecl} template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -16541,44 +18022,23 @@ \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 \exposid{c} as if by: -\begin{codeblock} -for (; first != last; ++first) { - value_type value = *first; - @\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(@\exposid{c}@.keys, @\exposid{c}@.values); -auto it = ranges::unique(zv, @\exposid{key-equiv}@(@\exposid{compare}@)).begin(); -auto dist = distance(zv.begin(), it); -@\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} +Equivalent to \tcode{insert(first, last)}. \pnum \complexity Linear in $N$, where $N$ is \tcode{size()} after the operation. - -\pnum -\remarks -Since this operation performs an in-place merge, it may allocate memory. \end{itemdescr} \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} @@ -16586,10 +18046,10 @@ \effects Adds elements to \exposid{c} as if by: \begin{codeblock} -for (const auto& e : rg) { - @\exposid{c}@.keys.insert(@\exposid{c}@.keys.end(), e.first); - @\exposid{c}@.values.insert(@\exposid{c}@.values.end(), e.second); -} +ranges::for_each(rg, [&](value_type e) { + @\exposid{c}@.keys.insert(@\exposid{c}@.keys.end(), std::move(e.first)); + @\exposid{c}@.values.insert(@\exposid{c}@.values.end(), std::move(e.second)); +}); \end{codeblock} Then, sorts the range of newly inserted elements with respect to \tcode{value_comp()}; @@ -16615,16 +18075,32 @@ Since this operation performs an in-place merge, it may allocate memory. \end{itemdescr} +\indexlibrarymember{insert_range}{flat_map}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(sorted_unique_t, R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{insert_range(rg)}. + +\pnum +\complexity +Linear in $N$, where $N$ is \tcode{size()} after the operation. +\end{itemdescr} + \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} @@ -16661,9 +18137,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} @@ -16695,7 +18171,7 @@ \tcode{*this} and \tcode{args...} are unchanged. Otherwise equivalent to: \begin{codeblock} -auto key_it = ranges::upper_bound(@\exposid{c}@.keys, k, @\exposid{compare}@); +auto key_it = upper_bound(@\exposid{c}@.keys.begin(), @\exposid{c}@.keys.end(), 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)...); @@ -16717,13 +18193,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} @@ -16762,9 +18238,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} @@ -16817,7 +18293,10 @@ \indexlibrarymember{swap}{flat_map}% \begin{itemdecl} -void swap(flat_map& y) noexcept; +constexpr void swap(flat_map& y) + noexcept(is_nothrow_swappable_v && + is_nothrow_swappable_v && + is_nothrow_swappable_v); \end{itemdecl} \begin{itemdescr} @@ -16833,7 +18312,7 @@ \indexlibrarymember{extract}{flat_map}% \begin{itemdecl} -containers extract() &&; +constexpr containers extract() &&; \end{itemdecl} \begin{itemdescr} @@ -16848,7 +18327,7 @@ \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} @@ -16873,7 +18352,7 @@ \begin{itemdecl} template - typename flat_map::size_type + constexpr typename flat_map::size_type erase_if(flat_map& c, Predicate pred); \end{itemdecl} @@ -16979,7 +18458,9 @@ \pnum If any member function in \ref{flat.multimap.defn} exits via an exception, -the invariants are restored. +the invariants of the object argument are restored. +For the move constructor and move assignment operator, +the invariants of both arguments are restored. \begin{note} This can result in the \tcode{flat_multimap} being emptied. \end{note} @@ -17010,11 +18491,15 @@ with containers of different sizes is undefined. \pnum -The effect of calling a constructor or member function +The effect of calling a member function that takes a \tcode{sorted_equivalent_t} argument 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} @@ -17041,11 +18526,11 @@ class value_compare { private: - key_compare @\exposid{comp}@; // \expos - value_compare(key_compare c) : @\exposid{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 { + constexpr bool operator()(const_reference x, const_reference y) const { return @\exposid{comp}@(x.first, y.first); } }; @@ -17056,198 +18541,212 @@ }; // \ref{flat.multimap.cons}, constructors - flat_multimap() : flat_multimap(key_compare()) { } + constexpr flat_multimap() : flat_multimap(key_compare()) { } + + constexpr flat_multimap(const flat_multimap&); + constexpr flat_multimap(flat_multimap&&); + constexpr flat_multimap& operator=(const flat_multimap&); + constexpr flat_multimap& operator=(flat_multimap&&); - explicit flat_multimap(const key_compare& comp) + 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()); + constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); - flat_multimap(sorted_equivalent_t, - 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(InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) + constexpr flat_multimap(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } template - flat_multimap(sorted_equivalent_t s, InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) - : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(s, first, last); } + 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, R&& rg) + 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)); } - flat_multimap(initializer_list il, const key_compare& comp = key_compare()) - : flat_multimap(il.begin(), il.end(), comp) { } + constexpr flat_multimap(initializer_list il, + const key_compare& comp = key_compare()) + : flat_multimap(il.begin(), il.end(), comp) { } - flat_multimap(sorted_equivalent_t s, initializer_list il, - const key_compare& comp = key_compare()) - : flat_multimap(s, il.begin(), il.end(), comp) { } + 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 - explicit flat_multimap(const Alloc& a); + constexpr explicit flat_multimap(const Alloc& a); template - flat_multimap(const key_compare& comp, const Alloc& a); + constexpr flat_multimap(const key_compare& comp, const Alloc& a); template - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Alloc& a); + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); template - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); template - flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); template - flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + 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 - flat_multimap(const flat_multimap&, const Alloc& a); + constexpr flat_multimap(const flat_multimap&, const Alloc& a); template - flat_multimap(flat_multimap&&, const Alloc& a); + constexpr flat_multimap(flat_multimap&&, const Alloc& a); template - flat_multimap(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); template - flat_multimap(InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_multimap(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); template - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + 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> - flat_multimap(from_range_t, R&& rg, const Alloc& a); + constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template - flat_multimap(initializer_list il, const Alloc& a); + constexpr flat_multimap(initializer_list il, const Alloc& a); template - flat_multimap(initializer_list il, const key_compare& comp, - const Alloc& a); + constexpr flat_multimap(initializer_list il, const key_compare& comp, + const Alloc& a); template - flat_multimap(sorted_equivalent_t, initializer_list il, const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, + const Alloc& a); template - flat_multimap(sorted_equivalent_t, initializer_list il, - const key_compare& comp, const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); - flat_multimap& operator=(initializer_list); + constexpr 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 - 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); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(sorted_equivalent_t, 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(is_nothrow_swappable_v && + is_nothrow_swappable_v && + is_nothrow_swappable_v); + 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 @\exposid{c}@.keys; } - const mapped_container_type& values() const noexcept { return @\exposid{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); + friend constexpr bool operator==(const flat_multimap& x, const flat_multimap& y); - friend @\exposid{synth-three-way-result}@ + friend constexpr @\exposid{synth-three-way-result}@ operator<=>(const flat_multimap& x, const flat_multimap& y); - friend void swap(flat_multimap& x, flat_multimap& y) noexcept + friend constexpr void swap(flat_multimap& x, flat_multimap& y) + noexcept(noexcept(x.swap(y))) { x.swap(y); } private: @@ -17316,10 +18815,10 @@ template> flat_multimap(sorted_equivalent_t, initializer_list>, Compare = Compare()) - -> flat_multimap; + -> flat_multimap; template + class Allocator> struct uses_allocator, Allocator> : bool_constant && @@ -17336,8 +18835,8 @@ \indexlibraryctor{flat_multimap}% \begin{itemdecl} -flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); +constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} @@ -17358,8 +18857,9 @@ \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()); +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} @@ -17385,11 +18885,12 @@ \indexlibraryctor{flat_multimap}% \begin{itemdecl} template - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Alloc& a); + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); template - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + 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} @@ -17409,19 +18910,19 @@ \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 Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); template - flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const key_compare& comp, - const Alloc& a); + 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); \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to \tcode{flat_multimap(s, key_cont, mapped_cont)} and -\tcode{flat_multimap(s, key_cont, mapped_cont, comp)}, respectively, +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}. @@ -17433,37 +18934,38 @@ \indexlibraryctor{flat_multimap}% \begin{itemdecl} template - explicit flat_multimap(const Alloc& a); + constexpr explicit flat_multimap(const Alloc& a); template - flat_multimap(const key_compare& comp, const Alloc& a); + constexpr flat_multimap(const key_compare& comp, const Alloc& a); template - flat_multimap(const flat_multimap&, const Alloc& a); + constexpr flat_multimap(const flat_multimap&, const Alloc& a); template - flat_multimap(flat_multimap&&, const Alloc& a); + constexpr flat_multimap(flat_multimap&&, const Alloc& a); template - flat_multimap(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); template - flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, - const Alloc& a); + constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); template - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); template - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + 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> - flat_multimap(from_range_t, R&& rg, const Alloc& a); + constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template - flat_multimap(initializer_list il, const Alloc& a); + constexpr flat_multimap(initializer_list il, const Alloc& a); template - flat_multimap(initializer_list il, const key_compare& comp, const Alloc& a); + constexpr flat_multimap(initializer_list il, const key_compare& comp, + const Alloc& a); template - flat_multimap(sorted_equivalent_t, initializer_list il, const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, const Alloc& a); template - flat_multimap(sorted_equivalent_t, initializer_list il, - const key_compare& comp, const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -17480,7 +18982,7 @@ \begin{itemdecl} template - typename flat_multimap::size_type + constexpr typename flat_multimap::size_type erase_if(flat_multimap& c, Predicate pred); \end{itemdecl} @@ -17533,7 +19035,7 @@ // \ref{flat.set.erasure}, erasure for \tcode{flat_set} template - typename flat_set::size_type + constexpr typename flat_set::size_type erase_if(flat_set& c, Predicate pred); // \ref{flat.multiset}, class template \tcode{flat_multiset} @@ -17548,7 +19050,7 @@ // \ref{flat.multiset.erasure}, erasure for \tcode{flat_multiset} template - typename flat_multiset::size_type + constexpr typename flat_multiset::size_type erase_if(flat_multiset& c, Predicate pred); } \end{codeblock} @@ -17612,7 +19114,9 @@ \pnum If any member function in \ref{flat.set.defn} exits via an exception, -the invariant is restored. +the invariant of the object argument is restored. +For the move constructor and move assignment operator, +the invariants of both arguments are restored. \begin{note} This can result in the \tcode{flat_set}'s being emptied. \end{note} @@ -17632,11 +19136,15 @@ as \tcode{KeyContainer::value_type}. \pnum -The effect of calling a constructor or member function +The effect of calling a member function that takes a \tcode{sorted_unique_t} argument 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} @@ -17645,201 +19153,213 @@ class @\libglobal{flat_set}@ { public: // types - using key_type = Key; - using value_type = Key; - using key_compare = Compare; - using value_compare = Compare; - using reference = value_type&; - using const_reference = const value_type&; - using size_type = typename KeyContainer::size_type; - using difference_type = typename KeyContainer::difference_type; - using iterator = @\impdefx{type of \tcode{flat_set::iterator}}@; // see \ref{container.requirements} - using const_iterator = @\impdefx{type of \tcode{flat_set::const_iterator}}@; // see \ref{container.requirements} - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - using container_type = KeyContainer; + using key_type = Key; + using value_type = Key; + using key_compare = Compare; + using value_compare = Compare; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = KeyContainer::size_type; + using difference_type = KeyContainer::difference_type; + using iterator = @\impdefx{type of \tcode{flat_set::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{flat_set::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using container_type = KeyContainer; // \ref{flat.set.cons}, constructors - flat_set() : flat_set(key_compare()) { } + constexpr flat_set() : flat_set(key_compare()) { } - explicit flat_set(const key_compare& comp) + constexpr flat_set(const flat_set&); + constexpr flat_set(flat_set&&); + constexpr flat_set& operator=(const flat_set&); + constexpr flat_set& operator=(flat_set&&); + + 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()); + 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(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(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) + 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, R&& rg) + 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)); } - flat_set(initializer_list il, const key_compare& comp = key_compare()) - : flat_set(il.begin(), il.end(), comp) { } + constexpr flat_set(initializer_list il, const key_compare& comp = key_compare()) + : flat_set(il.begin(), il.end(), comp) { } - flat_set(sorted_unique_t s, initializer_list il, - const key_compare& comp = key_compare()) - : flat_set(s, il.begin(), il.end(), comp) { } + constexpr flat_set(sorted_unique_t, initializer_list il, + const key_compare& comp = key_compare()) + : flat_set(sorted_unique, il.begin(), il.end(), comp) { } // \ref{flat.set.cons.alloc}, constructors with allocators template - explicit flat_set(const Alloc& a); + constexpr explicit flat_set(const Alloc& a); template - flat_set(const key_compare& comp, const Alloc& a); + constexpr flat_set(const key_compare& comp, const Alloc& a); template - flat_set(const container_type& cont, const Alloc& a); + constexpr flat_set(const container_type& cont, const Alloc& a); template - flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); + constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); template - flat_set(sorted_unique_t, const container_type& cont, const Alloc& a); + constexpr flat_set(sorted_unique_t, const container_type& cont, const Alloc& a); template - flat_set(sorted_unique_t, const container_type& cont, - const key_compare& comp, const Alloc& a); + constexpr flat_set(sorted_unique_t, const container_type& cont, + const key_compare& comp, const Alloc& a); template - flat_set(const flat_set&, const Alloc& a); + constexpr flat_set(const flat_set&, const Alloc& a); template - flat_set(flat_set&&, const Alloc& a); + constexpr flat_set(flat_set&&, const Alloc& a); template - flat_set(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a); template - flat_set(InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_set(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template - flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const Alloc& a); template - flat_set(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + 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> - flat_set(from_range_t, R&& rg, const Alloc& a); + constexpr flat_set(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template - flat_set(initializer_list il, const Alloc& a); + constexpr flat_set(initializer_list il, const Alloc& a); template - flat_set(initializer_list il, const key_compare& comp, const Alloc& a); + constexpr flat_set(initializer_list il, const key_compare& comp, + const Alloc& a); template - flat_set(sorted_unique_t, initializer_list il, const Alloc& a); + constexpr flat_set(sorted_unique_t, initializer_list il, const Alloc& a); template - flat_set(sorted_unique_t, initializer_list il, - const key_compare& comp, const Alloc& a); + constexpr flat_set(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); - flat_set& operator=(initializer_list); + 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 - 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); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(sorted_unique_t, 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) requires (!@\libconcept{same_as}@); + 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(@\seebelow@); + 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); + friend constexpr bool operator==(const flat_set& x, const flat_set& y); - friend @\placeholder{synth-three-way-result}@ + friend constexpr @\exposid{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); } + friend constexpr void swap(flat_set& x, flat_set& y) noexcept(noexcept(x.swap(y))) + { x.swap(y); } private: container_type @\exposidnc{c}@; // \expos @@ -17907,7 +19427,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} @@ -17934,9 +19454,9 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} template - flat_set(const container_type& cont, const Alloc& a); + constexpr flat_set(const container_type& cont, const Alloc& a); template - flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); + constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -17955,17 +19475,18 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} template - flat_set(sorted_unique_t s, const container_type& cont, const Alloc& a); + constexpr flat_set(sorted_unique_t, const container_type& cont, const Alloc& a); template - flat_set(sorted_unique_t s, const container_type& cont, - const key_compare& comp, const Alloc& a); + constexpr flat_set(sorted_unique_t, const container_type& cont, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} \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,\linebreak comp)}, respectively, except that \exposid{c} is constructed with uses-allocator construction\iref{allocator.uses.construction}. @@ -17977,35 +19498,36 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} template - explicit flat_set(const Alloc& a); + constexpr explicit flat_set(const Alloc& a); template - flat_set(const key_compare& comp, const Alloc& a); + constexpr flat_set(const key_compare& comp, const Alloc& a); template - flat_set(const flat_set&, const Alloc& a); + constexpr flat_set(const flat_set&, const Alloc& a); template - flat_set(flat_set&&, const Alloc& a); + constexpr flat_set(flat_set&&, const Alloc& a); template - flat_set(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a); template - flat_set(InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); + constexpr flat_set(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); template - flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); template - flat_set(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + 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> - flat_set(from_range_t, R&& rg, const Alloc& a); + constexpr flat_set(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template - flat_set(initializer_list il, const Alloc& a); + constexpr flat_set(initializer_list il, const Alloc& a); template - flat_set(initializer_list il, const key_compare& comp, const Alloc& a); + constexpr flat_set(initializer_list il, const key_compare& comp, const Alloc& a); template - flat_set(sorted_unique_t, initializer_list il, const Alloc& a); + constexpr flat_set(sorted_unique_t, initializer_list il, const Alloc& a); template - flat_set(sorted_unique_t, initializer_list il, - const key_compare& comp, const Alloc& a); + constexpr flat_set(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -18020,8 +19542,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} @@ -18055,7 +19577,7 @@ \indexlibrarymember{insert}{flat_set}% \begin{itemdecl} template - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -18085,7 +19607,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} @@ -18101,7 +19623,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} @@ -18109,9 +19631,9 @@ \effects Adds elements to \exposid{c} as if by: \begin{codeblock} -for (const auto& e : rg) { - @\exposid{c}@.insert(@\exposid{c}@.end(), e); -} +ranges::for_each(rg, [&](value_type e) { + @\exposid{c}@.insert(@\exposid{c}@.end(), std::move(e)); +}); \end{codeblock} Then, sorts the range of newly inserted elements with respect to \exposid{compare}; @@ -18130,9 +19652,27 @@ Since this operation performs an in-place merge, it may allocate memory. \end{itemdescr} +\indexlibrarymember{insert_range}{flat_set}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(sorted_unique_t, R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{insert_range(rg)}. + +\pnum +\complexity +Linear in $N$, where $N$ is \tcode{size()} after the operation. +\end{itemdescr} + \indexlibrarymember{swap}{flat_set}% \begin{itemdecl} -void swap(flat_set& y) noexcept; +constexpr void swap(flat_set& y) + noexcept(is_nothrow_swappable_v && + is_nothrow_swappable_v); \end{itemdecl} \begin{itemdescr} @@ -18147,7 +19687,7 @@ \indexlibrarymember{extract}{flat_set}% \begin{itemdecl} -container_type extract() &&; +constexpr container_type extract() &&; \end{itemdecl} \begin{itemdescr} @@ -18162,7 +19702,7 @@ \indexlibrarymember{replace}{flat_set}% \begin{itemdecl} -void replace(container_type&& cont); +constexpr void replace(container_type&& cont); \end{itemdecl} \begin{itemdescr} @@ -18181,7 +19721,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} @@ -18272,7 +19812,9 @@ \pnum If any member function in \ref{flat.multiset.defn} exits via an exception, -the invariant is restored. +the invariant of the object argument is restored. +For the move constructor and move assignment operator, +the invariants of both arguments are restored. \begin{note} This can result in the \tcode{flat_multiset}'s being emptied. \end{note} @@ -18292,10 +19834,14 @@ as \tcode{KeyContainer::value_type}. \pnum -The effect of calling a constructor or member function +The effect of calling a member function 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} @@ -18304,203 +19850,215 @@ class flat_multiset { public: // types - using key_type = Key; - using value_type = Key; - using key_compare = Compare; - using value_compare = Compare; - using reference = value_type&; - using const_reference = const value_type&; - using size_type = typename KeyContainer::size_type; - using difference_type = typename KeyContainer::difference_type; - using iterator = @\impdefx{type of \tcode{flat_multiset::iterator}}@; // see \ref{container.requirements} - using const_iterator = @\impdefx{type of \tcode{flat_multiset::const_iterator}}@; // see \ref{container.requirements} - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - using container_type = KeyContainer; + using key_type = Key; + using value_type = Key; + using key_compare = Compare; + using value_compare = Compare; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = KeyContainer::size_type; + using difference_type = KeyContainer::difference_type; + using iterator = @\impdefx{type of \tcode{flat_multiset::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{flat_multiset::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using container_type = KeyContainer; // \ref{flat.multiset.cons}, constructors - flat_multiset() : flat_multiset(key_compare()) { } + constexpr flat_multiset() : flat_multiset(key_compare()) { } - explicit flat_multiset(const key_compare& comp) + constexpr flat_multiset(const flat_multiset&); + constexpr flat_multiset(flat_multiset&&); + constexpr flat_multiset& operator=(const flat_multiset&); + constexpr flat_multiset& operator=(flat_multiset&&); + + 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()); + 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(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(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) + 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, R&& rg) + 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)); } - 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) { } - flat_multiset(sorted_equivalent_t s, initializer_list il, - const key_compare& comp = key_compare()) - : flat_multiset(s, il.begin(), il.end(), comp) { } + 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 - explicit flat_multiset(const Alloc& a); + constexpr explicit flat_multiset(const Alloc& a); template - flat_multiset(const key_compare& comp, const Alloc& a); + constexpr flat_multiset(const key_compare& comp, const Alloc& a); template - flat_multiset(const container_type& cont, const Alloc& a); + constexpr flat_multiset(const container_type& cont, const Alloc& a); template - flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a); + constexpr flat_multiset(const container_type& cont, const key_compare& comp, + const Alloc& a); template - flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a); template - flat_multiset(sorted_equivalent_t, const container_type& cont, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, + const key_compare& comp, const Alloc& a); template - flat_multiset(const flat_multiset&, const Alloc& a); + constexpr flat_multiset(const flat_multiset&, const Alloc& a); template - flat_multiset(flat_multiset&&, const Alloc& a); + constexpr flat_multiset(flat_multiset&&, const Alloc& a); template - flat_multiset(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a); template - flat_multiset(InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); template - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + 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> - flat_multiset(from_range_t, R&& rg, const Alloc& a); + constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template - flat_multiset(initializer_list il, const Alloc& a); + constexpr flat_multiset(initializer_list il, const Alloc& a); template - flat_multiset(initializer_list il, const key_compare& comp, - const Alloc& a); + constexpr flat_multiset(initializer_list il, const key_compare& comp, + const Alloc& a); template - flat_multiset(sorted_equivalent_t, initializer_list il, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, + const Alloc& a); template - flat_multiset(sorted_equivalent_t, initializer_list il, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); - flat_multiset& operator=(initializer_list); + 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 - 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); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(sorted_equivalent_t, 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) requires (!@\libconcept{same_as}@); + 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(@\seebelow@); + 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); + friend constexpr bool operator==(const flat_multiset& x, const flat_multiset& y); - friend @\placeholder{synth-three-way-result}@ + friend constexpr @\exposid{synth-three-way-result}@ operator<=>(const flat_multiset& x, const flat_multiset& y); - friend void swap(flat_multiset& x, flat_multiset& y) noexcept + friend constexpr void swap(flat_multiset& x, flat_multiset& y) + noexcept(noexcept(x.swap(y))) { x.swap(y); } private: @@ -18556,7 +20114,7 @@ -> flat_multiset; template> - flat_multiset(sorted_equivalent_t, initializer_list, Compare = Compare()) + flat_multiset(sorted_equivalent_t, initializer_list, Compare = Compare()) -> flat_multiset; template @@ -18569,7 +20127,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} @@ -18594,9 +20152,9 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} template - flat_multiset(const container_type& cont, const Alloc& a); + constexpr flat_multiset(const container_type& cont, const Alloc& a); template - flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a); + constexpr flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -18616,17 +20174,17 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} template - flat_multiset(sorted_equivalent_t s, const container_type& cont, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a); template - flat_multiset(sorted_equivalent_t s, const container_type& cont, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} \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}. @@ -18638,36 +20196,38 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} template - explicit flat_multiset(const Alloc& a); + constexpr explicit flat_multiset(const Alloc& a); template - flat_multiset(const key_compare& comp, const Alloc& a); + constexpr flat_multiset(const key_compare& comp, const Alloc& a); template - flat_multiset(const flat_multiset&, const Alloc& a); + constexpr flat_multiset(const flat_multiset&, const Alloc& a); template - flat_multiset(flat_multiset&&, const Alloc& a); + constexpr flat_multiset(flat_multiset&&, const Alloc& a); template - flat_multiset(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a); template - flat_multiset(InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); template - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + 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> - flat_multiset(from_range_t, R&& rg, const Alloc& a); + constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@ R, class Alloc> - flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template - flat_multiset(initializer_list il, const Alloc& a); + constexpr flat_multiset(initializer_list il, const Alloc& a); template - flat_multiset(initializer_list il, const key_compare& comp, const Alloc& a); + constexpr flat_multiset(initializer_list il, const key_compare& comp, + const Alloc& a); template - flat_multiset(sorted_equivalent_t, initializer_list il, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, const Alloc& a); template - flat_multiset(sorted_equivalent_t, initializer_list il, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -18682,7 +20242,7 @@ \indexlibrarymember{emplace}{flat_multiset}% \begin{itemdecl} -template iterator emplace(Args&&... args); +template constexpr iterator emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -18692,23 +20252,66 @@ \pnum \effects -First, initializes an object \tcode{t} of type \tcode{value_type} -with \tcode{std::forward(args)...}, -then inserts \tcode{t} as if by: -\begin{codeblock} -auto it = ranges::upper_bound(@\exposid{c}@, t, @\exposid{compare}@); -@\exposid{c}@.insert(it, std::move(t)); -\end{codeblock} +First, initializes an object \tcode{t} of type \tcode{value_type} +with \tcode{std::forward(args)...}, +then inserts \tcode{t} as if by: +\begin{codeblock} +auto it = ranges::upper_bound(@\exposid{c}@, t, @\exposid{compare}@); +@\exposid{c}@.insert(it, std::move(t)); +\end{codeblock} + +\pnum +\returns +An iterator that points to the inserted element. +\end{itemdescr} + +\indexlibrarymember{insert}{flat_multiset}% +\begin{itemdecl} +template + constexpr void insert(InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Adds elements to \exposid{c} as if by: +\begin{codeblock} +@\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 +the sorted range of pre-existing elements into a single sorted range. + +\pnum +\complexity +$N$ + $M \log M$, where $N$ is \tcode{size()} before the operation and $M$ +is \tcode{distance(first, last)}. + +\pnum +\remarks +Since this operation performs an in-place merge, it may allocate memory. +\end{itemdescr} + +\indexlibrarymember{insert}{flat_multiset}% +\begin{itemdecl} +template + constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{insert(first, last)}. \pnum -\returns -An iterator that points to the inserted element. +\complexity +Linear in $N$, where $N$ is \tcode{size()} after the operation. \end{itemdescr} -\indexlibrarymember{insert}{flat_multiset}% +\indexlibrarymember{insert_range}{flat_multiset}% \begin{itemdecl} -template - void insert(InputIterator first, InputIterator last); +template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -18716,7 +20319,9 @@ \effects Adds elements to \exposid{c} as if by: \begin{codeblock} -@\exposid{c}@.insert(@\exposid{c}@.end(), first, last); +ranges::for_each(rg, [&](value_type e) { + @\exposid{c}@.insert(@\exposid{c}@.end(), std::move(e)); +}); \end{codeblock} Then, sorts the range of newly inserted elements with respect to \exposid{compare}, and merges the resulting sorted range and @@ -18725,32 +20330,35 @@ \pnum \complexity $N$ + $M \log M$, where $N$ is \tcode{size()} before the operation and $M$ -is \tcode{distance(first, last)}. +is \tcode{ranges::distance(rg)}. \pnum \remarks -Since this operation performs an in-place merge, it may allocate memory. +Since this operation performs an in-place merge, +it may allocate memory. \end{itemdescr} -\indexlibrarymember{insert}{flat_multiset}% +\indexlibrarymember{insert_range}{flat_multiset}% \begin{itemdecl} -template - void insert(sorted_equivalent_t, InputIterator first, InputIterator last); +template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(sorted_equivalent_t, R&& rg); \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to \tcode{insert(first, last)}. +Equivalent to \tcode{insert_range(rg)}. \pnum \complexity -Linear. +Linear in $N$, where $N$ is \tcode{size()} after the operation. \end{itemdescr} \indexlibrarymember{swap}{flat_multiset}% \begin{itemdecl} -void swap(flat_multiset& y) noexcept; +constexpr void swap(flat_multiset& y) + noexcept(is_nothrow_swappable_v && + is_nothrow_swappable_v); \end{itemdecl} \begin{itemdescr} @@ -18765,7 +20373,7 @@ \indexlibrarymember{extract}{flat_multiset}% \begin{itemdecl} -container_type extract() &&; +constexpr container_type extract() &&; \end{itemdecl} \begin{itemdescr} @@ -18780,7 +20388,7 @@ \indexlibrarymember{replace}{flat_multiset}% \begin{itemdecl} -void replace(container_type&& cont); +constexpr void replace(container_type&& cont); \end{itemdecl} \begin{itemdescr} @@ -18798,7 +20406,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} @@ -18837,7 +20445,7 @@ \tcode{queue}, \tcode{priority_queue}, and \tcode{stack}, -the library provides the following formatter specialization +the library provides the following constexpr-enabled formatter specialization where \tcode{\placeholder{adaptor-type}} is the name of the template: \indexlibraryglobal{formatter}% @@ -18859,7 +20467,7 @@ parse(ParseContext& ctx); template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(@\exposid{maybe-const-adaptor}@& r, FormatContext& ctx) const; }; } @@ -18881,7 +20489,7 @@ \indexlibrarymember{format}{formatter}% \begin{itemdecl} template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(@\exposid{maybe-const-adaptor}@& r, FormatContext& ctx) const; \end{itemdecl} @@ -18900,14 +20508,16 @@ The header \libheaderref{mdspan} defines the class template \tcode{mdspan} and other facilities for interacting with these multidimensional views. +\pnum +In addition to being available via inclusion of the \libheaderref{span} header, +\tcode{dynamic_extent} is available when the header \libheaderref{mdspan} is included. + \rSec2[views.contiguous]{Contiguous access} \rSec3[span.syn]{Header \tcode{} synopsis}% \indexheader{span}% \begin{codeblock} -#include // see \ref{initializer.list.syn} - // mostly freestanding namespace std { // constants @@ -18915,17 +20525,14 @@ template concept @\defexposconcept{integral-constant-like}@ = // \expos - is_integral_v && - !is_same_v> && - @\libconcept{convertible_to}@ && - @\libconcept{equality_comparable_with}@ && - bool_constant::value && - bool_constant(T()) == T::value>::value; + is_integral_v> && + !is_same_v> && + @\exposconcept{constexpr-wrapper-like}@; template - constexpr size_t @\defexposconcept{maybe-static-ext}@ = dynamic_extent; // \expos + constexpr size_t @\exposid{maybe-static-ext}@ = dynamic_extent; // \expos template<@\exposconcept{integral-constant-like}@ T> - constexpr size_t @\exposconcept{maybe-static-ext}@ = {T::value}; + constexpr size_t @\exposid{maybe-static-ext}@ = {T::value}; // \ref{views.span}, class template \tcode{span} template @@ -18994,7 +20601,6 @@ constexpr span(const array& arr) noexcept; template constexpr explicit(extent != dynamic_extent) span(R&& r); - constexpr explicit(extent != dynamic_extent) span(std::initializer_list il); constexpr span(const span& other) noexcept = default; template constexpr explicit(@\seebelow@) span(const span& s) noexcept; @@ -19043,7 +20649,7 @@ template span(It, EndOrSize) -> span>, - @\exposconcept{maybe-static-ext}@>; + @\exposid{maybe-static-ext}@>; template span(T (&)[N]) -> span; template @@ -19112,11 +20718,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 @@ -19152,14 +20760,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 @@ -19230,14 +20840,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 @@ -19248,27 +20861,6 @@ What and when \tcode{ranges::data(r)} and \tcode{ranges::size(r)} throw. \end{itemdescr} -\indexlibraryctor{span}% -\begin{itemdecl} -constexpr explicit(extent != dynamic_extent) span(std::initializer_list il); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\constraints -\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}. - -\pnum -\effects -Initializes \exposid{data_} with \tcode{il.begin()} and -\exposid{size_} with \tcode{il.size()}. -\end{itemdescr} - \indexlibraryctor{span}% \begin{itemdecl} constexpr span(const span& other) noexcept = default; @@ -19299,9 +20891,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 @@ -19337,7 +20929,7 @@ \begin{itemdecl} template span(It, EndOrSize) -> span>, - @\exposconcept{maybe-static-ext}@>; + @\exposid{maybe-static-ext}@>; \end{itemdecl} \begin{itemdescr} @@ -19371,12 +20963,12 @@ \tcode{Count <= Extent} is \tcode{true}. \pnum -\expects +\hardexpects \tcode{Count <= size()} is \tcode{true}. \pnum \effects -Equivalent to: \tcode{return R\{data(), Count\};} +Equivalent to: \tcode{return R(data(), Count);} where \tcode{R} is the return type. \end{itemdescr} @@ -19391,12 +20983,12 @@ \tcode{Count <= Extent} is \tcode{true}. \pnum -\expects +\hardexpects \tcode{Count <= size()} is \tcode{true}. \pnum \effects -Equivalent to: \tcode{return R\{data() + (size() - Count), Count\};} +Equivalent to: \tcode{return R(data() + (size() - Count), Count);} where \tcode{R} is the return type. \end{itemdescr} @@ -19415,7 +21007,7 @@ is \tcode{true}. \pnum -\expects +\hardexpects \begin{codeblock} Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset) \end{codeblock} @@ -19446,12 +21038,13 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{count <= size()} is \tcode{true}. \pnum \effects -Equivalent to: \tcode{return \{data(), count\};} +Equivalent to: \tcode{return R(data(), count);} +where \tcode{R} is the return type. \end{itemdescr} \indexlibrarymember{span}{last}% @@ -19461,12 +21054,13 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{count <= size()} is \tcode{true}. \pnum \effects -Equivalent to: \tcode{return \{data() + (size() - count), count\};} +Equivalent to: \tcode{return R(data() + (size() - count), count);} +where \tcode{R} is the return type. \end{itemdescr} \indexlibrarymember{span}{subspan}% @@ -19477,7 +21071,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \begin{codeblock} offset <= size() && (count == dynamic_extent || count <= size() - offset) \end{codeblock} @@ -19487,8 +21081,9 @@ \effects Equivalent to: \begin{codeblock} -return {data() + offset, count == dynamic_extent ? size() - offset : count}; +return R(data() + offset, count == dynamic_extent ? size() - offset : count); \end{codeblock} +where \tcode{R} is the return type. \end{itemdescr} \rSec4[span.obs]{Observers} @@ -19535,7 +21130,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{idx < size()} is \tcode{true}. \pnum @@ -19569,7 +21164,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{empty()} is \tcode{false}. \pnum @@ -19588,7 +21183,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{empty()} is \tcode{false}. \pnum @@ -19691,6 +21286,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_volatile_v} is \tcode{false}. + \pnum \effects Equivalent to: \tcode{return R\{reinterpret_cast(s.data()), s.size_bytes()\};} @@ -19707,7 +21306,8 @@ \begin{itemdescr} \pnum \constraints -\tcode{is_const_v} is \tcode{false}. +\tcode{is_const_v} is \tcode{false} and +\tcode{is_volatile_v} is \tcode{false}. \pnum \effects @@ -19752,7 +21352,7 @@ \indexheader{mdspan}% \begin{codeblock} -// all freestanding +// mostly freestanding namespace std { // \ref{mdspan.extents}, class template \tcode{extents} template @@ -19786,33 +21386,51 @@ // \ref{mdspan.mdspan}, class template \tcode{mdspan} template> - class mdspan; + class mdspan; // partially freestanding // \ref{mdspan.sub}, \tcode{submdspan} creation template - struct strided_slice; + struct extent_slice; + template> + struct range_slice; template struct submdspan_mapping_result; - struct full_extent_t { explicit full_extent_t() = default; }; - inline constexpr full_extent_t full_extent{}; + struct @\libglobal{full_extent_t}@ { explicit full_extent_t() = default; }; + inline constexpr full_extent_t @\libglobal{full_extent}@{}; + + template + constexpr auto subextents(const extents&, SliceSpecifiers...); - template - constexpr auto submdspan_extents(const extents&, SliceSpecifiers...); + // \ref{mdspan.sub.canonical}, \tcode{submdspan} slice canonicalization + template + constexpr auto canonical_slices(const extents& src, + SliceSpecifiers... slices); // \ref{mdspan.sub.sub}, \tcode{submdspan} function template template constexpr auto submdspan( const mdspan& src, - SliceSpecifiers... slices) -> @\seebelow@; + SliceSpecifiers... raw_slices) -> @\seebelow@; template concept @\defexposconcept{index-pair-like}@ = // \expos @\exposconcept{pair-like}@ && @\libconcept{convertible_to}@, IndexType> && @\libconcept{convertible_to}@, IndexType>; + + // \ref{mdspan.copy}, multidimensional copy algorithms + template + constexpr void copy(const Src& src, const Dst& dst); + template + void copy(ExecutionPolicy&& policy, const Src& src, const Dst& dst); + + template + constexpr void fill(const Dst& dst, const T& value); + template + void fill(ExecutionPolicy&& policy, const Dst& dst, const T& value); } \end{codeblock} @@ -19822,7 +21440,7 @@ The class template \tcode{extents} represents a multidimensional index space of rank equal to \tcode{sizeof...(Extents)}. -In \iref{views}, +In~\ref{views}, \tcode{extents} is used synonymously with multidimensional index space. \begin{codeblock} @@ -19830,13 +21448,13 @@ template class @\libglobal{extents}@ { public: - using index_type = IndexType; - using size_type = make_unsigned_t; - using rank_type = size_t; + using @\libmember{index_type}{extents}@ = IndexType; + using @\libmember{size_type}{extents}@ = make_unsigned_t; + using @\libmember{rank_type}{extents}@ = size_t; // \ref{mdspan.extents.obs}, observers of the multidimensional index space - static constexpr rank_type rank() noexcept { return sizeof...(Extents); } - static constexpr rank_type rank_dynamic() noexcept { return @\exposid{dynamic-index}@(rank()); } + static constexpr rank_type @\libmember{rank}{extents}@() noexcept { return sizeof...(Extents); } + static constexpr rank_type @\libmember{rank_dynamic}{extents}@() noexcept { return @\exposid{dynamic-index}@(rank()); } static constexpr size_t static_extent(rank_type) noexcept; constexpr index_type extent(rank_type) const noexcept; @@ -19978,10 +21596,10 @@ \effects \begin{itemize} \item -If \tcode{OtherIndexType} is an integral type other than \tcode{bool}, +If \tcode{remove_cvref_t} is an integral type other than \tcode{bool}, then equivalent to \tcode{return i;}, \item -otherwise, equivalent to \tcode{return static_cast(i);}. +otherwise, equivalent to \tcode{return static_cast(std::forward(\brk{}i));}. \end{itemize} \begin{note} This function will always return an integral type other than \tcode{bool}. @@ -20159,7 +21777,7 @@ \pnum \remarks -The deduced type is \tcode{extents...>}. +The deduced type is \tcode{extents...>}. \end{itemdescr} \rSec4[mdspan.extents.obs]{Observers of the multidimensional index space} @@ -20521,6 +22139,13 @@ \pnum \returns $s_r$ as defined in \tcode{m.is_strided()} above. + +\pnum +\begin{note} +It is not required for \tcode{m.stride(r)} to be well-formed +if \tcode{m.extents().rank()} is zero, +even if \tcode{m.is_always_strided()} is \tcode{true}. +\end{note} \end{itemdescr} \begin{itemdecl} @@ -20530,7 +22155,7 @@ \begin{itemdescr} \pnum \result -A constant expression\iref{expr.const} of type \tcode{bool}. +A constant expression\iref{expr.const.const} of type \tcode{bool}. \pnum \returns @@ -20550,7 +22175,7 @@ \begin{itemdescr} \pnum \result -A constant expression\iref{expr.const} of type \tcode{bool}. +A constant expression\iref{expr.const.const} of type \tcode{bool}. \pnum \returns @@ -20570,7 +22195,7 @@ \begin{itemdescr} \pnum \result -A constant expression\iref{expr.const} of type \tcode{bool}. +A constant expression\iref{expr.const.const} of type \tcode{bool}. \pnum \returns @@ -20598,25 +22223,25 @@ \begin{codeblock} namespace std { - struct layout_left { + struct @\libglobal{layout_left}@ { template class mapping; }; - struct layout_right { + struct @\libglobal{layout_right}@ { template class mapping; }; - struct layout_stride { + struct @\libglobal{layout_stride}@ { template class mapping; }; template - struct layout_left_padded { + struct @\libglobal{layout_left_padded}@ { template class mapping; }; template - struct layout_right_padded { + struct @\libglobal{layout_right_padded}@ { template class mapping; }; } @@ -20640,16 +22265,17 @@ where the leftmost extent has stride 1, and strides increase left-to-right as the product of extents. +\indexlibrarymember{mapping}{layout_left}% \begin{codeblock} namespace std { template class layout_left::mapping { public: - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_left; + using @\libmember{extents_type}{layout_left::mapping}@ = Extents; + using @\libmember{index_type}{layout_left::mapping}@ = extents_type::index_type; + using @\libmember{size_type}{layout_left::mapping}@ = extents_type::size_type; + using @\libmember{rank_type}{layout_left::mapping}@ = extents_type::rank_type; + using @\libmember{layout_type}{layout_left::mapping}@ = layout_left; // \ref{mdspan.layout.left.cons}, constructors constexpr mapping() noexcept = default; @@ -20666,26 +22292,26 @@ extents_type>) mapping(const LayoutLeftPaddedMapping&) noexcept; template - constexpr explicit(extents_type::rank() > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping&); constexpr mapping& operator=(const mapping&) noexcept = default; // \ref{mdspan.layout.left.obs}, observers - constexpr const extents_type& extents() const noexcept { return @\exposid{extents_}@; } + constexpr const extents_type& @\libmember{extents}{layout_left::mapping}@() const noexcept { return @\exposid{extents_}@; } constexpr index_type required_span_size() const noexcept; template constexpr index_type operator()(Indices...) const noexcept; - static constexpr bool is_always_unique() noexcept { return true; } - static constexpr bool is_always_exhaustive() noexcept { return true; } - static constexpr bool is_always_strided() noexcept { return true; } + static constexpr bool @\libmember{is_always_unique}{layout_left::mapping}@() noexcept { return true; } + static constexpr bool @\libmember{is_always_exhaustive}{layout_left::mapping}@() noexcept { return true; } + static constexpr bool @\libmember{is_always_strided}{layout_left::mapping}@() noexcept { return true; } - static constexpr bool is_unique() noexcept { return true; } - static constexpr bool is_exhaustive() noexcept { return true; } - static constexpr bool is_strided() noexcept { return true; } + static constexpr bool @\libmember{is_unique}{layout_left::mapping}@() noexcept { return true; } + static constexpr bool @\libmember{is_exhaustive}{layout_left::mapping}@() noexcept { return true; } + static constexpr bool @\libmember{is_strided}{layout_left::mapping}@() noexcept { return true; } constexpr index_type stride(rank_type) const noexcept; @@ -20701,7 +22327,7 @@ -> @\seebelow@; template - friend constexpr auto submdspan_mapping( + friend constexpr auto @\libmember{submdspan_mapping}{layout_left::mapping}@( const mapping& src, SliceSpecifiers... slices) { return src.@\exposid{submdspan-mapping-impl}@(slices...); } @@ -20828,7 +22454,7 @@ \begin{itemize} \item If \tcode{extents_type::rank() > 1} is \tcode{true}, -then \tcode{other.stride(1)} equals \tcode{other.extents(0)}. +then \tcode{other.stride(1)} equals \tcode{other.extents().ex\-tent(0)}. \item \tcode{other.required_span_size()} is representable as a value of type \tcode{index_type}. @@ -20842,7 +22468,7 @@ \indexlibraryctor{layout_left::mapping}% \begin{itemdecl} template - constexpr explicit(extents_type::rank() > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping& other); \end{itemdecl} @@ -20867,6 +22493,13 @@ \pnum \effects Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(extents_type::rank() == 0 && is_convertible_v) +\end{codeblock} \end{itemdescr} \rSec5[mdspan.layout.left.obs]{Observers} @@ -20914,13 +22547,13 @@ is \tcode{true}. Equivalent to: \begin{codeblock} -return ((static_cast(i) * stride(P)) + ... + 0); +return ((static_cast(std::move(i)) * stride(P)) + ... + 0); \end{codeblock} \end{itemdescr} \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} @@ -20962,16 +22595,17 @@ where the rightmost extent is stride 1, and strides increase right-to-left as the product of extents. +\indexlibrarymember{mapping}{layout_right}% \begin{codeblock} namespace std { template class layout_right::mapping { public: - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_right; + using @\libmember{extents_type}{layout_right::mapping}@ = Extents; + using @\libmember{index_type}{layout_right::mapping}@ = extents_type::index_type; + using @\libmember{size_type}{layout_right::mapping}@ = extents_type::size_type; + using @\libmember{rank_type}{layout_right::mapping}@ = extents_type::rank_type; + using @\libmember{layout_type}{layout_right::mapping}@ = layout_right; // \ref{mdspan.layout.right.cons}, constructors constexpr mapping() noexcept = default; @@ -20988,26 +22622,26 @@ extents_type>) mapping(const LayoutRightPaddedMapping&) noexcept; template - constexpr explicit(extents_type::rank() > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // \ref{mdspan.layout.right.obs}, observers - constexpr const extents_type& extents() const noexcept { return @\exposid{extents_}@; } + constexpr const extents_type& @\libmember{extents}{layout_right::mapping}@() const noexcept { return @\exposid{extents_}@; } constexpr index_type required_span_size() const noexcept; template constexpr index_type operator()(Indices...) const noexcept; - static constexpr bool is_always_unique() noexcept { return true; } - static constexpr bool is_always_exhaustive() noexcept { return true; } - static constexpr bool is_always_strided() noexcept { return true; } + static constexpr bool @\libmember{is_always_unique}{layout_right::mapping}@() noexcept { return true; } + static constexpr bool @\libmember{is_always_exhaustive}{layout_right::mapping}@() noexcept { return true; } + static constexpr bool @\libmember{is_always_strided}{layout_right::mapping}@() noexcept { return true; } - static constexpr bool is_unique() noexcept { return true; } - static constexpr bool is_exhaustive() noexcept { return true; } - static constexpr bool is_strided() noexcept { return true; } + static constexpr bool @\libmember{is_unique}{layout_right::mapping}@() noexcept { return true; } + static constexpr bool @\libmember{is_exhaustive}{layout_right::mapping}@() noexcept { return true; } + static constexpr bool @\libmember{is_strided}{layout_right::mapping}@() noexcept { return true; } constexpr index_type stride(rank_type) const noexcept; @@ -21023,7 +22657,7 @@ -> @\seebelow@; template - friend constexpr auto submdspan_mapping( + friend constexpr auto @\libmember{submdspan_mapping}{layout_right::mapping}@( const mapping& src, SliceSpecifiers... slices) { return src.@\exposid{submdspan-mapping-impl}@(slices...); } @@ -21168,7 +22802,7 @@ \indexlibraryctor{layout_right::mapping}% \begin{itemdecl} template - constexpr explicit(extents_type::rank() > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping& other) noexcept; \end{itemdecl} @@ -21193,13 +22827,20 @@ \pnum \effects Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(extents_type::rank() == 0 && is_convertible_v) +\end{codeblock} \end{itemdescr} \rSec5[mdspan.layout.right.obs]{Observers} \indexlibrarymember{required_span_size}{layout_right::mapping}% \begin{itemdecl} -index_type required_span_size() const noexcept; +constexpr index_type required_span_size() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -21240,7 +22881,7 @@ \end{codeblock} is \tcode{true}. Equivalent to: \begin{codeblock} -return ((static_cast(i) * stride(P)) + ... + 0); +return ((static_cast(std::move(i)) * stride(P)) + ... + 0); \end{codeblock} \end{itemdescr} @@ -21287,16 +22928,17 @@ \tcode{layout_stride} provides a layout mapping where the strides are user-defined. +\indexlibrarymember{mapping}{layout_stride}% \begin{codeblock} namespace std { template class layout_stride::mapping { public: - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_stride; + using @\libmember{extents_type}{layout_stride::mapping}@ = Extents; + using @\libmember{index_type}{layout_stride::mapping}@ = extents_type::index_type; + using @\libmember{size_type}{layout_stride::mapping}@ = extents_type::size_type; + using @\libmember{rank_type}{layout_stride::mapping}@ = extents_type::rank_type; + using @\libmember{layout_type}{layout_stride::mapping}@ = layout_stride; private: static constexpr rank_type @\exposid{rank_}@ = extents_type::rank(); // \expos @@ -21316,23 +22958,23 @@ constexpr mapping& operator=(const mapping&) noexcept = default; // \ref{mdspan.layout.stride.obs}, observers - constexpr const extents_type& extents() const noexcept { return @\exposid{extents_}@; } - constexpr array strides() const noexcept { return @\exposid{strides_}@; } + constexpr const extents_type& @\libmember{extents}{layout_stride::mapping}@() const noexcept { return @\exposid{extents_}@; } + constexpr array @\libmember{strides}{layout_stride::mapping}@() const noexcept { return @\exposid{strides_}@; } constexpr index_type required_span_size() const noexcept; template constexpr index_type operator()(Indices...) const noexcept; - static constexpr bool is_always_unique() noexcept { return true; } - static constexpr bool is_always_exhaustive() noexcept { return false; } - static constexpr bool is_always_strided() noexcept { return true; } + static constexpr bool @\libmember{is_always_unique}{layout_stride::mapping}@() noexcept { return true; } + static constexpr bool is_always_exhaustive() noexcept; + static constexpr bool @\libmember{is_always_strided}{layout_stride::mapping}@() noexcept { return true; } - static constexpr bool is_unique() noexcept { return true; } + static constexpr bool @\libmember{is_unique}{layout_stride::mapping}@() noexcept { return true; } constexpr bool is_exhaustive() const noexcept; - static constexpr bool is_strided() noexcept { return true; } + static constexpr bool @\libmember{is_strided}{layout_stride::mapping}@() noexcept { return true; } - constexpr index_type stride(rank_type i) const noexcept { return @\exposid{strides_}@[i]; } + constexpr index_type @\libmember{stride}{layout_stride::mapping}@(rank_type i) const noexcept { return @\exposid{strides_}@[i]; } template friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept; @@ -21347,7 +22989,7 @@ -> @\seebelow@; template - friend constexpr auto submdspan_mapping( + friend constexpr auto @\libmember{submdspan_mapping}{layout_stride::mapping}@( const mapping& src, SliceSpecifiers... slices) { return src.@\exposid{submdspan-mapping-impl}@(slices...); } @@ -21604,10 +23246,24 @@ is \tcode{true}. Equivalent to: \begin{codeblock} -return ((static_cast(i) * stride(P)) + ... + 0); +return ((static_cast(std::move(i)) * stride(P)) + ... + 0); \end{codeblock} \end{itemdescr} +\indexlibrarymember{is_always_exhaustive}{layout_stride::mapping}% +\begin{itemdecl} +static constexpr bool is_always_exhaustive() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \exposid{rank_} is 0 +or if there is a rank index \tcode{r} of \tcode{extents()} +such that \tcode{extents_type::sta\-tic_extent(r)} is 0, +otherwise \tcode{false}. +\end{itemdescr} + \indexlibrarymember{is_exhaustive}{layout_stride::mapping}% \begin{itemdecl} constexpr bool is_exhaustive() const noexcept; @@ -21618,7 +23274,8 @@ \returns \begin{itemize} \item -\tcode{true} if \exposid{rank_} is 0. +\tcode{true} if \exposid{rank_} or the size of the multidimensional index space +\tcode{m.extents()} is 0. \item Otherwise, \tcode{true} if there is a permutation $P$ of the integers in the range $[0, \exposid{rank_})$ @@ -21672,19 +23329,20 @@ except that the padding stride \tcode{stride(1)} can be greater than or equal to \tcode{extent(0)}. +\indexlibrarymember{mapping}{layout_left_padded}% \begin{codeblock} namespace std { template template class layout_left_padded::mapping { public: - static constexpr size_t padding_value = PaddingValue; + static constexpr size_t @\libmember{padding_value}{layout_left_padded::mapping}@ = PaddingValue; - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_left_padded; + using @\libmember{extents_type}{layout_left_padded::mapping}@ = Extents; + using @\libmember{index_type}{layout_left_padded::mapping}@ = extents_type::index_type; + using @\libmember{size_type}{layout_left_padded::mapping}@ = extents_type::size_type; + using @\libmember{rank_type}{layout_left_padded::mapping}@ = extents_type::rank_type; + using @\libmember{layout_type}{layout_left_padded::mapping}@ = layout_left_padded; private: static constexpr size_t @\exposid{rank_}@ = extents_type::rank(); // \expos @@ -21705,7 +23363,7 @@ constexpr explicit(!is_convertible_v) mapping(const layout_left::mapping&); template - constexpr explicit(extents_type::rank() > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping&); template constexpr explicit(@\seebelow@) @@ -21717,20 +23375,20 @@ constexpr mapping& operator=(const mapping&) noexcept = default; // \ref{mdspan.layout.leftpad.obs}, observers - constexpr const extents_type& extents() const noexcept { return @\exposid{extents_}@; } - constexpr array strides() const noexcept; + constexpr const extents_type& @\libmember{extents}{layout_left_padded::mapping}@() const noexcept { return @\exposid{extents_}@; } + constexpr array strides() const noexcept; constexpr index_type required_span_size() const noexcept; template constexpr index_type operator()(Indices...) const noexcept; - static constexpr bool is_always_unique() noexcept { return true; } + static constexpr bool @\libmember{is_always_unique}{layout_left_padded::mapping}@() noexcept { return true; } static constexpr bool is_always_exhaustive() noexcept; - static constexpr bool is_always_strided() noexcept { return true; } + static constexpr bool @\libmember{is_always_strided}{layout_left_padded::mapping}@() noexcept { return true; } - static constexpr bool is_unique() noexcept { return true; } + static constexpr bool @\libmember{is_unique}{layout_left_padded::mapping}@() noexcept { return true; } constexpr bool is_exhaustive() const noexcept; - static constexpr bool is_strided() noexcept { return true; } + static constexpr bool @\libmember{is_strided}{layout_left_padded::mapping}@() noexcept { return true; } constexpr index_type stride(rank_type) const noexcept; @@ -21741,13 +23399,13 @@ // \ref{mdspan.layout.leftpad.expo}, exposition-only members index_type @\exposid{stride-1}@ = @\exposid{static-padding-stride}@; // \expos extents_type @\exposid{extents_}@{}; // \expos - // \ref{mdspan.sub.map}, submdspan mapping specialization + // \ref{mdspan.sub.map}, \tcode{submdspan} mapping specialization template constexpr auto @\exposid{submdspan-mapping-impl}@(SliceSpecifiers...) const // \expos -> @\seebelow@; template - friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) { + friend constexpr auto @\libmember{submdspan_mapping}{layout_left_padded::mapping}@(const mapping& src, SliceSpecifiers... slices) { return src.@\exposid{submdspan-mapping-impl}@(slices...); } }; @@ -21770,7 +23428,7 @@ \item the empty parameter pack, if \exposid{rank_} equals zero; \item -\tcode otherwise, \tcode{0zu}, if \exposid{rank_} equals one; +otherwise, \tcode{0zu}, if \exposid{rank_} equals one; \item otherwise, the parameter pack \tcode{0zu}, \tcode{1zu}, \ldots, \tcode{\exposid{rank_}- 1}. \end{itemize} @@ -21783,6 +23441,7 @@ then the size of the multidimensional index space \tcode{Extents()} is representable as a value of type \tcode{index_type}. \item +If \tcode{padding_value} is not equal to \tcode{dynamic_extent}, then \tcode{padding_value} is representable as a value of type \tcode{index_type}. \item If @@ -21892,7 +23551,7 @@ direct-non-list-initializes \exposid{stride-1} \begin{itemize} \item -with \tcode{ext.extent(0)} if padding_value is \tcode{dynamic_extent}, +with \tcode{ext.extent(0)} if \tcode{padding_value} is \tcode{dynamic_extent}, \item otherwise with \tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(padding_value, ext.extent(0))}. @@ -21903,10 +23562,14 @@ \indexlibraryctor{layout_left_padded::mapping}% \begin{itemdecl} template -constexpr mapping(const extents_type& ext, OtherIndexType pad); + constexpr mapping(const extents_type& ext, OtherIndexType padding); \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{pad} be +\tcode{extents_type::\exposid{index-cast}(std::move(padding))}. + \pnum \constraints \begin{itemize} @@ -21922,7 +23585,7 @@ \item \tcode{pad} is representable as a value of type \tcode{index_type}. \item -\tcode{extents_type::index-cast(pad)} is greater than zero. +\tcode{pad} is greater than zero. \item If \exposid{rank_} is greater than one, then \tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(pad, ext.extent(0))} @@ -21936,7 +23599,7 @@ is representable as a value of type \tcode{index_type}. \item If \tcode{padding_value} is not equal to \tcode{dynamic_extent}, -\tcode{padding_value} equals \tcode{extents_type::\exposid{in\-dex-cast}(pad)}. +\tcode{padding_value} equals \tcode{pad}. \end{itemize} \pnum @@ -21994,7 +23657,7 @@ \indexlibraryctor{layout_left_padded::mapping}% \begin{itemdecl} template - constexpr explicit(rank_ > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping& other); \end{itemdecl} @@ -22039,6 +23702,13 @@ direct-non-list-initializes \exposid{stride-1} with \tcode{other.stride(1)}. \end{itemize} + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(rank_ == 0 && is_convertible_v) +\end{codeblock} \end{itemdescr} \indexlibraryctor{layout_left_padded::mapping}% @@ -22072,6 +23742,7 @@ is \tcode{true}. \pnum +\expects \begin{itemize} \item If \exposid{rank_} is greater than 1 and @@ -22100,6 +23771,7 @@ \remarks The expression inside \tcode{explicit} is equivalent to: \begin{codeblock} +!is_convertible_v || rank_> 1 && (padding_value != dynamic_extent || LayoutLeftPaddedMapping::padding_value == dynamic_extent) @@ -22155,6 +23827,7 @@ \rSec5[mdspan.layout.leftpad.obs]{Observers} +\indexlibrarymember{strides}{layout_left_padded::mapping}% \begin{itemdecl} constexpr array strides() const noexcept; \end{itemdecl} @@ -22165,6 +23838,7 @@ \tcode{array(\{stride(P_rank)...\})}. \end{itemdescr} +\indexlibrarymember{required_span_size}{layout_left_padded::mapping}% \begin{itemdecl} constexpr index_type required_span_size() const noexcept; \end{itemdecl} @@ -22176,13 +23850,14 @@ \item \tcode{0} if the multidimensional index space \exposid{extents_} is empty, \item -otherwise, \tcode{*this(((\exposid{extents_}(P_rank) - index_type(1))...)) + 1}. +otherwise, \tcode{(*this)(\exposid{extents_}.extent(P_rank) - index_type(1)...) + 1}. \end{itemize} \end{itemdescr} +\indexlibrarymember{operator()}{layout_left_padded::mapping}% \begin{itemdecl} template -constexpr size_t operator()(Indices... idxs) const noexcept; + constexpr index_type operator()(Indices... idxs) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -22204,9 +23879,10 @@ \pnum \returns -\tcode{((static_cast(idxs) * stride(P_rank)) + ... + 0)}. +\tcode{((static_cast(std::move(idxs)) * stride(P_rank)) + ... + 0)}. \end{itemdescr} +\indexlibrarymember{is_always_exhaustive}{layout_left_padded::mapping}% \begin{itemdecl} static constexpr bool is_always_exhaustive() noexcept; \end{itemdecl} @@ -22227,6 +23903,7 @@ \end{itemize} \end{itemdescr} +\indexlibrarymember{is_exhaustive}{layout_left_padded::mapping}% \begin{itemdecl} constexpr bool is_exhaustive() const noexcept; \end{itemdecl} @@ -22238,6 +23915,7 @@ otherwise, \tcode{extents_.extent(0) == stride(1)}. \end{itemdescr} +\indexlibrarymember{stride}{layout_left_padded::mapping}% \begin{itemdecl} constexpr index_type stride(rank_type r) const noexcept; \end{itemdecl} @@ -22260,6 +23938,7 @@ \end{itemize} \end{itemdescr} +\indexlibrarymember{operator==}{layout_left_padded::mapping}% \begin{itemdecl} template friend constexpr bool operator==(const mapping& x, const LayoutLeftPaddedMapping& y) noexcept; @@ -22294,19 +23973,20 @@ can be greater than or equal to \tcode{extents_type::ex\-tent(extents_type::rank() - 1)}. +\indexlibrarymember{mapping}{layout_right_padded}% \begin{codeblock} namespace std { template template class layout_right_padded::mapping { public: - static constexpr size_t padding_value = PaddingValue; + static constexpr size_t @\libmember{padding_value}{layout_right_padded::mapping}@ = PaddingValue; - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_right_padded; + using @\libmember{extents_type}{layout_right_padded::mapping}@ = Extents; + using @\libmember{index_type}{layout_right_padded::mapping}@ = extents_type::index_type; + using @\libmember{size_type}{layout_right_padded::mapping}@ = extents_type::size_type; + using @\libmember{rank_type}{layout_right_padded::mapping}@ = extents_type::rank_type; + using @\libmember{layout_type}{layout_right_padded::mapping}@ = layout_right_padded; private: static constexpr size_t @\exposid{rank_}@ = extents_type::rank(); // \expos @@ -22328,7 +24008,7 @@ constexpr explicit(!is_convertible_v) mapping(const layout_right::mapping&); template - constexpr explicit(rank_ > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping&); template constexpr explicit(@\seebelow@) @@ -22340,21 +24020,21 @@ constexpr mapping& operator=(const mapping&) noexcept = default; // \ref{mdspan.layout.rightpad.obs}, observers - constexpr const extents_type& extents() const noexcept { return extents_; } - constexpr array strides() const noexcept; + constexpr const extents_type& @\libmember{extents}{layout_right_padded::mapping}@() const noexcept { return @\exposid{extents_}@; } + constexpr array strides() const noexcept; constexpr index_type required_span_size() const noexcept; template constexpr index_type operator()(Indices...) const noexcept; - static constexpr bool is_always_unique() noexcept { return true; } + static constexpr bool @\libmember{is_always_unique}{layout_right_padded::mapping}@() noexcept { return true; } static constexpr bool is_always_exhaustive() noexcept; - static constexpr bool is_always_strided() noexcept { return true; } + static constexpr bool @\libmember{is_always_strided}{layout_right_padded::mapping}@() noexcept { return true; } - static constexpr bool is_unique() noexcept { return true; } + static constexpr bool @\libmember{is_unique}{layout_right_padded::mapping}@() noexcept { return true; } constexpr bool is_exhaustive() const noexcept; - static constexpr bool is_strided() noexcept { return true; } + static constexpr bool @\libmember{is_strided}{layout_right_padded::mapping}@() noexcept { return true; } constexpr index_type stride(rank_type) const noexcept; @@ -22366,13 +24046,13 @@ index_type @\exposid{stride-rm2}@ = @\exposid{static-padding-stride}@; // \expos extents_type @\exposid{extents_}@{}; // \expos - // \ref{mdspan.sub.map}, submdspan mapping specialization + // \ref{mdspan.sub.map}, \tcode{submdspan} mapping specialization template constexpr auto @\exposid{submdspan-mapping-impl}@(SliceSpecifiers...) const // \expos -> @\seebelow@; template - friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) { + friend constexpr auto @\libmember{submdspan_mapping}{layout_right_padded::mapping}@(const mapping& src, SliceSpecifiers... slices) { return src.@\exposid{submdspan-mapping-impl}@(slices...); } }; @@ -22395,7 +24075,7 @@ \item the empty parameter pack, if \exposid{rank_} equals zero; \item -\tcode otherwise, \tcode{0zu}, if \exposid{rank_} equals one; +otherwise, \tcode{0zu}, if \exposid{rank_} equals one; \item otherwise, the parameter pack \tcode{0zu}, \tcode{1zu}, \ldots, \tcode{\exposid{rank_}- 1}. \end{itemize} @@ -22408,6 +24088,7 @@ then the size of the multidimensional index space \tcode{Extents()} is representable as a value of type \tcode{index_type}. \item +If \tcode{padding_value} is not equal to \tcode{dynamic_extent}, then \tcode{padding_value} is representable as a value of type \tcode{index_type}. \item If @@ -22530,10 +24211,14 @@ \indexlibraryctor{layout_right_padded::mapping}% \begin{itemdecl} template -constexpr mapping(const extents_type& ext, OtherIndexType pad); + constexpr mapping(const extents_type& ext, OtherIndexType padding); \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{pad} be +\tcode{extents_type::\exposid{index-cast}(std::move(padding))}. + \pnum \constraints \begin{itemize} @@ -22549,7 +24234,7 @@ \item \tcode{pad} is representable as a value of type \tcode{index_type}. \item -\tcode{extents_type::\exposid{index-cast}(pad)} is greater than zero. +\tcode{pad} is greater than zero. \item If \exposid{rank_} is greater than one, then \tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(pad, ext.extent(\exposid{rank_} - 1))} @@ -22563,7 +24248,7 @@ is representable as a value of type \tcode{index_type}. \item If \tcode{padding_value} is not equal to \tcode{dynamic_extent}, -\tcode{padding_value} equals \tcode{extents_type::\linebreak \exposid{index-cast}(pad)}. +\tcode{padding_value} equals \tcode{pad}. \end{itemize} \pnum @@ -22621,7 +24306,7 @@ \indexlibraryctor{layout_right_padded::mapping}% \begin{itemdecl} template - constexpr explicit(rank_ > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping& other); \end{itemdecl} @@ -22667,6 +24352,13 @@ direct-non-list-initializes \exposid{stride-rm2} with \tcode{other.stride(\exposid{rank_} - 2)}. \end{itemize} + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(rank_ == 0 && is_convertible_v) +\end{codeblock} \end{itemdescr} \indexlibraryctor{layout_right_padded::mapping}% @@ -22729,6 +24421,7 @@ \remarks The expression inside \tcode{explicit} is equivalent to: \begin{codeblock} +!is_convertible_v || @\exposid{rank_}@ > 1 && (padding_value != dynamic_extent || LayoutRightPaddedMapping::padding_value == dynamic_extent) @@ -22782,7 +24475,7 @@ \rSec5[mdspan.layout.rightpad.obs]{Observers} -\indexlibrarymember{layout_right_padded::mapping}{strides}% +\indexlibrarymember{strides}{layout_right_padded::mapping}% \begin{itemdecl} constexpr array strides() const noexcept; \end{itemdecl} @@ -22793,7 +24486,7 @@ \tcode{array({stride(P_rank)...})}. \end{itemdescr} -\indexlibrarymember{layout_right_padded::mapping}{required_span_size}% +\indexlibrarymember{required_span_size}{layout_right_padded::mapping}% \begin{itemdecl} constexpr index_type required_span_size() const noexcept; \end{itemdecl} @@ -22802,13 +24495,13 @@ \pnum \returns \tcode{0} if the multidimensional index space \exposid{extents_} is empty, -otherwise \tcode{*this(((\exposid{extents_}(P_rank) - index_type(1))...)) + 1}. +otherwise \tcode{(*this)(\exposid{extents_}.extent(P_rank) - index_type(1)...) + 1}. \end{itemdescr} -\indexlibrarymember{layout_right_padded::mapping}{operator()}% +\indexlibrarymember{operator()}{layout_right_padded::mapping}% \begin{itemdecl} template -constexpr size_t operator()(Indices... idxs) const noexcept; + constexpr index_type operator()(Indices... idxs) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -22830,10 +24523,10 @@ \pnum \returns -\tcode{((static_cast(idxs) * stride(P_rank)) + ... + 0)}. +\tcode{((static_cast(std::move(idxs)) * stride(P_rank)) + ... + 0)}. \end{itemdescr} -\indexlibrarymember{layout_right_padded::mapping}{is_always_exhaustive}% +\indexlibrarymember{is_always_exhaustive}{layout_right_padded::mapping}% \begin{itemdecl} static constexpr bool is_always_exhaustive() noexcept; \end{itemdecl} @@ -22854,7 +24547,7 @@ \end{itemize} \end{itemdescr} -\indexlibrarymember{layout_right_padded::mapping}{is_exhaustive}% +\indexlibrarymember{is_exhaustive}{layout_right_padded::mapping}% \begin{itemdecl} constexpr bool is_exhaustive() const noexcept; \end{itemdecl} @@ -22869,6 +24562,7 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{stride}{layout_right_padded::mapping}% \begin{itemdecl} constexpr index_type stride(rank_type r) const noexcept; \end{itemdecl} @@ -22893,7 +24587,7 @@ \end{itemize} \end{itemdescr} -\indexlibrarymember{layout_right_padded::mapping}{operator==}% +\indexlibrarymember{operator==}{layout_right_padded::mapping}% \begin{itemdecl} template friend constexpr bool operator==(const mapping& x, const LayoutRightPaddedMapping& y) noexcept; @@ -23086,11 +24780,11 @@ \begin{codeblock} namespace std { template - struct default_accessor { - using offset_policy = default_accessor; - using element_type = ElementType; - using reference = ElementType&; - using data_handle_type = ElementType*; + struct @\libglobal{default_accessor}@ { + using @\libmember{offset_policy}{default_accessor}@ = default_accessor; + using @\libmember{element_type}{default_accessor}@ = ElementType; + using @\libmember{reference}{default_accessor}@ = ElementType&; + using @\libmember{data_handle_type}{default_accessor}@ = ElementType*; constexpr default_accessor() noexcept = default; template @@ -23163,12 +24857,12 @@ namespace std { template struct @\libglobal{aligned_accessor}@ { - using offset_policy = default_accessor; - using element_type = ElementType; - using reference = ElementType&; - using data_handle_type = ElementType*; + using @\libmember{offset_policy}{aligned_accessor}@ = default_accessor; + using @\libmember{element_type}{aligned_accessor}@ = ElementType; + using @\libmember{reference}{aligned_accessor}@ = ElementType&; + using @\libmember{data_handle_type}{aligned_accessor}@ = ElementType*; - static constexpr size_t byte_alignment = ByteAlignment; + static constexpr size_t @\libmember{byte_alignment}{aligned_accessor}@ = ByteAlignment; constexpr aligned_accessor() noexcept = default; template @@ -23235,19 +24929,18 @@ that has no over-alignment requirement. \begin{codeblock} void compute_using_fourfold_overalignment( - std::mdspan, std::layout_right, - std::aligned_accessor> x); + mdspan, layout_right, aligned_accessor> x); void compute_without_requiring_overalignment( - std::mdspan, std::layout_right> x); + mdspan, layout_right> x); -void compute(std::mdspan> x) { +void compute(mdspan> x) { constexpr auto byte_alignment = 4 * sizeof(float); - auto accessor = std::aligned_accessor{}; + auto accessor = 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}); + if (is_sufficiently_aligned(x_handle)) { + compute_using_fourfold_overalignment(mdspan{x_handle, x.mapping(), accessor}); } else { compute_without_requiring_overalignment(x); } @@ -23355,25 +25048,25 @@ namespace std { template> - class mdspan { + class @\libglobal{mdspan}@ { public: - using extents_type = Extents; - using layout_type = LayoutPolicy; - using accessor_type = AccessorPolicy; - using mapping_type = typename layout_type::template mapping; - using element_type = ElementType; - using value_type = remove_cv_t; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using data_handle_type = typename accessor_type::data_handle_type; - using reference = typename accessor_type::reference; - - static constexpr rank_type rank() noexcept { return extents_type::rank(); } - static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); } - static constexpr size_t static_extent(rank_type r) noexcept + using @\libmember{extents_type}{mdspan}@ = Extents; + using @\libmember{layout_type}{mdspan}@ = LayoutPolicy; + using @\libmember{accessor_type}{mdspan}@ = AccessorPolicy; + using @\libmember{mapping_type}{mdspan}@ = layout_type::template mapping; + using @\libmember{element_type}{mdspan}@ = ElementType; + using @\libmember{value_type}{mdspan}@ = remove_cv_t; + using @\libmember{index_type}{mdspan}@ = extents_type::index_type; + using @\libmember{size_type}{mdspan}@ = extents_type::size_type; + using @\libmember{rank_type}{mdspan}@ = extents_type::rank_type; + using @\libmember{data_handle_type}{mdspan}@ = accessor_type::data_handle_type; + using @\libmember{reference}{mdspan}@ = accessor_type::reference; + + static constexpr rank_type @\libmember{rank}{mdspan}@() noexcept { return extents_type::rank(); } + static constexpr rank_type @\libmember{rank_dynamic}{mdspan}@() noexcept { return extents_type::rank_dynamic(); } + static constexpr size_t @\libmember{static_extent}{mdspan}@(rank_type r) noexcept { return extents_type::static_extent(r); } - constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); } + constexpr index_type @\libmember{extent}{mdspan}@(rank_type r) const noexcept { return extents().extent(r); } // \ref{mdspan.mdspan.cons}, constructors constexpr mdspan(); @@ -23409,30 +25102,40 @@ template constexpr reference operator[](const array& indices) const; + template + constexpr reference + at(OtherIndexTypes... indices) const; // freestanding-deleted + template + constexpr reference + at(span indices) const; // freestanding-deleted + template + constexpr reference + at(const array& indices) const; // freestanding-deleted + constexpr size_type size() const noexcept; constexpr bool empty() const noexcept; friend constexpr void swap(mdspan& x, mdspan& y) noexcept; - constexpr const extents_type& extents() const noexcept { return @\exposid{map_}@.extents(); } - constexpr const data_handle_type& data_handle() const noexcept { return @\exposid{ptr_}@; } - constexpr const mapping_type& mapping() const noexcept { return @\exposid{map_}@; } - constexpr const accessor_type& accessor() const noexcept { return @\exposid{acc_}@; } + constexpr const extents_type& @\libmember{extents}{mdspan}@() const noexcept { return @\exposid{map_}@.extents(); } + constexpr const data_handle_type& @\libmember{data_handle}{mdspan}@() const noexcept { return @\exposid{ptr_}@; } + constexpr const mapping_type& @\libmember{mapping}{mdspan}@() const noexcept { return @\exposid{map_}@; } + constexpr const accessor_type& @\libmember{accessor}{mdspan}@() const noexcept { return @\exposid{acc_}@; } - static constexpr bool is_always_unique() + static constexpr bool @\libmember{is_always_unique}{mdspan}@() { return mapping_type::is_always_unique(); } - static constexpr bool is_always_exhaustive() + static constexpr bool @\libmember{is_always_exhaustive}{mdspan}@() { return mapping_type::is_always_exhaustive(); } - static constexpr bool is_always_strided() + static constexpr bool @\libmember{is_always_strided}{mdspan}@() { return mapping_type::is_always_strided(); } - constexpr bool is_unique() const + constexpr bool @\libmember{is_unique}{mdspan}@() const { return @\exposid{map_}@.is_unique(); } - constexpr bool is_exhaustive() const + constexpr bool @\libmember{is_exhaustive}{mdspan}@() const { return @\exposid{map_}@.is_exhaustive(); } - constexpr bool is_strided() const + constexpr bool @\libmember{is_strided}{mdspan}@() const { return @\exposid{map_}@.is_strided(); } - constexpr index_type stride(rank_type r) const + constexpr index_type @\libmember{stride}{mdspan}@(rank_type r) const { return @\exposid{map_}@.stride(r); } private: @@ -23454,7 +25157,7 @@ template requires ((is_convertible_v && ...) && sizeof...(Integrals) > 0) explicit mdspan(ElementType*, Integrals...) - -> mdspan...>>; + -> mdspan...>>; template mdspan(ElementType*, span) @@ -23474,7 +25177,7 @@ typename MappingType::layout_type>; template - mdspan(const typename AccessorType::data_handle_type&, const MappingType&, + mdspan(typename AccessorType::data_handle_type, const MappingType&, const AccessorType&) -> mdspan; @@ -23565,7 +25268,7 @@ \item \tcode{(is_convertible_v \&\& ...)} is \tcode{true}, \item -\tcode{(is_nothrow_constructible \&\& ...)} is \tcode{true}, +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}, \item \tcode{N == rank() || N == rank_dynamic()} is \tcode{true}, \item @@ -23755,17 +25458,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 @@ -23811,7 +25513,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 @@ -23858,6 +25560,67 @@ \end{codeblock} \end{itemdescr} +\indexlibrarymember{at}{mdspan}% +\begin{itemdecl} +template + constexpr reference at(OtherIndexTypes... indices) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}, and +\item +\tcode{sizeof...(OtherIndexTypes) == rank()} is \tcode{true}. +\end{itemize} + +\pnum +Let \tcode{I} be \tcode{extents_type::\exposid{index-cast}(std::move(indices))}. + +\pnum +\returns +\tcode{(*this)[I...]}. + +\pnum +\throws +\tcode{out_of_range} if \tcode{I} is not a multidimensional index in \tcode{extents()}. +\end{itemdescr} + +\indexlibrarymember{at}{mdspan}% +\begin{itemdecl} +template + constexpr reference at(span indices) const; +template + constexpr reference at(const array& indices) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} is \tcode{true}, and +\item +\tcode{is_nothrow_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Let \tcode{P} be a parameter pack such that +\begin{codeblock} +is_same_v, index_sequence> +\end{codeblock} +is \tcode{true}. +Equivalent to: +\begin{codeblock} +return at(extents_type::@\exposid{index-cast}@(as_const(indices[P]))...); +\end{codeblock} +\end{itemdescr} + \indexlibrarymember{size}{mdspan}% \begin{itemdecl} constexpr size_type size() const noexcept; @@ -23914,76 +25677,225 @@ the \tcode{SliceSpecifier} arguments. \pnum -For each function defined in \ref{mdspan.sub} that -takes a parameter pack named \tcode{slices} as an argument: +Given a signed or unsigned integer type \tcode{IndexType}, +a type $S$ is a +\defnx{\tcode{submdspan} slice type for \tcode{IndexType}}{\tcode{submdspan}!slice type for \tcode{IndexType}} +if at least one of the following holds: +\begin{itemize} +\item + \tcode{is_convertible_v<$S$, full_extent_t>} is \tcode{true}; +\item + \tcode{is_convertible_v<$S$, IndexType>} is \tcode{true}; +\item + $S$ is a specialization of \tcode{extent_slice} and + \tcode{is_convertible_v<$X$, IndexType>} is \tcode{true} for $X$ denoting + \tcode{$S$::offset_type}, + \tcode{$S$::extent_type}, and + \tcode{$S$::stride_type}; +\item + $S$ is a specialization of \tcode{range_slice} and + \tcode{is_convertible_v<$X$, IndexType>} is \tcode{true} for $X$ denoting type of + \tcode{$S$::first}, + \tcode{$S$::last}, and + \tcode{$S$::stride} members; or +\item + all of the following hold: + \begin{itemize} + \item + the declaration \tcode{auto [...ls] = std::move(s);} is well-formed + for some object \tcode{s} of type $S$, + \item + \tcode{sizeof...(ls)} is equal to 2, and + \item + \tcode{(is_convertible_v \&\& ...)} is \tcode{true}. + \end{itemize} +\end{itemize} + +\pnum +Given a signed or unsigned integer type \tcode{IndexType}, +a type $S$ is a +\defnx{canonical \tcode{submdspan} index type for \tcode{IndexType}}{\tcode{submdspan}!canonical index type for \tcode{IndexType}} +if $S$ is either \tcode{IndexType} or \tcode{constant_wrapper} +for some value \tcode{v} of type \tcode{IndexType}, +such that \tcode{v} is greater than or equal to zero. + +\pnum +Given a signed or unsigned integer type \tcode{IndexType}, +a type $S$ is a +\defnx{canonical \tcode{submdspan} slice type for \tcode{IndexType}}{\tcode{submdspan}!canonical slice type for \tcode{IndexType}} +if exactly one of the following is \tcode{true}: +\begin{itemize} +\item + $S$ is \tcode{full_extent_t}; +\item + $S$ is a canonical \tcode{submdspan} index type for \tcode{IndexType}; or +\item + $S$ is a specialization of \tcode{extent_slice} + where all of the following hold: + \begin{itemize} + \item + \tcode{S::offset_type}, \tcode{S::extent_type}, and \tcode{S::stride_type} + are all canonical \tcode{submdspan} index types for \tcode{IndexType}; and + \item + if \tcode{$S$::stride_type} and \tcode{$S$::extent_type} + are both specializations of \tcode{constant_wrapper}, + then \tcode{$S$::stride_type::value} is greater than zero. + \end{itemize} +\end{itemize} + +\pnum +A type \tcode{S} is a \defnadj{collapsing}{slice type} if +it is neither \tcode{full_extent_t} nor +a specialization of \tcode{extent_slice}. +\begin{note} +Each collapsing slice type in \tcode{submdspan_mapping}'s parameter pack +of slice specifier types +reduces the rank of the result of \tcode{submdspan_mapping} by one. +\end{note} + +\pnum +A type \tcode{S} is a \defnadj{unit-stride}{slice type} if +\begin{itemize} +\item + \tcode{S} is a specialization of \tcode{extent_slice} + where \tcode{S::stride_type} is a specialization of \tcode{constant_wrapper} and + \tcode{S::stride_type::value} is equal to 1, or +\item + \tcode{S} denotes \tcode{full_extent_t}. +\end{itemize} + +\pnum +Given an object \tcode{e} of type \tcode{E} that is a specialization of \tcode{extents}, and +an object \tcode{s} of type \tcode{S} +that is a canonical \tcode{submdspan} slice type for \tcode{E::index_type}, +the \defnx{\tcode{submdspan} slice range of \tcode{s} for the $k^\text{th}$ extent of \tcode{e}}{\tcode{submdspan}!slice range of \tcode{s} for the $k^\text{th}$ extent of \tcode{e}} +is: +\begin{itemize} +\item + \range{$0$}{e.extent($k$)}, + if \tcode{S} is \tcode{full_extent_t}; +\item + \range{E::index_type(s.offset)}{E::index_type(s.offset)}, + if \tcode{S} is a specialization of \tcode{extent_slice} and + \tcode{E::index_type(s.extent)} is zero; otherwise +\item + \range{E::index_type(s.offset)}{E::index_type(s.offset + 1 + (s.extent - 1) * s.stride)}, + if \tcode{S} is a specialization of \tcode{extent_slice}; otherwise +\item + \range{\tcode{E::index_type(s)}}{$\tcode{E::index_type(s)} + 1$} +\end{itemize} +\pnum +Given a type \tcode{E} that is a specialization of \tcode{extents}, +a type \tcode{S} is a +\defnx{valid \tcode{submdspan} slice type for the $k^\text{th}$ extent of \tcode{E}}{\tcode{submdspan}!valid slice type for the $k^\text{th}$ extent of \tcode{E}} +if \tcode{S} is a canonical slice type for \tcode{E::index_type}, and +for $x$ equal to \tcode{E::static_extent($k$)}, +either $x$ is equal to \tcode{dynamic_extent}; or \begin{itemize} -\item let \tcode{index_type} be +\item + if \tcode{S} is a specialization of \tcode{extent_slice}, then \begin{itemize} \item - \tcode{M::index_type} - if the function is a member of a class \tcode{M}, + $o$ is less than or equal to $x$; \item - otherwise, - \tcode{remove_reference_t::index_type} - if the function has a parameter named \tcode{src}, + $e$ is less than or equal to $x$; \item - otherwise, - the same type as the function's template argument \tcode{IndexType}; + if $e$ is greater than one, + then $t$ is greater than zero, + \item + if $e$ is greater than zero, + then $o + 1 + (e - 1) * t$ is less than or equal to $x$, \end{itemize} -\item let \tcode{rank} be the number of elements in \tcode{slices}; -\item let $s_k$ be the $k^\text{th}$ element of \tcode{slices}; -\item let $S_k$ be the type of $s_k$; and -\item let \tcode{\placeholder{map-rank}} be an \tcode{array} such that -for each $k$ in the range \range{0}{rank}, -\tcode{\placeholder{map-rank}[$k$]} equals: + where \begin{itemize} \item - \tcode{dynamic_extent} - if $S_k$ models \tcode{\libconcept{convertible_to}}, + $o$ is the value of \tcode{S::offset_type::value} + if \tcode{S::offset_type} is a specialization of \tcode{constant_wrapper} and + \tcode{0} otherwise, \item - otherwise, - the number of types $S_j$ with $j < k$ that - do not model \tcode{\libconcept{convertible_to}}. + $e$ is the value of \tcode{S::extent_type::value} + if \tcode{S::extent_type} is a specialization of \tcode{constant_wrapper} and + \tcode{0} otherwise, + \item + $t$ is the value of \tcode{S::stride_type::value} + if \tcode{S::stride_type} is a specialization of \tcode{constant_wrapper} and + \tcode{1} otherwise; and + \end{itemize} +\item + if $S$ is a specialization of \tcode{constant_wrapper}, + then \tcode{S::value} is less than \tcode{x}. +\end{itemize} + +\pnum +Given an object \tcode{e} of type \tcode{E} +that is a specialization of \tcode{extents} and +an object \tcode{s} of type \tcode{S}, +\tcode{s} is a +\defnx{valid \tcode{submdspan} slice for the $k^\text{th}$ extent of \tcode{e}}{\tcode{submdspan}!valid slice for the $k^\text{th}$ extent of \tcode{e}} +if +\begin{itemize} +\item + \tcode{S} is a valid \tcode{submdspan} slice type for the $k^\text{th}$ extent of \tcode{E}; +\item + the $k^\text{th}$ interval of \tcode{e} + contains the \tcode{submdspan} slice range of \tcode{s} + for the $k^\text{th}$ extent of \tcode{e}; and +\item + if \tcode{S} is a specialization of \tcode{extent_slice}, then + \begin{itemize} + \item \tcode{s.extent} is greater than or equal to zero, and + \item either \tcode{s.extent} is less than two or \tcode{s.stride} is greater than zero. \end{itemize} \end{itemize} -\rSec4[mdspan.sub.strided.slice]{\tcode{strided_slice}} +\rSec4[mdspan.sub.range.slices]{Range slices} \pnum -\tcode{strided_slice} represents a set of +\tcode{extent_slice} and \tcode{range_slice} represent a set of \tcode{extent} regularly spaced integer indices. -The indices start at \tcode{offset}, and +The indices start at \tcode{offset} and \tcode{first}, respectively, and increase by increments of \tcode{stride}. -\indexlibraryglobal{strided_slice}% +\indexlibraryglobal{extent_slice}% +\indexlibraryglobal{range_slice}% \begin{codeblock} namespace std { template - struct strided_slice { - using offset_type = OffsetType; - using extent_type = ExtentType; - using stride_type = StrideType; - - [[no_unique_address]] offset_type offset{}; - [[no_unique_address]] extent_type extent{}; - [[no_unique_address]] stride_type stride{}; + struct extent_slice { + using @\libmember{offset_type}{extent_slice}@ = OffsetType; + using @\libmember{extent_type}{extent_slice}@ = ExtentType; + using @\libmember{stride_type}{extent_slice}@ = StrideType; + + [[no_unique_address]] offset_type @\libmember{offset}{extent_slice}@{}; + [[no_unique_address]] extent_type @\libmember{extent}{extent_slice}@{}; + [[no_unique_address]] stride_type @\libmember{stride}{extent_slice}@{}; + }; + + template> + struct range_slice { + [[no_unique_address]] FirstType @\libmember{first}{range_slice}@{}; + [[no_unique_address]] LastType @\libmember{last}{range_slice}@{}; + [[no_unique_address]] StrideType @\libmember{stride}{range_slice}@{}; }; } \end{codeblock} \pnum -\tcode{strided_slice} has the data members and special members specified above. -It has no base classes or members other than those specified. +\tcode{extent_slice} and \tcode{range_slice} +have the data members and special members specified above. +They have no base classes or members other than those specified. \pnum \mandates -\tcode{OffsetType}, \tcode{ExtentType}, and \tcode{StrideType} +\tcode{OffsetType}, \tcode{ExtentType}, +\tcode{FirstType}, \tcode{LastType}, and \tcode{StrideType} are signed or unsigned integer types, or model \exposconcept{integral-constant-like}. \begin{note} -\tcode{strided_slice\{.offset = 1, .extent = 10, .stride = 3\}} -indicates the indices \tcode{1}, \tcode{4}, \tcode{7}, and \tcode{10}. +Both \tcode{extent_slice\{.offset = 1, .extent = 4, .stride = 3\}} and +\tcode{range_slice\{.first = 1, .last = 11, .stride = 3\}} +indicate the indices \tcode{1}, \tcode{4}, \tcode{7}, and \tcode{10}. Indices are selected from the half-open interval \range{1}{1 + 10}. \end{note} @@ -23998,8 +25910,8 @@ namespace std { template struct submdspan_mapping_result { - [[no_unique_address]] LayoutMapping mapping = LayoutMapping(); - size_t offset{}; + [[no_unique_address]] LayoutMapping @\libmember{mapping}{submdspan_mapping_result}@ = LayoutMapping(); + size_t @\libmember{offset}{submdspan_mapping_result}@{}; }; } \end{codeblock} @@ -24015,209 +25927,257 @@ \rSec4[mdspan.sub.helpers]{Exposition-only helpers} -\indexlibraryglobal{\exposid{de-ice}}% -\indexlibraryglobal{\exposid{first_}}% +\pnum +\indexlibraryglobal{\tcode{\placeholder{MAP_RANK}}}% +For a pack \tcode{p} and an integer $i$, +let \tcode{\placeholder{MAP_RANK}(p, $i$)} be the number of elements \tcode{p...[$j$]} +for $0 \le j < i$ whose types are not collapsing slice types. + \begin{itemdecl} template - constexpr T @\exposid{de-ice}@(T val) { return val; } -template<@\exposconcept{integral-constant-like}@ T> - constexpr auto @\exposid{de-ice}@(T) { return T::value; } - -template - constexpr IndexType @\exposid{first_}@(SliceSpecifiers... slices); + concept @\defexposconcept{is-extent-slice}@ = @\seebelow;@ \end{itemdecl} \begin{itemdescr} \pnum -\mandates -\tcode{IndexType} is a signed or unsigned integer type. - -%FIXME: What is $k$ in this itemdescr? Did we mean the \tcode{k} passed to first_? If so, what do we do for de-ice? -\pnum -Let $\phi{}_k$ denote the following value: -\begin{itemize} -\item -$s_k$ if $S_k$ models \tcode{\libconcept{convertible_to}}; -\item -otherwise, -\tcode{get<0>($s_k$)} -if $S_k$ models \tcode{\exposconcept{index-pair-like}}; -\item -otherwise, -\tcode{\exposid{de-ice}($s_k$.offset)} -if $S_k$ is a specialization of \tcode{strided_slice}; -\item -otherwise, -\tcode{0}. -\end{itemize} +The concept \tcode{\exposconcept{is-extent-slice}} +is satisfied and modeled if and only +if \tcode{T} is a specialization of \tcode{extent_slice}. +\end{itemdescr} -\pnum -\expects -$\phi{}_k$ is representable as a value of type \tcode{IndexType}. +\begin{itemdecl} +template + concept @\defexposconcept{is-range-slice}@ = @\seebelow;@ +\end{itemdecl} +\begin{itemdescr} \pnum -\returns -\tcode{extents::\exposid{index-cast}($\phi{}_k$)}. +The concept \tcode{\exposconcept{is-range-slice}} +is satisfied and modeled if and only +if \tcode{T} is a specialization of \tcode{range_slice}. \end{itemdescr} -\indexlibraryglobal{\exposid{last_}}% +\indexlibraryglobal{\exposid{canonical-index}}% \begin{itemdecl} -template - constexpr auto @\exposid{last_}@(const Extents& src, SliceSpecifiers... slices); +template + constexpr auto @\exposid{canonical-index}@(S s); \end{itemdecl} \begin{itemdescr} \pnum \mandates -\tcode{Extents} is a specialization of \tcode{extents}. +If \tcode{S} models \exposconcept{integral-constant-like}, +then \tcode{extents::\exposid{index-cast}(S::val\-ue)} +is representable as a value of type \tcode{IndexType}. \pnum -Let \tcode{index_type} be \tcode{typename Extents::index_type}. +\expects +\tcode{extents::\exposid{index-cast}(std::move(s))} +is representable as a value of type \tcode{IndexType}. -%FIXME: What is $k$ in this itemdescr? Don't we want \tcode{k} and not $k$? \pnum -Let $\lambda{}_k$ denote the following value: +\effects +Equivalent to: \begin{itemize} \item -\tcode{\exposid{de-ice}($s_k$) + 1} -if $S_k$ models \tcode{\libconcept{convertible_to}}; otherwise -\item -\tcode{get<1>($s_k$)} -if $S_k$ models \tcode{\exposconcept{index-pair-like}}; otherwise +\tcode{return cw;} +if \tcode{S} models \exposconcept{integral-constant-like}; \item -\tcode{\exposid{de-ice}($s_k$.offset)} \tcode{+} -\tcode{\exposid{de-ice}($s_k$.extent)} -if $S_k$ is a specialization of \tcode{strided_slice}; otherwise +\tcode{return IndexType(std::move(s));} otherwise. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template + constexpr auto @\exposid{canonical-range-slice}@(OffsetType offset, SpanType span, StrideTypes... strides); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let +\begin{itemize} \item -%FIXME: Note that the paper uses \tcode{k} here. -\tcode{src.extent(k)}. + \tcode{StrideType} denote + \tcode{constant_wrapper} + if \tcode{StrideTypes} is an empty pack or + \tcode{SpanType} denotes \tcode{constant_wrapper}, otherwise + \tcode{StrideTypes...[0]}; +\item + \tcode{stride} be + \tcode{StrideType()} if \tcode{StrideType} + is a specialization of \tcode{constant_wrapper}, otherwise + \tcode{IndexType(1)} if \tcode{span == 0} is \tcode{true}, otherwise + \tcode{strides...[0]}; +\item + \exposid{extent-value} be \tcode{1 + (span - 1) / stride} + if \tcode{span != 0} is \tcode{true}, and + \tcode{0} otherwise; and +\item + let \tcode{extent} be \tcode{cw} + if both \tcode{SpanType} and \tcode{StrideType} + are specializations of \tcode{constant_wrapper}, and + \tcode{IndexType(\exposid{extent-value})} otherwise. \end{itemize} +\pnum +\mandates +\tcode{sizeof...(StrideTypes) <= 1} is \tcode{true}, and +if \tcode{StrideType} is a specialization of \tcode{con\-stant_wrapper}, +then \tcode{StrideType::value > 0} is \tcode{true}. + \pnum \expects -$\lambda{}_k$ is representable as a value of type \tcode{index_type}. +\tcode{stride > 0} is \tcode{true}. \pnum \returns -\tcode{Extents::\exposid{index-cast}($\lambda{}_k$)}. +\tcode{extent_slice\{.offset = offset, .extent = extent, .stride = stride\}}. \end{itemdescr} -\indexlibraryglobal{\exposid{src-indices}}% +\indexlibraryglobal{\exposid{canonical-slice}} \begin{itemdecl} -template - constexpr array - @\exposid{src-indices}@(const array& indices, SliceSpecifiers... slices); +template + constexpr auto @\exposid{canonical-slice}@(S s); \end{itemdecl} \begin{itemdescr} \pnum \mandates -\tcode{IndexType} is a signed or unsigned integer type. +\tcode{S} is a \tcode{submdspan} slice type for \tcode{IndexType}. \pnum -\returns -An \tcode{array src_idx} such that -for each $k$ in the range \range{0}{sizeof...(SliceSpecifiers)}, -\tcode{src_idx[$k$]} equals +\effects +Equivalent to: +\begin{codeblock} +if constexpr (is_convertible_v) { + return static_cast(std::move(s)); +} else if constexpr (is_convertible_v) { + return @\exposid{canonical-index}@(std::move(s)); +} else if constexpr (@\exposconcept{is-extent-slice}@) { + return extent_slice{ + .offset = @\exposid{canonical-index}@(std::move(s.offset)), + .extent = @\exposid{canonical-index}@(std::move(s.extent)), + .stride = @\exposid{canonical-index}@(std::move(s.stride)) + }; +} else if constexpr (@\exposconcept{is-range-slice}@) { + auto c_first = @\exposid{canonical-index}@(std::move(s.first)); + auto c_last = @\exposid{canonical-index}@(std::move(s.last)); + return @\exposid{canonical-slice-range}@( + c_first, + @\exposid{canonical-index}@(c_last - c_first), + @\exposid{canonical-index}@(std::move(s.stride))); +} else { + auto [s_first, s_last] = std::move(s); + auto c_first = @\exposid{canonical-index}@(std::move(s_first)); + auto c_last = @\exposid{canonical-index}@(std::move(s_last)); + return @\exposid{canonical-slice-range}@( + c_first, + @\exposid{canonical-index}@(c_last - c_first)); +} +\end{codeblock} +\end{itemdescr} + +\rSec4[mdspan.sub.canonical]{\tcode{submdspan} slice canonicalization} + +\indexlibraryglobal{canonical_slices}% +\begin{itemdecl} +template + constexpr auto canonical_slices(const extents& src, + SliceSpecifiers... slices); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{sizeof...(SliceSpecifiers)} equals \tcode{sizeof...(Extents)}. +\pnum +\mandates +For each rank index $k$ of \tcode{src}: \begin{itemize} \item -%FIXME: We're redefining what $k$ is here. -%FIXME: Also, calling first_ on each $k$ below gives us a set of indeces - how do we assign a set to the src_idx[$k$] above? -\tcode{\exposid{first_}(slices...)} for each $k$ -where \tcode{\placeholder{map-rank}[$k$]} equals -\tcode{dynamic_extent}, - + \tcode{SliceSpecifiers...[k]} + is a \tcode{submdspan} slice type for \tcode{IndexType}, and \item -%FIXME: How do we fail the previous \item to get here? There's no "if" test to fail. -otherwise, -\tcode{\exposid{first_}(slices...)} \tcode{+} -\tcode{indices[\placeholder{map-rank}[$k$]]}. + \tcode{decltype(\exposid{canonical-slice}(slices...[k]))} + is a valid \tcode{submdspan} slice type for the $k^\text{th}$ extent of + \tcode{extents}. \end{itemize} + +\pnum +\expects +For each rank index $k$ of \tcode{src}, +\tcode{\exposid{canonical-slice}(slices...[k])} +is a valid \tcode{submdspan} slice for the $k^\text{th}$ extent of \tcode{src}. + +\pnum +\returns +\tcode{make_tuple(\exposid{canonical-slice}(slices)...)}. \end{itemdescr} -\rSec4[mdspan.sub.extents]{\tcode{submdspan_extents} function} +\rSec4[mdspan.sub.extents]{\tcode{subextents} function} -\indexlibraryglobal{submdspan_extents}% +\indexlibraryglobal{subextents}% \begin{itemdecl} -template - constexpr auto submdspan_extents(const extents& src, - SliceSpecifiers... slices); +template + constexpr auto subextents(const extents& src, + SliceSpecifiers... raw_slices); \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{slices} be the pack introduced by the following declaration: +\begin{codeblock} +auto [...slices] = canonical_slices(src, raw_slices...); +\end{codeblock} + \pnum \constraints -\tcode{sizeof...(slices)} equals \tcode{Extents::rank()}. +\tcode{sizeof...(SliceSpecifiers)} equals \tcode{sizeof...(Extents)}. \pnum \mandates -For each rank index $k$ of \tcode{src.extents()}, -exactly one of the following is true: +For each rank index $k$ of \tcode{src}: \begin{itemize} -\item $S_k$ models \tcode{\libconcept{convertible_to}}, -\item $S_k$ models \tcode{\exposconcept{index-pair-like}}, -\item \tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}, or -\item $S_k$ is a specialization of \tcode{strided_slice}. +\item + \tcode{SliceSpecifiers...[$k$]} + is a \tcode{submdspan} slice type for \tcode{IndexType}, and +\item + \tcode{decltype(slices...[$k$])} is a valid \tcode{submdspan} slice type + for the $k^\text{th}$ extent of \tcode{extents<\brk{}Index\-Type, Extents...>}. \end{itemize} \pnum \expects -For each rank index $k$ of \tcode{src.extents()}, -all of the following are \tcode{true}: -\begin{itemize} -\item -if $S_k$ is a specialization of \tcode{strided_slice} - \begin{itemize} - \item $\tcode{$s_k$.extent} = 0$, or - \item $\tcode{$s_k$.stride} > 0$ - \end{itemize} -\item -$0 \le \tcode{\exposid{first_}(slices...)}$ -$\le \tcode{\exposid{last_}<$k$>(src, slices...)}$ -$\le \tcode{src.extent($k$)}$ -\end{itemize} +For each rank index $k$ of \tcode{src}, +\tcode{slices...[$k$]} is a valid \tcode{submdspan} slice +for the $k^\text{th}$ extent of \tcode{src}. \pnum Let \tcode{SubExtents} be a specialization of \tcode{extents} such that: \begin{itemize} \item -%FIXME: I think we want the count here, "number" is ambiguous. -\tcode{SubExtents::rank()} equals the number of $k$ such that -$S_k$ does not model \tcode{\libconcept{convertible_to}}; and +\tcode{SubExtents::rank()} equals +\tcode{\placeholder{MAP_RANK}(slices, Extents::rank())}; and \item -for each rank index $k$ of \tcode{Extents} such that -\tcode{\placeholder{map-rank}[$k$] != dynamic_extent} is \tcode{true}, -\tcode{SubExt\-ents::static_extent(\placeholder{map-rank}[$k$])} equals: +for each rank index $k$ of \tcode{extents} such that +the type of \tcode{slices...[$k$]} is not a collapsing slice type, +\tcode{SubExt\-ents::static_extent(\placeholder{MAP_RANK}(slices, $k$))} +equals the following, where $\Sigma_k$ +denotes the type of \tcode{slices...[$k$]}: \begin{itemize} \item \tcode{Extents::static_extent($k$)} - if \tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; + if $\Sigma_k$ denotes \tcode{full_extent_t}; otherwise \item - \tcode{\exposid{de-ice}(tuple_element_t<1, $S_k$>()) -} - \tcode{\exposid{de-ice}(tuple_element_t<0, $S_k$>())} - if $S_k$ models \tcode{\exposconcept{index-pair-like}}, and - both \tcode{tuple_element_t<0, $S_k$>} and - \tcode{tuple_elem\-ent_t<1, $S_k$>} - model \exposconcept{integral-constant-like}; otherwise - - \item - \tcode{0}, - if $S_k$ is a specialization of \tcode{strided_slice}, whose - \tcode{extent_type} models \exposconceptx{integral-cons\-tant-like}{integral-constant-like}, - for which \tcode{extent_type()} equals zero; otherwise - - \item - \tcode{1 + (\exposid{de-ice}($S_k$::extent_type()) - 1) /} - \tcode{\exposid{de-ice}($S_k$::stride_type())}, - if $S_k$ is a specialization of \tcode{strided_slice} whose - \tcode{extent_type} and \tcode{stride_type} - model \exposconceptx{integral-cons\-tant-like}{integral-constant-like}; + \tcode{$\Sigma_k$::extent_type::value} + if $\Sigma_k$ is a specialization of \tcode{extent_slice} whose + \tcode{extent_type} denotes a specialization of \tcode{constant_wrapper}; \item otherwise, @@ -24228,107 +26188,200 @@ \pnum \returns A value \tcode{ext} of type \tcode{SubExtents} such that -for each $k$ -for which \tcode{\placeholder{map-rank}[$k$] != dynamic_extent} is \tcode{true}, -\tcode{ext.extent(\placeholder{map-rank}[$k$])} equals: - +for each rank index $k$ of \tcode{extents}, +where the type of \tcode{slices...[$k$]} is not a collapsing slice type, +\tcode{ext.extent(\placeholder{MAP_RANK}(slices, $k$))} +equals the following, +where $\sigma_k$ denotes \tcode{slices...[$k$]}: \begin{itemize} \item -\tcode{$s_k$.extent == 0 ? 0 : 1 + (\exposid{de-ice}($s_k$.extent) - 1) / \exposid{de-ice}($s_k$.stride)} -if $S_k$ is a specialization of \tcode{strided_slice}, - + \tcode{$\sigma_k$.extent} + if the type of $\sigma_k$ is a specialization of \tcode{extent_slice}, \item -otherwise, -\tcode{\exposid{last_}<$k$>(src, slices...) - \exposid{first_}(slices...)}. + otherwise, + $U - L$, where \range{$L$}{$U$} is the \tcode{submdspan} slice range + of $\sigma_k$ for the $k^\text{th}$ extent of \tcode{src}. \end{itemize} \end{itemdescr} \rSec4[mdspan.sub.map]{Specializations of \tcode{submdspan_mapping}} -\rSec5[mdspan.sub.map.common]{Common} +\rSec5[mdspan.sub.map.sliceable]{Sliceable layout mapping requirements} \pnum -The following elements apply to all functions in \ref{mdspan.sub.map}. +Let: +\begin{itemize} +\item + \tcode{M} denote a layout mapping class; +\item + \tcode{IT} denote \tcode{M::extents_type::index_type}; +\item + \tcode{m} denote a value of type (possibly const) \tcode{M}; +\item + \tcode{M_rank} be equal to \tcode{M::extents_type::rank()}; +\item + \tcode{valid_slices} denote a pack of (possibly const) objects + for which \tcode{sizeof...(valid_slices) == M_rank} is \tcode{true} and, + for each rank index $i$ of \tcode{m.extents()}, + \tcode{valid_slices...[$i$]} is a valid \tcode{submdspan} slice + for the $i^\text{th}$ extent of \tcode{m.extents()}; +\item + \tcode{invalid_slices} denote a pack of objects + for which \tcode{sizeof...(invalid_slices) == M_rank} is \tcode{true} and + there exists an integer $k$ such that the cv-unqualified type + of \tcode{invalid_slices...[$k$]} is none of the following: + \begin{itemize} + \item \tcode{IT}, + \item \tcode{full_extent_t}, + \item a specialization of \tcode{constant_wrapper}, or + \item a specialization of \tcode{extent_slice}. + \end{itemize} +\end{itemize} \pnum -\constraints -\tcode{sizeof...(slices)} equals \tcode{extents_type::rank()}. +\indexlibraryglobal{submdspan_mapping}% +For the purpose of this section, +the meaning of \tcode{submdspan_mapping} is established +as if by performing argument-dependent lookup only\iref{basic.lookup.argdep}. \pnum -\mandates -For each rank index $k$ of \tcode{extents()}, -exactly one of the following is true: +A type \tcode{M} meets the \defn{sliceable layout mapping requirements} if \begin{itemize} \item -$S_k$ models \tcode{\libconcept{convertible_to}}, +\tcode{M} meets the layout mapping requirements\iref{mdspan.layout.policy.reqmts}, \item -$S_k$ models \tcode{\exposconcept{index-pair-like}}, +the expression \tcode{submdspan_mapping(m, invalid_slices...)} is ill-formed, and +\item +the following expression is well-formed and has the specified semantics: +\begin{codeblock} +submdspan_mapping(m, valid_slices...) +\end{codeblock} +\end{itemize} + +\begin{itemdescr} +\pnum +\result +A type \tcode{SMR} that is a specialization of type \tcode{submdspan_mapping_result} for some type \tcode{SM} such that +\begin{itemize} +\item \tcode{SM} meets the layout mapping requirements\iref{mdspan.layout.policy.reqmts}, +\item \tcode{SM::extents_type} is a specialization of \tcode{extents}, +\item \tcode{SM::extents_type::rank()} equals +\tcode{\placeholder{MAP_RANK}(valid_slices, M_rank)}, and +\item \tcode{SM::extents_type::index_type} denotes \tcode{IT}. +\end{itemize} + +\pnum +\returns +An object \tcode{smr} of type \tcode{SMR} such that +\begin{itemize} \item -\tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}, or + \tcode{smr.mapping.extents() == subextents(m.extents(), valid_slices...)} + is \tcode{true};\newline and \item -$S_k$ is a specialization of \tcode{strided_slice}. + for each integer pack \tcode{i} + which is a multidimensional index in \tcode{smr.mapping.extents()},\newline + \tcode{smr.mapping(i...) + smr.offset == m(j)} is \tcode{true}, + where \tcode{j} is an integer pack such that + \begin{itemize} + \item + \tcode{sizeof...(j)} is equal to \tcode{M_rank}; and + \item + for each rank index $\rho$ of \tcode{m.extents()}, + \tcode{j...[$\rho$]} is equal to the sum of + \begin{itemize} + \item + the lower bound of the \tcode{submdspan} slice range of \tcode{valid_slices...[$\rho$]} + for extent $\rho$ of \tcode{m.extents()}, and + \item + zero if the type of \tcode{valid_slices...[$\rho$]} is a collapsing slice type, + \tcode{i...[MAP_RANK(valid_slices,$\rho$)]} otherwise. + \end{itemize} + \end{itemize} \end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template + concept @\defexposconcept{sliceable-mapping}@ = @\seebelow@; +\end{itemdecl} +\begin{itemdescr} \pnum -\expects -For each rank index $k$ of \tcode{extents()}, -all of the following are \tcode{true}: +Let \tcode{lm} be an object of type \tcode{LayoutMapping} +and let \tcode{fe} denote a pack of objects of type \tcode{full_extent_t} +for which \tcode{sizeof...(fe) == LayoutMapping::extents_type::rank()} is \tcode{true}. +A type \tcode{LayoutMapping} satisfies \exposconcept{sliceable-mapping} if \begin{itemize} \item -if $S_k$ is a specialization of \tcode{strided_slice}, -\tcode{$s_k$.extent} is equal to zero or -\tcode{$s_k$.stride} is greater than zero; and + the expression \tcode{submdspan_mapping(lm, fe...)} is well-formed + when treated as an unevaluated operand, and \item -$0 \leq \tcode{\exposid{first_}(slices...)} \\ -\hphantom{0 } \leq \tcode{\exposid{last_}<$k$>(extents(), slices...)} \\ -\hphantom{0 } \leq \tcode{extents().extent($k$)}$ + the type of that expression is a specialization of + \tcode{submdspan_mapping_result}. \end{itemize} +\pnum +A type \tcode{LayoutMapping} models \exposconcept{sliceable-mapping} +if \tcode{LayoutMapping} meets the sliceable layout mapping requirements. +\end{itemdescr} + +\rSec5[mdspan.sub.map.common]{Common} + +\pnum +The following elements apply to all functions in \ref{mdspan.sub.map}. + +\pnum +\constraints +\tcode{sizeof...(SliceSpecifiers)} equals \tcode{extents_type::rank()}. + +\pnum +\mandates +For each rank index $k$ of \tcode{extents()}, +\tcode{SliceSpecifiers...[$k$]} is a valid \tcode{submdspan} slice type +for the $k^\text{th}$ extent of \tcode{Extents}. + +\pnum +\expects +For each rank index $k$ of \tcode{extents()}, +\tcode{slices...[$k$]} is a valid slice +for the $k^\text{th}$ extent of \tcode{extents()}. + \pnum Let \tcode{sub_ext} be -the result of \tcode{submdspan_extents(extents(), slices...)} and +the result of \tcode{subextents(extents(), slices...)} and let \tcode{SubExtents} be \tcode{decl\-type(sub_ext)}. \pnum Let \tcode{sub_strides} be an \tcode{array} such that for each rank index $k$ of \tcode{extents()} -for which \tcode{\exposid{map-rank}[$k$]} is not \tcode{dynamic_extent}, -\tcode{sub_strides[\exposid{map-rank}[$k$]]} equals: +for which the type of \tcode{slices...[$k$]} is not a collapsing slice type, +\tcode{sub_strides[\placeholder{MAP_RANK}(slices,$k$)]} equals: \begin{itemize} \item -\tcode{stride(k) * \exposid{de-ice}($s_k$.stride)} -if $S_k$ is a specialization of \tcode{strided_slice} and -\tcode{$s_k$.stride < $s_k$.\linebreak extent} is \tcode{true}; +\tcode{stride(k) * s.stride} +if the type of \tcode{s} is a specialization of \tcode{extent_slice} and +\tcode{s.extent > 1} is \tcode{true}, +where \tcode{s} is \tcode{slices...[$k$]}; \item otherwise, \tcode{stride($k$)}. \end{itemize} \pnum -Let \tcode{P} be a parameter pack -such that \tcode{is_same_v, index_sequence>} -is \tcode{true}. +Let \tcode{ls} be a pack of values of \tcode{index_type}, +where the $\rho^\text{th}$ element equals the lower bound +of the \tcode{submdspan} slice range of \tcode{slices...[$\rho$]} +for extent $\rho$ of \tcode{extents()}. \pnum -If \tcode{\exposid{first_}(slices...)} +If \tcode{ls...[$k$]} 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()}. +\tcode{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} +\tcode{operator()(ls...)}. \rSec5[mdspan.sub.map.left]{\tcode{layout_left} specialization of \tcode{submdspan_mapping}} @@ -24349,7 +26402,7 @@ if \tcode{Extents::rank() == 0} is \tcode{true}; \item otherwise, -\tcode{submdspan_mapping_result\{layout_left::mapping(sub_ext), offset\}}, +\tcode{submdspan_mapping_result\{layout_left::mapping(sub_ext), offset\}},\newline if \tcode{SubEx\-tents::rank() == 0} is \tcode{true}; \item otherwise, @@ -24357,15 +26410,15 @@ if \begin{itemize} \item - for each $k$ in the range \range{0}{SubExtents::rank() - 1)}, - \tcode{is_convertible_v<$S_k$, full_ext\-ent_t>} is \tcode{true}; and + for each $k$ in the range \range{0}{SubExtents::rank() - 1}, + \tcode{SliceSpecifiers...[$k$]} denotes \tcode{full_extent_t}; and \item for $k$ equal to \tcode{SubExtents::rank() - 1}, - $S_k$ is a unit-stride slice for \tcode{mapping}; + \tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; \end{itemize} \begin{note} If the above conditions are true, -all $S_k$ with $k$ larger than \tcode{SubExtents::rank() - 1} +all \tcode{SliceSpecifiers...[$k$]} with $k$ larger than \tcode{SubExtents\brk{}::rank\brk{}() - 1} are convertible to \tcode{index_type}. \end{note} \item @@ -24376,17 +26429,17 @@ \end{codeblock} if for a value $u$ for which $u+1$ is the smallest value $p$ larger than zero -for which $S_p$ is a unit-stride slice for \tcode{mapping}, +for which \tcode{SliceSpecifiers...\brk{}[\brk{}$p$]} is a unit-stride slice type, the following conditions are met: \begin{itemize} \item -$S_0$ is a unit-stride slice for \tcode{mapping}; and +\tcode{SliceSpecifiers...[0]} is a unit-stride slice type; 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 +\tcode{SliceSpecifiers...[$k$]} denotes \tcode{full_extent_t}; and \item for $k$ equal to \tcode{$u$ + SubExtents::rank() - 1}, -$S_k$ is a unit-stride slice for \tcode{mapping}; +\tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; \end{itemize} and where \tcode{S_static} is: \begin{itemize} @@ -24425,23 +26478,24 @@ if \tcode{Extents::rank() == 0} is \tcode{true}; \item otherwise, -\tcode{submdspan_mapping_result\{layout_right::mapping(sub_ext), offset\}}, +\tcode{submdspan_mapping_result\{layout_right::mapping(sub_ext), offset\}},\newline if \tcode{Sub\-Extents::rank() == 0} is \tcode{true}; \item otherwise, -\tcode{submdspan_mapping_result\{layout_left::mapping(sub_ext), offset\}}, +\tcode{submdspan_mapping_result\{layout_right::mapping(sub_ext), offset\}}, if \begin{itemize} \item - for each $k$ in the range \range{\exposid{rank_} - SubExtents::rank() + 1}{\exposid{rank_}}, - \tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}; and + for each $k$ in the range \range{\exposid{rank_} - SubExtents::rank() + 1}{\exposid{rank_}},\newline + \tcode{SliceSpecifiers...[$k$]} denotes \tcode{full_extent_t}; and \item - for $k$ equal to \exposid{_rank} - \tcode{SubExtents::rank()}, - $S_k$ is a unit-stride slice for \tcode{mapping}; + for $k$ equal to \exposid{rank_} - \tcode{SubExtents::rank()}, + \tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; \end{itemize} \begin{note} If the above conditions are true, -all $S_k$ with $k < \tcode{\exposid{_rank} - SubExtents::rank()}$ +all \tcode{SliceSpecifiers...[$k$]} with\newline +$k < \tcode{\exposid{rank_} - SubExtents::rank()}$ are convertible to \tcode{index_type}. \end{note} \item @@ -24452,19 +26506,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$ is a unit-stride slice for \tcode{mapping}, +for which \tcode{SliceSpecifiers...[$p$]} is a unit-stride slice type, the following conditions are met: \begin{itemize} \item for $k$ equal to \tcode{\exposid{rank_} - 1}, -$S_k$ is a unit-stride slice for \tcode{mapping}; and +\tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; 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 +\range{\exposid{rank_} - SubExtents::rank() - $u$ + 1}{\exposid{rank_} - $u$ - 1},\newline +\tcode{SliceSpecifiers...[$p$]} denotes \tcode{full_extent_t}; and \item -for $k$ equal to \tcode{\exposid{rank_} - SubExtents::rank() - $u$},\newline -$S_k$ is a unit-stride slice for \tcode{mapping}; +for $k$ equal to \tcode{\exposid{rank_} - SubExtents::rank() - $u$}, +\tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; \end{itemize} and where \tcode{S_static} is: \begin{itemize} @@ -24540,7 +26594,7 @@ \item \tcode{SubExtents::rank() == 1} is \tcode{true} and \item -$S_0$ is a unit-stride slice for \tcode{mapping}; +\tcode{SliceSpecifiers...[0]} is a unit-stride slice type; \end{itemize} \item otherwise, @@ -24550,17 +26604,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$ is a unit-stride slice for \tcode{mapping}, +for which \tcode{Slice\-Speci\-fiers\brk{}...[\brk{}$p$]} is a unit-stride slice type, the following conditions are met: \begin{itemize} \item -$S_0$ is a unit-stride slice for \tcode{mapping}; and +\tcode{SliceSpecifiers...[0]} is a unit-stride slice type; 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 +\tcode{SliceSpecifiers...[$k$]} denotes \tcode{full_extent_t}; and \item for $k$ equal to \tcode{$u$ + SubExtents::rank() - 1}, -$S_k$ is a unit-stride slice for \tcode{mapping}; +\tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; \end{itemize} where \tcode{S_static} is: \begin{itemize} @@ -24587,7 +26641,7 @@ \begin{itemdecl} template template -constexpr auto layout_right_padded::mapping::submdspan-mapping-impl( +constexpr auto layout_right_padded::mapping::@\exposid{submdspan-mapping-impl}@( SliceSpecifiers... slices) const -> @\seebelow@; \end{itemdecl} @@ -24612,7 +26666,7 @@ \tcode{SubExtents::rank() == 1} is \tcode{true} and \item for $k$ equal to \tcode{\exposid{rank_} - 1}, -$S_k$ is a unit-stride slice for \tcode{mapping}; +\tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; \end{itemize} \item otherwise, @@ -24622,20 +26676,20 @@ \end{codeblock} 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$ is a unit-stride slice for \tcode{mapping}, +is the largest value $p$ smaller than \tcode{\exposid{rank_} - 1} +for which \tcode{SliceSpecifiers...[$p$]} is a unit-stride slice type, the following conditions are met: \begin{itemize} \item for $k$ equal to \tcode{\exposid{rank_} - 1}, -$S_k$ is a unit-stride slice for \tcode{mapping}; and +\tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; 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 +\range{\exposid{rank_} - SubExtents::rank() - $u$ + 1}{\exposid{rank_} - $u$ - 1},\newline +\tcode{SliceSpecifiers...[$k$]} denotes \tcode{full_extent_t}; and \item -for $k$ equal to \tcode{\exposid{rank_} - SubExtents::rank() - $u$},\newline -$S_k$ is a unit-stride slice for \tcode{mapping}; +for $k$ equal to \tcode{\exposid{rank_} - SubExtents::rank() - $u$}, +\tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; \end{itemize} and where \tcode{S_static} is: \begin{itemize} @@ -24665,13 +26719,19 @@ class AccessorPolicy, class... SliceSpecifiers> constexpr auto submdspan( const mdspan& src, - SliceSpecifiers... slices) -> @\seebelow@; + SliceSpecifiers... raw_slices) -> @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{index_type} be \tcode{typename Extents::index_type}. +\pnum +Let \tcode{slices} be the pack introduced by the following declaration: +\begin{codeblock} +auto [...slices] = canonical_slices(src.extents(), raw_slices...); +\end{codeblock} + \pnum Let \tcode{sub_map_offset} be the result of \tcode{submdspan_mapping(src.mapping(), slices...)}. @@ -24688,79 +26748,35 @@ \item \tcode{sizeof...(slices)} equals \tcode{Extents::rank()}, and \item -the expression \tcode{submdspan_mapping(src.mapping(), slices...)} -is well-formed when treated as an unevaluated operand. +\tcode{LayoutPolicy::mapping} models \exposconcept{sliceable-mapping}. \end{itemize} \pnum \mandates +For each rank index $k$ of \tcode{src}: \begin{itemize} \item -\tcode{decltype(submdspan_mapping(src.mapping(), slices...))} -is a specialization of \tcode{submd-\linebreak{}span_mapping_result}. - -\item -\tcode{is_same_v,} -\tcode{decltype(\linebreak{}submdspan_extents(src.mapping(), slices...))>} -is \tcode{true}. - + \tcode{SliceSpecifiers...[$k$]} is a \tcode{submdspan} slice type + for \tcode{index_type}, and \item -For each rank index $k$ of \tcode{src.extents()}, -exactly one of the following is true: - \begin{itemize} - \item $S_k$ models \tcode{\libconcept{convertible_to}}, - \item $S_k$ models \tcode{\exposconcept{index-pair-like}}, - \item \tcode{is_convertible_v<$S_k$, full_extent_t>} is \tcode{true}, or - \item $S_k$ is a specialization of \tcode{strided_slice}. - \end{itemize} + \tcode{decltype(slices...[$k$])} is a valid \tcode{submdspan} slice type + for the $k^\text{th}$ extent of \tcode{Extents}. \end{itemize} \pnum \expects -\begin{itemize} -\item For each rank index $k$ of \tcode{src.extents()}, -all of the following are \tcode{true}: - \begin{itemize} - \item - if $S_k$ is a specialization of \tcode{strided_slice} - \begin{itemize} - \item $\tcode{$s_k$.extent} = 0$, or - \item $\tcode{$s_k$.stride} > 0$ - \end{itemize} - \item - $0 \le \tcode{\exposid{first_}(slices...)}$ - $\le \tcode{\exposid{last_}<$k$>(src.extents(), slices...)}$ - $\le \tcode{\linebreak{}src.extent($k$)}$ - \end{itemize} - -\item -\tcode{sub_map_offset.mapping.extents() == submdspan_extents(src.mapping(), slices...)}\linebreak -is \tcode{true}; and - -\item -for each integer pack \tcode{I} which is a multidimensional index -in \tcode{sub_map_offset.mapping.extents()}, -\begin{codeblock} -sub_map_offset.mapping(I...) + sub_map_offset.offset == - src.mapping()(@\exposid{src-indices}@(array{I...}, slices...)) -\end{codeblock} -is \tcode{true}. -\end{itemize} - -\begin{note} -These conditions ensure that the mapping returned by \tcode{submdspan_mapping} -matches the algorithmically expected index-mapping given the slice specifiers. -\end{note} +\tcode{slices...[$k$]} is a valid \tcode{submdspan} slice +for the $k^\text{th}$ extent of \tcode{src.extents()}. \pnum \effects Equivalent to: \begin{codeblock} auto sub_map_result = submdspan_mapping(src.mapping(), slices...); -return mdspan(src.accessor().offset(src.data(), sub_map_result.offset), +return mdspan(src.accessor().offset(src.data_handle(), sub_map_result.offset), sub_map_result.mapping, - AccessorPolicy::offset_policy(src.accessor())); + typename AccessorPolicy::offset_policy(src.accessor())); \end{codeblock} \end{itemdescr} @@ -24796,3 +26812,78 @@ } \end{codeblock} \end{example} + +\rSec3[mdspan.copy]{Multidimensional copy algorithms} + +\indexlibraryglobal{copy}% +\begin{itemdecl} +template + constexpr void copy(const Src& src, const Dst& dst); + +template + void copy(ExecutionPolicy&& policy, const Src& src, const Dst& dst); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{Src} and \tcode{Dst} are specializations of \tcode{mdspan}, +\item +\tcode{is_assignable_v} +is \tcode{true}, and +\item +\tcode{is_constructible_v} +is \tcode{true}. +\end{itemize} +\begin{note} +This constraint effectively verifies +that the ranks of the extents are the same and +that each extent is either static and the same, +or \tcode{dynamic_extent}. +\end{note} + +\pnum +\expects +\begin{itemize} +\item +\tcode{dst.is_unique()} is \tcode{true}, and +\item +for each multidimensional index \tcode{i} in \tcode{src.extents()}, +there is no multidimensional index \tcode{j} in \tcode{dst.extents()} +such that \tcode{src[i]} and \tcode{dst[j]} refer to the same element. +\end{itemize} + +\pnum +\hardexpects +\tcode{src.extents()} equals \tcode{dst.extents()}. + +\pnum +\effects +Assigns each element of \tcode{src} to the corresponding element of \tcode{dst}. +\end{itemdescr} + +\indexlibraryglobal{fill}% +\begin{itemdecl} +template + constexpr void fill(const Dst& dst, const T& value); + +template + void fill(ExecutionPolicy&& policy, const Dst& dst, const T& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{Dst} is a specialization of \tcode{mdspan}, and +\item +\tcode{is_assignable_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Assigns \tcode{value} to each element of \tcode{dst}. +\end{itemdescr} diff --git a/source/declarations.tex b/source/declarations.tex index 7cbe7fb501..d3821debca 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} @@ -53,6 +53,7 @@ using-enum-declaration\br using-directive\br static_assert-declaration\br + consteval-block-declaration\br alias-declaration\br opaque-enum-declaration \end{bnf} @@ -102,6 +103,11 @@ \keyword{static_assert} \terminal{(} constant-expression \terminal{,} static_assert-message \terminal{)} \terminal{;} \end{bnf} +\begin{bnf} +\nontermdef{consteval-block-declaration}\br + \keyword{consteval} compound-statement +\end{bnf} + \begin{bnf} \nontermdef{empty-declaration}\br \terminal{;} @@ -128,7 +134,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. @@ -243,10 +249,9 @@ \pnum If the \grammarterm{decl-specifier-seq} contains the \keyword{typedef} -specifier, the declaration is a \defnx{typedef declaration}{declaration!typedef} +specifier, the declaration is a \defnx{typedef declaration}{declaration!\idxcode{typedef}} and each \grammarterm{declarator-id} -is declared to be a \grammarterm{typedef-name}, synonymous with its -associated type\iref{dcl.typedef}. +is declared to be a \grammarterm{typedef-name}\iref{dcl.typedef}. \begin{note} Such a \grammarterm{declarator-id} is an \grammarterm{identifier}\iref{class.conv.fct}. @@ -323,7 +328,7 @@ In a \grammarterm{static_assert-declaration}, the \grammarterm{constant-expression} $E$ is contextually converted to \keyword{bool} and -the converted expression shall be a constant expression\iref{expr.const}. +the converted expression shall be a constant expression\iref{expr.const.const}. If the value of the expression $E$ when so converted is \tcode{true} or the expression is evaluated in the context of a template definition, the declaration has no effect and @@ -382,6 +387,35 @@ \end{codeblock} \end{example} +\pnum +For a \grammarterm{consteval-block-declaration} $D$, +the expression $E$ corresponding to $D$ is: +\begin{codeblock} + [] static consteval -> void @\grammarterm{compound-statement}@ () +\end{codeblock} +$E$ shall be a constant expression\iref{expr.const.const}. +\begin{note} +The evaluation of the expression +corresponding to a \grammarterm{consteval-block-declaration}\iref{lex.phases} +can produce injected declarations\iref{expr.const.reflect} as side effects. +\end{note} +\begin{example} +\begin{codeblock} +struct S; +consteval { + std::meta::define_aggregate(^^S, {}); // OK + + template + struct X { }; // error: local templates are not allowed + + template + concept C = true; // error: local concepts are not allowed + + return; // OK +} +\end{codeblock} +\end{example} + \pnum An \grammarterm{empty-declaration} has no effect. @@ -498,10 +532,10 @@ \grammarterm{storage-class-specifier} appears in a \grammarterm{decl-specifier-seq}, there can be no \tcode{typedef} specifier in the same \grammarterm{decl-specifier-seq} and -the \grammarterm{init-declarator-list} or \grammarterm{member-declarator-list} -of the declaration shall not be -empty (except for an anonymous union declared in a namespace scope\iref{class.union.anon}). The -\grammarterm{storage-class-specifier} applies to the name declared by each +the \grammarterm{init-declarator-list} of the \grammarterm{simple-declaration} or +the \grammarterm{member-declarator-list} of the \grammarterm{member-declaration} +shall not be empty (except for an anonymous union declared in a namespace scope\iref{class.union.anon}). +The \grammarterm{storage-class-specifier} applies to the name declared by each \grammarterm{init-declarator} in the list and not to any names declared by other specifiers. \begin{note} @@ -686,7 +720,7 @@ \pnum In an \grammarterm{explicit-specifier}, the \grammarterm{constant-expression}, if supplied, shall be a -contextually converted constant expression of type \tcode{bool}\iref{expr.const}. +contextually converted constant expression of type \tcode{bool}\iref{expr.const.const}. The \grammarterm{explicit-specifier} \keyword{explicit} without a \grammarterm{constant-expression} is equivalent to the \grammarterm{explicit-specifier} \tcode{explicit(true)}. @@ -706,11 +740,12 @@ \rSec2[dcl.typedef]{The \keyword{typedef} specifier}% \indextext{specifier!\idxcode{typedef}} +\indextext{declaration!\idxcode{typedef}}% +\indextext{declaration!\idxcode{typedef}|see{alias, type}}% \pnum Declarations containing the \grammarterm{decl-specifier} \keyword{typedef} -declare identifiers that can be used later for naming -fundamental\iref{basic.fundamental} or compound\iref{basic.compound} -types. The \keyword{typedef} specifier shall not be +declare \defnadjx{type}{aliases}{alias}. +The \keyword{typedef} specifier shall not be combined in a \grammarterm{decl-specifier-seq} with any other kind of specifier except a \grammarterm{defining-type-specifier}, and it shall not be used in the \grammarterm{decl-specifier-seq} of a @@ -728,14 +763,11 @@ A name declared with the \keyword{typedef} specifier becomes a \grammarterm{typedef-name}. -A \grammarterm{typedef-name} names +The underlying entity of the type alias is the type associated with the \grammarterm{identifier}\iref{dcl.decl} -or \grammarterm{simple-template-id}\iref{temp.pre}; -\indextext{declaration!typedef@\tcode{typedef} as type}% +or \grammarterm{simple-template-id}\iref{temp.pre}. \indextext{equivalence!type}% -\indextext{synonym!type name as}% -a \grammarterm{typedef-name} is thus a synonym for another type. A -\grammarterm{typedef-name} does not introduce a new type the way a class +A \grammarterm{typedef-name} does not introduce a new type the way a class declaration\iref{class.name} or enum declaration\iref{dcl.enum} does. \begin{example} After @@ -752,14 +784,14 @@ \end{example} \pnum -A \grammarterm{typedef-name} can also be introduced by an +A type alias can also be declared by an \grammarterm{alias-declaration}. The \grammarterm{identifier} following the -\tcode{using} keyword is not looked up; it becomes a \grammarterm{typedef-name} +\tcode{using} keyword is not looked up; +it becomes the \grammarterm{typedef-name} of a type alias and the optional \grammarterm{attribute-specifier-seq} following the -\grammarterm{identifier} appertains to that \grammarterm{typedef-name}. -Such a \grammarterm{typedef-name} has the same -semantics as if it were introduced by the \keyword{typedef} specifier. In -particular, it does not define a new type. +\grammarterm{identifier} appertains to that type alias. +Such a type alias has the same +semantics as if it were introduced by the \keyword{typedef} specifier. \begin{example} \begin{codeblock} using handler_t = void (*)(int); @@ -778,7 +810,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}. @@ -887,7 +919,7 @@ : x(a), y(x) // OK, definition { square(x); } constexpr pixel small(2); // error: \tcode{square} not defined, so \tcode{small(2)} - // not constant\iref{expr.const} so \keyword{constexpr} not satisfied + // not constant\iref{expr.const.core} so \keyword{constexpr} not satisfied constexpr void square(int &x) { // OK, definition x *= x; @@ -906,8 +938,8 @@ declares that function to be a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}. \begin{note} -A function or constructor declared with the \keyword{consteval} specifier -is an immediate function\iref{expr.const}. +A function declared with the \keyword{consteval} specifier +is an immediate function\iref{expr.const.imm}. \end{note} A destructor, an allocation function, or a deallocation function shall not be declared with the \keyword{consteval} specifier. @@ -916,14 +948,8 @@ \indextext{specifier!\idxcode{constexpr}!function}% \indextext{constexpr function}% A function is \defn{constexpr-suitable} if -\begin{itemize} -\item -it is not a coroutine\iref{dcl.fct.def.coroutine}, and +it is not a coroutine\iref{dcl.fct.def.coroutine}. -\item -if the function is a constructor or destructor, -its class does not have any virtual base classes. -\end{itemize} Except for instantiated constexpr functions, non-templated constexpr functions shall be constexpr-suitable. @@ -967,7 +993,7 @@ \begin{itemize} \item an invocation of a constexpr function -can appear in a constant expression\iref{expr.const} and +can appear in a constant expression\iref{expr.const.core} and \item copy elision is not performed in a constant expression\iref{class.copy.elision}. \end{itemize} @@ -1001,7 +1027,7 @@ Such an object shall have literal type and shall be initialized. -A \keyword{constexpr} variable shall be constant-initializable\iref{expr.const}. +A \keyword{constexpr} variable shall be constant-initializable\iref{expr.const.init}. 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. @@ -1039,7 +1065,7 @@ 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 -is reachable at the point of the initializing declaration. +is reachable at the point of the initializing declaration\ifndrdef{dcl.constinit.specifier.not.reachable}. \pnum If a variable declared with the \keyword{constinit} specifier has @@ -1065,21 +1091,32 @@ \indextext{specifier!\idxcode{inline}} \pnum +\indextext{specifier!\idxcode{inline}}% +\indextext{inline function}% +\indextext{inline variable}% The \keyword{inline} specifier shall be applied only to the declaration -of a variable or function. +of a function or variable. +The \keyword{inline} specifier shall not appear on a block scope declaration or +on the declaration of a function parameter. +If the \keyword{inline} specifier is used in a friend function declaration, that +declaration shall be a definition or the function shall have previously +been declared inline. \pnum -\indextext{specifier!\idxcode{inline}}% -\indextext{inline function}% A function declaration\iref{dcl.fct,class.mfct,class.friend} with an \keyword{inline} specifier declares an -\defnadj{inline}{function}. The inline specifier indicates to -the implementation that inline substitution of the function body at the -point of call is to be preferred to the usual function call mechanism. -An implementation is not required to perform this inline substitution at -the point of call; however, even if this inline substitution is omitted, -the other rules for inline functions specified in this subclause shall -still be respected. +\defnadj{inline}{function}. +A variable declaration with an \keyword{inline} specifier declares an +\defnadj{inline}{variable}. +\begin{note} +An inline function or variable +with external or module linkage +can be defined in multiple translation units\iref{basic.def.odr}, +but is one entity with one address. +A type or \keyword{static} variable +defined in the body of such a function +is therefore a single entity. +\end{note} \begin{note} The \keyword{inline} keyword has no effect on the linkage of a function. In certain cases, an inline function cannot use names with internal linkage; @@ -1087,15 +1124,13 @@ \end{note} \pnum -A variable declaration with an \keyword{inline} specifier declares an -\defnadj{inline}{variable}. - -\pnum -The \keyword{inline} specifier shall not appear on a block scope declaration or -on the declaration of a function parameter. -If the \keyword{inline} specifier is used in a friend function declaration, that -declaration shall be a definition or the function shall have previously -been declared inline. +The \keyword{inline} specifier indicates to +the implementation that inline substitution of the function body at the +point of call is to be preferred to the usual function call mechanism. +An implementation is not required to perform this inline substitution at +the point of call; however, even if this inline substitution is omitted, +the other rules for inline functions specified in this subclause shall +still be respected. \pnum If a definition of a function or variable is reachable @@ -1105,23 +1140,12 @@ is declared inline in one definition domain, an inline declaration of it shall be reachable from the end of every definition domain in which it is declared; -no diagnostic is required. +no diagnostic is required\ifndrdef{dcl.inline.missing.on.definition}. \begin{note} A call to an inline function or a use of an inline variable can be encountered before its definition becomes reachable in a translation unit. \end{note} -\pnum -\begin{note} -An inline function or variable -with external or module linkage -can be defined in multiple translation units\iref{basic.def.odr}, -but is one entity with one address. -A type or \keyword{static} variable -defined in the body of such a function -is therefore a single entity. -\end{note} - \pnum If an inline function or variable that is attached to a named module is declared in a definition domain, @@ -1209,13 +1233,6 @@ \grammarterm{cv-qualifier} shall appear in a complete \grammarterm{type-specifier-seq} or a complete \grammarterm{decl-specifier-seq}. -\begin{footnote} -There is no special -provision for a \grammarterm{decl-specifier-seq} that -lacks a \grammarterm{type-specifier} or that has a -\grammarterm{type-specifier} that only specifies \grammarterm{cv-qualifier}{s}. -The ``implicit int'' rule of C is no longer supported. -\end{footnote} \pnum \begin{note} @@ -1242,9 +1259,10 @@ There are two \grammarterm{cv-qualifier}{s}, \keyword{const} and \tcode{volatile}. Each \grammarterm{cv-qualifier} shall appear at most once in a \grammarterm{cv-qualifier-seq}. If a \grammarterm{cv-qualifier} appears in a -\grammarterm{decl-specifier-seq}, the \grammarterm{init-declarator-list} -or \grammarterm{member-declarator-list} of -the declaration shall not be empty. +\grammarterm{decl-specifier-seq}, +the \grammarterm{init-declarator-list} of the \grammarterm{simple-declaration} or +the \grammarterm{member-declarator-list} of the \grammarterm{member-declaration} +shall not be empty. \begin{note} \ref{basic.type.qualifier} and \ref{dcl.fct} describe how cv-qualifiers affect object and function types. @@ -1258,7 +1276,7 @@ \pnum \begin{note} Declaring a variable \keyword{const} can affect its linkage\iref{dcl.stc} -and its usability in constant expressions\iref{expr.const}. As +and its usability in constant expressions\iref{expr.const.init}. As described in~\ref{dcl.init}, the definition of an object or subobject of const-qualified type must specify an initializer or be subject to default-initialization. @@ -1277,9 +1295,9 @@ \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. +lifetime\iref{basic.life} results in undefined behavior\ubdef{dcl.type.cv.modify.const.obj}. \begin{example} \begin{codeblock} const int ci = 3; // cv-qualified (initialized as required) @@ -1323,7 +1341,7 @@ \impldef{semantics of an access through a volatile glvalue}. If an attempt is made to access an object defined with a volatile-qualified type through the use of a non-volatile glvalue, -the behavior is undefined. +the behavior is undefined\ubdef{dcl.type.cv.access.volatile}. \pnum \indextext{type specifier!\idxcode{volatile}}% @@ -1350,7 +1368,8 @@ nested-name-specifier \keyword{template} simple-template-id\br computed-type-specifier\br placeholder-type-specifier\br - \opt{nested-name-specifier} template-name\br + \opt{nested-name-specifier} simple-template-name\br + pack-index-template-name\br \keyword{char}\br \keyword{char8_t}\br \keyword{char16_t}\br @@ -1377,7 +1396,8 @@ \begin{bnf} \nontermdef{computed-type-specifier}\br decltype-specifier\br - pack-index-specifier + pack-index-specifier\br + splice-type-specifier \end{bnf} \pnum @@ -1386,7 +1406,7 @@ \grammarterm{nested-name-specifier}, \grammarterm{type-name}, \grammarterm{simple-template-id}, -\grammarterm{template-name}, and/or +\grammarterm{simple-template-name}, and/or \grammarterm{type-constraint} (if it is a \grammarterm{placeholder-type-specifier}). The component name of a \grammarterm{type-name} is the first name in it. @@ -1412,14 +1432,34 @@ is a placeholder for a type to be deduced\iref{dcl.spec.auto}. \indextext{deduction!class template arguments}% -A \grammarterm{type-specifier} of the form -\opt{\keyword{typename}} \opt{\grammarterm{nested-name-specifier}} \grammarterm{template-name} -is a placeholder for -a deduced class type\iref{dcl.type.class.deduct}. -The \grammarterm{nested-name-specifier}, if any, shall be non-dependent and -the \grammarterm{template-name} shall name a deducible template. -A \defnadj{deducible}{template} is either a class template or -is an alias template whose \grammarterm{defining-type-id} is of the form +A \grammarterm{type-specifier} is a placeholder for +a deduced class type\iref{dcl.type.class.deduct} if +\begin{itemize} +\item +it is of the form +\opt{\keyword{typename}} \opt{\grammarterm{nested-name-specifier}} \grammarterm{simple-template-name}, or +\item +it is of the form +\opt{\keyword{typename}} \grammarterm{pack-index-template-name}, or +\item +it is of the form \opt{\keyword{typename}} \grammarterm{splice-specifier} and +the \grammarterm{splice-specifier} designates +a class template or alias template. +\end{itemize} +The \grammarterm{nested-name-specifier} or \grammarterm{splice-specifier}, +if any, shall be non-dependent and the +\grammarterm{simple-template-name}, +\grammarterm{pack-index-template-name}, or +\grammarterm{splice-specifier} +shall designate a deducible template. +A \defnadj{deducible}{template} is +\begin{itemize} +\item +a class template, +\item +a type template template parameter, or +\item +an alias template \tcode{A} whose \grammarterm{defining-type-id} is of the form \begin{ncsimplebnf} \opt{\keyword{typename}} \opt{nested-name-specifier} \opt{\keyword{template}} simple-template-id @@ -1427,7 +1467,9 @@ where the \grammarterm{nested-name-specifier} (if any) is non-dependent and the \grammarterm{template-name} of the \grammarterm{simple-template-id} -names a deducible template. +names a deducible template +other than a type template template parameter of \tcode{A}. +\end{itemize} \begin{note} An injected-class-name is never interpreted as a \grammarterm{template-name} in contexts where class template argument deduction would be performed\iref{temp.local}. @@ -1455,6 +1497,7 @@ \grammarterm{placeholder-type-specifier} & the type as defined in~\ref{dcl.spec.auto}\\ \grammarterm{template-name} & the type as defined in~\ref{dcl.type.class.deduct}\\ +\grammarterm{splice-type-specifier} & the type as defined in~\ref{dcl.type.splice}\\ \tcode{char} & ``\tcode{char}'' \\ \tcode{unsigned char} & ``\tcode{unsigned char}'' \\ \tcode{signed char} & ``\tcode{signed char}'' \\ @@ -1510,11 +1553,11 @@ \pnum The \grammarterm{typedef-name} $P$ in a \grammarterm{pack-index-specifier} -shall denote a pack. +shall be an \grammarterm{identifier} that denotes a pack. \pnum The \grammarterm{constant-expression} shall be -a converted constant expression\iref{expr.const} of type \tcode{std::size_t} +a converted constant expression\iref{expr.const.const} of type \tcode{std::size_t} whose value $V$, termed the index, is such that $0 \le V < \tcode{sizeof...($P$)}$. @@ -1671,8 +1714,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}; @@ -1683,6 +1726,10 @@ type of the entity named by $E$. If there is no such entity, the program is ill-formed; +\item otherwise, if $E$ is an unparenthesized \grammarterm{splice-expression}, +\tcode{decltype($E$)} is the type of the entity, object, or value +designated by the \grammarterm{splice-specifier} of $E$; + \item otherwise, if $E$ is an xvalue, \tcode{decltype($E$)} is \tcode{T\&\&}, where \tcode{T} is the type of $E$; @@ -1706,11 +1753,13 @@ decltype(i) x2; // type is \tcode{int} decltype(a->x) x3; // type is \tcode{double} decltype((a->x)) x4 = x3; // type is \tcode{const double\&} +decltype([:^^x1:]) x5 = 18; // type is \tcode{const int\&\&} +decltype(([:^^x1:])) x6 = 19; // type is \tcode{const int\&} void f() { [](auto ...pack) { - decltype(pack...[0]) x5; // type is \tcode{int} - decltype((pack...[0])) x6; // type is \tcode{int\&} + decltype(pack...[0]) x7; // type is \tcode{int} + decltype((pack...[0])) x8; // type is \tcode{int\&} }(0); } \end{codeblock} @@ -1722,7 +1771,7 @@ \pnum If the operand of a \grammarterm{decltype-specifier} is a prvalue -and is not a (possibly parenthesized) immediate invocation\iref{expr.const}, +and is not a (possibly parenthesized) immediate invocation\iref{expr.const.imm}, the temporary materialization conversion is not applied\iref{conv.rval} and no result object is provided for the prvalue. The type of the prvalue may be incomplete or an abstract class type. @@ -1826,7 +1875,8 @@ \pnum A placeholder type can appear in the \grammarterm{decl-specifier-seq} or \grammarterm{type-specifier-seq} -in the declared return type of a function declarator that declares a function; +in the declared return type of a function declarator +that declares a function other than a conversion function\iref{class.conv.fct}; the return type of the function is deduced from non-discarded \tcode{return} statements, if any, in the body of the function\iref{stmt.if}. @@ -1867,9 +1917,9 @@ A placeholder type can also be used in the \grammarterm{type-specifier-seq} of the \grammarterm{new-type-id} or -in the \grammarterm{type-id} of a +in the \grammarterm{nofun-type-id} of a \grammarterm{new-expression}\iref{expr.new}. -In such a \grammarterm{type-id}, +In such a \grammarterm{nofun-type-id}, the placeholder type shall appear as one of the \grammarterm{type-specifier}{s} in the \grammarterm{type-specifier-seq} or @@ -1950,6 +2000,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 @@ -2106,9 +2170,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} @@ -2125,11 +2189,15 @@ shall precede\iref{basic.lookup.general} the \grammarterm{placeholder-type-specifier}. Obtain \tcode{P} from -\tcode{T} by replacing the occurrences of +\tcode{T} by replacing the occurrence of \opt{\grammarterm{type-constraint}} \keyword{auto} either with a new invented type template parameter \tcode{U} or, if the initialization is copy-list-initialization, with -\tcode{std::initializer_list}. Deduce a value for \tcode{U} using the rules +\tcode{std::initializer_list}. +If $E$ is a value synthesized for a constant template parameter +of type \tcode{decltype(auto)}\iref{temp.func.order}, +the declaration is ill-formed. +Otherwise, deduce a value for \tcode{U} using the rules of template argument deduction from a function call\iref{temp.deduct.call}, where \tcode{P} is a function template parameter type and @@ -2226,7 +2294,7 @@ A placeholder for a deduced class type can also be used in the \grammarterm{type-specifier-seq} -in the \grammarterm{new-type-id} or \grammarterm{type-id} +in the \grammarterm{new-type-id} or \grammarterm{nofun-type-id} of a \grammarterm{new-expression}\iref{expr.new}, as the \grammarterm{simple-type-specifier} in an explicit type conversion (functional notation)\iref{expr.type.conv}, @@ -2252,6 +2320,59 @@ container e{5, 6}; // error: \tcode{int} is not an iterator \end{codeblock} \end{example} + +\rSec3[dcl.type.splice]{Type splicing} + +\begin{bnf} +\nontermdef{splice-type-specifier}\br + \opt{\keyword{typename}} splice-specifier\br + \opt{\keyword{typename}} splice-specialization-specifier +\end{bnf} + +\pnum +A \grammarterm{splice-specifier} or +\grammarterm{splice-specialization-specifier} +immediately followed by \tcode{::} +is never interpreted as part of a \grammarterm{splice-type-specifier}. +A \grammarterm{splice-specifier} or +\grammarterm{splice-specialization-specifier} +not preceded by \keyword{typename} +is only interpreted as a \grammarterm{splice-type-specifier} +within a type-only context\iref{temp.res.general}. +\begin{example} +\begin{codeblock} +template void tfn() { + typename [:R:]::type m; // OK, \keyword{typename} applies to the qualified name +} + +struct S { using type = int; }; +void fn() { + [:^^S::type:] *var; // error: \tcode{[:\caret\caret S::type:]} is an expression + typename [:^^S::type:] *var; // OK, declares variable with type \tcode{int*} +} + +using alias = [:^^S::type:]; // OK, type-only context +\end{codeblock} +\end{example} + +\pnum +For a \grammarterm{splice-type-specifier} of the form +\opt{\keyword{typename}} \grammarterm{splice-specifier}, +the \grammarterm{splice-specifier} shall designate +a type, a class template, or an alias template. +The \grammarterm{splice-type-specifier} designates +the same entity as the \grammarterm{splice-specifier}. + +\pnum +For a \grammarterm{splice-type-specifier} of the form +\opt{\keyword{typename}} \grammarterm{splice-specialization-specifier}, +the \grammarterm{splice-specifier} of +the \grammarterm{splice-specialization-specifier} +shall designate a template \tcode{T} +that is either a class template or an alias template. +The \grammarterm{splice-type-specifier} designates +the specialization of \tcode{T} corresponding to +the template argument list of the \grammarterm{splice-specialization-specifier}. \indextext{specifier|)}% \rSec1[dcl.decl]{Declarators}% @@ -2282,8 +2403,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 @@ -2304,8 +2425,10 @@ \end{note} \pnum -Each \grammarterm{init-declarator} or \grammarterm{member-declarator} -in a declaration is analyzed separately as if it were in a declaration by itself. +Each \grammarterm{init-declarator} of a \grammarterm{simple-declaration} +or \grammarterm{member-declarator} of a \grammarterm{member-declaration} +is analyzed separately as if it were in a +\grammarterm{simple-declaration} or \grammarterm{member-declaration} by itself. \begin{note} A declaration with several declarators is usually equivalent to the corresponding sequence of declarations each with a single declarator. That is, @@ -2347,9 +2470,16 @@ \end{note} \pnum -The optional \grammarterm{requires-clause} in an +The \grammarterm{initializer} of an \grammarterm{init-declarator} +shall not be present unless +the declarator declares a variable and +the host scope\iref{basic.scope.scope} of the declaration +is the same as its target scope. + +\pnum +The optional \grammarterm{requires-clause} of an \grammarterm{init-declarator} or \grammarterm{member-declarator} -shall be present only if the declarator declares a +shall not be present unlesss the declarator declares a templated function\iref{temp.pre}. % \indextext{trailing requires-clause@trailing \gterm{requires-clause}|see{\gterm{requires-clause}, trailing}}% @@ -2375,6 +2505,12 @@ \end{codeblock} \end{example} +\pnum +The optional \grammarterm{function-contract-specifier-seq}\iref{dcl.contract.func} +of an \grammarterm{init-declarator} +shall not be present unless +the \grammarterm{declarator} declares a function. + \pnum Declarators have the syntax @@ -2406,11 +2542,11 @@ \begin{bnf} \nontermdef{trailing-return-type}\br - \terminal{->} type-id + \terminal{->} nofun-type-id \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 @@ -2444,20 +2580,40 @@ \pnum \indextext{type name}% -To specify type conversions explicitly, \indextext{operator!cast}% -and as an argument of -\tcode{sizeof}, -\tcode{alignof}, -\keyword{new}, -or -\tcode{typeid}, -the name of a type shall be specified. -This can be done with a -\grammarterm{type-id} or \grammarterm{new-type-id}\iref{expr.new}, -which is syntactically a declaration for a variable or function +A type can be named with a +\grammarterm{type-id}, +\grammarterm{nofun-type-id}, or +\grammarterm{new-type-id}\iref{expr.new}, +each of +which is syntactically a declaration for a variable or +(only for a \grammarterm{type-id}) function of that type that omits the name of the entity. +\begin{bnf} +\nontermdef{nofun-type-id}\br + type-specifier-seq \opt{nofun-declarator} +\end{bnf} + +\begin{bnf} +\nontermdef{nofun-declarator}\br + ptr-nofun-declarator\br + noptr-nofun-declarator parameters-and-qualifiers trailing-return-type +\end{bnf} + +\begin{bnf} +\nontermdef{ptr-nofun-declarator}\br + noptr-nofun-declarator\br + ptr-operator \opt{ptr-nofun-declarator} +\end{bnf} + +\begin{bnf} +\nontermdef{noptr-nofun-declarator}\br + noptr-nofun-declarator parameters-and-qualifiers\br + \opt{noptr-nofun-declarator} \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br + \terminal{(} ptr-nofun-declarator \terminal{)} +\end{bnf} + \begin{bnf} \nontermdef{type-id}\br type-specifier-seq \opt{abstract-declarator} @@ -2502,6 +2658,7 @@ It is possible to identify uniquely the location in the \grammarterm{abstract-declarator} +or \grammarterm{nofun-declarator} where the identifier would appear if the construction were a declarator in a declaration. The named type is then the same as the type of the @@ -2593,6 +2750,10 @@ \grammarterm{type-id} in its syntactic context shall be considered a \grammarterm{type-id}. +\begin{note} +No such ambiguity can arise between an expression and +a \grammarterm{nofun-type-id}. +\end{note} However, a construct that can syntactically be a \grammarterm{type-id} whose outermost \grammarterm{abstract-declarator} would match the grammar of an \grammarterm{abstract-declarator} @@ -2602,25 +2763,24 @@ \begin{codeblock} template struct X {}; template struct Y {}; -X a; // type-id +X a; // \grammarterm{type-id} X b; // expression (ill-formed) -Y c; // type-id (ill-formed) +Y c; // \grammarterm{type-id} (ill-formed) Y d; // expression void foo(signed char a) { - sizeof(int()); // type-id (ill-formed) + sizeof(int()); // expression sizeof(int(a)); // expression - sizeof(int(unsigned(a))); // type-id (ill-formed) - - (int())+1; // type-id (ill-formed) + sizeof(int(unsigned(a))); // expression + (int())+1; // expression (int(a))+1; // expression - (int(unsigned(a)))+1; // type-id (ill-formed) + (int(unsigned(a)))+1; // expression } typedef struct BB { int C[2]; } *B, C; void g() { sizeof(B()->C[1]); // OK, \tcode{\keyword{sizeof}(}expression\tcode{)} - sizeof(auto()->C[1]); // error: \keyword{sizeof} of a function returning an array + sizeof(auto()->C[1]); // error: ill-formed expression } \end{codeblock} \end{example} @@ -2834,7 +2994,7 @@ specifier or an \grammarterm{explicit-specifier} applies directly to each \grammarterm{declarator-id} -in a declaration; +in a \grammarterm{simple-declaration} or \grammarterm{member-declaration}; the type specified for each \grammarterm{declarator-id} depends on both the \grammarterm{decl-specifier-seq} and its \grammarterm{declarator}. @@ -3004,11 +3164,9 @@ *ppc = &ci; // OK, but would make \tcode{p} point to \tcode{ci} because of previous error *p = 5; // clobber \tcode{ci} \end{codeblock} +See also~\ref{expr.assign} and~\ref{dcl.init}. \end{example} -\pnum -See also~\ref{expr.ass} and~\ref{dcl.init}. - \pnum \begin{note} Forming a pointer to reference type is ill-formed; see~\ref{dcl.ref}. @@ -3165,11 +3323,11 @@ the converted initializer is a glvalue whose type is not call-compatible\iref{expr.call} with the type of the function's definition -results in undefined behavior. +results in undefined behavior\ubdef{dcl.ref.incompatible.function}. Attempting to bind a reference to an object where the converted initializer is a glvalue through which the object is not type-accessible\iref{basic.lval} -results in undefined behavior. +results in undefined behavior\ubdef{dcl.ref.incompatible.type}. \begin{note} \indextext{reference!null}% The object designated by such a glvalue can be @@ -3183,7 +3341,7 @@ \end{note} The behavior of an evaluation of a reference\iref{expr.prim.id, expr.ref} that does not happen after\iref{intro.races} the initialization of the reference -is undefined. +is undefined\ubdef{dcl.ref.uninitialized.reference}. \begin{example} \begin{codeblock} int &f(int&); @@ -3256,7 +3414,7 @@ \end{ncsimplebnf} and the \grammarterm{nested-name-specifier} -denotes a class, +designates a class, and the type of the contained \grammarterm{declarator-id} in the declaration \tcode{T} \tcode{D1} @@ -3269,6 +3427,7 @@ \tcode{T}''. The optional \grammarterm{attribute-specifier-seq}\iref{dcl.attr.grammar} appertains to the pointer-to-member. +The \grammarterm{nested-name-specifier} shall not designate an anonymous union. \pnum \begin{example} @@ -3360,7 +3519,7 @@ the type of the \grammarterm{declarator-id} in \tcode{D} is ``\placeholder{derived-declarator-type-list} array of \tcode{N} \tcode{T}''. The \grammarterm{constant-expression} -shall be a converted constant expression of type \tcode{std::size_t}\iref{expr.const}. +shall be a converted constant expression of type \tcode{std::size_t}\iref{expr.const.const}. \indextext{bound, of array}% Its value \tcode{N} specifies the \defnx{array bound}{array!bound}, i.e., the number of elements in the array; @@ -3433,6 +3592,8 @@ of \tcode{N} subobjects of type \tcode{U}, known as the \defnx{elements}{array!element} of the array, and numbered \tcode{0} to \tcode{N-1}. +The element numbered \tcode{0} is termed +the \defnx{first element}{array!first element} of the array. \pnum In addition to declarations in which an incomplete object type is allowed, @@ -3449,8 +3610,10 @@ and the type of the array is ``array of \tcode{N} \tcode{U}''. \pnum -Furthermore, if there is a reachable declaration of the entity that inhabits the same -scope in which the bound was specified, an omitted array bound is taken to +Furthermore, if there is a reachable declaration of the entity +that specifies a bound and +has the same host scope\iref{basic.scope.scope}, +an omitted array bound is taken to be the same as in that earlier declaration, and similarly for the definition of a static data member of a class. \begin{example} @@ -3467,6 +3630,9 @@ extern int x[]; int i = sizeof(x); // error: incomplete object type } + +namespace A { extern int z[3]; } +int A::z[] = {}; // OK, defines an array of 3 elements \end{codeblock} \end{example} @@ -3662,13 +3828,30 @@ If the \grammarterm{parameter-declaration-clause} is empty, the function takes no arguments. -A parameter list consisting of a single unnamed non-object parameter of -non-dependent type \keyword{void} is equivalent to an empty parameter -list. +A parameter list consisting of a single unnamed non-object parameter +whose type is the same as\iref{temp.over.link} \keyword{void} +is interpreted as an empty parameter list. \indextext{parameter!\idxcode{void}}% Except for this special case, a parameter shall not have type \cv{}~\keyword{void}. A parameter with volatile-qualified type is deprecated; see~\ref{depr.volatile.type}. +\begin{example} +\begin{codeblock} +template +struct S { + void f(std::void_t); // \#1 +}; +S x; // error: \#1 has a parameter of type \tcode{void} + +template +struct S2 { + void f(std::void_t); // \#2 +}; +S2 y; // OK, \#2 is a zero-parameter function +\end{codeblock} +\end{example} + +\pnum If the \grammarterm{parameter-declaration-clause} \indextext{argument type!unknown}% @@ -3753,6 +3936,10 @@ \end{codeblock} \end{example} +\pnum +A function with a parameter-type-list that has an ellipsis +is termed a \defnadj{vararg}{function}. + \pnum An \defn{explicit-object-parameter-declaration} is a \grammarterm{parameter-declaration} with a \keyword{this} specifier. @@ -3819,7 +4006,7 @@ \pnum A function type with a \grammarterm{cv-qualifier-seq} or a -\grammarterm{ref-qualifier} (including a type named by +\grammarterm{ref-qualifier} (including a type denoted by \grammarterm{typedef-name}\iref{dcl.typedef,temp.param}) shall appear only as: \begin{itemize} @@ -3831,19 +4018,22 @@ or \grammarterm{alias-declaration}, \item the \grammarterm{type-id} in the default argument of a -\grammarterm{type-parameter}\iref{temp.param}, or +\grammarterm{type-parameter}\iref{temp.param}, \item the \grammarterm{type-id} of a \grammarterm{template-argument} for a -\grammarterm{type-parameter}\iref{temp.arg.type}. +\grammarterm{type-parameter}\iref{temp.arg.type}, or + +\item the operand of a \grammarterm{reflect-expression}\iref{expr.reflect}. \end{itemize} \begin{example} \begin{codeblock} typedef int FIC(int) const; -FIC f; // error: does not declare a member function +FIC f; // error: does not declare a member function struct S { - FIC f; // OK + FIC f; // OK }; -FIC S::*pm = &S::f; // OK +FIC S::*pm = &S::f; // OK +constexpr std::meta::info yeti = ^^void(int) const &; // OK \end{codeblock} \end{example} @@ -4021,7 +4211,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}, @@ -4031,7 +4221,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. @@ -4040,7 +4230,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 = /* ... */; @@ -4068,7 +4258,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} @@ -4140,10 +4330,10 @@ \indextext{declaration!default argument|(} \pnum -If an \grammarterm{initializer-clause}{} is specified in a -\grammarterm{parameter-declaration}{} this -\grammarterm{initializer-clause}{} -is used as a default argument. +If an \grammarterm{initializer-clause} is specified in a +\grammarterm{parameter-declaration} that is not a +\grammarterm{template-parameter}\iref{temp.param}, +this \grammarterm{initializer-clause} is used as a default argument. \begin{note} Default arguments will be used in calls where trailing arguments are missing\iref{expr.call}. @@ -4174,15 +4364,10 @@ A default argument shall be specified only in the \grammarterm{parameter-declaration-clause} of a function declaration -or \grammarterm{lambda-declarator} -or in a -\grammarterm{template-parameter}\iref{temp.param}. +or \grammarterm{lambda-declarator}. A default argument shall not be specified for -a template parameter pack or a function parameter pack. -If it is specified in a -\grammarterm{parameter-declaration-clause}, -it shall not occur within a +A default argument shall not occur within a \grammarterm{declarator} or \grammarterm{abstract-declarator} @@ -4200,9 +4385,9 @@ \pnum For non-template functions, default arguments can be added in later declarations of a -function that inhabit the same scope. -Declarations that inhabit different -scopes have completely distinct sets of default arguments. +function that have the same host scope. +Declarations that have different +host scopes have completely distinct sets of default arguments. That is, declarations in inner scopes do not acquire default arguments from declarations in outer scopes, and vice versa. @@ -4245,7 +4430,8 @@ \end{example} For a given inline function defined in different translation units, the accumulated sets of default arguments at the end of the -translation units shall be the same; no diagnostic is required. +translation units shall be the same; +no diagnostic is required\ifndrdef{dcl.fct.default.inline.same.defaults}. If a friend declaration $D$ specifies a default argument expression, that declaration shall be a definition and there shall be no other declaration of the function or function template @@ -4262,7 +4448,7 @@ The names in the default argument are looked up, and the semantic constraints are checked, at the point where the default argument appears, except that -an immediate invocation\iref{expr.const} that +an immediate invocation\iref{expr.const.imm} that is a potentially-evaluated subexpression\iref{intro.execution} of the \grammarterm{initializer-clause} in a \grammarterm{parameter-declaration} is neither evaluated @@ -4357,7 +4543,7 @@ A default argument is evaluated each time the function is called with no argument for the corresponding parameter. \indextext{argument!scope of default}% -A parameter shall not appear as a potentially-evaluated expression +A parameter shall not appear as a potentially evaluated expression in a default argument. \indextext{argument and name hiding!default}% \begin{note} @@ -4373,9 +4559,19 @@ int h(int a, int b = sizeof(a)); // OK, unevaluated operand\iref{term.unevaluated.operand} \end{codeblock} \end{example} -A non-static member shall not appear in a default argument unless it appears as -the \grammarterm{id-expression} of a class member access expression\iref{expr.ref} or -unless it is used to form a pointer to member\iref{expr.unary.op}. +A non-static member shall not be designated in a default argument unless +\begin{itemize} +\item +it is designated by +the \grammarterm{id-expression} or \grammarterm{splice-expression} +of a class member access expression\iref{expr.ref}, +\item +it is designated by an expression +used to form a pointer to member\iref{expr.unary.op}, or +\item +it appears as the operand of +a \grammarterm{reflect-expression}\iref{expr.reflect}. +\end{itemize} \begin{example} The declaration of \tcode{X::mem1()} @@ -4387,8 +4583,10 @@ int b; class X { int a; - int mem1(int i = a); // error: non-static member \tcode{a} used as default argument - int mem2(int i = b); // OK; use \tcode{X::b} + int mem1(int i = a); // error: non-static member \tcode{a} used as default argument + int mem2(int i = b); // OK, use \tcode{X::b} + consteval void mem3(std::meta::info r = ^^a) {} // OK + int mem4(int i = [:^^a:]); // error: non-static member \tcode{a} designated in default argument static int b; }; \end{codeblock} @@ -4413,10 +4611,13 @@ int (*p2)() = &f; // error: type mismatch \end{codeblock} \end{example} +\begin{note} When an overload set contains a declaration of a function -that inhabits a scope $S$, -any default argument associated with any reachable declaration that inhabits $S$ -is available to the call. +whose host scope is $S$, +any default argument associated with any reachable declaration +whose host scope is $S$ +is available to the call\iref{over.match.viable}. +\end{note} \begin{note} The candidate might have been found through a \grammarterm{using-declarator} from which the declaration that provides the default argument is not reachable. @@ -4449,6 +4650,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 + \keyword{pre} \opt{attribute-specifier-seq} \terminal{(} conditional-expression \terminal{)} +\end{bnf} + +\begin{bnf} +\nontermdef{postcondition-specifier}\br + \keyword{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\ifndrdef{dcl.contract.func.mismatched.contract.specifiers}. + +\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{f}, 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; }()); // ill-formed, no diagnostic required: 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 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}% @@ -4493,9 +5014,15 @@ \end{bnf} \begin{bnf} -\nontermdef{designated-initializer-list}\br +\nontermdef{designated-only-initializer-list}\br designated-initializer-clause\br - designated-initializer-list \terminal{,} designated-initializer-clause + designated-only-initializer-list \terminal{,} designated-initializer-clause +\end{bnf} + +\begin{bnf} +\nontermdef{designated-initializer-list}\br + designated-only-initializer-list\br + initializer-list \terminal{,} designated-only-initializer-list \end{bnf} \begin{bnf} @@ -4546,29 +5073,20 @@ and~\ref{stmt.dcl}. \end{note} -\pnum -A declaration $D$ of a variable with linkage -shall not have an \grammarterm{initializer} -if $D$ inhabits a block scope. - \pnum \indextext{initialization!default}% \indextext{variable!indeterminate uninitialized}% \indextext{initialization!zero-initialization}% -To -\defnx{zero-initialize}{zero-initialization} -an object or reference of type -\tcode{T} -means: +To \defnx{zero-initialize}{zero-initialization} +an object or reference of type \tcode{T} means: \begin{itemize} \item -if -\tcode{T} -is a scalar type\iref{term.scalar.type}, the -object -is initialized to the value obtained by converting the integer literal \tcode{0} -(zero) to -\tcode{T}; +if \tcode{T} is \tcode{std::meta::info}, +the object is initialized to a null reflection value; +\item +if \tcode{T} is any other scalar type\iref{term.scalar.type}, +the object is initialized to the value +obtained by converting the integer literal \tcode{0} (zero) to \tcode{T}; \begin{footnote} As specified in~\ref{conv.ptr}, converting an integer literal whose value is @@ -4634,36 +5152,47 @@ shall be met and each element is default-initialized. +\item +If \tcode{T} is \tcode{std::meta::info}, the object is zero-initialized. + \item Otherwise, no initialization is performed. \end{itemize} \pnum -A class type \tcode{T} is \defn{const-default-constructible} if +A type \cv{}~\tcode{T} is \defn{const-default-constructible} if +\begin{itemize} +\item +\tcode{T} is \tcode{std::meta::info}; +\item +\tcode{T} is \tcode{std::nullptr_t}; +\item default-initialization of \tcode{T} would invoke -a user-provided constructor of \tcode{T} (not inherited from a base class) -or if +a user-provided constructor of \tcode{T} (not inherited from a base class); +\item +\tcode{T} is a class type where \begin{itemize} \item -each direct non-variant non-static data member \tcode{M} of \tcode{T} -has a default member initializer -or, if \tcode{M} is of class type \tcode{X} (or array thereof), -\tcode{X} is const-default-constructible, +each direct non-variant non-static data member of \tcode{T} +has a default member initializer or +is of const-default-constructible type, \item if \tcode{T} is a union with at least one non-static data member, exactly one variant member has a default member initializer, \item if \tcode{T} is not a union, -for each anonymous union member with at least one non-static data member (if any), -exactly one non-static data member has a default member initializer, and +the type of each anonymous union member is const-default-constructible, and +\item +each potentially constructed base class of \tcode{T} is const-default-constructible; or +\end{itemize} \item -each potentially constructed base class of \tcode{T} is const-default-constructible. +\tcode{T} is an array of const-default-constructible type. \end{itemize} If a program calls for the default-initialization of an object of a const-qualified type \tcode{T}, -\tcode{T} shall be a const-default-constructible class type or array thereof. +\tcode{T} shall be a const-default-constructible type. \pnum To @@ -4702,7 +5231,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. @@ -4821,7 +5350,7 @@ 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}. +\tcode{T x = T(T(T()));} value-initializes \tcode{x}\iref{basic.lval,expr.type.conv}. \end{example} \item Otherwise, if the initialization is direct-initialization, @@ -4951,7 +5480,7 @@ \end{itemize} \pnum -An immediate invocation\iref{expr.const} that is not evaluated where +An immediate invocation\iref{expr.const.imm} that is not evaluated where it appears\iref{dcl.fct.default,class.mem.general} is evaluated and checked for whether it is a constant expression at the point where @@ -4971,7 +5500,8 @@ function arguments or return values\iref{class.temporary}. \pnum -If the initializer is a parenthesized \grammarterm{expression-list}, +If the destination type is not an aggregate +and the initializer is a parenthesized \grammarterm{expression-list}, the expressions are evaluated in the order specified for function calls\iref{expr.call}. @@ -4981,8 +5511,13 @@ \grammarterm{designated-initializer-list}. \pnum -An object whose initialization has completed -is deemed to be constructed, +The \defnadj{deemed}{construction} of an object occurs when +its initialization completes; +for the purposes of~\ref{basic.start.term}, +if the initialization is a full-expression, +deemed construction occurs when +the evaluation of that full-expression completes. +The object is deemed to be constructed, even if the object is of non-class type or no constructor of the object's class is invoked for the initialization. @@ -5032,7 +5567,7 @@ \end{itemize} \begin{note} Aggregate initialization does not allow accessing -protected and private base class' members or constructors. +protected and private base class' members, including constructors. \end{note} \pnum @@ -5046,6 +5581,38 @@ that are not members of an anonymous union, in declaration order. \end{itemize} +\pnum +The \defnadj{associated}{element} of a member \tcode{M} +of an aggregate \tcode{T} is: +\begin{itemize} +\item \tcode{M} if \tcode{M} is an element of \tcode{T}; +\item otherwise, the element of \tcode{T} that contains \tcode{M}. +\end{itemize} +\begin{example} +\begin{codeblock} +struct A { + int a1; + union { + int a2; + char a3; + }; +}; + +struct B : A { + int b1; + union { + double b2; + }; +}; +\end{codeblock} +The associated element of each of +the members \tcode{A::a1}, \tcode{A::a2}, and \tcode{A::a3} +of \tcode{B} is \tcode{A}. +The associated element of the member \tcode{B::b1} of \tcode{B} is itself. +The associated element of the member \tcode{B::b2} of \tcode{B} is +the anonymous union containing it. +\end{example} + \pnum When an aggregate is initialized by an initializer list as specified in~\ref{dcl.init.list}, @@ -5057,32 +5624,74 @@ \item If the initializer list is a brace-enclosed \grammarterm{designated-initializer-list}, -the aggregate shall be of class type, -the \grammarterm{identifier} in each \grammarterm{designator} -shall name a direct non-static data member of the class, and -the explicitly initialized elements of the aggregate -are the elements that are, or contain, those members. +the aggregate shall be of class type \tcode{C}. +For each \grammarterm{designator} +within the \grammarterm{designated-only-initializer-list} +of the \grammarterm{designated-initializer-list}, +the lookup set for the \grammarterm{identifier} +in \tcode{C}\iref{class.member.lookup} shall comprise +\begin{itemize} +\item +a declaration set consisting of a single non-static data member and \item -If the initializer list is a brace-enclosed \grammarterm{initializer-list}, +a subobject set containing only one subobject, +whose type shall be an aggregate base of \tcode{C}. +An aggregate \tcode{B} is an \defnadj{aggregate}{base} of a class \tcode{D} +if it is \tcode{D} or a direct base class of an aggregate base of \tcode{D}. +\end{itemize} + +That non-static data member is \defnx{designated}{designate!aggregate element} +by the \grammarterm{identifier}. +Each \grammarterm{initializer-clause} of the \grammarterm{initializer-list}, +if any, +shall appertain (see below) to a (direct) base class subobject of \tcode{C}. +The explicitly initialized elements of the aggregate include +the associated elements of each member \tcode{M} of \tcode{C} +for which \tcode{M} is designated by an \grammarterm{identifier} +in a \grammarterm{designated-initializer-clause}. + +\item +If the \grammarterm{braced-init-list} has an \grammarterm{initializer-list} +(possibly within a \grammarterm{designated-initializer-list}) the explicitly initialized elements of the aggregate -are those for which an element of the initializer list +include those for which an element of the initializer list appertains to the aggregate element or to a subobject thereof (see below). \item -Otherwise, the initializer list must be \tcode{\{\}}, -and there are no explicitly initialized elements. +No other elements of the aggregate are explicitly initialized. +\begin{note} +The initializer \tcode{\{\}} does not explicitly initialize +any elements of the aggregate. +\end{note} \end{itemize} +If any element of the aggregate is explicitly initialized per +both an \grammarterm{initializer-list} and +a \grammarterm{designated-only-initializer-list}, +the program is ill-formed. +\begin{example} +\begin{codeblock} +struct A { int a1, a2; }; +struct B : A { int b; }; +struct C : A { int a1; }; + +A v0 = A{1, .a2=2}; // error: \grammarterm{initializer-clause} appertains to non-static data member +B v1 = B{.a1=1, .b=2}; // the explicitly initialized elements are \textnormal{[}\tcode{A}, \tcode{B::b}\textnormal{]} +B v2 = B{.a1=1, .a2=2, .b=3}; // the explicitly initialized elements are \textnormal{[}\tcode{A}, \tcode{B::b}\textnormal{]} +B v3 = B{A{1, 2}, .b=3}; // the explicitly initialized elements are \textnormal{[}\tcode{A}, \tcode{B::b}\textnormal{]} +B v4 = B{A{}, .a2=1, .b=3}; // error: \tcode{A} initialized two different ways +C v5 = C{.a1=4}; // the explicitly initialized elements are \textnormal{[}\tcode{C::a1}\textnormal{]} +\end{codeblock} +\end{example} \pnum For each explicitly initialized element: \begin{itemize} \item If the element is an anonymous union member and -the initializer list is -a brace-enclosed \grammarterm{designated-initializer-list}, +is explicitly initialized per a \grammarterm{designated-only-initializer-list}, the element is initialized by the \grammarterm{braced-init-list} \tcode{\{ }\placeholder{D}\tcode{ \}}, where \placeholder{D} is the \grammarterm{designated-initializer-clause} -naming a member of the anonymous union member. +whose associated element is the anonymous union member. There shall be only one such \grammarterm{designated-initializer-clause}. \begin{example} \begin{codeblock} @@ -5097,8 +5706,11 @@ initializes \tcode{c.a} with 1 and \tcode{c.x} with 3. \end{example} \item -Otherwise, if the initializer list is -a brace-enclosed \grammarterm{designated-initializer-list}, +Otherwise, if the element is explicitly initialized +per a \grammarterm{designated-only-initializer-list}, then: +\begin{itemize} +\item +If the element is a (direct) non-static data member, then the element is initialized with the \grammarterm{brace-or-equal-initializer} of the corresponding \grammarterm{designated-initializer-clause}. If that initializer is of the form @@ -5111,8 +5723,29 @@ whether copy-initialization or direct-initialization is performed. \end{note} \item +Otherwise, the element is a base class subobject $B$, and +is copy-initialized from +a brace-enclosed \grammarterm{designated-initializer-list} +consisting of all of the \grammarterm{designated-initializer-clause}s +whose associated element is $B$, in order. +\end{itemize} +\begin{example} +\begin{codeblock} +struct A { int a; }; +struct B : A { int b; }; +struct C : B { int c; }; + +// the \tcode{A} element is initialized from \tcode{\{.a=1\}} +B x = B{.a=1}; + +// the \tcode{B} element is initialized from \tcode{\{.a=2, .b=3\}} +// which leads to its \tcode{A} element being initialized from \tcode{\{.a=2\}} +C y = C{.a=2, .b=3, .c=4}; +\end{codeblock} +\end{example} +\item Otherwise, -the initializer list is a brace-enclosed \grammarterm{initializer-list}. +element is explicitly initialized per an \grammarterm{initializer-list}. If an \grammarterm{initializer-clause} appertains to the aggregate element, then the aggregate element is copy-initialized from the \grammarterm{initializer-clause}. Otherwise, @@ -5378,8 +6011,7 @@ \end{example} \pnum -Each \grammarterm{initializer-clause} in -a brace-enclosed \grammarterm{initializer-list} +Each \grammarterm{initializer-clause} in a \grammarterm{braced-init-list} is said to \defn{appertain} to an element of the aggregate being initialized or to an element of one of its subaggregates. @@ -5684,7 +6316,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} @@ -5789,7 +6421,11 @@ \item Otherwise, if the initializer expression \begin{itemize} -\item is an rvalue (but not a bit-field) or an lvalue of function type and +\item is either +\begin{itemize} +\item an rvalue (but not a bit-field), or +\item an lvalue of function type, and +\end{itemize} ``\cvqual{cv1} \tcode{T1}'' is reference-compatible with ``\cvqual{cv2} \tcode{T2}'', or @@ -5836,8 +6472,8 @@ } 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} +typedef int *AP[3]; // array of 3 pointer to \tcode{int} +typedef const int *const ACPC[3]; // array of 3 const pointer to \tcode{const int} ACPC &&r = AP{}; // binds directly \end{codeblock} \end{example} @@ -5852,9 +6488,10 @@ ``\cvqual{cv1} \tcode{T1}'' by user-defined conversion\iref{dcl.init,over.match.copy,over.match.conv}; the program is ill-formed if the corresponding non-reference -copy-initialization would be ill-formed. The result of the call to the +copy-initialization would be ill-formed. The result $E$ of the call to the conversion function, as described for the non-reference -copy-initialization, is then used to direct-initialize the reference. +copy-initialization, is then used to direct-initialize the reference +using the form \tcode{($E$)}. For this direct-initialization, user-defined conversions are not considered. \item Otherwise, @@ -5939,7 +6576,7 @@ \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.ass}. +\item on the right-hand side of an assignment\iref{expr.assign}. \end{itemize} \begin{example} @@ -5984,18 +6621,31 @@ contains a \grammarterm{designated-initializer-list} and \tcode{T} is not a reference type, \tcode{T} shall be an aggregate class. -The ordered \grammarterm{identifier}{s} +The associated elements of the non-static data members +designated by the ordered \grammarterm{identifier}{s} in the \grammarterm{designator}{s} of the \grammarterm{designated-initializer-list} -shall form a subsequence -of the ordered \grammarterm{identifier}{s} -in the direct non-static data members of \tcode{T}. +shall be in non-decreasing element order. Aggregate initialization is performed\iref{dcl.init.aggr}. \begin{example} \begin{codeblock} struct A { int x; int y; int z; }; A a{.y = 2, .x = 1}; // error: designator order does not match declaration order A b{.x = 1, .z = 2}; // OK, \tcode{b.y} initialized to \tcode{0} + +struct B : A { int q; }; +B e{.x = 1, .q = 3}; // OK, \tcode{e.y} and \tcode{e.z} initialized to \tcode{0} +B f{.q = 3, .x = 1}; // error: designator order does not match declaration order + +struct C { int p; int x; }; +struct D : A, C { }; +D g{.y=1, .p=2}; // OK +D h{.x=2}; // error: ambiguous lookup for \tcode{x} + +struct NonAggr { int na; NonAggr(int); }; +struct E : NonAggr { int e; }; +E i{.na=1, .e=2}; // error: the lookup set for \tcode{na} finds \tcode{NonAggr}, + // which is not an aggregate base of \tcode{E} \end{codeblock} \end{example} @@ -6203,6 +6853,11 @@ given \grammarterm{initializer-clause} is sequenced before every value computation and side effect associated with any \grammarterm{initializer-clause} that follows it in the comma-separated list of the \grammarterm{initializer-list}. +If the \grammarterm{initializer-clause}{s} of +the \grammarterm{initializer-list} +are interpreted as arguments of a constructor call\iref{over.match.list}, +any default arguments used are evaluated in the order as if +an \grammarterm{initializer-clause} were present for the corresponding parameter. \begin{note} This evaluation ordering holds regardless of the semantics of the initialization; for example, it applies when the elements of the @@ -6210,6 +6865,22 @@ call, even though ordinarily there are no sequencing constraints on the arguments of a call. \end{note} +\begin{example} +\begin{codeblock} +#include +struct I { + I(int x) { std::cout << x; } +}; +struct S { + S(I, I = 2) {} +}; +int main() { + S(1, 2); std::cout << '\n'; // unspecified order; prints \tcode{12} or \tcode{21} + S{1, 2}; std::cout << '\n'; // prints \tcode{12} + S{1}; // prints \tcode{12} +} +\end{codeblock} +\end{example} \pnum An object of type \tcode{std::initializer_list} is constructed from @@ -6378,8 +7049,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} @@ -6517,47 +7190,47 @@ is called an \defnx{explicitly-defaulted}{definition!function!explicitly-defaulted} definition. A function that is explicitly defaulted shall \begin{itemize} -\item be a special member function\iref{special} or -a comparison operator function\iref{over.binary, class.compare.default}, and +\item be a special member function\iref{special}, +comparison operator function\iref{over.binary, class.compare.default}, or +postfix increment or decrement operator function\iref{over.inc.default}, +and \item not have default arguments\iref{dcl.fct.default}. \end{itemize} \pnum -An explicitly defaulted special member function $\tcode{F}_1$ -is allowed to differ from -the corresponding special member function $\tcode{F}_2$ -that would have been implicitly declared, as follows: +The program is ill-formed +if an explicitly defaulted special member function $\tcode{F}_1$ +of class \tcode{C} +differs from the corresponding special member function $\tcode{F}_2$ +that would have been implicitly declared +other than as follows: \begin{itemize} \item - $\tcode{F}_1$ and $\tcode{F}_2$ may have differing \grammarterm{ref-qualifier}{s}; + if $\tcode{F}_1$ is an assignment operator, + it may have the \tcode{\&} \grammarterm{ref-qualifier}; \item - if $\tcode{F}_2$ has an implicit object parameter of - type ``reference to \tcode{C}'', - $\tcode{F}_1$ may be an explicit object member function whose - explicit object parameter is of (possibly different) type ``reference to \tcode{C}'', + if $\tcode{F}_2$ is an assignment operator + (which has an implicit object parameter + of type ``lvalue reference to \tcode{C}''), + $\tcode{F}_1$ may have an explicit object parameter + of type ``lvalue reference to \tcode{C}'', in which case the type of $\tcode{F}_1$ would differ from the type of $\tcode{F}_2$ in that the type of $\tcode{F}_1$ has an additional parameter; \item - $\tcode{F}_1$ and $\tcode{F}_2$ may have differing exception specifications; and -\item - if $\tcode{F}_2$ has a non-object parameter of type \tcode{const C\&}, - the corresponding non-object parameter of $\tcode{F}_1$ may be of - type \tcode{C\&}. -\end{itemize} -If the type of $\tcode{F}_1$ differs from the type of $\tcode{F}_2$ in a way -other than as allowed by the preceding rules, then: -\begin{itemize} + $\tcode{F}_1$ and $\tcode{F}_2$ may have differing exception specifications; \item - if $\tcode{F}_1$ is an assignment operator, and - the return type of $\tcode{F}_1$ differs from - the return type of $\tcode{F}_2$ or - $\tcode{F}_1${'s} non-object parameter type is not a reference, - the program is ill-formed; + if $\tcode{F}_2$ has a non-object parameter + of type ``lvalue reference to \tcode{const C}'', + the corresponding non-object parameter of $\tcode{F}_1$ may be + of type ``lvalue reference to \tcode{C}''; and \item - otherwise, if $\tcode{F}_1$ is explicitly defaulted on its first declaration, - it is defined as deleted; -\item - otherwise, the program is ill-formed. + if $\tcode{F}_2$ has a non-object parameter + of type ``lvalue reference to \tcode{C}'', + the corresponding non-object parameter of $\tcode{F}_1$ may be + of type ``lvalue reference to \tcode{const C}''; + in this case only, $\tcode{F}_1$ is defined as deleted + if it is explicitly defaulted on its first declaration and + the program is ill-formed otherwise. \end{itemize} \pnum @@ -6622,7 +7295,7 @@ A non-user-provided defaulted function (i.e., implicitly declared or explicitly defaulted in the class) that is not defined as deleted is implicitly defined when it is odr-used\iref{basic.def.odr} -or needed for constant evaluation\iref{expr.const}. +or needed for constant evaluation\iref{expr.const.defns}. \begin{note} The implicit definition of a non-user-provided defaulted function does not bind any names. @@ -6660,8 +7333,10 @@ deleted definition or a function that is implicitly defined as deleted. \pnum -A program that refers to a deleted function implicitly or explicitly, other -than to declare it, is ill-formed. +A construct that designates a deleted function implicitly or explicitly, +other than to declare it or to appear as the operand of +a \grammarterm{reflect-expression}\iref{expr.reflect}, +is ill-formed. \recommended The resulting diagnostic message should include @@ -6672,7 +7347,7 @@ This includes calling the function implicitly or explicitly and forming a pointer or pointer-to-member to the function. It applies even for references in expressions that are not -potentially-evaluated. For an overload set, only the +potentially evaluated. For an overload set, only the function selected by overload resolution is referenced. The implicit odr-use\iref{term.odr.use} of a virtual function does not, by itself, constitute a reference. @@ -6809,7 +7484,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 @@ -6875,14 +7556,10 @@ \end{itemize} \pnum -If searches for the names \tcode{return_void} and \tcode{return_value} -in the scope of the promise type each find any declarations, -the program is ill-formed. \begin{note} -If \tcode{return_void} is found, flowing off -the end of a coroutine is equivalent to a \keyword{co_return} with no operand. -Otherwise, flowing off the end of a coroutine -results in undefined behavior\iref{stmt.return.coroutine}. +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 @@ -6902,12 +7579,13 @@ The evaluation that invoked a resumption member function is called the \defnx{resumer}{coroutine!resumer}. Invoking a resumption member function for a coroutine -that is not suspended results in undefined behavior. +that is not suspended results in undefined behavior\ubdef{dcl.fct.def.coroutine.resume.not.suspended}. \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 @@ -6915,7 +7593,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 @@ -6993,7 +7673,7 @@ The storage for the coroutine state is released by calling a non-array deallocation function\iref{basic.stc.dynamic.deallocation}. If \tcode{destroy} is called for a coroutine that is not suspended, the -program has undefined behavior. +program has undefined behavior\ubdef{dcl.fct.def.coroutine.destroy.not.suspended}. \pnum The deallocation function's name is looked up by searching for it in the scope of the promise type. @@ -7011,16 +7691,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 @@ -7044,6 +7737,49 @@ 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} + +\indextext{function!replaceable|(}% +\indextext{replaceable!function|see{function, replaceable}}% + +\pnum +\label{term.replaceable.function}% +Certain functions +for which a definition is supplied by the implementation +are \defnx{replaceable}{function!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\ifndrdef{dcl.fct.def.replace.bad.replacement}. +\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} +\indextext{function!replaceable|)}% + \rSec1[dcl.struct.bind]{Structured binding declarations}% \indextext{structured binding declaration}% \indextext{declaration!structured binding|see{structured binding declaration}}% @@ -7105,7 +7841,7 @@ 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}. +the number of non-pack elements in the \grammarterm{sb-identifier-list}. \pnum Let $\textrm{SB}_i$ denote @@ -7140,7 +7876,8 @@ the program is ill-formed. \pnum -If \tcode{E} is an array type with element type \tcode{T}, +\tcode{E} shall not be an array type of unknown bound. +If \tcode{E} is any other 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 @@ -7176,16 +7913,15 @@ names a complete class type with a member named \tcode{value}, the expression \tcode{std::tuple_size::value} shall be a well-formed integral constant expression -and -the structured binding size of \tcode{E} is equal to the value of that -expression. +whose value is non-negative; +the structured binding size of \tcode{E} is equal to that value. Let \tcode{i} be an index prvalue of type \tcode{std::size_t} -corresponding to $\tcode{v}_i$. +corresponding to $\textrm{SB}_i$. If a search for the name \tcode{get} 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}. @@ -7197,10 +7933,10 @@ is an lvalue reference and an xvalue otherwise. Given the type $\tcode{T}_i$ designated by \tcode{std::tuple_element::type} and -the type $\tcode{U}_i$ designated by -either \tcode{$\tcode{T}_i$\&} or \tcode{$\tcode{T}_i$\&\&}, -where $\tcode{U}_i$ is an lvalue reference if -the initializer is an lvalue and an rvalue reference otherwise, +the type $\tcode{U}_i$ defined +as $\tcode{T}_i$ if the initializer is a prvalue, +as ``lvalue reference to $\tcode{T}_i$'' if the initializer is an lvalue, or +as ``rvalue reference to $\tcode{T}_i$'' otherwise, variables are introduced with unique names $\tcode{r}_i$ as follows: \begin{ncbnf} @@ -7425,7 +8161,7 @@ type and the \grammarterm{constant-expression} in the \grammarterm{enumerator-definition} shall be a converted constant expression of the underlying -type\iref{expr.const}. +type\iref{expr.const.const}. If the underlying type is not fixed, the type of each enumerator prior to the closing brace is determined as @@ -7435,7 +8171,7 @@ \item If an initializer is specified for an enumerator, the \grammarterm{constant-expression} shall be an integral constant -expression\iref{expr.const}. If the expression has +expression\iref{expr.const.const}. If the expression has unscoped enumeration type, the enumerator has the underlying type of that enumeration type, otherwise it has the same type as the expression. @@ -7503,7 +8239,8 @@ \pnum Two enumeration types are \defnx{layout-compatible enumerations}{layout-compatible!enumeration} -if they have the same underlying type. +if they have the same underlying type +and the same values. \pnum The value of an enumerator or an object of an unscoped enumeration type is @@ -7582,11 +8319,15 @@ \begin{bnf} \nontermdef{using-enum-declarator}\br \opt{nested-name-specifier} identifier\br - \opt{nested-name-specifier} simple-template-id + \opt{nested-name-specifier} simple-template-id\br + splice-type-specifier \end{bnf} \pnum -A \grammarterm{using-enum-declarator} +A \grammarterm{using-enum-declarator} of +the form \grammarterm{splice-type-specifier} +designates the same type designated by the \grammarterm{splice-type-specifier}. +Any other \grammarterm{using-enum-declarator} names the set of declarations found by type-only lookup\iref{basic.lookup.general} for the \grammarterm{using-enum-declarator}\iref{basic.lookup.unqual,basic.lookup.qual}. @@ -7850,7 +8591,7 @@ \grammarterm{unnamed-namespace-definition} and all occurrences of \exposid{unique} in a translation unit are replaced by the same identifier, and this identifier differs from all other -identifiers in the translation unit. +identifiers in the program. The optional \grammarterm{attribute-specifier-seq} in the \grammarterm{unnamed-namespace-definition} appertains to \exposid{unique}. @@ -7882,8 +8623,8 @@ \indextext{synonym} \pnum -A \grammarterm{namespace-alias-definition} declares an alternate name for a -namespace according to the following grammar: +A \grammarterm{namespace-alias-definition} declares a \defnadj{namespace}{alias} +according to the following grammar: \begin{bnf} \nontermdef{namespace-alias}\br @@ -7892,7 +8633,8 @@ \begin{bnf} \nontermdef{namespace-alias-definition}\br - \keyword{namespace} identifier \terminal{=} qualified-namespace-specifier \terminal{;} + \keyword{namespace} identifier \terminal{=} qualified-namespace-specifier \terminal{;}\br + \keyword{namespace} identifier \terminal{=} splice-specifier \terminal{;} \end{bnf} \begin{bnf} @@ -7900,10 +8642,19 @@ \opt{nested-name-specifier} namespace-name \end{bnf} +\pnum +The \grammarterm{splice-specifier} (if any) +shall designate a namespace that is not the global namespace. + \pnum The \grammarterm{identifier} in a \grammarterm{namespace-alias-definition} -becomes a \grammarterm{namespace-alias} and denotes the namespace denoted by the -\grammarterm{qualified-namespace-specifier}. +becomes a \grammarterm{namespace-alias}. + +\pnum +The underlying entity\iref{basic.pre} of the namespace alias is +the namespace either +denoted by the \grammarterm{qualified-namespace-specifier} or +designated by the \grammarterm{splice-specifier}. \begin{note} When looking up a \grammarterm{namespace-name} in a \grammarterm{namespace-alias-definition}, only namespace names are @@ -7915,9 +8666,18 @@ \begin{bnf} \nontermdef{using-directive}\br - \opt{attribute-specifier-seq} \keyword{using} \keyword{namespace} \opt{nested-name-specifier} namespace-name \terminal{;} + \opt{attribute-specifier-seq} \keyword{using} \keyword{namespace} \opt{nested-name-specifier} namespace-name \terminal{;}\br + \opt{attribute-specifier-seq} \keyword{using} \keyword{namespace} splice-specifier \terminal{;} \end{bnf} +\pnum +The \grammarterm{splice-specifier} (if any) shall designate a namespace +that is not the global namespace. +The \grammarterm{nested-name-specifier}, +\grammarterm{namespace-name}, and +\grammarterm{splice-specifier} +shall not be dependent. + \pnum A \grammarterm{using-directive} shall not appear in class scope, but may appear in namespace scope or in block scope. @@ -7930,13 +8690,13 @@ \pnum \begin{note} -A \grammarterm{using-directive} makes the names in the nominated +A \grammarterm{using-directive} makes the names in the designated namespace usable in the scope in which the \grammarterm{using-directive} appears after the \grammarterm{using-directive}\iref{basic.lookup.unqual,namespace.qual}. During unqualified name lookup, the names appear as if they were declared in the nearest enclosing namespace which -contains both the \grammarterm{using-directive} and the nominated +contains both the \grammarterm{using-directive} and the designated namespace. \end{note} @@ -7977,8 +8737,8 @@ \pnum \begin{note} A \grammarterm{using-directive} is transitive: if a scope contains a -\grammarterm{using-directive} that nominates a namespace that itself -contains \grammarterm{using-directive}{s}, the namespaces nominated by those +\grammarterm{using-directive} that designates a namespace that itself +contains \grammarterm{using-directive}{s}, the namespaces designated by those \grammarterm{using-directive}{s} are also eligible to be considered. \end{note} \begin{example} @@ -8236,14 +8996,14 @@ \grammarterm{using-declaration} cannot refer to a destructor for a base class. \end{note} -If a constructor or assignment operator brought from a base class into a derived class -has the signature of a copy/move constructor or assignment operator -for the derived class\iref{class.copy.ctor,class.copy.assign}, -the \grammarterm{using-declaration} does not by itself -suppress the implicit declaration of the derived class member; -the member from the base class is hidden or overridden -by the implicitly-declared copy/move constructor or assignment operator -of the derived class, as described below. +\begin{note} +A \grammarterm{using-declarator} that +names a member function of a base class +does not suppress the implicit declaration of a special member function +in the derived class, +even if their signatures are the +same\iref{class.default.ctor, class.copy.ctor, class.copy.assign}. +\end{note} \pnum A \grammarterm{using-declaration} shall not name a \grammarterm{template-id}. @@ -8406,9 +9166,9 @@ \indextext{name hiding!using-declaration and}% The set of declarations named by a \grammarterm{using-declarator} that inhabits a class \tcode{C} does not include -member functions and member function templates of a base class -that correspond to (and thus would conflict with) -a declaration of a function or function template in \tcode{C}. +member functions and member function templates of a base class that, +when considered as members of \tcode{C}, +correspond to a declaration of a function or function template in \tcode{C}. \begin{example} \begin{codeblock} struct B { @@ -8416,6 +9176,8 @@ virtual void f(char); void g(int); void h(int); + void i(); + void j(); }; struct D : B { @@ -8427,6 +9189,12 @@ using B::h; void h(int); // OK, \tcode{D::h(int)} hides \tcode{B::h(int)} + + using B::i; + void i(this B &); // OK + + using B::j; + void j(this D &); // OK, \tcode{D::j()} hides \tcode{B::j()} }; void k(D* p) @@ -8435,6 +9203,8 @@ p->f('a'); // calls \tcode{B::f(char)} p->g(1); // calls \tcode{B::g(int)} p->g('a'); // calls \tcode{D::g(char)} + p->i(); // calls \tcode{B::i}, because \tcode{B::i} as a member of \tcode{D} is a better match than \tcode{D::i} + p->j(); // calls \tcode{D::j} } struct B1 { @@ -8722,7 +9492,7 @@ \pnum If two declarations of an entity give it different language linkages, the program is ill-formed; no diagnostic is required if neither declaration -is reachable from the other. +is reachable from the other\ifndrdef{dcl.link.mismatched.language.linkage}. \indextext{consistency!linkage specification}% A redeclaration of an entity without a linkage specification inherits the language linkage of the entity and (if applicable) its type. @@ -8799,8 +9569,8 @@ \pnum \indextext{attribute!syntax and semantics}% -Attributes specify additional information for various source constructs -such as types, variables, names, blocks, or translation units. +Attributes and annotations specify additional information for various source constructs +such as types, variables, names, contract assertions, blocks, or translation units. \begin{bnf} \nontermdef{attribute-specifier-seq}\br @@ -8810,12 +9580,13 @@ \begin{bnf} \nontermdef{attribute-specifier}\br \terminal{[} \terminal{[} \opt{attribute-using-prefix} attribute-list \terminal{]} \terminal{]}\br + \terminal{[} \terminal{[} annotation-list \terminal{]} \terminal{]}\br alignment-specifier \end{bnf} \begin{bnf} \nontermdef{alignment-specifier}\br - \keyword{alignas} \terminal{(} type-id \opt{\terminal{...}} \terminal{)}\br + \keyword{alignas} \terminal{(} nofun-type-id \opt{\terminal{...}} \terminal{)}\br \keyword{alignas} \terminal{(} constant-expression \opt{\terminal{...}} \terminal{)} \end{bnf} @@ -8832,11 +9603,22 @@ attribute-list \terminal{,} attribute \terminal{...} \end{bnf} +\begin{bnf} +\nontermdef{annotation-list}\br + annotation \opt{\terminal{...}}\br + annotation-list \terminal{,} annotation \opt{\terminal{...}} +\end{bnf} + \begin{bnf} \nontermdef{attribute}\br attribute-token \opt{attribute-argument-clause} \end{bnf} +\begin{bnf} +\nontermdef{annotation}\br + \terminal{=} constant-expression +\end{bnf} + \begin{bnf} \nontermdef{attribute-token}\br identifier\br @@ -8864,12 +9646,13 @@ \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 \terminal{\{} \opt{balanced-token-seq} \terminal{\}}\br - \textnormal{any \grammarterm{token} other than a parenthesis, a bracket, or a brace} + \terminal{[:} \opt{balanced-token-seq} \terminal{:]}\br + \textnormal{any \grammarterm{token} other than \terminal{(}, \terminal{)}, \terminal{[}, \terminal{]}, \terminal{\{}, \terminal{\}}, \terminal{[:}, or \terminal{:]}} \end{bnf} \pnum @@ -8908,8 +9691,10 @@ In an \grammarterm{attribute-list}, an ellipsis may appear only if that \grammarterm{attribute}'s specification permits it. An \grammarterm{attribute} followed by an ellipsis is a pack expansion\iref{temp.variadic}. -An \grammarterm{attribute-specifier} that contains no \grammarterm{attribute}{s} has no -effect. The order in which the \grammarterm{attribute-token}{s} appear in an +An \grammarterm{attribute-specifier} that contains +an \grammarterm{attribute-list} with no \grammarterm{attribute}s +has no effect. +The order in which the \grammarterm{attribute-token}{s} appear in an \grammarterm{attribute-list} is not significant. If a keyword\iref{lex.key} or an alternative token\iref{lex.digraph} that satisfies the syntactic requirements @@ -8920,10 +9705,21 @@ \grammarterm{attribute-token}. The \grammarterm{attribute-token} determines additional requirements on the \grammarterm{attribute-argument-clause} (if any). +\pnum +\begin{note} +Unless otherwise specified, +an \grammarterm{attribute-token} specified in this document cannot be used +as a macro name\iref{cpp.replace.general}. +\end{note} + +\pnum +An \grammarterm{annotation} followed by an ellipsis +is a pack expansion\iref{temp.variadic}. + \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 @@ -9022,8 +9818,8 @@ \pnum An \grammarterm{alignment-specifier} of the form -\tcode{alignas(} \grammarterm{type-id} \tcode{)} has the same -effect as \tcode{alignas(\brk{}alignof(} \grammarterm{type-id}~\tcode{))}\iref{expr.alignof}. +\tcode{alignas(} \grammarterm{nofun-type-id} \tcode{)} has the same +effect as \tcode{alignas(alignof(} \grammarterm{nofun-type-id}~\tcode{))}\iref{expr.alignof}. \pnum The alignment requirement of an entity is the strictest nonzero alignment @@ -9054,7 +9850,7 @@ \grammarterm{alignment-specifier}{}, every defining declaration of that entity shall specify an equivalent alignment. -No diagnostic is required if declarations of an entity have +No diagnostic is required\ifndrdef{dcl.align.diff.translation.units} if declarations of an entity have different \grammarterm{alignment-specifier}{s} in different translation units. \begin{example} @@ -9108,7 +9904,7 @@ at the point where the assumption appears, the assumption has no effect. Otherwise, -evaluation of the assumption has runtime-undefined behavior. +evaluation of the assumption has runtime-undefined behavior\ubdef{dcl.attr.assume.false}. \pnum \begin{note} @@ -9140,86 +9936,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} @@ -9244,7 +9960,7 @@ \pnum The attribute may be applied to the declaration of a class, -a \grammarterm{typedef-name}, +a type alias, a variable, a non-static data member, a function, @@ -9284,8 +10000,7 @@ \pnum The \grammarterm{attribute-token} \tcode{fallthrough} may be applied to a null statement\iref{stmt.expr}; -\indextext{statement!fallthrough} -such a statement is a fallthrough statement. +such a statement is a \defnadj{fallthrough}{statement}. No \grammarterm{attribute-argument-clause} shall be present. A fallthrough statement may only appear within an enclosing \keyword{switch} statement\iref{stmt.switch}. @@ -9296,6 +10011,9 @@ the next statement shall be part of the same execution of the substatement of the innermost enclosing iteration statement. The program is ill-formed if there is no such statement. +The innermost enclosing \tcode{switch} statement +of a fallthrough statement $S$ shall be contained in +the innermost enclosing expansion statement\iref{stmt.expand} of $S$, if any. \pnum \recommended @@ -9362,7 +10080,7 @@ in one translation unit and the same function is declared without the \tcode{indeterminate} attribute on the same parameter in its first declaration in another translation unit, -the program is ill-formed, no diagnostic required. +the program is ill-formed, no diagnostic required\ifndrdef{dcl.attr.indet.mismatched.declarations}. \pnum \begin{note} @@ -9462,9 +10180,10 @@ \pnum The attribute may be applied to the declaration of a class, -\grammarterm{typedef-name}, +type alias, variable (including a structured binding declaration), structured binding, +result binding\iref{dcl.contract.res}, non-static data member, function, enumeration, or @@ -9562,7 +10281,8 @@ \pnum \recommended Appearance of a nodiscard call as -a potentially-evaluated discarded-value expression\iref{expr.prop} +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 @@ -9616,12 +10336,12 @@ specify the \tcode{noreturn} attribute if any declaration of that function specifies the \tcode{noreturn} attribute. If a function is declared with the \tcode{noreturn} attribute in one translation unit and the same function is declared without the \tcode{noreturn} attribute in another -translation unit, the program is ill-formed, no diagnostic required. +translation unit, the program is ill-formed, no diagnostic required\ifndrdef{dcl.attr.noreturn.trans.unit.mismatch}. \pnum 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. +the behavior is runtime-undefined\ubdef{dcl.attr.noreturn.eventually.returns}. \begin{note} The function can terminate by throwing an exception. @@ -9694,3 +10414,96 @@ could have the same address as \tcode{buckets} if their respective types are all empty. \end{example} + +\rSec2[dcl.attr.annotation]{Annotations}% +\indextext{attribute!annotations} + +\pnum +An annotation may be applied +to a \grammarterm{base-specifier} or +to a declaration $D$ of a +type, +type alias, +variable, +function, +function parameter of non-\tcode{void} type, +namespace, +enumerator, or +non-static data member, +unless +\begin{itemize} +\item the host scope of $X$ differs from its target scope or +\item $X$ is a non-defining friend declaration, +\end{itemize} +where $X$ is +\begin{itemize} +\item +$D'$ if $D$ is a function parameter declaration in +a function declarator\iref{dcl.fct} of a function declaration $D'$ and +\item $D$ otherwise. +\end{itemize} +\begin{note} +An annotation on a \grammarterm{parameter-declaration} in a function definition +applies to both the function parameter and the variable. +\begin{example} +\begin{codeblock} +void f([[=1]] int x); +void f([[=2]] int y) { + constexpr auto rp = parameters_of(@\reflexpr{f}@)[0]; + constexpr auto ry = variable_of(rp); + static_assert(ry == ^^y); + + static_assert(annotations_of(rp).size() == 2); // both \tcode{[1, 2]} + static_assert(annotations_of(ry).size() == 1); // just \tcode{[2]} + static_assert(annotations_of(rp)[1] == annotations_of(ry)[0]); +} +\end{codeblock} +\end{example} +\end{note} + +\pnum +Let $E$ be the expression +\tcode{std::meta::reflect_constant(\grammarterm{constant-expression})}. +$E$ shall be a constant expression; +the result of $E$ is the \defnadj{underlying}{constant} of the annotation. + +\pnum +Each \grammarterm{annotation} or instantiation thereof +produces a unique annotation. +\begin{example} +\begin{codeblock} +[[=1]] void f(); +[[=2, =3, =2]] void g(); +void g [[=4, =2]] (); +\end{codeblock} +\tcode{f} has one annotation +and \tcode{g} has five annotations. +These can be queried with metafunctions +such as \tcode{std::\brk{}meta::\brk{}anno\-tations_of}\iref{meta.reflection.annotation}. +\end{example} +\begin{example} +\begin{codeblock} +template int x [[=1]]; +static_assert(annotations_of(^^x<0>) != annotations_of(^^x<1>)); // OK +\end{codeblock} +\end{example} + +\pnum +Substituting into an \grammarterm{annotation} +is not in the immediate context. +\begin{example} +\begin{codeblock} +template + [[=T::type()]] void f(T t); + +void f(int); + +void g() { + f(0); // OK + f('0'); // error, substituting into the annotation results in an invalid expression +} +\end{codeblock} +\end{example} + +\indextext{attribute|)}% +\indextext{declaration|)} diff --git a/source/diagnostics.tex b/source/diagnostics.tex index e421b207f4..cd913a8e7e 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -82,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} @@ -98,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} @@ -109,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} @@ -125,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} @@ -139,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} @@ -150,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} @@ -166,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} @@ -179,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} @@ -190,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} @@ -206,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} @@ -221,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} @@ -232,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} @@ -248,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} @@ -263,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} @@ -274,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} @@ -290,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} @@ -304,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} @@ -315,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} @@ -331,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} @@ -345,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} @@ -356,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} @@ -372,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} @@ -385,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} @@ -396,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} @@ -412,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} @@ -425,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} @@ -436,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} @@ -456,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} @@ -468,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: @@ -483,7 +482,7 @@ If the evaluation yields \tcode{true} there are no further effects. \item Otherwise, the \tcode{assert} macro's expression -creates a diagnostic on the standard error stream in an +creates a diagnostic on the standard error stream (\IsoC{}, 7.23.3) in an \impldef{format of diagnostic created by \tcode{assert} macro's expression} format and calls \tcode{abort()}. The diagnostic contains \tcode{\#}\mname{VA_ARGS} and @@ -496,8 +495,11 @@ \pnum If \mname{VA_ARGS} does not expand to -an \grammarterm{assignment-expression}, +a well-formed \grammarterm{assignment-expression}, the program is ill-formed. +If such an \grammarterm{assignment-expression} is ill-formed when +treated as an unevaluated operand\iref{expr.await, expr.yield}, +the program is ill-formed, no diagnostic required. \pnum The macro \tcode{assert} is redefined according to @@ -522,7 +524,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} @@ -530,158 +532,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 @@ -732,80 +659,80 @@ struct @\libglobal{is_error_condition_enum}@ : public false_type {}; enum class @\libglobal{errc}@ { // freestanding - address_family_not_supported, // \tcode{EAFNOSUPPORT} - address_in_use, // \tcode{EADDRINUSE} - address_not_available, // \tcode{EADDRNOTAVAIL} - already_connected, // \tcode{EISCONN} - argument_list_too_long, // \tcode{E2BIG} - argument_out_of_domain, // \tcode{EDOM} - bad_address, // \tcode{EFAULT} - bad_file_descriptor, // \tcode{EBADF} - bad_message, // \tcode{EBADMSG} - broken_pipe, // \tcode{EPIPE} - connection_aborted, // \tcode{ECONNABORTED} - connection_already_in_progress, // \tcode{EALREADY} - connection_refused, // \tcode{ECONNREFUSED} - connection_reset, // \tcode{ECONNRESET} - cross_device_link, // \tcode{EXDEV} - destination_address_required, // \tcode{EDESTADDRREQ} - device_or_resource_busy, // \tcode{EBUSY} - directory_not_empty, // \tcode{ENOTEMPTY} - executable_format_error, // \tcode{ENOEXEC} - file_exists, // \tcode{EEXIST} - file_too_large, // \tcode{EFBIG} - filename_too_long, // \tcode{ENAMETOOLONG} - function_not_supported, // \tcode{ENOSYS} - host_unreachable, // \tcode{EHOSTUNREACH} - identifier_removed, // \tcode{EIDRM} - illegal_byte_sequence, // \tcode{EILSEQ} - inappropriate_io_control_operation, // \tcode{ENOTTY} - interrupted, // \tcode{EINTR} - invalid_argument, // \tcode{EINVAL} - invalid_seek, // \tcode{ESPIPE} - io_error, // \tcode{EIO} - is_a_directory, // \tcode{EISDIR} - message_size, // \tcode{EMSGSIZE} - network_down, // \tcode{ENETDOWN} - network_reset, // \tcode{ENETRESET} - network_unreachable, // \tcode{ENETUNREACH} - no_buffer_space, // \tcode{ENOBUFS} - no_child_process, // \tcode{ECHILD} - no_link, // \tcode{ENOLINK} - no_lock_available, // \tcode{ENOLCK} - no_message, // \tcode{ENOMSG} - no_protocol_option, // \tcode{ENOPROTOOPT} - no_space_on_device, // \tcode{ENOSPC} - no_such_device_or_address, // \tcode{ENXIO} - no_such_device, // \tcode{ENODEV} - no_such_file_or_directory, // \tcode{ENOENT} - no_such_process, // \tcode{ESRCH} - not_a_directory, // \tcode{ENOTDIR} - not_a_socket, // \tcode{ENOTSOCK} - not_connected, // \tcode{ENOTCONN} - not_enough_memory, // \tcode{ENOMEM} - not_supported, // \tcode{ENOTSUP} - operation_canceled, // \tcode{ECANCELED} - operation_in_progress, // \tcode{EINPROGRESS} - operation_not_permitted, // \tcode{EPERM} - operation_not_supported, // \tcode{EOPNOTSUPP} - operation_would_block, // \tcode{EWOULDBLOCK} - owner_dead, // \tcode{EOWNERDEAD} - permission_denied, // \tcode{EACCES} - protocol_error, // \tcode{EPROTO} - protocol_not_supported, // \tcode{EPROTONOSUPPORT} - read_only_file_system, // \tcode{EROFS} - resource_deadlock_would_occur, // \tcode{EDEADLK} - resource_unavailable_try_again, // \tcode{EAGAIN} - result_out_of_range, // \tcode{ERANGE} - state_not_recoverable, // \tcode{ENOTRECOVERABLE} - text_file_busy, // \tcode{ETXTBSY} - timed_out, // \tcode{ETIMEDOUT} - too_many_files_open_in_system, // \tcode{ENFILE} - too_many_files_open, // \tcode{EMFILE} - too_many_links, // \tcode{EMLINK} - too_many_symbolic_link_levels, // \tcode{ELOOP} - value_too_large, // \tcode{EOVERFLOW} - wrong_protocol_type, // \tcode{EPROTOTYPE} + @\libmember{address_family_not_supported}{errc}@, // \tcode{EAFNOSUPPORT} + @\libmember{address_in_use}{errc}@, // \tcode{EADDRINUSE} + @\libmember{address_not_available}{errc}@, // \tcode{EADDRNOTAVAIL} + @\libmember{already_connected}{errc}@, // \tcode{EISCONN} + @\libmember{argument_list_too_long}{errc}@, // \tcode{E2BIG} + @\libmember{argument_out_of_domain}{errc}@, // \tcode{EDOM} + @\libmember{bad_address}{errc}@, // \tcode{EFAULT} + @\libmember{bad_file_descriptor}{errc}@, // \tcode{EBADF} + @\libmember{bad_message}{errc}@, // \tcode{EBADMSG} + @\libmember{broken_pipe}{errc}@, // \tcode{EPIPE} + @\libmember{connection_aborted}{errc}@, // \tcode{ECONNABORTED} + @\libmember{connection_already_in_progress}{errc}@, // \tcode{EALREADY} + @\libmember{connection_refused}{errc}@, // \tcode{ECONNREFUSED} + @\libmember{connection_reset}{errc}@, // \tcode{ECONNRESET} + @\libmember{cross_device_link}{errc}@, // \tcode{EXDEV} + @\libmember{destination_address_required}{errc}@, // \tcode{EDESTADDRREQ} + @\libmember{device_or_resource_busy}{errc}@, // \tcode{EBUSY} + @\libmember{directory_not_empty}{errc}@, // \tcode{ENOTEMPTY} + @\libmember{executable_format_error}{errc}@, // \tcode{ENOEXEC} + @\libmember{file_exists}{errc}@, // \tcode{EEXIST} + @\libmember{file_too_large}{errc}@, // \tcode{EFBIG} + @\libmember{filename_too_long}{errc}@, // \tcode{ENAMETOOLONG} + @\libmember{function_not_supported}{errc}@, // \tcode{ENOSYS} + @\libmember{host_unreachable}{errc}@, // \tcode{EHOSTUNREACH} + @\libmember{identifier_removed}{errc}@, // \tcode{EIDRM} + @\libmember{illegal_byte_sequence}{errc}@, // \tcode{EILSEQ} + @\libmember{inappropriate_io_control_operation}{errc}@, // \tcode{ENOTTY} + @\libmember{interrupted}{errc}@, // \tcode{EINTR} + @\libmember{invalid_argument}{errc}@, // \tcode{EINVAL} + @\libmember{invalid_seek}{errc}@, // \tcode{ESPIPE} + @\libmember{io_error}{errc}@, // \tcode{EIO} + @\libmember{is_a_directory}{errc}@, // \tcode{EISDIR} + @\libmember{message_size}{errc}@, // \tcode{EMSGSIZE} + @\libmember{network_down}{errc}@, // \tcode{ENETDOWN} + @\libmember{network_reset}{errc}@, // \tcode{ENETRESET} + @\libmember{network_unreachable}{errc}@, // \tcode{ENETUNREACH} + @\libmember{no_buffer_space}{errc}@, // \tcode{ENOBUFS} + @\libmember{no_child_process}{errc}@, // \tcode{ECHILD} + @\libmember{no_link}{errc}@, // \tcode{ENOLINK} + @\libmember{no_lock_available}{errc}@, // \tcode{ENOLCK} + @\libmember{no_message}{errc}@, // \tcode{ENOMSG} + @\libmember{no_protocol_option}{errc}@, // \tcode{ENOPROTOOPT} + @\libmember{no_space_on_device}{errc}@, // \tcode{ENOSPC} + @\libmember{no_such_device_or_address}{errc}@, // \tcode{ENXIO} + @\libmember{no_such_device}{errc}@, // \tcode{ENODEV} + @\libmember{no_such_file_or_directory}{errc}@, // \tcode{ENOENT} + @\libmember{no_such_process}{errc}@, // \tcode{ESRCH} + @\libmember{not_a_directory}{errc}@, // \tcode{ENOTDIR} + @\libmember{not_a_socket}{errc}@, // \tcode{ENOTSOCK} + @\libmember{not_connected}{errc}@, // \tcode{ENOTCONN} + @\libmember{not_enough_memory}{errc}@, // \tcode{ENOMEM} + @\libmember{not_supported}{errc}@, // \tcode{ENOTSUP} + @\libmember{operation_canceled}{errc}@, // \tcode{ECANCELED} + @\libmember{operation_in_progress}{errc}@, // \tcode{EINPROGRESS} + @\libmember{operation_not_permitted}{errc}@, // \tcode{EPERM} + @\libmember{operation_not_supported}{errc}@, // \tcode{EOPNOTSUPP} + @\libmember{operation_would_block}{errc}@, // \tcode{EWOULDBLOCK} + @\libmember{owner_dead}{errc}@, // \tcode{EOWNERDEAD} + @\libmember{permission_denied}{errc}@, // \tcode{EACCES} + @\libmember{protocol_error}{errc}@, // \tcode{EPROTO} + @\libmember{protocol_not_supported}{errc}@, // \tcode{EPROTONOSUPPORT} + @\libmember{read_only_file_system}{errc}@, // \tcode{EROFS} + @\libmember{resource_deadlock_would_occur}{errc}@, // \tcode{EDEADLK} + @\libmember{resource_unavailable_try_again}{errc}@, // \tcode{EAGAIN} + @\libmember{result_out_of_range}{errc}@, // \tcode{ERANGE} + @\libmember{state_not_recoverable}{errc}@, // \tcode{ENOTRECOVERABLE} + @\libmember{text_file_busy}{errc}@, // \tcode{ETXTBSY} + @\libmember{timed_out}{errc}@, // \tcode{ETIMEDOUT} + @\libmember{too_many_files_open_in_system}{errc}@, // \tcode{ENFILE} + @\libmember{too_many_files_open}{errc}@, // \tcode{EMFILE} + @\libmember{too_many_links}{errc}@, // \tcode{EMLINK} + @\libmember{too_many_symbolic_link_levels}{errc}@, // \tcode{ELOOP} + @\libmember{value_too_large}{errc}@, // \tcode{EOVERFLOW} + @\libmember{wrong_protocol_type}{errc}@, // \tcode{EPROTOTYPE} }; template<> struct is_error_condition_enum : true_type {}; @@ -836,7 +763,10 @@ template 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; + constexpr bool @\libglobal{is_error_condition_enum_v}@ = is_error_condition_enum::value; + + // \ref{syserr.fmt}, formatter + template struct formatter; } \end{codeblock} @@ -909,7 +839,7 @@ \begin{itemdescr} \pnum \returns -A string naming the error category. +A string in the ordinary literal encoding naming the error category. \end{itemdescr} \indexlibrarymember{default_error_condition}{error_category}% @@ -953,7 +883,8 @@ \begin{itemdescr} \pnum \returns -A string that describes the error condition denoted by \tcode{ev}. +A string of multibyte characters in the execution character set +that describes the error condition denoted by \tcode{ev}. \end{itemdescr} \rSec3[syserr.errcat.nonvirtuals]{Non-virtual members} @@ -1308,6 +1239,97 @@ Equivalent to: \tcode{return os << ec.category().name() << ':' << ec.value();} \end{itemdescr} +\rSec3[syserr.fmt]{Formatting} + +\pnum +\indexlibraryglobal{formatter}% +\begin{codeblock} +template +struct formatter { + constexpr void set_debug_format(); + + constexpr typename basic_format_parse_context::iterator + parse(basic_format_parse_context& ctx); + + template + typename basic_format_context::iterator + format(const error_code& ec, basic_format_context& ctx) const; +}; +\end{codeblock} + +\indexlibrarymember{set_debug_format}{formatter}% +\begin{itemdecl} +constexpr void set_debug_format(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Modifies the state of the \tcode{formatter} to be as if the +\fmtgrammarterm{error-code-format-spec} parsed by the +last call to \tcode{parse} contained the \tcode{?} option. +\end{itemdescr} + +\indexlibrarymember{parse}{formatter}% +\begin{itemdecl} +constexpr typename basic_format_parse_context::iterator + parse(basic_format_parse_context& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Parses the format specifier as an \fmtgrammarterm{error-code-format-spec} +and stores the parsed specifiers in \tcode{*this}. +The syntax of format specifications is +\begin{ncbnf} +\fmtnontermdef{error-code-format-spec}\br + \opt{fill-and-align} \opt{width} \opt{\terminal{?}} \opt{\terminal{s}} +\end{ncbnf} +where the productions \fmtgrammarterm{fill-and-align} and \fmtgrammarterm{width} +are described in \ref{format.string}. + +\pnum +\returns +An iterator past the end of the \fmtgrammarterm{error-code-format-spec}. +\end{itemdescr} + +\indexlibrarymember{format}{formatter}% +\begin{itemdecl} +template + typename basic_format_context::iterator + format(const error_code& ec, basic_format_context& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If the \tcode{s} option is used, then: +\begin{itemize} +\item +If \tcode{charT} is \tcode{char} and the ordinary literal encoding is UTF-8, +then let \tcode{msg} be \tcode{ec.message()} transcoded to UTF-8 +with maximal subparts of ill-formed subsequences +substituted with \unicode{fffd}{replacement character} +per the Unicode Standard, Chapter 3.9 \ucode{fffd} Substitution in Conversion. +\item +Otherwise, let \tcode{msg} be \tcode{ec.message()} +transcoded to an +\impldef{encoding of an error message during formatting} +encoding. +\end{itemize} +Otherwise, let \tcode{msg} be +\tcode{format("\{\}:\{\}", ec.category().name(), ec.value())}. +If the \tcode{?} option is used then \tcode{msg} is formatted +as an escaped string\iref{format.string.escaped}. +Writes \tcode{msg} into \tcode{ctx.out()}, +adjusted according to the \fmtgrammarterm{error-code-format-spec}. + +\pnum +\returns +An iterator past the end of the output range. +\end{itemdescr} + \rSec2[syserr.errcondition]{Class \tcode{error_condition}} @@ -2110,7 +2132,7 @@ Let \tcode{n} be \tcode{t.size()}. \pnum -\expects +\hardexpects \tcode{skip <= skip + max_depth} is \tcode{true}. \pnum @@ -2289,7 +2311,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{frame_no < size()} is \tcode{true}. \pnum @@ -2365,8 +2387,8 @@ \indexlibrarymember{swap}{basic_stacktrace}% \begin{itemdecl} template -void swap(basic_stacktrace& a, basic_stacktrace& b) - noexcept(noexcept(a.swap(b))); + void swap(basic_stacktrace& a, basic_stacktrace& b) + noexcept(noexcept(a.swap(b))); \end{itemdecl} \begin{itemdescr} @@ -2395,7 +2417,7 @@ \indexlibrarymember{to_string}{basic_stacktrace}% \begin{itemdecl} template -string to_string(const basic_stacktrace& st); + string to_string(const basic_stacktrace& st); \end{itemdecl} \begin{itemdescr} @@ -2523,10 +2545,13 @@ 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. +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} @@ -2553,11 +2578,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\replaceable -A \Cpp{} program may define a function with this function signature, and -thereby displace the default version defined by the \Cpp{} standard library. - \pnum \required This function has no preconditions. @@ -2567,12 +2587,17 @@ \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. +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{term.replaceable.function}. + \end{itemdescr} diff --git a/source/exceptions.tex b/source/exceptions.tex index c14df21e84..23e143e137 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -177,7 +177,7 @@ try : i(f(ii)), d(id) { // constructor statements } catch (...) { - // handles exceptions thrown from the ctor-initializer and from the constructor statements + // handles exceptions thrown from the \grammarterm{ctor-initializer} and from the constructor statements } \end{codeblock} \end{example} @@ -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} @@ -536,9 +556,9 @@ \item% a standard pointer conversion\iref{conv.ptr} not involving conversions -to pointers to private or protected or ambiguous classes +to pointers to private or protected or ambiguous classes, \item% -a function pointer conversion\iref{conv.fctptr} +a function pointer conversion\iref{conv.fctptr}, \item% a qualification conversion\iref{conv.qual}, or @@ -619,7 +639,7 @@ \indextext{exception handling!terminate called@\tcode{terminate} called}% \indextext{\idxcode{terminate}!called}% If the search for a handler -encounters the outermost block of a function with a +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} @@ -670,7 +690,7 @@ Referring to any non-static member or base class of an object in the handler for a \grammarterm{function-try-block} -of a constructor or destructor for that object results in undefined behavior. +of a constructor or destructor for that object results in undefined behavior\ubdef{except.handle.handler.ctor.dtor}. \pnum Exceptions thrown in destructors of objects with static storage duration or in @@ -721,11 +741,14 @@ within the handler. \pnum +\begin{note} When the handler declares an object, any changes to that object will not affect the exception object. When the handler declares a reference to an object, any changes to the referenced object are changes to the -exception object and will have effect should that object be rethrown.% +exception object. +\end{note} +% \indextext{exception handling!handler!match|)}% \indextext{exception handling!handler|)} @@ -758,9 +781,7 @@ \indextext{exception specification!noexcept!constant expression and}% In a \grammarterm{noexcept-specifier}, the \grammarterm{constant-expression}, if supplied, shall be a contextually converted constant expression -of type \keyword{bool}\iref{expr.const}; -that constant expression is the exception specification of -the function type in which the \grammarterm{noexcept-specifier} appears. +of type \keyword{bool}\iref{expr.const.const}. A \tcode{(} token that follows \keyword{noexcept} is part of the \grammarterm{noexcept-specifier} and does not commence an initializer\iref{dcl.init}. @@ -776,6 +797,10 @@ \end{codeblock} \end{example} +\pnum +If the \grammarterm{noexcept-specifier} appears in a function type, +the \grammarterm{constant-expression} is the type's exception specification. + \pnum If a declaration of a function does not have a \grammarterm{noexcept-specifier}, @@ -864,7 +889,7 @@ or \item any of the immediate subexpressions\iref{intro.execution} -of $E$ is potentially-throwing. +of $E$ that is not an unevaluated operand is potentially-throwing. \end{itemize} \pnum @@ -921,7 +946,11 @@ has a non-throwing exception specification. \pnum -The exception specification for a comparison operator function\iref{over.binary} +The exception specification for +\begin{itemize} +\item a comparison operator function\iref{over.binary} or +\item a postfix increment or decrement operator function\iref{over.inc.general} +\end{itemize} without a \grammarterm{noexcept-specifier} that is defaulted on its first declaration is potentially-throwing if and only if @@ -967,15 +996,15 @@ \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 function); -\item the function is defined; or +\item the function is defined; + +\item the function is represented by a reflection; or \item the exception specification is needed for a defaulted function that calls the function. @@ -988,10 +1017,7 @@ \end{note} \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. +function is evaluated as described above only when needed. % \indextext{exception specification|)} @@ -1003,8 +1029,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. @@ -1031,9 +1059,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} @@ -1101,10 +1134,27 @@ 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. +whose promise type has an \tcode{unhandled_stopped} member function, or -\end{itemize} +\item% +when an object \tcode{scope} of type +\tcode{std::execution::simple_counting_scope} or +\tcode{std::execution::counting_scope} +is destroyed and +\tcode{scope.\exposid{state}} is not equal to +\exposid{joined}, +\exposid{unused}, or +\exposid{unused-and-closed}\iref{exec.simple.counting.ctor}, or +\item% +when \tcode{std::execution::get_parallel_scheduler} is called and +\tcode{std::execution::parallel_scheduler_re\-placement::query_parallel_scheduler_backend()} +returns a null pointer value\iref{exec.par.scheduler}, or + +\item% +when an exception is thrown from a coroutine \tcode{std::execution::task}\iref{exec.task} +which doesn't support a \tcode{std::execution::set_error_t(std::exception_ptr)} completion. +\end{itemize} \end{note} \pnum @@ -1113,8 +1163,8 @@ \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} @@ -1127,21 +1177,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 index 4f5f491425..2fd6f4f240 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -101,6 +101,13 @@ 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} @@ -365,6 +372,9 @@ The type of the receiver does not affect an asynchronous operation's completion signatures, only the type of the receiver's environment. +A \defnadj{non-dependent}{sender} is a sender type +whose completion signatures are knowable +independent of an execution environment. \pnum A sender algorithm is a function that takes and/or returns a sender. @@ -393,8 +403,9 @@ \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; + template struct is_execution_policy; // freestanding + template constexpr bool @\libglobal{is_execution_policy_v}@ = // freestanding + is_execution_policy::value; } namespace std::execution { @@ -452,18 +463,26 @@ // \ref{exec.queries}, queries struct @\libglobal{get_domain_t}@ { @\unspec@ }; struct @\libglobal{get_scheduler_t}@ { @\unspec@ }; + struct @\libglobal{get_start_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@ }; + template + struct @\libglobal{get_completion_domain_t}@ { @\unspec@ }; + struct get_await_completion_adaptor_t { @\unspec@ }; inline constexpr get_domain_t @\libglobal{get_domain}@{}; inline constexpr get_scheduler_t @\libglobal{get_scheduler}@{}; + inline constexpr get_start_scheduler_t @\libglobal{get_start_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}@{}; + template + constexpr get_completion_domain_t @\libglobal{get_completion_domain}@{}; + inline constexpr get_await_completion_adaptor_t get_await_completion_adaptor{}; struct @\libglobal{get_env_t}@ { @\unspec@ }; inline constexpr get_env_t @\libglobal{get_env}@{}; @@ -471,31 +490,30 @@ 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.indeterminate}, execution domains + template + struct indeterminate_domain; // \ref{exec.domain.default}, execution domains struct default_domain; // \ref{exec.sched}, schedulers - struct @\libglobal{scheduler_t}@ {}; + struct @\libglobal{scheduler_tag}@ {}; template concept @\libconcept{scheduler}@ = @\seebelow@; // \ref{exec.recv}, receivers - struct @\libglobal{receiver_t}@ {}; + struct @\libglobal{receiver_tag}@ {}; template concept @\libconcept{receiver}@ = @\seebelow@; template - concept @\libconcept{receiver_of}@ = @\seebelow@; + concept @\exposconceptnc{receiver-of}@ = @\seebelownc@; // \expos + + template + concept @\libconcept{inlinable_receiver}@ = @\seebelow@; struct @\libglobal{set_value_t}@ { @\unspec@ }; struct @\libglobal{set_error_t}@ { @\unspec@ }; @@ -506,7 +524,7 @@ inline constexpr set_stopped_t @\libglobal{set_stopped}@{}; // \ref{exec.opstate}, operation states - struct @\libglobal{operation_state_t}@ {}; + struct @\libglobal{operation_state_tag}@ {}; template concept @\libconcept{operation_state}@ = @\seebelow@; @@ -515,28 +533,26 @@ inline constexpr start_t @\libglobal{start}@{}; // \ref{exec.snd}, senders - struct @\libglobal{sender_t}@ {}; + struct @\libglobal{sender_tag}@ {}; + + template + inline constexpr bool enable_sender = @\seebelow@; template concept @\libconcept{sender}@ = @\seebelow@; - template> + template concept @\libconcept{sender_in}@ = @\seebelow@; + template + concept @\libconcept{dependent_sender}@ = @\seebelow@; + template - concept @\libconcept{sender_to}@ = @\seebelow@; + concept @\exposconceptnc{sender-to}@ = @\seebelownc@; // \expos 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 @@ -558,31 +574,33 @@ requires @\libconcept{sender_in}@ constexpr bool sends_stopped = @\seebelow@; - template + template using @\exposidnc{single-sender-value-type}@ = @\seebelownc@; // \expos - template - concept @\exposconcept{single-sender}@ = @\seebelow@; // \expos + template + concept @\exposconceptnc{single-sender}@ = @\seebelownc@; // \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; + template<@\libconcept{sender}@ Sndr, @\exposconcept{queryable}@ Env> + constexpr decltype(auto) transform_sender(Sndr&& sndr, + const Env& env) noexcept(@\seebelow@); // \ref{exec.snd.apply}, sender algorithm application template constexpr decltype(auto) apply_sender( Domain dom, Tag, Sndr&& sndr, Args&&... args) noexcept(@\seebelow@); + // \ref{exec.getcomplsigs}, get completion signatures + template + consteval auto get_completion_signatures() -> @\exposconcept{valid-completion-signatures}@ auto; + + template + requires @\libconcept{sender_in}@ + using completion_signatures_of_t = decltype(get_completion_signatures()); + // \ref{exec.connect}, the connect sender algorithm struct @\libglobal{connect_t}@; inline constexpr connect_t @\libglobal{connect}@{}; @@ -603,8 +621,8 @@ inline constexpr schedule_t @\libglobal{schedule}@{}; inline constexpr @\unspec@ @\libglobal{read_env}@{}; - template<@\libconcept{scheduler}@ Sndr> - using @\libglobal{schedule_result_t}@ = decltype(schedule(declval())); + template<@\libconcept{scheduler}@ Sch> + using @\libglobal{schedule_result_t}@ = decltype(schedule(declval())); // \ref{exec.adapt}, sender adaptors template<@\exposconcept{class-type}@ D> @@ -621,13 +639,18 @@ struct @\libglobal{let_error_t}@ { @\unspec@ }; struct @\libglobal{let_stopped_t}@ { @\unspec@ }; struct @\libglobal{bulk_t}@ { @\unspec@ }; - struct @\libglobal{split_t}@ { @\unspec@ }; + struct @\libglobal{bulk_chunked_t}@ { @\unspec@ }; + struct @\libglobal{bulk_unchunked_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@ }; + struct @\libglobal{associate_t}@ { @\unspec@ }; + struct @\libglobal{spawn_future_t}@ { @\unspec@ }; + inline constexpr @\unspec@ @\libglobal{write_env}@{}; + inline constexpr @\unspec@ @\libglobal{unstoppable}@{}; inline constexpr starts_on_t @\libglobal{starts_on}@{}; inline constexpr continues_on_t @\libglobal{continues_on}@{}; inline constexpr on_t @\libglobal{on}@{}; @@ -639,67 +662,108 @@ 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 bulk_chunked_t @\libglobal{bulk_chunked}@{}; + inline constexpr bulk_unchunked_t @\libglobal{bulk_unchunked}@{}; 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}@{}; + inline constexpr associate_t @\libglobal{associate}@{}; + inline constexpr spawn_future_t @\libglobal{spawn_future}@{}; +} + +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.consumers}, consumers + struct @\libglobal{spawn_t}@ { @\unspec@ }; + inline constexpr spawn_t spawn{}; - // \ref{exec.util}, sender and receiver utilities - // \ref{exec.util.cmplsig} + // \ref{exec.cmplsig}, completion signatures template concept @\exposconceptnc{completion-signature}@ = @\seebelownc@; // \expos template<@\exposconcept{completion-signature}@... Fns> - struct @\libglobal{completion_signatures}@ {}; + 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>; + struct dependent_sender_error : exception {}; - // \ref{exec.run.loop}, run_loop - class run_loop; -} + // \ref{exec.prop}, class template \tcode{prop} + template + struct prop; -namespace std::this_thread { - // \ref{exec.consumers}, consumers - struct @\libglobal{sync_wait_t}@ { @\unspec@ }; - struct @\libglobal{sync_wait_with_variant_t}@ { @\unspec@ }; + // \ref{exec.env}, class template \tcode{env} + template<@\exposconcept{queryable}@... Envs> + struct env; - inline constexpr sync_wait_t @\libglobal{sync_wait}@{}; - inline constexpr sync_wait_with_variant_t @\libglobal{sync_wait_with_variant}@{}; -} + // \ref{exec.run.loop}, run_loop + class run_loop; -namespace std::execution { - // \ref{exec.as.awaitable} + // \ref{exec.as.awaitable}, coroutine utility \tcode{as_awaitable} struct @\libglobal{as_awaitable_t}@ { @\unspec@ }; inline constexpr as_awaitable_t @\libglobal{as_awaitable}@{}; - // \ref{exec.with.awaitable.senders} + // \ref{exec.with.awaitable.senders}, coroutine utility \tcode{with_awaitable_senders} template<@\exposconcept{class-type}@ Promise> struct with_awaitable_senders; + + // \ref{exec.affine}, coroutine utility \tcode{affine} + struct @\libglobal{affine_t}@ { @\unspec@ }; + inline constexpr affine_t @\libglobal{affine}@{}; + + // \ref{exec.inline.scheduler}, inline scheduler + class @\libglobal{inline_scheduler}@; + + // \ref{exec.task.scheduler}, task scheduler + class @\libglobal{task_scheduler}@; + + template + struct @\libglobal{with_error}@ { + using type = remove_cvref_t; + type error; + }; + template + with_error(E) -> with_error; + + // \ref{exec.task}, class template \tcode{task} + template + class @\libglobal{task}@; + + // \ref{exec.scope.concepts}, scope concepts + template + concept @\libconcept{scope_association}@ = @\seebelow@; + template + concept @\libconcept{scope_token}@ = @\seebelow@; + + // \ref{exec.scope.simple.counting}, simple counting scope + class simple_counting_scope; + + // \ref{exec.scope.counting}, counting scope + class counting_scope; + + // \ref{exec.par.scheduler}, parallel scheduler + class @\libglobal{parallel_scheduler}@; + parallel_scheduler get_parallel_scheduler(); + + // \ref{exec.parschedrepl}, namespace \tcode{parallel_scheduler_replacement} + namespace @\libglobal{parallel_scheduler_replacement}@ { + struct receiver_proxy; + struct bulk_item_receiver_proxy; + struct parallel_scheduler_backend; + + shared_ptr query_parallel_scheduler_backend(); + } } \end{codeblock} @@ -725,37 +789,65 @@ \end{itemize} \pnum -For types \tcode{Sndr} and \tcode{Env}, -\tcode{\exposid{single-sender-value-type}} is an alias for: +For type \tcode{Sndr} and pack of types \tcode{Env}, +let \tcode{CS} be \tcode{completion_signatures_of_t}. +Then \tcode{\exposid{single-sender-value-type}} is ill-formed +if \tcode{CS} is ill-formed; +otherwise, it is an alias for: \begin{itemize} \item -\tcode{value_types_of_t} +\tcode{\exposid{gather-signatures}} if that type is well-formed, \item Otherwise, \tcode{void} -if \tcode{value_types_of_t} is -\tcode{variant>} or \tcode{vari\-ant<>}, +if \tcode{\exposid{gather-signatures}} is +\tcode{variant>} or \tcode{variant<>}, \item -Otherwise, \tcode{value_types_of_t} -if that type is well-formed, +Otherwise, \tcode{\exposid{gather-signatures}} +if that\linebreak{} type is well-formed, \item -Otherwise, \tcode{\exposid{single-sender-value-type}} is ill-formed. +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}@ && + template + concept @\defexposconcept{single-sender}@ = @\libconcept{sender_in}@ && requires { - typename @\exposid{single-sender-value-type}@; + typename @\exposid{single-sender-value-type}@; }; } \end{codeblock} +\pnum +A type satisfies and models the exposition-only concept +\defexposconcept{valid-completion-signatures} if +it is a specialization of the \tcode{completion_signatures} class template. + \rSec1[exec.queries]{Queries} +\rSec2[exec.queries.expos]{Query utilities} + +\pnum +Subclause \ref{exec.queries} makes use of the following exposition-only entities. + +\pnum +For subexpressions \tcode{q} and \tcode{tag} and pack \tcode{args}, +let \tcode{\exposid{TRY-QUERY}(q, tag, args...)} be expression-equivalent to +\tcode{\exposid{AS-CONST}(q).query(tag, args...)} +if that expression is well-formed, and +\tcode{\exposid{AS-CONST}(q).query(tag)} otherwise +except that \tcode{args...} is evaluated. + +\pnum +For subexpressions \tcode{q} and \tcode{tag} and pack \tcode{args}, +let \tcode{\exposid{HIDE-SCHED}(q)} be an object \tcode{o} such that +\tcode{o.query(\brk{}tag, args...)} is ill-formed when the decayed type of \tcode{tag} is +\tcode{get_scheduler_t} or \tcode{get_domain_t}, and +\tcode{q.query(tag, args...)} otherwise. + \rSec2[exec.fwd.env]{\tcode{forwarding_query}} \pnum @@ -789,7 +881,7 @@ 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}(as_const(env).query(get_allocator))}. +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_allocator))}. \mandates If the expression above is well-formed, @@ -811,7 +903,7 @@ \tcode{get_stop_token(env)} is expression-equivalent to: \begin{itemize} \item -\tcode{\exposid{MANDATE-NOTHROW}(as_const(env).query(get_stop_token))} +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_stop_token))} if that expression is well-formed. \mandates @@ -833,7 +925,7 @@ \tcode{execution::get_env(o)} is expression-equivalent to: \begin{itemize} \item -\tcode{\exposid{MANDATE-NOTHROW}(as_const(o).get_env())} +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(o).get_env())} if that expression is well-formed. \mandates @@ -864,7 +956,14 @@ 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}(as_const(env).query(get_domain))}. +\tcode{\exposid{MANDATE-NOTHROW}(D())}, +where \tcode{D} is the type of the first +of the following expressions that is well-formed: +\begin{itemize} +\item \tcode{auto(\exposid{AS-CONST}(env).query(get_domain))}. +\item \tcode{get_completion_domain(get_scheduler(env), \exposid{HIDE-SCHED}(env))}. +\item \tcode{default_domain()}, except that \tcode{env} is evaluated. +\end{itemize} \pnum \tcode{forwarding_query(execution::get_domain)} is @@ -879,7 +978,9 @@ 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}(as_const(env).query(get_scheduler))}. +\tcode{get_completion_scheduler( +\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env)\brk{}.query(get_scheduler)), +\exposid{HIDE-SCHED}(env))}. \mandates If the expression above is well-formed, @@ -889,6 +990,34 @@ \tcode{forwarding_query(execution::get_scheduler)} is a core constant expression and has value \tcode{true}. +\rSec2[exec.get.start.scheduler]{\tcode{execution::get_start_scheduler}} + +\pnum +\tcode{get_start_scheduler} asks a queryable object +for the scheduler an operation will be or was started on. + +\pnum +The name \tcode{get_start_scheduler} denotes a query object. +For a subexpression \tcode{env}, +\tcode{get_start_scheduler(\brk{}env)} is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_start_scheduler))}. + +\mandates +If the expression above is well-formed, +its type satisfies \libconcept{scheduler}. + +\pnum +\tcode{forwarding_query(execution::get_start_scheduler)} +is a core constant expression and has value \tcode{true}. + +\pnum +Given subexpressions \tcode{sndr} and \tcode{rcvr} +such that \tcode{\exposid{sender-to}} is \tcode{true} +and the expression \tcode{get_start_scheduler(get_env(rcvr))} is well-formed, +an operation state that is the result of calling \tcode{connect(sndr, rcvr)} +shall, if it is started, be started on an execution agent +associated with the scheduler \tcode{get_start_scheduler(get_env(rcvr))}. + \rSec2[exec.get.delegation.scheduler]{\tcode{execution::get_delegation_scheduler}} \pnum @@ -900,7 +1029,7 @@ 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}(as_const(env).query(get_delegation_scheduler))}. +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_delegation_scheduler))}. \mandates If the expression above is well-formed, @@ -934,16 +1063,12 @@ \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}(as_const(sch).query(get_forward_progress_guarantee))}, -if that expression is well-formed. +\begin{codeblock} +@\exposid{MANDATE-NOTHROW}@(@\exposid{AS-CONST}@(sch).query(get_forward_progress_guarantee)) +\end{codeblock} \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} @@ -957,34 +1082,72 @@ \rSec2[exec.get.compl.sched]{\tcode{execution::get_completion_scheduler}} \pnum -\tcode{get_completion_scheduler<\exposid{completion-tag>}} obtains +The name \tcode{get_completion_scheduler} denotes a query object template. + +\pnum +Let \exposid{completion-fn} be a completion function\iref{exec.async.ops}; +let \exposid{completion-fn-tag} be +the associated completion tag of \exposid{completion-fn}; +let \tcode{args} and \tcode{envs} be packs of subexpressions; and +let \tcode{sndr} be a subexpression +such that \tcode{\libconcept{sender}} is \tcode{true} and +\tcode{get_completion_scheduler<\exposid{completion-fn-tag}>(get_env(sndr), envs...)} +is well-formed and denotes a scheduler \tcode{sch}. + +\pnum +\tcode{get_completion_scheduler<\exposid{completion-fn-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 +For subexpression \tcode{sch1} and pack \tcode{envs}, +let \tcode{sch2} be +\tcode{\exposid{TRY-QUERY}(sch1, get_completion_scheduler, envs...)} and +let \tcode{\exposid{RECURSE-QUERY}(sch1, envs...)} be +expression-equivalent to \tcode{sch1} +if \tcode{sch2} is ill-formed or +if \tcode{sch1} and \tcode{sch2} have the same type and compare equal; +otherwise, \tcode{\exposid{RECURSE-QUERY}(sch2, envs...)}. + +\pnum +For a subexpression \tcode{q} and pack \tcode{envs}, +the expression \tcode{get_completion_scheduler<\exposid{completion-fn-tag}>(q, envs...)} +is ill-formed if \exposid{completion-fn-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 +Otherwise, the expression +is expression-equivalent to: +\begin{itemize} +\item \begin{codeblock} -@\exposid{MANDATE-NOTHROW}@(as_const(q).query(get_completion_scheduler<@\exposid{completion-tag}@>)) +@\exposid{MANDATE-NOTHROW}@(@\exposid{RECURSE-QUERY}@( + @\exposid{TRY-QUERY}@(q, get_completion_scheduler<@\exposid{completion-fn-tag}@>, envs...), envs...)) \end{codeblock} +if that expression is well-formed, +except that \tcode{envs...} is evaluated only once. +\item +Otherwise, \tcode{auto(q)} +if the type of \tcode{q} satisfies \libconcept{scheduler} and +\tcode{envs} is not an empty pack, +except that \tcode{envs...} is evaluated. +\item +Otherwise, \tcode{get_completion_scheduler<\exposid{completion-fn-tag}>(q, envs...)} +is ill-formed. +\end{itemize} \mandates -If the expression above is well-formed, +If \tcode{get_completion_scheduler<\exposid{completion-fn-tag}>(q, envs...)} +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}. +For a type \tcode{Tag}, subexpression \tcode{sndr}, and pack \tcode{envs}, +let \tcode{CS} be +\tcode{completion_signatures_of_t, decltype((envs))...>}. +If both \tcode{get_completion_scheduler(get_env(\newline sndr), envs...)} and +\tcode{CS} are well-formed and +\tcode{CS().\exposid{count-of}(Tag()) == 0} is \tcode{true}, +the program is ill-formed. + +\pnum If an asynchronous operation created by connecting \tcode{sndr} with a receiver \tcode{rcvr} causes the evaluation of \tcode{\exposid{completion-fn}(rcvr, args...)}, @@ -994,7 +1157,100 @@ \pnum The expression -\tcode{forwarding_query(get_completion_scheduler<\exposid{completion-tag}>)} +\tcode{forwarding_query(get_completion_scheduler<\exposid{completion-fn-tag}>)} +is a core constant expression and has value \tcode{true}. + +\rSec2[exec.get.compl.domain]{\tcode{execution::get_completion_domain}} + +\pnum +\tcode{get_completion_domain<\exposid{completion-tag}>} +obtains the completion domain associated with a completion tag +from a sender's attributes. + +\pnum +The name \tcode{get_completion_domain} denotes a query object template. +For a subexpression \tcode{attrs} and pack \tcode{envs}, +the expression \tcode{get_completion_domain<\exposid{completion-tag}>(attrs, envs...)} +is ill-formed if \exposid{completion-tag} is not one of +\tcode{void}, +\tcode{set_value_t}, +\tcode{set_error_t}, or +\tcode{set_stopped_t}. +Otherwise, the expression is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(D())}, +where \tcode{D} is: +\begin{itemize} +\item +The type of +\tcode{\exposid{TRY-QUERY}(attrs, get_completion_domain<\exposid{completion-tag}>, envs...)} +if that expression is well-formed. +\item +Otherwise, the type of +\tcode{get_completion_domain(attrs, envs...)} +if \exposid{completion-tag} is \tcode{void}. +\item +Otherwise, the type of +\begin{codeblock} +@\exposidnc{TRY-QUERY}@(get_completion_scheduler<@\exposid{completion-tag}@>(attrs, envs...), + get_completion_domain, envs...) +\end{codeblock} +if that expression is well-formed. +\item +Otherwise, \tcode{default_domain} if +\tcode{\libconcept{scheduler}} is \tcode{true} and +\tcode{envs} is not an empty pack. +\item +Otherwise, \tcode{get_completion_domain<\exposid{completion-tag}>(attrs, envs...)} +is ill-formed. +\end{itemize} + +\pnum +For a type \tcode{Tag}, subexpression \tcode{sndr}, and pack \tcode{envs}, +let \tcode{CS} be +\tcode{completion_signatures_of_t, decltype((envs))...>}. +If both \tcode{get_completion_domain(get_env(sndr), envs...)} and +\tcode{CS} are well-formed and +\tcode{CS().\exposid{count-of}(Tag()) == 0} is \tcode{true}, +the program is ill-formed. + +\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} and \tcode{envs} be packs of subexpressions; and +let \tcode{sndr} be a subexpression such that +\tcode{\libconcept{sender}} is \tcode{true} and +\tcode{get_completion_domain<\exposid{completion-tag}>(get_env(sndr), envs...)} +is well-formed and denotes a domain tag \tcode{D}. +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 of an execution resource +whose associated execution domain tag is \tcode{D}. + +The expression +\tcode{forwarding_query(get_completion_domain<\exposid{completion-tag}>)} +is a core constant expression and has value \tcode{true}. + +\rSec2[exec.get.await.adapt]{\tcode{execution::get_await_completion_adaptor}} + +\pnum +\tcode{get_await_completion_adaptor} asks a queryable object for +its associated awaitable completion adaptor. + +\pnum +The name \tcode{get_await_completion_adaptor} denotes a query object. +For a subexpression \tcode{env}, +\begin{codeblock} +get_await_completion_adaptor(env) +\end{codeblock} +is expression-equivalent to +\begin{codeblock} +@\exposidnc{MANDATE-NOTHROW}@(@\exposid{AS-CONST}@(env).query(get_await_completion_adaptor)) +\end{codeblock} + +\pnum +\tcode{forwarding_query(execution::get_await_completion_adaptor)} is a core constant expression and has value \tcode{true}. \rSec1[exec.sched]{Schedulers} @@ -1009,13 +1265,11 @@ namespace std::execution { template concept @\deflibconcept{scheduler}@ = - @\libconcept{derived_from}@::scheduler_concept, scheduler_t> && + @\libconcept{derived_from}@::scheduler_concept, scheduler_tag> && @\exposconcept{queryable}@ && requires(Sch&& sch) { { schedule(std::forward(sch)) } -> @\libconcept{sender}@; - { auto(get_completion_scheduler( - get_env(schedule(std::forward(sch))))) } - -> @\libconcept{same_as}@>; + { get_forward_progress_guarantee(sch) } -> @\libconcept{same_as}@; } && @\libconcept{equality_comparable}@> && @\libconcept{copyable}@>; @@ -1050,24 +1304,50 @@ \pnum For a given scheduler expression \tcode{sch}, -the expression +if the expression \tcode{get_completion_scheduler(get_env(schedule(sch)))} -shall compare equal to \tcode{sch}. +is well-formed, +it 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. +type \tcode{T}, and +pack of subexpressions \tcode{envs}, +the following expressions are either both ill-formed, or +both well-formed with the same type: +\begin{itemize} +\item \tcode{get_completion_domain(sch, envs...)} +\item \tcode{get_completion_domain(get_env(schedule(sch)), envs...)} +\end{itemize} +Likewise, the following expressions are either both ill-formed, or +both well-formed with the same type and value: +\begin{itemize} +\item \tcode{get_completion_scheduler(sch, envs...)} +\item \tcode{get_completion_scheduler(get_env(schedule(sch)), envs...)} +\end{itemize} \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} + +\pnum +The exposition-only \exposconcept{infallible-scheduler} concept +defines the requirements of a scheduler type +whose \tcode{schedule} asynchronous operation +can only complete with \tcode{set_value} unless stop can be requested: +\begin{codeblock} +template + concept @\defexposconcept{infallible-scheduler}@ = + @\libconcept{scheduler}@ && + (@\libconcept{same_as}@, + completion_signatures_of_t())), Env>> || + (!@\libconcept{unstoppable_token}@> && + (@\libconcept{same_as}@, + completion_signatures_of_t())), Env>> || + @\libconcept{same_as}@, + completion_signatures_of_t())), Env>>))); +\end{codeblock} \rSec1[exec.recv]{Receivers} @@ -1077,7 +1357,7 @@ 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 exposition-only concept \exposconcept{receiver-of} 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. @@ -1087,15 +1367,16 @@ namespace std::execution { template concept @\deflibconcept{receiver}@ = - @\libconcept{derived_from}@::receiver_concept, receiver_t> && + @\libconcept{derived_from}@::receiver_concept, receiver_tag> && 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 + @\libconcept{move_constructible}@> && // rvalues are movable, and + @\libconcept{constructible_from}@, Rcvr> && // lvalues are copyable, and + is_nothrow_move_constructible_v>; // no-throw-movable template - concept @\defexposconcept{valid-completion-for}@ = // \expos + concept @\defexposconceptnc{valid-completion-for}@ = // \expos requires (Signature* sig) { [](Tag(*)(Args...)) requires @\exposconcept{callable}@, Args...> @@ -1103,14 +1384,14 @@ }; template - concept @\defexposconcept{has-completions}@ = // \expos + concept @\defexposconceptnc{has-completions}@ = // \expos requires (Completions* completions) { []<@\exposconcept{valid-completion-for}@...Sigs>(completion_signatures*) {}(completions); }; template - concept @\deflibconcept{receiver_of}@ = + concept @\defexposconceptnc{receiver-of}@ = // \expos @\libconcept{receiver}@ && @\exposconcept{has-completions}@; } \end{codeblock} @@ -1135,6 +1416,98 @@ must be destroyed before the invocation of the completion operation. \end{note} +\pnum +\begin{codeblock} +namespace std::execution { + template + concept @\deflibconcept{inlinable_receiver}@ = @\libconcept{receiver}@ && + requires (ChildOp* child) { + { remove_cvref_t::make_receiver_for(child) } noexcept + -> @\libconcept{same_as}@>; + }; +} +\end{codeblock} + +The \libconcept{inlinable_receiver} concept +defines the requirements for a receiver +that can be reconstructed on demand +from a pointer to the operation state object +created when the receiver was connected to a sender. +Given a receiver object \tcode{rcvr} of type \tcode{Rcvr} +which was connected to a sender producing +an operation state object \tcode{op} of type \tcode{Op}, +\tcode{Rcvr} models \tcode{\libconcept{inlinable_receiver}} +only if the expression \tcode{Rcvr::make_receiver_for(addressof(op))} +evaluates to a receiver +that is equal to \tcode{rcvr}\iref{concepts.equality}. +\begin{note} +Such a receiver does not need to be stored as a data member of \tcode{op} +as it can be recreated on demand. +\end{note} +\tcode{ChildOp} may be an incomplete type. + +\pnum +Given objects $O_0, \dotsc, O_n$, +$O_n$ is \defnadj{transitively}{constructed} from $O_0$ if +\begin{itemize} +\item +\tcode{remove_cvref_t} +denotes the same type as +\tcode{remove_cvref_t} and +\item +either +\begin{itemize} +\item +$O_1$ was initialized by decay-copying a reference to $O_0$, or +\item +$n > 1$ and $O_{n-1}$ is transitively constructed from $O_0$ and +$O_n$ was initialized from +a non-const, non-volatile rvalue reference to $O_{n-1}$. +\end{itemize} +\end{itemize} + +\pnum +Let $E$ be some well-formed expression \tcode{connect(sndr, rcvr)}. +$E$ \defn{inlines the receiver} \tcode{rcvr} +if the lifetimes of all objects transitively constructed from +\tcode{rcvr} during the evaluation of $E$ +end within the evaluation of $E$. +\begin{note} +This means such an expression does not store the receiver in the operation state. +\end{note} + +\pnum +Let $E$ be some well-formed expression \tcode{connect(sndr, rcvr)} where +\begin{itemize} +\item +\tcode{sndr} denotes a sender type defined by this document and +\item +$E$ inlines the receiver \tcode{rcvr}. +\end{itemize} +Then, let \tcode{op} be the result of the evaluation of $E$, and +wherever the specification of the operation associated with \tcode{op} +contains a glvalue +which would denote an object transitively constructed from \tcode{rcvr}, +that glvalue instead denotes the result of applying +the temporary materialization conversion to the expression +\tcode{remove_cvref_t::make_receiver_for(addressof(op))}. + +\pnum +Let \tcode{StdRcvr} be a receiver type defined by this document. +Given some operation state type \tcode{Op}, +it is unspecified +whether \tcode{StdRcvr} models \tcode{\libconcept{inlinable_receiver}}. + +\pnum +Let \tcode{StdOp} be some operation state type defined by this document, +and let \tcode{Sndr} and \tcode{Rcvr} be types such that +\tcode{is_same_v, StdOp>} is \tcode{true}. +If \tcode{Rcvr} models \tcode{\libconcept{inlinable_receiver}} +then it is implementation-defined whether, +given an object \tcode{rcvr} of type \tcode{Rcvr}, +the \tcode{connect} operation which produces an object of type \tcode{StdOp} +inlines the receiver \tcode{rcvr}. + \rSec2[exec.set.value]{\tcode{execution::set_value}} \pnum @@ -1147,17 +1520,23 @@ Otherwise, it is expression-equivalent to \tcode{\exposid{MANDATE-NOTHROW}(rcvr.set_value(vs...))}. +\mandates +If the expression above is well-formed, its type is \tcode{void}. + \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 +for some 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))}. +\mandates +If the expression above is well-formed, its type is \tcode{void}. + \rSec2[exec.set.stopped]{\tcode{execution::set_stopped}} \pnum @@ -1169,6 +1548,9 @@ Otherwise, it is expression-equivalent to \tcode{\exposid{MANDATE-NOTHROW}(rcvr.set_stopped())}. +\mandates +If the expression above is well-formed, its type is \tcode{void}. + \rSec1[exec.opstate]{Operation states} \rSec2[exec.opstate.general]{General} @@ -1180,10 +1562,9 @@ namespace std::execution { template concept @\deflibconcept{operation_state}@ = - @\libconcept{derived_from}@ && - is_object_v && + @\libconcept{derived_from}@ && requires (O& o) { - { start(o) } noexcept; + start(o); }; } \end{codeblock} @@ -1217,6 +1598,9 @@ Otherwise, it is expression-equivalent to \tcode{\exposid{MANDATE-NOTHROW}(op.start())}. +\mandates +If the expression above is well-formed, its type is \tcode{void}. + \pnum If \tcode{op.start()} does not start\iref{exec.async.ops} the asynchronous operation associated with the operation state \tcode{op}, @@ -1235,34 +1619,135 @@ 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}. +such that \tcode{\exposconcept{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}. + +\pnum 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 +this set of completion operations, and +let \tcode{CS} be +the type of the expression \tcode{get_completion_signatures()}. +Then \tcode{CS} is a specialization of -the class template \tcode{completion_signatures}\iref{exec.util.cmplsig}, +the class template \tcode{completion_signatures}\iref{exec.cmplsig}, the set of whose template arguments is \tcode{Sigs}. +If none of the types in \tcode{Sigs} are dependent on the type \tcode{Env}, then +the expression \tcode{get_completion_signatures()} is well-formed and +its type is \tcode{CS}. + +\pnum +Each completion operation can potentially be evaluated +on one of several different execution agents +as determined by the semantics of the algorithm, +the environment of the receiver, and +the completions of any child senders. +For a completion tag \tcode{T}, +let $\tcode{Ds}_{\tcode{T}}$ be a pack comprised of the set of domain tags +associated with the execution agents that could potentially evaluate +any of the operation's completions with tag \tcode{T}. +If there are no potentially evaluated completion operations +with tag type \tcode{T}, +then \tcode{get_completion_domain(get_env(sndr), env)} is ill-formed; +otherwise, it has type +\tcode{\exposid{COMMON-DOMAIN}<$\tcode{Ds}_{\tcode{T}}$...>}\iref{exec.snd.expos}. +\begin{example} +Let \tcode{sndr2} be the sender \tcode{then(sndr, fn)}. +\tcode{sndr2} has the same \tcode{set_value} completion domain tag as \tcode{sndr}, +but if \tcode{fn}'s evaluation is potentially throwing, +\tcode{sndr}'s \tcode{set_error} completion domain tag would be +the \exposid{COMMON-DOMAIN} of \tcode{sndr}'s value and error completion domain tags, +in accordance with the semantics of the \tcode{then} algorithm\iref{exec.then}. +\end{example} + +\pnum +If \tcode{sndr} can determine that all of its completion operations +with tag \tcode{T} happen on execution agents +associated with a particular scheduler \tcode{sch} +(as determined by the semantics of the algorithm, +the environment of the receiver, and +the completion schedulers of any child senders), +then \tcode{get_completion_scheduler(get_env(sndr), env)} +is well-formed and has the type and value of \tcode{sch}; +otherwise, it is ill-formed. +\begin{example} +Let \tcode{sndr2} be the sender from the example above. +The \tcode{set_value} completion scheduler of \tcode{sndr2} is +the \tcode{set_value} completion scheduler of \tcode{sndr}, if any. +But \tcode{sndr2} can only report a \tcode{set_error} completion scheduler +when invocations of \tcode{fn} are not potentially throwing or +when \tcode{sndr} has no \tcode{set_error} completions. +When \tcode{fn} can throw, +\tcode{sndr2} could complete with \tcode{set_error} either +by forwarding an error completion from \tcode{sndr} or +by completing with the exception thrown by \tcode{fn}, +which would happen on an agent associated with \tcode{sndr}'s +\tcode{set_value} completion scheduler. +\end{example} + +\pnum If a user-provided implementation of the algorithm -that produced \tcode{sndr} is selected instead of the default, -any completion signature +that produced \tcode{sndr} is selected instead of the default: + +\begin{itemize} +\item +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. +\item +If none of the types in \tcode{Sigs} are dependent on the type \tcode{Env}, then +\tcode{completion_signatures_of_t} and +\tcode{completion_signatures_of_t} +shall denote the same type. +\end{itemize} + +\pnum +\indexlibraryglobal{\tcode{\placeholder{unspecified-exception}}}% +Various function templates in subclause \ref{exec.snd} +can throw an exception of type \exposid{unspecified-exception}. +Each such exception object is of an unspecified type +such that a \grammarterm{handler} of type \tcode{exception} +matches\iref{except.handle} the exception object +but a \grammarterm{handler} of type \tcode{dependent_sender_error} does not. +\begin{note} +There is no requirement that two such exception objects have the same type. +\end{note} + \rSec2[exec.snd.expos]{Exposition-only entities} +\pnum +Given an expression \tcode{sndr}, +whose type is any sender type defined in the standard library, +it is unspecified +whether the expression \tcode{sndr.affine()} is well-formed. +If that expression is well-formed, +then the evaluation thereof meets the semantic requirements of +the \tcode{affine}\iref{exec.affine} algorithm. + +\pnum +Given an expression \tcode{sndr}, +whose type is any sender type defined in the standard library, +and an expression \tcode{p}, +whose type is a promise type, +it is unspecified +whether the expression \tcode{sndr.as_awaitable(p)} is well-formed. +If that expression is well-formed, +then the evaluation thereof meets the semantic requirements of +the \tcode{as_awaitable}\iref{exec.as.awaitable} algorithm. + \pnum Subclause \ref{exec.snd} makes use of the following exposition-only entities. \pnum +\indexlibraryglobal{\exposid{FWD-ENV}}% For a queryable object \tcode{env}, \tcode{\exposid{FWD-ENV}(env)} is an expression whose type satisfies \exposconcept{queryable} @@ -1271,15 +1756,20 @@ 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...)}. +\indexlibraryglobal{\exposid{FWD-ENV-T}}% +The type \tcode{\exposid{FWD-ENV-T}(Env)} is +\tcode{decltype(\exposid{FWD-ENV}(declval()))}. \pnum -For a query object \tcode{q} and \tcode{a} subexpression \tcode{v}, +For a query object \tcode{q}, +a subexpression \tcode{v}, and +a pack of subexpressions \tcode{args}, \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 +such that the result of \tcode{env.query(q, args...)} has a value equal to \tcode{v}\iref{concepts.equality}. Unless otherwise stated, -the object to which \tcode{env.query(q)} refers remains valid +the object to which \tcode{env.query(q, args...)} refers remains valid while \tcode{env} remains valid. \pnum @@ -1305,20 +1795,31 @@ with different types and value categories in different contexts for the same arguments. +\pnum +For a pack of subexpressions \tcode{domains}, +\tcode{\exposid{COMMON-DOMAIN}(domains...)} is expression-equivalent to +\tcode{common_type_t()} +if that expression is well-formed, and +\tcode{indeterminate_domain<\brk{}Ds...>()} otherwise, +where \tcode{Ds} is the pack of types consisting of +\tcode{decltype(auto(domains))...} with duplicate types removed. + +\pnum +For a type \tcode{Tag}, subexpression \tcode{sndr}, and pack \tcode{envs}, +\tcode{\exposid{COMPL-DOMAIN}(Tag, sndr, envs)} +is expression-equivalent to \tcode{D()}, +where \tcode{D} is +the type of \tcode{get_completion_domain(get_env(sndr), envs...)} +if that expression is well-formed or \tcode{envs} is an empty pack, and +\tcode{indeterminate_domain()} otherwise. + \pnum For a scheduler \tcode{sch}, -\tcode{\exposid{SCHED-ATTRS}(sch)} is an expression \tcode{o1} +\tcode{\exposid{SCHED-ENV}(sch)} is an expression \tcode{o} 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 +such that \tcode{o.query(\brk{}get_start_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 +such that \tcode{o.query(get_domain)} is expression-equivalent to \tcode{sch.query(get_domain)}. \pnum @@ -1342,31 +1843,6 @@ \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}@( @@ -1385,78 +1861,7 @@ \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} +The expression in the \tcode{noexcept} clause is \tcode{noexcept(e)}. \end{itemdescr} \pnum @@ -1491,11 +1896,11 @@ \pnum \begin{codeblock} -template +template struct @\exposid{product-type}@ { // \expos T@$_0$@ t@$_0$@; // \expos T@$_1$@ t@$_1$@; // \expos - @...@ + @\vdots@ T@$_n$@ t@$_n$@; // \expos template @@ -1560,8 +1965,18 @@ otherwise, \tcode{false}. \end{itemdescr} +\pnum +Let \exposconcept{valid-specialization} be the following concept: +\begin{codeblock} +namespace std::execution { + template class T, class... Args> + concept @\defexposconceptnc{valid-specialization}@ = // \expos + requires { typename T; }; +} +\end{codeblock} + \begin{itemdecl} -template +template constexpr auto @\exposid{make-sender}@(Tag tag, Data&& data, Child&&... child); \end{itemdecl} @@ -1572,7 +1987,19 @@ \begin{itemize} \item \tcode{\libconcept{semiregular}} \item \tcode{\exposconcept{movable-value}} -\item \tcode{(\libconcept{sender} \&\&...)} +\item \tcode{(\libconcept{sender} \&\& ...)} +\item% +\tcode{\libconcept{dependent_sender} || \libconcept{sender_in}}, +where \tcode{Sndr} is +\tcode{\exposid{basic-sender}, decay_t...>} +as defined below. + + \recommended +If evaluation of \tcode{\libconcept{sender_in}} results in +an uncaught exception from +the evaluation of \tcode{get_completion_signatures()}, +the implementation should include information about that exception in +the resulting diagnostic. \end{itemize} \pnum @@ -1581,29 +2008,17 @@ 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. + +\pnum +\remarks +The default template argument for the \tcode{Data} template parameter +denotes an unspecified empty trivially copyable class type +that models \libconcept{semiregular}. \end{itemdescr} +\pnum \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&>>; @@ -1613,136 +2028,86 @@ decltype(@\exposid{impls-for}@>::@\exposid{get-env}@), Index, @\exposid{state-type}@&, const Rcvr&>; + template + using @\exposidnc{data-type}@ = decltype(declval().template @\exposidnc{get}@<1>()); // \expos + template - using @\exposid{child-type}@ = decltype(declval().template @\exposid{get}@()); // \expos + using @\exposidnc{child-type}@ = decltype(declval().template @\exposidnc{get}@()); // \expos template - using @\exposid{indices-for}@ = remove_reference_t::@\exposid{indices-for}@; // \expos + using @\exposidnc{indices-for}@ = remove_reference_t::@\exposidnc{indices-for}@; // \expos template - struct @\exposid{basic-state}@ { // \expos + struct @\exposidnc{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 + Rcvr @\exposidnc{rcvr}@; // \expos + @\exposidnc{state-type}@ @\exposidnc{state}@; // \expos }; +} +\end{codeblock} + +\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 +\begin{codeblock} +namespace std::execution { template requires @\exposconcept{valid-specialization}@<@\exposid{env-type}@, Index, Sndr, Rcvr> - struct @\exposid{basic-receiver}@ { // \expos - using receiver_concept = receiver_t; + struct @\exposidnc{basic-receiver}@ { // \expos + using receiver_concept = receiver_tag; - 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 + using @\exposidnc{tag-t}@ = tag_of_t; // \expos + using @\exposidnc{state-t}@ = @\exposidnc{state-type}@; // \expos + static constexpr const auto& @\exposidnc{complete}@ = @\exposidnc{impls-for}@<@\exposidnc{tag-t}@>::@\exposidnc{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)...); + @\exposid{complete}@(Index(), @\exposidnc{op}@->@\exposid{state}@, @\exposidnc{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)); + @\exposid{complete}@(Index(), @\exposidnc{op}@->@\exposid{state}@, @\exposidnc{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()); + void set_stopped() && noexcept { + @\exposid{complete}@(Index(), @\exposidnc{op}@->@\exposid{state}@, @\exposidnc{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}@); + return @\exposid{impls-for}@<@\exposid{tag-t}@>::@\exposid{get-env}@(Index(), @\exposidnc{op}@->@\exposid{state}@, @\exposidnc{op}@->@\exposid{rcvr}@); } - @\exposid{basic-state}@* @\exposid{op}@; // \expos + @\exposidnc{basic-state}@* @\exposidnc{op}@; // \expos }; +} +\end{codeblock} - constexpr auto @\exposid{connect-all}@ = @\seebelow@; // \expos +\begin{codeblock} +namespace std::execution { + constexpr auto @\exposidnc{connect-all}@ = @\seebelownc@; // \expos template - using @\exposid{connect-all-result}@ = @\exposid{call-result-t}@< // \expos + using @\exposidnc{connect-all-result}@ = @\exposidnc{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: @@ -1770,29 +2135,53 @@ \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}@())) +namespace std::execution { + template + requires @\exposconcept{valid-specialization}@<@\exposid{state-type}@, Sndr, Rcvr> && + @\exposconcept{valid-specialization}@<@\exposid{connect-all-result}@, Sndr, Rcvr> + struct @\exposidnc{basic-operation}@ : @\exposidnc{basic-state}@ { // \expos + using operation_state_concept = operation_state_tag; + using @\exposidnc{tag-t}@ = tag_of_t; // \expos + + @\exposidnc{connect-all-result}@ @\exposidnc{inner-ops}@; // \expos + + @\exposidnc{basic-operation}@(Sndr&& sndr, Rcvr&& rcvr) noexcept(@\seebelownc@) // \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{tag-t}@>::@\exposid{start}@(this->@\exposid{state}@, this->@\exposid{rcvr}@, ops...); + } + }; +} \end{codeblock} \pnum The expression in the \tcode{noexcept} clause of -the \tcode{connect} member function of \exposid{basic-sender} is: +the constructor of \exposid{basic-operation} is: \begin{codeblock} -is_nothrow_constructible_v<@\exposid{basic-operation}@, Self, Rcvr> +is_nothrow_constructible_v<@\exposid{basic-state}@, Self, Rcvr> && +noexcept(@\exposid{connect-all}@(this, std::forward(sndr), @\exposid{indices-for}@())) \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<>(); +namespace std::execution { + struct @\exposidnc{default-impls}@ { // \expos + static constexpr auto @\exposidnc{get-env}@ = @\seebelownc@; // \expos + static constexpr auto @\exposidnc{get-state}@ = @\seebelownc@; // \expos + static constexpr auto @\exposidnc{start}@ = @\seebelownc@; // \expos + static constexpr auto @\exposidnc{complete}@ = @\seebelownc@; // \expos + + template + static consteval void @\exposidnc{check-types}@(); // \expos + }; + + template + struct @\exposidnc{impls-for}@ : @\exposidnc{default-impls}@ {}; // \expos } \end{codeblock} @@ -1811,7 +2200,7 @@ \begin{codeblock} [](Sndr&& sndr, Rcvr& rcvr) noexcept -> decltype(auto) { auto& [_, data, ...child] = sndr; - return std::forward_like(data); + return @\exposid{allocator-aware-forward}@(std::forward_like(data), rcvr); } \end{codeblock} @@ -1836,136 +2225,328 @@ } \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. - +\indexlibrarymember{\exposid{check-types}}{\exposid{default-impls}}% \begin{itemdecl} -template<@\libconcept{sender}@ Sndr, @\exposconcept{queryable}@ Env> - constexpr auto @\exposid{write-env}@(Sndr&& sndr, Env&& env); // \expos +template + static consteval void @\exposid{default-impls}@::@\exposid{check-types}@(); \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. +Let \tcode{Is} be the pack of integral template arguments of +the \tcode{integer_sequence} specialization denoted by +\tcode{\exposid{indices-for}}. \pnum -\returns +\effects +Equivalent to: \begin{codeblock} -@\exposid{make-sender}@(@\exposid{write-env-t}@(), std::forward(env), std::forward(sndr)) +((void)get_completion_signatures<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)...>(), ...); \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} -\end{itemdescr} -Invocation of -\tcode{\exposid{impls-for}<\exposid{write-env-t}>::\exposid{get-env}} -returns an object \tcode{e} such that +\begin{note} +For any types \tcode{T} and \tcode{S}, and pack \tcode{E}, +let \tcode{e} be the expression +\tcode{\exposid{impls-for}::\exposid{check-types}()}. +Then exactly one of the following is \tcode{true}: \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).query(q)}. +\item \tcode{e} is ill-formed, or +\item the evaluation of \tcode{e} exits with an exception, or +\item \tcode{e} is a core constant expression. \end{itemize} - -\rSec2[exec.snd.concepts]{Sender concepts} +When \tcode{e} is a core constant expression, +the pack \tcode{S, E...} uniquely determines a set of completion signatures. +\end{note} +\end{itemdescr} \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 + struct @\exposidnc{basic-sender}@ : @\exposidnc{product-type}@ { // \expos + using sender_concept = sender_tag; + using @\exposidnc{indices-for}@ = index_sequence_for; // \expos - template - concept @\defexposconcept{is-sender}@ = // \expos - @\libconcept{derived_from}@; + decltype(auto) get_env() const noexcept { + auto& [_, data, ...child] = *this; + return @\exposid{impls-for}@::@\exposid{get-attrs}@(data, child...); + } - template - concept @\defexposconcept{enable-sender}@ = // \expos - @\exposconcept{is-sender}@ || - @\exposconcept{is-awaitable}@>>; // \ref{exec.awaitable} + 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> + static constexpr auto get_completion_signatures(); + }; +} +\end{codeblock} + +\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 \tcode{connect} member function of \exposid{basic-sender} is: +\begin{codeblock} +is_nothrow_constructible_v<@\exposid{basic-operation}@, Self, Rcvr> +\end{codeblock} + +\indexlibrarymember{get_completion_signatures}{\exposid{basic-sender}}% +\begin{itemdecl} +template + template<@\exposconcept{decays-to}@<@\exposid{basic-sender}@> Sndr, class... Env> + constexpr auto @\exposid{basic-sender}@::get_completion_signatures(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{Rcvr} be the type of a receiver whose +environment has type \tcode{E}, where +\tcode{E} is the first type in the list \tcode{Env..., env<>}. +Let \tcode{\placeholder{CHECK-TYPES}()} be the expression +\tcode{\exposid{impls-for}::template \exposid{check-types}<\linebreak{}Sndr, E>()}, and +let \tcode{CS} be a type determined as follows: + +\begin{itemize} +\item% +If \tcode{\exposid{CHECK-TYPES}()} is a core constant expression, +let \tcode{op} be an lvalue subexpression +whose type is \tcode{connect_result_t}. +Then \tcode{CS} is the specialization of \tcode{completion_signatures} +the set of whose template arguments +correspond to the set of completion operations +that are potentially evaluated\iref{basic.def.odr} +as a result of evaluating \tcode{op.start()}. + +\item% +Otherwise, \tcode{CS} is \tcode{completion_signatures<>}. +\end{itemize} + +\pnum +\constraints +\tcode{\exposid{CHECK-TYPES}()} is a well-formed expression. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{CHECK-TYPES}@(); +return CS(); +\end{codeblock} +\end{itemdescr} + +\pnum +\indexlibraryglobal{\exposid{overload-set}} +%%FIXME: Should this be in a namespace? +\begin{codeblock} +template +struct @\exposid{overload-set}@ : Fns... { + using Fns::operator()...; +}; +\end{codeblock} + +\pnum +\indexlibraryglobal{\exposid{not-a-sender}} +\indexlibrarymember{get_completion_signatures}{\exposid{not-a-sender}} +%%FIXME: Should this be in a namespace? +\begin{codeblock} +struct @\exposid{not-a-sender}@ { + using sender_concept = sender_tag; + + template + static consteval auto get_completion_signatures() -> completion_signatures<> { + throw @\placeholder{unspecified-exception}@(); + } +}; +\end{codeblock} + +\pnum +\indexlibraryglobal{\exposid{not-a-scheduler}}% +\indexlibrarymember{schedule}{\exposid{not-a-sender}}% +\begin{codeblock} +struct @\exposid{not-a-scheduler}@ { + using scheduler_concept = scheduler_tag; + + constexpr auto schedule() const noexcept { + return @\exposid{not-a-sender}@(); + } +}; +\end{codeblock} + +\pnum +\indexlibraryglobal{\exposid{decay-copyable-result-datums}} +%%FIXME: Should this be in a namespace? +\begin{codeblock} +constexpr void @\exposid{decay-copyable-result-datums}@(auto cs) { + cs.@\exposid{for-each}@([](Tag(*)(Ts...)) { + if constexpr (!(is_constructible_v, Ts> &&...)) + throw @\placeholder{unspecified-exception}@(); + }); +} +\end{codeblock} + +\begin{itemdecl} +template + decltype(auto) @\exposid{allocator-aware-forward}@(T&& obj, Context&& context); // \expos +\end{itemdecl} + +\begin{itemdescr} +\pnum +\exposid{allocator-aware-forward} is an exposition-only function template +used to either +create a new object of type \tcode{remove_cvref_t} from \tcode{obj} +or forward \tcode{obj} depending on whether an allocator is available. +If the environment associated with \tcode{context} provides an allocator +(i.e., the expression \tcode{get_allocator(get_env(context))} is valid), +let \exposid{alloc} be the result of this expression +and let \tcode{P} be \tcode{remove_cvref_t}. + +\pnum +\returns +\begin{itemize} +\item +If \exposid{alloc} is not defined, returns \tcode{std::forward(obj)}, +\item +otherwise if \tcode{P} is a specialization of \exposid{product-type}, +returns an object of type \tcode{P} whose elements are initialized using +\begin{codeblock} +make_obj_using_allocator(@\exposid{alloc}@, std::forward_like(e)) +\end{codeblock} +where \tcode{e} is the corresponding element of \tcode{obj}, +\item +otherwise, returns \tcode{make_obj_using_allocator

(\exposid{alloc}, std::forward(obj))}. +\end{itemize} +\end{itemdescr} + +\indexlibraryglobal{\exposid{call-with-default}} +\begin{itemdecl} +template + constexpr decltype(auto) @\exposid{call-with-default}@( + Fn&& fn, Default&& value, Args&&... args) noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{expr} be the expression +\tcode{std::forward(fn)(std::forward(args)...)} +if that expression is well-formed; +otherwise, it is \tcode{static_cast(std::forward(value))}. + +\pnum +\returns +\tcode{expr}. + +\pnum +\remarks +The expression in the \tcode{noexcept} clause is \tcode{noexcept(expr)}. +\end{itemdescr} + +\pnum +\indexlibraryglobal{\exposid{inline-attrs}}% +\begin{codeblock} +template +struct @\exposid{inline-attrs}@ { + @\seebelow@ +}; +\end{codeblock} + +\pnum +For a subexpression \tcode{env}, +\tcode{\exposid{inline-attrs}\{\}.query(get_completion_scheduler, env)} +is expres\-sion-equivalent to \tcode{get_scheduler(env)}. + +\pnum +For a subexpression \tcode{env}, +\tcode{\exposid{inline-attrs}\{\}.query(get_completion_domain, env)} +is expression-equivalent to \tcode{get_domain(env)}. + +\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 exposition-only concept \exposconcept{sender-to} 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. + +\indexlibraryglobal{\exposid{is-dependent-sender-helper}}% +\begin{codeblock} +namespace std::execution { + template + concept @\defexposconcept{is-constant}@ = true; // \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 + inline constexpr bool enable_sender = @\exposconcept{enable-sender}@; + + template + consteval bool @\exposidnc{is-dependent-sender-helper}@() try { // \expos + get_completion_signatures(); + return false; + } catch (dependent_sender_error&) { + return true; + } template concept @\deflibconcept{sender}@ = - bool(@\exposconcept{enable-sender}@>) && + enable_sender> && requires (const remove_cvref_t& sndr) { { get_env(sndr) } -> @\exposconcept{queryable}@; } && @\libconcept{move_constructible}@> && @\libconcept{constructible_from}@, Sndr>; - template> + 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}@; - }; + (sizeof...(Env) <= 1) && + (@\exposconcept{queryable}@ &&...) && + @\exposconcept{is-constant}@()>; + + template + concept @\deflibconcept{dependent_sender}@ = + @\libconcept{sender}@ && bool_constant<@\exposid{is-dependent-sender-helper}@()>::value; template - concept @\deflibconcept{sender_to}@ = + concept @\defexposconcept{sender-to}@ = // \expos @\libconcept{sender_in}@> && - @\libconcept{receiver_of}@>> && + @\exposconcept{receiver-of}@>> && requires (Sndr&& sndr, Rcvr&& rcvr) { connect(std::forward(sndr), std::forward(rcvr)); }; } \end{codeblock} +\pnum +For a type \tcode{Sndr}, if +\tcode{\libconcept{sender}} is \tcode{true} and +\tcode{\libconcept{dependent_sender}} is \tcode{false}, +then \tcode{Sndr} is a non-dependent sender\iref{exec.async.ops}. + \pnum Given a subexpression \tcode{sndr}, let \tcode{Sndr} be \tcode{decltype((sndr))} and @@ -1982,10 +2563,15 @@ 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. +\remarks +Pursuant to \ref{namespace.std}, +users may specialize \tcode{enable_sender} to +\tcode{true} for cv-unqualified program-defined types that +model \libconcept{sender}, and +\tcode{false} for types that do not. +Such specializations shall +be usable in constant expressions\iref{expr.const.init} and +have type \tcode{const bool}. \pnum The exposition-only concepts @@ -1997,15 +2583,22 @@ template using @\exposid{value-signature}@ = set_value_t(As...); // \expos + template + concept @\defexposconcept{sender-in-of-impl}@ = // \expos + @\libconcept{sender_in}@ && + @\exposid{MATCHING-SIG}@(SetValue, // see \ref{exec.general} + @\exposid{gather-signatures}@, + @\exposid{value-signature}@, + type_identity_t>); + template - concept @\defexposconcept{sender-in-of}@ = - @\libconcept{sender_in}@ && - @\exposid{MATCHING-SIG}@( // see \ref{exec.general} - set_value_t(Values...), - value_types_of_t); + concept @\defexposconcept{sender-in-of}@ = // \expos + @\exposconcept{sender-in-of-impl}@; template - concept @\defexposconcept{sender-of}@ = @\exposconcept{sender-in-of}@, Values...>; + concept @\defexposconcept{sender-of}@ = // \expos + @\exposconcept{sender-in-of-impl}@; } \end{codeblock} @@ -2077,6 +2670,14 @@ any necessary implicit conversions and materializations. \end{note} +Let \tcode{\exposid{GET-AWAITER}(c)} be +expression-equivalent to \tcode{\exposid{GET-AWAITER}(c, q)} +where \tcode{q} is an lvalue of +an unspecified empty class type \tcode{\placeholder{none-such}} that +lacks an \tcode{await_transform} member, and +where \tcode{coroutine_handle<\placeholder{none-such}>} behaves as +\tcode{coroutine_handle}. + \pnum Let \exposconcept{is-awaitable} be the following exposition-only concept: \begin{codeblock} @@ -2084,18 +2685,18 @@ template concept @\exposconcept{await-suspend-result}@ = @\seebelow@; // \expos - template + template concept @\defexposconcept{is-awaiter}@ = // \expos - requires (A& a, coroutine_handle h) { + requires (A& a, coroutine_handle h) { a.await_ready() ? 1 : 0; { a.await_suspend(h) } -> @\exposconcept{await-suspend-result}@; a.await_resume(); }; - template + template concept @\defexposconcept{is-awaitable}@ = // \expos - requires (C (*fc)() noexcept, Promise& p) { - { @\exposid{GET-AWAITER}@(fc(), p) } -> @\exposconcept{is-awaiter}@; + requires (C (*fc)() noexcept, Promise&... p) { + { @\exposid{GET-AWAITER}@(fc(), p...) } -> @\exposconcept{is-awaiter}@; }; } \end{codeblock} @@ -2113,7 +2714,9 @@ 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())}. +the type \tcode{decltype(\exposid{GET-AWAITER}(c, p).await_resume())} and +\tcode{\exposid{await-re\-sult-type}} denotes +the type \tcode{decltype(\exposid{GET-AWAITER}(c).await_resume())}. \pnum Let \exposid{with-await-transform} be the exposition-only class template: @@ -2133,8 +2736,9 @@ } template<@\exposconcept{has-as-awaitable}@ T> - decltype(auto) await_transform(T&& value) - noexcept(noexcept(std::forward(value).as_awaitable(declval()))) { + auto await_transform(T&& value) + noexcept(noexcept(std::forward(value).as_awaitable(declval()))) + -> decltype(std::forward(value).as_awaitable(declval())) { return std::forward(value).as_awaitable(static_cast(*this)); } }; @@ -2163,75 +2767,103 @@ its members need not be defined. \end{note} -\rSec2[exec.domain.default]{\tcode{execution::default_domain}} +\rSec2[exec.domain.indeterminate]{\tcode{execution::indeterminate_domain}} \pnum +\indexlibraryglobal{indeterminate_domain}% +\indexlibraryctor{indeterminate_domain}% \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 + struct indeterminate_domain { + indeterminate_domain() = default; + constexpr indeterminate_domain(auto&&) noexcept {} - 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) + template + static constexpr decltype(auto) transform_sender(Tag, Sndr&& sndr, const Env& env) noexcept(@\seebelow@); }; } \end{codeblock} -\indexlibrarymember{transform_sender}{default_domain}% +\indexlibrarymember{transform_sender}{indeterminate_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@); +template + static constexpr decltype(auto) transform_sender(Tag, Sndr&& sndr, const Env& env) + noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} \pnum -Let \tcode{e} be the expression +\mandates +For each type \tcode{D} in \tcode{Domains...}, +the expression \begin{codeblock} -tag_of_t().transform_sender(std::forward(sndr), env...) +D().transform_sender(Tag(), std::forward(sndr), env) \end{codeblock} -if that expression is well-formed; -otherwise, \tcode{std::forward(sndr)}. +is either ill-formed or has the same decayed type as +\tcode{default_domain().transform_sender(Tag(), std::forward(sndr), env)}. \pnum \returns -\tcode{e}. +\tcode{default_domain().transform_sender(Tag(), std::forward(sndr), env)}. \pnum \remarks -The exception specification is equivalent to \tcode{noexcept(e)}. +For a pack of types \tcode{Ds}, +\begin{codeblock} +common_type_t, indeterminate_domain> +\end{codeblock} +is \tcode{indeterminate_domain} +where \tcode{Us} is a pack that contains each type in +\tcode{Domains..., Ds...} except with duplicate types removed. +For a type \tcode{D} that is not a specialization of \tcode{indeterminate_domain}, +\tcode{common_type_t, D>} +is \tcode{D} if \tcode{Domains} is an empty pack, and +\tcode{common_type_t, indeterminate_domain>} +otherwise. \end{itemdescr} -\indexlibrarymember{transform_env}{default_domain}% +\rSec2[exec.domain.default]{\tcode{execution::default_domain}} + +\pnum +\begin{codeblock} +namespace std::execution { + struct @\libglobal{default_domain}@ { + template + static constexpr decltype(auto) transform_sender(Tag, Sndr&& sndr, const Env& env) + noexcept(@\seebelow@); + + 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> - constexpr @\exposconcept{queryable}@ decltype(auto) transform_env(Sndr&& sndr, Env&& env) noexcept; +template +constexpr decltype(auto) transform_sender(Tag, Sndr&& sndr, const Env& env) + noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{e} be the expression \begin{codeblock} -tag_of_t().transform_env(std::forward(sndr), std::forward(env)) +tag_of_t().transform_sender(Tag(), std::forward(sndr), env) \end{codeblock} if that expression is well-formed; -otherwise, \tcode{static_cast(std::forward(env))}. - -\pnum -\mandates -\tcode{noexcept(e)} is \tcode{true}. +otherwise, \tcode{static_cast(std::forward(sndr))}. \pnum \returns \tcode{e}. + +\pnum +\remarks +The exception specification is equivalent to \tcode{noexcept(e)}. \end{itemdescr} \indexlibrarymember{apply_sender}{default_domain}% @@ -2266,67 +2898,63 @@ \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) + template<@\libconcept{sender}@ Sndr, @\exposconcept{queryable}@ Env> + constexpr decltype(auto) transform_sender(Sndr&& sndr, const Env& env) noexcept(@\seebelow@); } \end{itemdecl} \begin{itemdescr} \pnum -Let \exposid{transformed-sndr} be the expression +For a subexpression \tcode{s}, +let \exposid{start-domain} be +\tcode{D()} where \tcode{D} is the decayed type of \tcode{get_domain(env)} +if that expression is well-formed, and +\tcode{default_domain} otherwise. + +\pnum +Let \tcode{\exposid{completion-domain}(s)} be +\tcode{D()} where \tcode{D} is the decayed type of +\tcode{get_completion_domain<>(get_env(s), env)} +if that is well-formed; +otherwise, \tcode{D} is \tcode{default_domain}. + +\pnum +Let \tcode{\exposid{transformed-sndr}(dom, tag, s)} be the expression \begin{codeblock} -dom.transform_sender(std::forward(sndr), env...) +dom.transform_sender(tag, s, env) \end{codeblock} if that expression is well-formed; otherwise, \begin{codeblock} -default_domain().transform_sender(std::forward(sndr), env...) +default_domain().transform_sender(tag, s, env) \end{codeblock} -Let \exposid{final-sndr} be the expression \exposid{transformed-sndr} -if \exposid{transformed-sndr} and \exposid{sndr} +Let \tcode{\exposid{transform-recurse}(dom, tag, s)} be +the expression \tcode{\exposid{transformed-sndr}(dom, tag, s)} +if\newline \tcode{\exposid{transformed-sndr}(dom, tag, s)} and \exposid{s} 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} +the expression \tcode{\exposid{transform-recurse}(dom2, tag, s2)}, where +\tcode{s2} is \tcode{\exposid{transformed-sender}(dom, tag, s)} and +\tcode{dom2} is \exposid{start-domain} if \tcode{tag} is \tcode{start}, and +\tcode{\exposid{completion-domain}(s2)} otherwise. -\begin{itemdescr} -\pnum -Let \tcode{e} be the expression +Let \exposid{tmp-sndr} be the expression \begin{codeblock} -dom.transform_env(std::forward(sndr), std::forward(env)) +@\exposid{transform-recurse}@(@\exposid{completion-domain}@(sndr), set_value, sndr) \end{codeblock} -if that expression is well-formed; otherwise, +and let \exposid{final-sndr} be the expression \begin{codeblock} -default_domain().transform_env(std::forward(sndr), std::forward(env)) +@\exposid{transform-recurse}@(@\exposid{start-domain}@, start, @\exposid{tmp-sndr}@) \end{codeblock} \pnum -\mandates -\tcode{noexcept(e)} is \tcode{true}. +\returns +\exposid{final-sndr}. \pnum -\returns -\tcode{e}. +\remarks +The exception specification is equivalent to +\tcode{noexcept(\exposid{final-sndr})}. \end{itemdescr} \rSec2[exec.snd.apply]{\tcode{execution::apply_sender}} @@ -2366,43 +2994,92 @@ \rSec2[exec.getcomplsigs]{\tcode{execution::get_completion_signatures}} +\indexlibraryglobal{get_completion_signatures}% +%%FIXME: Should this be in namespace std::execution? +\begin{itemdecl} +template + consteval auto get_completion_signatures() -> @\exposconcept{valid-completion-signatures}@ auto; +\end{itemdecl} + +\begin{itemdescr} \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-equivalent to -\tcode{(void(sndr), void(env), CS())} -except that \tcode{void(sndr)} and \tcode{void(env)} are -indeterminately sequenced, -where \tcode{CS} is: +Let $except$ be an rvalue subexpression of +an unspecified class type $Except$ such that +\tcode{\libconceptx{move_construc\-tible}{move_constructible}<$Except$> \&\& \libconcept{derived_from}<$Except$, exception>} +is \tcode{true}. +Let \tcode{\placeholder{CHECKED-COMPLSIGS}($e$)} be $e$ +if $e$ is a core constant expression whose +type satisfies \exposconcept{valid-completion-signatures}; +otherwise, it is the following expression: +\begin{codeblock} +(@$e$@, throw @$except$@, completion_signatures()) +\end{codeblock} +Let \tcode{\placeholder{get-complsigs}()} +be expression-equivalent to +\tcode{remove_reference_t::tem\-plate get_completion_signatures()}. +Let \tcode{NewSndr} be \tcode{Sndr} +if \tcode{sizeof...(Env) == 0} is \tcode{true}; +otherwise, \tcode{decltype($s$)} +where $s$ is the following expression: +\begin{codeblock} +transform_sender( + declval(), + declval()...) +\end{codeblock} + +\pnum +\constraints +\tcode{sizeof...(Env) <= 1} is \tcode{true}. + +\pnum +\effects +Equivalent to: \tcode{return $e$;} +where $e$ is expression-equivalent to the following: \begin{itemize} \item -\tcode{decltype(new_sndr.get_completion_signatures(env))} -if that type is well-formed, +\tcode{\placeholder{CHECKED-COMPLSIGS}(\placeholder{get-complsigs}())} +if \tcode{\placeholder{get-complsigs}()} +is a well-formed expression. \item -Otherwise, \tcode{remove_cvref_t::completion_signatures} -if that type is well-formed, +Otherwise, +\tcode{\placeholder{CHECKED-COMPLSIGS}(\placeholder{get-complsigs}())} +if \tcode{\placeholder{get-complsigs}()} +is a well-formed expression. \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} + @\exposid{SET-VALUE-SIG}@(@\exposid{await-result-type}@...>), // \ref{exec.snd.concepts} set_error_t(exception_ptr), set_stopped_t()> \end{codeblock} +if \tcode{\exposconcept{is-awaitable}...>} +is \tcode{true}. + +\item +Otherwise, +\tcode{(throw \placeholder{dependent-sender-error}(), completion_signatures())} +if \tcode{sizeof...(\linebreak{}Env) == 0} is \tcode{true}, +where \tcode{\placeholder{dependent-sender-error}} is +\tcode{dependent_sender_error} or +an unspecified type derived publicly and unambiguously from +\tcode{dependent_sender_error}. \item -Otherwise, \tcode{CS} is ill-formed. +Otherwise, +\tcode{(throw $except$, completion_signatures())}. \end{itemize} +\end{itemdescr} + +\pnum +Given a type \tcode{Env}, if +\tcode{completion_signatures_of_t} and +\tcode{completion_signatures_of_t} +are both well-formed, +the former shall be a superset of the latter, +with the difference corresponding to error or stopped completion operations. \pnum Let \tcode{rcvr} be an rvalue @@ -2434,9 +3111,7 @@ 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} +\tcode{transform_sender(\newline sndr, get_env(rcvr))} and let \tcode{DS} and \tcode{DR} be \tcode{decay_t} and \tcode{decay_t}, respectively. @@ -2479,7 +3154,7 @@ \begin{codeblock} namespace std::execution { struct @\exposid{operation-state-task}@ { // \expos - using operation_state_concept = operation_state_t; + using operation_state_concept = operation_state_tag; using promise_type = @\exposid{connect-awaitable-promise}@; explicit @\exposid{operation-state-task}@(coroutine_handle<> h) noexcept : coro(h) {} @@ -2502,7 +3177,7 @@ let \tcode{Sigs} name the type \begin{codeblock} completion_signatures< - @\exposid{SET-VALUE-SIG}@(V), // see \iref{exec.snd.concepts} + @\exposid{SET-VALUE-SIG}@(V), // see~\ref{exec.snd.concepts} set_error_t(exception_ptr), set_stopped_t()> \end{codeblock} @@ -2515,16 +3190,16 @@ auto fn = [&, fun]() noexcept { fun(std::forward(as)...); }; struct awaiter { - decltype(@\exposid{fn}@) @\exposid{fn}@; // \expos + decltype(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}@}; + return awaiter{fn}; } - @\exposid{operation-state-task}@ @\exposid{connect-awaitable}@(DS sndr, DR rcvr) requires @\libconcept{receiver_of}@ { + @\exposid{operation-state-task}@ @\exposid{connect-awaitable}@(DS sndr, DR rcvr) requires @\exposconcept{receiver-of}@ { exception_ptr ep; try { if constexpr (@\libconcept{same_as}@) { @@ -2553,9 +3228,31 @@ \item Otherwise, \tcode{\exposid{connect-awaitable}(new_sndr, rcvr)}. \end{itemize} - +Except that \tcode{rcvr} is evaluated only once. +The program is ill-formed, no diagnostic required, +if there exists an rvalue expression \tcode{rcvr2} such that: +\begin{itemize} +\item \tcode{decltype(rcvr2)} models \libconcept{receiver}, +\item \tcode{noexcept(rcvr2)} is \tcode{true}, +\item \tcode{is_same_v} is \tcode{true}, +\item \tcode{noexcept(execution::connect(sndr, rcvr))} is \tcode{true}, and +\item \tcode{noexcept(execution::connect(sndr, rcvr2))} +is well-formed and evaluates to \tcode{false}. +\end{itemize} +\begin{note} +This allows determination of whether \tcode{connect} throws +with only the context of the environment, +such as within \tcode{get_completion_signatures}. +\end{note} + \mandates -\tcode{\libconcept{sender} \&\& \libconcept{receiver}} is \tcode{true}. +The following are \tcode{true}: +\begin{itemize} +\item +\tcode{\libconcept{sender_in}>} +\item +\tcode{\exposconcept{receiver-of}>>} +\end{itemize} \rSec2[exec.factories]{Sender factories} @@ -2575,14 +3272,6 @@ \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 @@ -2617,7 +3306,7 @@ 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} +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} is specialized for \exposid{just-cpo} as follows: \begin{codeblock} namespace std::execution { @@ -2647,8 +3336,9 @@ \tcode{\exposid{make-sender}(read_env, q)}. \pnum -The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} is specialized for \tcode{read_env} as follows: +\indexlibraryglobal{\exposid{impls-for}<\exposid{decayed-typeof}>} \begin{codeblock} namespace std::execution { template<> @@ -2658,9 +3348,30 @@ @\exposid{TRY-SET-VALUE}@(rcvr, query(get_env(rcvr))); }; }; + + template + static consteval void @\exposid{check-types}@(); } \end{codeblock} +\indexlibrarymember{\exposid{check-types}}{\exposid{impls-for}<\exposid{decayed-typeof}>} +\begin{itemdecl} +template + static consteval void @\exposid{check-types}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{Q} be \tcode{decay_t<\exposid{data-type}>}. + +\pnum +\throws +An exception of type +\tcode{\placeholder{unspecified-exception}}\iref{exec.snd.general} if +the expression \tcode{Q()(env)} is ill-formed or has type \tcode{void}, where +\tcode{env} is an lvalue subexpression whose type is \tcode{Env}. +\end{itemdescr} + \rSec2[exec.adapt]{Sender adaptors} \rSec3[exec.adapt.general]{General} @@ -2684,17 +3395,34 @@ \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}. +\tcode{\exposid{FWD-ENV}(get_env(sndr))}\iref{exec.fwd.env} +except that the +\tcode{get_completion_scheduler<\exposid{completion-tag}>} and +\tcode{get_completion_domain<\exposid{completion-tag}>} +queries are handled as described in \ref{exec.snd.general}. \item A parent sender with more than one child sender has -an associated attributes object equal to \tcode{env<>\{\}}. +an associated attributes object equal to \tcode{env<>\{\}} +except that the +\tcode{get_completion_scheduler<\exposid{completion-tag}>} and +\tcode{get_completion_domain<\exposid{comple\-tion-tag}>} +queries are handled as described in \ref{exec.snd.general}. \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 +An adaptor whose child senders are all non-dependent\iref{exec.async.ops} +is itself non-dependent. +\item These requirements apply to any function that is selected by the implementation of the sender adaptor. +\item + \recommended +Implementations should use +the completion signatures of the adaptors +to communicate type errors to users and +to propagate any such type errors from child senders. \end{itemize} \pnum @@ -2709,6 +3437,7 @@ \rSec3[exec.adapt.obj]{Closure objects} +\indexlibrarymisc{\idxcode{operator"|}}{pipeable sender adaptor 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}. @@ -2736,7 +3465,7 @@ 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}. +where \tcode{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} @@ -2795,6 +3524,87 @@ the initializations of the bound argument entities of the result, as specified above, are all well-formed. +\rSec3[exec.write.env]{\tcode{execution::write_env}} + +\pnum +\tcode{write_env} is a sender adaptor +that accepts a sender and a queryable object, and +that returns a sender 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} object +to the result of \tcode{get_env(rcvr)}. + +\pnum +\tcode{write_env} is a customization point object. +For some subexpressions \tcode{sndr} and \tcode{env}, +if \tcode{decltype((sndr))} does not satisfy \libconcept{sender} or +if \tcode{decltype((env))} does not satisfy \exposconcept{queryable}, +the expression \tcode{write_env(sndr, env)} is ill-formed. +Otherwise, it is expression-equivalent to +\tcode{\exposid{make-sender}(write_env, env, sndr)}. + +\pnum +Let \exposid{write-env-t} denote the type \tcode{decltype(auto(write_env))}. +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \exposid{write-env-t} as follows: +\indexlibraryglobal{\exposid{impls-for}<\exposid{write-env-t}>} +\begin{codeblock} +template<> +struct @\exposid{impls-for}@<@\exposid{write-env-t}@> : @\exposid{default-impls}@ { + static constexpr auto @\exposid{join-env}@(const auto& state, const auto& env) noexcept { + return @\seebelow@; + } + + static constexpr auto @\exposid{get-env}@ = + [](auto, const auto& state, const auto& rcvr) noexcept { + return @\exposid{join-env}@(state, @\exposid{FWD-ENV}@(get_env(rcvr))); + }; + + template + static consteval void @\exposid{check-types}@(); +}; +\end{codeblock} + +\pnum +Invocation of +\tcode{\exposid{impls-for}<\exposid{write-env-t}>::\exposid{join-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{env.query(q)}. +\end{itemize} + +\pnum +For a type \tcode{Sndr} and a pack of types \tcode{Env}, +let \tcode{State} be \tcode{\exposid{data-type}} and +let \tcode{JoinEnv} be the pack +\tcode{decltype(\exposid{join-env}(declval(), \exposid{FWD-ENV}(declval())))}. +Then \tcode{\exposid{impls-for}<\exposid{write-env-\brk{}t}>::\exposid{check-types}()} +is expression-equivalent to +\tcode{get_completion_signatures<\exposid{child-\linebreak{}type}, JoinEnv...>()}. + +\rSec3[exec.unstoppable]{\tcode{execution::unstoppable}} + +\pnum +\tcode{unstoppable} is a sender adaptor +that connects its inner sender +with a receiver that has the execution environment of the outer receiver +but with an object of type \tcode{never_stop_token} +as the result of the \tcode{get_stop_token query}. + +\pnum +For a subexpression \tcode{sndr}, +\tcode{unstoppable(sndr)} is expression-equivalent to +\tcode{write_env(sndr, prop(get_stop_token, never_stop_token\{\}))}. + \rSec3[exec.starts.on]{\tcode{execution::starts_on}} \pnum @@ -2812,38 +3622,24 @@ \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. +\tcode{\exposid{make-sender}(starts_on, sch, sndr)}. \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: +then the expression +\tcode{starts_on.transform_sender(set_value, out_sndr, env)} is ill-formed; otherwise +\tcode{starts_on.transform_sender(set_value, out_sndr, env)} is equivalent to: \begin{codeblock} auto&& [_, sch, sndr] = out_sndr; return let_value( - schedule(sch), + continues_on(just(), 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 @@ -2863,132 +3659,46 @@ \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 +\tcode{continues_on} 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. +The name \tcode{continues_on} 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. +\tcode{continues_on(sndr, sch)} 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. +the expression \tcode{continues_on(sndr, sch)} is expression-equivalent to +\tcode{\exposid{make-sender}(continues_on, sch, schedule_from(sndr))}. \pnum -The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} -is specialized for \tcode{schedule_from_t} as follows: +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \tcode{continues_on_t} as follows: +\indexlibraryglobal{\exposid{impls-for}}% \begin{codeblock} namespace std::execution { template<> - struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { - static constexpr auto @\exposid{get-attrs}@ = @\seebelow@; + 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-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))); + template + static consteval void @\exposid{check-types}@(); + }; } \end{codeblock} \pnum -The member \tcode{\exposid{impls-for}::\exposid{get-state}} +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> { - + requires @\libconcept{sender_in}@<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(env_of_t)> { auto& [_, sch, child] = sndr; using sched_t = decltype(auto(sch)); @@ -3010,6 +3720,23 @@ } \end{codeblock} +\indexlibrarymember{\exposid{check-types}}{\exposid{impls-for}} +\begin{itemdecl} +template + static consteval void @\exposid{check-types}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +get_completion_signatures>, @\exposid{FWD-ENV-T}@(Env)...>(); +auto cs = get_completion_signatures<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)...>(); +@\exposid{decay-copyable-result-datums}@(cs); // see \ref{exec.snd.expos} +\end{codeblock} +\end{itemdescr} + \pnum Objects of the local class \exposid{state-type} can be used to initialize a structured binding. @@ -3017,12 +3744,20 @@ \pnum Let \tcode{Sigs} be a pack of the arguments to the \tcode{completion_signatures} specialization -named by \tcode{completion_signatures_of_t, 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}}. +named by \tcode{completion_signatures_of_t<\exposid{child-type}, \exposid{FWD-ENV-T}(env_of_t)>}. +Let \exposid{as-tuple} be an alias template such that +\tcode{\exposid{as-tuple}} denotes +the type \tcode{\exposid{decayed-tuple}}, and +let \exposid{is-no\-throw-decay-copy-sig} be a variable template such that +\tcode{auto(\exposid{is-nothrow-decay-copy-sig})} is +a constant expression of type \tcode{bool} and +equal to \tcode{(is_nothrow_constructible_v, Args> \&\& ...)}. +Let \exposid{error-completion} be a pack consisting of +the type \tcode{set_error_t(exception_ptr)} +if \tcode{(\exposid{is-nothrow-decay-copy-sig} \&\&...)} is \tcode{false}, +and an empty pack otherwise. Then \tcode{variant_t} denotes -the type \tcode{variant...>}, +the type \tcode{variant..., \exposid{error-completion}...>}, except with duplicate types removed. \pnum @@ -3030,7 +3765,7 @@ \begin{codeblock} namespace std::execution { struct @\exposid{receiver-type}@ { - using receiver_concept = receiver_t; + using receiver_concept = receiver_tag; @\exposid{state-type}@* @\exposid{state}@; // \expos void set_value() && noexcept { @@ -3067,21 +3802,20 @@ otherwise, \tcode{false}. \pnum -The member \tcode{\exposid{impls-for}::\exposid{complete}} +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; + constexpr bool nothrow = (is_nothrow_constructible_v, Args> && ...); try { state.@\exposid{async-result}@.template emplace(Tag(), std::forward(args)...); } catch (...) { - if constexpr (!nothrow) { - set_error(std::move(rcvr), current_exception()); - return; - } + if constexpr (!nothrow) + state.@\exposid{async-result}@.template emplace>(set_error, current_exception()); } start(state.@\exposid{op-state}@); }; @@ -3089,7 +3823,7 @@ \pnum Let \tcode{out_sndr} be a subexpression denoting -a sender returned from \tcode{schedule_from(sch, sndr)} or one equal to such, +a sender returned from \tcode{continues_on_t(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} @@ -3104,6 +3838,21 @@ an error completion on \tcode{out_rcvr} shall be executed on an unspecified execution agent. +\rSec3[exec.schedule.from]{\tcode{execution::schedule_from}} + +\pnum +The name \tcode{schedule_from} denotes a customization point object. +For some subexpression \tcode{sndr}, +if \tcode{decltype((\brk{}sndr))} does not satisfy \libconcept{sender}, +\tcode{schedule_from(sndr)} is ill-formed. +Otherwise, +the expression \tcode{schedule_from(sndr)} is expression-equivalent to +\tcode{\exposid{make-sender}(schedule_from, \{\}, sndr)}. +\begin{note} +\tcode{schedule_from} is used by schedulers to control +how to transition off of their schedulers' associated execution contexts. +\end{note} + \rSec3[exec.on]{\tcode{execution::on}} \pnum @@ -3130,7 +3879,7 @@ \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 true: +\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 @@ -3145,13 +3894,8 @@ \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. +the expression \tcode{on(sch, sndr)} is expression-equivalent to +\tcode{\exposid{make-sender}(on, sch, sndr)}. \pnum For subexpressions \tcode{sndr}, \tcode{sch}, and \tcode{closure}, if @@ -3164,96 +3908,36 @@ \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. +otherwise, it is expression-equivalent to +\tcode{\exposid{make-sender}(\brk{}on, \exposid{product-type}\{sch, closure\}, sndr)}. \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} +then the expression \tcode{on.transform_sender(set_value, out_sndr, env)} is ill-formed. \pnum -The expression \tcode{on.transform_sender(out_sndr, env)} +Otherwise, the expression \tcode{on.transform_sender(set_value, 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)); - } + auto orig_sch = @\exposid{call-with-default}@(get_start_scheduler, @\exposid{not-a-scheduler}@(), env); + 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)); - } + auto orig_sch = @\exposid{call-with-default}@( + get_completion_scheduler, @\exposid{not-a-scheduler}@(), get_env(child), env); + return continues_on( + std::forward_like(closure)(continues_on(std::forward_like(child), sch)), + orig_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 @@ -3266,10 +3950,11 @@ Calling \tcode{start(op)} shall \begin{itemize} \item -remember the current scheduler, \tcode{get_scheduler(get_env(rcvr))}; +remember the current scheduler, +which is obtained by \tcode{get_start_scheduler(get_env(rcvr))}; \item start \tcode{sndr} on an execution agent belonging to -sch's associated execution resource; +\tcode{sch}'s associated execution resource; \item upon \tcode{sndr}'s completion, transfer execution back to the execution resource @@ -3294,17 +3979,14 @@ \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} +which is +\tcode{get_completion_scheduler(get_env(\newline sndr), get_env(out_rcvr))}; \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; +owned by \tcode{sch}'s associated execution resource; \item forward \tcode{sndr}'s async result as if by connecting and starting a sender \tcode{closure(S)}, @@ -3341,18 +4023,16 @@ \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. +the expression \tcode{\exposid{then-cpo}(sndr, f)} is expression-equivalent to +\tcode{\exposid{make-sender}(\exposid{then-cpo}, f, sndr)}. \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} +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} is specialized for \exposid{then-cpo} as follows: +\indexlibraryglobal{\exposid{impls-for}<\exposid{decayed-typeof}<\exposid{then-cpo}>>} \begin{codeblock} namespace std::execution { template<> @@ -3360,17 +4040,40 @@ static constexpr auto @\exposid{complete}@ = [] (auto, auto& fn, auto& rcvr, Tag, Args&&... args) noexcept -> void { - if constexpr (@\libconcept{same_as}@>) { + 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)...); } }; + + template + static consteval void @\exposid{check-types}@(); }; } \end{codeblock} +\indexlibrarymember{\exposid{check-types}}{\exposid{impls-for}<\exposid{decayed-typeof}<\exposid{then-cpo}>>} +\begin{itemdecl} +template + static consteval void @\exposid{check-types}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto cs = get_completion_signatures<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)...>(); +auto fn = [](@\exposid{decayed-typeof}@<@\exposid{set-cpo}@>(*)(Ts...)) { + if constexpr (!@\libconcept{invocable}@>, Ts...>) + throw @\placeholder{unspecified-exception}@(); +}; +cs.@\exposid{for-each}@(@\exposid{overload-set}@{fn, [](auto){}}); +\end{codeblock} +\end{itemdescr} + \pnum The expression \tcode{\exposid{then-cpo}(sndr, f)} has undefined behavior unless it returns a sender \tcode{out_sndr} that @@ -3399,14 +4102,16 @@ \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 +Let \exposid{let-tag} denote a unique, empty class type for each of +\tcode{let_value}, \tcode{let_error}, and \tcode{let_stopped}. +For subexpressions \tcode{sndr} and \tcode{env}, +let \tcode{\exposid{let-env}(sndr, env)} be expression-equivalent to the first well-formed expression below: \begin{itemize} \item -\tcode{SCHED-ENV(get_completion_scheduler<\exposid{decayed-typeof}<\exposid{set-cpo}>>(get_env(sndr)))} +\tcode{\exposid{SCHED-ENV}(get_completion_scheduler<\exposid{decayed-typeof}<\exposid{set-cpo}>>(get_env(sndr),\newline \exposid{FWD-ENV}(env)))} \item -\tcode{\exposid{MAKE-ENV}(get_domain, get_domain(get_env(sndr)))} +\tcode{\exposid{MAKE-ENV}(get_domain, get_completion_domain<\exposid{decayed-typeof}<\exposid{set-cpo}>>(get_env(sndr),\newline \exposid{FWD-ENV}(env)))} \item \tcode{(void(sndr), env<>\{\})} \end{itemize} @@ -3424,24 +4129,40 @@ \pnum Otherwise, -the expression \tcode{\exposid{let-cpo}(sndr, f)} is expression-equivalent to: +the expression \tcode{\exposid{let-cpo}(sndr, f)} is expression-equivalent to +\tcode{\exposid{make-sender}(\exposid{let-cpo}, f, sndr)}. + +\pnum +Let \exposid{let-data} denote the following exposition-only class template: \begin{codeblock} -transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(@\exposid{let-cpo}@, f, sndr)) +template +struct @\exposid{let-data}@ { + Sndr @\exposid{sndr}@; // \expos + Fn @\exposid{fn}@; // \expos +}; \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: +Then let the expression \tcode{\exposid{let-cpo}.transform_sender(s, es...)} +be expression-equivalent to: \begin{codeblock} -namespace std::execution { - template - void @\exposid{let-bind}@(State& state, Rcvr& rcvr, Args&&... args); // \expos +@\exposid{make-sender}@(@\exposid{let-tag}@{}, @\exposid{let-data}@{s.template @\exposid{get}@<2>(), s.template @\exposid{get}@<1>()}) +\end{codeblock} +except that \tcode{s} is evaluated only once. +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \exposid{let-tag} as follows: +\indexlibraryglobal{\exposid{impls-for}<\exposid{decayed-typeof}<\exposid{let-cpo}>>} +\begin{codeblock} +namespace std::execution { template<> - struct @\exposid{impls-for}@<@\exposid{decayed-typeof}@<@\exposid{let-cpo}@>> : @\exposid{default-impls}@ { + struct @\exposid{impls-for}@<@\exposid{let-tag}@> : @\exposid{default-impls}@ { static constexpr auto @\exposid{get-state}@ = @\seebelow@; - static constexpr auto @\exposid{complete}@ = @\seebelow@; + static constexpr auto @\exposid{start}@ = @\seebelow@; + + template + static consteval void @\exposid{check-types}@(); }; } \end{codeblock} @@ -3452,7 +4173,7 @@ namespace std::execution { template struct @\exposid{receiver2}@ { - using receiver_concept = receiver_t; + using receiver_concept = receiver_tag; template void set_value(Args&&... args) && noexcept { @@ -3483,42 +4204,148 @@ \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)}. +given a query object \tcode{q} and a pack of subexpressions \tcode{args}, +the expression \tcode{e.query(q, args...)} is expression-equivalent +to \tcode{\exposid{env}.query(q, args...)} if that expression is valid; +otherwise, +if the type of \tcode{q} satisfies \exposconcept{forwarding-query}, +\tcode{e.query(q, args...)} is expression-equivalent +to \tcode{get_env(\exposid{rcvr}).query\newline (q, args...)}; +otherwise, +\tcode{e.query(q, args...)} is ill-formed. \end{itemize} +\indexlibrarymember{\exposid{check-types}}{\exposid{impls-for}<\exposid{decayed-typeof}<\exposid{let-cpo}>>} +\begin{itemdecl} +template + static consteval void @\exposid{check-types}@(); +\end{itemdecl} + +\begin{itemdescr} \pnum -\tcode{\exposid{impls-for}<\exposid{decayed-typeof}<\exposid{let-cpo}>>::\exposid{get-state}} -is initialized with a callable object equivalent to the following: +\effects +Equivalent to: \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), {}, {}}; -} +using LetFn = remove_cvref_t<@\exposid{data-type}@>; +auto cs = get_completion_signatures<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)...>(); +auto fn = [](@\exposid{decayed-typeof}@<@\exposid{set-cpo}@>(*)(Ts...)) { + if constexpr (!@\placeholder{is-valid-let-sender}@) // \seebelow + throw @\placeholder{unspecified-exception}@(); +}; +cs.@\exposid{for-each}@(@\exposid{overload-set}@(fn, [](auto){})); +\end{codeblock} +where \tcode{\placeholder{is-valid-let-sender}} is \tcode{true} if and only if +all of the following are \tcode{true}: +\begin{itemize} +\item \tcode{(\libconcept{constructible_from}, Ts> \&\&...)} +\item \tcode{\libconcept{invocable}\&...>} +\item \tcode{\libconcept{sender}\&...>>} +\item% +\tcode{sizeof...(Env) == 0 || \libconcept{sender_in}\&...>, \placeholder{env-t}\linebreak{}...>} +\end{itemize} +where \tcode{\placeholder{env-t}} is the pack +\tcode{decltype(\exposid{JOIN-ENV}(\exposid{let-env}(declval<\exposid{child-type}>(), declval<\brk{}Env>()), \exposid{FWD-ENV}(declval())))}. +\end{itemdescr} + +\pnum +Let \exposid{let-state} denote the following exposition-only class template: +\begin{codeblock} +template +struct @\exposid{let-state}@ { + using @\exposidnc{env_t}@ = decltype(@\exposidnc{let-env}@(declval(), get_env(declval()))); // \expos + Fn @\exposidnc{fn}@; // \expos + env_t @\exposidnc{env}@; // \expos + ArgsVariant @\exposidnc{args}@; // \expos + OpsVariant @\exposidnc{ops}@; // \expos + + template + constexpr void @\exposid{impl}@(Rcvr& rcvr, Tag tag, Ts&&... ts) noexcept { // \expos + using args_t = @\exposid{decayed-tuple}@; + using receiver_type = @\exposid{receiver2}@; + using sender_type = apply_result_t; + if constexpr (is_same_v) { + try { + auto& tuple = @\exposid{args}@.template emplace(std::forward(ts)...); + @\exposid{ops}@.template emplace(); + auto&& sndr = apply(std::move(@\exposid{fn}@), tuple); + using op_t = connect_result_t; + auto mkop2 = [&] { + return connect(std::forward(sndr), + receiver_type{@\exposid{rcvr}@, @\exposid{env}@}); + }; + auto& op = @\exposid{ops}@.template emplace(@\exposid{emplace-from}@{mkop2}); + start(op); + } catch (...) { + constexpr bool nothrow = + is_nothrow_constructible_v && + is_nothrow_applicable_v && + noexcept(connect(declval(), receiver_type{@\exposid{rcvr}@, @\exposid{env}@})); + if constexpr (!nothrow) { + set_error(std::move(@\exposid{rcvr}@), current_exception()); + } + } + } else { + tag(std::move(@\exposid{rcvr}@), std::forward(ts)...); + } + } + + struct @\exposid{receiver}@ { // \expos + @\exposid{let-state}@& state; // \expos + Rcvr& @\exposid{rcvr}@; // \expos + + using receiver_concept = receiver_tag; + + template + constexpr void set_value(Args&&... args) noexcept { + @\exposid{state}@.@\exposid{impl}@(@\exposid{rcvr}@, execution::set_value, std::forward(args)...); + } + template + constexpr void set_error(Args&&... args) noexcept { + @\exposid{state}@.@\exposid{impl}@(@\exposid{rcvr}@, execution::set_error, std::forward(args)...); + } + template + constexpr void set_stopped(Args&&... args) noexcept { + @\exposid{state}@.@\exposid{impl}@(@\exposid{rcvr}@, execution::set_stopped, std::forward(args)...); + } + + constexpr env_of_t get_env() const noexcept { + return execution::get_env(@\exposid{rcvr}@); + } + }; + + using @\exposidnc{op_t}@ = connect_result_t; // \expos + + constexpr @\exposidnc{let-state}@(Sndr&& sndr, Fn fn, Rcvr& rcvr) // \expos + : @\exposid{fn}@(std::move(fn)), @\exposid{env}@(@\exposid{let-env}@(sndr, get_env(rcvr))), + @\exposid{ops}@(in_place_type<@\exposid{op_t}@>, std::forward(sndr), @\exposid{receiver}@{*this, rcvr}) {} +}; +\end{codeblock} + +\pnum +\tcode{\exposid{impls-for}<\exposid{let-tag}>::\exposid{get-state}} +is initialized with a callable object equivalent to the following: +\begin{codeblock} +[](Sndr&& sndr, Rcvr& rcvr) requires @\seebelow@ { + auto& [_, data] = sndr; + auto& [child, fn] = data; + using child_t = decltype(std::forward_like(child)); + using fn_t = decay_t; + using args_variant_t = @\seebelow@; + using ops_variant_t = @\seebelow@; + using state_t = @\exposid{let-state}@<@\exposid{decayed-typeof}@<@\exposid{set-cpo}@>, child_t, fn_t, Rcvr, + args_variant_t, ops_variant_t>; + return state_t(std::forward_like(child), std::forward_like(fn), @\exposid{rcvr}@); +} \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>}. +\tcode{completion_signatures_of_t<\exposid{child-type}, \exposid{FWD-ENV-T}(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 +such that \tcode{\exposid{as-tuple}} denotes the type \tcode{\exposid{decayed-tuple}}. Then \tcode{args_variant_t} denotes the type \tcode{variant...>} @@ -3528,11 +4355,13 @@ 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 \tcode{\exposid{call-result-t}\&...>}. +Then \tcode{ops_variant_t} denotes the type \begin{codeblock} -variant, @\exposid{receiver2}@>...> +variant, + connect_result_t<@\exposid{as-sndr2}@, @\exposid{receiver2}@>...> \end{codeblock} except with duplicate types removed. @@ -3542,44 +4371,14 @@ 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}} +\tcode{\exposid{impls-for}<\exposid{let-tag}>::\exposid{start}} 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)...); - } - } +[](State& state, Rcvr&) noexcept { + start(get(state.@\exposid{ops}@)); +} \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 @@ -3600,54 +4399,149 @@ propagates the other completion operations sent by \tcode{sndr}. \end{itemize} -\rSec3[exec.bulk]{\tcode{execution::bulk}} +\rSec3[exec.bulk]{\tcode{execution::bulk}, \tcode{execution::bulk_chunked}, and \tcode{execution::bulk_unchunked}} \pnum -\tcode{bulk} runs a task repeatedly for every index in an index space. +\tcode{bulk}, \tcode{bulk_chunked}, and \tcode{bulk_unchunked} +run 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))}. +\pnum +The names \tcode{bulk}, \tcode{bulk_chunked}, and \tcode{bulk_unchunked} +denote pipeable sender adaptor objects. +Let \tcode{\placeholder{bulk-algo}} be either +\tcode{bulk}, \tcode{bulk_chunked}, or \tcode{bulk_unchunked}. +For subexpressions \tcode{sndr}, \tcode{policy}, \tcode{shape}, and \tcode{f}, +let +\tcode{Policy} be \tcode{remove_cvref_t}, +\tcode{Shape} be \tcode{decltype(auto(shape))}, and +\tcode{Func} be \tcode{decay_t}. If \begin{itemize} \item \tcode{decltype((sndr))} does not satisfy \libconcept{sender}, or \item +\tcode{is_execution_policy_v} is \tcode{false}, or +\item \tcode{Shape} does not satisfy \libconcept{integral}, or \item -\tcode{decltype((f))} does not satisfy \exposconcept{movable-value}, +\tcode{Func} does not model \libconcept{copy_constructible}, \end{itemize} -\tcode{bulk(sndr, shape, f)} is ill-formed. +\tcode{\placeholder{bulk-algo}(sndr, policy, shape, f)} is ill-formed. \pnum Otherwise, -the expression \tcode{bulk(sndr, shape, f)} is expression-equivalent to: +the expression \tcode{\placeholder{bulk-algo}(sndr, policy, shape, f)} +is expression-equivalent to: +\begin{codeblock} +@\exposid{make-sender}@(@\placeholder{bulk-algo}@, @\exposid{product-type}@<@\seebelow@, Shape, Func>{policy, shape, f}, sndr) +\end{codeblock} +The first template argument of \exposid{product-type} is \tcode{Policy} +if \tcode{Policy} models \libconcept{copy_constructible}, and +\tcode{const Policy\&} otherwise. +\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{bulk.transform_sender(set_value, sndr, env)} is ill-formed; +otherwise, it is equivalent to: \begin{codeblock} -transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(bulk, @\exposid{product-type}@{shape, f}, sndr)) +auto [_, data, child] = sndr; +auto& [policy, shape, f] = data; +auto new_f = [func = std::move(f)](Shape begin, Shape end, auto&&... vs) + noexcept(noexcept(f(begin, vs...))) { + while (begin != end) func(begin++, vs...); +} +return bulk_chunked(std::move(child), policy, shape, std::move(new_f)); \end{codeblock} -except that \tcode{sndr} is evaluated only once. +\begin{note} +This causes the \tcode{bulk(sndr, policy, shape, f)} sender to be +expressed in terms of \tcode{bulk_chunked(sndr, policy, shape, f)} when +it is connected to a receiver whose +execution domain does not customize \tcode{bulk}. +\end{note} \pnum -The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} -is specialized for \tcode{bulk_t} as follows: +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \tcode{bulk_chunked_t} as follows: +\indexlibraryglobal{\exposid{impls-for}} \begin{codeblock} namespace std::execution { template<> - struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { static constexpr auto @\exposid{complete}@ = @\seebelow@; + + template + static consteval void @\exposid{check-types}@(); }; } \end{codeblock} +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& [policy, shape, f] = state; + constexpr bool nothrow = noexcept(f(auto(shape), auto(shape), args...)); + @\exposid{TRY-EVAL}@(rcvr, [&]() noexcept(nothrow) { + f(static_cast(0), auto(shape), args...); + Tag()(std::move(rcvr), std::forward(args)...); + }()); + } else { + Tag()(std::move(rcvr), std::forward(args)...); + } + } +\end{codeblock} +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), auto(shape), args...)} is well-formed. + +\begin{itemdecl} +template + static consteval void @\exposid{check-types}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto cs = get_completion_signatures<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)...>(); +auto fn = [](set_value_t(*)(Ts...)) { + using data_type = @\exposid{data-type}@; + if constexpr (!@\libconcept{invocable}@&, + remove_cvref_t<@\exposid{data-type}@>, Ts&...>) + throw @\placeholder{unspecified-exception}@(); +}; +cs.@\exposid{for-each}@(@\exposid{overload-set}@(fn, [](auto){})); +\end{codeblock} +\end{itemdescr} \pnum -The member \tcode{\exposid{impls-for}::\exposid{complete}} +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \tcode{bulk_unchunked_t} as follows: +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { + static constexpr auto @\exposid{complete}@ = @\seebelow@; + + template + static consteval void @\exposid{check-types}@(); + }; +} +\end{codeblock} +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@ { + (Index, State& state, Rcvr& rcvr, Tag, Args&&... args) noexcept + -> void requires @\seebelow@ { if constexpr (@\libconcept{same_as}@) { - auto& [shape, f] = state; + auto& [policy, 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) { @@ -3660,523 +4554,277 @@ } } \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. +\indexlibrarymember{\exposid{check-types}}{\exposid{impls-for}} +\begin{itemdecl} +template + static consteval void @\exposid{check-types}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto cs = get_completion_signatures<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)...>(); +auto fn = [](set_value_t(*)(Ts...)) { + using data_type = @\exposid{data-type}@; + if constexpr (!@\libconcept{invocable}@&, + remove_cvref_t<@\exposid{data-type}@>, Ts&...>) + throw @\placeholder{unspecified-exception}@(); +}; +cs.@\exposid{for-each}@(@\exposid{overload-set}@(fn, [](auto){})); +\end{codeblock} +\end{itemdescr} + \pnum Let the subexpression \tcode{out_sndr} denote -the result of the invocation \tcode{bulk(sndr, shape, f)} or +the result of the invocation +\tcode{\placeholder{bulk-algo}(sndr, policy, 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, +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 +If \tcode{sndr} has a successful completion, where +\tcode{args} is a pack of lvalue subexpressions +referring to the value completion result datums of \tcode{sndr}, or +decayed copies of those values if they model \libconcept{copy_constructible}, +then: + + \begin{itemize} + \item + If \tcode{out_sndr} also completes successfully, then: + + \begin{itemize} + \item + for \tcode{bulk}, + invokes \tcode{f($i$, args...)} for every $i$ of type \tcode{Shape} + from \tcode{0} to \tcode{shape}; + + \item + for \tcode{bulk_unchunked}, + invokes \tcode{f($i$, args...)} for every $i$ of type \tcode{Shape} + from \tcode{0} to \tcode{shape}; + + \recommended + The underlying scheduler should execute each iteration + on a distinct execution agent. + + \item + for \tcode{bulk_chunked}, + invokes \tcode{f($b$, $e$, args...)} zero or more times + with pairs of $b$ and $e$ of type \tcode{Shape} + in range \crange{\tcode{0}}{\tcode{shape}}, + such that $b < e$ and + for every $i$ of type \tcode{Shape} from \tcode{0} to \tcode{shape}, + there is exactly one invocation with a pair $b$ and $e$, + such that $i$ is in the range \range{$b$}{$e$}. + \end{itemize} + + \item + If \tcode{out_sndr} completes with \tcode{set_error(rcvr, eptr)}, then + the asynchronous operation may invoke a subset of + the invocations of \tcode{f} + before the error completion handler is called, and + \tcode{eptr} is an \tcode{exception_ptr} containing either: + \begin{itemize} + \item + an exception thrown by an invocation of \tcode{f}, or + \item + a \tcode{bad_alloc} exception if + the implementation fails to allocate required resources, or + \item + an exception derived from \tcode{runtime_error}. + \end{itemize} + + \item + If \tcode{out_sndr} completes with \tcode{set_stopped(rcvr)}, then + the asynchronous operation may invoke a subset of + the invocations of \tcode{f} + before the stopped completion handler. + \end{itemize} + +\item +If \tcode{sndr} does not complete with \tcode{set_value}, then +the completion is forwarded to \tcode{recv}. + \item -propagates all completion operations sent by \tcode{sndr}. +For \tcode{\placeholder{bulk-algo}}, +the parameter \tcode{policy} describes +the manner in which +the execution of the asynchronous operations corresponding to these algorithms +may be parallelized and +the manner in which +%%FIXME: Should this be "apply to f"? +they apply \tcode{f}. +Permissions and requirements +on parallel algorithm element access functions\iref{algorithms.parallel.exec} +apply to \tcode{f}. \end{itemize} -\rSec3[exec.split]{\tcode{execution::split}} - \pnum -\tcode{split} adapts an arbitrary sender -into a sender that can be connected multiple times. +\begin{note} +The asynchronous operation corresponding to +\tcode{\placeholder{bulk-algo}(sndr, policy, shape, f)} +can complete with \tcode{set_stopped} if cancellation is requested or +ignore cancellation requests. +\end{note} -\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.} +\rSec3[exec.when.all]{\tcode{execution::when_all}} \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. +\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 -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} +The names \tcode{when_all} and \tcode{when_all_with_variant} denote +customization point objects. +Let \tcode{sndrs} be a pack of subexpressions and +let \tcode{Sndrs} be a pack of the types \tcode{decltype((sndrs))...}. +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}. +\end{itemize} \pnum -Let \exposid{local-state} denote the following exposition-only class template: +The expression \tcode{when_all(sndrs...)} is expression-equivalent to +\tcode{\exposid{make-sender}(when_all, \{\}, sndrs...)}. +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \tcode{when_all_t} as follows: +\indexlibraryglobal{\exposid{impls-for}} \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; + template<> + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { + 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@; - private: - optional<@\exposid{on-stop-callback}@> @\exposid{on_stop}@; // \expos - @\exposid{shared-state}@* @\exposid{sh_state}@; // \expos - Rcvr* @\exposid{rcvr}@; // \expos + template + static consteval void @\exposid{check-types}@(); }; } \end{codeblock} -\begin{itemdecl} -@\exposid{local-state}@(Sndr&& sndr, Rcvr& rcvr) noexcept; -\end{itemdecl} - -\begin{itemdescr} \pnum -\effects -Equivalent to: +Let \exposid{make-when-all-env} be +the following exposition-only function template: +\indexlibraryglobal{\exposid{make-when-all-env}} +%%FIXME: Should this be in namespace std::execution? \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); +template + constexpr auto @\exposid{make-when-all-env}@(inplace_stop_source& stop_src, // \expos + Env&& env) noexcept; \end{codeblock} -\end{itemdescr} -\begin{itemdecl} -~@\exposid{local-state}@(); -\end{itemdecl} +\pnum +\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{stop_src.get_token()}, and +\item +given a query object \tcode{q} +with type other than \cv{} \tcode{get_stop_token_t}, +\tcode{e.query(q)} is expression-equivalent to \tcode{env.query(q)} +if the type of \tcode{q} satisfies \exposconcept{forwarding-query}, and +ill-formed otherwise. +\end{itemize} -\begin{itemdescr} \pnum -\effects -Equivalent to: -\begin{codeblock} -sh_state->@\exposid{dec-ref}@(); -\end{codeblock} -\end{itemdescr} +Let \tcode{\placeholder{when-all-env}} be an alias template such that +\tcode{\placeholder{when-all-env}} denotes the type +\tcode{decltype(\exposid{make-\linebreak{}when-all-env}(declval(), declval()))}. +\indexlibrarymember{\exposid{check-types}}{\exposid{impls-for}} \begin{itemdecl} -void @\exposid{notify}@() noexcept override; +template + static consteval void @\exposid{check-types}@(); \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{Is} be the pack of integral template arguments of +the \tcode{integer_sequence} specialization denoted by +\tcode{\exposid{indices-for}}. + \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); +auto fn = []() { + auto cs = get_completion_signatures...>(); + if constexpr (cs.@\exposid{count-of}@(set_value) >= 2) + throw @\placeholder{unspecified-exception}@(); + @\exposid{decay-copyable-result-datums}@(cs); // see \ref{exec.snd.expos} +}; +(fn.template operator()<@\exposid{child-type}@>(), ...); \end{codeblock} \end{itemdescr} \pnum -Let \exposid{split-receiver} denote -the following exposition-only class template: +The member \tcode{\exposid{impls-for}::\exposid{get-env}} +is initialized with a callable object +equivalent to the following lambda expression: \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 - }; +[](auto&&, State& state, const Rcvr& rcvr) noexcept { + return @\exposid{make-when-all-env}@(state.@\exposid{stop-src}@, get_env(rcvr)); } \end{codeblock} \pnum -Let \exposid{shared-state} denote the following exposition-only class template: +The member \tcode{\exposid{impls-for}::\exposid{get-state}} +is initialized with a callable object +equivalent to the following lambda expression: \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 - }; +[](Sndr&& sndr, Rcvr& rcvr) noexcept(noexcept(@$e$@)) -> decltype(@$e$@) { + return @$e$@; } \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 +where $e$ is the expression \begin{codeblock} -variant, tuple, @\exposid{as-tuple}@...> +std::forward(sndr).@\exposid{apply}@(@\exposid{make-state}@()) \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. +and where \exposid{make-state} is the following exposition-only class template: +\begin{codeblock} +enum class @\exposid{disposition}@ { @\exposid{started}@, @\exposid{error}@, @\exposid{stopped}@ }; // \expos -\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}@>; +template +struct @\exposid{make-state}@ { + template + 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 @@ -4203,19 +4851,19 @@ \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. +otherwise, \tcode{\placeholder{none-such}}, +where \tcode{\placeholder{none-such}} is an unspecified empty class type. \pnum The alias \tcode{values_tuple} denotes the type \begin{codeblock} -tuple, @\exposid{decayed-tuple}@, optional>...> +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...>} +the type \tcode{variant<\placeholder{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. @@ -4247,7 +4895,7 @@ @\exposid{on_stop}@.reset(); visit( [&](Error& error) noexcept { - if constexpr (!@\libconcept{same_as}@) { + if constexpr (!@\libconcept{same_as}@) { set_error(std::move(rcvr), std::move(error)); } }, @@ -4256,9 +4904,15 @@ \item Otherwise, evaluates: \begin{codeblock} -@\exposid{on_stop}@.reset(); -set_stopped(std::move(rcvr)); +if constexpr (@\placeholder{sends-stopped}@) { + @\exposid{on_stop}@.reset(); + set_stopped(std::move(rcvr)); +} \end{codeblock} +where \tcode{\placeholder{sends-stopped}} equals \tcode{true} +if and only if there exists an element \tcode{S} of \tcode{Sndrs} such that +\tcode{completion_signatures_of_t>>} +contains \tcode{set_stopped_t()}. \end{itemize} \pnum @@ -4271,17 +4925,12 @@ 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), ...); - } + (start(ops), ...); } \end{codeblock} \pnum -The member \exposid{\tcode{impls-for}::\exposid{complete}} +The member \tcode{\exposid{impls-for}::\exposid{complete}} is initialized with a callable object equivalent to the following lambda expression: \begin{codeblock} @@ -4334,17 +4983,15 @@ \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} +is expression-equivalent to +\tcode{\exposid{make-sender}(when_all_with_variant, \{\}, sndrs...)}. \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)} +then the expression \tcode{when_all_with_variant.transform_sender(set_value, sndr, env)} is ill-formed; otherwise, it is equivalent to: \begin{codeblock} @@ -4373,21 +5020,26 @@ \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. +is expression-equivalent to +\tcode{\exposid{make-sender}(into_variant, \{\}, sndr)}. \pnum -The exposition-only class template \exposid{impls-for}\iref{exec.snd.general} +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} is specialized for \tcode{into_variant} as follows: +\indexlibraryglobal{\exposid{impls-for}} +\indexlibrarymember{\exposid{check-types}}{\exposid{impls-for}} \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@; + + template + static consteval void @\exposid{check-types}@() { + auto cs = get_completion_signatures<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)...>(); + @\exposid{decay-copyable-result-datums}@(cs); // see \ref{exec.snd.expos} + } }; } \end{codeblock} @@ -4397,7 +5049,7 @@ is initialized with a callable object equivalent to the following lambda: \begin{codeblock} [](Sndr&& sndr, Rcvr& rcvr) noexcept - -> type_identity, env_of_t>> { + -> type_identity, @\exposid{FWD-ENV-T}@(env_of_t)>> { return {}; } \end{codeblock} @@ -4409,7 +5061,7 @@ []( auto, State, Rcvr& rcvr, Tag, Args&&... args) noexcept -> void { if constexpr (@\libconcept{same_as}@) { - using variant_type = typename State::type; + using variant_type = State::type; @\exposid{TRY-SET-VALUE}@(rcvr, variant_type(@\exposid{decayed-tuple}@{std::forward(args)...})); } else { Tag()(std::move(rcvr), std::forward(args)...); @@ -4430,32 +5082,53 @@ \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: +The expression \tcode{stopped_as_optional(sndr)} is expression-equivalent to +\tcode{\exposid{make-sender}(stopped_as_optional, \{\}, sndr)}. + +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \tcode{stopped_as_optional_t} as follows: +\indexlibraryglobal{\exposid{impls-for}} +\indexlibrarymember{\exposid{check-types}}{\exposid{impls-for}} \begin{codeblock} -transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(stopped_as_optional, {}, sndr)) +namespace std::execution { + template<> + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { + template + static consteval void @\exposid{check-types}@() { + @\exposid{default-impls}@::@\exposid{check-types}@(); + if constexpr (!requires { + requires (!@\libconcept{same_as}@, + @\exposid{FWD-ENV-T}@(Env)...>>); }) + throw @\placeholder{unspecified-exception}@(); + } + }; +} \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 \tcode{false} +then the expression \tcode{stopped_as_optional.trans\-form_sender(set_value, sndr, env)} is ill-formed; +otherwise, +if \tcode{\libconcept{sender_in}<\exposid{child-type}, \exposid{FWD-\brk{}ENV-\brk{}T}(Env)>} +is \tcode{false}, +the expression \tcode{stopped_as_optional.transform_sender(set_value, sndr, env)} +is equivalent to \tcode{\exposid{not-a-sen\-der}()}; otherwise, it is equivalent to: \begin{codeblock} auto&& [_, _, child] = sndr; -using V = @\exposid{single-sender-value-type}@; +using V = @\exposid{single-sender-value-type}@<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)>; 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()); }); + 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}} @@ -4475,1193 +5148,4323 @@ 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. +is expression-equivalent to +\tcode{\exposid{make-sender}(stopped_as_error, err, sndr)}. \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)} +then the expression \tcode{stopped_as_error.transform_sender(set_value, 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)); - }); + 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}} +\rSec3[exec.associate]{\tcode{execution::associate}} \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. +\tcode{associate} tries to associate +a sender with an async scope such that +the scope can track the lifetime of any asynchronous operations +created with the sender. \pnum -Let \exposid{sync-wait-env} be the following exposition-only class type: +Let \exposid{associate-data} be the following exposition-only class template: + +\indexlibraryglobal{execution::\exposid{associate-data}}% \begin{codeblock} -namespace std::this_thread { - struct @\exposid{sync-wait-env}@ { - execution::run_loop* @\exposid{loop}@; // \expos +namespace std::execution { + template<@\libconcept{scope_token}@ Token, @\libconcept{sender}@ Sender> + struct @\exposidnc{associate-data}@ { // \expos + using @\exposidnc{wrap-sender}@ = // \expos + remove_cvref_t().wrap(declval()))>; + using @\exposidnc{assoc-t}@ = decltype(declval().try_associate()); // \expos + using @\exposidnc{sender-ref}@ = // \expos + unique_ptr<@\exposidnc{wrap-sender}@, decltype([](auto* p) noexcept { destroy_at(p); })>; + + explicit @\exposid{associate-data}@(Token t, Sender&& s) + : @\exposid{sndr}@(t.wrap(std::forward(s))), + @\exposid{assoc}@([&] { + @\exposid{sender-ref}@ guard{addressof(@\exposid{sndr}@)}; + auto assoc = t.try_associate(); + if (assoc) { + guard.release(); + } + return assoc; + }()) {} - auto query(execution::get_scheduler_t) const noexcept { - return @\exposid{loop}@->get_scheduler(); - } + @\exposid{associate-data}@(const @\exposid{associate-data}@& other) + noexcept(is_nothrow_copy_constructible_v<@\exposid{wrap-sender}@> && + noexcept(other.@\exposid{assoc}@.try_associate())); - auto query(execution::get_delegation_scheduler_t) const noexcept { - return @\exposid{loop}@->get_scheduler(); - } + @\exposid{associate-data}@(@\exposid{associate-data}@&& other) + noexcept(is_nothrow_move_constructible_v<@\exposid{wrap-sender}@>) + : @\exposid{associate-data}@(std::move(other).release()) {} + + ~@\exposid{associate-data}@(); + + pair<@\exposid{assoc-t}@, @\exposid{sender-ref}@> release() && noexcept; + + private: + @\exposidnc{associate-data}@(pair<@\exposidnc{assoc-t}@, @\exposidnc{sender-ref}@> parts); // \expos + union { + @\exposidnc{wrap-sender}@ @\exposidnc{sndr}@; // \expos + }; + @\exposidnc{assoc-t}@ @\exposidnc{assoc}@; // \expos }; + + template<@\libconcept{scope_token}@ Token, @\libconcept{sender}@ Sender> + @\exposid{associate-data}@(Token, Sender&&) -> @\exposid{associate-data}@; } \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>; +For an \exposid{associate-data} object \tcode{a}, +\tcode{bool(a.\exposid{assoc})} is \tcode{true} +if and only if +an association was successfully made and is owned by \tcode{a}. - template Sndr> - using @\exposid{sync-wait-with-variant-result-type}@ = - optional>; -} -\end{codeblock} +\indexlibraryctor{execution::\exposid{associate-data}}% +\begin{itemdecl} +@\exposid{associate-data}@(const @\exposid{associate-data}@& other) + noexcept(is_nothrow_copy_constructible_v<@\exposid{wrap-sender}@> && + noexcept(other.@\exposid{assoc}@.try_associate())); +\end{itemdecl} +\begin{itemdescr} \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} +\constraints +\exposid{wrap-sender} models \libconcept{copy_constructible}. \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} +\effects +Initializes \exposid{assoc} with \tcode{other.\exposid{assoc}.try_associate()}. +If \tcode{bool(\exposid{assoc})} is \tcode{true}, +initializes \exposid{sndr} with \tcode{other.\exposid{sndr}}. +\end{itemdescr} +\indexlibraryctor{execution::\exposid{associate-data}}% \begin{itemdecl} -template -void set_value(Args&&... args) && noexcept; +@\exposid{associate-data}@(pair<@\exposid{assoc-t}@, @\exposid{sender-ref}@> parts); \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} +Initializes \exposid{assoc} with \tcode{std::move(parts.first)}. +If \tcode{bool(\exposid{assoc})} is \tcode{true}, +initializes \exposid{sndr} with \tcode{std::move(*parts.second)}. \end{itemdescr} +\indexlibrarydtor{execution::\exposid{associate-data}}% \begin{itemdecl} -template -void set_error(Error&& err) && noexcept; +~@\exposid{associate-data}@(); \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} +If \tcode{bool(\exposid{assoc})} is \tcode{true}, destroys \exposid{sndr}. \end{itemdescr} +\indexlibrarymember{release}{execution::\exposid{associate-data}}% \begin{itemdecl} -void set_stopped() && noexcept; +pair<@\exposid{assoc-t}@, @\exposid{sender-ref}@> release() && noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to \tcode{\exposid{state}->\exposid{loop}.finish()}. +Constructs an object \tcode{u} of type \exposid{sender-ref} +that is initialized with \tcode{addressof(\exposid{sndr})} +if \tcode{bool(\exposid{assoc})} is \tcode{true} and +with \tcode{nullptr} otherwise, +then returns \tcode{pair\{std::move(\exposid{assoc}), std::\brk move(u)\}}. \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); +The name \tcode{associate} denotes a pipeable sender adaptor object. +For subexpressions \tcode{sndr} and \tcode{token}: +\begin{itemize} +\item +If \tcode{decltype((sndr))} does not satisfy \libconcept{sender}, or +\tcode{remove_cvref_t} +does not satisfy \libconcept{scope_token}, then +\tcode{associate(sndr, token)} is ill-formed. +\item +Otherwise, +the expression \tcode{associate(sndr, token)} +is expression-equivalent to +\tcode{\exposid{make-sender}(asso\-ci\-ate, \exposid{associate-data}(token, sndr))}. +\end{itemize} -state.@\exposid{loop}@.run(); -if (state.@\exposid{error}@) { - rethrow_exception(std::move(state.@\exposid{error}@)); +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \tcode{associate_t} as follows: +\indexlibraryglobal{execution::\exposid{impls-for}}% +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { + static constexpr auto @\exposid{get-state}@ = @\seebelow@; // \expos + static constexpr auto @\exposid{start}@ = @\seebelow@; // \expos + + template + static consteval void @\exposid{check-types}@() { // \expos + using associate_data_t = remove_cvref_t<@\exposid{data-type}@>; + using child_type_t = associate_data_t::@\exposid{wrap-sender}@; + (void)get_completion_signatures(); + } + }; } -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} +The member \tcode{\exposid{impls-for}::\exposid{get-state}} +is initialized with a callable object equivalent to the following lambda: -\rSec3[exec.sync.wait.var]{\tcode{this_thread::sync_wait_with_variant}} +\begin{codeblock} +[](Sndr&& sndr, Rcvr& rcvr) noexcept(@\seebelow@) { + auto&& [_, data] = std::forward(sndr); + + using associate_data_t = remove_cvref_t; + using assoc_t = associate_data_t::@\exposid{assoc-t}@; + using sender_ref_t = associate_data_t::@\exposid{sender-ref}@; + + using op_t = connect_result_t; + + struct op_state { + assoc_t @\exposid{assoc}@; // \expos + union { + Rcvr* @\exposid{rcvr}@; // \expos + op_t @\exposid{op}@; // \expos + }; + + explicit op_state(pair parts, Rcvr& r) + : @\exposid{assoc}@(std::move(parts.first)) { + if (@\exposid{assoc}@) { + ::new (@\placeholdernc{voidify}@(@\exposid{op}@)) op_t(connect(std::move(*parts.second), std::move(r))); + } else { + @\exposid{rcvr}@ = addressof(r); + } + } + + explicit op_state(associate_data_t&& ad, Rcvr& r) + : op_state(std::move(ad).release(), r) {} + + explicit op_state(const associate_data_t& ad, Rcvr& r) + requires @\libconcept{copy_constructible}@ + : op_state(associate_data_t(ad).release(), r) {} + + op_state(op_state&&) = delete; + + ~op_state() { + if (@\exposid{assoc}@) { + @\exposid{op}@.~op_t(); + } + } + + void @\exposid{run}@() noexcept { // \expos + if (@\exposid{assoc}@) { + start(@\exposid{op}@); + } else { + set_stopped(std::move(*@\exposid{rcvr}@)); + } + } + }; + + return op_state{std::forward_like(data), @\exposid{rcvr}@}; +} +\end{codeblock} \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: +The expression in the \tcode{noexcept} clause of +\tcode{\exposid{impls-for}::\exposid{get-state}} is \begin{codeblock} -apply_sender(@\exposid{get-domain-early}@(sndr), sync_wait_with_variant, sndr) +(is_same_v> || + is_nothrow_constructible_v, Sndr>) && +@\exposconcept{nothrow-callable}@ \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} +where \exposid{wrap-sender} is the type +\tcode{remove_cvref_t<\exposid{data-type}>::\exposid{wrap-sender}}. \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: +The member \tcode{\exposid{impls-for}::\exposid{start}} +is initialized with a callable object equivalent to the following lambda: \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))); +[](auto& state, auto&) noexcept -> void { + state.@\exposid{run}@(); } -return result_type(nullopt); \end{codeblock} \pnum -The behavior of \tcode{this_thread::sync_wait_with_variant(sndr)} -is undefined unless: +%%FIXME: What are "sndr" and "token" referring to here? +The evaluation of \tcode{associate(sndr, token)} +may cause side effects observable +via \tcode{token}{'s} associated async scope object. + +\rSec3[exec.stop.when]{Exposition-only \tcode{execution::\exposid{stop-when}}} + +\pnum +%%FIXME: Should stop-when be declared somewhere as \expos? +\exposid{stop-when} fuses an additional stop token \tcode{t} +into a sender so that, upon connecting to a receiver \tcode{r}, +the resulting operation state receives stop requests from both +\tcode{t} and the token returned from \tcode{get_stop_token(get_env(r))}. + +\pnum +The name \exposid{stop-when} denotes an exposition-only sender adaptor. +For subexpressions \tcode{sndr} and \tcode{token}: \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} +If \tcode{decltype((sndr))} does not satisfy \libconcept{sender}, or +\tcode{remove_cvref_t} +does not satisfy \libconcept{stoppable_token}, +then \tcode{\exposid{stop-when}(sndr, token)} is ill-formed. + \item -It returns the specified sender's async results as follows: -\begin{itemize} +Otherwise, +if \tcode{remove_cvref_t} models +\libconcept{unstoppable_token} then +\tcode{\exposid{stop-when}(\brk{}sndr, token)} is expression-equivalent to +\tcode{(void)token, sndr}, +except that \tcode{token} and \tcode{sndr} are indeterminately sequenced. + \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. +Otherwise, +\tcode{\exposid{stop-when}(sndr, token)} returns a sender \tcode{osndr}. +%%FIXME: What is rtoken if osndr is not connected to a receiver? +If \tcode{osndr} is connected to a receiver \tcode{r}, +let \tcode{rtoken} be the result of \tcode{get_stop_token(get_env(r))}. + +\begin{itemize} \item -For an error completion, an exception is thrown. +If the type of \tcode{rtoken} models \libconcept{unstoppable_token} then +the effects of connecting \tcode{osndr} to \tcode{r} +are equivalent to +\tcode{connect(write_env(sndr, prop(get_stop_token, token)), r)}. + \item -For a stopped completion, a disengaged \tcode{optional} object is returned. +Otherwise, +the effects of connecting \tcode{osndr} to \tcode{r} +are equivalent to +\tcode{connect(write_env(sndr, prop(get_stop_token, stoken)), r)} +where \tcode{stoken} is an object of +an exposition-only type \exposid{stoken-t} such that: + \begin{itemize} + \item + \exposid{stoken-t} models \libconcept{stoppable_token}; + \item + \tcode{stoken.stop_requested()} returns + \tcode{token.stop_requested() || rtoken.stop_reques-\linebreak{}ted()}; + \item + \tcode{stoken.stop_possible()} returns + \tcode{token.stop_possible() || rtoken.stop_possible()}; and + \item + for types \tcode{Fn} and \tcode{Init} such that both + \tcode{\libconcept{invocable}} and + \tcode{\libconcept{constructible_from}} + are modeled, + \tcode{\exposid{stoken-t}::callback_type} models + \tcode{\exposconcept{stoppable-callback-for}}. + \begin{tailnote} + For an object \tcode{fn} of type \tcode{Fn} + constructed from a value, \tcode{init}, of type \tcode{Init}, + registering \tcode{fn} using + \tcode{\exposid{stoken-t}::callback_type(stoken, init)} + results in an invocation of \tcode{fn} when + a callback registered with \tcode{token} or \tcode{rtoken} would be invoked. + \tcode{fn} is invoked at most once. + \end{tailnote} + \end{itemize} \end{itemize} \end{itemize} -\rSec1[exec.util]{Sender/receiver utilities} +\rSec3[exec.spawn.future]{\tcode{execution::spawn_future}} -\rSec2[exec.util.cmplsig]{\tcode{execution::completion_signatures}} +\pnum +\tcode{spawn_future} attempts to associate the given input sender +with the given token's async scope and, on success, +eagerly starts the input sender; +the return value is a sender that, when connected and started, +completes with either +the result of the eagerly-started input sender or with +\tcode{set_stopped} if the input sender was not started. \pnum -\tcode{completion_signatures} is a type -that encodes a set of completion signatures\iref{exec.async.ops}. +The name \tcode{spawn_future} denotes a customization point object. +For subexpressions \tcode{sndr}, \tcode{token}, and \tcode{env}, +\begin{itemize} +\item let \tcode{Sndr} be \tcode{decltype((sndr))}, +\item let \tcode{Token} be \tcode{remove_cvref_t}, and +\item let \tcode{Env} be \tcode{remove_cvref_t}. +\end{itemize} +If any of +\tcode{\libconcept{sender}}, +\tcode{\libconcept{scope_token}}, or +\tcode{\exposconcept{queryable}} +are not satisfied, +the expression \tcode{spawn_future(sndr, token, env)} is ill-formed. \pnum -\begin{example} +Let \exposid{try-cancelable} be the exposition-only class: + +\indexlibraryglobal{execution::\exposid{try-cancelable}}% \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()>; -}; +namespace std::execution { + struct @\exposid{try-cancelable}@ { // \expos + virtual void @\exposid{try-cancel}@() noexcept = 0; // \expos + }; +} \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: +Let \exposid{spawn-future-state-base} be the exposition-only class template: + +\indexlibraryglobal{execution::\exposid{spawn-future-state-base}}% \begin{codeblock} -template - concept @\defexposconcept{completion-signature}@ = @\seebelow@; +namespace std::execution { + template + struct @\exposid{spawn-future-state-base}@; // \expos + + template + struct @\exposid{spawn-future-state-base}@> // \expos + : @\exposid{try-cancelable}@ { + using @\exposid{variant-t}@ = @\seebelow@; // \expos + @\exposid{variant-t}@ @\exposid{result}@; // \expos + virtual void @\exposid{complete}@() noexcept = 0; // \expos + }; +} \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: +Let \tcode{Sigs} be the pack of arguments to +the \tcode{completion_signatures} specialization provided as +a parameter to the \exposid{spawn-future-state-base} class template. +Let \exposid{as-tuple} be an alias template that +transforms a completion signature \tcode{Tag(Args...)} +into the tuple specialization \tcode{\exposid{decayed-tuple}}. + \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. +If \tcode{is_nothrow_constructible_v, Arg>} is \tcode{true} +for every type \tcode{Arg} +in every parameter pack \tcode{Args} +in every completion signature \tcode{Tag(Args...)} +in \tcode{Sigs} then +\exposid{variant-t} denotes the type +\tcode{variant, \placeholder{as-tuple}...>}, +except with duplicate types removed. + \item -\tcode{set_stopped_t()} +Otherwise +\exposid{variant-t} denotes the type +\tcode{variant, tuple, \placeholder{as-tuple}...>}, +except with duplicate types removed. \end{itemize} \pnum +Let \exposid{spawn-future-receiver} be the exposition-only class template: + +\indexlibraryglobal{execution::\exposid{spawn-future-receiver}}% \begin{codeblock} -template - struct @\exposid{indirect-meta-apply}@ { - template class T, class... As> - using @\exposid{meta-apply}@ = T; // \expos - }; +namespace std::execution { + template + struct @\exposid{spawn-future-receiver}@ { // \expos + using receiver_concept = receiver_tag; -template - concept @\defexposconcept{always-true}@ = true; // \expos + @\exposid{spawn-future-state-base}@* @\exposid{state}@; // \expos -template class Tuple, - template class Variant> - using @\exposid{gather-signatures}@ = @\seebelow@; -\end{codeblock} + template + void set_value(T&&... t) && noexcept { + @\exposid{set-complete}@(std::forward(t)...); + } -\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}$@...)) + template + void set_error(E&& e) && noexcept { + @\exposid{set-complete}@(std::forward(e)); + } + + void set_stopped() && noexcept { + @\exposid{set-complete}@(); + } + + private: + template + void @\exposid{set-complete}@(T&&... t) noexcept { // \expos + constexpr bool nothrow = (is_nothrow_constructible_v, T> && ...); + try { + @\exposid{state}@->@\exposid{result}@.template emplace<@\exposid{decayed-tuple}@>(CPO{}, + std::forward(t)...); + } + catch (...) { + if constexpr (!nothrow) { + using tuple_t = @\exposid{decayed-tuple}@; + @\exposid{state}@->@\exposid{result}@.template emplace(set_error_t{}, current_exception()); + } + } + @\exposid{state}@->@\exposid{complete}@(); + } + }; +} \end{codeblock} -where $m$ is the size of the pack \tcode{TagFns} and -\tcode{META-APPLY(T, As...)} is equivalent to: + +\pnum +Let \tcode{\placeholder{ssource-t}} be an unspecified type +that models \exposconcept{stoppable-source} and \libconcept{default_initializable}, +such that a default-initialized object of type \tcode{\placeholder{ssource-t}} +has an associated stop state. +Let \tcode{ssource} be an lvalue of type \tcode{\placeholder{ssource-t}}. +Let \tcode{\placeholder{stoken-t}} be \tcode{decltype(ssource.get_token())}. +Let \exposid{future-spawned-sender} be the alias template: + \begin{codeblock} -typename @\exposid{indirect-meta-apply}@<@\exposid{always-true}@>::template @\exposid{meta-apply}@ +template<@\libconcept{sender}@ Sender, class Env> +using @\exposid{future-spawned-sender}@ = // \expos + decltype(write_env(@\exposid{stop-when}@(declval(), declval<@\placeholder{stoken-t}@>()), declval())); \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} +Let \exposid{spawn-future-state} be the exposition-only class template: -\pnum +\indexlibraryglobal{execution::\exposid{spawn-future-state}}% \begin{codeblock} namespace std::execution { - template<@\exposconcept{completion-signature}@... Fns> - struct completion_signatures {}; + template + struct @\exposidnc{spawn-future-state}@ // \expos + : @\exposid{spawn-future-state-base}@, + env<>>> { + using @\exposidnc{sigs-t}@ = // \expos + completion_signatures_of_t<@\exposid{future-spawned-sender}@, env<>>; + using @\exposidnc{receiver-t}@ = // \expos + @\exposid{spawn-future-receiver}@<@\exposid{sigs-t}@>; + using @\exposidnc{op-t}@ = // \expos + connect_result_t<@\exposid{future-spawned-sender}@, @\exposid{receiver-t}@>; + + @\exposidnc{spawn-future-state}@(Alloc alloc, Sender&& sndr, Token token, Env env) // \expos + : @\exposid{alloc}@(std::move(alloc)), + @\exposid{op}@(connect( + write_env(@\exposid{stop-when}@(std::forward(sndr), @\exposid{ssource}@.get_token()), std::move(env)), + @\exposid{receiver-t}@(this))), + @\exposid{assoc}@(token.try_associate()) { + if (@\exposid{assoc}@) + start(@\exposid{op}@); + else + set_stopped(@\exposid{receiver-t}@(this)); + } - 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>; + void @\exposidnc{complete}@() noexcept override; // \expos + void @\exposidnc{consume}@(@\libconcept{receiver}@ auto& rcvr) noexcept; // \expos + void @\exposidnc{abandon}@() noexcept; // \expos + void @\exposidnc{try-cancel}@() noexcept override { // \expos + @\exposid{ssource}@.request_stop(); + @\exposid{try-set-stopped}@(); + } + void @\exposidnc{try-set-stopped}@() noexcept; // \expos - template, - template class Variant = @\exposid{variant-or-empty}@> - requires @\libconcept{sender_in}@ - using error_types_of_t = - @\exposid{gather-signatures}@, - type_identity_t, Variant>; + private: + using @\exposidnc{assoc-t}@ = // \expos + remove_cvref_t().try_associate())>; - template> - requires @\libconcept{sender_in}@ - constexpr bool sends_stopped = - !@\libconcept{same_as}@<@\exposid{type-list}@<>, - @\exposid{gather-signatures}@, - @\exposid{type-list}@, @\exposid{type-list}@>>; + Alloc @\exposidnc{alloc}@; // \expos + @\exposidnc{ssource-t}@ @\exposidnc{ssource}@; // \expos + @\exposidnc{op-t}@ @\exposidnc{op}@; // \expos + @\exposidnc{assoc-t}@ @\exposidnc{assoc}@; // \expos + + void @\exposidnc{destroy}@() noexcept; // \expos + }; + + template // \expos + @\exposid{spawn-future-state}@(Alloc alloc, Sender&& sndr, Token token, Env env) + -> @\exposid{spawn-future-state}@; } \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...)>; +For purposes of determining the existence of a data race, +\exposid{complete}, \exposid{consume}, \exposid{try-set-stopped}, and \exposid{abandon} +behave as atomic operations\iref{intro.multithread}. +These operations on a single object of a type +that is a specialization of \exposid{spawn-future-state} +appear to occur in a single total order. -using my_completion_signatures = - transform_completion_signatures< - completion_signatures_of_t, - completion_signatures, - my_set_value_t>; -\end{codeblock} -\end{example} +\indexlibrarymember{\exposid{complete}}{execution::\exposid{spawn-future-state}}% +\begin{itemdecl} +void @\exposid{complete}@() noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -This subclause makes use of the following exposition-only entities: -\begin{codeblock} -template - using @\exposid{default-set-value}@ = - completion_signatures; +\effects +\begin{itemize} +\item +No effects if this invocation of \exposid{complete} happens before +an invocation of +\exposid{consume}, \exposid{try-set-\linebreak{}stopped}, or \exposid{abandon} +on \tcode{*this}; +\item +otherwise, +if an invocation of \exposid{consume} on \tcode{*this} happens before +this invocation of \exposid{complete} and +no invocation of \exposid{try-set-stopped} on \tcode{*this} happened before +this invocation of \tcode{complete} then +there is a receiver, \tcode{rcvr}, registered and +that receiver is deregistered and completed +as if by \tcode{\exposid{consume}(rcvr)}; +\item +otherwise, +\exposid{destroy} is invoked. +\end{itemize} +\end{itemdescr} -template - using @\exposid{default-set-error}@ = - completion_signatures; -\end{codeblock} +\indexlibrarymember{\exposid{consume}}{execution::\exposid{spawn-future-state}}% +\begin{itemdecl} +void @\exposid{consume}@(@\libconcept{receiver}@ auto& rcvr) noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum +\effects +\begin{itemize} +\item +If this invocation of \exposid{consume} happens before +an invocation of \exposid{complete} on \tcode{*this} and +no invocation of \exposid{try-set-stopped} on \tcode{*this} happened before +this invocation of \exposid{consume} then +\tcode{rcvr} is registered to be completed when +\exposid{complete} is subsequently invoked on \tcode{*this}; + +\item +otherwise, +if this invocation of \exposid{consume} happens after +an invocation of \exposid{try-set-stopped} on \tcode{*this} and +no invocation of \exposid{complete} on \tcode{*this} happened before +this invocation of \exposid{consume} then +\tcode{rcvr} is completed as if by \tcode{set_stopped(std::move(rcvr))}; + +\item +otherwise, +\tcode{rcvr} is completed as if by: \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@>; -} +std::move(this->@\exposid{result}@).visit( + [&rcvr](auto&& tuple) noexcept { + if constexpr (!@\libconcept{same_as}@, monostate>) { + apply([&rcvr](auto cpo, auto&&... vals) { + cpo(std::move(rcvr), std::move(vals)...); + }, std::move(tuple)); + } + }); +@\exposid{destroy}@(); \end{codeblock} +\end{itemize} +\end{itemdescr} -\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. +\indexlibrarymember{\exposid{try-set-stopped}}{execution::\exposid{spawn-future-state}}% +\begin{itemdecl} +void @\exposid{try-set-stopped}@() noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -Let \tcode{Vs} be a pack of the types in the \exposid{type-list} named by -\tcode{\exposid{gather-signatures}}. +\effects +\begin{itemize} +\item +If an invocation of \exposid{consume} on \tcode{*this} happens before +this invocation of \exposid{try-set-stopped} and +no invocation of \exposid{complete} on \tcode{*this} happened before +this invocation of \exposid{try-set-stopped} then +there is a receiver, \tcode{rcvr}, registered and +that receiver is deregistered and completed as if by +\tcode{set_stopped(std::move(rcvr)), \exposid{destroy}()}; -\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}...>}. +\item +otherwise, no effects. +\end{itemize} +\end{itemdescr} -\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}. +\indexlibrarymember{\exposid{abandon}}{execution::\exposid{spawn-future-state}}% +\begin{itemdecl} +void @\exposid{abandon}@() noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -If any of the above types are ill-formed, -then +\effects +\begin{itemize} +\item +If this invocation of \exposid{abandon} happens before +an invocation of \exposid{complete} on \tcode{*this} then +equivalent to: \begin{codeblock} -transform_completion_signatures +@\exposid{ssource}@.request_stop(); \end{codeblock} -is ill-formed. -Otherwise, +\item +otherwise, +\exposid{destroy} is invoked. +\end{itemize} +\end{itemdescr} + +\indexlibrarymember{\exposid{destroy}}{execution::\exposid{spawn-future-state}}% +\begin{itemdecl} +void @\exposid{destroy}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \begin{codeblock} -transform_completion_signatures +auto associated = std::move(this->@\exposid{associated}@); +{ + using traits = allocator_traits::template rebind_traits<@\exposid{spawn-future-state}@>; + typename traits::allocator_type alloc(std::move(this->@\exposid{alloc}@)); + traits::destroy(alloc, this); + traits::deallocate(alloc, this, 1); +} \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} +\end{itemdescr} -\rSec2[exec.prop]{Class template \tcode{prop}} +\pnum +Let \exposid{future-operation} be the exposition-only class template: \begin{codeblock} namespace std::execution { - template - struct @\libglobal{prop}@ { - QueryTag @\exposid{query_}@; // \expos - ValueType @\exposid{value_}@; // \expos + template + struct @\exposid{future-operation}@ { // \expos + struct @\exposid{callback}@ { // \expos + @\exposid{try-cancelable}@* @\exposid{state}@; // \expos - constexpr const ValueType& query(QueryTag) const noexcept { - return @\exposid{value_}@; + void operator()() noexcept { + @\exposid{state}@->@\exposid{try-cancel}@(); + }; + }; + + using @\exposid{stop-token-t}@ = // \expos + stop_token_of_t>; + + using @\exposid{stop-callback-t}@ = // \expos + stop_callback_for_t<@\exposid{stop-token-t}@, @\exposid{callback}@>; + + struct @\exposid{rcvr-t}@ { // \expos + using receiver_concept = receiver_tag; + @\exposid{future-operation}@* @\exposid{op}@; // \expos + + template + void set_value(T&&... ts) && noexcept { + @\exposid{op}@->@\exposid{set-complete}@(std::forward(ts)...); + } + + template + void set_error(E&& e) && noexcept { + @\exposid{op}@->@\exposid{set-complete}@(std::forward(e)); + } + + void set_stopped() && noexcept { + @\exposid{op}@->@\exposid{set-complete}@(); + } + + env_of_t get_env() const noexcept { + return execution::get_env(@\exposid{op}@->@\exposid{rcvr}@); + } + }; + + Rcvr @\exposid{rcvr}@; // \expos + StatePtr @\exposid{state}@; // \expos + @\exposid{rcvr-t}@ @\exposid{inner}@; // \expos + optional<@\exposid{stop-callback-t}@> @\exposid{stopCallback}@; // \expos + + + @\exposid{future-operation}@(StatePtr state, Rcvr rcvr) noexcept // \expos + : @\exposid{rcvr}@(std::move(rcvr)), @\exposid{state}@(std::move(state)), @\exposid{inner}@(this) + {} + + @\exposid{future-operation}@(@\exposid{future-operation}@&&) = delete; + + void @\exposid{run}@() & noexcept { // \expos + constexpr bool nothrow = + is_nothrow_constructible_v<@\exposid{stop-callback-t}@, @\exposid{stop-token-t}@, @\exposid{callback}@>; + try { + @\exposid{stopCallback}@.emplace(get_stop_token(@\exposid{rcvr}@), @\exposid{callback}@(@\exposid{state}@.get())); + } + catch (...) { + if constexpr (!nothrow) { + set_error(std::move(@\exposid{rcvr}@), current_exception()); + return; + } + } + + @\exposid{state}@.release()->@\exposid{consume}@(@\exposid{inner}@); } - }; - template - prop(QueryTag, ValueType) -> prop>; + template + void @\exposid{set-complete}@(T&&... ts) noexcept { // \expos + @\exposid{stopCallback}@.reset(); + CPO{}(std::move(@\exposid{rcvr}@), std::forward(ts)...); + } + }; } \end{codeblock} \pnum -Class template \tcode{prop} is for building a queryable object -from a query object and a value. +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \tcode{spawn_future_t} as follows: -\pnum -\mandates -\tcode{\exposconcept{callable}>} -is modeled, -where \exposid{prop-like} is the following exposition-only class template: +\indexlibraryglobal{execution::\exposid{impls-for}}% \begin{codeblock} -template -struct @\exposid{prop-like}@ { // \expos - const ValueType& query(auto) const noexcept; -}; +namespace std::execution { + template<> + struct @\exposid{impls-for}@ : @\exposid{default-impls}@ { + static constexpr auto @\exposid{start}@ = @\seebelow@; // \expos + static constexpr auto @\exposid{get-state}@ = @\seebelow@; // \expos + }; +} \end{codeblock} \pnum -\begin{example} +The member \tcode{\exposid{impls-for}::\exposid{start}} +is initialized with a callable object equivalent to the following lambda: \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); +[](auto& state, auto&) noexcept -> void { + state.@\exposid{run}@(); } \end{codeblock} -\end{example} \pnum -Specializations of \tcode{prop} are not assignable. - -\rSec2[exec.env]{Class template \tcode{env}} - +The member \tcode{\exposid{impls-for}::\exposid{get-state}} +is initialized with a callable object equivalent to the following lambda: \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...>; +[](Sndr sndr, Rcvr& rcvr) noexcept { + auto& [_, data] = sndr; + using state_ptr = remove_cvref_t; + return @\exposid{future-operation}@(std::move(data), std::move(rcvr)); } \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. +For the expression \tcode{spawn_future(sndr, token, env)} +let \tcode{new_sender} be the expression \tcode{token.wrap(sndr)} and +let \tcode{alloc} and \tcode{senv} be defined as follows: +\begin{itemize} +\item +if the expression \tcode{get_allocator(env)} is well-formed, then +\tcode{alloc} is the result of \tcode{get_allocator(env)} and +\tcode{senv} is the expression \tcode{env}; +\item +otherwise, +if the expression \tcode{get_allocator(get_env(new_sender))} is well-formed, then +\tcode{alloc} is the result of \tcode{get_allocator(get_env(new_sender))} and +\tcode{senv} is the expression +\tcode{\exposid{JOIN-ENV}(prop(get_allocator, alloc), env)}; +\item +otherwise, +\tcode{alloc} is \tcode{allocator()} and +\tcode{senv} is the expression \tcode{env}. +\end{itemize} \pnum -Specializations of \tcode{env} are not assignable. +The expression \tcode{spawn_future(sndr, token, env)} +has the following effects: -\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}. +\begin{itemize} +\item +Uses \tcode{alloc} to allocate and construct an object \tcode{s} of type +\tcode{decltype(\exposid{spawn-future-state}(alloc, token.wrap(sndr), token, senv))} +from \tcode{alloc}, \tcode{token.wrap(sndr)}, \tcode{token}, and \tcode{senv}. +If an exception is thrown then +any constructed objects are destroyed and +any allocated memory is deallocated. + +\item +Constructs an object \tcode{u} of +a type that is a specialization of \tcode{unique_ptr} such that: + \begin{itemize} + \item + \tcode{u.get()} is equal to the address of \tcode{s}, and + \item + \tcode{u.get_deleter()(u.release())} is equivalent to + \tcode{u.release()->\exposid{abandon}()}. + \end{itemize} + +\item +Returns \tcode{\exposid{make-sender}(spawn_future, std::move(u))}. +\end{itemize} \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{})}; +The expression \tcode{spawn_future(sndr, token)} is expression-equivalent to +\tcode{spawn_future(sndr, token, ex\-ecution::env<>())}. - // Parameterize the input sender so that it will use our custom execution environment. - return write_env(sndr, e); -} -\end{codeblock} -\end{example} +\rSec2[exec.consumers]{Sender consumers} -\indexlibrarymember{query}{env}% -\begin{itemdecl} -template -constexpr decltype(auto) query(QueryTag q) const noexcept(@\seebelow@); -\end{itemdecl} +\rSec3[exec.sync.wait]{\tcode{this_thread::sync_wait}} -\begin{itemdescr} +\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_start_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))}. +The expression \tcode{this_thread::sync_wait(sndr)} +is equivalent to \tcode{apply_sender(Domain(), sync_wait, sndr)}, +where \tcode{Domain} is the type of +\tcode{get_completion_domain(get_env(sndr), \exposid{sync-wait-env}\{\})}. + +\pnum +\mandates +\begin{itemize} +\item +\tcode{\libconcept{sender_in}} is \tcode{true}. +\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_tag; + @\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{\exposconcept{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))}. +The expression \tcode{this_thread::sync_wait_with_variant(sndr)} +is equivalent to \tcode{apply_sender(Domain(), sync_wait_with_variant, sndr)}, +where \tcode{Domain} is the type of +\tcode{get_completion_domain(get_env(sndr), \exposid{sync-wait-env}\{\})}. + +\pnum +\mandates +\begin{itemize} +\item +\tcode{\libconcept{sender_in}} is \tcode{true}. +\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 +The expression \tcode{sync_wait_with_variant.apply_sender(sndr)} 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} + +\rSec3[exec.spawn]{\tcode{execution::spawn}} + +\pnum +\tcode{spawn} attempts to associate the given input sender with +the given token's async scope and, on success, +eagerly starts the input sender. + +\pnum +The name \tcode{spawn} denotes a customization point object. +For subexpressions \tcode{sndr}, \tcode{token}, and \tcode{env}, +\begin{itemize} +\item let \tcode{Sndr} be \tcode{decltype((sndr))}, +\item let \tcode{Token} be \tcode{remove_cvref_t}, and +\item let \tcode{Env} be \tcode{remove_cvref_t}. +\end{itemize} +If any of +\tcode{\libconcept{sender}}, +\tcode{\libconcept{scope_token}}, or +\tcode{\exposconcept{queryable}} +are not satisfied, +the expression \tcode{spawn(\brk{}sndr, token, env)} is ill-formed. + +\pnum +Let \exposid{spawn-state-base} be the exposition-only class: + +\indexlibraryglobal{execution::\exposid{spawn-state-base}}% +\begin{codeblock} +namespace std::execution { + struct @\exposid{spawn-state-base}@ { // \expos + virtual void @\exposid{complete}@() noexcept = 0; // \expos + }; +} +\end{codeblock} + +\pnum +Let \exposid{spawn-receiver} be the exposition-only class: + +\indexlibraryglobal{execution::\exposid{spawn-receiver}}% +\begin{codeblock} +namespace std::execution { + struct @\exposid{spawn-receiver}@ { // \expos + using receiver_concept = receiver_tag; + + @\exposid{spawn-state-base}@* @\exposid{state}@; // \expos + void set_value() && noexcept { @\exposid{state}@->@\exposid{complete}@(); } + void set_stopped() && noexcept { @\exposid{state}@->@\exposid{complete}@(); } + }; +} +\end{codeblock} + +\pnum +Let \exposid{spawn-state} be the exposition-only class template: + +\indexlibraryglobal{execution::\exposid{spawn-state}}% +\begin{codeblock} +namespace std::execution { + template + struct @\exposid{spawn-state}@ : @\exposid{spawn-state-base}@ { // \expos + using @\exposid{op-t}@ = connect_result_t; // \expos + + @\exposid{spawn-state}@(Alloc alloc, Sender&& sndr, Token token); // \expos + void @\exposid{complete}@() noexcept override; // \expos + void @\exposid{run}@() noexcept; // \expos + + private: + using @\exposid{assoc-t}@ = // \expos + remove_cvref_t().try_associate())>; + + Alloc @\exposid{alloc}@; // \expos + @\exposid{op-t}@ @\exposid{op}@; // \expos + @\exposid{assoc-t}@ @\exposid{assoc}@; // \expos + }; +} +\end{codeblock} + +\indexlibraryctor{execution::\exposid{spawn-state}}% +\begin{itemdecl} +@\exposid{spawn-state}@(Alloc alloc, Sender&& sndr, Token token); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes +\exposid{alloc} with \tcode{std::move(alloc)}, +\exposid{op} with \tcode{connect(std::move(sndr), \exposid{spawn-re\-ceiv\-er}(this))}, and +\exposid{assoc} with \tcode{token.try_associate()}. +\end{itemdescr} + +\indexlibrarymember{\exposid{run}}{execution::\exposid{spawn-state}}% +\begin{itemdecl} +void @\exposid{run}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (@\exposid{assoc}@) + start(@\exposid{op}@); +else + @\exposid{complete}@(); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{\exposid{complete}}{execution::\exposid{spawn-state}}% +\begin{itemdecl} +void @\exposid{complete}@() noexcept override; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto assoc = std::move(this->@\exposid{assoc}@); +{ + using traits = allocator_traits::template rebind_traits<@\exposid{spawn-state}@>; + typename traits::allocator_type alloc(this->@\exposid{alloc}@); + traits::destroy(alloc, this); + traits::deallocate(alloc, this, 1); +} +\end{codeblock} +\end{itemdescr} + +\pnum +For the expression \tcode{spawn(sndr, token, env)} +let \tcode{new_sender} be the expression \tcode{token.wrap(sndr)} and +let \tcode{alloc} and \tcode{senv} be defined as follows: +\begin{itemize} +\item +if the expression \tcode{get_allocator(env)} is well-formed, then +\tcode{alloc} is the result of \tcode{get_allocator(env)} and +\tcode{senv} is the expression \tcode{env}, +\item +otherwise +if the expression \tcode{get_allocator(get_env(new_sender))} is well-formed, then +\tcode{alloc} is the result of \tcode{get_allocator(get_env(new_sender))} and +\tcode{senv} is the expression \tcode{\exposid{JOIN-ENV}(prop(get_allocator, alloc), env)}, +\item +otherwise +\tcode{alloc} is \tcode{allocator()} and +\tcode{senv} is the expression \tcode{env}. +\end{itemize} + +\pnum +The expression \tcode{spawn(sndr, token, env)} is of type \tcode{void} and +has the following effects: +%%FIXME: Was this supposed to be more than a single bullet? +\begin{itemize} +\item +Uses \tcode{alloc} to allocate and construct an object \tcode{o} of type +\tcode{decltype(\exposid{spawn-state}(alloc, write_env(token.wrap(sndr), senv), token))} +from \tcode{alloc}, \tcode{write_env(token.wrap(sndr), senv)}, and \tcode{token} +and then +invokes \tcode{o.\exposid{run}()}. +If an exception is thrown then +any constructed objects are destroyed and any allocated memory is deallocated. +\end{itemize} + +\pnum +The expression \tcode{spawn(sndr, token)} is expression-equivalent to +\tcode{spawn(sndr, token, execution::env<>(\brk{}))}. + +\rSec1[exec.cmplsig]{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_tag; + 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{\exposid{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 +\indexlibraryglobal{execution::completion_signatures}% +\indexlibrarymember{\exposid{for-each}}{execution::completion_signatures}% +\indexlibrarymember{\exposid{count-of}}{execution::completion_signatures}% +\begin{codeblock} +namespace std::execution { + template<@\exposconcept{completion-signature}@... Fns> + struct completion_signatures { + template + static constexpr size_t @\exposid{count-of}@(Tag) { return @\seebelow@; } + + template + static constexpr void @\exposid{for-each}@(Fn&& fn) { // \expos + (fn(static_cast(nullptr)), ...); + } + }; + + template, + template class Tuple = @\exposid{decayed-tuple}@, + template class Variant = @\exposid{variant-or-empty}@> + requires @\libconcept{sender_in}@ + using @\libglobal{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} + +\pnum +For a subexpression \tcode{tag}, +let \tcode{Tag} be the decayed type of \tcode{tag}. +\tcode{completion_signatures::\exposid{count-of}(\linebreak{}tag)} +returns the count of function types in \tcode{Fns...} that +are of the form \tcode{Tag(Ts...)} where \tcode{Ts} is a pack of types. + +\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, auto&&...) 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> +@\libconcept{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, Args&&... args) 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, Args&&... args) 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()); - }; +template + concept @\defexposconcept{has-query}@ = // \expos + requires (const Env& env, Args&&... args) { + env.query(QueryTag(), std::forward(args)...); + }; +\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, std::forward(args)...)} +is well-formed. + +\pnum +\constraints +\tcode{(\exposconcept{has-query} || ...)} is \tcode{true}. + +\pnum +\effects +Equivalent to: \tcode{return \exposid{fe}.query(q, std::forward(args)...);} + +\pnum +\remarks +The expression in the \tcode{noexcept} clause is equivalent +to \tcode{noexcept(\exposid{fe}.query(q, std::for\-ward(args)...))}. +\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}@() noexcept = 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}@() noexcept; // \expos + void @\exposid{push-back}@(@\exposid{run-loop-opstate-base}@*) noexcept; // \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() noexcept; + void run() noexcept; + void finish() noexcept; + }; +} +\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. + +\pnum +For type \exposid{set-tag} other than \tcode{set_error_t}, +the expression +\tcode{get_completion_scheduler<\exposid{set-tag}>(get_env(schedule(\exposid{sch}))) == \exposid{sch}} +evaluates to \tcode{true}. + +\begin{itemdecl} +class @\exposid{run-loop-sender}@; +\end{itemdecl} + +\pnum +\exposid{run-loop-sender} is an exposition-only type +that satisfies \libconcept{sender}. +Let \tcode{E} be the type of an environment. +If \tcode{unstoppable_token>} is \tcode{true}, then +\tcode{completion_signatures_of_t<\exposid{run-loop-sen\-der}, E>} is +\tcode{completion_signatures}. +Otherwise, it is \tcode{completion_signatures}. + +\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{\exposconcept{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}))} +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} +@$o$@.@\exposid{loop}@->@\exposid{push-back}@(addressof(@$o$@)); +\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 +The \tcode{run_loop} instance's count is 0 and +its state is starting. +\end{itemdescr} + +\indexlibrarydtor{run_loop}% +\begin{itemdecl} +~run_loop(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If the \tcode{run_loop} instance's count is not 0 or +if its state is 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}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Blocks\iref{defns.block} until one of the following conditions is \tcode{true}: +\begin{itemize} +\item +The \tcode{run_loop} instance's count is 0 and its state is finishing, +in which case \exposid{pop-front} sets the state to finished +and returns \tcode{nullptr}; or +\item +the \tcode{run_loop} instance's count is greater than 0, +in which case an item is removed from the front of the queue, +the 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) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Adds \tcode{item} to the back of the queue and +increments the \tcode{run_loop} instance's count by 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() noexcept; +\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() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +The \tcode{run_loop} instance's state is either starting or finishing. + +\pnum +\effects +If the \tcode{run_loop} instance's state is starting, +sets the state to running, +otherwise leaves the state unchanged. +Then, equivalent to: +\begin{codeblock} +while (auto* op = @\exposid{pop-front}@()) { + op->@\exposid{execute}@(); +} +\end{codeblock} + +\pnum +\remarks +When the \tcode{run_loop} instance's state changes, +it does so without introducing data races. +\end{itemdescr} + +\indexlibrarymember{finish}{run_loop}% +\begin{itemdecl} +void finish() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +The \tcode{run_loop} instance's state is either starting or running. + +\pnum +\effects +Changes the \tcode{run_loop} instance's state to 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}@> && + @\exposconcept{sender-to}@::@\exposid{awaitable-receiver}@> && // \seebelow + requires (Promise& p) { + { p.unhandled_stopped() } -> @\libconcept{convertible_to}@>; + }; + + template + concept @\defexposconcept{has-queryable-await-completion-adaptor}@ = // \expos + @\libconcept{sender}@ && + requires(Sndr&& sender) { + get_await_completion_adaptor(get_env(sender)); + }; + + 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_tag; + 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}. +Let \tcode{\placeholder{MAKE-NOEXCEPT}(expr)} +for some subexpression \tcode{expr} be expression-equivalent to +\tcode{[\&] noexcept -> decltype(auto) \{ return (expr); \}()}. +Then: +\begin{itemize} +\item +The expression \tcode{set_value(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()); +} +@\placeholder{MAKE-NOEXCEPT}@(rcvr.@\exposid{continuation}@.resume()); +\end{codeblock} + +\mandates +\tcode{\libconcept{constructible_from}<\exposid{result-type}, decltype((vs))...>} +is satisfied. +\item +The expression \tcode{set_error(rcvr, err)} is equivalent to: +\begin{codeblock} +try { + rcvr.@\exposid{result-ptr}@->template emplace<2>(@\exposid{AS-EXCEPT-PTR}@(err)); // see \ref{exec.general} +} catch(...) { + rcvr.@\exposid{result-ptr}@->template emplace<2>(current_exception()); +} +@\placeholder{MAKE-NOEXCEPT}@(rcvr.@\exposid{continuation}@.resume()); +\end{codeblock} +\item +The expression \tcode{set_stopped(rcvr)} is equivalent to: +\begin{codeblock} +@\placeholder{MAKE-NOEXCEPT}@( + 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(@\placeholder{MAKE-NOEXCEPT}@(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(@\exposid{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{Expr} names the type \tcode{decltype((expr))} and +\tcode{Promise} names the type \tcode{decay_t}, +\tcode{as_awaitable(expr, p)} is ill-formed if \tcode{p} is not an lvalue, +otherwise \tcode{as_awaitable(expr, p)} is expression-equivalent to +the expression specified below, +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, +\begin{codeblock} +@\exposid{adapt-for-await-completion}@(transform_sender(expr, get_env(p))).as_awaitable(p) +\end{codeblock} +if this expression is well-formed, +\tcode{\libconcept{sender_in}>} is \tcode{true}, and +\tcode{\exposid{single-sen\-der-value-type}>} +is well-formed, +except that \tcode{p} is only evaluated once. +\item +Otherwise, \tcode{(void(p), expr)} +if \tcode{decltype(\exposid{GET-AWAITER}(expr))} +satisfies \tcode{\exposconcept{is-awaiter}}. +\item +Otherwise, +\begin{codeblock} +@\exposid{sender-awaitable}@{@\exposid{adapt-for-await-completion}@(transform_sender(expr, get_env(p))), p} +\end{codeblock} +if \tcode{sender_in>} is \tcode{true} and +\tcode{\exposid{single-sender-value-type}>} +is well-formed, +except that \tcode{p} is only evaluated once. +\item +Otherwise, \tcode{(void(p), expr)}. +\end{itemize} + +\pnum +\tcode{\exposid{adapt-for-await-completion}(s)} is expression-equivalent to +\begin{itemize} +\item +\tcode{get_await_completion_adaptor(get_env(s))(s)} if that is well-formed, +except that \tcode{s} is evaluated only once, +\item +otherwise, \tcode{s}. +\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} + +\rSec2[exec.affine]{\tcode{execution::affine}} + +\pnum +\tcode{affine} adapts a sender into one that completes on +the receiver's scheduler. +If the algorithm determines that the adapted sender already completes +on the correct scheduler it can avoid any scheduling operation. + +\pnum +The name \tcode{affine} denotes a pipeable sender adaptor +object. +For a subexpression \tcode{sndr}, if \tcode{decltype((\brk{}sndr))} +does not satisfy \libconcept{sender}, \tcode{affine(sndr)} +is ill-formed. + +\pnum +Otherwise, the expression \tcode{affine(sndr)} is +expression-equivalent to \tcode{\exposid{make-sender}(affine, env<>(), sndr)}. + +\pnum +For a subexpression \tcode{sch} whose type models \libconcept{scheduler}, +let \tcode{\exposid{UNSTOPPABLE-SCHEDULER}(sch)} be an expression \tcode{e} +whose type models \libconcept{scheduler} such that: +\begin{itemize} +\item +\tcode{schedule(e)} is expression-equivalent to \tcode{unstoppable(schedule(sch))}. +\item +For any query object \tcode{q} and pack of subexpressions \tcode{args...}, +\tcode{e.query(q, args...)} is expression-equivalent to +\tcode{sch.query(q, args...)}. +\item +The expression \tcode{e == \exposid{UNSTOPPABLE-SCHEDULER}(other)} +is expression-equivalent to \tcode{sch == other}. +\end{itemize} + +\pnum +Let \tcode{sndr} and \tcode{ev} be subexpressions +such that \tcode{Sndr} is \tcode{decltype((sndr))}. +If \tcode{\exposconcept{sender-for}} is \tcode{false}, +then the expression \tcode{affine.transform_sender(sndr, ev)} is ill-formed; +otherwise, it is equal to: +\begin{codeblock} +auto& [_, _, child] = sndr; +if constexpr (requires { std::forward_like(child).affine(); }) { + return std::forward_like(child).affine(); +} else { + return continues_on(std::forward_like(child), + @\exposidnc{UNSTOPPABLE-SCHEDULER}@(get_start_scheduler(ev))); +} +\end{codeblock} + +\pnum +\recommended +Implementations should provide \tcode{affine} member functions +for senders that are known to resume on the scheduler where they were started. +Example senders for which that is the case are +\tcode{just}, +\tcode{just_error}, +\tcode{just_stopped}, +\tcode{read_env}, and +\tcode{write_env}. + +\pnum +Let \tcode{\placeholder{out_sndr}} be a subexpression denoting a sender +returned from \tcode{affine(sndr)} or one equal to such, +and let \tcode{\placeholder{OutSndr}} be the type \tcode{decltype((\placeholder{out_sndr}))}. +Let \tcode{\placeholder{out_rcvr}} be a subexpression denoting a receiver that +has an environment of type \tcode{Env}. +If \tcode{get_start_scheduler(get_env(\placeholder{out_rcvr}))} is ill-formed or +does not satisfy \tcode{\exposconcept{infallible-scheduler}}, +then evaluation of +the expression \tcode{get_completion_signatures<\placeholder{OutSndr}, Env>()} +exits with an exception. +Let \tcode{\placeholder{op}} be an lvalue referring to the operation state that +results from connecting \tcode{\placeholder{out_sndr}} to \tcode{\placeholder{out_rcvr}}. +Calling \tcode{start(\placeholder{op})} will start \tcode{sndr} on the current +execution agent and execute completion operations on \tcode{\placeholder{out_rcvr}} +on an execution agent of the execution resource associated with +\tcode{\placeholder{sch}}. +If the current execution resource is the same as the execution +resource associated with \tcode{\placeholder{sch}}, the completion operation on +\tcode{\placeholder{out_rcvr}} may be called before \tcode{start(\placeholder{op})} completes. + +\rSec2[exec.inline.scheduler]{\tcode{execution::inline_scheduler}} + +\begin{codeblock} +namespace std::execution { + class @\libglobal{inline_scheduler}@ { + class @\exposidnc{inline-sender}@; // \expos + + template<@\libconcept{receiver}@ R> + class @\exposidnc{inline-state}@; // \expos + + public: + using scheduler_concept = scheduler_tag; + + constexpr @\exposid{inline-sender}@ schedule() noexcept { return {}; } + constexpr bool operator==(const inline_scheduler&) const noexcept = default; + }; +} +\end{codeblock} + +\pnum +\tcode{inline_scheduler} is a class that models +\libconcept{scheduler}\iref{exec.sched}. +All objects of type \tcode{inline_scheduler} are equal. +For a subexpression \tcode{sch} of type \tcode{inline_scheduler}, +a query object \tcode{q}, and +a pack of subexpressions \tcode{args}, +the expression \tcode{sch.query(q, args...)} is expression-equivalent to +\tcode{\exposid{inline-attrs}().query(q, args...)}. + +\pnum +\exposid{inline-sender} is an exposition-only type that satisfies +\libconcept{sender}. +The type \tcode{completion_signatures_of_t<\exposid{inline-sender}>} +is \tcode{completion_signatures}. + +\pnum +Let \tcode{sndr} be an expression of type \exposid{inline-sender}, +let \tcode{rcvr} be an expression such that +\tcode{\exposconcept{receiver-of}} is \tcode{true} +where \tcode{CS} is \tcode{completion_signatures}, +then the expression \tcode{connect(sndr, rcvr)} has +type \tcode{\exposid{inline-state}>} +and is potentially-throwing if and only if +\tcode{((void)sndr, auto(rcvr))} is potentially-throwing. + +\pnum +Let \tcode{\placeholder{o}} be a non-\tcode{const} lvalue of type +\tcode{\exposid{inline-state}}, and let \tcode{REC(\placeholder{o})} be +a non-\tcode{const} lvalue reference to an object of type \tcode{Rcvr} that +was initialized with the expression \tcode{rcvr} passed to an +invocation of \tcode{connect} that returned \tcode{\placeholder{o}}, then: +\begin{itemize} +\item the object to which \tcode{REC(\placeholder{o})} refers remains valid for +the lifetime of the object to which \tcode{\placeholder{o}} refers, and +\item the expression \tcode{start(\placeholder{o})} is equivalent to +\tcode{set_value(std::move(REC(\placeholder{o})))}. +\end{itemize} + +\rSec2[exec.task.scheduler]{\tcode{execution::task_scheduler}} + +\begin{codeblock} +namespace std::execution { + class @\libglobal{task_scheduler}@ { + class @\exposid{ts-domain}@; // \expos + + template<@\libconcept{scheduler}@ Sch> + class @\exposid{backend-for}@; // \expos + + public: + using scheduler_concept = scheduler_tag; + + template> + requires (!@\libconcept{same_as}@>) && @\libconcept{scheduler}@ + explicit task_scheduler(Sch&& sch, Allocator alloc = {}); + + task_scheduler(const task_scheduler&) = default; + task_scheduler& operator=(const task_scheduler&) = default; + + @\seebelow@ schedule(); + + friend bool operator==(const task_scheduler& lhs, const task_scheduler& rhs) noexcept; + template + requires (!@\libconcept{same_as}@) && @\libconcept{scheduler}@ + friend bool operator==(const task_scheduler& lhs, const Sch& rhs) noexcept; + + private: + // see \ref{exec.parschedrepl.psb} + shared_ptr @\exposidnc{sch_}@; // \expos + }; +} +\end{codeblock} + +\pnum +\tcode{task_scheduler} is a class that models +\libconcept{scheduler}\iref{exec.sched}. +Given an object \tcode{s} of type \tcode{task_scheduler}, let +\tcode{\exposid{SCHED}(s)} be the object +pointed to by the pointer owned by \tcode{s.\exposid{sch_}}. +The expression \tcode{get_forward_progress_guarantee(s)} is equivalent to +\tcode{get_forward_progress_guarantee(\exposid{SCHED}(s))}. +The expression \tcode{get_completion_domain(s)} is equivalent to +\tcode{task_scheduler::\exposid{ts-domain}()}. + +\indexlibraryctor{task_scheduler} +\begin{itemdecl} +template> + requires(!@\libconcept{same_as}@>) && @\libconcept{scheduler}@ +explicit task_scheduler(Sch&& sch, Allocator alloc = {}); +\end{itemdecl} +\begin{itemdescr} +\pnum +\mandates +\tcode{Sch} satisfies \tcode{\exposconcept{infallible-scheduler}>}. + +\pnum +\effects +Initializes \exposid{sch_} with: +\begin{codeblock} +allocate_shared<@\exposid{backend-for}@>>(alloc, std::forward(sch)) +\end{codeblock} + +\pnum +\recommended +Implementations should avoid the use of dynamically +allocated memory for small scheduler objects. + +\pnum +\remarks +Any allocations performed by calls on \tcode{*this} are +performed using a copy of \tcode{alloc}. +\end{itemdescr} + +\indexlibrarymember{operator==}{task_scheduler}% +\begin{itemdecl} +bool operator==(const task_scheduler& lhs, const task_scheduler& rhs) noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return lhs == \exposid{SCHED}(rhs);} +\end{itemdescr} + +\indexlibrarymember{operator==}{task_scheduler}% +\begin{itemdecl} +template + requires (!@\libconcept{same_as}@) + && @\libconcept{scheduler}@ +bool operator==(const task_scheduler& lhs, const Sch& rhs) noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\returns +\tcode{false} if the type of \tcode{\exposid{SCHED}(lhs)} is not \tcode{Sch}, +otherwise \tcode{\exposid{SCHED}(lhs) == rhs}. +\end{itemdescr} + +\pnum +For an lvalue \tcode{r} of a type derived from \tcode{receiver_proxy}, +let \tcode{\exposid{WRAP-RCVR}(r)} be an object of a type +that models \libconcept{receiver} and +whose completion handlers result in +invoking the corresponding completion handlers of \tcode{r}. +\begin{codeblock} +namespace std::execution { + template<@\libconcept{scheduler}@ Sch> + class task_scheduler::@\exposid{backend-for}@ + : public parallel_scheduler_replacement::parallel_scheduler_backend { // \expos + public: + explicit @\exposid{backend-for}@(Sch sch) : @\exposid{sched_}@(std::move(sch)) {} + + void schedule(receiver_proxy& r, span s) noexcept override; + void schedule_bulk_chunked(size_t shape, bulk_item_receiver_proxy& r, + span s) noexcept override; + void schedule_bulk_unchunked(size_t shape, bulk_item_receiver_proxy& r, + span s) noexcept override; + + private: + Sch @\exposid{sched_}@; + }; +} +\end{codeblock} + +\pnum +Let \tcode{env} be a pack of subexpressions, and +let \exposid{just-sndr-like} be a sender +whose only value completion signature is \tcode{set_value_t()} and +for which the expression +\tcode{get_completion_scheduler(get_env(\exposid{just-sndr-like)}, env...)} +is expression-equivalent to +\tcode{get_completion_scheduler(\exposid{sched_}, env...)}. + +\begin{itemdecl} +void schedule(receiver_proxy& r, span s) noexcept override; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an operation state \tcode{os} +with \tcode{connect(schedule(\exposid{sched_}), \exposid{WRAP-RCVR}(r))} and +calls \tcode{start(os)}. +\end{itemdescr} + +\begin{itemdecl} +void schedule_bulk_chunked(size_t shape, bulk_item_receiver_proxy& r, + span s) noexcept override; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Let \tcode{chunk_size} be an integer less than or equal to \tcode{shape}, +let \tcode{num_chunks} be \tcode{(shape + chunk_size - 1) / chunk_size}, and +let \tcode{fn} be a function object such that +for an integer \tcode{i}, +\tcode{fn(i)} calls \tcode{r.execute(i * chunk_size, m)}, +where \tcode{m} is the lesser of \tcode{(i + 1) * chunk_size} and \tcode{shape}. +Constructs an operation state \tcode{os} as if with +\begin{codeblock} +connect(bulk(@\exposid{just-sndr-like}@, par, num_chunks, fn), @\exposid{WRAP-RCVR}@(r)) +\end{codeblock} +and calls \tcode{start(os)}. +\end{itemdescr} + +\begin{itemdecl} +void schedule_bulk_unchunked(size_t shape, bulk_item_receiver_proxy& r, + span s) noexcept override; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Let \tcode{fn} be a function object such that +for an integer \tcode{i}, +\tcode{fn(i)} is equivalent to \tcode{r.execute(i, i + 1)}. +Constructs an operation state \tcode{os} as if with +\begin{codeblock} +connect(bulk(@\exposid{just-sndr-like}@, par, shape, fn), @\exposid{WRAP-RCVR}@(r)) +\end{codeblock} +and calls \tcode{start(os)}. +\end{itemdescr} + +\begin{itemdecl} +@\seebelow@ schedule(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A prvalue \exposid{ts-sndr} whose type models \libconcept{sender} such that: +\begin{itemize} +\item +\tcode{get_completion_scheduler(get_env(\exposid{ts-sndr}))} +is equal to \tcode{*this}. +\item +\tcode{get_completion_domain(get_env(\exposid{ts-sndr}))} +is expression-equivalent to \tcode{\exposid{ts-do\-main}()}. +\item +If a receiver \tcode{rcvr} is connected to \exposid{ts-sndr} and +the resulting operation state is started, +calls \tcode{\exposid{sch_}->schedule(r, s)}, where +\begin{itemize} +\item +\tcode{r} is a proxy for \tcode{rcvr} with base +\tcode{parallel_scheduler_replacement::receiver_proxy}\iref{exec.par.scheduler} +and +\item +\tcode{s} is a preallocated backend storage for \tcode{r}. +\end{itemize} +\item +For any type \tcode{E}, +\tcode{completion_signatures_of_t} denotes +\tcode{completion_signatures} if +\tcode{\libconcept{unstoppable_token}>} is \tcode{true}, and +otherwise \tcode{completion_signatures}. +\end{itemize} +\end{itemdescr} + +\begin{codeblock} +namespace std::execution { + class task_scheduler::@\exposid{ts-domain}@ : public default_domain { // \expos + public: + template + static constexpr auto transform_sender(set_value_t, BulkSndr&& bulk_sndr, const Env& env) + noexcept(@\seebelow@); + }; +} +\end{codeblock} + +\begin{itemdecl} +template + static constexpr auto transform_sender(BulkSndr&& bulk_sndr, const Env& env) + noexcept(is_nothrow_constructible_v, BulkSndr>); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{\libconcept{sender_in}} is \tcode{true}, +\item +\tcode{auto(std::forward(bulk_sndr))} is well-formed, and +\item +either +\begin{itemize} +\item +\tcode{\exposconcept{sender-for}} or +\item +\tcode{\exposconcept{sender-for}} +\end{itemize} +is \tcode{true}. +\end{itemize} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto& [_, data, child] = bulk_sndr; +auto& [_, shape, fn] = data; +auto sch = @\exposidnc{call-with-default}@(get_completion_scheduler, + @\exposidnc{not-a-scheduler}@(), get_env(child), @\exposidnc{FWD-ENV}@(env)); +return @$e$@; +\end{codeblock} +where $e$ is \tcode{\exposid{not-a-sender}()} +if the type of \tcode{sch} is not \tcode{task_scheduler}; +otherwise, it is a prvalue whose type models \libconcept{sender} such that, +if it is connected to a receiver \tcode{rcvr} and +the resulting operation state is started, +\tcode{child} is connected to an unspecified receiver \tcode{R} and started. +The expression \tcode{get_env(R)} +is expression-equivalent to \tcode{\exposid{FWD-ENV}(get_env(\exposid{rcvr-copy}))}, +where \exposid{rcvr-copy} is an lvalue subexpression +designating an object decay-copied from \tcode{rcvr}. + +If \tcode{child} completes with an error or a stopped completion, +the completion operation is forwarded unchanged to \tcode{rcvr}. +Otherwise, let \tcode{args} be a pack of lvalue subexpressions +designating objects decay-copied from the value result datums. +Then: +\begin{itemize} +\item +If \tcode{bulk_sndr} was the result of the evaluation of +an expression equivalent to \tcode{bulk_chunked(child, policy, shape, fn)} or +a copy of such, +then \tcode{\exposid{sch_}->schedule_bulk_chunked(shape, r, s)} is called +where \tcode{r} is a bulk chunked proxy\iref{exec.par.scheduler} +for \tcode{rcvr} with callable \tcode{fn} and arguments \tcode{args}, and +\tcode{s} is a preallocated backend storage for \tcode{r}. +\item +Otherwise, calls \tcode{\exposid{sch_}->schedule_bulk_unchunked(shape, r, s)} +where \tcode{r} is a bulk unchunked proxy for \tcode{rcvr} +with callable \tcode{fn} and arguments \tcode{args}, and +\tcode{s} is a preallocated backend storage for \tcode{r}. +\end{itemize} +\end{itemdescr} + +\rSec2[exec.task]{\tcode{execution::task}} + +\rSec3[task.overview]{\tcode{task} overview} + +\pnum +The \tcode{task} class template represents a sender that can +be used as the return type of coroutines. +The first template parameter \tcode{T} defines the type of the value +completion datum\iref{exec.async.ops} if \tcode{T} is not \tcode{void}. +Otherwise, there are no value completion datums. +Inside coroutines returning \tcode{task} the operand of +\tcode{co_return} (if any) becomes the argument of \tcode{set_value}. +The second template parameter \tcode{Environment} is used to customize +the behavior of \tcode{task}. + +\rSec3[task.class]{Class template \tcode{task}} + +\begin{codeblock} +namespace std::execution { + template> + class @\libglobal{task}@ { + // \ref{task.state} + template<@\libconcept{receiver}@ Rcvr> + class @\exposidnc{state}@; // \expos + + public: + using sender_concept = sender_tag; + using allocator_type = @\seebelow@; + using start_scheduler_type = @\seebelow@; + using stop_source_type = @\seebelow@; + using stop_token_type = decltype(declval().get_token()); + using error_types = @\seebelow@; + + // \ref{task.promise} + class promise_type; + + task(task&&) noexcept; + ~task(); + + template + static consteval auto get_completion_signatures(); + + template<@\libconcept{receiver}@ Rcvr> + @\exposid{state}@ connect(Rcvr&& rcvr) &&; + + private: + coroutine_handle @\exposidnc{handle}@; // \expos + }; +} +\end{codeblock} + +\pnum +\tcode{task} models \libconcept{sender}\iref{exec.snd} +if \tcode{T} is \tcode{void}, a reference type, or a \cv{}-unqualified +non-array object type and \tcode{E} is a class type. +Otherwise a program that instantiates the definition of \tcode{task} +is ill-formed. + +\pnum +The nested types of \tcode{task} template specializations +are determined based on the \tcode{Environment} parameter: +\begin{itemize} +\item \tcode{allocator_type} is \tcode{Environment::allocator_type} +if that \grammarterm{qualified-id} is valid and denotes a type, +\tcode{allocator} otherwise. +\item \tcode{start_scheduler_type} is \tcode{Environment::start_scheduler_type} +if that \grammarterm{qualified-id} is valid and denotes a type, +\tcode{task_scheduler} otherwise. +\item \tcode{stop_source_type} is \tcode{Environment::stop_source_type} +if that \grammarterm{qualified-id} is valid and denotes a type, +\tcode{inplace_stop_source} otherwise. +\item \tcode{error_types} is \tcode{Environment::error_types} if +that \grammarterm{qualified-id} is valid and denotes a type, +\tcode{com\-pletion_sign\-atures} otherwise. +\end{itemize} + +\pnum + A program is ill-formed if \tcode{error_types} is not a +specialization of \tcode{execution::completion_signatures} +or if the template arguments of that specialization +contain an element which is not of the form +\tcode{set_error_t(E)} for some type \tcode{E}. + +\pnum +\tcode{allocator_type} shall meet the \oldconcept{Allocator} requirements, +\tcode{scheduler_type} shall model \libconcept{scheduler}, and +\tcode{stop_source_type} shall model \exposconcept{stoppable-source}. + +\rSec3[task.members]{\tcode{task} members} + +\indexlibraryctor{task}% +\begin{itemdecl} +task(task&& other) noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{handle} with \tcode{exchange(other.\exposid{handle}, +\{\})}. +\end{itemdescr} + +\indexlibrarydtor{task}% +\begin{itemdecl} +~task(); +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (@\exposid{handle}@) + @\exposid{handle}@.destroy(); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{get_completion_signatures}{task}% +\begin{itemdecl} +template + static consteval auto get_completion_signatures(); +\end{itemdecl} +\begin{itemdescr} +\pnum +Let the type \tcode{C} be a specialization +of \tcode{execution::completion_signatures} +with the template arguments (in unspecified order): +\begin{itemize} +\item +\tcode{set_value_t()} if \tcode{T} is \tcode{void}, +and \tcode{set_value_t(T)} otherwise; +\item +template arguments of the specialization of +\tcode{execution::completion_signatures} denoted by \tcode{error_types}; +and +\item \tcode{set_stopped_t()}. +\end{itemize} + +\pnum +\returns +\tcode{C()}. +\end{itemdescr} + +\indexlibrarymember{connect}{task}% +\begin{itemdecl} +template<@\libconcept{receiver}@ Rcvr> + @\exposid{state}@ connect(Rcvr&& recv) &&; +\end{itemdecl} +\begin{itemdescr} +\pnum +\mandates +At least one of the expressions +\tcode{allocator_type(get_allocator(get_env(rcvr)))} and +\tcode{allocator_type()} +is well-formed. + +\pnum +\expects +\tcode{bool(\exposid{handle})} is \tcode{true}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +return @\exposid{state}@(exchange(@\exposid{handle}@, {}), std::forward(recv)); +\end{codeblock} +\end{itemdescr} + +\rSec3[task.state]{Class template \tcode{task::\exposid{state}}} + +\begin{codeblock} +namespace std::execution { + template + template<@\libconcept{receiver}@ Rcvr> + class task::@\exposidnc{state}@ { // \expos + public: + using operation_state_concept = operation_state_tag; + + template + @\exposid{state}@(coroutine_handle h, R&& rr); + + ~@\exposid{state}@(); + + void start() & noexcept; + + stop_token_type @\exposidnc{get-stop-token}@(); // \expos + + private: + using @\exposidnc{own-env-t}@ = @\seebelownc@; // \expos + coroutine_handle @\exposidnc{handle}@; // \expos + remove_cvref_t @\exposidnc{rcvr}@; // \expos + optional @\exposidnc{source}@; // \expos + @\exposidnc{own-env-t}@ @\exposidnc{own-env}@; // \expos + Environment @\exposidnc{environment}@; // \expos + optional @\exposidnc{result}@; // \expos; present only if \tcode{is_void_v} is \tcode{false} + exception_ptr @\exposidnc{error}@; // \expos + }; +} +\end{codeblock} + +\pnum +The type \exposid{own-env-t} is \tcode{Environment::template +env_type(\brk{})))\brk{}>} if that +\grammarterm{qualified-id} is valid and denotes a type, \tcode{env<>} otherwise. + +\indexlibraryctor{task::\exposid{state}}% +\begin{itemdecl} +template + @\exposid{state}@(coroutine_handle h, R&& rr); +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Initializes +\begin{itemize} +\item \exposid{handle} with \tcode{std::move(h)}; +\item \exposid{rcvr} with \tcode{std::forward(rr)}; +\item \exposid{own-env} +with \tcode{\exposid{own-env-t}(get_env(\exposid{rcvr}))} if that expression +is valid and \tcode{\exposid{own-env-t}()} otherwise. +If neither of these expressions is valid, the program is ill-formed. +\item \exposid{environment} with +\tcode{Environment(\exposid{own-env})} if that expression is +valid, otherwise \tcode{Environment(\brk{}get_env(\exposid{rcvr}))} +if this expression is valid, otherwise \tcode{Environment()}. +If neither of these expressions is valid, the program is ill-formed. +\end{itemize} +\end{itemdescr} + +\indexlibrarydtor{task::\exposid{state}}% +\begin{itemdecl} +~@\exposid{state}@(); +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (@\exposid{handle}@) + @\exposid{handle}@.destroy(); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{start}{task::\exposid{state}}% +\begin{itemdecl} +void start() & noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Let \tcode{\placeholder{prom}} be the object \tcode{\exposid{handle}.promise()}. +Associates \tcode{\exposid{STATE}(\placeholder{prom})}, \tcode{\exposid{RCVR}(\placeholder{prom})}, and \tcode{\exposid{SCHED}(\placeholder{prom})} +with \tcode{*this} as follows: +\begin{itemize} +\item \tcode{\exposid{STATE}(\placeholder{prom})} is \tcode{*this}. +\item \tcode{\exposid{RCVR}(\placeholder{prom})} is \exposid{rcvr}. +\item \tcode{\exposid{SCHED}(\placeholder{prom})} is the object initialized +with \tcode{start_scheduler_type(get_start_scheduler(get_env(\exposid{rcvr})))} +if that expression is valid and \tcode{start_scheduler_type()} otherwise. +If neither of these expressions is valid, the program is ill-formed. +\end{itemize} +Finally, invokes \tcode{\exposid{handle}.resume()}. +\end{itemdescr} + +\indexlibrarymember{\exposid{get-stop-token}}{task::\exposid{state}}% +\begin{itemdecl} +stop_token_type @\exposidnc{get-stop-token}@(); // \expos +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +If +\tcode{\libconcept{same_as}().get_token()), decltype(get_\linebreak{}stop_token(get_env(\exposid{rcvr})))>} +is \tcode{true}, +returns \tcode{get_stop_token(get_env(\exposid{rcvr}))}. +Otherwise, if \tcode{\exposid{source}.has_value()} is \tcode{false}, +initializes the contained value of \exposid{source} such that +\begin{itemize} +\item +\tcode{\exposid{source}->stop_requested()} returns +\tcode{get_stop_token(get_env(\exposid{rcvr}))->stop_requested()};\linebreak +and +\item +\tcode{\exposid{source}->stop_possible()} returns +\tcode{get_stop_token(get_env(\exposid{rcvr}))->stop_possible()}. +\end{itemize} +Finally, returns \tcode{\exposid{source}->get_token()}. +\end{itemdescr} + +\rSec3[task.promise]{Class \tcode{task::promise_type}} + +\begin{codeblock} +namespace std::execution { + template + class task::promise_type { + public: + task get_return_object() noexcept; + + static constexpr suspend_always @\libmember{initial_suspend}{task::promise_type}@() noexcept { return {}; } + auto final_suspend() noexcept; + + void unhandled_exception(); + coroutine_handle<> unhandled_stopped() noexcept; + + void return_void(); // present only if \tcode{is_void_v} is \tcode{true} + template + void return_value(V&& value); // present only if \tcode{is_void_v} is \tcode{false} + + template + @\unspec@ yield_value(with_error error); + + template<@\libconcept{sender}@ Sender> + auto await_transform(Sender&& sndr); + + @\unspec@ get_env() const noexcept; + + void* operator new(size_t size); + template + void* operator new(size_t size, allocator_arg_t, Alloc alloc, Args&&...); + template + void* operator new(size_t size, const This&, allocator_arg_t, Alloc alloc, Args&&...); + + void operator delete(void* pointer, size_t size) noexcept; + }; +} \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. +Let \tcode{\placeholder{prom}} be an object of \tcode{promise_type} +and let \tcode{\placeholder{tsk}} be the \tcode{task} object +created by \tcode{\placeholder{prom}.get_return_object()}. +The description below +refers to objects \tcode{\exposid{STATE}(\placeholder{prom})}, +\tcode{\exposid{RCVR}(\placeholder{prom})}, +and \tcode{\exposid{SCHED}(\placeholder{prom})} +associated with \tcode{\placeholder{tsk}} +during evaluation of \tcode{task::\exposid{state}::start} +for some receiver \tcode{Rcvr}. + +\indexlibrarymember{get_return_object}{task::promise_type}% +\begin{itemdecl} +task get_return_object() noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\returns +A \tcode{task} object whose member \exposid{handle} is +\tcode{coroutine_handle::\brk{}from_promise\brk{}(*this)}. +\end{itemdescr} + +\indexlibrarymember{final_suspend}{task::promise_type}% +\begin{itemdecl} +auto final_suspend() noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\returns +An awaitable object of unspecified type\iref{expr.await} whose +member functions arrange for the completion of the asynchronous +operation associated with \tcode{\exposid{STATE}(*this)}. +Let \tcode{st} be a reference to \tcode{\exposid{STATE}(*this)}. +The asynchronous completion first destroys the coroutine frame +using \tcode{st.\exposid{handle}.destroy()} and then invokes: +\begin{itemize} +\item +\tcode{set_error(std::move(st.\exposid{rcvr}), std::move(st.\exposid{error}))} +if \tcode{bool(st.\exposid{error})} is \tcode{true}, otherwise +\item +\tcode{set_value(std::move(st.\exposid{rcvr}))} if \tcode{is_void_v} is \tcode{true}, +and otherwise +\item + \tcode{set_value(std::move(st.\exposid{rcvr}), *std::move(st.\exposid{result}))}. +\end{itemize} +\end{itemdescr} + +\indexlibrarymember{yield_value}{task::promise_type}% +\begin{itemdecl} +template + auto yield_value(with_error err); +\end{itemdecl} +\begin{itemdescr} +\pnum +\mandates +\tcode{std::move(err.error)} is convertible to exactly one of the +\tcode{set_error_t} argument types of \tcode{error_types}. +Let \tcode{\placeholder{Cerr}} be that type. \pnum -\constraints -\tcode{(\exposconcept{has-query} || ...)} is \tcode{true}. +\returns +An awaitable object of unspecified type\iref{expr.await} whose +member functions arrange for the calling coroutine to be suspended +and then completes the asynchronous operation associated with +\tcode{\exposid{STATE}(*this)}. +Let \tcode{st} be a reference to \tcode{\exposid{STATE}(*this)}. +Then the asynchronous operation completes by first +destroying the coroutine frame using \tcode{st.\exposid{handle}.destroy()} +and then invoking +\tcode{set_error(std::move(st.\exposid{rcvr}), +\placeholder{Cerr}(std::move(err.error)))}. +\end{itemdescr} + +\indexlibrarymember{await_transform}{task::promise_type}% +\begin{itemdecl} +template<@\libconcept{sender}@ Sender> + auto await_transform(Sender&& sndr); +\end{itemdecl} +\begin{itemdescr} +\pnum +\returns +If \tcode{\libconcept{same_as}} +is \tcode{true}, +returns \tcode{as_awaitable(\brk{}std::forward(sndr), *this)}; +otherwise returns \tcode{as_awaitable(affine(std::forward<\brk{}Sender>(sndr)), *this)}. +\end{itemdescr} +\indexlibrarymember{unhandled_exception}{task::promise_type}% +\begin{itemdecl} +void unhandled_exception(); +\end{itemdecl} +\begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return \exposid{fe}.query(q);} +If the signature \tcode{set_error_t(exception_ptr)} is not an element +of \tcode{error_types}, calls \tcode{terminate()}\iref{except.terminate}. +Otherwise, stores \tcode{current_exception()} into +\tcode{\exposid{STATE}(*this).\exposid{error}}. +\end{itemdescr} +\indexlibrarymember{unhandled_stopped}{task::promise_type}% +\begin{itemdecl} +coroutine_handle<> unhandled_stopped() noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\remarks -The expression in the \tcode{noexcept} clause is equivalent -to \tcode{noexcept(\exposid{fe}.query(q))}. +\effects +Completes the asynchronous operation associated with \tcode{\exposid{STATE}(*this)}. +Let \tcode{st} be a reference to \tcode{\exposid{STATE}(*this)}. +The asynchronous operation is completed by first +destroying the coroutine frame +using \tcode{st.\exposid{handle}.destroy()} and then +invoking \tcode{set_stopped(std::move(st.\exposid{rcvr}))}. +\end{itemdescr} +\begin{itemdescr} +\pnum +\returns +\tcode{noop_coroutine()}. \end{itemdescr} -\rSec1[exec.ctx]{Execution contexts} +\indexlibrarymember{return_void}{task::promise_type}% +\begin{itemdecl} +void return_void(); +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Does nothing. +\end{itemdescr} -\rSec2[exec.run.loop]{\tcode{execution::run_loop}} +\indexlibrarymember{return_value}{task::promise_type}% +\begin{itemdecl} +template + void return_value(V&& v); +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{\exposid{result}.emplace(std::forward(v))}. +\end{itemdescr} -\rSec3[exec.run.loop.general]{General} +\indexlibrarymember{get_env}{task::promise_type}% +\begin{itemdecl} +@\unspec@ get_env() const noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\returns +An object \tcode{env} such that queries are forwarded as follows: +\begin{itemize} +\item \tcode{env.query(get_start_scheduler)} returns +\tcode{start_scheduler_type(\exposid{SCHED}(*this))}. +\item \tcode{env.query(get_allocator)} returns +\tcode{allocator_type(get_allocator(get_env(\exposid{RCVR}(*this))\brk{}))} +if this expression is well-formed and +\tcode{allocator_type()} otherwise. +\item \tcode{env.query(get_stop_token)} returns +\tcode{\exposid{STATE}(*this).\exposid{get-stop-token}()}. +\item For any other query \tcode{q} and arguments \tcode{a...} a +call to \tcode{env.query(q, a...)} returns +\tcode{\exposid{STATE}(*this)}. \tcode{\exposid{environment}.query(q, a...)} if this expression +is well-formed and \tcode{forwarding_query(q)} is well-formed and is \tcode{true}. +Otherwise \tcode{env.query(q, a...)} is ill-formed. +\end{itemize} +\end{itemdescr} + +\indexlibrarymember{operator new}{task::promise_type}% +\begin{itemdecl} +void* operator new(size_t size); +\end{itemdecl} +\begin{itemdescr} \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}. +\effects +Equivalent to: +\tcode{return operator new(size, allocator_arg, allocator_type());} +\end{itemdescr} +\indexlibrarymember{operator new}{task::promise_type}% +\begin{itemdecl} +template + void* operator new(size_t size, allocator_arg_t, Alloc alloc, Args&&...); +template + void* operator new(size_t size, const This&, allocator_arg_t, Alloc alloc, Args&&...); +\end{itemdecl} +\begin{itemdescr} \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}. +Let \tcode{PAlloc} be +\tcode{allocator_traits::template rebind_alloc}, +where \tcode{U} is an unspecified type +whose size and alignment are both \mname{STDCPP_DEFAULT_NEW_ALIGNMENT}. \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. +\mandates +\tcode{allocator_traits::pointer} is a pointer type. + +\pnum +\effects +Initializes an allocator \tcode{palloc} of type \tcode{PAlloc} with +\tcode{alloc}. +Uses \tcode{palloc} to allocate storage for the +smallest array of \tcode{U} sufficient to provide storage for a +coroutine state of size \tcode{size}, and unspecified additional +state necessary to ensure that \tcode{operator delete} can later +deallocate this memory block with an allocator equal to \tcode{palloc}. + +\pnum +\returns +A pointer to the allocated storage. +\end{itemdescr} + +\indexlibrarymember{operator delete}{task::promise_type}% +\begin{itemdecl} +void operator delete(void* pointer, size_t size) noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\expects +\tcode{pointer} was returned from an invocation of the above overload +of \tcode{operator new} with a size argument equal to \tcode{size}. + +\pnum +\effects +Deallocates the storage pointed to by \tcode{pointer} using an +allocator equal to that used to allocate it. +\end{itemdescr} + +\rSec1[exec.scope]{Execution scope utilities} + +\rSec2[exec.scope.concepts]{Execution scope concepts} + +\pnum +The \libconcept{scope_association} concept defines +the requirements on a type \tcode{Assoc}. +An object of type \tcode{Assoc} is \defn{engaged} +if and only if it owns an association with an async scope, +referred to as its \defnadj{associated}{scope}. + +\begin{codeblock} +namespace std::execution { + template + concept @\deflibconcept{scope_association}@ = + @\libconcept{movable}@ && + is_nothrow_move_constructible_v && + is_nothrow_move_assignable_v && + @\libconcept{default_initializable}@ && + requires(const Assoc assoc) { + { static_cast(assoc) } noexcept; + { assoc.try_associate() } -> @\libconcept{same_as}@; + }; +} +\end{codeblock} + +\pnum +A type \tcode{Assoc} models \libconcept{scope_association} only if: +\begin{itemize} +\item +a default constructed object of type \tcode{Assoc} is not engaged; +\item +for an object \exposid{assoc} of type \tcode{Assoc}, +\tcode{static_cast(assoc)} is \tcode{true} +if and only if \tcode{assoc} is engaged; +\item +no two distinct objects of type \tcode{Assoc} own the same association; +\item +for an object \tcode{assoc} of type \tcode{Assoc}, +destroying \tcode{assoc} releases the association owned by \tcode{assoc}, if any; +\item +for an object \tcode{assoc} of type \tcode{Assoc}, +after it is used as the source operand of a move constructor, +the \tcode{assoc} is not engaged; +\item +for distinct objects \tcode{assoc1} and \tcode{assoc2} of type \tcode{Assoc}, +after evaluating \tcode{assoc1 = std::move(assoc2)}, +the association owned by \tcode{assoc1}, if any, is released and +\tcode{assoc2} is not engaged; +\item +for an object \tcode{assoc} of type \tcode{Assoc} that is engaged, +\tcode{assoc.try_associate()} either +returns an object that is not engaged or +acquires a new association with \tcode{assoc}'s associated scope and +returns an engaged object that owns that association; +\item +for an object \tcode{assoc} of type \tcode{Assoc} that is not engaged, +\tcode{assoc.try_associate()} returns an object that is not engaged. +\end{itemize} + +\pnum +The \libconcept{scope_token} concept defines the requirements on +a type \tcode{Token} that can be used to create associations +between senders and an async scope. +Every object of type \tcode{Token} is associated with an async scope +that is referred to as its \term{associated scope}. + +\pnum +Let \placeholder{test-sender} and \placeholder{test-env} +be unspecified types such that +\tcode{\libconcept{sender_in}<\placeholder{test-sender}, \placeholder{test-env}>} +is modeled. + +\begin{codeblock} +namespace std::execution { + template + concept @\deflibconcept{scope_token}@ = + @\libconcept{copyable}@ && + requires(const Token token) { + { token.try_associate() } -> @\libconcept{scope_association}@; + { token.wrap(declval<@\placeholder{test-sender}@>()) } -> @\libconcept{sender_in}@<@\placeholder{test-env}@>; + }; +} +\end{codeblock} + +\pnum +A type \tcode{Token} models \libconcept{scope_token} only if: + +\begin{itemize} +\item +no exceptions are thrown from +copy construction, +move construction, +copy assignment, or +move assignment +of objects of type \tcode{Token}; + +\item +for an object \tcode{token} of type \tcode{Token}, +\tcode{token.try_associate()} either +returns an object that is not engaged or +acquires a new association with \tcode{token}'s associated scope and +returns an engaged object that owns that association; and + +\item +given an lvalue \tcode{token} of type (possibly const) \tcode{Token}, +for all expressions \tcode{sndr} such that +\tcode{decltype((\linebreak{}sndr))} models \libconcept{sender}: + \begin{itemize} + \item + \tcode{token.wrap(sndr)} is a valid expression, + \item + \tcode{decltype(token.wrap(sndr))} models \libconcept{sender}, and + \item + \tcode{completion_signatures_of_t} + contains the same completion signatures as + \tcode{completion_signatures_of_t} + for all types \tcode{E} such that + \tcode{\libconcept{sender_in}} is modeled. + \end{itemize} +\end{itemize} + +\rSec2[exec.counting.scopes]{Counting Scopes} + +\rSec3[exec.counting.scopes.general]{General} + +\pnum +Scopes of type \tcode{simple_counting_scope} and \tcode{counting_scope} +maintain counts of associations. +Let: +\begin{itemize} +\item +\tcode{Scope} be either \tcode{simple_counting_scope} or \tcode{counting_scope}, +\item +\tcode{scope} be an object of type \tcode{Scope}, +\item +\tcode{tkn} be an object of type \tcode{Scope::token} +obtained from \tcode{scope.get_token()}, +\item +\tcode{jsndr} be a sender obtained from \tcode{scope.join()}, and +\item +\tcode{op} be an operation state obtained from +connecting \tcode{jsndr} to a receiver. +\end{itemize} +During its lifetime \tcode{scope} goes through different states +which govern what operations are allowed and the result of these operations: + +\begin{itemize} +\item +\exposid{unused}: +a newly constructed object starts in the \exposid{unused} state. + +\item +\exposid{open}: +when \tcode{tkn.try_associate()} is called +while \tcode{scope} is in the \exposid{unused} state, +\tcode{scope} moves to the \exposid{open} state. + +\item +\exposid{open-and-joining}: +when the operation state \tcode{op} is started +while \tcode{scope} is in the \exposid{unused} or \exposid{open} state, +\tcode{scope} moves to the \exposid{open-and-joining} state. + +\item +\exposid{closed}: +when \tcode{scope.close()} is called +while \tcode{scope} is in the \exposid{open} state, +\tcode{scope} moves to the \exposid{closed} state. + +\item +\exposid{unused-and-closed}: +when \tcode{scope.close()} is called +while \tcode{scope} is in the \exposid{unused} state, +\tcode{scope} moves to the \exposid{unused-and-closed} state. + +\item +\exposid{closed-and-joining}: +when \tcode{scope.close()} is called +while \tcode{scope} is in the \exposid{open-and-joining} state or +the operation state \tcode{op} is started +while \tcode{scope} is in +the \exposid{closed} or \exposid{unused-and-closed} state, +\tcode{scope} moves to the \exposid{closed-and-joining} state. + +\item +\exposid{joined}: +when the count of associations drops to zero +while \tcode{scope} is in +the \exposid{open-and-joining} or \exposid{closed-and-joining} state, +\tcode{scope} moves to the \exposid{joined} state. +\end{itemize} \pnum \recommended -Implementations should use an intrusive queue of operation states -to hold the work units to make scheduling allocation-free. +For \tcode{simple_counting_scope} and \tcode{counting_scope}, +implementations should store the state and the count of associations +in a single member of type \tcode{size_t}. + +\pnum +Subclause \ref{exec.counting.scopes} makes use of +the following exposition-only entities: + +\begin{codeblock} +struct @\exposid{scope-join-t}@ {}; // \expos + +enum @\exposid{scope-state-type}@ { // \expos + @\exposid{unused}@, // \expos + @\exposid{open}@, // \expos + @\exposid{closed}@, // \expos + @\exposid{open-and-joining}@, // \expos + @\exposid{closed-and-joining}@, // \expos + @\exposid{unused-and-closed}@, // \expos + @\exposid{joined}@, // \expos +}; + +template + struct @\exposid{association-t}@; // \expos +\end{codeblock} + +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \exposid{scope-join-t} as follows: +\indexlibraryglobal{execution::\exposid{impls-for}<\exposid{scope-join-t}>}% +%%FIXME: The declarations of "receiver" below hide the \libconcept of the same name \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 - run-loop-opstate-base* @\exposid{next}@; // \expos + template<> + struct @\exposid{impls-for}@<@\exposid{scope-join-t}@> : @\exposid{default-impls}@ { + template + struct @\exposid{state}@ { // \expos + struct @\exposid{rcvr-t}@ { // \expos + using receiver_concept = receiver_tag; + + Rcvr& @\exposid{rcvr}@; // \expos + + void set_value() && noexcept { + execution::set_value(std::move(@\exposid{rcvr}@)); + } + + template + void set_error(E&& e) && noexcept { + execution::set_error(std::move(@\exposid{rcvr}@), std::forward(e)); + } + + void set_stopped() && noexcept { + execution::set_stopped(std::move(@\exposid{rcvr}@)); + } + + decltype(auto) get_env() const noexcept { + return execution::get_env(@\exposid{rcvr}@); + } + }; + + using @\exposid{sched-sender}@ = // \expos + decltype(schedule(get_start_scheduler(get_env(declval())))); + using @\exposid{op-t}@ = // \expos + connect_result_t<@\exposid{sched-sender}@, @\exposid{rcvr-t}@>; + + Scope* @\exposid{scope}@; // \expos + Rcvr& @\exposid{receiver}@; // \expos + @\exposid{op-t}@ @\exposid{op}@; // \expos + + @\exposid{state}@(Scope* scope, Rcvr& rcvr) // \expos + noexcept(@\exposconcept{nothrow-callable}@) + : @\exposid{scope}@(scope), + @\exposid{receiver}@(rcvr), + @\exposid{op}@(connect(schedule(get_start_scheduler(get_env(rcvr))), @\exposid{rcvr-t}@(rcvr))) {} + + void @\exposid{complete}@() noexcept { // \expos + start(@\exposid{op}@); + } + + void @\exposid{complete-inline}@() noexcept { // \expos + set_value(std::move(@\exposid{receiver}@)); + } }; - 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 + static constexpr auto @\exposid{get-state}@ = // \expos + [](auto&& sender, Rcvr& receiver) + noexcept(is_nothrow_constructible_v<@\exposid{state}@, @\exposid{data-type}@, Rcvr&>) { + auto[_, self] = sender; + return @\exposid{state}@(self, receiver); + }; + + static constexpr auto @\exposid{start}@ = // \expos + [](auto& s, auto&) noexcept { + if (s.@\exposid{scope}@->@\exposid{start-join-sender}@(s)) + s.@\exposid{complete-inline}@(); + }; + }; +} +\end{codeblock} + +\pnum +\exposid{association-t} is a class template, +specializations of which model \libconcept{scope_association} and +contain an exposition-only member \exposid{scope} of type \tcode{Scope*}. +For a class type \tcode{Scope} and +an object \tcode{assoc} of type \tcode{\exposid{association-t}}: +\begin{itemize} +\item +\tcode{assoc.\exposid{scope}} points to its associated scope, +\item +\tcode{assoc} is engaged when \tcode{assoc.\exposid{scope} != nullptr} is \tcode{true}, +\item +if \tcode{assoc} is engaged, +then \tcode{assoc.try_associate()} is equivalent to +\tcode{assoc.\exposid{scope}->\exposid{try-associate}()}, and +\item +the association owned by \tcode{assoc} +is released by invoking \tcode{assoc.\exposid{scope}->\exposid{disassociate}()}. +\end{itemize} +\rSec3[exec.scope.simple.counting]{Simple Counting Scope} + +\rSec4[exec.scope.simple.counting.general]{General} + +\indexlibraryglobal{execution::simple_counting_scope}% +\begin{codeblock} +namespace std::execution { + class simple_counting_scope { public: - // \ref{exec.run.loop.ctor}, constructor and destructor - run_loop() noexcept; - run_loop(run_loop&&) = delete; - ~run_loop(); + // \ref{exec.simple.counting.token}, token + struct token; - // \ref{exec.run.loop.members}, member functions - @\exposid{run-loop-scheduler}@ get_scheduler(); - void run(); - void finish(); + using @\exposid{assoc-t}@ = @\exposid{association-t}@; // \expos + + static constexpr size_t max_associations = @\UNSP{\impldef{value of \tcode{std::execution::simple_counting_scope::max_associations}}}@; + + // \ref{exec.simple.counting.ctor}, constructor and destructor + simple_counting_scope() noexcept; + simple_counting_scope(simple_counting_scope&&) = delete; + ~simple_counting_scope(); + + // \ref{exec.simple.counting.mem}, members + token get_token() noexcept; + void close() noexcept; + @\libconcept{sender}@ auto join() noexcept; + + private: + size_t @\exposid{count}@; // \expos + @\exposid{scope-state-type}@ @\exposid{state}@; // \expos + + @\exposid{assoc-t}@ @\exposid{try-associate}@() noexcept; // \expos + void @\exposid{disassociate}@() noexcept; // \expos + template + bool @\exposid{start-join-sender}@(State& state) noexcept; // \expos }; } \end{codeblock} -\rSec3[exec.run.loop.types]{Associated types} +\pnum +For purposes of determining the existence of a data race, +\tcode{get_token}, +\tcode{close}, +\tcode{join}, +\exposid{try-associate}, +\exposid{disassociate}, and +\exposid{start-join-sender} +behave as atomic operations\iref{intro.multithread}. +These operations on a single object of +type \tcode{simple_counting_scope} appear to occur in a single total order. + +\rSec4[exec.simple.counting.ctor]{Constructor and Destructor} + +\indexlibraryctor{execution::simple_counting_scope}% +\begin{itemdecl} +simple_counting_scope() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\exposid{count} is \tcode{0} and \exposid{state} is \exposid{unused}. +\end{itemdescr} + +\indexlibrarydtor{execution::simple_counting_scope}% +\begin{itemdecl} +~simple_counting_scope(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \exposid{state} is not one of +\exposid{joined}, \exposid{unused}, or \exposid{unused-and-closed}, +invokes \tcode{terminate}\iref{except.terminate}. +Otherwise, has no effects. +\end{itemdescr} + +\rSec4[exec.simple.counting.mem]{Members} +\indexlibrarymember{get_token}{execution::simple_counting_scope}% \begin{itemdecl} -class @\exposid{run-loop-scheduler}@; +token get_token() noexcept; \end{itemdecl} +\begin{itemdescr} \pnum -\exposid{run-loop-scheduler} is an unspecified type -that models \libconcept{scheduler}. +\returns +An object \tcode{t} of type \tcode{simple_counting_scope::token} such that +\tcode{t.\exposid{scope} == this} is \tcode{true}. +\end{itemdescr} -\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. +\indexlibrarymember{close}{execution::simple_counting_scope}% +\begin{itemdecl} +void close() noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -Two instances of \exposid{run-loop-scheduler} compare equal -if and only if they were obtained from the same \tcode{run_loop} instance. +\effects +If \exposid{state} is +\begin{itemize} +\item +\exposid{unused}, then changes \exposid{state} to \exposid{unused-and-closed}; +\item +\exposid{open}, then changes \exposid{state} to \exposid{closed}; +\item +\exposid{open-and-joining}, +then changes \exposid{state} to \exposid{closed-and-joining}; +\item +otherwise, no effects. +\end{itemize} \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. +\ensures +Any subsequent call to \tcode{\exposid{try-associate}()} on \tcode{*this} +returns \tcode{false}. +\end{itemdescr} +\indexlibrarymember{join}{execution::simple_counting_scope}% \begin{itemdecl} -class @\exposid{run-loop-sender}@; +@\libconcept{sender}@ auto join() noexcept; \end{itemdecl} +\begin{itemdescr} \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} +\returns +\tcode{\exposid{make-sender}(\exposid{scope-join-t}(), this)}. +\end{itemdescr} -\pnum -An instance of \exposid{run-loop-sender} remains valid -until the end of the lifetime of its associated \tcode{run_loop} instance. +\indexlibrarymember{\exposid{try-associate}}{execution::simple_counting_scope}% +\begin{itemdecl} +@\exposid{assoc-t}@ @\exposid{try-associate}@() noexcept; +\end{itemdecl} +\begin{itemdescr} \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: +\effects +If \exposid{count} is equal to \tcode{max_associations}, then no effects. +Otherwise, if \exposid{state} is \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. +\exposid{unused}, +then increments \exposid{count} and changes \exposid{state} to \exposid{open}; \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. +\exposid{open} or \exposid{open-and-joining}, +then increments \exposid{count}; +\item +otherwise, no effects. \end{itemize} +\pnum +\returns +If \exposid{count} was incremented, +an object of type \exposid{assoc-t} +that is engaged and associated with \tcode{*this}, and +\tcode{\exposid{assoc-t}()} otherwise. +\end{itemdescr} + +\indexlibrarymember{\exposid{disassociate}}{execution::simple_counting_scope}% \begin{itemdecl} -template - struct @\exposid{run-loop-opstate}@; +void @\exposid{disassociate}@() noexcept; \end{itemdecl} +\begin{itemdescr} \pnum -\tcode{\exposid{run-loop-opstate}} -inherits privately and unambiguously from \exposid{run-loop-opstate-base}. +\expects +\exposid{count} is greater than zero. \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: +\effects +Decrements \exposid{count}. +If \exposid{count} is zero after decrementing and +\exposid{state} is \exposid{open-and-joining} or \exposid{closed-and-joining}, +changes \exposid{state} to \exposid{joined} and +calls \tcode{\exposid{complete}()} on all objects registered with \tcode{*this}. +\begin{note} +Calling \tcode{\exposid{complete}()} on any registered object +can cause \tcode{*this} to be destroyed. +\end{note} +\end{itemdescr} + +\indexlibrarymember{\exposid{start-join-sender}}{execution::simple_counting_scope}% +\begin{itemdecl} +template + bool @\exposid{start-join-sender}@(State& st) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{count} is zero, then +changes \exposid{state} to \exposid{joined} and returns \tcode{true}. +Otherwise, if \exposid{state} is \begin{itemize} \item -The object to which \tcode{\exposid{REC}($o$)} refers -remains valid for the lifetime of the object to which $o$ refers. +\exposid{open} or \exposid{open-and-joining}, then +changes \exposid{state} to \exposid{open-and-joining}, +registers \tcode{st} with \tcode{*this} and returns \tcode{false}; \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: +\exposid{closed} or \exposid{closed-and-joining}, then +changes \exposid{state} to \exposid{closed-and-joining}, +registers \tcode{st} with \tcode{*this} and returns \tcode{false}. +\end{itemize} +\end{itemdescr} + +\rSec4[exec.simple.counting.token]{Token} + +\indexlibraryglobal{execution::simple_counting_scope::token}% \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$@))); +namespace std::execution { + struct simple_counting_scope::token { + template<@\libconcept{sender}@ Sender> + Sender&& wrap(Sender&& snd) const noexcept; + @\exposid{assoc-t}@ try_associate() const noexcept; + + private: + simple_counting_scope* @\exposid{scope}@; // \expos + }; } \end{codeblock} -\item -The expression \tcode{start($o$)} is equivalent to: + +\indexlibrarymember{wrap}{execution::simple_counting_scope::token}% +\begin{itemdecl} +template<@\libconcept{sender}@ Sender> + Sender&& wrap(Sender&& snd) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{std::forward(snd)}. +\end{itemdescr} + +\indexlibrarymember{try_associate}{execution::simple_counting_scope::token}% +\begin{itemdecl} +@\exposid{assoc-t}@ try_associate() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{scope}->\exposid{try-associate}();} +\end{itemdescr} + +\rSec3[exec.scope.counting]{Counting Scope} + +\indexlibraryglobal{execution::counting_scope}% +\indexlibrarymember{token}{execution::counting_scope}% \begin{codeblock} -try { - @$o$@.@\exposid{loop}@->@\exposid{push-back}@(addressof(@$o$@)); -} catch(...) { - set_error(std::move(@\exposid{REC}@(@$o$@)), current_exception()); +namespace std::execution { + class counting_scope { + public: + using @\exposid{assoc-t}@ = @\exposid{association-t}@; // \expos + + struct token { + template<@\libconcept{sender}@ Sender> + @\libconcept{sender}@ auto wrap(Sender&& snd) const noexcept(@\seebelow@); + @\exposid{assoc-t}@ try_associate() const noexcept; + + private: + counting_scope* @\exposid{scope}@; // \expos + }; + + static constexpr size_t max_associations = @\UNSP{\impldef{value of \tcode{std::execution::counting_scope::max_associations}}}@; + + counting_scope() noexcept; + counting_scope(counting_scope&&) = delete; + ~counting_scope(); + + token get_token() noexcept; + void close() noexcept; + @\libconcept{sender}@ auto join() noexcept; + void request_stop() noexcept; + + private: + size_t @\exposid{count}@; // \expos + @\exposid{scope-state-type}@ @\exposid{state}@; // \expos + inplace_stop_source @\exposid{s_source}@; // \expos + + @\exposid{assoc-t}@ @\exposid{try-associate}@() noexcept; // \expos + void @\exposid{disassociate}@() noexcept; // \expos + + template + bool @\exposid{start-join-sender}@(State& state) noexcept; // \expos + }; } \end{codeblock} -\end{itemize} -\rSec3[exec.run.loop.ctor]{Constructor and destructor} +\pnum +\tcode{counting_scope} differs from \tcode{simple_counting_scope} by +adding support for cancellation. +Unless specified below, the semantics of members of \tcode{counting_scope} +are the same as the corresponding members of \tcode{simple_counting_scope}. -\indexlibraryctor{run_loop}% +\indexlibrarymember{get_token}{execution::counting_scope}% \begin{itemdecl} -run_loop() noexcept; +token get_token() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\ensures -\exposid{count} is \tcode{0} and \exposid{state} is \exposid{starting}. +\returns +An object \tcode{t} of type \tcode{counting_scope::token} such that +\tcode{t.\exposid{scope} == this} is \tcode{true}. \end{itemdescr} -\indexlibrarydtor{run_loop}% +\indexlibrarymember{request_stop}{execution::counting_scope}% \begin{itemdecl} -~run_loop(); +void request_stop() noexcept; \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} +Equivalent to \tcode{\exposid{s_source}.request_stop()}. -\rSec3[exec.run.loop.members]{Member functions} +\pnum +\remarks +Calls to \tcode{request_stop} do not introduce data races. +\end{itemdescr} +\indexlibrarymember{\exposid{try-associate}}{execution::counting_scope}% \begin{itemdecl} -@\exposid{run-loop-opstate-base}@* @\exposid{pop-front}@(); +@\exposid{assoc-t}@ @\exposid{try-associate}@() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Blocks\iref{defns.block} until one of the following conditions is \tcode{true}: +If \exposid{count} is equal to \tcode{max_associations}, +then no effects. +Otherwise, if \exposid{state} is \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 +\exposid{unused}, then increments \exposid{count} and +changes \exposid{state} to \exposid{open}; \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. +\exposid{open} or \exposid{open-and-joining}, then increments \exposid{count}; +\item +otherwise, no effects. \end{itemize} + +\pnum +\returns +If \exposid{count} was incremented, +an object of type \exposid{assoc-t} +that is engaged and associated with \tcode{*this}, and +\tcode{\exposid{assoc-t}()} otherwise. \end{itemdescr} +\indexlibrarymember{wrap}{execution::counting_scope::token}% \begin{itemdecl} -void @\exposid{push-back}@(@\exposid{run-loop-opstate-base}@* item); +template<@\libconcept{sender}@ Sender> + @\libconcept{sender}@ auto counting_scope::token::wrap(Sender&& snd) const + noexcept(is_nothrow_constructible_v, Sender>); \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}. +Equivalent to: +\begin{codeblock} +return @\exposid{stop-when}@(std::forward(snd), @\exposid{scope}@->@\exposid{s_source}@.get_token()); +\end{codeblock} \end{itemdescr} -\indexlibrarymember{get_scheduler}{run_loop}% +\indexlibrarymember{wrap}{execution::counting_scope::token}% \begin{itemdecl} -@\exposid{run-loop-scheduler}@ get_scheduler(); +@\exposid{assoc-t}@ counting_scope::token::try_associate() const noexcept; \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. +\effects +Equivalent to: \tcode{return \exposid{scope}->\exposid{try-associate}();} \end{itemdescr} -\indexlibrarymember{run}{run_loop}% +\rSec1[exec.par.scheduler]{Parallel scheduler} + +\begin{codeblock} +namespace std::execution { + class @\libglobal{parallel_scheduler}@ { + @\unspec@ + }; +} +\end{codeblock} + +\pnum +\tcode{parallel_scheduler} models \libconcept{scheduler}. + +\pnum +Let \tcode{sch} be an object of type \tcode{parallel_scheduler}, and +let \tcode{\exposid{BACKEND-OF}(sch)} be \tcode{*ptr}, +where \tcode{sch} is associated with \tcode{ptr}. + +\pnum +The expression \tcode{get_forward_progress_guarantee(sch)} has the value +\tcode{forward_progress_guarantee::\brk{}parallel}. + +\pnum +Let \tcode{sch2} be an object of type \tcode{parallel_scheduler}. +Two objects \tcode{sch} and \tcode{sch2} compare equal if and only if +\tcode{\exposid{BACKEND-OF}(sch)} and +\tcode{\exposid{BACKEND-OF}(sch2)} refer to the same object. + +\pnum +Let \tcode{rcvr} be a receiver. +A \defnx{proxy for \tcode{rcvr} with base \tcode{B}}{proxy} is +an lvalue \tcode{r} of type \tcode{B} such that: +\begin{itemize} +\item +\tcode{r.set_value()} has effects equivalent to +\tcode{set_value(std::move(rcvr))}. +\item +\tcode{r.set_error(e)}, where \tcode{e} is an \tcode{exception_ptr} object, +has effects equivalent to \tcode{set_error(std::move(\brk{}rcvr), std::move(e))}. +\item +\tcode{r.set_stopped()} has effects equivalent to +\tcode{set_stopped(std::move(rcvr))}. +\end{itemize} + +\pnum +A \defn{preallocated backend storage for a proxy} \tcode{r} is +an object \tcode{s} of type \tcode{span} +such that the range \tcode{s} remains valid and may be overwritten +until one of \tcode{set_value}, \tcode{set_error}, or \tcode{set_stopped} +is called on \tcode{r}. +\begin{note} +The storage referenced by \tcode{s} can be used as temporary storage +for operations launched via calls to \tcode{parallel_scheduler_backend}. +\end{note} + +\pnum +Let \tcode{b} be \tcode{\exposid{BACKEND-OF}(sch)}, +let \tcode{sndr} be the object returned by \tcode{schedule(sch)}, and +let \tcode{rcvr} be a receiver. +If \tcode{rcvr} is connected to \tcode{sndr} and +the resulting operation state is started, then: +\begin{itemize} +\item +If \tcode{sndr} completes successfully, +then \tcode{b.schedule(r, s)} is called, where +\begin{itemize} +\item +\tcode{r} is a proxy for \tcode{rcvr} +with base \tcode{parallel_scheduler_replacement::receiver_proxy} and +\item +\tcode{s} is a preallocated backend storage for \tcode{r}. +\end{itemize} +\item +All other completion operations are forwarded unchanged. +\end{itemize} + +\pnum +The expression \tcode{get_domain(sch)} +returns an expression of exposition-only type +\exposid{parallel-scheduler-do\-main}, that is equivalent with: + +\begin{codeblock} +struct @\exposid{parallel-scheduler-domain}@ { + template<@\exposconcept{sender-for}@ Sndr, @\exposconcept{queryable}@ Env> + static constexpr decltype(auto) + transform_sender(set_value_t, Sndr&& sndr, const Env& env) const noexcept { + return @\seebelow@; + } + template<@\exposconcept{sender-for}@ Sndr, @\exposconcept{queryable}@ Env> + static constexpr decltype(auto) + transform_sender(set_value_t, Sndr&& sndr, const Env& env) const noexcept { + return @\seebelow@; + } +}; +\end{codeblock} + +\pnum +For argument \tcode{sndr} of the above \tcode{transform_sender}, +let \tcode{child}, \tcode{pol}, \tcode{shape} and \tcode{f} +be defined by the following declarations: +\begin{codeblock} +auto& [_, data, child] = sndr; +auto& [pol, shape, f] = data; +\end{codeblock} + +\pnum +Let \tcode{p} be +\begin{itemize} +\item +\tcode{true}, if the type of the expression \tcode{pol} is +\cv{}~\tcode{parallel_policy} or \cv{}~\tcode{parallel_unsequenced_policy}; +\item +\impldef{parallelism flag for an implementation-defined execution policy}, +if \tcode{pol} is an implementation-defined execution policy; +\item +\tcode{false}, otherwise. +\end{itemize} + +\pnum +The \tcode{transform_sender} overload +that accepts senders with tag \tcode{bulk_chunked_t} +returns a sender such that if it is connected to a receiver \tcode{rcvr} and +the resulting operation state is started, then: +\begin{itemize} +\item +If \tcode{child} completes with values \tcode{vals}, +let \tcode{args} be a pack of lvalue subexpressions designating \tcode{vals}, +then \tcode{b.schedule_bulk_chunked(p ? shape : 1, r, s)} is called, where +\begin{itemize} +\item +\tcode{r} is a proxy for \tcode{rcvr} +with base \tcode{parallel_scheduler_replacement::bulk_item_receiver_proxy} +such that \tcode{r.execute(i, j)} for indices \tcode{i} and \tcode{j} +has effects equivalent to +\tcode{f(i, j, args...)} if \tcode{p} is true and +\tcode{f(0, shape, args...)} otherwise; and +\item +\tcode{s} is a preallocated backend storage for \tcode{r}. +\end{itemize} +\item +All other completion operations are forwarded unchanged. +\end{itemize} + +\pnum +The \tcode{transform_sender} overload +that accepts senders with tag \tcode{bulk_unchunked_t} +returns a sender such that if it is connected to a receiver \tcode{rcvr} and +the resulting operation state is started, then: +\begin{itemize} +\item +If \tcode{child} completes with values \tcode{vals}, +let \tcode{args} be a pack of lvalue subexpressions designating \tcode{vals}, +then \tcode{b.schedule_bulk_unchunked(p ? shape : 1, r, s)} is called, where +\begin{itemize} +\item +\tcode{r} is a proxy for \tcode{rcvr} +with base \tcode{parallel_scheduler_replacement::bulk_item_receiver_proxy} +such that \tcode{r.execute(i, i + 1)} for index \tcode{i} +has effects equivalent to +\tcode{f(i, args...)} if \tcode{p} is true and +\begin{codeblock} +for (decltype(shape) i = 0; i < shape; i++) { f(i, args...); } +\end{codeblock} +otherwise; and +\item +\tcode{s} is a preallocated backend storage for \tcode{r}. +\end{itemize} +\item +All other completion operations are forwarded unchanged. +\end{itemize} + +\indexlibraryglobal{get_parallel_scheduler}% \begin{itemdecl} -void run(); +parallel_scheduler get_parallel_scheduler(); \end{itemdecl} \begin{itemdescr} \pnum -\expects -\exposid{state} is either \exposid{starting} or \exposid{finishing}. +\effects +Let \tcode{eb} be the result of \tcode{parallel_scheduler_replacement::query_parallel_scheduler_backend()}. +If \tcode{eb == nullptr} is \tcode{true}, +calls \tcode{terminate}\iref{except.terminate}. +Otherwise, returns a \tcode{parallel_scheduler} object +associated with \tcode{eb}. +\end{itemdescr} + +\rSec1[exec.parschedrepl]{Namespace \tcode{parallel_scheduler_replacement}} + +\rSec2[exec.parschedrepl.general]{General} \pnum -\effects -If \exposid{state} is \exposid{starting}, -sets the \exposid{state} to \exposid{running}, -otherwise leaves \exposid{state} unchanged. -Then, equivalent to: +Facilities in the \tcode{parallel_scheduler_replacement} namespace +allow users to replace the default implementation of \tcode{parallel_scheduler}. + +\rSec2[exec.parschedrepl.recvproxy]{Receiver proxies} + \begin{codeblock} -while (auto* op = @\exposid{pop-front}@()) { - op->@\exposid{execute}@(); +namespace std::execution::parallel_scheduler_replacement { + struct @\libglobal{receiver_proxy}@ { + protected: + virtual bool @\exposidnc{query-env}@(@\unspecnc@) noexcept = 0; // \expos + + public: + virtual void set_value() noexcept = 0; + virtual void set_error(exception_ptr) noexcept = 0; + virtual void set_stopped() noexcept = 0; + + template + optional

try_query(Query q) const noexcept; + }; + + struct @\libglobal{bulk_item_receiver_proxy}@ : receiver_proxy { + virtual void execute(size_t, size_t) noexcept = 0; + }; } \end{codeblock} \pnum -\remarks -When \exposid{state} changes, it does so without introducing data races. -\end{itemdescr} +\tcode{receiver_proxy} represents a receiver +that will be notified +by the implementations of \tcode{parallel_scheduler_backend} +to trigger the completion operations. +\tcode{bulk_item_receiver_proxy} is derived from \tcode{receiver_proxy} and +is used for \tcode{bulk_chunked} and \tcode{bulk_unchunked} customizations +that will also receive notifications +from implementations of \tcode{parallel_scheduler_backend} +corresponding to different iterations. -\indexlibrarymember{finish}{run_loop}% \begin{itemdecl} -void finish(); +template + optional

@\libglobal{try_query}@(Query q) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\expects -\exposid{state} is either \exposid{starting} or \exposid{running}. +\mandates +\tcode{P} is a cv-unqualified non-array object type. \pnum -\effects -Changes \exposid{state} to \exposid{finishing}. +\returns +Let \tcode{env} be the environment of the receiver represented by \tcode{*this}. +If +\begin{itemize} +\item +\tcode{Query} is not a member of an implementation-defined set +of supported queries; or +\item +\tcode{P} is not a member of an implementation-defined set +of supported result types for \tcode{Query}; or +\item +the expression \tcode{q(env)} is not well-formed, +\end{itemize} +then returns \tcode{nullopt}. +Otherwise, if \tcode{q(env)} has type \cv{}~\tcode{P}, +then returns \tcode{q(env)}. +Otherwise, returns an +\impldef{return value of \tcode{receiver_proxy::try_query}} value +of type \tcode{optional

}. \pnum -\sync -\tcode{finish} synchronizes with the \exposid{pop-front} operation -that returns \tcode{nullptr}. +\remarks +\tcode{get_stop_token_t} is +in the implementation-defined set of supported queries, and +\tcode{inplace_stop_token} is a member +of the implementation-defined set of supported result types +for \tcode{get_stop_token_t}. + +\pnum +\recommended +If \tcode{P} is \tcode{inplace_stop_token} and +\tcode{T} is a type other than \tcode{inplace_stop_token} +that models \libconcept{stoppable_token}, +\tcode{try_query} should return an object of type \tcode{inplace_stop_token} +such that until one of +\tcode{set_value}, +\tcode{set_error} or +\tcode{set_stopped} +is called on \tcode{*this}, +all calls to \tcode{try_query} return equivalent \tcode{inplace_stop_token} objects. \end{itemdescr} -\rSec1[exec.coro.util]{Coroutine utilities} +\rSec2[exec.parschedrepl.query]{\tcode{query_parallel_scheduler_backend}} -\rSec2[exec.as.awaitable]{\tcode{execution::as_awaitable}} +\indexlibraryglobal{query_parallel_scheduler_backend}% +\begin{itemdecl} +shared_ptr query_parallel_scheduler_backend(); +\end{itemdecl} +\begin{itemdescr} \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}@>; - }; +\tcode{query_parallel_scheduler_backend()} returns +the implementation object for a parallel scheduler. - template - class @\exposidnc{sender-awaitable}@; // \expos -} -\end{codeblock} +\pnum +\returns +An object \tcode{p}, +such that \tcode{p.get()} points to a \tcode{parallel_scheduler_backend} object +that is a base-class subobject +of some most derived object \tcode{o} within its lifetime. +The lifetime of \tcode{o} does not end +as long as there exists a \tcode{shared_ptr} object \tcode{q} within its lifetime +such that \tcode{q.owner_equal(p)} is \tcode{true}. \pnum -The type \tcode{\exposid{sender-awaitable}} is equivalent to: +\remarks +This function is replaceable\iref{term.replaceable.function}. +\end{itemdescr} -\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 +\rSec2[exec.parschedrepl.psb]{Class \tcode{parallel_scheduler_backend}} - variant @\exposidnc{result}@{}; // \expos - connect_result_t @\exposidnc{state}@; // \expos +\begin{codeblock} +namespace std::execution::parallel_scheduler_replacement { + struct @\libglobal{parallel_scheduler_backend}@ { + virtual ~parallel_scheduler_backend() = default; - 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(); + virtual void schedule(receiver_proxy&, span) noexcept = 0; + virtual void schedule_bulk_chunked(size_t, bulk_item_receiver_proxy&, + span) noexcept = 0; + virtual void schedule_bulk_unchunked(size_t, bulk_item_receiver_proxy&, + span) noexcept = 0; }; } \end{codeblock} +\indexlibrarymember{schedule}{parallel_scheduler_backend}% +\begin{itemdecl} +virtual void schedule(receiver_proxy& r, span s) noexcept = 0; +\end{itemdecl} + +\begin{itemdescr} \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} +\expects +The ends +of the lifetime of \tcode{*this}, +of the lifetime of the object referred to by \tcode{r}, and +of the duration of any storage referenced by \tcode{s} +all happen after +the beginning of the evaluation of +the call to \tcode{set_value}, \tcode{set_error}, or \tcode{set_stopped} +on \tcode{r} (see below). \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: +\effects +A derived class shall implement this function such that: \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. +One of the following expressions is evaluated: +\begin{itemize} \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} +\tcode{r.set_value()}, if no error occurs, and the work is successful; \item -The expression \tcode{set_stopped(rcvr)} is equivalent to: -\begin{codeblock} -static_cast>(rcvr.@\exposid{continuation}@.promise().unhandled_stopped()).resume(); -\end{codeblock} +\tcode{r.set_error(eptr)}, if an error occurs, +where \tcode{eptr} is an object of type \tcode{exception_ptr}; \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} +\tcode{r.set_stopped()}, if the work is canceled. +\end{itemize} +\item +Any call to \tcode{r.set_value()} happens on +an execution agent of the execution context represented by \tcode{*this}. \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} +\remarks +The storage referenced by \tcode{s} +may be used by \tcode{*this} as temporary storage +for the duration of the operation launched by this call. \end{itemdescr} +\indexlibrarymember{schedule_bulk_chunked}{parallel_scheduler_backend}% \begin{itemdecl} -@\exposid{value-type}@ await_resume(); +virtual void schedule_bulk_chunked(size_t n, bulk_item_receiver_proxy& r, + span s) noexcept = 0; \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} +\expects +The ends +of the lifetime of \tcode{*this}, +of the lifetime of the object referred to by \tcode{r}, and +of the duration of any storage referenced by \tcode{s} +all happen after +the beginning of the evaluation of the call to +\tcode{set_value}, \tcode{set_error}, or \tcode{set_stopped} +on \tcode{r} (see below). \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: +\effects +A derived class shall implement this function such that: \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. +Eventually, one of the following expressions is evaluated: +\begin{itemize} \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}. +\tcode{r.set_value()}, if no error occurs, and the work is successful; \item -Otherwise, \tcode{\exposid{sender-awaitable}\{expr, p\}} -if \tcode{\exposconcept{awaitable-sender}} is \tcode{true}. +\tcode{r.set_error(eptr)}, if an error occurs, +where \tcode{eptr} is an object of type \tcode{exception_ptr}; \item -Otherwise, \tcode{(void(p), expr)}. +\tcode{r.set_stopped()}, if the work is canceled. +\end{itemize} +\item +If \tcode{r.execute(b, e)} is called, +then \tcode{b} and \tcode{e} are in the range \crange{0}{n} and +$\tcode{b} < \tcode{e}$. +\item +For each $i$ in \range{0}{n}, +there is at most one call to \tcode{r.execute(b, e)} +such that $i$ is in the range \range{b}{e}. +\item +If \tcode{r.set_value()} is called, +then for each $i$ in \range{0}{n}, +there is exactly one call to \tcode{r.execute(b, e)} +such that $i$ is in the range \range{b}{e}. +\item +All calls to \tcode{execute} on \tcode{r} happen before +the call to either \tcode{set_value}, \tcode{set_error}, or \tcode{set_stopped} +on \tcode{r}. +\item +All calls to \tcode{execute} and \tcode{set_value} on \tcode{r} are made +on execution agents of the execution context represented by \tcode{*this}. \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} +\remarks +The storage referenced by \tcode{s} may be used by \tcode{*this} +as temporary storage for the duration of the operation launched by this call. +\end{itemdescr} -\indexlibrarymember{set_continuation}{with_awaitable_senders}% +\indexlibrarymember{schedule_bulk_unchunked}{parallel_scheduler_backend}% \begin{itemdecl} -template - requires (!@\libconcept{same_as}@) -void set_continuation(coroutine_handle h) noexcept; +virtual void schedule_bulk_unchunked(size_t n, bulk_item_receiver_proxy& r, + span s) noexcept = 0; \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} +\expects +The ends +of the lifetime of \tcode{*this}, +of the lifetime of the object referred to by \tcode{r}, and +of the duration of any storage referenced by \tcode{s} +all happen after +the beginning of the evaluation of the call to +\tcode{set_value}, \tcode{set_error}, or \tcode{set_stopped} +on \tcode{r} (see below). -\begin{itemdescr} \pnum \effects -Equivalent to: -\begin{codeblock} -return as_awaitable(std::forward(value), static_cast(*this)); -\end{codeblock} +A derived class shall implement this function such that: +\begin{itemize} +\item +Eventually, one of the following expressions is evaluated: +\begin{itemize} +\item +\tcode{r.set_value()}, if no error occurs, and the work is successful; +\item +\tcode{r.set_error(eptr)}, if an error occurs, +where \tcode{eptr} is an object of type \tcode{exception_ptr}; +\item +\tcode{r.set_stopped()}, if the work is canceled. +\end{itemize} +\item +If \tcode{r.execute(b, e)} is called, +then \tcode{b} is in the range \range{0}{n} and +\tcode{e} is equal to \tcode{b + 1}. +For each $i$ in \range{0}{n}, +there is at most one call to \tcode{r.execute($i$, $i$ + 1)}. +\item +If \tcode{r.set_value()} is called, +then for each $i$ in \range{0}{n}, +there is exactly one call to \tcode{r.execute($i$, $i$ + 1)}. +\item +All calls to \tcode{execute} on \tcode{r} happen before +the call to either \tcode{set_value}, \tcode{set_error}, or \tcode{set_stopped} +on \tcode{r}. +\item +All calls to \tcode{execute} and \tcode{set_value} on \tcode{r} are made +on execution agents of the execution context represented by \tcode{*this}. +\end{itemize} + +\pnum +\remarks +The storage referenced by \tcode{s} may be used by \tcode{*this} +as temporary storage for the duration of the operation launched by this call. \end{itemdescr} diff --git a/source/expressions.tex b/source/expressions.tex index c3261ce53e..fb3c8c03bb 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -39,7 +39,7 @@ obey the rules for syntax and evaluation order specified in \ref{expr.compound}, but the requirements of operand type and value category are replaced by the rules for function call. Relations between operators, such as -\tcode{++a} meaning \tcode{a+=1}, are not guaranteed for overloaded +\tcode{++a} meaning \tcode{a += 1}, are not guaranteed for overloaded operators\iref{over.oper}. \end{note} @@ -62,9 +62,52 @@ \indextext{overflow!undefined}% \indextext{zero!division by undefined}% \indextext{zero!remainder undefined}% -If during the evaluation of an expression, the result is not -mathematically defined or not in the range of representable values for -its type, the behavior is undefined. +An \defnadj{arithmetic}{expression} is +\begin{itemize} +\item a unary plus or minus\iref{expr.unary.op}, +\item an addition\iref{expr.add}, +\item a subtraction\iref{expr.sub}, or +\item a multiplication, division, or remainder\iref{expr.mul} +\end{itemize} +expression where every (possibly converted) operand is of arithmetic type. +\begin{note} +There exist non-arithmetic expressions such as compound assignment\iref{expr.assign} +which are defined in terms of arithmetic expressions. +\end{note} +The behavior of evaluating an arithmetic expression is undefined\ubdef{expr.expr.eval} +if the mathematical result is neither +\begin{itemize} +\item +in the range of representable values for its type nor +\item +a negative infinity, positive infinity, or NaN +that is among the values of the type. +\end{itemize} +\begin{note} +If the operands are of a type that adheres to \IsoFloatUndated, +division by zero is the only case +where an arithmetic expression has undefined behavior\iref{expr.mul}. +However, some well-defined arithmetic expressions +are not core constant expressions\iref{expr.const.core}. +\begin{example} +The following example assumes that \tcode{std::float32_t} is supported\iref{basic.extended.fp}. +\begin{codeblock} +constexpr std::float32_t min = std::numeric_limits::min(); // OK +constexpr std::float32_t max = std::numeric_limits::max(); // OK +constexpr std::float32_t inf = std::numeric_limits::infinity(); // OK +constexpr std::float32_t nan = std::numeric_limits::quiet_NaN(); // OK + +// Furthermore, if arithmetic expressions with operands of type \tcode{std::float32_t} +// behave as specified in ISO/IEC 60559 for binary32: +constexpr std::float32_t inf2 = inf * 2; // OK, also positive infinity +constexpr std::float32_t zero = min / max; // OK, result cannot be represented, and is rounded to zero +constexpr std::float32_t oflo = max * 2; // error: non-finite result but operands are finite\iref{expr.const.core} +constexpr std::float32_t nan2 = nan * 2; // OK, propagating a NaN +constexpr std::float32_t udef = inf * 0; // error: result is NaN but neither operand is NaN\iref{expr.const.core} +constexpr std::float32_t div0 = max / 0; // error: division by zero is undefined\iref{expr.mul,expr.const.core} +\end{codeblock} +\end{example} +\end{note} \begin{note} \indextext{overflow}% Treatment of division by zero, forming a remainder using a zero divisor, @@ -95,7 +138,7 @@ \end{codeblock} due to the associativity and precedence of these operators. Thus, the result of the sum \tcode{(a + 32760)} is next added to \tcode{b}, and -that result is then added to 5 which results in the value assigned to +that result is then added to \tcode{5} which results in the value assigned to \tcode{a}. On a machine in which overflows produce an exception and in which the range of values representable by an \tcode{int} is \crange{-32768}{+32767}, the implementation cannot rewrite this @@ -131,7 +174,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} @@ -147,7 +190,10 @@ \end{importgraphic} \begin{itemize} -\item A \defn{glvalue} is an expression whose evaluation determines the identity of an object or function. +\item A \defn{glvalue} is an expression +whose evaluation determines the identity of +an object, function, non-static data member, or +a direct base class relationship. \item A \defn{prvalue} is an expression whose evaluation initializes an object or computes the value of an operand of an operator, as specified by the context in which it appears, @@ -186,7 +232,8 @@ \begin{note} An expression is an xvalue if it is: \begin{itemize} -\item a move-eligible \grammarterm{id-expression}\iref{expr.prim.id.unqual}, +\item a move-eligible \grammarterm{id-expression}\iref{expr.prim.id.unqual} +or \grammarterm{splice-expression}\iref{expr.prim.splice}, \item the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to object type\iref{expr.call}, @@ -233,13 +280,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} @@ -267,9 +312,10 @@ \pnum Unless otherwise specified\iref{expr.reinterpret.cast, expr.const.cast}, -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 +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 @@ -297,7 +343,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 @@ -314,7 +360,7 @@ If a program attempts to access\iref{defns.access} the stored value of an object through a glvalue through which it is not type-accessible, -the behavior is undefined. +the behavior is undefined\ubdef{expr.basic.lvalue.strict.aliasing.violation}. \begin{footnote} The intent of this list is to specify those circumstances in which an object can or cannot be aliased. @@ -322,8 +368,8 @@ 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, -the behavior is undefined. +that does not denote an object of type \cv{}~\tcode{U} within its lifetime, +the behavior is undefined\ubdef{expr.basic.lvalue.union.initialization}. \begin{note} In C, an entire object of structure type can be accessed, e.g., using assignment. By contrast, \Cpp{} has no notion of accessing an object of class type @@ -342,7 +388,7 @@ 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. +otherwise, the behavior is undefined\ubdef{expr.type.reference.lifetime}. \begin{note} Before the lifetime of the reference has started or after it has ended, the behavior is undefined (see~\ref{basic.life}). @@ -382,8 +428,8 @@ ``pointer to function''; \item -if \tcode{T1} is ``pointer to \cvqual{cv1} \tcode{C1}'' and \tcode{T2} is ``pointer to -\cvqual{cv2} \tcode{C2}'', where \tcode{C1} is reference-related to \tcode{C2} or \tcode{C2} is +if \tcode{T1} is ``pointer to \tcode{C1}'' and \tcode{T2} is ``pointer to +\tcode{C2}'', where \tcode{C1} is reference-related to \tcode{C2} or \tcode{C2} is reference-related to \tcode{C1}\iref{dcl.init.ref}, the qualification-combined type\iref{conv.qual} of \tcode{T1} and \tcode{T2} or the qualification-combined type of \tcode{T2} and \tcode{T1}, @@ -443,6 +489,7 @@ expr.typeid, expr.sizeof, expr.unary.noexcept, +expr.reflect, dcl.type.decltype, temp.pre, temp.concept}. @@ -468,6 +515,7 @@ \item \tcode{(} \grammarterm{expression} \tcode{)}, where \grammarterm{expression} is one of these expressions, \item \grammarterm{id-expression}\iref{expr.prim.id}, +\item \grammarterm{splice-expression}\iref{expr.prim.splice}, \item subscripting\iref{expr.sub}, \item class member access\iref{expr.ref}, \item indirection\iref{expr.unary.op}, @@ -557,7 +605,7 @@ \pnum An expression $E$ can be \defnx{implicitly converted}{conversion!implicit} to a type \tcode{T} if and only if the -declaration \tcode{T t=$E$;} is well-formed, for some invented temporary +declaration \tcode{T t = $E$;} is well-formed, for some invented temporary variable \tcode{t}\iref{dcl.init}. \pnum @@ -675,13 +723,9 @@ type, the conversion copy-initializes the result object from 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 -\impldef{lvalue-to-rvalue conversion of an invalid pointer value}. - \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. +are not valid for the object's type, the behavior is undefined\ubdef{conv.lval.valid.representation}. \begin{example} \begin{codeblock} bool f() { @@ -695,11 +739,20 @@ \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 +The prvalue result is +\begin{itemize} +\item +the value of type \tcode{T} congruent\iref{basic.fundamental} to \tcode{V} +if \tcode{T} is an integer type, +\item +the result of \tcode{reinterpret_cast(reinterpret_cast(V))} +if \tcode{T} is volatile-qualified +and \tcode{V} is a pointer value +that is not valid in the context of the evaluation\iref{basic.compound}, and +\item \tcode{V} otherwise. \end{itemize} +\end{itemize} \pnum \begin{note} @@ -712,11 +765,15 @@ \indextext{conversion!array-to-pointer}% \indextext{decay!array|see{conversion, array-to-pointer}}% \indextext{decay!function|see{conversion, function-to-pointer}}% -An lvalue or rvalue of type ``array of \tcode{N} \tcode{T}'' or ``array +An expression $E$ of type ``array of \tcode{N} \tcode{T}'' or ``array of unknown bound of \tcode{T}'' can be converted to a prvalue of type ``pointer to \tcode{T}''. -The temporary materialization conversion\iref{conv.rval} is applied. -The result is a pointer to the first element of the array. +If $E$ is a prvalue, +the temporary materialization conversion\iref{conv.rval} is applied. +If the result of $E$ (possibly converted) is an object +whose type is similar to the type of $E$, +the result is a pointer to the first element of the array; +otherwise, the behavior is undefined. \rSec2[conv.func]{Function-to-pointer conversion} @@ -780,10 +837,6 @@ as ``pointer to \tcode{\keyword{const} \keyword{int}}'', and as ``pointer to pointer to \tcode{\keyword{const} \keyword{int}}''. \end{example} -The $n$-tuple of cv-qualifiers after the first one -in the longest qualification-decomposition of \tcode{T}, that is, -$\cv{}_1, \cv{}_2, \dotsc, \cv{}_n$, is called the -\defn{cv-qualification signature} of \tcode{T}. \pnum \indextext{type!similar|see{similar types}}% @@ -984,7 +1037,7 @@ that exact representation. If the source value is between two adjacent destination values, the result of the conversion is an \impldef{result of inexact floating-point conversion} choice of either of those values. -Otherwise, the behavior is undefined. +Otherwise, the behavior is undefined\ubdef{conv.double.out.of.range}. \pnum The conversions allowed as floating-point promotions are excluded from @@ -998,7 +1051,7 @@ integer type. The conversion truncates; that is, the fractional part is discarded. \indextext{value!undefined unrepresentable integral}% -The behavior is undefined if the truncated value cannot be represented +The behavior is undefined\ubdef{conv.fpint.float.not.represented} if the truncated value cannot be represented in the destination type. \begin{note} If the destination type is \keyword{bool}, see~\ref{conv.bool}. @@ -1019,7 +1072,9 @@ exactly as a value of the floating-point type. \end{note} If the value being converted is -outside the range of values that can be represented, the behavior is undefined. If the +outside the range of values that can be represented, +the behavior is undefined\ubdef{conv.fpint.int.not.represented}. +If the source type is \keyword{bool}, the value \keyword{false} is converted to zero and the value \keyword{true} is converted to one. @@ -1065,13 +1120,14 @@ 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 +if \tcode{B} is a virtual base class of \tcode{D} +or is a base class of 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. +the behavior is undefined\ubdef{conv.ptr.virtual.base}. Otherwise, the result is a pointer to the base class subobject of the derived class object. @@ -1105,7 +1161,8 @@ \tcode{D}, a program that necessitates this conversion is ill-formed. If class \tcode{D} does not contain the original member and is not a base class of the class containing the original member, -the behavior is undefined. Otherwise, +the behavior is undefined\ubdef{conv.member.missing.member}. +Otherwise, the result of the conversion refers to the same member as the pointer to member before the conversion took place, but it refers to the base class member as if it were a member of the derived class. The result refers to @@ -1248,7 +1305,8 @@ id-expression\br lambda-expression\br fold-expression\br - requires-expression + requires-expression\br + splice-expression \end{bnf} \rSec2[expr.prim.literal]{Literals} @@ -1280,6 +1338,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 @@ -1364,7 +1432,6 @@ \pnum \indextext{name}% -\indextext{id-expression}% An \grammarterm{id-expression} is a restricted form of a \grammarterm{primary-expression}. \begin{note} @@ -1384,12 +1451,19 @@ $E$ is not the \grammarterm{id-expression} of a class member access expression\iref{expr.ref}, and \item +$E$ is not the \grammarterm{id-expression} of +a \grammarterm{reflect-expression}\iref{expr.reflect}, and +\item if $E$ is a \grammarterm{qualified-id}, $E$ is not the un-parenthesized operand of the unary \tcode{\&} operator\iref{expr.unary.op}, \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. @@ -1399,10 +1473,20 @@ \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 -a member $M$ of an anonymous union\iref{class.union.anon} $U$: +a variant member $M$ of an anonymous union\iref{class.union.anon} $U$: \begin{itemize} \item If $U$ is a non-static data member, @@ -1427,7 +1511,8 @@ \end{itemize} \pnum -An \grammarterm{id-expression} that denotes a non-static data member or +An \grammarterm{id-expression} or \grammarterm{splice-expression} +that designates a non-static data member or implicit object member function of a class can only be used: \begin{itemize} \item as part of a class member access @@ -1440,7 +1525,8 @@ \item to form a pointer to member\iref{expr.unary.op}, or -\item if that \grammarterm{id-expression} denotes a non-static data member +\item if that \grammarterm{id-expression} or \grammarterm{splice-expression} +designates a non-static data member and it appears in an unevaluated operand. \begin{example} \begin{codeblock} @@ -1449,10 +1535,15 @@ }; int i = sizeof(S::m); // OK int j = sizeof(S::m + 42); // OK +int S::*k = &[:^^S::m:]; // OK \end{codeblock} \end{example} \end{itemize} +\pnum +A \grammarterm{splice-expression} that designates a direct base class relationship +shall appear only as the second operand of a class member access. + \pnum For an \grammarterm{id-expression} that denotes an overload set, overload resolution is performed @@ -1499,10 +1590,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 @@ -1533,21 +1622,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 @@ -1557,26 +1653,7 @@ If $E$ is not declared \keyword{mutable}, the type of such an identifier will typically be \keyword{const} qualified. \end{note} -\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. -\end{itemize} -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}. -In all other cases, the type of the expression is the type of the entity. -\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} -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 -template parameter object; -and a prvalue otherwise\iref{basic.lval}; -it is a bit-field if the identifier designates a bit-field. + \begin{example} \begin{codeblock} void f() { @@ -1606,32 +1683,188 @@ \end{codeblock} \end{example} +\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 +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, +the type of the expression is \tcode{const U}. +\end{itemize} + +\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}, +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. + \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} or +\grammarterm{splice-expression}\iref{expr.prim.splice} +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 +it designates an implicitly movable entity, \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 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 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} @@ -1653,9 +1886,15 @@ type-name \terminal{::}\br namespace-name \terminal{::}\br computed-type-specifier \terminal{::}\br + splice-scope-specifier \terminal{::}\br nested-name-specifier identifier \terminal{::}\br nested-name-specifier \opt{\keyword{template}} simple-template-id \terminal{::} \end{bnf} +\begin{bnf} +\nontermdef{splice-scope-specifier}\br + splice-specifier\br + \opt{\keyword{template}} splice-specialization-specifier +\end{bnf} \pnum \indextext{component name}% @@ -1668,31 +1907,89 @@ \grammarterm{simple-template-id}, and/or \grammarterm{nested-name-specifier}. +\pnum +A \grammarterm{splice-specifier} or +\grammarterm{splice-specialization-specifier} +that is not followed by \tcode{::} +is never interpreted as part of a \grammarterm{splice-scope-specifier}. +The keyword \keyword{template} may only be omitted +from the form +\tcode{\opt{\keyword{template}} \grammarterm{splice-specialization-specifier} ::} +when the \grammarterm{splice-specialization-specifier} +is preceded by \keyword{typename}. +\begin{example} +\begin{codeblock} +template +struct TCls { + static constexpr int s = V; + using type = int; +}; + +int v1 = [:^^TCls<1>:]::s; +int v2 = template [:^^TCls:]<2>::s; // OK, \keyword{template} binds to \grammarterm{splice-scope-specifier} +typename [:^^TCls:]<3>::type v3 = 3; // OK, \keyword{typename} binds to the qualified name +template [:^^TCls:]<3>::type v4 = 4; // OK, \keyword{template} binds to the \grammarterm{splice-scope-specifier} +typename template [:^^TCls:]<3>::type v5 = 5; // OK, same as \tcode{v3} +[:^^TCls:]<3>::type v6 = 6; // error: unexpected \tcode{<} +\end{codeblock} +\end{example} + \pnum A \grammarterm{nested-name-specifier} is \defn{declarative} if it is part of \begin{itemize} \item -a \grammarterm{class-head-name}, +a \grammarterm{class-head-name}\iref{class.pre}, \item -an \grammarterm{enum-head-name}, +an \grammarterm{enum-head-name}\iref{dcl.enum}, \item a \grammarterm{qualified-id} -that is the \grammarterm{id-expression} of a \grammarterm{declarator-id}, or +that is the \grammarterm{id-expression} +of a \grammarterm{declarator-id}\iref{dcl.decl.general}, +\item +an \grammarterm{elaborated-type-specifier} +of an explicit instantiation\iref{temp.explicit}, or \item a declarative \grammarterm{nested-name-specifier}. \end{itemize} A declarative \grammarterm{nested-name-specifier} -shall not have a \grammarterm{computed-type-specifier}. +shall not have a \grammarterm{computed-type-specifier} or +a \grammarterm{splice-scope-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. \pnum -The \grammarterm{nested-name-specifier} \tcode{::} nominates +The entity designated by a \grammarterm{nested-name-specifier} +is determined as follows: +\begin{itemize} +\item +The \grammarterm{nested-name-specifier} \tcode{::} designates the global namespace. +\item A \grammarterm{nested-name-specifier} with a \grammarterm{computed-type-specifier} -nominates the type denoted by the \grammarterm{computed-type-specifier}, +designates the same type designated by the \grammarterm{computed-type-specifier}, which shall be a class or enumeration type. +\item +For a \grammarterm{nested-name-specifier} of +the form \tcode{\grammarterm{splice-specifier} ::}, +the \grammarterm{splice-specifier} shall designate +a class or enumeration type or a namespace. +The \grammarterm{nested-name-specifier} designates the same entity +as the \grammarterm{splice-specifier}. +\item +For a \grammarterm{nested-name-specifier} of +the form +\tcode{\opt{\keyword{template}} \grammarterm{splice-specialization-specifier} ::}, +the \grammarterm{splice-specifier} of +the \grammarterm{splice-specialization-specifier} shall designate +a class template or an alias template $T$. +Letting $S$ be the specialization of $T$ +corresponding to the template argument list of +the \grammarterm{splice-specialization-specifier}, +$S$ shall either be a class template specialization or +an alias template specialization that denotes a class or enumeration type. +The \grammarterm{nested-name-specifier} designates the underlying entity of $S$. +\item If a \grammarterm{nested-name-specifier} $N$ is declarative and has a \grammarterm{simple-template-id} with a template argument list $A$ @@ -1703,22 +2000,24 @@ \item If $A$ is the template argument list\iref{temp.arg} of the corresponding \grammarterm{template-head} $H$\iref{temp.mem}, -$N$ nominates the primary template of $T$; +$N$ designates the primary template of $T$; $H$ shall be equivalent to the \grammarterm{template-head} of $T$\iref{temp.over.link}. \item -Otherwise, $N$ nominates the partial specialization\iref{temp.spec.partial} of $T$ +Otherwise, $N$ designates the partial specialization\iref{temp.spec.partial} of $T$ whose template argument list is equivalent to $A$\iref{temp.over.link}; the program is ill-formed if no such partial specialization exists. \end{itemize} -Any other \grammarterm{nested-name-specifier} nominates -the entity denoted by its +\item +Any other \grammarterm{nested-name-specifier} designates +the entity denotes by its \grammarterm{type-name}, \grammarterm{namespace-name}, \grammarterm{identifier}, or \grammarterm{simple-template-id}. If the \grammarterm{nested-name-specifier} is not declarative, the entity shall not be a template. +\end{itemize} \pnum A \grammarterm{qualified-id} shall not be of the form @@ -1730,7 +2029,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 @@ -1760,7 +2084,7 @@ \pnum The \grammarterm{constant-expression} shall be -a converted constant expression\iref{expr.const} of type \tcode{std::size_t} +a converted constant expression\iref{expr.const.const} of type \tcode{std::size_t} whose value $V$, termed the index, is such that $0 \le V < \tcode{sizeof...($P$)}$. @@ -1830,10 +2154,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} @@ -1947,6 +2272,10 @@ called the \defn{closure type}, whose properties are described below. +\pnum +The closure type is incomplete +until the end of its corresponding \grammarterm{compound-statement}. + \pnum The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding @@ -1959,7 +2288,8 @@ \end{note} \pnum -The closure type is not an aggregate type\iref{dcl.init.aggr}; +The closure type is not an aggregate type\iref{dcl.init.aggr} +and is not \tcode{final}\iref{class.pre}; it is a structural type\iref{term.structural.type} if and only if the lambda has no \grammarterm{lambda-capture}. An implementation may define the closure type differently from what @@ -1967,9 +2297,7 @@ 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 a standard-layout class\iref{class.prop}. \end{itemize} @@ -1986,6 +2314,8 @@ respectively, and whose \grammarterm{template-parameter-list} consists of the specified \grammarterm{template-parameter-list}, if any. +The function call operator or the function call operator template are +direct members of the closure type. The \grammarterm{requires-clause} of the function call operator template is the \grammarterm{requires-clause} immediately following \tcode{<}~\grammarterm{template-parameter-list}{}~\tcode{>}, if any. @@ -2064,8 +2394,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. @@ -2144,6 +2475,51 @@ \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} @@ -2202,7 +2578,7 @@ @\commentellip@ } template using fptr_t = - decltype(lambda_call_operator_invoker(declval())) (*)(T); + decltype(lambda_call_operator_invoker(declval())) (*)(T); template operator fptr_t() const { return &lambda_call_operator_invoker; } @@ -2292,7 +2668,9 @@ }; \end{codeblock} \end{example} -Further, a variable \mname{func} is implicitly defined at the beginning of +Unless the \grammarterm{compound-statement} is +that of a \grammarterm{consteval-block-declaration}\iref{dcl.pre}, +a variable \mname{func} is implicitly defined at the beginning of the \grammarterm{compound-statement} of the \grammarterm{lambda-expression}, with semantics as described in~\ref{dcl.fct.def.general}. @@ -2352,7 +2730,7 @@ identifier \opt{\terminal{...}}\br \terminal{\&} identifier \opt{\terminal{...}}\br \keyword{this}\br - \terminal{*} \terminal{this} + \terminal{*} \keyword{this} \end{bnf} \begin{bnf} @@ -2363,7 +2741,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 @@ -2404,10 +2782,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} @@ -2464,7 +2851,8 @@ return x+2; }(); // Updates \tcode{::x} to 6, and initializes \tcode{y} to 7. -auto z = [a = 42](int a) { return 1; }; // error: parameter and conceptual local variable have the same name +auto z = [a = 42](int a) { return 1; }; // error: parameter and conceptual local variable + // have the same name auto counter = [i=0]() mutable -> decltype(i) { // OK, returns \tcode{int} return i++; }; @@ -2649,11 +3037,10 @@ \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 -these members is unspecified. The type of such a data member is -the referenced type if the entity is a reference to an object, -an lvalue reference to the referenced function type if the entity is a reference to a function, or -the type of the corresponding captured entity otherwise. +unnamed non-static data member is declared in the closure type. +The type of such a data member is the referenced type if the entity is a reference to an object, +an lvalue reference to the referenced function type if the entity is a reference to a function, +or the type of the corresponding captured entity otherwise. A member of an anonymous union shall not be captured by copy. \pnum @@ -2755,16 +3142,37 @@ \end{example} \pnum -When the \grammarterm{lambda-expression} is evaluated, the entities that are +The non-static data members in the closure type are declared in an unspecified order, +except that the members introduced for explicit captures are declared in an order +consistent with that of those captures. + +\pnum +The entities that are captured by copy are used to direct-initialize each corresponding non-static data member -of the resulting closure object, and the non-static data members corresponding to the -\grammarterm{init-capture}{s} are initialized as indicated by the corresponding -\grammarterm{initializer} (which may be copy- or direct-initialization). (For array members, the array elements are -direct-initialized in increasing subscript order.) These initializations are performed -in the (unspecified) order in which the non-static data members are declared. +of the resulting closure object. +The non-static data members corresponding to the \grammarterm{init-capture}{s} +and the (reference) variables declared by \grammarterm{init-capture}{s} +without corresponding non-static data members +are initialized as indicated by the corresponding \grammarterm{initializer} +(which may be copy- or direct-initialization). +(For array members, the array elements are direct-initialized in increasing subscript order.) +These initializations are performed +when the \grammarterm{lambda-expression} is evaluated, +in an order consistent with the (partially unspecified) order +in which the non-static data members are declared +and with the order of explicit captures. \begin{note} This ensures that the destructions will occur in the reverse order of the constructions. \end{note} +\begin{example} +\begin{codeblock} +void f(std::vector &&v) { + [size = v.size(), own = std::move(v)] {}; +} +\end{codeblock} +Since \tcode{size} is initialized before \tcode{own}, +it contains the original size of \tcode{v}. +\end{example} \pnum \begin{note} @@ -2891,7 +3299,7 @@ \end{bnf} \begin{bnf} -\microtypesetup{protrusion=false}\obeyspaces +\microtypesetup{protrusion=false} \nontermdef{requirement-body}\br \terminal{\{} requirement-seq \terminal{\}} \end{bnf} @@ -2982,7 +3390,7 @@ \end{note} If the substitution of template arguments into a \grammarterm{requirement} would always result in a substitution failure, the program is ill-formed; -no diagnostic required. +no diagnostic required\ifndrdef{expr.prim.req.always.sub.fail}. \begin{example} \begin{codeblock} template concept C = @@ -3030,13 +3438,16 @@ \begin{bnf} \nontermdef{type-requirement}\br - \keyword{typename} \opt{nested-name-specifier} type-name \terminal{;} + \keyword{typename} \opt{nested-name-specifier} type-name \terminal{;}\br + \keyword{typename} splice-specifier \terminal{;}\br + \keyword{typename} splice-specialization-specifier \terminal{;} \end{bnf} \pnum A \grammarterm{type-requirement} asserts the validity of a type. The component names of a \grammarterm{type-requirement} are those of its -\grammarterm{nested-name-specifier} (if any) and \grammarterm{type-name}. +\grammarterm{nested-name-specifier} (if any) and +\grammarterm{type-name} (if any). \begin{note} The enclosing \grammarterm{requires-expression} will evaluate to \keyword{false} if substitution of template arguments fails. @@ -3047,10 +3458,12 @@ template using Ref = T&; template concept C = requires { - typename T::inner; // required nested member name - typename S; // required valid\iref{temp.names} \grammarterm{template-id}; - // fails if \tcode{T::type} does not exist as a type to which \tcode{0} can be implicitly converted - typename Ref; // required alias template substitution, fails if \tcode{T} is void + typename T::inner; // required nested member name + typename S; // required valid\iref{temp.names} \grammarterm{template-id}; fails if \tcode{T::type} does not exist as a type + // to which \tcode{0} can be implicitly converted + typename Ref; // required alias template substitution, fails if \tcode{T} is \tcode{void} + typename [:T::r1:]; // fails if \tcode{T::r1} is not a reflection of a type + typename [:T::r2:]; // fails if \tcode{T::r2} is not a reflection of a template \tcode{Z} for which \tcode{Z} is a type }; \end{codeblock} \end{example} @@ -3064,7 +3477,7 @@ \begin{bnf} \nontermdef{compound-requirement}\br - \terminal{\{} expression \terminal{\}} \opt{\keyword{noexcept}} \opt{return-type-requirement} \terminal{;} + \terminal{\{} expression \terminal{\}} \opt{noexcept-specifier} \opt{return-type-requirement} \terminal{;} \end{bnf} \begin{bnf} @@ -3086,8 +3499,15 @@ into the \grammarterm{expression} is performed. \item -If the \keyword{noexcept} specifier is present, -$E$ shall not be a potentially-throwing expression\iref{except.spec}. +If the \grammarterm{noexcept-specifier}\iref{except.spec} is present, then: +\begin{itemize} +\item +Substitution of template arguments (if any) +into its associated \grammarterm{constant-expression} is performed. +\item +If the value of the converted \grammarterm{constant-expression} is \tcode{true}, +$E$ shall not be a potentially-throwing expression. +\end{itemize} \item If the \grammarterm{return-type-requirement} is present, then: @@ -3185,6 +3605,168 @@ \indextext{expression!requires|)} \indextext{expression!primary|)} +\rSec2[expr.prim.splice]{Expression splicing} + +\begin{bnf} +\nontermdef{splice-expression}\br + splice-specifier\br + \keyword{template} splice-specifier\br + \keyword{template} splice-specialization-specifier +\end{bnf} + +\pnum +A \grammarterm{splice-specifier} +or \grammarterm{splice-specialization-specifier} +immediately followed by \tcode{::} or preceded by \keyword{typename} +is never interpreted as part of a \grammarterm{splice-expression}. +\begin{example} +\begin{codeblock} +struct S { static constexpr int a = 1; }; +template struct TCls { static constexpr int b = 2; }; + +constexpr int c = [:^^S:]::a; // OK, \tcode{[:\caret\caret S:]} is not an expression +constexpr int d = template [:^^TCls:]::b; // OK, \tcode{template [:\caret\caret TCls:]} is not an expression +template constexpr int e = [:V:]; // OK +constexpr int f = template [:^^e:]<^^S::a>; // OK + +constexpr auto g = typename [:^^int:](42); // OK, \tcode{typename [:\caret\caret int:]} is a \grammarterm{splice-type-specifier} + +constexpr auto h = ^^g; +constexpr auto i = e<[:^^h:]>; // error: unparenthesized \grammarterm{splice-expression} used as template argument +constexpr auto j = e<([:^^h:])>; // OK +\end{codeblock} +\end{example} + +\pnum +For a \grammarterm{splice-expression} $E$ of the form \grammarterm{splice-specifier}, +let $S$ be the construct designated by \grammarterm{splice-specifier}. +\begin{itemize} +\item +The expression is ill-formed if $S$ is +\begin{itemize} +\item +a constructor, +\item +a destructor, +\item +an unnamed bit-field, or +\item +a local entity\iref{basic.pre} such that +\begin{itemize} +\item +there is a lambda scope that intervenes +between the expression and the point at which $S$ was introduced and +\item +the expression would be potentially evaluated +if the effect of any enclosing \keyword{typeid} expressions\iref{expr.typeid} +were ignored. +\end{itemize} +\end{itemize} +\item +Otherwise, if $S$ is a function $F$, +the expression denotes an overload set containing all declarations of $F$ +that precede either the expression or +the point immediately following the \grammarterm{class-specifier} of +the outermost class for which the expression is in a complete-class context; +overload resolution is performed\iref{over.match,over.over}. +\item +Otherwise, if $S$ is an object or a non-static data member, +the expression is an lvalue designating $S$. +The expression has the same type as that of $S$, and +is a bit-field if and only if $S$ is a bit-field. +\begin{note} +The implicit transformation +whereby an \grammarterm{id-expression} denoting a non-static member +becomes a class member access\iref{expr.prim.id} +does not apply to a \grammarterm{splice-expression}. +\end{note} +\item +Otherwise, if $S$ is a direct base class relationship $(\tcode{D}, \tcode{B})$, +the expression is an lvalue designating $S$. +The expression has the type \tcode{B}. +\item +Otherwise, if $S$ is a variable or a structured binding, +$S$ shall either have static or thread storage duration or +shall inhabit a scope enclosing the expression. +The expression $E$ is an lvalue referring to the object or function $X$ +associated with or referenced by $S$, and +is a bit-field if and only if $X$ is a bit-field. +If $E$ appears in the predicate of a contract assertion $C$\iref{basic.contract} +and $S$ 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 $E$ is \tcode{const T}, +otherwise $E$ has the same type as that of $S$. +\begin{note} +The type of a \grammarterm{splice-expression} +designating a variable or structured binding of reference type +will be adjusted to a non-reference type\iref{expr.type}. +\end{note} +\item +Otherwise, if $S$ is a value or an enumerator, +the expression is a prvalue that computes $S$ and +whose type is the same as that of $S$. +\item +Otherwise, the expression is ill-formed. +\end{itemize} + +\pnum +For a \grammarterm{splice-expression} of +the form \tcode{\keyword{template} \grammarterm{splice-specifier}}, +the \grammarterm{splice-specifier} shall designate a function template $T$ +that is not a constructor template. +The expression denotes an overload set containing all declarations of $T$ +that precede either the expression or +the point immediately following the \grammarterm{class-specifier} of +the outermost class for which the expression is in a complete-class context; +overload resolution is performed. +\begin{note} +During overload resolution, +candidate function templates undergo template argument deduction and +the resulting specializations are considered as candidate functions. +\end{note} + +\pnum +For a \grammarterm{splice-expression} of +the form \tcode{template \grammarterm{splice-specialization-specifier}}, +the \grammarterm{splice-specifier} of +the \grammarterm{splice-specialization-specifier} +shall designate a template $T$. +\begin{itemize} +\item +If $T$ is a function template, +the expression denotes an overload set containing all declarations of $T$ +that precede either the expression or +the point immediately following the \grammarterm{class-specifier} of +the outermost class for which the expression is in a complete-class context; +overload resolution is performed\iref{over.match,over.over}. +\item +Otherwise, if $T$ is a variable template, +let $S$ be the specialization of $T$ corresponding to +the template argument list of the \grammarterm{splice-specialization-specifier}. +The expression is an lvalue referring to +the object associated with $S$ and has the same type as that of $S$. +\item +Otherwise, the expression is ill-formed. +\end{itemize} +\begin{note} +Class members are accessible from any point +when designated by \grammarterm{splice-expression}s\iref{class.access.base}. +A class member access expression\iref{expr.ref} +whose right operand is a \grammarterm{splice-expression} is ill-formed +if the left operand (considered as a pointer) cannot be implicitly converted +to a pointer to the designating class of the right operand. +\end{note} + \rSec1[expr.compound]{Compound expressions} \rSec2[expr.post]{Postfix expressions}% @@ -3204,8 +3786,10 @@ typename-specifier \terminal{(} \opt{expression-list} \terminal{)}\br simple-type-specifier braced-init-list\br typename-specifier braced-init-list\br - postfix-expression \terminal{.} \opt{\terminal{template}} id-expression\br - postfix-expression \terminal{->} \opt{\terminal{template}} id-expression\br + postfix-expression \terminal{.} \opt{\keyword{template}} id-expression\br + postfix-expression \terminal{.} splice-expression\br + postfix-expression \terminal{->} \opt{\keyword{template}} id-expression\br + postfix-expression \terminal{->} splice-expression\br postfix-expression \terminal{++}\br postfix-expression \terminal{--}\br \keyword{dynamic_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br @@ -3241,12 +3825,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}. @@ -3290,7 +3874,7 @@ \grammarterm{initializer-clause}{s} which constitute the arguments to the function. \begin{note} -If the postfix expression is a function or member function name, +If the postfix expression is a function name, the appropriate function and the validity of the call are determined according to the rules in~\ref{over.match}. \end{note} @@ -3319,7 +3903,7 @@ \pnum \begin{note} -If a function or member function name is used, and name +If a function name is used, and name lookup\iref{basic.lookup} does not find a declaration of that name, the program is ill-formed. No function is implicitly declared by such a call. @@ -3341,6 +3925,60 @@ denoted by the object expression of the class member access\iref{expr.ref,basic.life}. +\pnum +The precondition assertions of a function call are, +in order: +\begin{itemize} +\item +if the \grammarterm{postfix-expression} +is a (possibly implicit) class member access expression +and the call +is a virtual function call, +the precondition assertions\iref{dcl.contract.func} +of the statically chosen function; +\item +the precondition assertions +of the function actually called. +\end{itemize} +The postcondition assertions of a function call are, +in order: +\begin{itemize} +\item +the postcondition assertions +of the function actually called; +\item +if the \grammarterm{postfix-expression} +is a (possibly implicit) class member access expression +and the call +is a virtual function call, +the postcondition assertions +of the statically chosen function. +\end{itemize} +\begin{example} +\begin{codeblock} +struct X1 { virtual void f() pre(a) post(b) {} }; +struct X2 { virtual void f() pre(c) post(d) {} }; +struct Y : X1 { void f() override pre(e) post(f) {} }; +struct Z : Y, X2 { void f() override pre(g) post(h) {} }; + +void t() { + Z z; + z.f(); // asserts g, h + static_cast(&z)->f(); // asserts e, g, h, f + + X1& x1ref = z; + X2& x2ref = z; + x1ref.f(); // asserts a, g, h, b + x2ref.f(); // asserts c, g, h, d + x1ref.X1::f(); // asserts a, b + x1ref.[:^^X1::f:](); // asserts a, g, h, b + + void (X1::*pmf)() = &X1::f; + (x1ref.*pmf)(); // asserts g, h +} +\end{codeblock} +\end{example} + \pnum A type $\tcode{T}_\text{call}$ is \defn{call-compatible} with a function type $\tcode{T}_\text{func}$ @@ -3352,7 +3990,7 @@ expression whose function type is not call-compatible with the type of the called function's -definition results in undefined behavior. +definition results in undefined behavior\ubdef{expr.call.different.type}. \begin{note} This requirement allows the case when the expression has the type of a @@ -3367,7 +4005,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 call +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 @@ -3403,7 +4043,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 @@ -3425,11 +4065,23 @@ \indextext{evaluation!unspecified order of function call}% \indextext{evaluation!unspecified order of argument}% The \grammarterm{postfix-expression} is sequenced before -each \grammarterm{expression} in the \grammarterm{expression-list} +each \grammarterm{initializer-clause} 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 call, +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 @@ -3475,6 +4127,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 call +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}% @@ -3511,7 +4175,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}, @@ -3527,7 +4191,7 @@ After these conversions, if the argument does not have arithmetic, enumeration, pointer, pointer-to-member, or class type, the program is ill-formed. -Passing a potentially-evaluated argument +Passing a potentially evaluated argument of a scoped enumeration type\iref{dcl.enum} or of a class type\iref{class} having an eligible non-trivial copy constructor\iref{special,class.copy.ctor}, @@ -3648,10 +4312,12 @@ A postfix expression followed by a dot \tcode{.} or an arrow \tcode{->}, optionally followed by the keyword \keyword{template}, and then followed by an -\grammarterm{id-expression}, is a postfix expression. +\grammarterm{id-expression} or a \grammarterm{splice-expression}, +is a postfix expression. \begin{note} -If the keyword \keyword{template} is used, -the following unqualified name +If the keyword \keyword{template} is used and +followed by an \grammarterm{id-expression}, +the unqualified name is considered to refer to a template\iref{temp.names}. If a \grammarterm{simple-template-id} results and is followed by a \tcode{::}, the \grammarterm{id-expression} is a \grammarterm{qualified-id}. @@ -3659,16 +4325,18 @@ \pnum \indextext{type!incomplete}% -For the first option (dot), -if the \grammarterm{id-expression} names a static member or an enumerator, +For a dot that is followed by an expression +that designates a static member or an enumerator, the first expression is a discarded-value expression\iref{expr.context}; -if the \grammarterm{id-expression} names a non-static data member, +if the expression after the dot designates a +non-static data member\iref{class.mem.general} or +a direct base class relationship\iref{class.derived.general}, the first expression shall be a glvalue. -For the second option (arrow), the first expression +A postfix expression that is followed by an arrow shall be a prvalue having pointer type. The expression \tcode{E1->E2} is converted to the equivalent form \tcode{(*(E1)).E2}; the remainder of -\ref{expr.ref}~will address only the first option (dot). +\ref{expr.ref}~will address only the form using a dot. \begin{footnote} Note that \tcode{(*(E1))} is an lvalue. @@ -3684,12 +4352,14 @@ \grammarterm{id-expression} denotes a static member. \end{footnote} the result of that evaluation, -together with the \grammarterm{id-expression}, +together with +the \grammarterm{id-expression} or \grammarterm{splice-expression}, determines the result of the entire postfix expression. \pnum Abbreviating -\grammarterm{postfix-expression}\tcode{.}\grammarterm{id-expression} +\grammarterm{postfix-expression}\tcode{.}\grammarterm{id-expression} or +\grammarterm{postfix-expression}\tcode{.}\grammarterm{splice-expression} as \tcode{E1.E2}, \tcode{E1} is called the \defn{object expression}. If the object expression is of scalar type, \tcode{E2} shall name the pseudo-destructor @@ -3714,7 +4384,14 @@ \end{note} \pnum -If \tcode{E2} is a bit-field, \tcode{E1.E2} is a bit-field. The +If \tcode{E2} is a \grammarterm{splice-expression}, +then let \tcode{T1} be the type of \tcode{E1}. +\tcode{E2} shall designate either +a member of \tcode{T1} or +a direct base class relationship $(\tcode{T1}, \tcode{B})$. + +\pnum +If \tcode{E2} designates a bit-field, \tcode{E1.E2} is a bit-field. The type and value category of \tcode{E1.E2} are determined as follows. In the remainder of~\ref{expr.ref}, \cvqual{cq} represents either \keyword{const} or the absence of \keyword{const} and \cvqual{vq} represents @@ -3723,24 +4400,26 @@ in~\ref{basic.type.qualifier}. \pnum -If \tcode{E2} is declared to have type ``reference to \tcode{T}'', then +If \tcode{E2} designates an entity +that is declared to have type ``reference to \tcode{T}'', then \tcode{E1.E2} is an lvalue of type \tcode{T}. -If \tcode{E2} is a static data member, +In that case, if \tcode{E2} designates a static data member, \tcode{E1.E2} designates the object or function to which the reference is bound, otherwise \tcode{E1.E2} designates the object or function to which the corresponding reference member of \tcode{E1} is bound. Otherwise, one of the following rules applies. - \begin{itemize} -\item If \tcode{E2} is a static data member and the type of \tcode{E2} +\item +If \tcode{E2} designates a static data member and the type of \tcode{E2} is \tcode{T}, then \tcode{E1.E2} is an lvalue; the expression designates the named member of the class. The type of \tcode{E1.E2} is \tcode{T}. -\item If \tcode{E2} is a non-static data member and the type of +\item +Otherwise, if \tcode{E2} designates a non-static data member and the type of \tcode{E1} is ``\cvqual{cq1 vq1} \tcode{X}'', and the type of \tcode{E2} is ``\cvqual{cq2 vq2} \tcode{T}'', the expression designates the corresponding -member subobject of the object designated by the first expression. If \tcode{E1} +member subobject of the object designated by \tcode{E1}. If \tcode{E1} is an lvalue, then \tcode{E1.E2} is an lvalue; otherwise \tcode{E1.E2} is an xvalue. Let the notation \cvqual{vq12} stand for the ``union'' of @@ -3748,25 +4427,28 @@ is \tcode{volatile}, then \cvqual{vq12} is \keyword{volatile}. Similarly, let the notation \cvqual{cq12} stand for the ``union'' of \cvqual{cq1} and \cvqual{cq2}; that is, if \cvqual{cq1} or \cvqual{cq2} is -\keyword{const}, then \cvqual{cq12} is \keyword{const}. If \tcode{E2} is -declared to be a \keyword{mutable} member, then the type of \tcode{E1.E2} -is ``\cvqual{vq12} \tcode{T}''. If \tcode{E2} is not declared to be a -\keyword{mutable} member, then the type of \tcode{E1.E2} is -``\cvqual{cq12} \cvqual{vq12} \tcode{T}''. +\keyword{const}, then \cvqual{cq12} is \keyword{const}. +If the entity designated by \tcode{E2} +is declared to be a \keyword{mutable} member, +then the type of \tcode{E1.E2} is ``\cvqual{vq12} \tcode{T}''. +If the entity designated by \tcode{E2} +is not declared to be a \keyword{mutable} member, +then the type of \tcode{E1.E2} is ``\cvqual{cq12} \cvqual{vq12} \tcode{T}''. -\item If \tcode{E2} is an overload set, +\item +Otherwise, if \tcode{E2} denotes an overload set, the expression shall be the (possibly-parenthesized) left-hand operand of a member function call\iref{expr.call}, and function overload resolution\iref{over.match} is used to select the function to which \tcode{E2} refers. The type of \tcode{E1.E2} is the type of \tcode{E2} and \tcode{E1.E2} refers to the function referred to by \tcode{E2}. - \begin{itemize} -\item If \tcode{E2} refers to a static member function, +\item +If \tcode{E2} refers to a static member function, \tcode{E1.E2} is an lvalue. - -\item Otherwise (when \tcode{E2} refers to a non-static member function), +\item +Otherwise (when \tcode{E2} refers to a non-static member function), \tcode{E1.E2} is a prvalue. \begin{note} Any redundant set of parentheses surrounding the expression @@ -3774,29 +4456,73 @@ \end{note} \end{itemize} -\item If \tcode{E2} is a nested type, the expression \tcode{E1.E2} is -ill-formed. +\item +Otherwise, if \tcode{E2} designates a nested type, +the expression \tcode{E1.E2} is ill-formed. -\item If \tcode{E2} is a member enumerator and the type of \tcode{E2} +\item +Otherwise, if \tcode{E2} designates a member enumerator and the type of \tcode{E2} is \tcode{T}, the expression \tcode{E1.E2} is a prvalue of type \tcode{T} whose value is the value of the enumerator. + +\item +Otherwise, if \tcode{E2} designates a direct base class relationship $(D, B)$ and +$D$ is either the cv-unqualified class type of \tcode{E1} or a base class thereof, +let \cv{} be the cv-qualification of the type of \tcode{E1}. +\tcode{E1} is implicitly converted to the type ``reference to \cv{}~\tcode{$D$}'' +(where the reference is an lvalue reference if \tcode{E1} is an lvalue +and an rvalue reference otherwise) and +the expression designates the direct base class subobject of type $B$ +of the object designated by the converted \tcode{E1}. +If \tcode{E1} is an lvalue, +then \tcode{E1.E2} is an lvalue; +otherwise, \tcode{E1.E2} is an xvalue. +The type of \tcode{E1.E2} is \cv{}~\tcode{$B$}. +\begin{example} +\begin{codeblock} +struct B { + int b; +}; +struct C : B { + int get() const { return b; } +}; +struct D : B, C { }; + +constexpr int f() { + D d = {1, {}}; + + // \tcode{b} unambiguously refers to the direct base class of type \tcode{B}, + // not the indirect base class of type \tcode{B} + B& b = d.[: std::meta::bases_of(^^D, std::meta::access_context::current())[0] :]; + b.b += 10; + return 10 * b.b + d.get(); +} +static_assert(f() == 110); +\end{codeblock} +\end{example} + +\item +Otherwise, the program is ill-formed. \end{itemize} \pnum -If \tcode{E2} is a non-static member, -the program is ill-formed if the class of which \tcode{E2} is -directly a member is an ambiguous base\iref{class.member.lookup} of -the naming class\iref{class.access.base} of \tcode{E2}. +If \tcode{E2} designates a non-static member +(possibly after overload resolution), +the program is ill-formed if the class of which \tcode{E2} designates +a direct member is an ambiguous base\iref{class.member.lookup} of +the designating class\iref{class.access.base} of \tcode{E2}. \begin{note} The program is also ill-formed if the naming class is an ambiguous base of the class type of the object expression; see~\ref{class.access.base}. \end{note} \pnum -If \tcode{E2} is a non-static member and +If \tcode{E2} designates a non-static member +(possibly after overload resolution) +or direct base class relationship and the result of \tcode{E1} is an object whose type is not similar\iref{conv.qual} to the type of \tcode{E1}, -the behavior is undefined. +the behavior is undefined\ubdef{expr.ref.member.not.similar}. \begin{example} \begin{codeblock} struct A { int i; }; @@ -3925,14 +4651,14 @@ that is within its lifetime or within its period of construction or destruction\iref{class.cdtor}, -the behavior is undefined. +the behavior is undefined\ubdef{expr.dynamic.cast.pointer.lifetime}. 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. +the behavior is undefined\ubdef{expr.dynamic.cast.glvalue.lifetime}. \pnum If \tcode{T} is ``pointer to \cv{} \keyword{void}'', then the result @@ -4011,7 +4737,7 @@ \indextext{\idxcode{type_info}}% \indexlibraryglobal{type_info}% \keyword{const} \tcode{std::type_info}\iref{type.info} and dynamic type \keyword{const} -\tcode{std::type_info} or \keyword{const} \term{name} where \term{name} is an +\tcode{std::type_info} or \keyword{const} \tcode{\placeholder{name}} where \tcode{\placeholder{name}} is an \impldef{derived type for \tcode{typeid}} class publicly derived from \tcode{std::type_info} which preserves the behavior described in~\ref{type.info}. @@ -4117,8 +4843,7 @@ If \tcode{T} is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if \tcode{T} is an rvalue reference to object type, the result is an xvalue; -otherwise, the result is a prvalue. The \keyword{static_cast} operator shall not cast -away constness\iref{expr.const.cast}. +otherwise, the result is a prvalue. \pnum \indextext{cast!static!reference}% @@ -4138,7 +4863,7 @@ type ``\cvqual{cv1} \tcode{B}''. If the object of type ``\cvqual{cv1} \tcode{B}'' is actually a base class subobject of an object of type \tcode{D}, the result refers to the enclosing object of type -\tcode{D}. Otherwise, the behavior is undefined. +\tcode{D}. Otherwise, the behavior is undefined\ubdef{expr.static.cast.base.class}. \begin{example} \begin{codeblock} struct B { }; @@ -4207,36 +4932,11 @@ \end{note} \pnum -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}, -null pointer\iref{conv.ptr}, null member pointer\iref{conv.mem}, -boolean\iref{conv.bool}, or -function pointer\iref{conv.fctptr} -conversion, can be performed explicitly using \keyword{static_cast}. A -program is ill-formed if it uses \keyword{static_cast} to perform the -inverse of an ill-formed standard conversion sequence. -\begin{example} -\begin{codeblock} -struct B { }; -struct D : private B { }; -void f() { - static_cast((B*)0); // error: \tcode{B} is a private base of \tcode{D} - static_cast((int D::*)0); // error: \tcode{B} is a private base of \tcode{D} -} -\end{codeblock} -\end{example} - -\pnum -The lvalue-to-rvalue\iref{conv.lval}, +Otherwise, the lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, and function-to-pointer\iref{conv.func} conversions are applied to the -operand. Such a \keyword{static_cast} is subject to the restriction that -the explicit conversion does not cast away -constness\iref{expr.const.cast}, and the following additional rules -for specific cases: +operand, and the conversions that can be performed using \keyword{static_cast} are listed below. +No other conversion can be performed using \keyword{static_cast}. \pnum A value of a scoped enumeration type\iref{dcl.enum} @@ -4263,7 +4963,7 @@ the value is unchanged if the original value is within the range of the enumeration values\iref{dcl.enum}, and -otherwise, the behavior is undefined. +otherwise, the behavior is undefined\ubdef{expr.static.cast.enum.outside.range}. A value of floating-point type can also be explicitly converted to an enumeration type. The resulting value is the same as converting the original value to the underlying type of the enumeration\iref{conv.fpint}, and subsequently to @@ -4278,7 +4978,7 @@ the result of the conversion is an \impldef{result of inexact floating-point conversion} choice of either of those values. -Otherwise, the behavior is undefined. +Otherwise, the behavior is undefined\ubdef{expr.static.cast.fp.outside.range}. \pnum \indextext{cast!base class}% @@ -4299,7 +4999,7 @@ ``pointer to \cvqual{cv1} \tcode{B}'' points to a \tcode{B} that is actually a base class subobject of an object of type \tcode{D}, the resulting pointer points to the enclosing object of type \tcode{D}. Otherwise, the -behavior is undefined. +behavior is undefined\ubdef{expr.static.cast.downcast.wrong.derived.type}. \pnum \indextext{cast!pointer-to-member}% @@ -4322,7 +5022,7 @@ member pointer value of the destination type. If class \tcode{B} contains the original member, or is a base class of the class containing the original member, the resulting pointer to member points -to the original member. Otherwise, the behavior is undefined. +to the original member. Otherwise, the behavior is undefined\ubdef{expr.static.cast.does.not.contain.original.member}. \begin{note} Although class \tcode{B} need not contain the original member, the dynamic type of the object with which indirection through the pointer @@ -4352,9 +5052,6 @@ \end{codeblock} \end{example} -\pnum -No other conversion can be performed using \keyword{static_cast}. - \rSec3[expr.reinterpret.cast]{Reinterpret cast} \pnum @@ -4389,7 +5086,7 @@ \indextext{cast!reinterpret!pointer to integer}% \indextext{cast!pointer to integer}% A pointer can be explicitly converted to any integral type large enough -to hold all values of its type. +to distinguish all value representations of its type. \indextext{conversion!implementation-defined pointer integer}% The mapping function is \impldef{mapping of pointer to integer}. \begin{note} @@ -4409,12 +5106,26 @@ \indextext{cast!reinterpret!integer to pointer}% \indextext{cast!integer to pointer}% A value of integral type or enumeration type can be explicitly converted -to a pointer. A pointer converted to an integer of sufficient size (if -any such exists on the implementation) and back to the same pointer type -will have its original value\iref{basic.compound}; +to a pointer. +If the value is one that can be produced +by converting one or more pointer values\iref{basic.compound} +to an integral type, +the result is an unspecified choice among all such values +that would result in the program having defined behavior. +If no such value exists, the behavior is undefined. +\begin{note} +It is possible for the result +to be an invalid pointer value or +to not be valid in the context of the conversion\iref{basic.compound} +because it points to an object in a region of storage +whose duration has ended or has not yet begun. +\end{note} \indextext{conversion!implementation-defined pointer integer}% -mappings between pointers and integers are otherwise +Otherwise, the result is \impldef{conversions between pointers and integers}. +\begin{note} +It can be an invalid pointer value. +\end{note} \pnum \indextext{cast!reinterpret!pointer-to-function}% @@ -4422,17 +5133,13 @@ \indextext{cast!undefined pointer-to-function}% A function pointer can be explicitly converted to a function pointer of a different type. +The function pointer value is unchanged by the conversion. \indextext{function call!undefined}% \begin{note} The effect of calling a function through a pointer to a function -type\iref{dcl.fct} that is not the same as the type used in the +type\iref{dcl.fct} that is not call-compatible with the type used in the definition of the function is undefined\iref{expr.call}. \end{note} -Except that converting -a prvalue of type ``pointer to \tcode{T1}'' to the type ``pointer to -\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. \pnum An object pointer @@ -4664,12 +5371,13 @@ \terminal{--} cast-expression\br await-expression\br \keyword{sizeof} unary-expression\br - \keyword{sizeof} \terminal{(} type-id \terminal{)}\br + \keyword{sizeof} \terminal{(} nofun-type-id \terminal{)}\br \keyword{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br - \keyword{alignof} \terminal{(} type-id \terminal{)}\br + \keyword{alignof} \terminal{(} nofun-type-id \terminal{)}\br noexcept-expression\br new-expression\br - delete-expression + delete-expression\br + reflect-expression \end{bnf} \indextext{operator!indirection}% @@ -4706,7 +5414,11 @@ The operator yields an lvalue of type \tcode{T}. If the operand points to an object or function, the result denotes that object or function; -otherwise, the behavior is undefined except as specified in \ref{expr.typeid}. +otherwise, the behavior is undefined except as specified in \ref{expr.typeid} +\ubdef{expr.unary.dereference}. +\begin{note} +Indirection through a pointer to an out-of-lifetime object is valid\iref{basic.life}. +\end{note} \begin{note} \indextext{type!incomplete}% Indirection through a pointer to an incomplete type (other than @@ -4725,14 +5437,25 @@ shall be an lvalue of some type \tcode{T}. \begin{itemize} \item -If the operand is a \grammarterm{qualified-id} naming a non-static or variant member \tcode{m} -of some class \tcode{C}, other than an explicit object member function, the result has type ``pointer to member -of class \tcode{C} of type \tcode{T}'' and designates \tcode{C::m}. +If the operand is a \grammarterm{qualified-id} or \grammarterm{splice-expression} +designating a non-static member \tcode{m}, +other than an explicit object member function, +\tcode{m} shall be a direct member of some class \tcode{C} +that is not an anonymous union. +The result has type ``pointer to member of class \tcode{C} of type \tcode{T}'' +and designates \tcode{C::m}. +\begin{note} +A \grammarterm{qualified-id} +that names a member of a namespace-scope anonymous union +is considered to be a class member access expression\iref{expr.prim.id.general} +and cannot be used to form a pointer to member. +\end{note} \item Otherwise, the result has type ``pointer to \tcode{T}'' and points to the designated object\iref{intro.memory} or function\iref{basic.compound}. -If the operand names an explicit object member function\iref{dcl.fct}, -the operand shall be a \grammarterm{qualified-id}. +If the operand designates an explicit object member function\iref{dcl.fct}, +the operand shall be +a \grammarterm{qualified-id} or a \grammarterm{splice-expression}. \begin{note} In particular, taking the address of a variable of type ``\cv{}~\tcode{T}'' yields a pointer of type ``pointer to \cv{}~\tcode{T}''. @@ -4757,8 +5480,9 @@ \pnum A pointer to member is only formed when an explicit \tcode{\&} is used -and its operand is a \grammarterm{qualified-id} not enclosed in -parentheses. +and its operand is +a \grammarterm{qualified-id} or \grammarterm{splice-expression} +not enclosed in parentheses. \begin{note} That is, the expression \tcode{\&(qualified-id)}, where the \grammarterm{qualified-id} is enclosed in parentheses, does not form an @@ -4864,7 +5588,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} @@ -4882,11 +5606,11 @@ \begin{bnf} \nontermdef{await-expression}\br - \terminal{co_await} cast-expression + \keyword{co_await} cast-expression \end{bnf} \pnum -An \grammarterm{await-expression} shall appear only as a potentially-evaluated +An \grammarterm{await-expression} shall appear only as a potentially evaluated expression within the \grammarterm{compound-statement} of a \grammarterm{function-body} or \grammarterm{lambda-expression}, in either case @@ -4900,6 +5624,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. @@ -4919,7 +5646,7 @@ an initial await expression, or a final await expression\iref{dcl.fct.def.coroutine}, a search is performed for the name \tcode{await_transform} -in the scope of \tcode{P} \iref{class.member.lookup}. +in the scope of \tcode{P}\iref{class.member.lookup}. If this search is performed and finds at least one declaration, then \placeholder{a} is \mbox{\placeholder{p}\tcode{.await_transform(}\grammarterm{cast-expression}\tcode{)}}; @@ -5075,7 +5802,7 @@ occupied by a non-potentially-overlapping object of the type of its operand. The operand is either an expression, which is an unevaluated operand\iref{term.unevaluated.operand}, or a parenthesized -\grammarterm{type-id}. +\grammarterm{nofun-type-id}. \indextext{type!incomplete}% The \keyword{sizeof} operator shall not be applied to an expression that has function or incomplete type, @@ -5109,6 +5836,8 @@ When applied to a class, the result is the number of bytes in an object of that class including any padding required for placing objects of that type in an array. +The amount and placement of padding in a class type +is a property of the implementation. The result of applying \keyword{sizeof} to a potentially-overlapping subobject is the size of the type, not the size of the subobject. @@ -5153,8 +5882,8 @@ \tcode{std::size_t}. \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 +is an integral constant expression\iref{expr.const.const}. +The \grammarterm{typedef-name} \tcode{std::size_t} is declared in the standard header \libheader{cstddef}\iref{cstddef.syn,support.types.layout}. \end{note} @@ -5164,7 +5893,7 @@ \indextext{\idxcode{alignof}}% \indextext{expression!\idxcode{alignof}}% An \keyword{alignof} expression yields the alignment requirement -of its operand type. The operand shall be a \grammarterm{type-id} +of its operand type. The operand shall be a \grammarterm{nofun-type-id} representing a complete object type, or an array thereof, or a reference to one of those types. @@ -5172,8 +5901,8 @@ The result is a prvalue of type \tcode{std::size_t}. \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 +is an integral constant expression\iref{expr.const.const}. +The \grammarterm{typedef-name} \tcode{std::size_t} is declared in the standard header \libheader{cstddef}\iref{cstddef.syn,support.types.layout}. \end{note} @@ -5206,7 +5935,7 @@ \tcode{true} otherwise. \begin{note} A \grammarterm{noexcept-expression} -is an integral constant expression\iref{expr.const}. +is an integral constant expression\iref{expr.const.const}. \end{note} \indextext{expression!unary|)} @@ -5222,7 +5951,7 @@ \indextext{storage management|see{\tcode{delete}}}% \indextext{\idxcode{new}}% The \grammarterm{new-expression} attempts to create an object of the -\grammarterm{type-id} or \grammarterm{new-type-id}\iref{dcl.name} to which +\grammarterm{nofun-type-id} or \grammarterm{new-type-id}\iref{dcl.name} to which it is applied. The type of that object is the \defnadj{allocated}{type}. \indextext{type!incomplete}% This type shall be a complete object type\iref{term.incomplete.type}, @@ -5233,14 +5962,14 @@ \grammarterm{new-expression}{s}. \end{note} \begin{note} -The \grammarterm{type-id} can be a cv-qualified type, in which case the +The \grammarterm{nofun-type-id} can be a cv-qualified type, in which case the object created by the \grammarterm{new-expression} has a cv-qualified type. \end{note} \begin{bnf} \nontermdef{new-expression}\br \opt{\terminal{::}} \keyword{new} \opt{new-placement} new-type-id \opt{new-initializer} \br - \opt{\terminal{::}} \keyword{new} \opt{new-placement} \terminal{(} type-id \terminal{)} \opt{new-initializer} + \opt{\terminal{::}} \keyword{new} \opt{new-placement} \terminal{(} nofun-type-id \terminal{)} \opt{new-initializer} \end{bnf} \indextext{\idxcode{new}!storage allocation}% @@ -5278,12 +6007,12 @@ a placeholder for a deduced class type\iref{dcl.type.class.deduct} appears in the \grammarterm{type-specifier-seq} of a \grammarterm{new-type-id} or -\grammarterm{type-id} of a \grammarterm{new-expression}, +\grammarterm{nofun-type-id} of a \grammarterm{new-expression}, the allocated type is deduced as follows: Let \placeholder{init} be the \grammarterm{new-initializer}, if any, and -\tcode{T} be the \grammarterm{new-type-id} or \grammarterm{type-id} of +\tcode{T} be the \grammarterm{new-type-id} or \grammarterm{nofun-type-id} of the \grammarterm{new-expression}, then the allocated type is the type deduced for the variable \tcode{x} in the invented declaration\iref{dcl.spec.auto}: @@ -5350,7 +6079,7 @@ \pnum Every \grammarterm{constant-expression} in a \grammarterm{noptr-new-declarator} shall be a converted constant -expression\iref{expr.const} of type \tcode{std::size_t} and +expression\iref{expr.const.const} of type \tcode{std::size_t} and its value shall be greater than zero. \begin{example} Given the definition \tcode{int n = 42}, @@ -5370,7 +6099,7 @@ \end{example} \pnum -If the \grammarterm{type-id} or \grammarterm{new-type-id} +If the \grammarterm{nofun-type-id} or \grammarterm{new-type-id} denotes an array type of unknown bound\iref{dcl.array}, the \grammarterm{new-initializer} shall not be omitted; the allocated object is an array with \tcode{n} elements, @@ -5405,7 +6134,8 @@ \impldef{maximum size of an allocated object} limit\iref{implimits}; or \item -the \grammarterm{new-initializer} is a \grammarterm{braced-init-list} and the +the \grammarterm{new-initializer} is a \grammarterm{braced-init-list} +or a parenthesized \grammarterm{expression-list} and the number of array elements for which initializers are provided (including the terminating \tcode{'\textbackslash 0'} in a \grammarterm{string-literal}\iref{lex.string}) exceeds the number of elements to initialize. @@ -5414,7 +6144,7 @@ If the value of the \grammarterm{expression} is invalid after converting to \tcode{std::size_t}: \begin{itemize} \item -if the \grammarterm{expression} is a potentially-evaluated core constant expression, +if the \grammarterm{expression} is a potentially evaluated core constant expression, the program is ill-formed; \item otherwise, an allocation function is not called; instead @@ -5435,17 +6165,24 @@ \pnum If the allocated type is an array, -the \grammarterm{new-initializer} is a \grammarterm{braced-init-list}, and +the \grammarterm{new-initializer} is a \grammarterm{braced-init-list} +or a parenthesized \grammarterm{expression-list}, and the \grammarterm{expression} -is potentially-evaluated and not a core constant expression, -the semantic constraints of copy-initializing a hypothetical element of -the array from an empty initializer list -are checked\iref{dcl.init.list}. +is potentially evaluated and not a core constant expression, +the semantic constraints of initializing a hypothetical element of +the array are checked as follows: +\begin{itemize} +\item +If the \grammarterm{new-initializer} is a \grammarterm{braced-init-list}, +the hypothetical element is copy-initialized +from an empty initializer list\iref{dcl.init.list}. +\item +Otherwise, the hypothetical element is value-initialized\iref{dcl.init.general}. +\end{itemize} \begin{note} The array can contain more elements than there are -elements in the \grammarterm{braced-init-list}, -requiring initialization of the remainder of the array elements from -an empty initializer list. +elements in the \grammarterm{new-initializer}, +requiring initialization of the remainder of the array elements as appropriate. \end{note} \pnum @@ -5462,7 +6199,7 @@ \indextext{array!\idxcode{new}}% When the allocated type is ``array of \tcode{N} \tcode{T}'' (that is, the \grammarterm{noptr-new-declarator} syntax is used or the -\grammarterm{new-type-id} or \grammarterm{type-id} denotes an array type), +\grammarterm{new-type-id} or \grammarterm{nofun-type-id} denotes an array type), the \grammarterm{new-expression} yields a prvalue of type ``pointer to \tcode{T}'' that points to the initial element (if any) of the array. Otherwise, let \tcode{T} be the allocated type; @@ -5523,7 +6260,7 @@ \pnum During an evaluation of a constant expression, -a call to a replaceable allocation function is always omitted\iref{expr.const}. +a call to a replaceable allocation function is always omitted\iref{expr.const.core}. \pnum The implementation may @@ -5686,7 +6423,7 @@ \indextext{\idxcode{bad_alloc}}% \indexlibraryglobal{bad_alloc}% \tcode{std::bad_alloc} -exception\iref{basic.stc.dynamic.allocation,except,bad.alloc}; +exception\iref{basic.stc.dynamic.allocation,except.throw,bad.alloc}; it returns a non-null pointer otherwise. If the allocation function has a non-throwing exception specification, it returns null to indicate failure to allocate storage @@ -5694,7 +6431,7 @@ \end{note} If the allocation function is a non-allocating form\iref{new.delete.placement} that returns null, -the behavior is undefined. +the behavior is undefined\ubdef{expr.new.non.allocating.null}. Otherwise, if the allocation function returns null, initialization shall not be done, the deallocation function shall not be called, and the value of @@ -5776,23 +6513,45 @@ searching for it in the global scope. \pnum -A declaration of a placement deallocation function matches the -declaration of a placement allocation function if it has the same number -of parameters and, after parameter transformations\iref{dcl.fct}, all -parameter types except the first are identical. If -the lookup finds a single matching deallocation function, that function -will be called; otherwise, no deallocation function will be called. If -the lookup finds a usual deallocation -function -and that function, -considered as a placement deallocation function, would have been -selected as a match for the allocation function, the program is -ill-formed. For a non-placement allocation function, the normal deallocation +For a non-placement allocation function, the normal deallocation function lookup is used to find the matching deallocation function\iref{expr.delete}. +For a placement allocation function, the selection process is described below. In any case, the matching deallocation function (if any) shall be non-deleted and accessible from the point where the \grammarterm{new-expression} appears. + +\pnum +For a placement allocation function, +the matching deallocation function is selected as follows: +\begin{itemize} +\item +Each candidate that is a function template is replaced by +the function template specializations (if any) +generated using template argument deduction\iref{temp.over,temp.deduct.call} +with arguments as specified below. +\item +Each candidate whose parameter-type-list is not identical to +that of the allocation function, +ignoring their respective first parameters, +is removed from the set of candidates. +\item +Each candidate whose associated constraints (if any) +are not satisfied\iref{temp.constr.constr} +is removed from the set of candidates. +\item +If exactly one function remains, that function is selected. +\item +Otherwise, no deallocation function is selected. +\end{itemize} +If a usual deallocation function is selected, the program is ill-formed. +\begin{note} +A deallocation function with an additional trailing parameter +compared to the allocation function is never matched, +even if a default argument is provided. +\end{note} + +\pnum \begin{example} \begin{codeblock} struct S { @@ -5806,7 +6565,55 @@ S* p = new (0) S; // error: non-placement deallocation function matches // placement allocation function \end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +struct A {}; +struct T { T(); }; + +void* operator new(std::size_t s, A& al); // \#1 + +template +void operator delete(void* p, A& al); // \#2 + +A al; +T* p = new (al) T; // OK, uses \#1 and \#2. +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +template +struct A {}; +struct T { T(); }; + +void* operator new(std::size_t s, A<0>& al); // \#1 + +template +void operator delete(void* p, A& al); +void operator delete(void* p, A<0>& al); + +A<0> al; +T* p = new (al) T; // OK, uses \#1. No deallocation function is selected (two candidates remain). +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +template +struct A {}; +struct T { T(); }; + +void* operator new(std::size_t s, A<0>& al); // \#1 + +template requires (I > 0) +void operator delete(void* p, A& al); +void operator delete(void* p, A<0>& al); // \#2 +A<0> al; +T* p = new (al) T; // OK, uses \#1 and \#2. +\end{codeblock} \end{example} \pnum @@ -5866,7 +6673,7 @@ that resulted from a previous non-array \grammarterm{new-expression}, or a pointer to a base class subobject of an object created by such a \grammarterm{new-expression}. -If not, the behavior is undefined. +If not, the behavior is undefined\ubdef{expr.delete.mismatch}. \indextext{array!\idxcode{delete}}% In an array delete expression, the value of the operand of \keyword{delete} may be a null pointer value or a pointer value that resulted from @@ -5878,7 +6685,7 @@ element of the array created by that \grammarterm{new-expression}. Zero-length arrays do not have a first element. \end{footnote} -If not, the behavior is undefined. +If not, the behavior is undefined\ubdef{expr.delete.array.mismatch}. \begin{note} This means that the syntax of the \grammarterm{delete-expression} must match the type of the object allocated by \keyword{new}, not the syntax of the @@ -5899,9 +6706,9 @@ is not a destroying operator delete, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall -have a virtual destructor or the behavior is undefined. In an array delete +have a virtual destructor or the behavior is undefined\ubdef{expr.delete.dynamic.type.differ}. In an array delete expression, if the dynamic type of the object to be deleted is not similar to -its static type, the behavior is undefined. +its static type, the behavior is undefined\ubdef{expr.delete.dynamic.array.dynamic.type.differ}. \pnum \indextext{type!incomplete}% @@ -6086,6 +6893,254 @@ the behavior is undefined\iref{new.delete.single,new.delete.array}. \end{note} +\rSec3[expr.reflect]{The reflection operator} + +\begin{bnf} +\nontermdef{reflect-expression}\br + \terminal{\caret\caret} \terminal{::}\br + \terminal{\caret\caret} reflection-name\br + \terminal{\caret\caret} type-id\br + \terminal{\caret\caret} id-expression +\end{bnf} + +\begin{bnf} +\nontermdef{reflection-name}\br + \opt{nested-name-specifier} identifier\br + nested-name-specifier \keyword{template} identifier +\end{bnf} + +\pnum +The unary \tcode{\caret\caret} operator, +called the \defnadj{reflection}{operator}, +yields a prvalue of type \tcode{std::meta::info}\iref{basic.fundamental}. +\begin{note} +This document places no restriction on representing, by reflections, +constructs not described by this document or +using the names of such constructs +as operands of \grammarterm{reflect-expression}s. +\end{note} + +\pnum +The component names of a \grammarterm{reflection-name} +are those of its \grammarterm{nested-name-specifier} (if any) and +its \grammarterm{identifier}. +The terminal name of a \grammarterm{reflection-name} of the form +\grammarterm{nested-name-specifier} \keyword{template} \grammarterm{identifier} +shall denote a template. + +\pnum +A \grammarterm{reflect-expression} is parsed as +the longest possible sequence of tokens +that could syntactically form a \grammarterm{reflect-expression}. +An unparenthesized \grammarterm{reflect-expression} +that represents a template shall not be followed by \tcode{<}. +\begin{example} +\begin{codeblock} +static_assert(std::meta::is_type(^^int())); // \tcode{\caret\caret} applies to the \grammarterm{type-id} \tcode{int()} + +template struct X {}; +consteval bool operator<(std::meta::info, X) { return false; } +consteval void g(std::meta::info r, X xv) { + r == ^^int && true; // error: \tcode{\caret\caret} applies to the \grammarterm{type-id} \tcode{int\&\&} + r == ^^int & true; // error: \tcode{\caret\caret} applies to the \grammarterm{type-id} \tcode{int\&} + r == (^^int) && true; // OK + r == ^^int &&&& true; // error: \tcode{int \&\&\&\&} is not a valid \grammarterm{type-id} + ^^X < xv; // error: \grammarterm{reflect-expression} that represents a template is followed by \tcode{<} + (^^X) < xv; // OK + ^^X < xv; // OK +} +\end{codeblock} +\end{example} + +\pnum +A \grammarterm{reflect-expression} of the form \tcode{\caret\caret ::} +represents the global namespace. + +\pnum +If a \grammarterm{reflect-expression} $R$ matches +the form \tcode{\caret\caret \grammarterm{reflection-name}}, +it is interpreted as such; +the \grammarterm{identifier} is looked up and +the representation of $R$ is determined as follows: +\begin{itemize} +\item +If lookup finds a declaration +that replaced a \grammarterm{using-declarator} +during a single search\iref{basic.lookup.general,namespace.udecl}, +$R$ is ill-formed. +\begin{example} +\begin{codeblock} +struct A { struct S {}; }; +struct B : A { using A::S; }; +constexpr std::meta::info r1 = ^^B::S; // error: \tcode{A::S} found through \grammarterm{using-declarator} + +struct C : virtual B { struct S {}; }; +struct D : virtual B, C {}; +D::S s; // OK, names \tcode{C::S} per \ref{class.member.lookup} +constexpr std::meta::info r2 = ^^D::S; // OK, result \tcode{C::S} not found through \grammarterm{using-declarator} +\end{codeblock} +\end{example} +\item +Otherwise, if lookup finds a namespace alias\iref{namespace.alias}, +all declarations found by name lookup shall have the same target scope, and +$R$ represents the namespace alias. +\item +Otherwise, if lookup finds a namespace\iref{basic.namespace}, +$R$ represents that namespace. +\item +Otherwise, if lookup finds a concept\iref{temp.concept}, +$R$ represents the denoted concept. +\item +Otherwise, if lookup finds a template\iref{temp.names}, +the representation of $R$ is determined as follows: +\begin{itemize} +\item +If lookup finds an injected-class-name\iref{class.pre}, then: +\begin{itemize} +\item +If the \grammarterm{reflection-name} is of the form +\tcode{\grammarterm{nested-name-specifier} \keyword{template} \grammarterm{identifier}}, +then $R$ represents the class template named by the injected-class-name. +\item +Otherwise, the injected-class-name shall be unambiguous +when considered as a \grammarterm{type-name} and +$R$ represents the class template specialization so named. +\end{itemize} +\item +Otherwise, if lookup finds an overload set, +that overload set shall contain only +declarations of a unique function template F; +$R$ represents F. +\item +Otherwise, if lookup finds +a class template, variable template, or alias template, +$R$ represents that template. +\begin{note} +Lookup never finds a partial or explicit specialization. +\end{note} +\end{itemize} +\item +Otherwise, if lookup finds a type alias: +\begin{itemize} +\item +If any declaration found by name lookup is of a template parameter $T$, +$R$ represents the underlying entity of $T$. +\item +Otherwise, +all declarations found by name lookup shall have the same target scope, and +$R$ represents the type alias. +\end{itemize} +\begin{example} +\begin{codeblock} +namespace A { + using T = int; +} +namespace B { + using T = int; +} +using namespace A; +using namespace B; +auto r = ^^T; // error: lookup finds type aliases with different target scopes +\end{codeblock} +\end{example} +\item +Otherwise, if lookup finds a class or an enumeration, +$R$ represents the denoted type. +\item +Otherwise, if lookup finds a class member of an anonymous union\iref{class.union.anon}, $R$ represents that class member. +\item +Otherwise, +the \grammarterm{reflection-name} shall be an \grammarterm{id-expression} \tcode{I} +and $R$ is \tcode{\caret\caret I} (see below). +\end{itemize} + +\pnum +A \grammarterm{reflect-expression} $R$ of the form +\tcode{\caret\caret \grammarterm{type-id}} +represents an entity determined as follows: +\begin{itemize} +\item +If the \grammarterm{type-id} designates +a placeholder type\iref{dcl.spec.auto.general}, +$R$ is ill-formed. +\item +Otherwise, if the \grammarterm{type-id} is of the form +\opt{\grammarterm{nested-name-specifier}} \opt{\keyword{template}} \grammarterm{simple-template-id} +and whose terminal name is a \grammarterm{template-name} +that names an alias template\iref{temp.alias}, +$R$ represents the type alias so named. +\item +Otherwise, $R$ represents the type denoted by the \grammarterm{type-id}. +\end{itemize} + +\pnum +A \grammarterm{reflect-expression} $R$ of the form +\tcode{\caret\caret \grammarterm{id-expression}} +represents an entity determined as follows: +\begin{itemize} +\item +If the \grammarterm{id-expression} denotes +\begin{itemize} +\item +a variable declared by +an \grammarterm{init-capture}\iref{expr.prim.lambda.capture}, +\item +a function-local predefined variable\iref{dcl.fct.def.general}, +\item +a local parameter introduced by +a \grammarterm{requires-expression}\iref{expr.prim.req}, or +\item +a local entity $E$\iref{basic.pre} for which a lambda scope intervenes +between the point at which $E$ was introduced and $R$, +\end{itemize} +then $R$ is ill-formed. +\item +Otherwise, if the \grammarterm{id-expression} denotes an overload set $S$, +the expression \tcode{\&\grammarterm{id-expression}} shall be well-formed +when considered as an unevaluated operand, +except that the function $F$ selected as described in \ref{over.over} +may be deleted\iref{dcl.fct.def.delete}; +$R$ represents $F$. +\item +Otherwise, if the \grammarterm{id-expression} denotes +a variable, structured binding, enumerator, or non-static data member, +$R$ represents that entity. +\item +Otherwise, $R$ is ill-formed. +\begin{note} +This includes \grammarterm{unqualified-id}s +that name a constant template parameter and +\grammarterm{pack-index-expression}s. +\end{note} +\end{itemize} +The \grammarterm{id-expression} of +a \grammarterm{reflect-expression} is an unevaluated operand\iref{expr.context}. +\begin{example} +\begin{codeblock} +template void fn() requires (^^T != ^^int); +template void fn() requires (^^T == ^^int); +template void fn() requires (sizeof(T) == sizeof(int)); + +constexpr std::meta::info a = ^^fn; // OK +constexpr std::meta::info b = ^^fn; // error: ambiguous + +constexpr std::meta::info c = ^^std::vector; // OK + +template +struct S { + static constexpr std::meta::info r = ^^T; + using type = T; +}; +static_assert(S::r == ^^int); +static_assert(^^S::type != ^^int); + +typedef struct X {} Y; +typedef struct Z {} Z; +constexpr std::meta::info e = ^^Y; // OK, represents the type alias \tcode{Y} +constexpr std::meta::info f = ^^Z; // OK, represents the type alias \tcode{Z}, not the type\iref{basic.lookup.general} +\end{codeblock} +\end{example} + \rSec2[expr.cast]{Explicit type conversion (cast notation)}% \indextext{expression!cast|(} @@ -6109,7 +7164,7 @@ \begin{bnf} \nontermdef{cast-expression}\br unary-expression\br - \terminal{(} type-id \terminal{)} cast-expression + \terminal{(} nofun-type-id \terminal{)} cast-expression \end{bnf} \pnum @@ -6240,7 +7295,7 @@ whose type is not similar to the type of \tcode{E1}, or whose most derived object does not contain the member to which -\tcode{E2} refers, the behavior is undefined. +\tcode{E2} refers, the behavior is undefined\ubdef{expr.mptr.oper.not.contain.member}. The expression \tcode{E1} is sequenced before the expression \tcode{E2}. \pnum @@ -6292,7 +7347,7 @@ operand is an lvalue and an xvalue otherwise. The result of a \tcode{.*} expression whose second operand is a pointer to a member function is a prvalue. If the second operand is the null -member pointer value\iref{conv.mem}, the behavior is undefined. +member pointer value\iref{conv.mem}, the behavior is undefined\ubdef{expr.mptr.oper.member.func.null}. \rSec2[expr.mul]{Multiplicative operators}% \indextext{expression!multiplicative operators}% @@ -6333,7 +7388,7 @@ expression by the second. \indextext{zero!undefined division by}% If the second operand of \tcode{/} or \tcode{\%} is zero, the behavior is -undefined. +undefined\ubdef{expr.mul.div.by.zero}. For integral operands, the \tcode{/} operator yields the algebraic quotient with any fractional part discarded; \begin{footnote} @@ -6341,7 +7396,7 @@ \end{footnote} if the quotient \tcode{a/b} is representable in the type of the result, \tcode{(a/b)*b + a\%b} is equal to \tcode{a}; otherwise, the behavior -of both \tcode{a/b} and \tcode{a\%b} is undefined. +of both \tcode{a/b} and \tcode{a\%b} is undefined\ubdef{expr.mul.representable.type.result}. \rSec2[expr.add]{Additive operators}% \indextext{expression!additive operators}% @@ -6383,8 +7438,8 @@ \item \indextext{arithmetic!pointer}% -both operands are pointers to cv-qualified or cv-unqualified -versions of the same completely-defined object type; or +both operands are pointers +to similar\iref{conv.qual} complete object types; or \item the left operand is a pointer to a completely-defined object type and the right operand has integral type. @@ -6420,7 +7475,7 @@ and the expression \tcode{P - J} points to the (possibly-hypothetical) array element $i - j$ of \tcode{x} if $0 \le i - j \le n$. -\item Otherwise, the behavior is undefined. +\item Otherwise, the behavior is undefined\ubdef{expr.add.out.of.bounds}. \end{itemize} \begin{note} Adding a value other than $0$ or $1$ @@ -6429,18 +7484,13 @@ \end{note} \pnum -\indextext{\idxcode{ptrdiff_t}!implementation-defined type of}% -\indextext{subtraction!implementation-defined pointer}% \indextext{\idxcode{ptrdiff_t}}% \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 -\tcode{std::ptrdiff_t} in the \libheader{cstddef} -header\iref{support.types.layout}. +The result of subtracting two pointer expressions \tcode{P} and \tcode{Q} +is a prvalue of type \tcode{std::ptrdiff_t}\iref{support.types.layout}. \begin{itemize} \item If \tcode{P} and \tcode{Q} both evaluate to null pointer values, -the result is 0. +the value is 0. \item Otherwise, if \tcode{P} and \tcode{Q} point to, respectively, array elements $i$ and $j$ of the same array object \tcode{x}, @@ -6451,13 +7501,13 @@ of type \tcode{std::ptrdiff_t}, the behavior is undefined\iref{expr.pre}. \end{note} -\item Otherwise, the behavior is undefined. +\item Otherwise, the behavior is undefined\ubdef{expr.add.sub.diff.pointers}. \end{itemize} \pnum For addition or subtraction, if the expressions \tcode{P} or \tcode{Q} have type ``pointer to \cv{}~\tcode{T}'', where \tcode{T} and the array element type -are not similar\iref{conv.qual}, the behavior is undefined. +are not similar\iref{conv.qual}, the behavior is undefined\ubdef{expr.add.not.similar}. \begin{example} \begin{codeblock} int arr[5] = {1, 2, 3, 4, 5}; @@ -6494,7 +7544,7 @@ promotions are performed. The type of the result is that of the promoted left operand. \indextext{left shift!undefined}% -The behavior is undefined if the right operand is negative, or greater +The behavior is undefined\ubdef{expr.shift.neg.and.width} if the right operand is negative, or greater than or equal to the width of the promoted left operand. \pnum @@ -6771,6 +7821,14 @@ result of type \keyword{bool}. In each case below, the operands shall have the same type after the specified conversions have been applied. +\pnum +Any two pointer values or two pointer-to-member values +either compare equal or compare unequal. +\begin{note} +Repeated comparisons are consistent +so long as neither value is an invalid pointer value. +\end{note} + \pnum \indextext{comparison!pointer}% \indextext{comparison!pointer to function}% @@ -6872,12 +7930,25 @@ Two operands of type \tcode{std::nullptr_t} or one operand of type \tcode{std::nullptr_t} and the other a null pointer constant compare equal. +\pnum +If both operands are of type \tcode{std::meta::info}, +they compare equal if both operands +\begin{itemize} +\item are null reflection values, +\item represent values that are template-argument-equivalent\iref{temp.type}, +\item represent the same object, +\item represent the same entity, +\item represent the same annotation\iref{dcl.attr.annotation}, +\item represent the same direct base class relationship, or +\item represent equal data member descriptions\iref{class.mem.general}, +\end{itemize} +and they compare unequal otherwise. + \pnum If two operands compare equal, the result is \keyword{true} for the \tcode{==} operator and \keyword{false} for the \tcode{!=} operator. If two operands compare unequal, the result is \keyword{false} for the \tcode{==} operator and -\keyword{true} for the \tcode{!=} operator. Otherwise, the result of each of the -operators is unspecified. +\keyword{true} for the \tcode{!=} operator. \pnum If both operands are of arithmetic or enumeration type, the usual arithmetic @@ -7199,8 +8270,8 @@ \begin{bnf} \nontermdef{yield-expression}\br - \terminal{co_yield} assignment-expression\br - \terminal{co_yield} braced-init-list + \keyword{co_yield} assignment-expression\br + \keyword{co_yield} braced-init-list \end{bnf} \pnum @@ -7296,7 +8367,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 @@ -7352,9 +8423,19 @@ 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, +with +\begin{itemize} +\item +the value congruent\iref{basic.fundamental} to \tcode{V} if the object is of integer type, -with the value congruent\iref{basic.fundamental} to \tcode{V}. +\item +the result of \tcode{reinterpret_cast(reinterpret_cast(V))} +if the left operand is a volatile-qualified glvalue of pointer type \tcode{T} +and \tcode{V} is a pointer value +that is not valid in the context of the evaluation\iref{basic.compound}, and +\item +\tcode{V} otherwise. +\end{itemize} \pnum \indextext{assignment!conversion by}% @@ -7391,7 +8472,7 @@ If the value being stored in an object is read via another object that overlaps in any way the storage of the first object, then the overlap shall be exact and the two objects shall have the same type, otherwise the behavior is -undefined. +undefined\ubdef{expr.assign.overlap}. \begin{note} This restriction applies to the relationship between the left and right sides of the assignment operation; it is not a @@ -7413,7 +8494,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} @@ -7471,219 +8552,70 @@ \end{example} \end{note} -\rSec1[expr.const]{Constant expressions}% +\rSec1[expr.const]{Constant evaluation}% \indextext{expression!constant} +\rSec2[expr.const.general]{General} + +\begin{bnf} +\nontermdef{constant-expression}\br + conditional-expression +\end{bnf} + \pnum Certain contexts require expressions that satisfy additional -requirements as detailed in this subclause; other contexts have different +requirements as detailed in \ref{expr.const}; other contexts have different semantics depending on whether or not an expression satisfies these requirements. Expressions that satisfy these requirements, assuming that copy elision\iref{class.copy.elision} is not performed, -are called -\indexdefn{expression!constant}% -\defnx{constant expressions}{constant expression}. +are called constant expressions. \begin{note} -Constant expressions can be evaluated -during translation. +Certain constant expressions are evaluated during translation\iref{lex.phases}. \end{note} -\begin{bnf} -\nontermdef{constant-expression}\br - conditional-expression -\end{bnf} +\pnum +\recommended +Implementations should provide consistent results of floating-point evaluations, +irrespective of whether the evaluation is performed +during translation or during program execution. +\begin{note} +Since this document +imposes no restrictions on the accuracy of floating-point operations, it is unspecified whether the +evaluation of a floating-point expression during translation yields the same result as the +evaluation of the same expression (or the same operations on the same values) during program +execution. +\begin{example} +\begin{codeblock} +bool f() { + char array[1 + int(1 + 0.2 - 0.1 - 0.1)]; // Must be evaluated during translation + int size = 1 + int(1 + 0.2 - 0.1 - 0.1); // May be evaluated at runtime + return sizeof(array) == size; +} +\end{codeblock} +It is unspecified whether the value of \tcode{f()} will be \tcode{true} or \tcode{false}. +\end{example} +\end{note} + +\rSec2[expr.const.core]{Core constant expressions} \pnum -The \defnx{constituent values}{constituent value} of an object $o$ are -\begin{itemize} -\item -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 +\indextext{type!constexpr-unknown representation}% +A type has \defnadj{constexpr-unknown}{representation} if it \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. +\item is a union, +\item is \tcode{std::meta::info}, +\item is a pointer or pointer-to-member type, +\item is volatile-qualified, +\item is a class type with a non-static data member of reference type, or +\item +has a base class or a non-static member whose +type has constexpr-unknown representation. \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 -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}, -\begin{note} -Within this evaluation, -\tcode{std::is_constant_evaluated()}\iref{meta.const.eval} -returns \keyword{true}. -\end{note} -and -\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 default-initialization results in some initialization being performed. -\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 -it has reference or non-volatile const-qualified integral or enumeration type. - -\pnum -A constant-initialized potentially-constant variable $V$ is -\defn{usable in constant expressions} at a point $P$ if -$V$'s initializing declaration $D$ is reachable from $P$ and -\begin{itemize} -\item $V$ is constexpr, -\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{potentially usable in constant expressions} at point $P$ if it is -\begin{itemize} -\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} -unless the evaluation of $E$, following the rules of the abstract -machine\iref{intro.execution}, would evaluate one of the following: +An expression $E$ is a \defnadj{core constant}{expression} +unless the evaluation of $E$, following the rules of the abstract +machine\iref{intro.execution}, would evaluate one of the following: \begin{itemize} \item \keyword{this}\iref{expr.prim.this}, except @@ -7745,12 +8677,20 @@ zero\iref{expr.mul}, or certain shift operations\iref{expr.shift}. \end{footnote} +\item +an arithmetic expression\iref{expr.pre} where +\begin{itemize} +\item all operands are finite and the result is not finite, +\item any operand is a signaling NaN, or +\item no operand is NaN and the result is NaN; +\end{itemize} + \item 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}, + a glvalue of type \cv{}~\tcode{std::nullptr_t}, \item a non-volatile glvalue that refers to an object that is @@ -7827,7 +8767,14 @@ a \keyword{reinterpret_cast}\iref{expr.reinterpret.cast}; \item -a modification of an object\iref{expr.ass,expr.post.incr,expr.pre.incr} +pointer arithmetic\iref{expr.add} where +one (possibly converted) operand +points to the first element of an array of unknown bound and +the other (possibly converted) operand +is of integral type with non-zero value; + +\item +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$; @@ -7851,10 +8798,11 @@ 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 +the placement argument to the \grammarterm{new-expression} points +to an object that is transparently replaceable\iref{basic.life} by +the object created by the \grammarterm{new-expression} +or, if \tcode{T} is an array type, +to the first element of such an object, and \item the placement argument points to storage whose duration began within the evaluation of $E$; @@ -7884,6 +8832,11 @@ \tcode{std::current_exception} or \tcode{std::rethrow_exception}\iref{propagation} are destroyed within the evaluation of $E$; +\item +a \grammarterm{throw-expression}\iref{expr.throw} with no operand, +unless there is a currently handled exception +whose exception object was constructed within the evaluation of $E$; + \item an \grammarterm{await-expression}\iref{expr.await}; @@ -7895,6 +8848,34 @@ relational\iref{expr.rel}, or equality\iref{expr.eq} operator where the result is unspecified; +\item +an equality operator comparing pointers to potentially non-unique objects, +if the pointer values of the two operands +are associated with different evaluations\iref{basic.compound} and either +they can both point to the same offset within +the same potentially non-unique object or +one of them points to an object whose +type has constexpr-unknown representation; +\begin{example} +\begin{codeblock} +constexpr const char *f() { return "foo"; } + +constexpr bool b1 = +"foo" == "foo"; // error: non-constant +constexpr bool b2 = f() == f(); // error: non-constant +constexpr const char *p = f(); +constexpr bool b3 = p == p; // OK, value of \tcode{b3} is \tcode{true} +constexpr bool b4 = "xfoo" + 1 == "foo\0y"; // error: non-constant; string literal + // object could contain \tcode{"xfoo\textbackslash{}0y"} +constexpr bool b5 = "foo" == "bar" + 0; // OK, value of \tcode{b5} is \tcode{false} +constexpr bool b6 = (const char*)"foo" == "oo"; // OK, value of \tcode{b6} is \tcode{false}; offsets would + // be different in a merged string literal object + +constexpr std::initializer_list il1 = { (int *)nullptr }; +constexpr std::initializer_list il2 = { 0 }; +constexpr bool b7 = il1.begin() == (void *)il2.begin(); // error: non-constant +\end{codeblock} +\end{example} + \item a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or \keyword{typeid}\iref{expr.typeid} expression @@ -7908,11 +8889,16 @@ that would throw an exception where no definition of the exception type is reachable; +\item +an expression that would produce an injected declaration (see below), +unless $E$ is the corresponding expression of +a \grammarterm{consteval-block-declaration}\iref{dcl.pre}; + \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}; @@ -7921,7 +8907,7 @@ \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. @@ -7944,7 +8930,7 @@ an operation that has undefined behavior as specified in \ref{library} through \ref{\lastlibchapter} or \item -an invocation of the \tcode{va_start} macro\iref{cstdarg.syn}. +an invocation of the \libmacro{va_start} macro\iref{cstdarg.syn}. \end{itemize} \pnum @@ -7992,8 +8978,7 @@ For the purposes of determining whether an expression $E$ is a core constant expression, 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. +as defined in \ref{allocator.members}, is ignored. \pnum For the purposes of determining whether $E$ is a core constant expression, @@ -8045,9 +9030,10 @@ \pnum During the evaluation of an expression $E$ as a core constant expression, -all \grammarterm{id-expression}s and uses of \tcode{*\keyword{this}} +all \grammarterm{id-expression}s, \grammarterm{splice-expression}s, and +uses of \tcode{*\keyword{this}} that refer to an object or reference -whose lifetime did not begin with the evaluation of $E$ +whose lifetime did not begin within the evaluation of $E$ are treated as referring to a specific instance of that object or reference whose lifetime and that of all subobjects (including all union members) includes the entire constant evaluation. @@ -8112,20 +9098,108 @@ \end{codeblock} \end{example} +\rSec2[expr.const.const]{Constant expressions} + \pnum -An object \tcode{a} is said to have \defnadj{constant}{destruction} if +A \defnadj{consteval-only}{value} is either \begin{itemize} \item - it is not of class type nor (possibly multidimensional) array thereof, or +a reflection value\iref{basic.fundamental} +that is not the null reflection value or \item - it is of class type or (possibly multidimensional) array thereof, - that class type has a constexpr destructor, and - for a hypothetical expression $E$ - whose only effect is to destroy \tcode{a}, - $E$ would be a core constant expression - if the lifetime of \tcode{a} and its non-mutable subobjects - (but not its mutable subobjects) were considered to start within $E$. +a pointer or pointer-to-member +that points to an immediate function +or to or past the end of an immediate object. +\end{itemize} + +\pnum +An object is an \defnadj{immediate}{object} +if its complete object has +\begin{itemize} +\item +a constituent value that is consteval-only or +\item +a constituent reference that refers to +an immediate object or immediate function. +\end{itemize} + +\pnum +Every immediate object shall be +\begin{itemize} +\item +the object associated with a constexpr variable +or a subobject thereof, +\item +a template parameter object\iref{temp.param} +or a subject thereof, or +\item +an object whose lifetime begins and ends +during the evaluation of a core constant expression. +\end{itemize} +\begin{example} +\begin{codeblock} +consteval int plus1(int x) { return x + 1; } +template struct C {}; + +auto a = plus1; // error: immediate object not associated with constexpr variable +constexpr auto b = plus1; // OK +auto c = C(); // OK + +auto d = @\reflexpr{int}@; // error: immediate object not associated with constexpr variable +auto e = @C<\reflexpr{char}@>(); // OK +\end{codeblock} +\end{example} +Each expression $E$ that odr-uses a variable +that declares or refers to an immediate object +shall be in an immediate function context; +a diagnostic is required only if either +\begin{itemize} +\item +the innermost declaration that contains $E$ or +\item +the defining declaration of the variable \end{itemize} +is reachable from the other. + +\pnum +A core constant expression +is a \defnadj{constant}{expression} +unless it is a prvalue whose result object\iref{basic.lval} +has a constituent value that is an invalid pointer value\iref{basic.compound} +or is indeterminate or erroneous\iref{basic.indet}. + +\pnum +A constant expression is an \defnadj{immediate constant}{expression} +if it is either +\begin{itemize} +\item +a glvalue that refers to an immediate object or an immediate function, or +\item +a prvalue whose result object (if any) is an immediate object. +\end{itemize} +\begin{note} +A glvalue core constant expression +that either refers to or points to an unspecified object +is not a constant expression. +\end{note} +\begin{example} +\begin{codeblock} +consteval int f() { return 42; } +consteval auto g() { return f; } +consteval int h(int (*p)() = g()) { return p(); } +constexpr int r = h(); // OK +constexpr auto e = g(); // error: a pointer to an immediate function is + // not a permitted result of a constant expression + +struct S { + int x; + constexpr S() {} +}; +int i() { + constexpr S s; // error: \tcode{s.x} has erroneous value +} +\end{codeblock} +\end{example} \pnum An \defnadj{integral constant}{expression} @@ -8185,80 +9259,209 @@ Such expressions can be used in \keyword{new} 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 -arguments\iref{temp.arg}. +fixed\iref{dcl.enum}, as array bounds\iref{dcl.array}, +as constant template arguments\iref{temp.arg}, +and as the constant expression of a \grammarterm{splice-specifier}\iref{basic.splice}. \end{note} \indextext{contextually converted constant expression of type \tcode{bool}|see{conversion, contextual}}% \indextext{conversion!contextual to constant expression of type \tcode{bool}}% + +\pnum A \term{contextually converted constant expression of type \tcode{bool}} is an expression, contextually converted to \keyword{bool}\iref{conv}, where the converted expression is a constant expression and the conversion sequence contains only the conversions above. +\rSec2[expr.const.init]{Constant initialization} + \pnum -A \defnadj{constant}{expression} is either -a glvalue core constant expression that refers to -an object or a non-immediate function, or -a prvalue core constant expression whose value -satisfies the following constraints: +The constituent values and constituent references of +a variable \tcode{x} are defined as follows: \begin{itemize} \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 +If \tcode{x} declares an object, +the constituent values and references of that object\iref{intro.object} are +constituent values and references of \tcode{x}. \item -no constituent value of pointer-to-member type designates an immediate function. +If \tcode{x} declares a reference, +that reference is a constituent reference of \tcode{x}. \end{itemize} -\begin{note} -A glvalue core constant expression -that either refers to or points to an unspecified object -is not a constant expression. -\end{note} -\begin{example} -\begin{codeblock} -consteval int f() { return 42; } -consteval auto g() { return f; } -consteval int h(int (*p)() = g()) { return p(); } -constexpr int r = h(); // OK -constexpr auto e = g(); // error: a pointer to an immediate function is - // not a permitted result of a constant expression +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. -struct S { - int x; - constexpr S() {} +\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; }; -int i() { - constexpr S s; // error: \tcode{s.x} has erroneous value +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 -\recommended -Implementations should provide consistent results of floating-point evaluations, -irrespective of whether the evaluation is performed -during translation or during program execution. +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} -Since this document -imposes no restrictions on the accuracy of floating-point operations, it is unspecified whether the -evaluation of a floating-point expression during translation yields the same result as the -evaluation of the same expression (or the same operations on the same values) during program -execution. +In the course of this determination, +\tcode{std::is_constant_evaluated()}\iref{meta.const.eval} +has the value \keyword{true}. +\end{note} +\begin{note} +Furthermore, if the initialization is manifestly constant-evaluated\iref{expr.const.defns}, +its evaluation during translation +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} -bool f() { - char array[1 + int(1 + 0.2 - 0.1 - 0.1)]; // Must be evaluated during translation - int size = 1 + int(1 + 0.2 - 0.1 - 0.1); // May be evaluated at runtime - return sizeof(array) == size; +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} -It is unspecified whether the value of \tcode{f()} will be \tcode{true} or \tcode{false}. \end{example} -\end{note} + +\pnum +A variable is \defn{potentially-constant} if +it is constexpr or +it has reference or non-volatile const-qualified integral or enumeration type. + +\pnum +A variable $V$ is +\defnx{usable in constant expressions}{usable in constant expressions!variable} at a point $P$ if +$V$ is constant-initialized and potentially-constant, +$V$'s initializing declaration $D$ is reachable from $P$, and +\begin{itemize} +\item $V$ is constexpr, +\item $V$ is not initialized to a TU-local value, or +\item $P$ is in the same translation unit as $D$. +\end{itemize} + +\pnum +An object or reference is +\defn{potentially usable in constant expressions} at point $P$ if it is +\begin{itemize} +\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} + +\pnum +An object or reference is +\defnx{usable in constant expressions}{usable in constant expressions!object or reference} +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} + +\rSec2[expr.const.imm]{Immediate functions} \pnum An expression or conversion is in an \defn{immediate function context} @@ -8269,13 +9472,13 @@ a function parameter scope of an immediate function, \item it is a subexpression of a manifestly constant-evaluated expression -or conversion, or +or conversion\iref{expr.const.defns}, or \item its enclosing statement is enclosed\iref{stmt.pre} by the \grammarterm{compound-statement} of a consteval if statement\iref{stmt.if}. \end{itemize} An invocation is an \defn{immediate invocation} -if it is a potentially-evaluated explicit or implicit invocation of +if it is a potentially evaluated explicit or implicit invocation of an immediate function and is not in an immediate function context. An aggregate initialization is an immediate invocation @@ -8287,17 +9490,30 @@ \indexdefn{conversion!immediate-escalating}% \indexdefn{immediate-escalating!expression|see{expression, immediate-escalating}}% \indexdefn{immediate-escalating!conversion|see{conversion, immediate-escalating}}% -An expression or conversion is \defn{immediate-escalating} -if it is not initially in an immediate function context -and it is either +A potentially evaluated expression or conversion is \defn{immediate-escalating} +if it is neither initially in an immediate function context +nor a subexpression of an immediate invocation, and \begin{itemize} \item -a potentially-evaluated \grammarterm{id-expression} -that denotes an immediate function -that is not a subexpression of an immediate invocation, or +it is an immediate constant expression or +\begin{example} +\begin{codeblock} +consteval std::meta::info refl() { return @\reflexpr{int}@; } +template constexpr void ex() { auto x = F(); } +auto p = &ex; // error: immediate function because \tcode{F()} + // is an immediate constant expression +\end{codeblock} +\end{example} \item -an immediate invocation that is not a constant expression -and is not a subexpression of an immediate invocation. +it is an immediate invocation that is not a constant expression. +\begin{example} +\begin{codeblock} +consteval int id(int x) { return x; } +template constexpr auto apply_to(int i) { return F(i); } +auto p = &apply_to; // error: immediate function because \tcode{F(i)} + // is not a constant expression +\end{codeblock} +\end{example} \end{itemize} \pnum @@ -8308,24 +9524,25 @@ the call operator of a lambda that is not declared with the \keyword{consteval} specifier, \item -a defaulted special member function +a non-user-provided defaulted function that is not declared with the \keyword{consteval} specifier, or \item -a function that results from the instantiation +a function that is not a prospective destructor and +that results from the instantiation of a templated entity defined with the \keyword{constexpr} specifier. \end{itemize} An immediate-escalating expression shall appear only in an immediate-escalating function. \pnum -An \defnadj{immediate}{function} is a function or constructor that is +An \defnadj{immediate}{function} is a function that is either \begin{itemize} \item declared with the \keyword{consteval} specifier, or \item an immediate-escalating function \tcode{\placeholder{F}} -whose function body contains an immediate-escalating expression \tcode{\placeholder{E}} -such that \tcode{\placeholder{E}}'s innermost enclosing non-block scope +whose function body contains an immediate-escalating expression +whose innermost enclosing non-block scope is \tcode{\placeholder{F}}'s function parameter scope. \begin{tailnote} Default member initializers used to initialize @@ -8333,6 +9550,8 @@ are considered to be part of the function body\iref{dcl.fct.def.general}. \end{tailnote} \end{itemize} + +\pnum \begin{example} \begin{codeblock} consteval int id(int i) { return i; } @@ -8387,16 +9606,227 @@ 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} +\rSec2[expr.const.reflect]{Reflection} + +\pnum +The evaluation of an expression can introduce +one or more \defnadjx{injected}{declarations}{declaration}. +The evaluation is said to \defn{produce} the declarations. +\begin{note} +An invocation of +the library function template \tcode{std::meta::define_aggregate} +produces an injected declaration\iref{meta.reflection.define.aggregate}. +\end{note} +Each such declaration has +\begin{itemize} +\item +an associated \defnadj{synthesized}{point}, +which follows the last non-synthesized program point +in the translation unit containing that declaration, and +\item +an associated \defnadj{characteristic}{sequence} of values. +\end{itemize} +\begin{note} +Special rules concerning reachability +apply to synthesized points\iref{module.reach}. +\end{note} +\begin{note} +The program is ill-formed +if injected declarations with different characteristic sequences +define the same entity in different translation units\iref{basic.def.odr}. +\end{note} + +\pnum +A member of an entity defined by an injected declaration +shall not have a name reserved to the implementation\iref{lex.name}; +no diagnostic is required. + +\pnum +Let $C$ be a \grammarterm{consteval-block-declaration}, +the evaluation of whose corresponding expression +produces an injected declaration for an entity $E$. +The program is ill-formed if either +\begin{itemize} +\item +$C$ is enclosed by a scope associated with $E$ or +\item +letting $P$ be a point whose immediate scope is that to which $E$ belongs, +there is a function parameter scope or class scope +that encloses exactly one of $C$ or $P$. +\end{itemize} + +\pnum +\begin{example} +\begin{codeblock} +struct S0 { + consteval { + std::meta::define_aggregate(^^S0, {}); // error: scope associated with \tcode{S0} encloses the consteval block + } +}; + +struct S1; +consteval { std::meta::define_aggregate(^^S1, {}); } // OK + +template consteval void tfn1() { + std::meta::define_aggregate(R, {}); +} + +struct S2; +consteval { tfn1<^^S2>(); } // OK + +template consteval void tfn2() { + consteval { std::meta::define_aggregate(R, {}); } +} + +struct S3; +consteval { tfn2<^^S3>(); } + // error: function parameter scope of \tcode{tfn2<\caret\caret S3>} intervenes between the declaration of \tcode{S3} + // and the consteval block that produces the injected declaration + +template struct TCls { + struct S4; + static void sfn() requires ([] { + consteval { std::meta::define_aggregate(^^S4, {}); } + return true; + }()) { } +}; + +consteval { TCls::sfn(); } // error: \tcode{TCls::S4} is not enclosed by \grammarterm{requires-clause} lambda + +struct S5; +struct Cls { + consteval { std::meta::define_aggregate(^^S5, {}); } // error: \tcode{S5} is not enclosed by class \tcode{Cls} +}; + +struct S6; +consteval { // \#1 + struct S7; // local class + + std::meta::define_aggregate(^^S7, {}); // error: consteval block \#1 does not enclose itself, + // but encloses \tcode{S7} + + struct S8; // local class + consteval { // \#2 + std::meta::define_aggregate(^^S6, {}); // error: consteval block \#1 encloses + // consteval block \#2 but not \tcode{S6} + + std::meta::define_aggregate(^^S8, {}); // OK, consteval block \#1 encloses both \#2 and \tcode{S8} + } +} +\end{codeblock} +\end{example} + +\pnum +During an evaluation $V$\iref{intro.execution} of +an expression, conversion, or initialization $E$ +as a core constant expression, the +\indextext{point of!evaluation}% +\indextext{point!of evaluation}% +\indextext{evaluation!point of evaluation, during}% +\defnx{point of evaluation of $E$ during $V$}{point of evaluation during evaluation} +is the program point $P$ determined as follows: +\begin{itemize} +\item +If $E$ is a potentially-evaluated subexpression of +a default member initializer $I$, and +$V$ is the evaluation of $E$ in the evaluation of $I$ +as an immediate subexpression of a (possibly aggregate) initialization, then +$P$ is the point of evaluation of that initialization. +\begin{tailnote} +For example, +$E$ can be an immediate invocation in a default member initializer +used by an aggregate initialization appearing at $P$. +\end{tailnote} + +\item +Otherwise, +if $E$ is a potentially-evaluated subexpression of +a default argument $A$\iref{dcl.fct.default}, and +$V$ is the evaluation of $E$ in the evaluation of $A$ as +an immediate subexpression of a function call\iref{expr.call}, then +$P$ is the point of evaluation of that function call. + +\item +Otherwise, +$P$ is the point at which $E$ appears. +\end{itemize} +During the evaluation $V$ of an expression $E$ as a core constant expression, +the \defnadj{evaluation}{context} of an evaluation $X$ +during $V$ is the set $C$ of program points determined as follows: +\begin{itemize} +\item +If $X$ occurs during the evaluation $Y$ of +a manifestly constant-evaluated expression, +where $Y$ occurs during $V$, then +$C$ is the evaluation context of $X$ during $Y$. +\item +Otherwise, $C$ contains + \begin{itemize} + \item + the point of evaluation of $E$ during $V$ and + each synthesized point in the instantiation context thereof and + \item + each synthesized point corresponding to an injected declaration + produced by any evaluation executed during $V$ that + is sequenced before $X$\iref{intro.execution}. + \end{itemize} +\end{itemize} +\begin{note} +The evaluation context determines the behavior of certain functions +used for reflection\iref{meta.reflection}. +\end{note} +\begin{example} +\begin{codeblock} +struct S; +consteval std::size_t f(int p) { + constexpr std::size_t r = /* @\tcode{Q}@ */ + std::meta::is_complete_type(^^S) ? 1 : 2; // \#1 + if (!std::meta::is_complete_type(^^S)) { // \#2 + std::meta::define_aggregate(^^S, {}); + } + return (p > 0) ? f(p - 1) : r; +} + +consteval { + if (f(1) != 2) { + throw; // OK, not evaluated + } +} +\end{codeblock} +During each evaluation of +\tcode{std::meta::is_complete_type(\caret\caret{}S)} +at \#1\iref{meta.reflection.queries} that is +executed during the evaluation of \tcode{f(1) != 2}, +the evaluation context contains \tcode{Q}, +but does not contain the synthesized point +associated with the injected declaration of \tcode{S}. +However, the synthesized point is in the evaluation context of +\tcode{std::meta::is_complete_type(\caret\caret{}S)} at \#2 +during the evaluation of \tcode{f(0)}. +\end{example} + +\rSec2[expr.const.defns]{Further definitions} \pnum An expression or conversion is \defn{manifestly constant-evaluated} -if it is: +if it is \begin{itemize} \item a \grammarterm{constant-expression}, or \item the condition of a constexpr if statement\iref{stmt.if}, or +\item the expression corresponding to +a \grammarterm{consteval-block-declaration}\iref{dcl.pre}, or \item an immediate invocation, or \item the result of substitution into an atomic constraint expression to determine whether it is satisfied\iref{temp.constr.atomic}, or @@ -8405,7 +9835,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 notional 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} @@ -8421,7 +9854,7 @@ constexpr int f() { const int n = std::is_constant_evaluated() ? 13 : 17; // \tcode{n} is 13 int m = std::is_constant_evaluated() ? 13 : 17; // \tcode{m} can be 13 or 17 (see below) - char arr[n] = {}; // char[13] + char arr[n] = {}; // \tcode{char[13]} return m + sizeof(arr); } int p = f(); // \tcode{m} is 13; initialized to 26 @@ -8436,15 +9869,15 @@ \end{note} \pnum -\indextext{expression!potentially constant evaluated}% -An expression or conversion is \defn{potentially constant evaluated} +\indextext{expression!potentially constant-evaluated}% +An expression or conversion is \defn{potentially constant-evaluated} if it is: \begin{itemize} \item a manifestly constant-evaluated expression, \item -a potentially-evaluated expression\iref{basic.def.odr}, +a potentially evaluated expression\iref{basic.def.odr}, \item an immediate subexpression of a \grammarterm{braced-init-list}, @@ -8472,10 +9905,25 @@ \begin{itemize} \item a constexpr function that is named by an expression\iref{basic.def.odr} -that is potentially constant evaluated, or +that is potentially constant-evaluated, or \item -a potentially-constant variable named by a potentially constant evaluated expression. +a potentially-constant variable named by a potentially constant-evaluated expression. +\end{itemize} + +\pnum +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\iref{dcl.constexpr}, and + for a hypothetical expression $E$ + whose only effect is to destroy \tcode{a}, + $E$ would be a core constant expression + if the lifetime of \tcode{a} and its non-mutable subobjects + (but not its mutable subobjects) were considered to start within $E$. \end{itemize} \indextext{expression|)} diff --git a/source/future.tex b/source/future.tex index 5a66416998..38948be5d0 100644 --- a/source/future.tex +++ b/source/future.tex @@ -73,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} @@ -220,34 +220,43 @@ \rSec1[depr.c.macros]{Deprecated C macros} \pnum -The header \libheaderref{stdalign.h} has the following macros: -\indexlibraryglobal{__alignas_is_defined}% +The header \libheaderref{cfloat} has the following macros: \begin{codeblock} -#define @\xname{alignas_is_defined}@ 1 -#define @\xname{alignof_is_defined}@ 1 +#define @\libmacro{FLT_HAS_SUBNORM}@ @\seebelow@ +#define @\libmacro{DBL_HAS_SUBNORM}@ @\seebelow@ +#define @\libmacro{LDBL_HAS_SUBNORM}@ @\seebelow@ +#define @\libmacro{DECIMAL_DIG}@ @\seebelow@ \end{codeblock} +The header defines these macros the same as +the C standard library header \libheader{float.h}. + +\xrefc{5.3.5.3.3, 7.33.6} + +\pnum +In addition to being available via inclusion of the \libheader{cfloat} header, +the macros \tcode{INFINITY} and \tcode{NAN} are +available when \libheaderref{cmath} is included. + +\xrefc{7.12} \pnum The header \libheaderref{stdbool.h} has the following macro: -\indexlibraryglobal{__bool_true_false_are_defined}% \begin{codeblock} -#define @\xname{bool_true_false_are_defined}@ 1 +#define @\libxmacro{bool_true_false_are_defined}@ 1 \end{codeblock} +\xrefc{7.19} + \rSec1[depr.cerrno]{Deprecated error numbers} \pnum 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 @@ -284,11 +293,11 @@ template // \seebelow struct aligned_storage; template // \seebelow - using @\libglobal{aligned_storage_t}@ = typename aligned_storage::type; + using @\libglobal{aligned_storage_t}@ = aligned_storage::type; template struct aligned_union; template - using @\libglobal{aligned_union_t}@ = typename aligned_union::type; + using @\libglobal{aligned_union_t}@ = aligned_union::type; } \end{codeblock} @@ -567,8 +576,8 @@ the \oldconcept{TransformationTrait} requirements with a member typedef \tcode{type} that names the following type: \begin{itemize} -\item for the first specialization, \tcode{add_volatile_t}, and -\item for the second specialization, \tcode{add_cv_t}. +\item for the first specialization, \tcode{volatile TE}, and +\item for the second specialization, \tcode{const volatile TE}. \end{itemize} \pnum @@ -622,11 +631,42 @@ the \oldconcept{TransformationTrait} requirements with a member typedef \tcode{type} that names the following type: \begin{itemize} -\item for the first specialization, \tcode{add_volatile_t}, and -\item for the second specialization, \tcode{add_cv_t}. +\item for the first specialization, \tcode{volatile VA::type}, and +\item for the second specialization, \tcode{const volatile VA::type}. \end{itemize} \end{itemdescr} +\rSec1[depr.vector.bool.swap]{Deprecated \tcode{vector} swap} + +\pnum +The following member is declared in addition to those members specified in +\ref{vector.bool}: + +\begin{codeblock} +namespace std { + template class vector { + public: + static constexpr void swap(reference x, reference y) noexcept; + }; +} +\end{codeblock} + +\indexlibrarymember{swap}{vector}% +\begin{itemdecl} +static constexpr void swap(reference x, reference y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Exchanges the values denoted by \tcode{x} and \tcode{y} as if by: +\begin{codeblock} +bool b = x; +x = y; +y = b; +\end{codeblock} +\end{itemdescr} + \rSec1[depr.iterator]{Deprecated \tcode{iterator} class template} \pnum @@ -765,10 +805,27 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return visit(std::forward(vis), arg.value);} +Equivalent to: \tcode{return visit(std::forward(vis), arg.\exposid{value_});} \end{itemdescr} -\rSec1[depr.fs.path.factory]{Deprecated filesystem path factory functions} +\rSec1[depr.ctime]{Deprecated time formatting} + +\pnum +The header \libheaderref{ctime} has the following additions: +\begin{codeblock} +char* asctime(const tm* timeptr); +char* ctime(const time_t* timer); +\end{codeblock} + +\pnum +The functions \tcode{asctime} and \tcode{ctime} +are not required to avoid data races\iref{res.on.data.races}. + +\xrefc{7.29} + +\rSec1[depr.filesystems]{Deprecated file systems} + +\rSec2[depr.fs.path.factory]{Deprecated filesystem path factory functions} \pnum The header \libheaderrefx{filesystem}{fs.filesystem.syn} has the following additions: @@ -847,6 +904,45 @@ \end{note} \end{itemdescr} +\rSec2[depr.fs.path.obs]{Deprecated filesystem path format observers} + +\indexlibraryglobal{path}% +\pnum +The following members are declared in addition to those members +specified in \ref{fs.path.member}: + +\begin{codeblock} +namespace std::filesystem { + class path { + public: + std::string string() const; + std::string generic_string() const; + }; +} +\end{codeblock} + +\indexlibrarymember{string}{path}% +\begin{itemdecl} +std::string string() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{native_encoded_string()}. +\end{itemdescr} + +\indexlibrarymember{generic_string}{path}% +\begin{itemdecl} +std::string generic_string() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{generic_native_encoded_string()}. +\end{itemdescr} + \rSec1[depr.atomics]{Deprecated atomic operations} \rSec2[depr.atomics.general]{General} @@ -860,8 +956,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} @@ -888,6 +987,13 @@ T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) volatile noexcept; T operator @\placeholdernc{op}@=(T operand) volatile noexcept; T* fetch_@\placeholdernc{key}@(ptrdiff_t operand, memory_order order = memory_order::seq_cst) volatile noexcept; +value_type operator++(int) volatile noexcept; +value_type operator--(int) volatile noexcept; +value_type operator++() volatile noexcept; +value_type operator--() volatile noexcept; +void wait(T old, memory_order order = memory_order::seq_cst) const volatile noexcept; +void notify_one() volatile noexcept; +void notify_all() volatile noexcept; \end{codeblock} \rSec2[depr.atomics.nonmembers]{Non-member functions} @@ -910,13 +1016,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. @@ -930,3 +1036,132 @@ \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} + +\rSec1[depr.istream.extractors]{Deprecated \tcode{signed char} and \tcode{unsigned char} extraction} +\pnum +The header \libheaderref{istream} has the following additions: + +\begin{itemdecl} +template + basic_istream& operator>>(basic_istream& in, unsigned char& c); +template + basic_istream& operator>>(basic_istream& in, signed char& c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Behaves like a formatted input member +(as described in \ref{istream.formatted.reqmts}) +of \tcode{in}. +A character is extracted from \tcode{in}, +if one is available, and stored in \tcode{c}. +Otherwise, \tcode{ios_base::failbit} is set +in the input function's local error state +before \tcode{setstate} is called. + +\pnum +\returns +\tcode{in}. +\end{itemdescr} + +\pnum +\begin{itemdecl} +template + basic_istream& operator>>(basic_istream& in, unsigned char (&s)[N]); +template + basic_istream& operator>>(basic_istream& in, signed char (&s)[N]); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Behaves like a formatted input member +(as described in \ref{istream.formatted.reqmts}) +of \tcode{in}. +After a sentry object is constructed, +\tcode{operator>>} extracts characters and stores them into \tcode{s}. +If \tcode{width()} is greater than zero, +\tcode{n} is \tcode{min(size_t(width()), N)}. +Otherwise \tcode{n} is \tcode{N}. +\tcode{n} is the maximum number of characters stored. + +\pnum +Characters are extracted and stored until any of the following occurs: +\begin{itemize} +\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, s)} + is \tcode{true}. +\end{itemize} + +\pnum +\tcode{operator>>} then stores a null byte (\tcode{charT()}) in the next position, +which may be the first position if no characters were extracted. +\tcode{operator>>} then calls \tcode{width(0)}. + +\pnum +If the function extracted no characters, +\tcode{ios_bit::failbit} is set in the input function's +local error state before \tcode{setstate} is called. + +\pnum +\returns +\tcode{in}. +\end{itemdescr} + +\rSec1[depr.ostream.inserters]{Deprecated \tcode{signed char} and \tcode{unsigned char} insertion} +\pnum +The header \libheaderref{ostream} has the following additions: + +\pnum +\begin{itemdecl} +template + basic_ostream& operator<<(basic_ostream& out, signed char c); +template + basic_ostream& operator<<(basic_ostream& out, unsigned char c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return out << static_cast(c);} +\end{itemdescr} + +\pnum +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& out, const signed char* s); +template + basic_ostream& + operator<<(basic_ostream& out, const unsigned char* s); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return out << reinterpret_cast(s);} +\end{itemdescr} diff --git a/source/grammar.tex b/source/grammar.tex index 8501d39453..259dabaedf 100644 --- a/source/grammar.tex +++ b/source/grammar.tex @@ -54,8 +54,8 @@ \end{ncbnf} \begin{ncbnf} -template-name:\br +simple-template-name:\br identifier \end{ncbnf} -\FlushAndPrintGrammar +\input{std-gram.ext} diff --git a/source/ifndr.tex b/source/ifndr.tex new file mode 100644 index 0000000000..47b36e13e3 --- /dev/null +++ b/source/ifndr.tex @@ -0,0 +1,1060 @@ +%!TEX root = std.tex +\infannex{ifndr}{Ill-formed, no diagnostic required} + +\rSec1[ifndr.general]{General} + +\pnum +This Annex documents +rules for which no diagnostic is required, +called out in +\ref{intro} through \ref{\lastcorechapter} +using the following phrases: +\begin{itemize} +\item no diagnostic is required +\item no diagnostic required +\item a diagnostic is required only if +\end{itemize} +Each entry contains +a title, +a cross-reference, +a summary of the circumstances, +and code examples. +The code examples are not intended +to exhaustively cover all possible ways of invoking that case. + +\rSec1[ifndr.lex]{\ref*{lex}: Lexical conventions} + +\ifndrdescription{lex.name.reserved} + +\pnum +Using an identifier reserved for use by \Cpp{} +is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +int _z; // IFNDR, \tcode{_z} is reserved because it starts with \tcode{_} at global scope + +int main() { + int __x; // IFNDR, \tcode{__x} is reserved because it starts with \tcode{__} + int _Y; // IFNDR, \tcode{_Y} is reserved because it starts with \tcode{_} followed by a capital letter + int x__y; // IFNDR, \tcode{x__y} is reserved because it contains \tcode{__} +} +\end{codeblock} +\end{example} + +\rSec1[ifndr.basic]{\ref*{basic}: Basics} + +\ifndrdescription{basic.link.consistent.types} + +\pnum +Having multiple declarations of the same entity +with different kinds +when those declarations are not reachable from one another +is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Module interface of \tcode{M}} +void g(); // \#1 +void h(); // \#2 +template int j; // \#3 +\end{codeblocktu} +\begin{codeblocktu}{Module interface of \tcode{N}} +int g(); // same entity as \#1, different type +namespace h {} // same entity as \#2, not both namespaces +template int j; // same entity as \#3, non-equivalent template heads +\end{codeblocktu} +\begin{codeblocktu}{Other translation unit} +import M; +import N; + // IFNDR due to the mismatched pairs above +\end{codeblocktu} +\end{example} + +\ifndrdescription{basic.def.odr.minimum.one.def} + +\pnum +Not having a definition +for a function or variable +that is odr-used from a non-discarded statement\iref{stmt.if} +is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +auto f() { + struct A {}; + return A{}; +} +decltype(f()) g(); +auto x = g(); // IFNDR, function \tcode{g} is used but not defined in this translation unit, and cannot + // be defined in any other translation unit because its type does not have linkage +\end{codeblock} +\end{example} + +\ifndrdescription{basic.def.odr.injected.match} + +\pnum +Defining a definable item \tcode{D} +with an injected declaration\iref{expr.const.reflect} +in one translation unit and +a definition in a different translation unit +when \tcode{D} is not attached to a named module +or neither definition is reachable from the other +is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +struct S; +consteval { std::meta::define_aggregate(^^S, {}); } // \#1 +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +struct S {}; // IFNDR, definition here, injected declaration at \#1 +\end{codeblocktu} +\end{example} + +\ifndrdescription{basic.def.odr.maximum.one.def} + +\pnum +If there are definitions +in different translation units +of a non-inline non-templated function or variable +that are not attached to a named module +or are not reachable from one another, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module M:A; // module partition +void f() {} // \#1 +void g() {} // \#2 +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +export module M:B; // module partition +void f() {} // IFNDR, \#1 not reachable +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#3} +export module M; // primary module interface unit +export import :A; +void g(); // error: \#2 is reachable +\end{codeblocktu} +\end{example} + +\ifndrdescription{basic.def.odr.definition.matches} + +\pnum +If there are definitions +in different translation units +of a definable item \tcode{D} +where +\begin{itemize} +\item \tcode{D} is not defined by an injected declaration\iref{expr.const.reflect}, +\item \tcode{D} is not an inline or templated function or variable, and +\item \tcode{D} is not attached to a named module or the declarations are not reachable from one another, +\end{itemize} +that do not satisfy the matching rules described in \ref{basic.def.odr}, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +inline void f() {} // \#1 +inline void g() {} // \#2 +inline void h() {[]{}();} // \#3 +namespace { int i = 0; } +inline void j() {++i;} // \#4 +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +inline void f() {} // OK, same as \#1 +inline void g() {;} // IFNDR, different sequence of tokens than \#2 +inline void h() {[]{}();} // IFNDR, closure has different type than \#3 +namespace { int i = 0; } +inline void j() {++i; } // IFNDR, \tcode{i} refers to different entity than in \#4 +\end{codeblocktu} +\end{example} + +\ifndrdescription{basic.def.odr.unnamed.enum.same.type} + +\pnum +Having multiple unnamed enumeration definitions +in the same scope +that have the same first enumerator name +and do not have typedef names for linkage purposes\iref{dcl.enum} +that are not the same enumeration +is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Source file \tcode{"a.h"}} +enum { a }; +\end{codeblocktu} +\begin{codeblocktu}{Source file \tcode{"b.h"}} +enum { a, b }; +\end{codeblocktu} +\begin{codeblocktu}{Source file \tcode{"main.cpp"}} +import "a.h"; +import "b.h"; +auto n = decltype(a)::b; // IFNDR, more than one unnamed enum definition reachable at + // this point but their types are not the same +\end{codeblocktu} +\end{example} + +\ifndrdescription{basic.contract.vastart.contract.predicate} + +\pnum +The use of \tcode{va_start}\iref{cstdarg.syn} +within the predicate of a contract assertion +is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +void f(...) +{ + va_list args; + contract_assert((va_start(const_cast(args)), true)) // IFNDR +} +\end{codeblock} +\end{example} + +\ifndrdescription{basic.contract.handler.replacing.nonreplaceable} + +\pnum +On platforms where +the contract-violation handler +is not replaceable\iref{dcl.fct.def.replace} +a function declaration which could be such a replacement function +is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +#include +void handle_contract_violation(const std::contracts::contract_violation& violation); + // IFNDR, if contract-violation handler is not replaceable +\end{codeblock} +\end{example} + +\ifndrdescription{class.member.lookup.name.refers.diff.decl} + +\pnum +A name $N$ used in a class $S$ +referring to a different declaration when resolved in its context +than when re-evaluated in the completed scope of $S$ +is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +struct foo {}; + +struct bar { + foo *m_foo; + + foo *foo() { + return m_foo; + } // IFNDR, \tcode{foo} now refers to member function \tcode{foo()} while previously referred to \tcode{struct} \tcode{foo} +}; +\end{codeblock} +\end{example} +\begin{example} +\begin{codeblock} +struct B { + static int f(); +}; + +struct D : public B { + using B::f; + int g(decltype(f()) x) { + return 0; + } // IFNDR, \tcode{decltype(f())} will refer to \tcode{B::f()} here but if + // moved to the end of \tcode{D} it would refer to \tcode{D::f()} + static float f(); +}; + +int main() { + D d; + + return d.g(0); +} +\end{codeblock} +\end{example} + +\rSec1[ifndr.expr]{\ref*{expr}: Expressions} + +\ifndrdescription{expr.prim.req.always.sub.fail} + +\pnum +If the substitution of template arguments +into a \grammarterm{requirement} +would always result in a substitution failure, +the program is ill-formed; no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +template concept C = requires { + new int[-(int)sizeof(T)]; // IFNDR, the size of the allocation is required to be greater + // than zero but can never be +}; +\end{codeblock} +\end{example} + +\rSec1[ifndr.stmt]{\ref*{stmt}: Statements} + +\ifndrdescription{stmt.ambig.bound.diff.parse} + +\pnum +If, during +parsing, a name in a template parameter is bound differently than it would be bound during a trial parse, +the program is ill-formed. No diagnostic is required. + +\pnum +\begin{example} +\begin{codeblock} +template struct A { const static int a = 20; }; + +template <> struct A<100> { using a = char; }; + +const int x = 10; + +int main() { + using T = const int; + T(x) + (100), (y)(A::a); // IFNDR, during trial parse the template parameter \tcode{x} is bound to + // the global \tcode{x} later during parsing the template parameter \tcode{x} + // is bound to the local \tcode{x} declared on the same line +} +\end{codeblock} +\end{example} + +\rSec1[ifndr.dcl]{\ref*{dcl}: Declarations} + +\ifndrdescription{dcl.constinit.specifier.not.reachable} + +\pnum +If the initializing declaration +of a variable without the \tcode{constinit} specifier +has the \tcode{constinit} specifier +applied to declarations that are not reachable from +that initializing declaration, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +int x = 5; // initializing declaration of \tcode{x} +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +extern constinit int x; // IFNDR, not reachable from initializing declaration of \tcode{x} +\end{codeblocktu} +\end{example} + +\ifndrdescription{dcl.inline.missing.on.definition} + +\pnum +If a function or variable +with external or module linkage +is declared inline +but there is no inline declaration +reachable from the end of some definition domain +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +inline int f(); +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +int f() { return 17; } + // IFNDR, end of definition domain but no inline declaration of \tcode{f} is reachable +\end{codeblocktu} +\end{example} + +\ifndrdescription{dcl.fct.default.inline.same.defaults} + +\pnum +If the accumulated set of default arguments +for a given inline function +with definitions in multiple translation units +is different at the end +of different translation units, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +inline int f(int x, int y = 2); +inline int f(int x = 1, int y); + // IFNDR, default arguments of \tcode{f} are \tcode{1} and \tcode{2} +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +inline int f(int x = 3, int y = 4); + // IFNDR, default arguments of \tcode{f} are \tcode{3} and \tcode{4} +\end{codeblocktu} +\end{example} + +\ifndrdescription{dcl.contract.func.mismatched.contract.specifiers} + +\pnum +If two different first declarations of a function +(which must therefore not be reachable from one another) +do not have equivalent function contract specifiers +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +int f(int x) pre(x >= 0); // IFNDR, \tcode{pre} present, not present in the other first declaration of \tcode{f} +int g(int x) pre(x == 0); // IFNDR, \tcode{pre} differs from the other first declaration of \tcode{g} +int h(int x) pre(x <= 0); // OK, \tcode{pre} equivalent to \tcode{pre} on the other first declaration of \tcode{h} +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +int f(int x); // IFNDR, \tcode{pre} not present, present in the other first declaration of \tcode{f} +int g(int x) pre(x != 0); // IFNDR, \tcode{pre} differs from the other first declaration of \tcode{g} +int h(int y) pre(y <= 0); // OK, \tcode{pre} equivalent to \tcode{pre} on the other first declaration of \tcode{h} +\end{codeblocktu} +\end{example} + +\ifndrdescription{dcl.fct.def.replace.bad.replacement} + +\pnum +A declaration of a replaceable function +that is inline, +not attached to the global module, +does not have \Cpp{} language linkage, +does not have the required return type, +or is not a valid redeclaration of the +corresponding declaration in a standard library header (if there is one) +then the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +extern "C" // IFNDR, wrong language linkage +inline // IFNDR, inline +int // IFNDR, wrong return type +handle_contract_violation(const std::contracts::contract_violation&) {} + +void* operator new(decltype(sizeof(0))) noexcept; // IFNDR, mismatched exception specification to + // declaration in \tcode{} +\end{codeblock} +\end{example} + +\ifndrdescription{dcl.link.mismatched.language.linkage} + +\pnum +If two declarations of an entity +do not have the same language linkage +and neither is reachable from the other +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +extern "C" { void f(); } +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +extern "C++" { void f(); } // IFNDR, different language linkage +\end{codeblocktu} +\end{example} + +\ifndrdescription{dcl.align.diff.translation.units} + +\pnum +No diagnostic is required if declarations of an entity have different \grammarterm{alignment-specifier}s in different +translation units. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +struct S { int x; } s, *p = &s; +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +struct alignas(16) S; // IFNDR, definition of \tcode{S} lacks alignment +extern S* p; +\end{codeblocktu} +\end{example} + +\ifndrdescription{dcl.attr.indet.mismatched.declarations} + +\pnum +If two first declarations of a function +declare a function parameter with +mismatched uses of the \tcode{indeterminate} attribute, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +int h(int x [[indeterminate]]); // IFNDR, mismatched \tcode{[[indeterminate]]} to other first declaration of \tcode{h} +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +int h(int x); // IFNDR, mismatched \tcode{[[indeterminate]]} to other first declaration of \tcode{h} +\end{codeblocktu} +\end{example} + +\ifndrdescription{dcl.attr.noreturn.trans.unit.mismatch} + +\pnum +No diagnostic is required if a function is declared +in one translation unit with the \tcode{noreturn} attribute +but has declarations in other translation units +without the attribute. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +[[noreturn]] void f() {} +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +void f(); // IFNDR, declared without \tcode{noreturn} +\end{codeblocktu} +\end{example} + +\rSec1[ifndr.module]{\ref*{module}: Modules} + +\ifndrdescription{module.unit.reserved.identifiers} + +\pnum +Specifying a \grammarterm{module-name} +beginning with an identifier +consisting of \tcode{std} followed by zero or more digits, +or containing a reserved identifier\iref{lex.token} +in a \grammarterm{module-declaration} +is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +module std; // IFNDR, \tcode{std} is not allowed at the beginning +module module; // IFNDR, \tcode{module} is a reserved identifier +module std0; // IFNDR, \tcode{std} followed by digits is not allowed at the beginning +export module _Test; // IFNDR, \tcode{_Test} is a reserved identifier +export module te__st; // IFNDR, \tcode{te__st} is a reserved identifier +\end{codeblock} +\end{example} + +\ifndrdescription{module.unit.named.module.no.partition} + +\pnum +Having multiple primary module interface units +for a named module +is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +module A; +export import :Internals; // IFNDR, module partition not allowed +\end{codeblock} +\end{example} + +\ifndrdescription{module.unit.unexported.module.partition} + +\pnum +If a module partition of a module +that is a module interface unit +but is not directly or indirectly exported +by the primary module interface unit\iref{module.import}, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module M; // primary module interface unit +export import :A; +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +export module M:A; // OK, directly exported by \tcode{M} +export import :B; +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#3} +export module M:B; // OK, indirectly exported by \tcode{M} +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#4} +export module M:C; // IFNDR, not directly or indirectly exported by \tcode{M} +\end{codeblocktu} +\end{example} + +\ifndrdescription{module.private.frag.other.module.units} + +\pnum +If a module has a private module fragment +and there is another module unit of that module, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module M; +module :private; // private module fragment +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +module M:A; // IFNDR, partition of \tcode{M} with private module fragment +\end{codeblocktu} +\end{example} + +\rSec1[ifndr.class]{\ref*{class}: Classes} + +\ifndrdescription{class.base.init.delegate.itself} + +\pnum +If a constructor delegates to itself directly or indirectly, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +struct C { + C( int ) { } // \#1: non-delegating constructor + C(): C(42) { } // \#2: delegates to \#1 + C( char c ) : C(42.0) { } // \#3: IFNDR due to recursion with \#4 + C( double d ) : C('a') { } // \#4: IFNDR due to recursion with \#3 +}; +\end{codeblock} +\end{example} + +\ifndrdescription{class.virtual.pure.or.defined} + +\pnum +If a virtual function that is not pure +has no definition, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +class A { + virtual void f(); +}; + +int main() { + A a; // IFNDR, virtual function that is not pure but has no definition +} +\end{codeblock} +\end{example} + +\rSec1[ifndr.over]{\ref*{over}: Overloading} + +\ifndrdescription{over.literal.reserved} + +\pnum +Some literal suffix identifiers are +reserved for future standardization. A declaration whose \grammarterm{literal-operator-id} uses such a literal +suffix identifier is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +float operator ""E(const char*); // IFNDR, reserved literal suffix +double operator"" _Bq(long double); // IFNDR, uses the reserved identifier \tcode{_Bq} +\end{codeblock} +\end{example} + +\rSec1[ifndr.temp]{\ref*{temp}: Templates} + +\ifndrdescription{temp.pre.reach.def} + +\pnum +A definition of a function template, +member function of a class template, +variable template, +or static data member of a class template +that is not reachable from +the end of every definition domain\iref{basic.def.odr} +in which it is implicitly instantiated\iref{temp.inst} +and whose corresponding specialization +is not explicitly instantiated\iref{temp.explicit} in some translation unit +is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Source file \tcode{"a.h"}} +template +void f(); +\end{codeblocktu} +\begin{codeblocktu}{Source file \tcode{"a.cpp"}} +#include "a.h" +int main() { + f(); // IFNDR, function template implicitly instantiated but not reachable definition +} +\end{codeblocktu} +\end{example} + +\ifndrdescription{temp.arg.template.sat.constraints} + +\pnum +Any partial specializations\iref{temp.spec.partial} +associated with the primary template are considered when a 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. + +\pnum +\begin{example} +\begin{codeblock} +template struct A { + int x; +}; + +template class V> struct C { + V y; + V z; +}; + +C c; + +// IFNDR, specialization is not reachable from point of instantiation above and it would have +// been selected if it had +template struct A { + long x; +}; +\end{codeblock} +\end{example} + +\ifndrdescription{temp.constr.atomic.equiv.but.not.equiv} + +\pnum +If the validity or meaning of the program +depends on whether two atomic constraints are equivalent, +and they are functionally equivalent but not equivalent, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +template concept Add1 = true; +template void f2() +requires Add1<2 * N>; +template int f2() +requires Add1 && true; +void h2() { +f2<0>(); // IFNDR, requires determination of subsumption between atomic constraints + // that are functionally equivalent but not equivalent +} +\end{codeblock} +\end{example} + +\ifndrdescription{temp.constr.atomic.sat.result.diff} + +\pnum +If, at different points in the program, +the satisfaction result is different +for identical atomic constraints and template arguments, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +template +concept Complete = sizeof(T) == sizeof(T); + +struct A; +static_assert(!Complete); // \#1 +struct A {}; +static_assert(Complete); // IFNDR, satisfaction result differs from point \#1 +\end{codeblock} +\end{example} + +\ifndrdescription{temp.constr.normal.invalid} + +\pnum +If during constraint normalization +any such substitution results in an invalid type or expression, +the program is ill-formed, no diagnostic is required. + +\pnum +\begin{example} +\begin{codeblock} +template concept A = T::value || true; +template concept B = A; +template concept C = B; // IFNDR, it would form the invalid type \tcode{V\&*} + // in the parameter mapping +\end{codeblock} +\end{example} + +\ifndrdescription{temp.spec.partial.general.partial.reachable} + +\pnum +If a partial specialization +is not reachable from a use of a template specialization +that would make use of that partial specialization +as the result of an implicit or explicit instantiation, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +template class X{ +public: + void foo(){}; +}; + +template class X; // IFNDR, explicit instantiation and partial specialization is not reachable + +template class X{ +public: + void baz(); +}; +\end{codeblock} +\end{example} + +\ifndrdescription{temp.over.link.equiv.not.equiv} + +\pnum +If the validity or meaning of the program +depends on whether two constructs are equivalent, +and they are functionally equivalent but not equivalent, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +template +struct A{}; + +// IFNDR, the following declarations are functionally equivalent but not equivalent +template void f(A, A); +template void f(A, A); +\end{codeblock} +\end{example} + +\ifndrdescription{temp.res.general.default.but.not.found} + +\pnum +If the validity or meaning of the program +would be changed by considering +a default argument or default template argument +introduced in a declaration that is reachable +from the point of instantiation of a specialization\iref{temp.point} +but is not found by lookup for the specialization, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +void f(long); // \#1 +void f(int, int); // \#2 +template void g(T t) { f(t); } +void f(int, int = 0); // \#3 +void h() { g(0); } // IFNDR, selects \#3 here but selects \#1 using lookup for \tcode{g} +\end{codeblock} +\end{example} + +\ifndrdescription{temp.point.diff.pt.diff.meaning} + +\pnum +A specialization for a class template has +at most one point of instantiation within a translation unit. +A specialization for any template +may have points of instantiation in multiple translation units. +If two different points of instantiation +give a template specialization +different meanings according to the one-definition rule\iref{basic.def.odr}, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Source file \tcode{"a.h"}} +#include + +template +struct is_complete : std::false_type {}; + +template +struct is_complete> : std::true_type {}; +\end{codeblocktu} +\begin{codeblocktu}{Source file \tcode{"a.cpp"}} +#include "a.h" +struct X; +static_assert(!is_complete::value); // IFNDR, different specialization selected in \tcode{"b.cpp"} +\end{codeblocktu} +\begin{codeblocktu}{Source file \tcode{"b.cpp"}} +#include "a.h" +struct X { }; +static_assert(is_complete::value); // IFNDR, different specialization selected in \tcode{"a.cpp"} +\end{codeblocktu} +\end{example} + +\ifndrdescription{temp.dep.candidate.different.lookup.different} + +\pnum +If considering all function declarations +with external linkage +in the associated namespaces in all translations +would make a dependent call\iref{temp.dep} ill-formed +or find a better match, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +namespace A { + struct S {}; + void f(S&, long x, int y); // \#3 + void g(S&, int x); // \#4 +} +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +namespace A { + struct S {}; + void f(S&, int x, long y); // \#5 + void g(S&, long x); // \#6 +} +template +void h(T& t) +{ + f(t, 1, 1); // Selects \#5 in \tcode{h}, would be ambiguous call if all declarations were considered. + g(t, 1); // Selects \#6 in \tcode{h}, would select \#4 if all declarations were considered. +} +\end{codeblocktu} +\end{example} + +\ifndrdescription{temp.explicit.decl.implicit.inst} + +\pnum +If an entity that is the subject of +an explicit instantiation declaration +and that is also used +in a way that would otherwise cause an implicit +instantiation\iref{temp.inst} +in the translation unit +is not the subject of +an explicit instantiation definition somewhere in the program +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +extern template class std::vector; // explicit instantiation declaration + +int main() { + std::cout << std::vector().size(); // IFNDR, implicit instantiation but no explicit + // instantiation definition +} +\end{codeblock} +\end{example} + +\ifndrdescription{temp.expl.spec.unreachable.declaration} + +\pnum +If an implicit instantiation of a template would occur +and there is an unreachable explicit specialization +that would have matched, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblocktu}{Source file \tcode{"a.h"}} +template struct S {}; +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#2} +#include "a.h" +template <> struct S { int oops; }; // \#1 +\end{codeblocktu} +\begin{codeblocktu}{Translation unit \#3} +#include "a.h" +S s; // IFNDR, \#1 is not reachable but would have matched +\end{codeblocktu} +\end{example} + +\ifndrdescription{temp.expl.spec.missing.definition} + +\pnum +If an explicit specialization of a template is +declared but there is no definition provided +for that specialization, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +template int f(T&&) { return 0; } +template <> int f(int&&); +int j = f(1); // IFNDR, odr-use of \tcode{f} with no definition +\end{codeblock} +\end{example} + +\ifndrdescription{temp.deduct.general.diff.order} + +\pnum +If substitution +into different declarations +of the same function template +would cause template instantiations to occur +in a different order or not at all, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +template struct A { using X = typename T::X; }; +template typename T::X h(typename A::X); // \#1 +template auto h(typename A::X) -> typename T::X; // redeclaration \#2 +template void h(...) { } + +void x() { + h(0); // Substituting into \#1 forms an invalid type from \tcode{T::X} and does + // not attempt to instantiate \tcode{A}. + // Substituting into \#2 instantiates \tcode{A}, which is ill-formed. +} +\end{codeblock} +\end{example} + +\rSec1[ifndr.cpp]{\ref*{cpp}: Preprocessing directives} + +\ifndrdescription{cpp.cond.defined.after.macro} + +\pnum +If the expansion of a macro produces the preprocessing token \tcode{defined} +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +#define A defined +#if A // IFNDR, \tcode{defined} is generated by macro replacement in controlling expression +#endif +\end{codeblock} +\end{example} + +\ifndrdescription{cpp.cond.defined.malformed} + +\pnum +If the \tcode{defined} unary operator is used when it +does not match +one of the specified grammatical forms, +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +#define A +#define B A) +#if defined ( B // IFNDR, unary operator \tcode{defined} did not match valid form before replacement +#endif +\end{codeblock} +\end{example} + +\ifndrdescription{cpp.include.malformed.headername} + +\pnum +If the \grammarterm{header-name-tokens} after +an \tcode{include} directive +cannot be formed into a \grammarterm{header-name} +(with imp\-lementation-defined treatment of whitespace), +the program is ill-formed, no diagnostic required. + +\pnum +\begin{example} +\begin{codeblock} +#include `` // IFNDR, does not match one of the two allowable forms +\end{codeblock} +\end{example} diff --git a/source/intro.tex b/source/intro.tex index d5cb23dc23..3fdf69f16e 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -1,23 +1,26 @@ %!TEX root = std.tex +\clearpage +\bigskip\noindent\textlarger{\textbf{Programming languages --- \Cpp{}}} +\bigskip\bigskip + +\begingroup +\let\clearpage\relax \rSec0[intro.scope]{Scope} +\endgroup +\copypagestyle{cpppageone}{cpppage} +\makeoddhead{cpppageone}{\textbf{WORKING DRAFT}}{}{\leaders\hrule height 2pt\hfill\kern0pt\\\textbf{\docno}} +\makeheadrule{cpppageone}{\textwidth}{2pt} +\thispagestyle{cpppageone} \pnum \indextext{scope|(}% This document specifies requirements for implementations -of the \Cpp{} programming language. The first such requirement is that +of \Cpp{}, which is a general-purpose programming language. +The first such requirement is that an implementation implements the language, so this document also defines \Cpp{}. Other requirements and relaxations of the first requirement appear at various places within this document. - -\pnum -\Cpp{} is a general purpose programming language based on the C -programming language as described in \IsoC{}. -\Cpp{} provides many facilities -beyond those provided by C, including additional data types, -classes, templates, exceptions, namespaces, operator -overloading, function name overloading, references, free store -management operators, and additional library facilities.% \indextext{scope|)} \rSec0[intro.refs]{Normative references}% @@ -60,8 +63,8 @@ Language Specification}, Standard Ecma-262, third edition, 1999. \item -The Unicode Consortium. \doccite{The Unicode Standard}. -Available from: \url{https://www.unicode.org/versions/latest/} +The Unicode Consortium. \doccite{The Unicode Standard}, Version 15.1. +Available from: \url{https://www.unicode.org/versions/Unicode15.1.0/} \end{itemize} \indextext{references!normative|)} @@ -89,10 +92,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 +106,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}% @@ -209,7 +213,7 @@ \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} +as a core constant expression\iref{expr.const.core} \definition{constant subexpression}{defns.const.subexpr} \indexdefn{constant subexpression}% @@ -242,8 +246,9 @@ glvalue refers \begin{example} -If a pointer\iref{dcl.ptr} \tcode{p} whose static type is ``pointer to -class \tcode{B}'' is pointing to an object of class \tcode{D}, derived +If a pointer\iref{dcl.ptr} \tcode{p} whose type is ``pointer to +class \tcode{B}'' is pointing to a base class subobject +of class \tcode{B}, whose most derived object is of class \tcode{D}, derived from \tcode{B}\iref{class.derived}, the dynamic type of the expression \tcode{*p} is ``\tcode{D}''. References\iref{dcl.ref} are treated similarly. @@ -260,7 +265,7 @@ Erroneous behavior is always the consequence of incorrect program code. Implementations are allowed, but not required, to diagnose it\iref{intro.compliance.general}. -Evaluation of a constant expression\iref{expr.const} +Evaluation of a constant expression\iref{expr.const.core} never exhibits behavior specified as erroneous in \ref{intro} through \ref{\lastcorechapter}. \end{defnote} @@ -457,6 +462,11 @@ \end{codeblock} \end{example} +\indexdefn{property!of the implementation}% +\definition{property of the implementation}{defns.impl.prop} +behavior, for a well-formed program\iref{defns.well.formed} +construct and correct data, that depends on the implementation + \definition{referenceable type}{defns.referenceable} \indexdefn{type!referenceable}% type that is either an @@ -520,7 +530,7 @@ 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 +(as specified in~\ref{expr.const.core}) and \item runtime-undefined behavior has no other effect. \end{itemize} @@ -665,7 +675,7 @@ \termref{defns.diagnostic}{diagnostic message}{}), to terminating a translation or execution (with the 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 +Evaluation of a constant expression\iref{expr.const.core} never exhibits behavior explicitly specified as undefined in \ref{intro} through \ref{\lastcorechapter}. \end{defnote} @@ -749,7 +759,7 @@ \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}. +the data being processed; see \ref{intro.defs} and~\ref{intro.abstract}. \end{footnote} that program, except when the implementation's limitations (see below) are exceeded. @@ -761,17 +771,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.defns} +resulting in a contract violation, \end{itemize} a conforming implementation shall issue at least one diagnostic message. @@ -787,10 +804,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.defns} +resulting in a contract violation. \end{itemize} \pnum @@ -821,7 +842,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 @@ -834,12 +856,27 @@ 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 +\recommended 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 use an implementation-defined version +of the Unicode Standard that is a later version than the one +referenced in \ref{intro.refs}. + \pnum A conforming implementation may have extensions (including additional library functions), provided they do not alter the @@ -888,10 +925,14 @@ \pnum \indextext{behavior!implementation-defined}% -Certain aspects and operations of the abstract machine are described in this +Certain aspects and operations of the abstract machine +constitute the parameters of the abstract machine and +are described in this document as implementation-defined behavior (for example, -\tcode{sizeof(int)}). These constitute the parameters of the abstract machine. -Each implementation shall include documentation describing its characteristics +\tcode{sizeof(int)}) +or as properties of the implementation (for example, padding in class types). +For implementation-defined behavior, +each implementation shall include documentation describing its characteristics and behavior in these respects. \begin{footnote} This documentation also includes @@ -918,27 +959,46 @@ 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_checkpoint}\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 execution contains an operation specified as having erroneous behavior, +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 of an operation is specified as having erroneous behavior, the implementation is permitted to issue a diagnostic and -is permitted to terminate the execution -at an unspecified time after that operation. +is permitted to terminate the execution of the program. \pnum \recommended @@ -952,23 +1012,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.23.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. @@ -1030,9 +1095,9 @@ (e.g., \grammarterm{qualified-id}). \item \fakegrammarterm{X-seq} is one or more \fakegrammarterm{X}'s without intervening delimiters (e.g., \grammarterm{declaration-seq} is a sequence of -declarations). +\grammarterm{declaration}s). \item \fakegrammarterm{X-list} is one or more \fakegrammarterm{X}'s separated by intervening commas (e.g., \grammarterm{identifier-list} is a sequence of -identifiers separated by commas). +\grammarterm{identifier}s separated by commas). \end{itemize}% \indextext{notation!syntax|)} diff --git a/source/iostreams.tex b/source/iostreams.tex index c44ab8b2a8..e517bbccde 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -225,17 +225,13 @@ template> class basic_iostream; - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_stringbuf; - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_istringstream; - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_ostringstream; - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_stringstream; template> @@ -256,11 +252,9 @@ template> class basic_fstream; - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_syncbuf; - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_osyncstream; template> @@ -369,17 +363,19 @@ serves as a base class for class templates \tcode{basic_stringbuf}, \tcode{basic_filebuf}, +\tcode{basic_syncbuf}, and -\tcode{basic_syncbuf}. +\tcode{basic_spanbuf}. \pnum The class template specialization \tcode{basic_istream} serves as a base class for class templates -\tcode{basic_istringstream} +\tcode{basic_istringstream}, +\tcode{basic_ifstream}, and -\tcode{basic_ifstream}. +\tcode{basic_ispanstream}. \pnum The @@ -388,17 +384,19 @@ serves as a base class for class templates \tcode{basic_ostringstream}, \tcode{basic_ofstream}, +\tcode{basic_osyncstream}, and -\tcode{basic_osyncstream}. +\tcode{basic_ospanstream}. \pnum The class template specialization \tcode{basic_iostream} serves as a base class for class templates -\tcode{basic_stringstream} +\tcode{basic_stringstream}, +\tcode{basic_fstream}, and -\tcode{basic_fstream}. +\tcode{basic_spanstream}. \pnum \begin{note} @@ -410,9 +408,8 @@ \end{note} \pnum -Other \grammarterm{typedef-name}{s} define instances of -class templates -specialized for +Other \grammarterm{typedef-name}{s} designate +class template specializations for \tcode{char} or \keyword{wchar_t} @@ -480,6 +477,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 @@ -532,7 +535,7 @@ can result in interleaved characters. \end{note} -\xrefc{7.21.2} +\xrefc{7.23.2} \rSec2[narrow.stream.objects]{Narrow stream objects} @@ -1814,9 +1817,9 @@ class basic_ios : public ios_base { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; // \ref{iostate.flags}, flags functions @@ -2046,7 +2049,7 @@ \begin{itemdescr} \pnum \returns -\tcode{use_facet>(getloc()).narrow(c, dfault)} +\tcode{use_facet>(getloc()).narrow(c, dfault)}. \end{itemdescr} \indexlibrarymember{widen}{basic_ios}% @@ -2057,7 +2060,7 @@ \begin{itemdescr} \pnum \returns -\tcode{use_facet>(getloc()).widen(c)} +\tcode{use_facet>(getloc()).widen(c)}. \end{itemdescr} \indexlibrarymember{fill}{basic_ios}% @@ -2310,7 +2313,7 @@ \begin{itemdescr} \pnum \returns -\tcode{rdstate() == 0} +\tcode{rdstate() == 0}. \end{itemdescr} \indexlibrarymember{eof}{basic_ios}% @@ -2999,9 +3002,9 @@ class basic_streambuf { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; virtual ~basic_streambuf(); @@ -3636,7 +3639,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} @@ -3658,7 +3661,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} @@ -4058,7 +4061,7 @@ That is, for each class derived from a specialization of \tcode{basic_streambuf} in this Clause\iref{stringbuf,filebuf}, -a specification of how consuming a character effects the associated output sequence is given. +a specification of how consuming a character affects the associated output sequence is given. There is no requirement on a program-defined class. \end{footnote} \item @@ -4310,9 +4313,9 @@ public: // types (inherited from \tcode{basic_ios}\iref{ios}) using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; // \ref{istream.cons}, constructor/destructor @@ -4357,6 +4360,7 @@ basic_istream& getline(char_type* s, streamsize n, char_type delim); basic_istream& ignore(streamsize n = 1, int_type delim = traits::eof()); + basic_istream& ignore(streamsize n, char_type delim); int_type peek(); basic_istream& read (char_type* s, streamsize n); streamsize readsome(char_type* s, streamsize n); @@ -4383,17 +4387,9 @@ // \ref{istream.extractors}, character extraction templates template basic_istream& operator>>(basic_istream&, charT&); - template - basic_istream& operator>>(basic_istream&, unsigned char&); - template - basic_istream& operator>>(basic_istream&, signed char&); template basic_istream& operator>>(basic_istream&, charT(&)[N]); - template - basic_istream& operator>>(basic_istream&, unsigned char(&)[N]); - template - basic_istream& operator>>(basic_istream&, signed char(&)[N]); } \end{codeblock} @@ -4762,7 +4758,7 @@ } else if (numeric_limits::max() < lval) { state |= ios_base::failbit; val = numeric_limits::max(); -} else +} else val = static_cast(lval); \end{codeblock} \end{itemdescr} @@ -4786,7 +4782,7 @@ } else if (numeric_limits::max() < lval) { state |= ios_base::failbit; val = numeric_limits::max(); -} else +} else val = static_cast(lval); \end{codeblock} \end{itemdescr} @@ -4915,10 +4911,6 @@ \begin{itemdecl} template basic_istream& operator>>(basic_istream& in, charT (&s)[N]); -template - basic_istream& operator>>(basic_istream& in, unsigned char (&s)[N]); -template - basic_istream& operator>>(basic_istream& in, signed char (&s)[N]); \end{itemdecl} \begin{itemdescr} @@ -4942,7 +4934,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}. @@ -4972,10 +4964,6 @@ \begin{itemdecl} template basic_istream& operator>>(basic_istream& in, charT& c); -template - basic_istream& operator>>(basic_istream& in, unsigned char& c); -template - basic_istream& operator>>(basic_istream& in, signed char& c); \end{itemdecl} \begin{itemdescr} @@ -5378,7 +5366,7 @@ \begin{itemdescr} \pnum \returns -\tcode{getline(s, n, widen('\textbackslash n'))} +\tcode{getline(s, n, widen('\textbackslash n'))}. \end{itemdescr} \indexlibrarymember{ignore}{basic_istream}% @@ -5420,6 +5408,21 @@ \tcode{*this}. \end{itemdescr} +\indexlibrarymember{ignore}{basic_istream}% +\begin{itemdecl} +basic_istream& ignore(streamsize n, char_type delim); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_same_v} is \tcode{true}. + +\pnum +\effects +Equivalent to: \tcode{return ignore(n, traits::to_int_type(delim));} +\end{itemdescr} + \indexlibrarymember{peek}{basic_istream}% \begin{itemdecl} int_type peek(); @@ -5635,7 +5638,7 @@ calls \tcode{setstate(badbit)} (which may throw -\tcode{ios_base::failure}\iref{iostate.flags}, +\tcode{ios_base::failure}\iref{iostate.flags}), and returns \tcode{-1}. Otherwise, returns zero. @@ -5787,9 +5790,9 @@ public basic_ostream { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; // \ref{iostream.cons}, constructor @@ -5918,9 +5921,9 @@ public: // types (inherited from \tcode{basic_ios}\iref{ios}) using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; // \ref{ostream.cons}, constructor/destructor @@ -5984,11 +5987,6 @@ template basic_ostream& operator<<(basic_ostream&, char); - template - basic_ostream& operator<<(basic_ostream&, signed char); - template - basic_ostream& operator<<(basic_ostream&, unsigned char); - template basic_ostream& operator<<(basic_ostream&, wchar_t) = delete; template @@ -6014,11 +6012,6 @@ template basic_ostream& operator<<(basic_ostream&, const char*); - template - basic_ostream& operator<<(basic_ostream&, const signed char*); - template - basic_ostream& operator<<(basic_ostream&, const unsigned char*); - template basic_ostream& operator<<(basic_ostream&, const wchar_t*) = delete; @@ -6251,7 +6244,8 @@ is \tcode{true}, calls -\tcode{os.rdbuf()->pubsync()}. If that function returns $-1$, sets \tcode{badbit} in +\tcode{os.rdbuf()->pubsync()}. If that function returns $-1$ or +exits via an exception, sets \tcode{badbit} in \tcode{os.rdstate()} without propagating an exception. \end{itemdescr} @@ -6699,11 +6693,6 @@ // specialization template basic_ostream& operator<<(basic_ostream& out, char c); -// signed and unsigned -template - basic_ostream& operator<<(basic_ostream& out, signed char c); -template - basic_ostream& operator<<(basic_ostream& out, unsigned char c); \end{itemdecl} \begin{itemdescr} @@ -6735,11 +6724,6 @@ basic_ostream& operator<<(basic_ostream& out, const char* s); template basic_ostream& operator<<(basic_ostream& out, const char* s); -template - basic_ostream& operator<<(basic_ostream& out, const signed char* s); -template - basic_ostream& operator<<(basic_ostream& out, - const unsigned char* s); \end{itemdecl} \begin{itemdescr} @@ -6770,10 +6754,7 @@ for the overload where the first argument is of type \tcode{basic_ostream\&} and the second is of type -\tcode{const char*}, -\item -\tcode{traits::length(reinterpret_cast(s))} -for the other two overloads. +\tcode{const char*}. \end{itemize} Determines padding for \tcode{seq} as described in~\ref{ostream.formatted.reqmts}. Inserts \tcode{seq} into @@ -6872,6 +6853,7 @@ if \tcode{out} contains invalid code units, \indextext{undefined}% the behavior is undefined. +Then establishes an observable checkpoint\iref{intro.abstract}. \item Otherwise inserts the character sequence @@ -7780,7 +7762,7 @@ \effects Equivalent to: \begin{codeblock} -print(stream, runtime_format(string(fmt.get()) + '\n'), std::forward(args)...); +print(stream, dynamic_format(string(fmt.get()) + '\n'), std::forward(args)...); \end{codeblock} \end{itemdescr} @@ -7852,12 +7834,13 @@ if \tcode{out} contains invalid code units, \indextext{undefined}% the behavior is undefined. +Then establishes an observable checkpoint\iref{intro.abstract}. \item Otherwise writes \tcode{out} to \tcode{stream} unchanged. \end{itemize} Unconditionally unlocks \tcode{stream} on function exit. -\xrefc{7.21.2}. +\xrefc{7.23.2}. \begin{note} On Windows the native Unicode API is \tcode{WriteConsoleW} and @@ -7905,7 +7888,7 @@ Equivalent to: \begin{codeblock} string out = vformat(fmt, args); -vprint_nonunicode("{}", make_format_args(out)); +vprint_nonunicode(stream, "{}", make_format_args(out)); \end{codeblock} \end{itemdescr} @@ -7957,8 +7940,7 @@ \begin{codeblock} namespace std { // \ref{stringbuf}, class template \tcode{basic_stringbuf} - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_stringbuf; template @@ -7969,8 +7951,7 @@ using wstringbuf = basic_stringbuf; // \ref{istringstream}, class template \tcode{basic_istringstream} - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_istringstream; template @@ -7981,8 +7962,7 @@ using wistringstream = basic_istringstream; // \ref{ostringstream}, class template \tcode{basic_ostringstream} - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_ostringstream; template @@ -7993,8 +7973,7 @@ using wostringstream = basic_ostringstream; // \ref{stringstream}, class template \tcode{basic_stringstream} - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_stringstream; template @@ -8019,14 +7998,13 @@ \indexlibraryglobal{basic_stringbuf}% \begin{codeblock} namespace std { - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_stringbuf : public basic_streambuf { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; using allocator_type = Allocator; @@ -8095,10 +8073,10 @@ 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 @\exposid{mode}@; // \expos @@ -8402,7 +8380,7 @@ (except for those characters re-initialized by the new \tcode{basic_string}). \begin{itemdecl} -void @\exposid{init-buf-ptrs}@(); // \expos +void @\exposid{init-buf-ptrs}@(); \end{itemdecl} \begin{itemdescr} @@ -8522,9 +8500,9 @@ the \tcode{basic_stringbuf}'s underlying character sequence in \tcode{buf}: \begin{itemize} \item If \tcode{ios_base::out} is set in \exposid{mode}, - then \tcode{sv(pbase(), high_mark-pbase())} is returned. + 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. + then \tcode{sv(eback(), egptr() - eback())} is returned. \item Otherwise, \tcode{sv()} is returned. \end{itemize} @@ -8560,7 +8538,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{is_same_v} is \tcode{false}. +\tcode{is_same_v} is \tcode{false}. \pnum \effects @@ -8880,14 +8858,13 @@ \indexlibraryglobal{basic_istringstream}% \begin{codeblock} namespace std { - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_istringstream : public basic_istream { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; using allocator_type = Allocator; @@ -9252,14 +9229,13 @@ \indexlibraryglobal{basic_ostringstream}% \begin{codeblock} namespace std { - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_ostringstream : public basic_ostream { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; using allocator_type = Allocator; @@ -9316,7 +9292,7 @@ template void str(const T& t); - private: + private: basic_stringbuf @\exposid{sb}@; // \expos }; } @@ -9426,7 +9402,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{is_same_v} is \tcode{false}. +\tcode{is_same_v} is \tcode{false}. \pnum \effects @@ -9624,14 +9600,13 @@ \indexlibraryglobal{basic_stringstream}% \begin{codeblock} namespace std { - template, - class Allocator = allocator> + template, class Allocator = allocator> class basic_stringstream : public basic_iostream { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; using allocator_type = Allocator; @@ -9804,7 +9779,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{is_same_v} is \tcode{false}. +\tcode{is_same_v} is \tcode{false}. \pnum \effects @@ -9981,7 +9956,7 @@ \indexlibrarymember{str}{basic_stringstream}% \begin{itemdecl} template - void str(const T&); + void str(const T& t); \end{itemdecl} \begin{itemdescr} @@ -10080,9 +10055,9 @@ : public basic_streambuf { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; // \ref{spanbuf.cons}, constructors @@ -10407,9 +10382,9 @@ : public basic_istream { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; // \ref{ispanstream.cons}, constructors @@ -10595,9 +10570,9 @@ : public basic_ostream { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; // \ref{ospanstream.cons}, constructors @@ -10734,9 +10709,9 @@ : public basic_iostream { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; // \ref{spanstream.cons}, constructors @@ -10978,9 +10953,9 @@ class basic_filebuf : public basic_streambuf { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; using native_handle_type = @\impdefx{type of \tcode{native_handle_type}}@; // see \ref{file.native} @@ -11420,10 +11395,10 @@ and then as if by doing: \begin{codeblock} -char extern_buf[XSIZE]; -char* extern_end; -charT intern_buf[ISIZE]; -charT* intern_end; +char extern_buf[XSIZE]; +const char* extern_end; +charT intern_buf[ISIZE]; +charT* intern_end; codecvt_base::result r = a_codecvt.in(state, extern_buf, extern_buf+XSIZE, extern_end, intern_buf, intern_buf+ISIZE, intern_end); @@ -11551,11 +11526,11 @@ except that the behavior of ``consuming characters'' is performed by first converting as if by: \begin{codeblock} -charT* b = pbase(); -charT* p = pptr(); -charT* end; -char xbuf[XSIZE]; -char* xbuf_end; +charT* b = pbase(); +charT* p = pptr(); +const charT* end; +char xbuf[XSIZE]; +char* xbuf_end; codecvt_base::result r = a_codecvt.out(state, b, p, end, xbuf, xbuf+XSIZE, xbuf_end); \end{codeblock} @@ -11571,6 +11546,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 @@ -11776,11 +11752,11 @@ class basic_ifstream : public basic_istream { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; - using native_handle_type = typename basic_filebuf::native_handle_type; + using native_handle_type = basic_filebuf::native_handle_type; // \ref{ifstream.cons}, constructors basic_ifstream(); @@ -11949,7 +11925,7 @@ \begin{itemdescr} \pnum \returns -\tcode{const_cast*>(addressof(@\exposid{sb}@))}. +\tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{native_handle}{basic_ifstream}% @@ -12035,11 +12011,11 @@ class basic_ofstream : public basic_ostream { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; - using native_handle_type = typename basic_filebuf::native_handle_type; + using native_handle_type = basic_filebuf::native_handle_type; // \ref{ofstream.cons}, constructors basic_ofstream(); @@ -12292,11 +12268,11 @@ class basic_fstream : public basic_iostream { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; - using native_handle_type = typename basic_filebuf::native_handle_type; + using native_handle_type = basic_filebuf::native_handle_type; // \ref{fstream.cons}, constructors basic_fstream(); @@ -12609,9 +12585,9 @@ class basic_syncbuf : public basic_streambuf { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; using allocator_type = Allocator; @@ -12922,9 +12898,9 @@ class basic_osyncstream : public basic_ostream { public: using char_type = charT; - using int_type = typename traits::int_type; - using pos_type = typename traits::pos_type; - using off_type = typename traits::off_type; + using int_type = traits::int_type; + using pos_type = traits::pos_type; + using off_type = traits::off_type; using traits_type = traits; using allocator_type = Allocator; @@ -13567,7 +13543,10 @@ \pnum \begin{note} -Class \tcode{path} is used to support the differences between the string types used by different operating systems to represent pathnames, and to perform conversions between encodings when necessary. +Class \tcode{path} is used to support the differences +between the string types used by different operating systems +to represent pathnames, +and to perform conversions between encodings when necessary. \end{note} \pnum @@ -13698,7 +13677,8 @@ class Allocator = allocator> basic_string string(const Allocator& a = Allocator()) const; - std::string string() const; + std::string display_string() const; + std::string native_encoded_string() const; std::wstring wstring() const; std::u8string u8string() const; std::u16string u16string() const; @@ -13709,7 +13689,8 @@ class Allocator = allocator> basic_string generic_string(const Allocator& a = Allocator()) const; - std::string generic_string() const; + std::string generic_display_string() const; + std::string generic_native_encoded_string() const; std::wstring generic_wstring() const; std::u8string generic_u8string() const; std::u16string generic_u16string() const; @@ -13769,7 +13750,7 @@ \indexlibrarymember{value_type}{path}% \pnum -\tcode{value_type} is a \keyword{typedef} for the +\tcode{value_type} is a \grammarterm{typedef-name} for the operating system dependent encoded character type used to represent pathnames. \indexlibrarymember{preferred_separator}{path}% @@ -14031,7 +14012,8 @@ so no conversion from \tcode{char} value type arguments or to \tcode{char} value type return values is performed. For Windows-based operating systems, the -native ordinary encoding is determined by calling a Windows API function. +native ordinary encoding is determined by +the current locale encoding and the Windows \tcode{AreFileApisANSI} function. \end{note} \begin{note} This results in behavior identical to other C and \Cpp{} @@ -14662,10 +14644,8 @@ \indexlibrarymember{string}{path}% \begin{itemdecl} -template, - class Allocator = allocator> - basic_string - string(const Allocator& a = Allocator()) const; +template, class Allocator = allocator> + basic_string string(const Allocator& a = Allocator()) const; \end{itemdecl} \begin{itemdescr} @@ -14680,13 +14660,13 @@ \ref{fs.path.cvt}. \end{itemdescr} -\indexlibrarymember{string}{path}% +\indexlibrarymember{native_encoded_string}{path}% \indexlibrarymember{wstring}{path}% \indexlibrarymember{u8string}{path}% \indexlibrarymember{u16string}{path}% \indexlibrarymember{u32string}{path}% \begin{itemdecl} -std::string string() const; +std::string native_encoded_string() const; std::wstring wstring() const; std::u8string u8string() const; std::u16string u16string() const; @@ -14704,6 +14684,20 @@ by \ref{fs.path.cvt}. \end{itemdescr} +\indexlibrarymember{display_string}{path}% +\begin{itemdecl} +std::string display_string() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{std::format("\{\}", *this)}. +\begin{note} +The returned string is suitable for use with formatting\iref{format.functions} +and print functions\iref{print.fun}. +\end{note} +\end{itemdescr} \rSec4[fs.path.generic.obs]{Generic format observers} @@ -14725,10 +14719,8 @@ \indexlibrarymember{generic_string}{path}% \begin{itemdecl} -template, - class Allocator = allocator> - basic_string - generic_string(const Allocator& a = Allocator()) const; +template, class Allocator = allocator> + basic_string generic_string(const Allocator& a = Allocator()) const; \end{itemdecl} \begin{itemdescr} @@ -14743,13 +14735,13 @@ \ref{fs.path.cvt}. \end{itemdescr} -\indexlibrarymember{generic_string}{path}% +\indexlibrarymember{generic_native_encoded_string}{path}% \indexlibrarymember{generic_wstring}{path}% \indexlibrarymember{generic_u8string}{path}% \indexlibrarymember{generic_u16string}{path}% \indexlibrarymember{generic_u32string}{path}% \begin{itemdecl} -std::string generic_string() const; +std::string generic_native_encoded_string() const; std::wstring generic_wstring() const; std::u8string generic_u8string() const; std::u16string generic_u16string() const; @@ -14766,6 +14758,21 @@ Conversion, if any, is specified by~\ref{fs.path.cvt}. \end{itemdescr} +\indexlibrarymember{generic_display_string}{path}% +\begin{itemdecl} +std::string generic_display_string() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{std::format("\{:g\}", *this)}. +\begin{note} +The returned string is suitable for use with formatting\iref{format.functions} +and print functions\iref{print.fun}. +\end{note} +\end{itemdescr} + \rSec4[fs.path.compare]{Compare} \indexlibrarymember{compare}{path}% @@ -17085,7 +17092,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} @@ -17245,7 +17252,7 @@ \begin{itemdecl} void filesystem::copy(const path& from, const path& to, copy_options options); void filesystem::copy(const path& from, const path& to, copy_options options, - error_code& ec); + error_code& ec); \end{itemdecl} \begin{itemdescr} @@ -17363,16 +17370,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 @@ -17381,10 +17388,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 @@ -17395,7 +17402,7 @@ file2 dir2 file3 -\end{codeblock} +\end{outputblock} \end{example} \end{itemdescr} @@ -17423,7 +17430,7 @@ \begin{itemdecl} bool filesystem::copy_file(const path& from, const path& to, copy_options options); bool filesystem::copy_file(const path& from, const path& to, copy_options options, - error_code& ec); + error_code& ec); \end{itemdecl} \begin{itemdescr} @@ -17486,7 +17493,7 @@ \begin{itemdecl} void filesystem::copy_symlink(const path& existing_symlink, const path& new_symlink); void filesystem::copy_symlink(const path& existing_symlink, const path& new_symlink, - error_code& ec) noexcept; + error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} @@ -17515,7 +17522,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 @@ -17602,13 +17609,13 @@ \begin{itemdecl} void filesystem::create_directory_symlink(const path& to, const path& new_symlink); void filesystem::create_directory_symlink(const path& to, const path& new_symlink, - error_code& ec) noexcept; + error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Establishes the postcondition, as if by POSIX \tcode{symlink()}. +Establishes the postcondition, as if by POSIX \tcode{symlink}. \pnum \ensures @@ -17623,7 +17630,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} @@ -17643,13 +17650,13 @@ \begin{itemdecl} void filesystem::create_hard_link(const path& to, const path& new_hard_link); void filesystem::create_hard_link(const path& to, const path& new_hard_link, - error_code& ec) noexcept; + error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Establishes the postcondition, as if by POSIX \tcode{link()}. +Establishes the postcondition, as if by POSIX \tcode{link}. \pnum \ensures @@ -17678,13 +17685,13 @@ \begin{itemdecl} void filesystem::create_symlink(const path& to, const path& new_symlink); void filesystem::create_symlink(const path& to, const path& new_symlink, - error_code& ec) noexcept; + error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Establishes the postcondition, as if by POSIX \tcode{symlink()}. +Establishes the postcondition, as if by POSIX \tcode{symlink}. \pnum \ensures @@ -17717,7 +17724,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. @@ -17731,12 +17738,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 @@ -17754,7 +17755,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 @@ -17787,7 +17788,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} @@ -17865,7 +17866,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} @@ -18227,7 +18228,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. @@ -18240,14 +18241,14 @@ \begin{itemdecl} void filesystem::last_write_time(const path& p, file_time_type new_time); void filesystem::last_write_time(const path& p, file_time_type new_time, - error_code& ec) noexcept; + error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \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 @@ -18281,7 +18282,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} @@ -18418,7 +18419,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. @@ -18453,7 +18454,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. @@ -18487,7 +18488,7 @@ \pnum \effects Renames \tcode{old_p} to \tcode{new_p}, as if by - POSIX \tcode{rename()}. + POSIX \tcode{rename}. \begin{note} \begin{itemize} @@ -18523,7 +18524,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 @@ -18610,14 +18611,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} @@ -18711,9 +18712,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 @@ -18723,7 +18724,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 @@ -18792,14 +18793,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. @@ -18825,22 +18826,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}% @@ -18887,28 +18872,31 @@ \indexlibraryglobal{ferror}% \indexlibraryglobal{perror}% \begin{codeblock} +#define @\libmacro{__STDC_VERSION_STDIO_H__}@ 202311L + namespace std { using size_t = @\textit{see \ref{support.types.layout}}@; using FILE = @\seebelow@; 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{_PRINTF_NAN_LEN_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); @@ -18963,12 +18951,28 @@ 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.23.3}) +is an observable checkpoint\iref{intro.abstract}. + +\pnum +When the input item for the \tcode{\%p} conversion +of the \tcode{fscanf} function (or equivalent) +is one that can be produced +from more than one pointer value\iref{basic.compound}, +the pointer that results is an unspecified choice among all those values +that would result in the program having defined behavior. +If no such value exists, the behavior is undefined. + \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 an argument that is a null pointer value. -\xrefc{7.21} +\xrefc{7.23} \rSec2[cinttypes.syn]{Header \tcode{} synopsis} @@ -18988,55 +18992,42 @@ \indexlibraryglobal{PRIuN}% \indexlibraryglobal{PRIxN}% \indexlibraryglobal{PRIXN}% +\indexlibraryglobal{PRIbN}% +\indexlibraryglobal{PRIBN}% \indexlibraryglobal{SCNdN}% \indexlibraryglobal{SCNiN}% \indexlibraryglobal{SCNoN}% \indexlibraryglobal{SCNuN}% \indexlibraryglobal{SCNxN}% +\indexlibraryglobal{SCNbN}% \indexlibraryglobal{PRIdLEASTN}% \indexlibraryglobal{PRIiLEASTN}% \indexlibraryglobal{PRIoLEASTN}% \indexlibraryglobal{PRIuLEASTN}% \indexlibraryglobal{PRIxLEASTN}% \indexlibraryglobal{PRIXLEASTN}% +\indexlibraryglobal{PRIbLEASTN}% +\indexlibraryglobal{PRIBLEASTN}% \indexlibraryglobal{SCNdLEASTN}% \indexlibraryglobal{SCNiLEASTN}% \indexlibraryglobal{SCNoLEASTN}% \indexlibraryglobal{SCNuLEASTN}% \indexlibraryglobal{SCNxLEASTN}% +\indexlibraryglobal{SCNbLEASTN}% \indexlibraryglobal{PRIdFASTN}% \indexlibraryglobal{PRIiFASTN}% \indexlibraryglobal{PRIoFASTN}% \indexlibraryglobal{PRIuFASTN}% \indexlibraryglobal{PRIxFASTN}% \indexlibraryglobal{PRIXFASTN}% +\indexlibraryglobal{PRIbFASTN}% +\indexlibraryglobal{PRIBFASTN}% \indexlibraryglobal{SCNdFASTN}% \indexlibraryglobal{SCNiFASTN}% \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}% +\indexlibraryglobal{SCNbFASTN}% \begin{codeblock} #include // see \ref{cstdint.syn} @@ -19054,61 +19045,78 @@ constexpr imaxdiv_t div(intmax_t, intmax_t); // optional, see below } +#define @\libmacro{__STDC_VERSION_INTTYPES_H__}@ 202311L + #define PRId@\placeholdernc{N}@ @\seebelow@ #define PRIi@\placeholdernc{N}@ @\seebelow@ #define PRIo@\placeholdernc{N}@ @\seebelow@ #define PRIu@\placeholdernc{N}@ @\seebelow@ #define PRIx@\placeholdernc{N}@ @\seebelow@ #define PRIX@\placeholdernc{N}@ @\seebelow@ +#define PRIb@\placeholdernc{N}@ @\seebelow@ +#define PRIB@\placeholdernc{N}@ @\seebelow@ #define SCNd@\placeholdernc{N}@ @\seebelow@ #define SCNi@\placeholdernc{N}@ @\seebelow@ #define SCNo@\placeholdernc{N}@ @\seebelow@ #define SCNu@\placeholdernc{N}@ @\seebelow@ #define SCNx@\placeholdernc{N}@ @\seebelow@ +#define SCNb@\placeholdernc{N}@ @\seebelow@ #define PRIdLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIiLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIoLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIuLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIxLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIXLEAST@\placeholdernc{N}@ @\seebelow@ +#define PRIbLEAST@\placeholdernc{N}@ @\seebelow@ +#define PRIBLEAST@\placeholdernc{N}@ @\seebelow@ #define SCNdLEAST@\placeholdernc{N}@ @\seebelow@ #define SCNiLEAST@\placeholdernc{N}@ @\seebelow@ #define SCNoLEAST@\placeholdernc{N}@ @\seebelow@ #define SCNuLEAST@\placeholdernc{N}@ @\seebelow@ #define SCNxLEAST@\placeholdernc{N}@ @\seebelow@ +#define SCNbLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIdFAST@\placeholdernc{N}@ @\seebelow@ #define PRIiFAST@\placeholdernc{N}@ @\seebelow@ #define PRIoFAST@\placeholdernc{N}@ @\seebelow@ #define PRIuFAST@\placeholdernc{N}@ @\seebelow@ #define PRIxFAST@\placeholdernc{N}@ @\seebelow@ #define PRIXFAST@\placeholdernc{N}@ @\seebelow@ +#define PRIbFAST@\placeholdernc{N}@ @\seebelow@ +#define PRIBFAST@\placeholdernc{N}@ @\seebelow@ #define SCNdFAST@\placeholdernc{N}@ @\seebelow@ #define SCNiFAST@\placeholdernc{N}@ @\seebelow@ #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 SCNbFAST@\placeholdernc{N}@ @\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{PRIbMAX}@ @\seebelow@ +#define @\libmacro{PRIBMAX}@ @\seebelow@ +#define @\libmacro{SCNdMAX}@ @\seebelow@ +#define @\libmacro{SCNiMAX}@ @\seebelow@ +#define @\libmacro{SCNoMAX}@ @\seebelow@ +#define @\libmacro{SCNuMAX}@ @\seebelow@ +#define @\libmacro{SCNxMAX}@ @\seebelow@ +#define @\libmacro{SCNbMAX}@ @\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{PRIbPTR}@ @\seebelow@ +#define @\libmacro{PRIBPTR}@ @\seebelow@ +#define @\libmacro{SCNdPTR}@ @\seebelow@ +#define @\libmacro{SCNiPTR}@ @\seebelow@ +#define @\libmacro{SCNoPTR}@ @\seebelow@ +#define @\libmacro{SCNuPTR}@ @\seebelow@ +#define @\libmacro{SCNxPTR}@ @\seebelow@ +#define @\libmacro{SCNbPTR}@ @\seebelow@ \end{codeblock} \pnum @@ -19120,10 +19128,6 @@ The header \libheader{cinttypes} includes the header \libheaderref{cstdint} instead of \libheader{stdint.h}, and \item -\tcode{intmax_t} and \tcode{uintmax_t} are not required -to be able to represent all values of extended integer types -wider than \tcode{long long} and \tcode{unsigned long long}, respectively, and -\item if and only if the type \tcode{intmax_t} designates an extended integer type\iref{basic.fundamental}, the following function signatures are added: \begin{codeblock} @@ -19145,3 +19149,6 @@ is defined if and only if the implementation defines the corresponding \grammarterm{typedef-name} in~\ref{cstdint.syn} and has a suitable \tcode{fscanf} length modifier for the type. +Each of the \tcode{PRIB} macros listed in this subclause +is defined if and only if \tcode{fprintf} supports +the \tcode{B} conversion specifier. diff --git a/source/iterators.tex b/source/iterators.tex index 7fcbff2083..8c8469c0fa 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -33,6 +33,7 @@ \begin{codeblock} #include // see \ref{compare.syn} #include // see \ref{concepts.syn} +#include // see \ref{initializer.list.syn} namespace std { template using @\exposid{with-reference}@ = T&; // \expos @@ -169,11 +170,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 @@ -208,7 +205,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} @@ -325,7 +322,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; @@ -415,7 +412,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; @@ -456,7 +453,7 @@ const istream_iterator& y); template> - class ostream_iterator; + class ostream_iterator; template> class istreambuf_iterator; @@ -468,53 +465,64 @@ class ostreambuf_iterator; // \ref{iterator.range}, range access - template constexpr auto begin(C& c) -> decltype(c.begin()); // freestanding - template constexpr auto begin(const C& c) -> decltype(c.begin()); // freestanding - template constexpr auto end(C& c) -> decltype(c.end()); // freestanding - template constexpr auto end(const C& c) -> decltype(c.end()); // freestanding + template constexpr auto + begin(C& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()); // freestanding + template constexpr auto + begin(const C& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()); // freestanding + template constexpr auto + end(C& c) noexcept(noexcept(c.end())) -> decltype(c.end()); // freestanding + template constexpr auto + end(const C& c) noexcept(noexcept(c.end())) -> decltype(c.end()); // freestanding template constexpr T* begin(T (&array)[N]) noexcept; // freestanding template constexpr T* end(T (&array)[N]) noexcept; // freestanding - template constexpr auto cbegin(const C& c) // freestanding - noexcept(noexcept(std::begin(c))) -> decltype(std::begin(c)); - template constexpr auto cend(const C& c) // freestanding - noexcept(noexcept(std::end(c))) -> decltype(std::end(c)); - template constexpr auto rbegin(C& c) -> decltype(c.rbegin()); // freestanding - template constexpr auto rbegin(const C& c) -> decltype(c.rbegin()); // freestanding - template constexpr auto rend(C& c) -> decltype(c.rend()); // freestanding - template constexpr auto rend(const C& c) -> decltype(c.rend()); // freestanding - template constexpr reverse_iterator rbegin(T (&array)[N]) // freestanding - template constexpr reverse_iterator rend(T (&array)[N]); // freestanding + template constexpr auto + cbegin(const C& c) noexcept(noexcept(std::begin(c))) + -> decltype(std::begin(c)); // freestanding + template constexpr auto + cend(const C& c) noexcept(noexcept(std::end(c))) -> decltype(std::end(c)); // freestanding + template constexpr auto + rbegin(C& c) noexcept(noexcept(c.rbegin())) -> decltype(c.rbegin()); // freestanding + template constexpr auto + rbegin(const C& c) noexcept(noexcept(c.rbegin())) -> decltype(c.rbegin()); // freestanding + template constexpr auto + rend(C& c) noexcept(noexcept(c.rend())) -> decltype(c.rend()); // freestanding + template constexpr auto + rend(const C& c) noexcept(noexcept(c.rend())) -> decltype(c.rend()); // freestanding + template constexpr reverse_iterator + rbegin(T (&array)[N]) noexcept; // freestanding + template constexpr reverse_iterator + rend(T (&array)[N]) noexcept; // freestanding template constexpr reverse_iterator - rbegin(initializer_list il); // freestanding + rbegin(initializer_list il) noexcept; // freestanding template constexpr reverse_iterator - rend(initializer_list il); // freestanding + rend(initializer_list il) noexcept; // freestanding template constexpr auto - crbegin(const C& c) -> decltype(std::rbegin(c)); // freestanding + crbegin(const C& c) noexcept(noexcept(std::rbegin(c))) + -> decltype(std::rbegin(c)); // freestanding template constexpr auto - crend(const C& c) -> decltype(std::rend(c)); // freestanding + crend(const C& c) noexcept(noexcept(std::rend(c))) -> decltype(std::rend(c)); // freestanding template constexpr auto - size(const C& c) -> decltype(c.size()); // freestanding + size(const C& c) noexcept(noexcept(c.size())) -> decltype(c.size()); // freestanding template constexpr size_t size(const T (&array)[N]) noexcept; // freestanding template constexpr auto - ssize(const C& c) + ssize(const C& c) noexcept(noexcept(c.size())) -> common_type_t>; // freestanding template constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // freestanding template constexpr auto - empty(const C& c) -> decltype(c.empty()); // freestanding + empty(const C& c) noexcept(noexcept(c.empty())) -> decltype(c.empty()); // freestanding template constexpr bool empty(const T (&array)[N]) noexcept; // freestanding - template constexpr bool - empty(initializer_list il) noexcept; // freestanding - template constexpr auto data(C& c) -> decltype(c.data()); // freestanding - template constexpr auto data(const C& c) -> decltype(c.data()); // freestanding + template constexpr auto + data(C& c) noexcept(noexcept(c.data())) -> decltype(c.data()); // freestanding + template constexpr auto + data(const C& c) noexcept(noexcept(c.data())) -> decltype(c.data()); // freestanding template constexpr T* data(T (&array)[N]) noexcept; // freestanding - template constexpr const E* data(initializer_list il) noexcept; // freestanding } \end{codeblock} @@ -693,6 +701,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). @@ -757,7 +783,7 @@ template requires requires { typename T::difference_type; } struct incrementable_traits { - using difference_type = typename T::difference_type; + using difference_type = T::difference_type; }; template @@ -876,7 +902,7 @@ \pnum \begin{note} -Some legacy output iterators define a nested type named \tcode{value_type} +Some legacy output iterators declare a nested type named \tcode{value_type} that is an alias for \keyword{void}. These types are not \libconcept{indirectly_readable} and have no associated value types. @@ -903,7 +929,7 @@ \begin{codeblock} iterator_traits::iterator_category \end{codeblock} -be defined as the iterator's iterator category. +be declared as the iterator's iterator category. In addition, the types \indexlibrarymember{pointer}{iterator_traits}% \indexlibrarymember{reference}{iterator_traits}% @@ -911,7 +937,7 @@ iterator_traits::pointer iterator_traits::reference \end{codeblock} -shall be defined as the iterator's pointer and reference types; +shall be declared as the iterator's pointer and reference types; that is, for an iterator object \tcode{a} of class type, the same type as @@ -924,12 +950,15 @@ for an iterator of class type \tcode{I} that does not support \tcode{operator->}. Additionally, in the case of an output iterator, the types +\indexlibrarymember{value_type}{iterator_traits}% +\indexlibrarymember{difference_type}{iterator_traits}% +\indexlibrarymember{reference}{iterator_traits}% \begin{codeblock} iterator_traits::value_type iterator_traits::difference_type iterator_traits::reference \end{codeblock} -may be defined as \keyword{void}. +may be declared as \keyword{void}. \pnum The definitions in this subclause make use of the following @@ -1002,11 +1031,11 @@ \tcode{iterator_traits} has the following publicly accessible members: \begin{codeblock} -using iterator_category = typename I::iterator_category; -using value_type = typename I::value_type; -using difference_type = typename I::difference_type; -using pointer = @\seebelow@; -using reference = typename I::reference; +using @\libmember{iterator_category}{iterator_traits}@ = I::iterator_category; +using @\libmember{value_type}{iterator_traits}@ = I::value_type; +using @\libmember{difference_type}{iterator_traits}@ = I::difference_type; +using @\libmember{pointer}{iterator_traits}@ = @\seebelow@; +using @\libmember{reference}{iterator_traits}@ = I::reference; \end{codeblock} If the \grammarterm{qualified-id} \tcode{I::pointer} is valid and denotes a type, then \tcode{iterator_traits::pointer} names that type; @@ -1020,8 +1049,8 @@ publicly accessible members: \begin{codeblock} using iterator_category = @\seebelow@; -using value_type = typename indirectly_readable_traits::value_type; -using difference_type = typename incrementable_traits::difference_type; +using value_type = indirectly_readable_traits::value_type; +using difference_type = incrementable_traits::difference_type; using pointer = @\seebelow@; using reference = @\seebelow@; \end{codeblock} @@ -1081,7 +1110,7 @@ \pnum Explicit or partial specializations of \tcode{iterator_traits} may -have a member type \tcode{iterator_concept} that is used to indicate +have a member type \tcode{\libmember{iterator_concept}{iterator_traits}} that is used to indicate conformance to the iterator concepts\iref{iterator.concepts}. \begin{example} To indicate conformance to the \libconcept{input_iterator} concept @@ -1089,7 +1118,7 @@ the \oldconcept{InputIter\-ator} requirements\iref{input.iterators}, an \tcode{iterator_traits} specialization might have \tcode{iterator_concept} denote \tcode{input_iterator_tag} -but not define \tcode{iterator_category}. +but not declare \tcode{iterator_category}. \end{example} \pnum @@ -1117,12 +1146,10 @@ \begin{codeblock} template void reverse(BI first, BI last) { - typename iterator_traits::difference_type n = - distance(first, last); + typename iterator_traits::difference_type n = distance(first, last); --n; - while(n > 0) { - typename iterator_traits::value_type - tmp = *first; + while (n > 0) { + typename iterator_traits::value_type tmp = *first; *first++ = *--last; *last = tmp; n -= 2; @@ -1576,7 +1603,8 @@ and post-increment operators. The increment operations are required to be equality-preserving, and the type is required to be \libconcept{equality_comparable}. \begin{note} -This supersedes the annotations on the increment expressions +This supersedes the ``not required to be equality-preserving'' comments +on the increment expressions in the definition of \libconcept{weakly_incrementable}. \end{note} @@ -1647,6 +1675,7 @@ template concept @\deflibconcept{sentinel_for}@ = @\libconcept{semiregular}@ && + !@\exposid{is-integer-like}@ && @\libconcept{input_or_output_iterator}@ && @\exposconcept{weakly-equality-comparable-with}@; // see \ref{concept.equalitycomparable} \end{itemdecl} @@ -1663,6 +1692,9 @@ \range{++i}{s} denotes a range. \item \tcode{\libconcept{assignable_from}} is either modeled or not satisfied. + +\item If \tcode{I} and \tcode{S} are the same type, then + \tcode{i == i} is \tcode{true}. \end{itemize} \end{itemdescr} @@ -1724,7 +1756,7 @@ for cv-unqualified non-array object types \tcode{S} and \tcode{I} if \tcode{S} and/or \tcode{I} is a program-defined type. Such specializations shall -be usable in constant expressions\iref{expr.const} and +be usable in constant expressions\iref{expr.const.init} and have type \tcode{const bool}. \pnum @@ -2149,8 +2181,6 @@ should never attempt to pass through the same iterator twice; such an algorithm should be a single pass algorithm. -\newpage - \begin{note} For input iterators, \tcode{a == b} does not imply \tcode{++a == ++b}. (Equality does not guarantee the substitution property or referential transparency.) @@ -2501,10 +2531,10 @@ } \end{codeblock} -\rSec3[projected]{Class template \tcode{projected}} +\rSec3[projected]{Alias template \tcode{projected}} \pnum -Class template \tcode{projected} is used to constrain algorithms +Alias template \tcode{projected} is used to constrain algorithms that accept callable objects and projections\iref{defns.projection}. It combines an \libconcept{indirectly_readable} type \tcode{I} and a callable object type \tcode{Proj} into a new \libconcept{indirectly_readable} type @@ -2758,7 +2788,7 @@ For every iterator of type \tcode{I}, \tcode{iterator_traits::it\-er\-a\-tor_ca\-te\-go\-ry} -shall be defined to be a category tag that describes the +shall be declared to be a category tag that describes the iterator's behavior. Additionally, \tcode{iterator_traits::it\-er\-a\-tor_con\-cept} @@ -3054,7 +3084,13 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return last - static_cast\&>(first);} +Equivalent to: +\begin{codeblock} +if constexpr (!is_array_v>) + return last - first; +else + return last - static_cast>(first); +\end{codeblock} \end{itemdescr} \indexlibraryglobal{distance}% @@ -3185,7 +3221,7 @@ using iterator_category = @\seebelow@; using value_type = iter_value_t; using difference_type = iter_difference_t; - using pointer = typename iterator_traits::pointer; + using pointer = iterator_traits::pointer; using reference = iter_reference_t; constexpr reverse_iterator(); @@ -3410,7 +3446,7 @@ \begin{itemdescr} \pnum \returns -\tcode{current[-n-1]}. +\tcode{current[-n - 1]}. \end{itemdescr} \rSec3[reverse.iter.nav]{Navigation} @@ -3423,7 +3459,7 @@ \begin{itemdescr} \pnum \returns -\tcode{reverse_iterator(current-n)}. +\tcode{reverse_iterator(current - n)}. \end{itemdescr} \indexlibrarymember{operator-}{reverse_iterator}% @@ -3434,7 +3470,7 @@ \begin{itemdescr} \pnum \returns -\tcode{reverse_iterator(current+n)}. +\tcode{reverse_iterator(current + n)}. \end{itemdescr} \indexlibrarymember{operator++}{reverse_iterator}% @@ -4229,6 +4265,7 @@ @\exposid{iter-const-rvalue-reference-t}@; public: + using iterator_type = Iterator; using iterator_concept = @\seebelow@; using iterator_category = @\seebelow@; // not always present using value_type = iter_value_t; @@ -4239,7 +4276,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; @@ -4247,15 +4284,15 @@ 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); - constexpr basic_const_iterator operator++(int) requires @\libconcept{forward_iterator}@; + basic_const_iterator operator++(int) requires @\libconcept{forward_iterator}@ = default; constexpr basic_const_iterator& operator--() requires @\libconcept{bidirectional_iterator}@; - constexpr basic_const_iterator operator--(int) requires @\libconcept{bidirectional_iterator}@; + basic_const_iterator operator--(int) = default; constexpr basic_const_iterator& operator+=(difference_type n) requires @\libconcept{random_access_iterator}@; @@ -4302,17 +4339,17 @@ constexpr auto operator<=>(const I& y) const requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@ && @\libconcept{three_way_comparable_with}@; - template<@\exposconcept{not-a-const-iterator}@ I> - friend constexpr bool operator<(const I& x, const basic_const_iterator& y) + template<@\exposconcept{not-a-const-iterator}@ I, @\libconcept{same_as}@ J> + friend constexpr bool operator<(const I& x, const basic_const_iterator& y) requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; - template<@\exposconcept{not-a-const-iterator}@ I> - friend constexpr bool operator>(const I& x, const basic_const_iterator& y) + template<@\exposconcept{not-a-const-iterator}@ I, @\libconcept{same_as}@ J> + friend constexpr bool operator>(const I& x, const basic_const_iterator& y) requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; - template<@\exposconcept{not-a-const-iterator}@ I> - friend constexpr bool operator<=(const I& x, const basic_const_iterator& y) + template<@\exposconcept{not-a-const-iterator}@ I, @\libconcept{same_as}@ J> + friend constexpr bool operator<=(const I& x, const basic_const_iterator& y) requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; - template<@\exposconcept{not-a-const-iterator}@ I> - friend constexpr bool operator>=(const I& x, const basic_const_iterator& y) + template<@\exposconcept{not-a-const-iterator}@ I, @\libconcept{same_as}@ J> + friend constexpr bool operator>=(const I& x, const basic_const_iterator& y) requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; friend constexpr basic_const_iterator operator+(const basic_const_iterator& i, @@ -4366,7 +4403,7 @@ \end{itemize} \pnum -The member \grammarterm{typedef-name} \tcode{iterator_category} is defined +The member \grammarterm{typedef-name} \tcode{iterator_category} is declared if and only if \tcode{Iterator} models \libconcept{forward_iterator}. In that case, \tcode{basic_const_iterator::iterator_category} denotes @@ -4485,22 +4522,6 @@ Equivalent to: \tcode{++\exposid{current_};} \end{itemdescr} -\indexlibrarymember{operator++}{basic_const_iterator}% -\begin{itemdecl} -constexpr basic_const_iterator operator++(int) requires @\libconcept{forward_iterator}@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -auto tmp = *this; -++*this; -return tmp; -\end{codeblock} -\end{itemdescr} - \indexlibrarymember{operator--}{basic_const_iterator}% \begin{itemdecl} constexpr basic_const_iterator& operator--() requires @\libconcept{bidirectional_iterator}@; @@ -4516,22 +4537,6 @@ \end{codeblock} \end{itemdescr} -\indexlibrarymember{operator--}{basic_const_iterator}% -\begin{itemdecl} -constexpr basic_const_iterator operator--(int) requires @\libconcept{bidirectional_iterator}@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -auto tmp = *this; ---*this; -return tmp; -\end{codeblock} -\end{itemdescr} - \indexlibrarymember{operator+=}{basic_const_iterator}% \indexlibrarymember{operator-=}{basic_const_iterator}% \begin{itemdecl} @@ -4667,17 +4672,17 @@ \indexlibrarymember{operator<=}{basic_const_iterator}% \indexlibrarymember{operator>=}{basic_const_iterator}% \begin{itemdecl} -template<@\exposconcept{not-a-const-iterator}@ I> - friend constexpr bool operator<(const I& x, const basic_const_iterator& y) +template<@\exposconcept{not-a-const-iterator}@ I, @\libconcept{same_as}@ J> + friend constexpr bool operator<(const I& x, const basic_const_iterator& y) requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; -template<@\exposconcept{not-a-const-iterator}@ I> - friend constexpr bool operator>(const I& x, const basic_const_iterator& y) +template<@\exposconcept{not-a-const-iterator}@ I, @\libconcept{same_as}@ J> + friend constexpr bool operator>(const I& x, const basic_const_iterator& y) requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; -template<@\exposconcept{not-a-const-iterator}@ I> - friend constexpr bool operator<=(const I& x, const basic_const_iterator& y) +template<@\exposconcept{not-a-const-iterator}@ I, @\libconcept{same_as}@ J> + friend constexpr bool operator<=(const I& x, const basic_const_iterator& y) requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; -template<@\exposconcept{not-a-const-iterator}@ I> - friend constexpr bool operator>=(const I& x, const basic_const_iterator& y) +template<@\exposconcept{not-a-const-iterator}@ I, @\libconcept{same_as}@ J> + friend constexpr bool operator>=(const I& x, const basic_const_iterator& y) requires @\libconcept{random_access_iterator}@ && @\libconcept{totally_ordered_with}@; \end{itemdecl} @@ -4781,7 +4786,7 @@ using pointer = Iterator; using reference = iter_rvalue_reference_t; - constexpr move_iterator(); + constexpr move_iterator() requires @\libconcept{default_initializable}@ = default; constexpr explicit move_iterator(Iterator i); template constexpr move_iterator(const move_iterator& u); template constexpr move_iterator& operator=(const move_iterator& u); @@ -4791,9 +4796,10 @@ constexpr reference operator*() const; constexpr move_iterator& operator++(); - constexpr auto operator++(int); + constexpr void operator++(int); + move_iterator operator++(int) requires @\libconcept{forward_iterator}@ = default; constexpr move_iterator& operator--(); - constexpr move_iterator operator--(int); + move_iterator operator--(int) = default; constexpr move_iterator operator+(difference_type n) const; constexpr move_iterator& operator+=(difference_type n); @@ -4819,7 +4825,7 @@ noexcept(noexcept(ranges::iter_swap(x.current, y.current))); private: - Iterator current; // \expos + Iterator current = Iterator(); // \expos }; } \end{codeblock} @@ -4842,7 +4848,7 @@ \end{itemize} \pnum -The member \grammarterm{typedef-name} \tcode{iterator_category} is defined +The member \grammarterm{typedef-name} \tcode{iterator_category} is declared if and only if the \grammarterm{qualified-id} \tcode{iterator_traits::iterator_category} is valid and denotes a type. @@ -4875,18 +4881,6 @@ \rSec3[move.iter.cons]{Construction and assignment} -\indexlibraryctor{move_iterator}% -\begin{itemdecl} -constexpr move_iterator(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Value-initializes \tcode{current}. -\end{itemdescr} - - \indexlibraryctor{move_iterator}% \begin{itemdecl} constexpr explicit move_iterator(Iterator i); @@ -5004,19 +4998,13 @@ \indexlibrarymember{operator++}{move_iterator}% \begin{itemdecl} -constexpr auto operator++(int); +constexpr void operator++(int); \end{itemdecl} \begin{itemdescr} \pnum \effects -If \tcode{Iterator} models \libconcept{forward_iterator}, equivalent to: -\begin{codeblock} -move_iterator tmp = *this; -++current; -return tmp; -\end{codeblock} -Otherwise, equivalent to \tcode{++current}. +Equivalent to \tcode{++current}. \end{itemdescr} \indexlibrarymember{operator--}{move_iterator}% @@ -5034,22 +5022,6 @@ \tcode{*this}. \end{itemdescr} -\indexlibrarymember{operator--}{move_iterator}% -\begin{itemdecl} -constexpr move_iterator operator--(int); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -As if by: -\begin{codeblock} -move_iterator tmp = *this; ---current; -return tmp; -\end{codeblock} -\end{itemdescr} - \indexlibrarymember{operator+}{move_iterator}% \begin{itemdecl} constexpr move_iterator operator+(difference_type n) const; @@ -5276,7 +5248,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} @@ -5454,6 +5426,7 @@ constexpr common_iterator& operator++(); constexpr decltype(auto) operator++(int); + common_iterator operator++(int) requires @\libconcept{forward_iterator}@ = default; template S2> requires @\libconcept{sentinel_for}@ @@ -5502,7 +5475,7 @@ \pnum The nested \grammarterm{typedef-name} \tcode{iterator_category} of the specialization of \tcode{iterator_traits} for \tcode{common_iterator} -is defined if and only if \tcode{iter_difference_t} is an integral type. +is declared if and only if \tcode{iter_difference_t} is an integral type. In that case, \tcode{iterator_category} denotes \tcode{forward_iterator_tag} if the \grammarterm{qualified-id} \tcode{iterator_traits::iterator_category} @@ -5560,7 +5533,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{x.v_.valueless_by_exception()} is \tcode{false}. \pnum @@ -5580,7 +5553,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{x.v_.valueless_by_exception()} is \tcode{false}. \pnum @@ -5610,7 +5583,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{holds_alternative(v_)} is \tcode{true}. \pnum @@ -5635,7 +5608,7 @@ \end{codeblock} \pnum -\expects +\hardexpects \tcode{holds_alternative(v_)} is \tcode{true}. \pnum @@ -5680,7 +5653,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{holds_alternative(v_)} is \tcode{true}. \pnum @@ -5699,19 +5672,12 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{holds_alternative(v_)} is \tcode{true}. \pnum \effects -If \tcode{I} models \libconcept{forward_iterator}, equivalent to: -\begin{codeblock} -common_iterator tmp = *this; -++*this; -return tmp; -\end{codeblock} -Otherwise, if -\tcode{requires(I\& i) \{ \{ *i++ \} -> \exposconceptnc{can-reference}; \}} +If \tcode{requires(I\& i) \{ \{ *i++ \} -> \exposconceptnc{can-reference}; \}} is \tcode{true} or \begin{codeblock} @\libconcept{indirectly_readable}@ && @\libconcept{constructible_from}@, iter_reference_t> && @@ -5754,7 +5720,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{x.v_.valueless_by_exception()} and \tcode{y.v_.valueless_by_exception()} are each \tcode{false}. @@ -5775,7 +5741,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{x.v_.valueless_by_exception()} and \tcode{y.v_.valueless_by_exception()} are each \tcode{false}. @@ -5796,7 +5762,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{x.v_.valueless_by_exception()} and \tcode{y.v_.valueless_by_exception()} are each \tcode{false}. @@ -5818,7 +5784,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{holds_alternative(i.v_)} is \tcode{true}. \pnum @@ -5835,7 +5801,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{holds_alternative(x.v_)} and \tcode{holds_alternative(y.v_)} are each \tcode{true}. @@ -5904,9 +5870,9 @@ using value_type = iter_value_t; // present only // if \tcode{I} models \libconcept{indirectly_readable} using difference_type = iter_difference_t; - using iterator_concept = typename I::iterator_concept; // present only + using iterator_concept = I::iterator_concept; // present only // if the \grammarterm{qualified-id} \tcode{I::iterator_concept} is valid and denotes a type - using iterator_category = typename I::iterator_category; // present only + using iterator_category = I::iterator_category; // present only // if the \grammarterm{qualified-id} \tcode{I::iterator_category} is valid and denotes a type constexpr counted_iterator() requires @\libconcept{default_initializable}@ = default; constexpr counted_iterator(I x, iter_difference_t n); @@ -5930,12 +5896,11 @@ constexpr counted_iterator& operator++(); constexpr decltype(auto) operator++(int); - constexpr counted_iterator operator++(int) - requires @\libconcept{forward_iterator}@; + counted_iterator operator++(int) + requires @\libconcept{forward_iterator}@ = default; constexpr counted_iterator& operator--() requires @\libconcept{bidirectional_iterator}@; - constexpr counted_iterator operator--(int) - requires @\libconcept{bidirectional_iterator}@; + counted_iterator operator--(int) = default; constexpr counted_iterator operator+(iter_difference_t n) const requires @\libconcept{random_access_iterator}@; @@ -5951,9 +5916,9 @@ friend constexpr iter_difference_t operator-( const counted_iterator& x, const counted_iterator& y); friend constexpr iter_difference_t operator-( - const counted_iterator& x, default_sentinel_t); + const counted_iterator& x, default_sentinel_t) noexcept; friend constexpr iter_difference_t operator-( - default_sentinel_t, const counted_iterator& y); + default_sentinel_t, const counted_iterator& y) noexcept; constexpr counted_iterator& operator-=(iter_difference_t n) requires @\libconcept{random_access_iterator}@; @@ -5964,7 +5929,7 @@ friend constexpr bool operator==( const counted_iterator& x, const counted_iterator& y); friend constexpr bool operator==( - const counted_iterator& x, default_sentinel_t); + const counted_iterator& x, default_sentinel_t) noexcept; template<@\libconcept{common_with}@ I2> friend constexpr strong_ordering operator<=>( @@ -6000,8 +5965,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{n >= 0}. +\hardexpects +\tcode{n >= 0} is \tcode{true}. \pnum \effects @@ -6087,7 +6052,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{length > 0} is \tcode{true}. \pnum @@ -6115,8 +6080,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{n < length}. +\hardexpects +\tcode{n < length} is \tcode{true}. \pnum \effects @@ -6132,8 +6097,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{length > 0}. +\hardexpects +\tcode{length > 0} is \tcode{true}. \pnum \effects @@ -6152,8 +6117,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{length > 0}. +\hardexpects +\tcode{length > 0} is \tcode{true}. \pnum \effects @@ -6165,23 +6130,6 @@ \end{codeblock} \end{itemdescr} -\indexlibrarymember{operator++}{counted_iterator}% -\begin{itemdecl} -constexpr counted_iterator operator++(int) - requires @\libconcept{forward_iterator}@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -counted_iterator tmp = *this; -++*this; -return tmp; -\end{codeblock} -\end{itemdescr} - \indexlibrarymember{operator--}{counted_iterator}% \begin{itemdecl} constexpr counted_iterator& operator--() @@ -6199,23 +6147,6 @@ \end{codeblock} \end{itemdescr} -\indexlibrarymember{operator--}{counted_iterator}% -\begin{itemdecl} -constexpr counted_iterator operator--(int) - requires @\libconcept{bidirectional_iterator}@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -counted_iterator tmp = *this; ---*this; -return tmp; -\end{codeblock} -\end{itemdescr} - \indexlibrarymember{operator+}{counted_iterator}% \begin{itemdecl} constexpr counted_iterator operator+(iter_difference_t n) const @@ -6249,8 +6180,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{n <= length}. +\hardexpects +\tcode{n <= length} is \tcode{true}. \pnum \effects @@ -6295,7 +6226,7 @@ \indexlibrarymember{operator-}{counted_iterator}% \begin{itemdecl} friend constexpr iter_difference_t operator-( - const counted_iterator& x, default_sentinel_t); + const counted_iterator& x, default_sentinel_t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -6308,7 +6239,7 @@ \indexlibrarymember{operator-}{counted_iterator}% \begin{itemdecl} friend constexpr iter_difference_t operator-( - default_sentinel_t, const counted_iterator& y); + default_sentinel_t, const counted_iterator& y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -6325,8 +6256,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{-n <= length}. +\hardexpects +\tcode{-n <= length} is \tcode{true}. \pnum \effects @@ -6361,7 +6292,7 @@ \indexlibrarymember{operator==}{counted_iterator}% \begin{itemdecl} friend constexpr bool operator==( - const counted_iterator& x, default_sentinel_t); + const counted_iterator& x, default_sentinel_t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -6406,7 +6337,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{i.length > 0} is \tcode{true}. \pnum @@ -6424,7 +6355,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects Both \tcode{x.length > 0} and \tcode{y.length > 0} are \tcode{true}. \pnum @@ -6523,7 +6454,7 @@ const T& operator*() const; const T* operator->() const; istream_iterator& operator++(); - istream_iterator operator++(int); + istream_iterator operator++(int) = default; friend bool operator==(const istream_iterator& i, default_sentinel_t); @@ -6558,7 +6489,7 @@ \pnum \remarks If the initializer \tcode{T()} in the declaration \tcode{auto x = T();} -is a constant initializer\iref{expr.const}, +is a constant initializer\iref{expr.const.init}, then these constructors are \keyword{constexpr} constructors. \end{itemdescr} @@ -6664,26 +6595,6 @@ \tcode{*this}. \end{itemdescr} -\indexlibrarymember{operator++}{istream_iterator}% -\begin{itemdecl} -istream_iterator operator++(int); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{in_stream != nullptr} is \tcode{true}. - -\pnum -\effects -Equivalent to: -\begin{codeblock} -istream_iterator tmp = *this; -++*this; -return tmp; -\end{codeblock} -\end{itemdescr} - \indexlibrarymember{operator==}{istream_iterator}% \begin{itemdecl} template @@ -6876,12 +6787,12 @@ public: using iterator_category = input_iterator_tag; using value_type = charT; - using difference_type = typename traits::off_type; + using difference_type = traits::off_type; using pointer = @\unspec@; using reference = charT; using char_type = charT; using traits_type = traits; - using int_type = typename traits::int_type; + using int_type = traits::int_type; using streambuf_type = basic_streambuf; using istream_type = basic_istream; @@ -7224,27 +7135,36 @@ In addition to being available via inclusion of the \libheader{iterator} header, the function templates in \ref{iterator.range} are available when any of the following headers are included: -\libheaderref{array}, -\libheaderref{deque}, -\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}, -\libheaderrefx{set}{associative.set.syn}, -\libheaderref{span}, -\libheaderref{string}, -\libheaderrefx{string_view}{string.view.synop}, -\libheaderrefx{unordered_map}{unord.map.syn}, -\libheaderrefx{unordered_set}{unord.set.syn}, and -\libheaderref{vector}. +\begin{itemize} +\item \libheaderref{array} +\item \libheaderref{deque} +\item \libheaderrefx{flat_map}{flat.map.syn} +\item \libheaderrefx{flat_set}{flat.set.syn} +\item \libheaderrefx{forward_list}{forward.list.syn} +\item \libheaderref{hive} +\item \libheaderrefx{inplace_vector}{inplace.vector.syn} +\item \libheaderref{list} +\item \libheaderrefx{map}{associative.map.syn} +\item \libheaderref{optional} +\item \libheaderrefx{regex}{re.syn} +\item \libheaderrefx{set}{associative.set.syn} +\item \libheaderref{simd} +\item \libheaderref{span} +\item \libheaderref{stacktrace} +\item \libheaderref{string} +\item \libheaderrefx{string_view}{string.view.synop} +\item \libheaderrefx{unordered_map}{unord.map.syn} +\item \libheaderrefx{unordered_set}{unord.set.syn} +\item \libheaderref{valarray} +\item \libheaderref{vector} +\end{itemize} \indexlibrary{\idxcode{begin(C\&)}}% \begin{itemdecl} -template constexpr auto begin(C& c) -> decltype(c.begin()); -template constexpr auto begin(const C& c) -> decltype(c.begin()); +template constexpr auto begin(C& c) noexcept(noexcept(c.begin())) + -> decltype(c.begin()); +template constexpr auto begin(const C& c) noexcept(noexcept(c.begin())) + -> decltype(c.begin()); \end{itemdecl} \begin{itemdescr} @@ -7255,8 +7175,8 @@ \indexlibrary{\idxcode{end(C\&)}}% \begin{itemdecl} -template constexpr auto end(C& c) -> decltype(c.end()); -template constexpr auto end(const C& c) -> decltype(c.end()); +template constexpr auto end(C& c) noexcept(noexcept(c.end())) -> decltype(c.end()); +template constexpr auto end(const C& c) noexcept(noexcept(c.end())) -> decltype(c.end()); \end{itemdecl} \begin{itemdescr} @@ -7311,8 +7231,10 @@ \indexlibrary{\idxcode{rbegin(C\&)}}% \begin{itemdecl} -template constexpr auto rbegin(C& c) -> decltype(c.rbegin()); -template constexpr auto rbegin(const C& c) -> decltype(c.rbegin()); +template constexpr auto rbegin(C& c) noexcept(noexcept(c.rbegin())) + -> decltype(c.rbegin()); +template constexpr auto rbegin(const C& c) noexcept(noexcept(c.rbegin())) + -> decltype(c.rbegin()); \end{itemdecl} \begin{itemdescr} \pnum @@ -7322,8 +7244,9 @@ \indexlibrary{\idxcode{rend(C\&)}}% \begin{itemdecl} -template constexpr auto rend(C& c) -> decltype(c.rend()); -template constexpr auto rend(const C& c) -> decltype(c.rend()); +template constexpr auto rend(C& c) noexcept(noexcept(c.rend())) -> decltype(c.rend()); +template constexpr auto rend(const C& c) noexcept(noexcept(c.rend())) + -> decltype(c.rend()); \end{itemdecl} \begin{itemdescr} \pnum @@ -7333,7 +7256,7 @@ \indexlibrary{\idxcode{rbegin(T (\&array)[N])}}% \begin{itemdecl} -template constexpr reverse_iterator rbegin(T (&array)[N]); +template constexpr reverse_iterator rbegin(T (&array)[N]) noexcept; \end{itemdecl} \begin{itemdescr} \pnum @@ -7343,7 +7266,7 @@ \indexlibrary{\idxcode{rend(T (\&array)[N])}}% \begin{itemdecl} -template constexpr reverse_iterator rend(T (&array)[N]); +template constexpr reverse_iterator rend(T (&array)[N]) noexcept; \end{itemdecl} \begin{itemdescr} \pnum @@ -7353,7 +7276,7 @@ \indexlibrary{\idxcode{rbegin(initializer_list)}}% \begin{itemdecl} -template constexpr reverse_iterator rbegin(initializer_list il); +template constexpr reverse_iterator rbegin(initializer_list il) noexcept; \end{itemdecl} \begin{itemdescr} \pnum @@ -7363,7 +7286,7 @@ \indexlibrary{\idxcode{rend(initializer_list)}}% \begin{itemdecl} -template constexpr reverse_iterator rend(initializer_list il); +template constexpr reverse_iterator rend(initializer_list il) noexcept; \end{itemdecl} \begin{itemdescr} \pnum @@ -7373,7 +7296,8 @@ \indexlibrary{\idxcode{crbegin(const C\& c)}}% \begin{itemdecl} -template constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c)); +template constexpr auto crbegin(const C& c) noexcept(noexcept(std::rbegin(c))) + -> decltype(std::rbegin(c)); \end{itemdecl} \begin{itemdescr} \pnum @@ -7383,7 +7307,8 @@ \indexlibrary{\idxcode{crend(const C\& c)}}% \begin{itemdecl} -template constexpr auto crend(const C& c) -> decltype(std::rend(c)); +template constexpr auto crend(const C& c) noexcept(noexcept(c.crend())) + -> decltype(std::rend(c)); \end{itemdecl} \begin{itemdescr} \pnum @@ -7393,7 +7318,8 @@ \indexlibrary{\idxcode{size(C\& c)}}% \begin{itemdecl} -template constexpr auto size(const C& c) -> decltype(c.size()); +template constexpr auto size(const C& c) noexcept(noexcept(c.size())) + -> decltype(c.size()); \end{itemdecl} \begin{itemdescr} \pnum @@ -7413,7 +7339,7 @@ \indexlibrary{\idxcode{ssize(C\& c)}}% \begin{itemdecl} -template constexpr auto ssize(const C& c) +template constexpr auto ssize(const C& c) noexcept(noexcept(c.size())) -> common_type_t>; \end{itemdecl} \begin{itemdescr} @@ -7437,7 +7363,8 @@ \indexlibrary{\idxcode{empty(C\& c)}}% \begin{itemdecl} -template constexpr auto empty(const C& c) -> decltype(c.empty()); +template constexpr auto empty(const C& c) noexcept(noexcept(c.empty())) + -> decltype(c.empty()); \end{itemdecl} \begin{itemdescr} \pnum @@ -7455,20 +7382,11 @@ \tcode{false}. \end{itemdescr} -\indexlibrary{\idxcode{empty(initializer_list)}}% -\begin{itemdecl} -template constexpr bool empty(initializer_list il) noexcept; -\end{itemdecl} -\begin{itemdescr} -\pnum -\returns -\tcode{il.size() == 0}. -\end{itemdescr} - \indexlibrary{\idxcode{data(C\& c)}}% \begin{itemdecl} -template constexpr auto data(C& c) -> decltype(c.data()); -template constexpr auto data(const C& c) -> decltype(c.data()); +template constexpr auto data(C& c) noexcept(noexcept(c.data())) -> decltype(c.data()); +template constexpr auto data(const C& c) noexcept(noexcept(c.data())) + -> decltype(c.data()); \end{itemdecl} \begin{itemdescr} \pnum @@ -7485,13 +7403,3 @@ \returns \tcode{array}. \end{itemdescr} - -\indexlibrary{\idxcode{data(initializer_list)}}% -\begin{itemdecl} -template constexpr const E* data(initializer_list il) noexcept; -\end{itemdecl} -\begin{itemdescr} -\pnum -\returns -\tcode{il.begin()}. -\end{itemdescr} diff --git a/source/layout.tex b/source/layout.tex index 1f82bd20d9..98564d8bd0 100644 --- a/source/layout.tex +++ b/source/layout.tex @@ -10,7 +10,7 @@ %%-------------------------------------------------- %% set header and footer positions and sizes -\setheadfoot{\onelineskip}{4\onelineskip} +\setheadfoot{3\onelineskip}{4\onelineskip} \setheaderspaces{*}{2\onelineskip}{*} %%-------------------------------------------------- diff --git a/source/lex.tex b/source/lex.tex index 8f8df12ed3..f96ec6b62c 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -39,19 +39,15 @@ called a \defnadj{preprocessing}{translation unit}. \begin{note} A \Cpp{} program need not all be translated at the same time. +Translation units can be separately translated and then later linked +to produce an executable program\iref{basic.link}. \end{note} - -\pnum \begin{note} -Previously translated translation units and instantiation -units can be preserved individually or in libraries. The separate -translation units of a program communicate\iref{basic.link} by (for -example) -calls to functions whose identifiers have external or module linkage, -manipulation of objects whose identifiers have external or module linkage, or -manipulation of data files. Translation units can be separately -translated and then later linked to produce an executable -program\iref{basic.link}. +Source files, translation units, and translated translation units +need not necessarily be stored as files, nor need there be any one-to-one +correspondence between these entities and any external representation. +The description is conceptual only, +and does not specify any particular implementation. \end{note} \indextext{compilation!separate|)} @@ -102,7 +98,7 @@ 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, +\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. @@ -110,12 +106,12 @@ \indextext{line splicing}% If the first translation character is \unicode{feff}{byte order mark}, it is deleted. -Each sequence of a backslash character (\textbackslash) +Each sequence comprising a backslash character (\textbackslash) 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 \defnx{logical source lines}{source line!logical}. Only the last -backslash on any physical source line shall be eligible for being part +backslash on any physical source line is eligible for being part of such a splice. \begin{note} Line splicing can form @@ -123,7 +119,7 @@ \end{note} A source file that is not empty and that (after splicing) does not end in a new-line character -shall be processed as if an additional new-line character were appended +is processed as if an additional new-line character were appended to the file. \item The source file is decomposed into preprocessing @@ -140,9 +136,9 @@ would arise from a source file ending with an unclosed \tcode{/*} comment. \end{footnote} -Each comment\iref{lex.comment} is replaced by one space character. New-line characters are +Each comment\iref{lex.comment} is replaced by one \unicode{0020}{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 +than new-line is retained or replaced by one \unicode{0020}{space} character is unspecified. As characters from the source file are consumed to form the next preprocessing token @@ -159,7 +155,7 @@ 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 The source file is analyzed as a \grammarterm{preprocessing-file}\iref{cpp.pre}. @@ -168,21 +164,22 @@ 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. +Whitespace characters separating preprocessing tokens are no longer significant. \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}. +\indextext{concatenation!string}% +Then, adjacent \grammarterm{string-literal} preprocessing tokens are concatenated\iref{lex.string}. \item -Adjacent \grammarterm{string-literal} tokens are concatenated\iref{lex.string}. +Each preprocessing token is converted into a token\iref{lex.token}. \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 +The tokens constitute a \defn{translation unit} and are syntactically and semantically analyzed as a \grammarterm{translation-unit}\iref{basic.link} and translated. @@ -202,48 +199,94 @@ dependency\iref{module.unit,module.import} are required to be available. \begin{note} -Source files, translation -units and translated translation units need not necessarily be stored as -files, nor need there be any one-to-one correspondence between these -entities and any external representation. The description is conceptual -only, and does not specify any particular implementation. +Previously translated translation units can be preserved individually or in libraries. +The separate translation units of a program communicate\iref{basic.link} by (for example) +calls to functions whose names have external or module linkage, +manipulation of variables whose names have external or module linkage, or +manipulation of data files. \end{note} -\item Translated translation units and instantiation units are combined -as follows: -\begin{note} -Some or all of these can be supplied from a -library. -\end{note} -Each translated translation unit is examined to -produce a list of required instantiations. +While the tokens constituting translation units +are being analyzed and translated, +required instantiations are performed. \begin{note} This can include instantiations which have been explicitly requested\iref{temp.explicit}. \end{note} -The definitions of the -required templates are located. It is \impldef{whether source of translation units must -be available to locate template definitions} whether the -source of the translation units containing these definitions is required -to be available. -\begin{note} -An implementation can choose to encode sufficient -information into the translated translation unit so as to ensure the -source is not required here. -\end{note} -All the required instantiations -are performed to produce -\defn{instantiation units}. + +The contexts from which instantiations may be performed +are determined by their respective points of instantiation\iref{temp.point}. + \begin{note} -These are similar -to translated translation units, but contain no references to -uninstantiated templates and no template definitions. +Other requirements in this document can further constrain +the context from which an instantiation can be performed. +For example, a constexpr function template specialization +might have a point of instantiation at the end of a translation unit, +but its use in certain constant expressions could require +that it be instantiated at an earlier point\iref{temp.inst}. \end{note} -The -program is ill-formed if any instantiation fails. -\item All external entity references are resolved. Library +The program is ill-formed if any instantiation fails. + +During the analysis and translation of tokens, +each manifestly constant-evaluated expression is evaluated\iref{expr.const.defns}. +The values of these expressions affect +the types named and reflection values used in the program and +thus the syntactic analysis. +Their evaluation also can produce side effects that affect that analysis. +Constructs appearing at a program point $P$ are analyzed +in a context where each side effect of evaluating an expression $E$ +as a full-expression is complete if and only if +\begin{itemize} +\item +$E$ is the expression corresponding to +a \grammarterm{consteval-block-declaration}\iref{dcl.pre}, and +\item +either that \grammarterm{consteval-block-declaration} or +the template definition from which it is instantiated +is reachable from\iref{module.reach} +\begin{itemize} +\item +$P$, or +\item +the point immediately following +the \grammarterm{class-specifier} of the outermost class +for which $P$ is in a complete-class context\iref{class.mem.general}. +\end{itemize} +\end{itemize} +\begin{example} +\begin{codeblock} +class S { + class Incomplete; + + class Inner { + void fn() { + /* @$p_1$@ */ Incomplete i; // OK + } + } /* @$p_2$@ */ ; + + consteval { + define_aggregate(^^Incomplete, {}); + } +} /* @$p_3$@ */ ; +\end{codeblock} +Constructs at $p_1$ are analyzed in a context +where the side effect of the call to \tcode{define_aggregate} is complete +because +\begin{itemize} +\item +the call appears in a consteval block, and +\item +$p_1$ is in a complete-class context of \tcode{S} and +the consteval block is reachable from $p_3$. +\end{itemize} +\end{example} + +\item +\indextext{linking}% +Translated translation units are combined, and +all external entity references are resolved\iref{basic.link}. 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 @@ -277,6 +320,9 @@ \pnum The \defnadj{basic}{character set} is a subset of the translation character set, consisting of 99 characters as specified in \tref{lex.charset.basic}. +In this document, +glyphs are often used to identify +elements of the basic character set. \begin{note} Unicode short names are given only as a means to identifying the character; the numerical value has no other meaning in this context. @@ -375,7 +421,7 @@ 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. +is 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}% @@ -428,9 +474,8 @@ 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} +the \grammarterm{c-char-sequence} or \grammarterm{s-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. @@ -458,8 +503,7 @@ in the Unicode Standard (chapter 4.8 Name) if the \grammarterm{n-char-sequence} is equal to its character name or -to one of its character name aliases of -type ``control'', ``correction'', or ``alternate''; +to one of its character name aliases; otherwise, the program is ill-formed. \begin{note} These aliases are listed in @@ -477,10 +521,7 @@ 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. +next new-line character. \begin{note} The comment characters \tcode{//}, \tcode{/*}, and \tcode{*/} have no special meaning within a \tcode{//} comment and @@ -511,10 +552,7 @@ \pnum A preprocessing token is the minimal lexical element of the language in translation -phases 3 through 6. -In this document, -glyphs are used to identify -elements of the basic character set\iref{lex.charset}. +phases 3 through 5. The categories of preprocessing token are: header names, placeholder tokens produced by preprocessing \tcode{import} and \tcode{module} directives (\grammarterm{import-keyword}, \grammarterm{module-keyword}, and \grammarterm{export-keyword}), @@ -522,10 +560,11 @@ literals), string literals (including user-defined string literals), preprocessing operators and punctuators, and single non-whitespace characters that do not lexically match the other preprocessing token categories. -If a \unicode{0027}{apostrophe} or a \unicode{0022}{quotation mark} character +If a \unicode{0027}{apostrophe}, a \unicode{0022}{quotation mark}, +or any character not in the basic character set matches the last category, the program is ill-formed. -If any character not in the basic character set matches the last category, -the program is ill-formed. + +\pnum Preprocessing tokens can be separated by \indextext{whitespace}% whitespace; @@ -536,19 +575,25 @@ new-line, \unicode{000b}{line tabulation}, and \unicode{000c}{form feed}), or both. +\begin{note} As described in \ref{cpp}, in certain circumstances during translation phase 4, whitespace (or the absence thereof) serves as more than preprocessing token separation. Whitespace can appear within a preprocessing token only as part of a header name or between the quotation characters in a character literal or string literal. +\end{note} \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, +a header name, or an operator or punctuator. \pnum +\indexgrammar{\idxgram{import-keyword}}% +\indexgrammar{\idxgram{module-keyword}}% +\indexgrammar{\idxgram{export-keyword}}% The \grammarterm{import-keyword} is produced by processing an \keyword{import} directive\iref{cpp.import}, the \grammarterm{module-keyword} is produced @@ -570,7 +615,7 @@ token shall be a raw string literal. Between the initial and final double quote characters of the raw string, any transformations performed in phase 2 (line splicing) are reverted; this reversion -shall apply before any \grammarterm{d-char}, \grammarterm{r-char}, or delimiting +is applied before any \grammarterm{d-char}, \grammarterm{r-char}, or delimiting parenthesis is identified. The raw string literal is defined as the shortest sequence of characters that matches the raw-string pattern \begin{ncbnf} @@ -581,20 +626,45 @@ is neither \tcode{:} nor \tcode{>}, the \tcode{<} is treated as a preprocessing token by itself and not as the first character of the alternative token \tcode{<:}. +\item +Otherwise, if the next three characters are \tcode{[::} and +the subsequent character is not \tcode{:}, or +if the next three characters are \tcode{[:>}, +the \tcode{[} is treated as a preprocessing token by itself and +not as the first character of the preprocessing token \tcode{[:}. +\begin{note} +The tokens \tcode{[:} and \tcode{:]} cannot be composed from digraphs. +\end{note} + \item Otherwise, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token, even if that would cause further lexical analysis to fail, -except that a \grammarterm{header-name}\iref{lex.header} is only formed +except that \begin{itemize} \item -after the \tcode{include} or \tcode{import} preprocessing token in a -\tcode{\#include}\iref{cpp.include} or -\tcode{import}\iref{cpp.import} directive, or - +a \grammarterm{string-literal} token is never formed +when a \grammarterm{header-name} token can be formed, and \item -within a \grammarterm{has-include-expression}. - +a \grammarterm{header-name}\iref{lex.header} is only formed +\begin{itemize} +\item +immediately after the \tcode{include} or \tcode{embed} preprocessing token in a +\tcode{\#include}\iref{cpp.include} or \tcode{\#embed}\iref{cpp.embed} +directive, respectively, or +\item +immediately after an \tcode{import} preprocessing token that +is at the start of a logical source line, or +\item +immediately after a preprocessing token sequence of \xname{has_include} +or \xname{has_embed} immediately followed by \tcode{(} +in a \tcode{\#if}, \tcode{\#elif}, or \tcode{\#embed} directive\iref{cpp.cond,cpp.embed}. +\end{itemize} +A preprocessing token is considered to be +\defnx{immediately after}{token!immediately after} +another preprocessing token if +the preprocessing tokens are on the same logical source line and +there are no intervening preprocessing tokens. \end{itemize} \end{itemize} @@ -632,7 +702,7 @@ \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{"} @@ -732,27 +802,27 @@ \begin{bnf} %% Ed. note: character protrusion would misalign various operators. -\microtypesetup{protrusion=false}\obeyspaces +\microtypesetup{protrusion=false} \nontermdef{preprocessing-operator} \textnormal{one of}\br - \terminal{\# \#\# \%: \%:\%:} + \terminal{\# \ \ \ \ \ \ \ \#\# \ \ \ \ \ \ \%: \ \ \ \ \ \ \%:\%:} \end{bnf} \begin{bnf} -\microtypesetup{protrusion=false}\obeyspaces +\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}} + \terminal{\{ \ \ \ \ \ \ \ \} \ \ \ \ \ \ \ [ \ \ \ \ \ \ \ ] \ \ \ \ \ \ \ ( \ \ \ \ \ \ \ ) \ \ \ \ \ \ \ [: \ \ \ \ \ \ :]}\br + \terminal{<\% \ \ \ \ \ \ \%> \ \ \ \ \ \ <: \ \ \ \ \ \ :> \ \ \ \ \ \ ; \ \ \ \ \ \ \ : \ \ \ \ \ \ \ ...}\br + \terminal{? \ \ \ \ \ \ \ :: \ \ \ \ \ \ . \ \ \ \ \ \ \ .* \ \ \ \ \ \ -> \ \ \ \ \ \ ->* \ \ \ \ \ \caret{}\caret{} \ \ \ \ \ \ \~}\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}.% +in translation phase 6\iref{lex.phases}.% \indextext{punctuator|)}% \indextext{operator|)} @@ -775,11 +845,11 @@ \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} +\begin{note} +The ``stringized'' values\iref{cpp.stringize} of +\tcode{[} and \tcode{<:} are different, +maintaining the source spelling. +\end{note} The set of alternative tokens is defined in \tref{lex.digraph}. @@ -813,27 +883,20 @@ identifier\br keyword\br literal\br + header-name\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} +There are six kinds of tokens: identifiers, keywords, literals, +header names, 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} @@ -845,14 +908,16 @@ \begin{bnf} \nontermdef{identifier-start}\br nondigit\br - \textnormal{an element of the translation character set with the Unicode property XID_Start} + \textnormal% + {an element of the translation character set with the Unicode property XID_Start or the Unicode property ID_Compat_Math_Start} \end{bnf} \begin{bnf} \nontermdef{identifier-continue}\br digit\br nondigit\br - \textnormal{an element of the translation character set with the Unicode property XID_Continue} + \textnormal% + {an element of the translation character set with the Unicode property XID_Continue or the Unicode property ID_Compat_Math_Continue} \end{bnf} \begin{bnf} @@ -915,7 +980,7 @@ token as a regular \grammarterm{identifier}. \begin{multicolfloattable}{Identifiers with special meaning}{lex.name.special} -{llll} +{llllll} \keyword{final} \\ \columnbreak \keyword{import} \\ @@ -923,8 +988,18 @@ \keyword{module} \\ \columnbreak \keyword{override} \\ +\columnbreak +\keyword{post} \\ +\columnbreak +\keyword{pre} \\ \end{multicolfloattable} +\pnum +\begin{note} +Identifiers with special meaning +cannot be used as macro names\iref{cpp.replace.general}. +\end{note} + \pnum \indextext{\idxcode{_}|see{character, underscore}}% \indextext{character!underscore!in identifier}% @@ -933,7 +1008,7 @@ appearing as a \grammarterm{token} or \grammarterm{preprocessing-token} are reserved for use by \Cpp{} implementations and shall -not be used otherwise; no diagnostic is required. +not be used otherwise; no diagnostic is required \ifndrdef{lex.name.reserved}. \begin{itemize} \item Each identifier that contains a double underscore @@ -967,7 +1042,7 @@ \indextext{keyword|(}% The identifiers shown in \tref{lex.key} are reserved for use as keywords (that is, they are unconditionally treated as keywords in -phase 7) except in an \grammarterm{attribute-token}\iref{dcl.attr.grammar}. +phases 6 and 7) except in an \grammarterm{attribute-token}\iref{dcl.attr.grammar}. \begin{note} The \keyword{register} keyword is unused but is reserved for future use. @@ -996,6 +1071,7 @@ \keyword{constinit} \\ \keyword{const_cast} \\ \keyword{continue} \\ +\keyword{contract_assert} \\ \keyword{co_await} \\ \keyword{co_return} \\ \keyword{co_yield} \\ @@ -1009,8 +1085,8 @@ \keyword{enum} \\ \keyword{explicit} \\ \keyword{export} \\ -\keyword{extern} \\ \columnbreak +\keyword{extern} \\ \keyword{false} \\ \keyword{float} \\ \keyword{for} \\ @@ -1027,8 +1103,8 @@ \keyword{nullptr} \\ \keyword{operator} \\ \keyword{private} \\ -\keyword{protected} \\ \columnbreak +\keyword{protected} \\ \keyword{public} \\ \keyword{register} \\ \keyword{reinterpret_cast} \\ @@ -1045,8 +1121,8 @@ \keyword{template} \\ \keyword{this} \\ \keyword{thread_local} \\ -\keyword{throw} \\ \columnbreak +\keyword{throw} \\ \keyword{true} \\ \keyword{try} \\ \keyword{typedef} \\ @@ -1062,6 +1138,11 @@ \keyword{while} \\ \end{multicolfloattable} +\pnum +\begin{note} +Keywords cannot be used as macro names\iref{cpp.replace.general}. +\end{note} + \pnum Furthermore, the alternative representations shown in \tref{lex.key.digraph} for certain operators and @@ -1086,10 +1167,6 @@ \indextext{constant}% \indextext{literal!constant}% There are several kinds of literals. -\begin{footnote} -The term ``literal'' generally designates, in this -document, those tokens that are called ``constants'' in C. -\end{footnote} \begin{bnf} \nontermdef{literal}\br @@ -1679,7 +1756,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} \\ @@ -1727,19 +1804,33 @@ values for its type, the program is ill-formed. Otherwise, the value of a \grammarterm{floating-point-literal} is the scaled value if representable, -else the larger or smaller representable value nearest the scaled value, +else the next greater or lesser value of the type, chosen in an \impldef{choice of larger or smaller value of \grammarterm{floating-point-literal}} manner. +\begin{example} +The following example assumes that +\tcode{std::float32_t} is supported\iref{basic.extended.fp}. +\begin{codeblock} +std::float32_t x = 0.0f32; // value \tcode{0} is exactly representable +std::float32_t y = 0.1f32; // rounded to one of two values nearest to \tcode{0.1} +std::float32_t z = 1e1000000000f32; // either greatest finite value or positive infinity +\end{codeblock} +\end{example} \rSec2[lex.string]{String literals} \indextext{literal!string}% \begin{bnf} \nontermdef{string-literal}\br - \opt{encoding-prefix} \terminal{"} \opt{s-char-sequence} \terminal{"}\br + \opt{encoding-prefix} plain-string-literal\br \opt{encoding-prefix} \terminal{R} raw-string \end{bnf} +\begin{bnf} +\nontermdef{plain-string-literal}\br + \terminal{"} \opt{s-char-sequence} \terminal{"} +\end{bnf} + \begin{bnf} \nontermdef{s-char-sequence}\br s-char \opt{s-char-sequence} @@ -1776,7 +1867,7 @@ \begin{bnf} \nontermdef{d-char-sequence}\br - d-char\opt{d-char-sequence} + d-char \opt{d-char-sequence} \end{bnf} \begin{bnf} @@ -1788,7 +1879,6 @@ \pnum \indextext{literal!string}% -\indextext{character string}% \indextext{string!type of}% \indextext{type!\idxcode{wchar_t}}% \indextext{prefix!\idxcode{L}}% @@ -1802,7 +1892,9 @@ 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}} @@ -1907,7 +1999,7 @@ \end{note} \pnum -In translation phase 6\iref{lex.phases}, +In translation phase 5\iref{lex.phases}, adjacent \grammarterm{string-literal}s are concatenated. The lexical structure and grouping of the contents of the individual \grammarterm{string-literal}s is retained. @@ -2068,8 +2160,8 @@ \indextext{literal!boolean}% \begin{bnf} \nontermdef{boolean-literal}\br - \terminal{false}\br - \terminal{true} + \keyword{false}\br + \keyword{true} \end{bnf} \pnum @@ -2082,7 +2174,7 @@ \indextext{literal!pointer}% \begin{bnf} \nontermdef{pointer-literal}\br - \terminal{nullptr} + \keyword{nullptr} \end{bnf} \pnum @@ -2197,7 +2289,7 @@ Otherwise, \placeholder{S} shall contain a raw literal operator or a numeric literal operator template\iref{over.literal} but not both. If \placeholder{S} contains a raw literal operator, -the \grammarterm{literal} \placeholder{L} is treated as a call of the form +the literal \placeholder{L} is treated as a call of the form \begin{codeblock} operator ""@\placeholder{X}@("@\placeholder{f}@") \end{codeblock} @@ -2218,7 +2310,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} @@ -2256,11 +2348,11 @@ \end{example} \pnum -In translation phase 6\iref{lex.phases}, adjacent \grammarterm{string-literal}s are concatenated and +In translation phase 5\iref{lex.phases}, adjacent \grammarterm{string-literal}s are concatenated and \grammarterm{user-defined-string-literal}{s} are considered \grammarterm{string-literal}s for that purpose. During concatenation, \grammarterm{ud-suffix}{es} are removed and ignored and the concatenation process occurs as described in~\ref{lex.string}. At the end of phase -6, if a \grammarterm{string-literal} is the result of a concatenation involving at least one +5, if a \grammarterm{string-literal} is the result of a concatenation involving at least one \grammarterm{user-defined-string-literal}, all the participating \grammarterm{user-defined-string-literal}{s} shall have the same \grammarterm{ud-suffix} and that suffix is applied to the result of the concatenation. diff --git a/source/lib-intro.tex b/source/lib-intro.tex index fab923bf47..99420d7c6d 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -368,11 +368,36 @@ and also define the function as deleted. \end{example} +\item +\constantwhen +the conditions that are required for a call to the function +to be a constant subexpression\iref{defns.const.subexpr}. + \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, +contract assertions +whose predicates are as described in the hardened precondition +are evaluated with a terminating semantic\iref{basic.contract.eval}. +\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 @@ -386,6 +411,11 @@ \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 @@ -424,9 +454,19 @@ 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{Constant When}, +\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, @@ -487,25 +527,25 @@ \rSec3[expos.only.entity]{Exposition-only entities, etc.} \pnum -Several entities and \grammarterm{typedef-name}{s} -defined in \ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} -are only defined for the purpose of exposition. -The declaration of such an entity or \grammarterm{typedef-name} +Several entities +declared in \ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} +are provided for exposition only. +The declaration of such an entity is followed by a comment ending in \expos. \pnum -The following are defined for exposition only +The following are provided for exposition only to aid in the specification of the library: -\indexlibrary{decay-copy@\tcode{\placeholder{decay-copy}}}% +\indexlibrary{decay-copy@\exposid{decay-copy}}% \begin{codeblock} namespace std { template requires @\libconcept{convertible_to}@> - constexpr decay_t @\placeholdernc{decay-copy}@(T&& v) // \expos + constexpr decay_t @\exposidnc{decay-copy}@(T&& v) // \expos noexcept(is_nothrow_convertible_v>) { return std::forward(v); } - constexpr auto @\placeholdernc{synth-three-way}@ = // \expos + constexpr auto @\exposidnc{synth-three-way}@ = // \expos [](const T& t, const U& u) requires requires { { t < u } -> @\exposconcept{boolean-testable}@; @@ -521,9 +561,16 @@ } }; - template - using @\placeholdernc{synth-three-way-result}@ = // \expos - decltype(@\placeholdernc{synth-three-way}@(declval(), declval())); + template + using @\exposidnc{synth-three-way-result}@ = // \expos + decltype(@\exposidnc{synth-three-way}@(declval(), declval())); + + template + concept @\defexposconceptnc{constexpr-wrapper-like}@ = // \expos + @\libconcept{convertible_to}@ && + @\libconcept{equality_comparable_with}@ && + bool_constant::value && + bool_constant(T()) == T::value>::value; } \end{codeblock} @@ -558,14 +605,14 @@ the library. \pnum -Certain types defined in \ref{input.output} are used to describe implementation-defined types. +Certain types shown in \ref{input.output} are used to describe implementation-defined types. \indextext{types!implementation-defined}% They are based on other types, but with added constraints. \rSec4[enumerated.types]{Enumerated types} \pnum -Several types defined in \ref{input.output} are +Several types specified in \ref{input.output} and \ref{re} are \defnadjx{enumerated}{types}{type}. Each enumerated type may be implemented as an enumeration or as a synonym for an enumeration. @@ -598,7 +645,7 @@ \rSec4[bitmask.types]{Bitmask types} \pnum -Several types defined in \ref{\firstlibchapter} through \ref{\lastlibchapter} +Several types specified in \ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} are \defnx{bitmask types}{type!bitmask}. Each bitmask type can be implemented as an @@ -746,6 +793,11 @@ predicate. A character sequence can be designated by a pointer value \tcode{\placeholder{S}} that points to its first element. +\item +\indextext{STATICALLY-WIDEN@\exposid{STATICALLY-WIDEN}}% +Let \exposid{STATICALLY-WIDEN}\tcode{("...")} be +\tcode{"..."} if \tcode{charT} is \tcode{char} and +\tcode{L"..."} if \tcode{charT} is \keyword{wchar_t}. \end{itemize} \rSec5[byte.strings]{Byte strings} @@ -817,13 +869,18 @@ \rSec4[customization.point.object]{Customization Point Object types} \pnum -A \term{customization point object} is a function object\iref{function.objects} +A \defnadj{customization point}{object} is a function object\iref{function.objects} with a literal class type that interacts with program-defined types while enforcing semantic requirements on that interaction. \pnum The type of a customization point object, ignoring cv-qualifiers, shall model -\libconcept{semiregular}\iref{concepts.object}. +\libconcept{semiregular}\iref{concepts.object} +and shall be +a structural type\iref{temp.param} and +a trivially copyable type\iref{class.prop}. +Every constructor of this type +shall have a non-throwing exception specification\iref{except.spec}. \pnum All instances of a specific customization point object type shall @@ -935,7 +992,7 @@ \pnum \indextext{item!freestanding|see{freestanding item}}% A \defn{freestanding item} is -a declaration, entity, \grammarterm{typedef-name}, or macro +a declaration, entity, or macro that is required to be present in a freestanding implementation and a hosted implementation. @@ -991,9 +1048,9 @@ \pnum \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 or deduction guide +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, @@ -1001,7 +1058,7 @@ \item a deduction guide of a freestanding item, \item an enclosing namespace of a freestanding item, \item a friend of a freestanding item, -\item denoted by a \grammarterm{typedef-name} that is a freestanding item, or +\item denoted by a type alias that is a freestanding item, or \item denoted by an alias template that is a freestanding item. \end{itemize} @@ -1111,7 +1168,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}, @@ -1135,7 +1193,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}. @@ -1172,6 +1231,7 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1189,6 +1249,7 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1207,6 +1268,7 @@ \tcode{} \\ \tcode{} \\ \columnbreak +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1229,8 +1291,8 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ -\tcode{} \\ \columnbreak +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1562,6 +1624,7 @@ \ref{support.rtti} & Type identification & \tcode{} \\ \rowsep \ref{support.srcloc} & Source location & \tcode{} \\ \rowsep \ref{support.exception} & Exception handling & \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 support & \tcode{} \\ \rowsep @@ -1580,6 +1643,7 @@ \ref{expected} & Expected objects & \tcode{} \\ \rowsep \ref{function.objects} & Function objects & \tcode{} \\ \rowsep \ref{bit} & Bit manipulation & \tcode{} \\ \rowsep +\ref{stdbit.h.syn} & C-compatible bit manipulation & \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 @@ -1587,10 +1651,12 @@ \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} @@ -1609,7 +1675,7 @@ a (possibly empty) implementation-defined subset of the hosted library facilities. Unless otherwise specified, the requirements on -each declaration, entity, \grammarterm{typedef-name}, and macro +each declaration, entity, and macro provided in this way are the same as the corresponding requirements for a hosted implementation, except that not all of the members of the namespaces are required to be present. @@ -1758,12 +1824,6 @@ rvalue of type \tcode{const T}. \end{itemize} -\pnum -In general, a default constructor is not required. Certain container class -member function signatures specify \tcode{T()} as a default argument. -\tcode{T()} shall be a well-defined expression\iref{dcl.init} if one of those -signatures is called using the default argument\iref{dcl.fct.default}. - \begin{oldconcepttable}{EqualityComparable}{}{cpp17.equalitycomparable} {x{1in}x{1in}p{3in}} \topline @@ -1791,7 +1851,6 @@ \tcode{<} is a strict weak ordering relation\iref{alg.sorting} \\ \end{oldconcepttable} -\enlargethispage{-3\baselineskip} \begin{oldconcepttable}{DefaultConstructible}{}{cpp17.defaultconstructible} {x{2.15in}p{3in}} \topline @@ -1857,7 +1916,7 @@ {p{1in}p{4.15in}} \topline \hdstyle{Expression} & \hdstyle{Post-condition} \\ \capsep -\tcode{u.\~T()} & All resources owned by \tcode{u} are reclaimed, no exception is propagated. \\ \rowsep +\tcode{a.\~T()} & No exception is propagated. \\ \rowsep \multicolumn{2}{|l|}{ \begin{tailnote} Array types and non-object types are not \oldconcept{Destructible}. @@ -2288,12 +2347,12 @@ \pnum \remarks -If \tcode{Allocator} is a class template instantiation of the form +If \tcode{Allocator} is a class template specialization of the form \tcode{SomeAllocator}, where \tcode{Args} is zero or more type arguments, and \tcode{Allocator} does not supply a \tcode{rebind} member template, the standard \tcode{allocator_traits} template uses \tcode{SomeAllocator} in place of \tcode{Allocator::re\-bind::other} -by default. For allocator types that are not template instantiations of the +by default. For allocator types that are not template specializations of the above form, no default is provided. \pnum @@ -2905,14 +2964,16 @@ 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}@; +namespace std { + 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}. @@ -3013,7 +3074,7 @@ Let \tcode{\placeholder{F}} denote a standard library function\iref{global.functions}, a standard library static member function, -or an instantiation +or a specialization of a standard library function template. Unless \tcode{\placeholder{F}} is designated an \defnadj{addressable}{function}, @@ -3035,7 +3096,35 @@ or if it attempts to form a pointer-to-member designating either a standard library non-static member function\iref{member.functions} -or an instantiation of a standard library member function template. +or a specialization of a standard library member function template. + +\pnum +Let \tcode{\placeholder{F}} denote +a standard library function or function template. +Unless \tcode{\placeholder{F}} is designated an addressable function, +it is unspecified if or how +a reflection value designating the associated entity can be formed. +For any value \tcode{\placeholder{p}} of type \tcode{meta::info} that +represents a reflection of a parameter of \tcode{\placeholder{F}}, +it is unspecified if \tcode{has_identifier(\placeholder{p})} +returns \tcode{true} or \tcode{false}, and +if \tcode{meta::has_identifier(\placeholder{p})} is \tcode{true}, then +the \ntmbs{} produced by +\tcode{meta::identifier_of(\placeholder{p})} and +\tcode{meta::u8identifier_of(\placeholder{p})} is unspecified. +%FIXME: Why is this not an example, but a note that begins with "For example"? +\begin{note} +For example, it is possible that \tcode{std::meta::members_of} +will not return reflections of standard library functions +that an implementation handles through an extra-linguistic mechanism. +\end{note} + +\pnum +Let \tcode{\placeholder{C}} denote +a standard library class or class template specialization. +It is unspecified if or how +a reflection value can be formed to any private member of \tcode{\placeholder{C}}, +or what the names of such members may be. \pnum A translation unit shall not declare namespace \tcode{std} to be an inline namespace\iref{namespace.def}. @@ -3224,16 +3313,6 @@ \tcode{\#define} or \tcode{\#undef} names declared in any standard library header. -\pnum -\indextext{unit!translation}% -A translation unit shall not \tcode{\#define} or \tcode{\#undef} -names lexically identical -to keywords, -to the identifiers listed in \tref{lex.name.special}, or -to the \grammarterm{attribute-token}{s} described in~\ref{dcl.attr}, -except that the names \tcode{likely} and \tcode{unlikely} may be -defined as function-like macros~\iref{cpp.replace}. - \rSec4[extern.names]{External linkage} \pnum @@ -3313,7 +3392,7 @@ \tcode{::T} and \tcode{std::T} -are reserved to the implementation and, when defined, +are reserved to the implementation and, when declared, \tcode{::T} shall be identical to \tcode{std::T}. @@ -3351,72 +3430,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{term.replaceable.function}, +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} @@ -3456,7 +3476,7 @@ \pnum Calling the \tcode{set_*} and \tcode{get_*} functions shall not incur a data race\iref{intro.races}. -A call to any of the \tcode{set_*} functions shall synchronize with subsequent calls to the same +A call to any of the \tcode{set_*} functions synchronizes with subsequent calls to the same \tcode{set_*} function and to the corresponding \tcode{get_*} function. \rSec3[res.on.functions]{Other functions} @@ -3473,7 +3493,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. @@ -3601,12 +3621,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} @@ -3679,15 +3705,9 @@ the swappable with requirements\iref{swappable.requirements}. The exception for overloaded operators allows argument-dependent lookup in cases like that of -\tcode{ostream_iterator::operator=}\iref{ostream.iterator.ops}: - -\effects -\begin{codeblock} -*@\textit{out_stream}@ << value; -if (@\textit{delim}@ != 0) - *@\textit{out_stream}@ << @\textit{delim}@; -return *this; -\end{codeblock} +\tcode{ostream_iterator::operator=}\iref{ostream.iterator.ops} +where lookup for the expression \tcode{*out_stream << value} +includes the associated namespaces of \tcode{value}'s type. \end{note} \rSec3[member.functions]{Member functions} @@ -3740,7 +3760,7 @@ any standard library function signature as \keyword{constexpr} except for those where it is explicitly required. Within any header that provides any non-defining declarations of constexpr -functions or constructors an implementation shall provide corresponding definitions. +functions an implementation shall provide corresponding definitions. \rSec3[algorithm.stable]{Requirements for stable algorithms} @@ -3770,6 +3790,16 @@ the \Cpp{} standard library may be recursively reentered} which functions in the \Cpp{} standard library may be recursively reentered. +\pnum +During the execution of +a standard library non-static member function $F$ on an object, +if that object is accessed through a glvalue that is not obtained, +directly or indirectly, +from the object parameter of $F$, +in a manner that can conflict\iref{intro.races} +with any access that $F$ is permitted to perform\iref{res.on.data.races}, +the behavior is undefined unless otherwise specified. + \rSec3[res.on.data.races]{Data race avoidance} \pnum @@ -3826,6 +3856,14 @@ 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}. + \rSec3[protection.within.classes]{Protection within classes} \pnum @@ -3939,12 +3977,21 @@ 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 -Certain functions in the \Cpp{} standard library report errors via a -\tcode{std::error_code}\iref{syserr.errcode.overview} object. That object's -\tcode{category()} member shall return \tcode{std::system_category()} for +Certain functions in the \Cpp{} standard library report errors via an +\tcode{error_code}\iref{syserr.errcode.overview} object. That object's +\tcode{category()} member shall return \tcode{system_category()} for errors originating from the operating system, or a reference to an \impldef{\tcode{error_category} for errors originating outside the operating system} \tcode{error_category} object for errors originating elsewhere. diff --git a/source/limits.tex b/source/limits.tex index bdc1f3deb6..e0596a320a 100644 --- a/source/limits.tex +++ b/source/limits.tex @@ -111,7 +111,7 @@ \item% Recursive constexpr function invocations\iref{dcl.constexpr} [512]. \item% -Full-expressions evaluated within a core constant expression\iref{expr.const} [1\,048\,576]. +Full-expressions evaluated within a core constant expression\iref{expr.const.core} [1\,048\,576]. \item% Template parameters in a template declaration\iref{temp.param} [1\,024]. \item% diff --git a/source/macros.tex b/source/macros.tex index 10e808750c..bbba8134c6 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. %%-------------------------------------------------- @@ -214,6 +212,13 @@ \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{\libheaderx}[2]{\indexhdr{#1}\tcode{<#2>}} \newcommand{\libheader}[1]{\libheaderx{#1}{#1}} @@ -230,6 +235,11 @@ %%-------------------------------------------------- \newcommand{\CodeStyle}{\ttfamily} \newcommand{\CodeStylex}[1]{\texttt{\protect\frenchspacing #1}} +\makeatletter +% Append `\@` to restore proper sentence spacing in text mode. This insertion +% happens only during normal typesetting; it is suppressed for .idx generation. +\newcommand{\CodeStylexGuarded}[1]{\CodeStylex{#1\ifmmode\else\ifx\protect\@typeset@protect\@\fi\fi}} +\makeatother \definecolor{grammar-gray}{gray}{0.2} @@ -237,7 +247,7 @@ \newcommand{\GrammarStylex}[1]{\textcolor{grammar-gray}{\textsf{\textit{#1}}}} % Code and definitions embedded in text. -\newcommand{\tcode}[1]{\CodeStylex{#1}} +\newcommand{\tcode}[1]{\CodeStylexGuarded{#1}} \newcommand{\term}[1]{\textit{#1}} \newcommand{\gterm}[1]{\GrammarStylex{#1}} \newcommand{\fakegrammarterm}[1]{\gterm{#1}} @@ -287,7 +297,7 @@ \newcommand{\CppXXIII}{\Cpp{} 2023} \newcommand{\CppXXVI}{\Cpp{} 2026} \newcommand{\IsoCUndated}{ISO/IEC 9899} -\newcommand{\IsoC}{\IsoCUndated{}:2018} +\newcommand{\IsoC}{\IsoCUndated{}:2024} \newcommand{\IsoFloatUndated}{ISO/IEC 60559} \newcommand{\IsoPosixUndated}{ISO/IEC/IEEE 9945} \newcommand{\IsoPosix}{\IsoPosixUndated{}:2009} @@ -358,7 +368,9 @@ \newcommand{\required}{\Fundesc{Required behavior}} \newcommand{\constraints}{\Fundesc{Constraints}} \newcommand{\mandates}{\Fundesc{Mandates}} +\newcommand{\constantwhen}{\Fundesc{Constant When}} \newcommand{\expects}{\Fundesc{Preconditions}} +\newcommand{\hardexpects}{\Fundesc{Hardened preconditions}} \newcommand{\effects}{\Fundesc{Effects}} \newcommand{\ensures}{\Fundesc{Postconditions}} \newcommand{\returns}{\Fundesc{Returns}} @@ -369,7 +381,6 @@ \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}} @@ -395,8 +406,10 @@ \ExplSyntaxOff %% Inline non-parenthesized table reference (override memoir's \tref) +\providecommand{\tref}{} \renewcommand{\tref}[1]{\hyperref[tab:#1]{\tablerefname \nolinebreak[3] \ref*{tab:#1}}} %% Inline non-parenthesized figure reference (override memoir's \fref) +\providecommand{\fref}{} \renewcommand{\fref}[1]{\hyperref[fig:#1]{\figurerefname \nolinebreak[3] \ref*{fig:#1}}} %% NTBS, etc. @@ -457,9 +470,15 @@ \newcommand{\unspecbool}{\UNSP{unspecified-bool-type}} \newcommand{\seebelow}{\UNSP{see below}} % macro length: 0 \newcommand{\seebelownc}{\UNSPnc{see below}} % macro length: 2 +\newcommand{\seeabove}{\UNSP{see above}} % macro length: 0 +\newcommand{\seeabovenc}{\UNSPnc{see above}} % macro length: 2 \newcommand{\unspecuniqtype}{\UNSP{unspecified unique type}} \newcommand{\unspecalloctype}{\UNSP{unspecified allocator type}} +%% Convenience macro for double carets in expressions, +%% particularly within \tcode. +\newcommand{\reflexpr}[1]{\caret\caret#1} + %% Manual insertion of italic corrections, for aligning in the presence %% of the above annotations. \newlength{\itcorrwidth} @@ -498,8 +517,8 @@ \newcommand{\libconceptx}[2]{\cname{#1}\indexconcept{\idxconcept{#2}}} \newcommand{\libconcept}[1]{\libconceptx{#1}{#1}} \newcommand{\deflibconcept}[1]{\cname{#1}\indexlibrary{\idxconcept{#1}}\indexconcept{\idxconcept{#1}|idxbfpage}} -\newcommand{\exposconcept}[1]{\ecname{#1}\indexconcept{\idxexposconcept{#1}}} \newcommand{\exposconceptx}[2]{\ecname{#1}\indexconcept{\idxexposconcept{#2}}} +\newcommand{\exposconcept}[1]{\exposconceptx{#1}{#1}} \newcommand{\exposconceptnc}[1]{\indexconcept{\idxexposconcept{#1}}\ecname{#1}\itcorr[-1]} % macro length: 15 \newcommand{\defexposconcept}[1]{\ecname{#1}\indexconcept{\idxexposconcept{#1}|idxbfpage}} % macro length: 16 \newcommand{\defexposconceptnc}[1]{\ecname{#1}\indexconcept{\idxexposconcept{#1}|idxbfpage}\itcorr[-1]} % macro length: 18 @@ -580,7 +599,7 @@ \lstset{escapechar=@, aboveskip=\parskip, belowskip=0pt, midpenalty=500, endpenalty=-50, emptylinepenalty=-250, semicolonpenalty=0,upquote=true}% -\renewcommand{\tcode}[1]{\textup{\CodeStylex{##1}}} +\renewcommand{\tcode}[1]{\textup{\CodeStylexGuarded{##1}}} \renewcommand{\term}[1]{\textit{##1}}% \renewcommand{\grammarterm}[1]{\gterm{##1}}% } @@ -592,7 +611,7 @@ #1:}}\CodeBlockSetup}{} % An environment for command / program output that is not C++ code. -\lstnewenvironment{outputblock}{\lstset{language=}}{} +\lstnewenvironment{outputblock}{\lstset{escapechar=@, language=}}{} % A code block in which single-quotes are digit separators % rather than character literals. @@ -638,7 +657,7 @@ belowskip=0ex % leave this alone: it keeps these things out of the % footnote area }% - \renewcommand{\tcode}[1]{\textup{\CodeStylex{##1}}} + \renewcommand{\tcode}[1]{\textup{\CodeStylexGuarded{##1}}} } { } @@ -694,7 +713,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 @@ -705,7 +729,7 @@ \end{bnfbase} } -\newenvironment{bnf} +\newenvironment{ncbnf} { \begin{bnfbase} \begin{bnflist} @@ -717,6 +741,7 @@ \end{bnfbase} } +% The regex grammar is never copied. \newenvironment{ncrebnf} { \begin{bnfbase} @@ -730,11 +755,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 @@ -777,3 +801,37 @@ } \newcommand{\defncontext}[1]{\textlangle#1\textrangle} \newnoteenvironment{defnote}{Note \arabic{defnote} to entry}{end note} + +%%---------------------------------- +%% UB and IFNDR sections for annexes +%%---------------------------------- +%% Undefined behavior and ill-formed, no diagnostic required + +\newcommand{\behaviordef}[2]{\nolinebreak[3] (\label{#2x:#1}\ref{#2:#1})} + +\newcommand{\behaviordescription}[2]{% +\let\oldcontentsline\addcontentsline% +\let\addcontentsline\nocontentsline% +\ifcase\value{SectionDepth} + \let\s=\section + \or\let\s=\subsection + \or\let\s=\subsubsection + \or\let\s=\paragraph + \or\let\s=\subparagraph + \fi% +\s[#1]{\hfill[#2:#1]}\label{#2:#1}% +\textbf{Specified in:}\space\ref{#2x:#1}% +\let\addcontentsline\oldcontentsline% +} + +% Use in main body of text to mark undefined behavior +\newcommand{\ubdef}[1]{\behaviordef{#1}{ub}} + +% Use in Annex for sections describing each individual UB +\newcommand{\ubdescription}[1]{\behaviordescription{#1}{ub}} + +% Use in main body of text to mark IFNDR +\newcommand{\ifndrdef}[1]{\behaviordef{#1}{ifndr}} + +% Use in Annex for sections describing each individual IFNDR +\newcommand{\ifndrdescription}[1]{\behaviordescription{#1}{ifndr}} diff --git a/source/memory.tex b/source/memory.tex index ed7d8b8c05..2c68fbe7ab 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -8,13 +8,15 @@ \pnum The following subclauses describe general memory management facilities, -smart pointers, memory resources, and scoped allocators, +smart pointers, pointer tagging, memory resources, and scoped allocators, as summarized in \tref{mem.summary}. \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{ptrtag} & Pointer tagging & \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} @@ -36,6 +38,10 @@ construct objects in uninitialized memory buffers~(\ref{pointer.traits}--\ref{specialized.addressof} and \ref{specialized.algorithms}). +The header also defines class template \tcode{pointer_tag_pair} +to support storing additional information in unused bits of pointers. +Selection of the bits is implementation-defined, +and the size of the pointer wrapping object is the same as the size of the original pointer. The header also defines the templates \tcode{unique_ptr}, \tcode{shared_ptr}, \tcode{weak_ptr}, \tcode{out_ptr_t}, \tcode{inout_ptr_t}, and various function @@ -84,9 +90,11 @@ template constexpr T* assume_aligned(T* ptr); // freestanding template - bool is_sufficiently_aligned(T* ptr); + bool is_sufficiently_aligned(T* ptr); // freestanding // \ref{obj.lifetime}, explicit lifetime management + template + constexpr void start_lifetime(T& r) noexcept; // freestanding template T* start_lifetime_as(void* p) noexcept; // freestanding template @@ -157,9 +165,9 @@ template struct allocator_traits; // freestanding template - struct allocation_result { // freestanding - Pointer ptr; - SizeType count; + struct @\libglobal{allocation_result}@ { // freestanding + Pointer @\libmember{ptr}{allocation_result}@; + SizeType @\libmember{count}{allocation_result}@; }; // \ref{default.allocator}, the default allocator @@ -176,30 +184,43 @@ // \ref{specialized.algorithms}, specialized algorithms // \ref{special.mem.concepts}, special memory concepts template - concept @\exposconcept{nothrow-input-iterator}@ = @\seebelow@; // \expos + concept @\exposconcept{nothrow-input-iterator}@ = @\seebelow@; // \expos + template + concept @\exposconcept{nothrow-forward-iterator}@ = @\seebelow@; // \expos template - concept @\exposconcept{nothrow-forward-iterator}@ = @\seebelow@; // \expos + concept @\exposconcept{nothrow-bidirectional-iterator}@ = @\seebelow@; // \expos + template + concept @\exposconcept{nothrow-random-access-iterator}@ = @\seebelow@; // \expos + template + concept @\exposconcept{nothrow-sentinel-for}@ = @\seebelow@; // \expos template - concept @\exposconcept{nothrow-sentinel-for}@ = @\seebelow@; // \expos + concept @\exposconcept{nothrow-sized-sentinel-for}@ = @\seebelow@; // \expos template - concept @\exposconcept{nothrow-input-range}@ = @\seebelow@; // \expos + concept @\exposconcept{nothrow-input-range}@ = @\seebelow@; // \expos template - concept @\exposconcept{nothrow-forward-range}@ = @\seebelow@; // \expos + concept @\exposconcept{nothrow-forward-range}@ = @\seebelow@; // \expos + template + concept @\exposconcept{nothrow-bidirectional-range}@ = @\seebelow@; // \expos + template + concept @\exposconcept{nothrow-random-access-range}@ = @\seebelow@; // \expos + template + concept @\exposconcept{nothrow-sized-random-access-range}@ = @\seebelow@; // \expos template 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 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> @@ -213,22 +234,38 @@ requires @\libconcept{default_initializable}@> constexpr I uninitialized_default_construct_n(I first, // freestanding iter_difference_t n); + + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-random-access-iterator}@ I, + @\exposconcept{nothrow-sized-sentinel-for}@ S> + requires @\libconcept{default_initializable}@> + I uninitialized_default_construct(Ep&& exec, I first, S last); // freestanding-deleted, + // see \ref{algorithms.parallel.overloads} + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-sized-random-access-range}@ R> + requires @\libconcept{default_initializable}@> + borrowed_iterator_t uninitialized_default_construct(Ep&& exec, // freestanding-deleted, + R&& r); // see \ref{algorithms.parallel.overloads} + + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-random-access-iterator}@ I> + requires @\libconcept{default_initializable}@> + I uninitialized_default_construct_n(Ep&& exec, I first, // freestanding-deleted, + iter_difference_t n); // see \ref{algorithms.parallel.overloads} } template 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 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> @@ -242,6 +279,21 @@ requires @\libconcept{default_initializable}@> constexpr I uninitialized_value_construct_n(I first, // freestanding iter_difference_t n); + + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-random-access-iterator}@ I, + @\exposconcept{nothrow-sized-sentinel-for}@ S> + requires @\libconcept{default_initializable}@> + I uninitialized_value_construct(Ep&& exec, I first, S last); // freestanding-deleted, + // see \ref{algorithms.parallel.overloads} + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-sized-random-access-range}@ R> + requires @\libconcept{default_initializable}@> + borrowed_iterator_t uninitialized_value_construct(Ep&& exec, // freestanding-deleted, + R&& r); // see \ref{algorithms.parallel.overloads} + + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-random-access-iterator}@ I> + requires @\libconcept{default_initializable}@> + I uninitialized_value_construct_n(Ep&& exec, I first, // freestanding-deleted, + iter_difference_t n); // see \ref{algorithms.parallel.overloads} } template @@ -249,8 +301,9 @@ 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 constexpr NoThrowForwardIterator uninitialized_copy_n(InputIterator first, // freestanding @@ -258,13 +311,14 @@ 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 { template - using uninitialized_copy_result = in_out_result; // freestanding + using @\libglobal{uninitialized_copy_result}@ = in_out_result; // freestanding 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> @@ -276,21 +330,41 @@ uninitialized_copy(IR&& in_range, OR&& out_range); // freestanding template - using uninitialized_copy_n_result = in_out_result; // freestanding + using @\libglobal{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> constexpr uninitialized_copy_n_result uninitialized_copy_n(I ifirst, iter_difference_t n, // freestanding O ofirst, S olast); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S1, + @\exposconcept{nothrow-random-access-iterator}@ O, @\exposconcept{nothrow-sized-sentinel-for}@ S2> + requires @\libconcept{constructible_from}@, iter_reference_t> + uninitialized_copy_result + uninitialized_copy(Ep&& exec, I ifirst, S1 ilast, // freestanding-deleted, + O ofirst, S2 olast); // see \ref{algorithms.parallel.overloads} + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ IR, + @\exposconcept{nothrow-sized-random-access-range}@ OR> + requires @\libconcept{constructible_from}@, range_reference_t> + uninitialized_copy_result, borrowed_iterator_t> + uninitialized_copy(Ep&& exec, IR&& in_range, OR&& out_range); // freestanding-deleted, + // see \ref{algorithms.parallel.overloads} + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\exposconcept{nothrow-random-access-iterator}@ O, + @\exposconcept{nothrow-sized-sentinel-for}@ S> + requires @\libconcept{constructible_from}@, iter_reference_t> + uninitialized_copy_n_result + uninitialized_copy_n(Ep&& exec, I ifirst, iter_difference_t n, // freestanding-deleted, + O ofirst, S olast); // see \ref{algorithms.parallel.overloads} } template constexpr NoThrowForwardIterator uninitialized_move(InputIterator first, // freestanding - InputIterator last, - NoThrowForwardIterator result); + 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 constexpr pair @@ -299,12 +373,13 @@ 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 - using uninitialized_move_result = in_out_result; // freestanding + using @\libglobal{uninitialized_move_result}@ = in_out_result; // freestanding 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> @@ -316,42 +391,84 @@ uninitialized_move(IR&& in_range, OR&& out_range); // freestanding template - using uninitialized_move_n_result = in_out_result; // freestanding + using @\libglobal{uninitialized_move_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_rvalue_reference_t> constexpr uninitialized_move_n_result uninitialized_move_n(I ifirst, iter_difference_t n, // freestanding O ofirst, S olast); + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S1, + @\exposconcept{nothrow-random-access-iterator}@ O, @\exposconcept{nothrow-sized-sentinel-for}@ S2> + requires @\libconcept{constructible_from}@, iter_rvalue_reference_t> + uninitialized_move_result + uninitialized_move(Ep&& exec, I ifirst, S1 ilast, // freestanding-deleted, + O ofirst, S2 olast); // see \ref{algorithms.parallel.overloads} + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ IR, + @\exposconcept{nothrow-sized-random-access-range}@ OR> + requires @\libconcept{constructible_from}@, range_rvalue_reference_t> + uninitialized_move_result, borrowed_iterator_t> + uninitialized_move(Ep&& exec, IR&& in_range, OR&& out_range); // freestanding-deleted, + // see \ref{algorithms.parallel.overloads} + + template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, + @\exposconcept{nothrow-random-access-iterator}@ O, @\exposconcept{nothrow-sized-sentinel-for}@ S> + requires @\libconcept{constructible_from}@, iter_rvalue_reference_t> + uninitialized_move_n_result + uninitialized_move_n(Ep&& exec, I ifirst, iter_difference_t n, // freestanding-deleted, + O ofirst, S olast); // see \ref{algorithms.parallel.overloads} } - template + template::value_type> 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, + NoThrowForwardIterator last, const T& x); + template::value_type> + void uninitialized_fill(ExecutionPolicy&& exec, // freestanding-deleted, + NoThrowForwardIterator first, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator last, const T& x); - template + template::value_type> constexpr NoThrowForwardIterator uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); // freestanding - template + template::value_type> 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> + template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S, class T = iter_value_t> requires @\libconcept{constructible_from}@, const T&> constexpr I uninitialized_fill(I first, S last, const T& x); // freestanding - template<@\exposconcept{nothrow-forward-range}@ R, class T> + template<@\exposconcept{nothrow-forward-range}@ R, class T = range_value_t> requires @\libconcept{constructible_from}@, const T&> constexpr borrowed_iterator_t uninitialized_fill(R&& r, const T& x); // freestanding - template<@\exposconcept{nothrow-forward-iterator}@ I, class T> + template<@\exposconcept{nothrow-forward-iterator}@ I, class T = iter_value_t> requires @\libconcept{constructible_from}@, const T&> constexpr I uninitialized_fill_n(I first, // freestanding iter_difference_t n, const T& x); + + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-random-access-iterator}@ I, + @\exposconcept{nothrow-sized-sentinel-for}@ S, class T = iter_value_t> + requires @\libconcept{constructible_from}@, const T&> + I uninitialized_fill(Ep&& exec, I first, S last, const T& x); // freestanding-deleted, + // see \ref{algorithms.parallel.overloads} + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-sized-random-access-range}@ R, + class T = range_value_t> + requires @\libconcept{constructible_from}@, const T&> + borrowed_iterator_t uninitialized_fill(Ep&& exec, R&& r, // freestanding-deleted, + const T& x); // see \ref{algorithms.parallel.overloads} + + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-random-access-iterator}@ I, class T = iter_value_t> + requires @\libconcept{constructible_from}@, const T&> + I uninitialized_fill_n(Ep&& exec, I first, // freestanding-deleted, + iter_difference_t n, const T& x); // see \ref{algorithms.parallel.overloads} } // \ref{specialized.construct}, \tcode{construct_at} @@ -370,14 +487,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> @@ -393,8 +511,61 @@ template<@\exposconcept{nothrow-input-iterator}@ I> requires @\libconcept{destructible}@> constexpr I destroy_n(I first, iter_difference_t n) noexcept; // freestanding + + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-random-access-iterator}@ I, + @\exposconcept{nothrow-sized-sentinel-for}@ S> + requires @\libconcept{destructible}@> + I destroy(Ep&& exec, I first, S last); // freestanding-deleted, + // see \ref{algorithms.parallel.overloads} + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-sized-random-access-range}@ R> + requires @\libconcept{destructible}@> + borrowed_iterator_t destroy(Ep&& exec, R&& r); // freestanding-deleted, + // see \ref{algorithms.parallel.overloads} + template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-random-access-iterator}@ I> + requires @\libconcept{destructible}@> + I destroy_n(Ep&& exec, I first, iter_difference_t n); // freestanding-deleted, + // see \ref{algorithms.parallel.overloads} } + // \ref{ptrtag}, pointer tagging + inline constexpr unsigned max_pointer_bits_available = @\seebelownc@; // freestanding + constexpr unsigned pointer_bits_available(size_t alignment); // freestanding + + template + constexpr unsigned @\exposidnc{bits-available}@ = pointer_bits_available(alignof(T)); // \expos + + template using @\exposidnc{element-of}@ = pointer_traits::element_type; // \expos + + template>, + class TagT = unsigned> + class pointer_tag_pair; // freestanding + + template + struct tuple_size> // freestanding + : integral_constant { }; + + template + struct tuple_element<0, pointer_tag_pair> { // freestanding + using type = Ptr; + }; + template + struct tuple_element<1, pointer_tag_pair> { // freestanding + using type = TagT; + }; + + template + struct tuple_element<0, const pointer_tag_pair> { // freestanding + using type = Ptr; + }; + template + struct tuple_element<1, const pointer_tag_pair> { // freestanding + using type = TagT; + }; + + template + constexpr tuple_element_t> // freestanding + get(pointer_tag_pair p) noexcept; + // \ref{unique.ptr}, class template \tcode{unique_ptr} template struct default_delete; // freestanding template struct default_delete; // freestanding @@ -422,18 +593,22 @@ constexpr bool operator==(const unique_ptr& x, // freestanding const unique_ptr& y); template - bool operator<(const unique_ptr& x, const unique_ptr& y); // freestanding + constexpr bool operator<(const unique_ptr& x, // freestanding + const unique_ptr& y); template - bool operator>(const unique_ptr& x, const unique_ptr& y); // freestanding + constexpr bool operator>(const unique_ptr& x, // freestanding + const unique_ptr& y); template - bool operator<=(const unique_ptr& x, const unique_ptr& y); // freestanding + constexpr bool operator<=(const unique_ptr& x, // freestanding + const unique_ptr& y); template - bool operator>=(const unique_ptr& x, const unique_ptr& y); // freestanding + constexpr bool operator>=(const unique_ptr& x, // freestanding + const unique_ptr& y); template requires @\libconcept{three_way_comparable_with}@::pointer, typename unique_ptr::pointer> - compare_three_way_result_t::pointer, - typename unique_ptr::pointer> + constexpr compare_three_way_result_t::pointer, + typename unique_ptr::pointer> operator<=>(const unique_ptr& x, const unique_ptr& y); // freestanding template @@ -470,69 +645,71 @@ // \ref{util.smartptr.shared.create}, \tcode{shared_ptr} creation template - shared_ptr make_shared(Args&&... args); // \tcode{T} is not array + constexpr shared_ptr make_shared(Args&&... args); // \tcode{T} is not array template - shared_ptr allocate_shared(const A& a, Args&&... args); // \tcode{T} is not array + constexpr shared_ptr allocate_shared(const A& a, Args&&... args); // \tcode{T} is not array template - shared_ptr make_shared(size_t N); // \tcode{T} is \tcode{U[]} + constexpr shared_ptr make_shared(size_t N); // \tcode{T} is \tcode{U[]} template - shared_ptr allocate_shared(const A& a, size_t N); // \tcode{T} is \tcode{U[]} + constexpr shared_ptr allocate_shared(const A& a, size_t N); // \tcode{T} is \tcode{U[]} template - shared_ptr make_shared(); // \tcode{T} is \tcode{U[N]} + constexpr shared_ptr make_shared(); // \tcode{T} is \tcode{U[N]} template - shared_ptr allocate_shared(const A& a); // \tcode{T} is \tcode{U[N]} + constexpr shared_ptr allocate_shared(const A& a); // \tcode{T} is \tcode{U[N]} template - shared_ptr make_shared(size_t N, const remove_extent_t& u); // \tcode{T} is \tcode{U[]} + constexpr shared_ptr make_shared(size_t N, const remove_extent_t& u); // \tcode{T} is \tcode{U[]} template - shared_ptr allocate_shared(const A& a, size_t N, - const remove_extent_t& u); // \tcode{T} is \tcode{U[]} + constexpr shared_ptr allocate_shared(const A& a, size_t N, + const remove_extent_t& u); // \tcode{T} is \tcode{U[]} template - shared_ptr make_shared(const remove_extent_t& u); // \tcode{T} is \tcode{U[N]} + constexpr shared_ptr make_shared(const remove_extent_t& u); // \tcode{T} is \tcode{U[N]} template - shared_ptr allocate_shared(const A& a, const remove_extent_t& u); // \tcode{T} is \tcode{U[N]} + constexpr shared_ptr allocate_shared(const A& a, // \tcode{T} is \tcode{U[N]} + const remove_extent_t& u); template - shared_ptr make_shared_for_overwrite(); // \tcode{T} is not \tcode{U[]} + constexpr shared_ptr make_shared_for_overwrite(); // \tcode{T} is not \tcode{U[]} template - shared_ptr allocate_shared_for_overwrite(const A& a); // \tcode{T} is not \tcode{U[]} + constexpr shared_ptr allocate_shared_for_overwrite(const A& a); // \tcode{T} is not \tcode{U[]} template - shared_ptr make_shared_for_overwrite(size_t N); // \tcode{T} is \tcode{U[]} + constexpr shared_ptr make_shared_for_overwrite(size_t N); // \tcode{T} is \tcode{U[]} template - shared_ptr allocate_shared_for_overwrite(const A& a, size_t N); // \tcode{T} is \tcode{U[]} + constexpr shared_ptr allocate_shared_for_overwrite(const A& a, size_t N); // \tcode{T} is \tcode{U[]} // \ref{util.smartptr.shared.cmp}, \tcode{shared_ptr} comparisons template - bool operator==(const shared_ptr& a, const shared_ptr& b) noexcept; + constexpr bool operator==(const shared_ptr& a, const shared_ptr& b) noexcept; template - strong_ordering operator<=>(const shared_ptr& a, const shared_ptr& b) noexcept; + constexpr strong_ordering operator<=>(const shared_ptr& a, + const shared_ptr& b) noexcept; template - bool operator==(const shared_ptr& x, nullptr_t) noexcept; + constexpr bool operator==(const shared_ptr& x, nullptr_t) noexcept; template - strong_ordering operator<=>(const shared_ptr& x, nullptr_t) noexcept; + constexpr strong_ordering operator<=>(const shared_ptr& x, nullptr_t) noexcept; // \ref{util.smartptr.shared.spec}, \tcode{shared_ptr} specialized algorithms template - void swap(shared_ptr& a, shared_ptr& b) noexcept; + constexpr void swap(shared_ptr& a, shared_ptr& b) noexcept; // \ref{util.smartptr.shared.cast}, \tcode{shared_ptr} casts template - shared_ptr static_pointer_cast(const shared_ptr& r) noexcept; + constexpr shared_ptr static_pointer_cast(const shared_ptr& r) noexcept; template - shared_ptr static_pointer_cast(shared_ptr&& r) noexcept; + constexpr shared_ptr static_pointer_cast(shared_ptr&& r) noexcept; template - shared_ptr dynamic_pointer_cast(const shared_ptr& r) noexcept; + constexpr shared_ptr dynamic_pointer_cast(const shared_ptr& r) noexcept; template - shared_ptr dynamic_pointer_cast(shared_ptr&& r) noexcept; + constexpr shared_ptr dynamic_pointer_cast(shared_ptr&& r) noexcept; template - shared_ptr const_pointer_cast(const shared_ptr& r) noexcept; + constexpr shared_ptr const_pointer_cast(const shared_ptr& r) noexcept; template - shared_ptr const_pointer_cast(shared_ptr&& r) noexcept; + constexpr shared_ptr const_pointer_cast(shared_ptr&& r) noexcept; template shared_ptr reinterpret_pointer_cast(const shared_ptr& r) noexcept; template @@ -540,7 +717,7 @@ // \ref{util.smartptr.getdeleter}, \tcode{shared_ptr} \tcode{get_deleter} template - D* get_deleter(const shared_ptr& p) noexcept; + constexpr D* get_deleter(const shared_ptr& p) noexcept; // \ref{util.smartptr.shared.io}, \tcode{shared_ptr} I/O template @@ -550,7 +727,7 @@ template class weak_ptr; // \ref{util.smartptr.weak.spec}, \tcode{weak_ptr} specialized algorithms - template void swap(weak_ptr& a, weak_ptr& b) noexcept; + template constexpr void swap(weak_ptr& a, weak_ptr& b) noexcept; // \ref{util.smartptr.ownerless}, class template \tcode{owner_less} template struct owner_less; @@ -580,7 +757,7 @@ // \ref{out.ptr}, function template \tcode{out_ptr} template - auto out_ptr(Smart& s, Args&&... args); // freestanding + constexpr auto out_ptr(Smart& s, Args&&... args); // freestanding // \ref{inout.ptr.t}, class template \tcode{inout_ptr_t} template @@ -588,7 +765,23 @@ // \ref{inout.ptr}, function template \tcode{inout_ptr} template - auto inout_ptr(Smart& s, Args&&... args); // freestanding + constexpr 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} @@ -631,7 +824,7 @@ template requires requires { typename T::element_type; } struct @\exposid{ptr-traits-elem}@ -{ using type = typename T::element_type; }; +{ using type = T::element_type; }; template class SomePointer, class T, class... Args> requires (!requires { typename SomePointer::element_type; }) @@ -695,7 +888,7 @@ the \grammarterm{qualified-id} \tcode{Ptr::rebind} is valid and denotes a type\iref{temp.deduct}; otherwise, \tcode{SomePointer} if -\tcode{Ptr} is a class template instantiation of the form \tcode{SomePointer}, +\tcode{Ptr} is a class template specialization of the form \tcode{SomePointer}, where \tcode{Args} is zero or more type arguments; otherwise, the instantiation of \tcode{rebind} is ill-formed. \end{itemdescr} @@ -704,7 +897,7 @@ \indexlibrarymember{pointer_to}{pointer_traits}% \begin{itemdecl} -static pointer pointer_traits::pointer_to(@\seebelow@ r); +static constexpr pointer pointer_traits::pointer_to(@\seebelow@ r); static constexpr pointer pointer_traits::pointer_to(@\seebelow@ r) noexcept; \end{itemdecl} @@ -877,6 +1070,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +\tcode{Alignment} is a power of two. + \pnum \expects \tcode{p} points to @@ -894,6 +1091,31 @@ \rSec2[obj.lifetime]{Explicit lifetime management} +\indexlibraryglobal{start_lifetime}% +\begin{itemdecl} +template + constexpr void start_lifetime(T& r) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{T} is a complete type and +an implicit-lifetime\iref{basic.types} aggregate\iref{dcl.init.aggr} type. + +\pnum +\effects +If the object referenced by \tcode{r} +is already within its lifetime\iref{basic.life}, +no effects. +Otherwise, begins the lifetime of the object referenced by \tcode{r}. +\begin{note} +No initialization is performed and no subobject has its lifetime started. +If \tcode{r} denotes a member of a union $U$, +it becomes the active member of $U$\iref{class.union}. +\end{note} +\end{itemdescr} + \indexlibraryglobal{start_lifetime_as}% \begin{itemdecl} template @@ -1058,7 +1280,7 @@ then \tcode{alloc} is ignored. \item Otherwise, if \tcode{T} has a constructor invocable as - \tcode{T(allocator_arg, alloc, args...)} (leading-allocator convention), + \tcode{T(allocator_arg_t\{\}, alloc, args...)} (leading-allocator convention), then uses-allocator construction chooses this constructor form. \item Otherwise, if \tcode{T} has a constructor invocable as @@ -1389,7 +1611,7 @@ template struct allocator_traits { using allocator_type = Alloc; - using value_type = typename Alloc::value_type; + using value_type = Alloc::value_type; using pointer = @\seebelow@; using const_pointer = @\seebelow@; @@ -1568,7 +1790,7 @@ \templalias \tcode{Alloc::rebind::other} if the \grammarterm{qualified-id} \tcode{Alloc::rebind::other} is valid and denotes a type\iref{temp.deduct}; otherwise, -\tcode{Alloc} if \tcode{Alloc} is a class template instantiation +\tcode{Alloc} if \tcode{Alloc} is a class template specialization of the form \tcode{Alloc}, where \tcode{Args} is zero or more type arguments; otherwise, the instantiation of \tcode{rebind_alloc} is ill-formed. \end{itemdescr} @@ -1660,7 +1882,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}% @@ -1870,12 +2092,10 @@ \indexlibraryglobal{aligned_alloc}% \indexlibraryglobal{calloc}% \indexlibraryglobal{malloc}% -\indexlibraryglobal{realloc}% \begin{itemdecl} void* aligned_alloc(size_t alignment, size_t size); void* calloc(size_t nmemb, size_t size); void* malloc(size_t size); -void* realloc(void* ptr, size_t size); \end{itemdecl} \begin{itemdescr} @@ -1887,14 +2107,40 @@ \remarks These functions do not attempt to allocate storage by calling \tcode{::operator new()}\iref{new.delete}. -\indexlibrarymember{new}{operator}% \pnum These functions implicitly create objects\iref{intro.object} in the returned region of storage and return a pointer to a suitable created object. -In the case of \tcode{calloc} and \tcode{realloc}, -the objects are created before the storage is zeroed or copied, respectively. +In the case of \tcode{calloc}, +the objects are created before the storage is zeroed. +\end{itemdescr} + +\indexlibraryglobal{realloc}% +\begin{itemdecl} +void* realloc(void* ptr, size_t size); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{free(ptr)} has well-defined behavior. + +\pnum +\effects +If \tcode{ptr} is not null and \tcode{size} is zero, +the behavior is erroneous and the effects are implementation-defined. +Otherwise, this function has the semantics specified in the C standard library. + +\pnum +\remarks +This function does not attempt to allocate storage +by calling \tcode{::operator new()}\iref{new.delete}. +When a non-null pointer is returned, +this function implicitly creates objects\iref{intro.object} +in the returned region of storage and +returns a pointer to a suitable created object. +The objects are created before the storage is copied. \end{itemdescr} \indexlibraryglobal{free}% @@ -1911,156 +2157,579 @@ \remarks This function does not attempt to deallocate storage by calling -\tcode{::operator delete()}\indexlibrarymember{delete}{operator}. +\tcode{::operator delete()}\iref{new.delete}. \end{itemdescr} -\xrefc{7.22.3} +\xrefc{7.24.4} -\rSec1[smartptr]{Smart pointers} +\rSec1[ptrtag]{Pointer tagging} -\rSec2[unique.ptr]{Unique-ownership pointers} +\rSec2[ptrtag.bits]{Pointer tagging limits} -\rSec3[unique.ptr.general]{General} +\indexlibraryglobal{max_pointer_bits_available}% +\begin{itemdecl} +inline constexpr unsigned max_pointer_bits_available = @\seebelow@; +\end{itemdecl} +\begin{itemdescr} \pnum -A \defn{unique pointer} is an object that owns another object and -manages that other object through a pointer. More precisely, a unique pointer -is an object \textit{u} that stores a pointer to a second object \textit{p} and -will dispose of \textit{p} when \textit{u} is itself destroyed (e.g., when -leaving block scope\iref{stmt.dcl}). In this context, \textit{u} is said -to \defn{own} \tcode{p}. +The \impldef{value of \tcode{max_pointer_bits_available}} +limit of usable bits for pointer tagging. \pnum -The mechanism by which \textit{u} disposes of \textit{p} is known as -\textit{p}'s associated \defn{deleter}, a function object whose correct -invocation results in \textit{p}'s appropriate disposition (typically its deletion). +\remarks +A non-zero value of \tcode{max_pointer_bits_available} indicates +that non-arithmetic operations on invalid pointers +with implementation-defined behavior\iref{basic.compound} +preserve sufficient information to guarantee that +for an object \tcode{tp} of a type \tcode{TP} +that is a specialization of \tcode{tagged_pointer_pair} and a pointer value \tcode{q}, +that is a result of applying a sequence of such operations +to the result of \tcode{tp.tagged()}, +\tcode{tp} is equal to \tcode{TP::from_tagged(q)}. +\end{itemdescr} +\indexlibraryglobal{pointer_bits_available}% +\begin{itemdecl} +constexpr unsigned pointer_bits_available(size_t alignment); +\end{itemdecl} + +\begin{itemdescr} \pnum -Let the notation \textit{u.p} denote the pointer stored by \textit{u}, and -let \textit{u.d} denote the associated deleter. Upon request, \textit{u} can -\defn{reset} (replace) \textit{u.p} and \textit{u.d} with another pointer and -deleter, but properly disposes of its owned object via the associated -deleter before such replacement is considered completed. +\constantwhen +Precondition is met. \pnum -Each object of a type \tcode{U} instantiated from the \tcode{unique_ptr} template -specified in \ref{unique.ptr} has the strict ownership semantics, specified above, -of a unique pointer. In partial satisfaction of these semantics, each such \tcode{U} -is \oldconcept{MoveConstructible} and \oldconcept{MoveAssignable}, but is not -\oldconcept{CopyConstructible} nor \oldconcept{CopyAssignable}. -The template parameter \tcode{T} of \tcode{unique_ptr} may be an incomplete type. +\expects +\tcode{alignment} is a power of two. + +\pnum +\returns +The \impldef{value returned by \tcode{pointer_bits_available}} +number of unused bits in a pointer +pointing to a hypothetical object with alignment \tcode{alignment}. + +\pnum +\recommended +The result is non-zero for \tcode{alignment} values larger than \tcode{1}. \pnum \begin{note} -The uses -of \tcode{unique_ptr} include providing exception safety for -dynamically allocated memory, passing ownership of dynamically allocated -memory to a function, and returning dynamically allocated memory from a -function. +On most platforms, the value is the minimum of +\tcode{countr_zero(alignment)} and \tcode{max_pointer_bits_available}. \end{note} +\end{itemdescr} -\rSec3[unique.ptr.dltr]{Default deleters} - -\rSec4[unique.ptr.dltr.general]{General} +\rSec2[ptrtag.pair]{Class template \tcode{pointer_tag_pair}} -\pnum -The class template \tcode{default_delete} serves as the default deleter (destruction policy) -for the class template \tcode{unique_ptr}. +\rSec3[ptrtag.pair.general]{General} \pnum -The template parameter \tcode{T} of \tcode{default_delete} may be -an incomplete type. - -\rSec4[unique.ptr.dltr.dflt]{\tcode{default_delete}} +The class template \tcode{pointer_tag_pair} provides a type to store an +object pointer together with a tag value. +\indexlibraryglobal{pointer_tag_pair}% \begin{codeblock} namespace std { - template struct default_delete { - constexpr default_delete() noexcept = default; - template constexpr default_delete(const default_delete&) noexcept; - constexpr void operator()(T*) const; + template + concept @\defexposconceptnc{tagging-compatible-pointee}@ = // \expos + @\libconcept{convertible_to}@ && + pointer_bits_available(Alignment) >= BitsRequested && + (is_void_v<@\exposid{element-of}@> || + is_scalar_v<@\exposid{element-of}@> || + is_union_v<@\exposid{element-of}@> || + is_pointer_interconvertible_base_of_v<@\exposid{element-of}@, U>); + + template + constexpr unsigned @\exposidnc{tag-bit-width}@(TagT value) noexcept; // \expos + + template>, + class TagT = unsigned> + class pointer_tag_pair { // freestanding + public: + using pointer_type = Ptr; + using element_type = pointer_traits::element_type; + using tagged_pointer_type = @\seebelow@; + using tag_type = TagT; + static constexpr unsigned bits_requested = BitsRequested; + + // \ref{ptrtag.pair.cons}, constructors + constexpr pointer_tag_pair() noexcept; + + template<@\exposconcept{tagging-compatible-pointee}@ U> + constexpr pointer_tag_pair(U* p, tag_type t); + constexpr pointer_tag_pair(nullptr_t p, tag_type t); + + // \ref{ptrtag.pair.overalign}, support for overaligned pointers + template U> + static constexpr pointer_tag_pair from_overaligned(U* p, tag_type t); + + // \ref{ptrtag.pair.tagops}, tagged pointer operations + tagged_pointer_type tagged_pointer() const noexcept; + static pointer_tag_pair from_tagged(tagged_pointer_type p) noexcept; + + // \ref{ptrtag.pair.accessors}, accessors + constexpr pointer_type pointer() const noexcept; + constexpr tag_type tag() const noexcept; + + // \ref{ptrtag.pair.swap}, swap + constexpr void swap(pointer_tag_pair& o) noexcept; + + // \ref{ptrtag.pair.comp}, comparisons + friend constexpr @\seebelow@ operator<=>(pointer_tag_pair lhs, pointer_tag_pair rhs) + noexcept requires @\libconcept{three_way_comparable}@; + friend constexpr bool operator==(pointer_tag_pair, pointer_tag_pair) + noexcept requires @\libconcept{equality_comparable}@; }; + + template + pointer_tag_pair(Ptr*) + -> pointer_tag_pair; + template + pointer_tag_pair(Ptr*, TagT tag) + -> pointer_tag_pair>, TagT>; } \end{codeblock} -\indexlibraryctor{default_delete}% +\pnum +An object of class \tcode{pointer_tag_pair} +represents a pair of +pointer value of type \tcode{Ptr} and +tag value of type \tcode{TagT}. + +\pnum +Each specialization \tcode{PT} of \tcode{pointer_tag_pair} +is a trivially copyable type that models \libconcept{copyable} such that +\tcode{sizeof(PT)} is equal to \tcode{sizeof(Ptr)} and +\tcode{alignof(PT)} is equal to \tcode{alignof(Ptr)}. + +\pnum +\mandates +\begin{itemize} +\item \tcode{is_same_v, Ptr>} is \tcode{true}. +\item \tcode{is_same_v, TagT>} is \tcode{true}. +\item \tcode{is_pointer_v \&\& !is_function_v>} is \tcode{true}. +\item \tcode{is_unsigned_v} is \tcode{true}, +where \tcode{UT} is +\tcode{underlying_type_t} if \tcode{TagT} is an enumeration type, and +\tcode{TagT} otherwise. +\item \tcode{sizeof(TagT) <= sizeof(void*)} is \tcode{true}. +\item \tcode{BitsRequested <= max_pointer_bits_available} is \tcode{true}. +\end{itemize} + +\indexlibraryglobal{\exposid{tag-bit-width}}% \begin{itemdecl} -template constexpr default_delete(const default_delete& other) noexcept; +template constexpr unsigned @\exposid{tag-bit-width}@(T v) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\constraints -\tcode{U*} is implicitly convertible to \tcode{T*}. +\returns +\tcode{static_cast(bit_width(to_underlying(v)))} +if \tcode{is_enum_v} is \tcode{true}, +otherwise \tcode{static_cast(bit_width(v))}. +\end{itemdescr} + +\rSec3[ptrtag.pair.cons]{Constructors} + +\indexlibraryglobal{pointer_tag_pair}% +\begin{itemdecl} +constexpr pointer_tag_pair() noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\effects -Constructs a \tcode{default_delete} object -from another \tcode{default_delete} object. +\ensures +\tcode{pointer()} is equal to \tcode{nullptr} and +\tcode{tag()} is equal to \tcode{TagT()}. \end{itemdescr} -\indexlibrarymember{operator()}{default_delete}% +\indexlibraryglobal{pointer_tag_pair}% \begin{itemdecl} -constexpr void operator()(T* ptr) const; +template<@\exposconcept{tagging-compatible-pointee}@ U> + constexpr pointer_tag_pair(U* p, tag_type t); +constexpr pointer_tag_pair(nullptr_t p, tag_type t); \end{itemdecl} \begin{itemdescr} \pnum -\mandates -\tcode{T} is a complete type. +\constantwhen +Preconditions are met. \pnum -\effects -Calls \keyword{delete} on \tcode{ptr}. -\end{itemdescr} +\expects +\begin{itemize} +\item \tcode{p} is not a pointer past the end of an object\iref{basic.compound}. +\item \tcode{\exposid{tag-bit-width}(t) <= bits_requested} is \tcode{true}. +\end{itemize} -\rSec4[unique.ptr.dltr.dflt1]{\tcode{default_delete}} +\pnum +\ensures +\tcode{pointer()} is equal to \tcode{p} and +\tcode{tag()} is equal to \tcode{t}. -\begin{codeblock} -namespace std { - template struct default_delete { - constexpr default_delete() noexcept = default; - template constexpr default_delete(const default_delete&) noexcept; - template constexpr void operator()(U* ptr) const; - }; -} -\end{codeblock} +\pnum +\throws +Nothing. +\end{itemdescr} -\indexlibraryctor{default_delete} +\rSec3[ptrtag.pair.overalign]{Support for overaligned pointers} + +\indexlibraryglobal{from_overaligned}% \begin{itemdecl} -template constexpr default_delete(const default_delete& other) noexcept; +template U> + static constexpr pointer_tag_pair from_overaligned(U* p, tag_type t); \end{itemdecl} \begin{itemdescr} \pnum -\constraints -\tcode{U(*)[]} is convertible to \tcode{T(*)[]}. +\constantwhen +Preconditions are met. \pnum -\effects -Constructs a \tcode{default_delete} object from another \tcode{default_delete} object. +\expects +\begin{itemize} +\item \tcode{p} is not a pointer past the end of an object\iref{basic.compound}. +\item \tcode{p == nullptr || is_sufficiently_aligned(p)} is \tcode{true}. +\item \tcode{\exposid{tag-bit-width}(t) <= bits_requested} is \tcode{true}. +\end{itemize} + +\pnum +\returns +An object \tcode{ptp} of type \tcode{pointer_tag_pair} such that both +\tcode{ptp.pointer()} is equal to \tcode{p} and +\tcode{ptp.tag()} is equal to \tcode{t}. + +\pnum +\throws +Nothing. \end{itemdescr} -\indexlibrarymember{operator()}{default_delete}% +\rSec3[ptrtag.pair.tagops]{Tagged pointer operations} + +\indexlibraryglobal{tagged_pointer_type}% \begin{itemdecl} -template constexpr void operator()(U* ptr) const; +using tagged_pointer_type = @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum -\constraints -\tcode{U(*)[]} is convertible to \tcode{T(*)[]}. +\tcode{tagged_pointer_type} denotes \cv{}~\tcode{void*}, +%FIXME: what do we mean by "pointer denotes"? \tcode{pointer()}? +for \cv{} such that pointer denotes \cv{}~\tcode{U*} for some type \tcode{U}. +\end{itemdescr} + +\indexlibraryglobal{tagged_pointer}% +\begin{itemdecl} +tagged_pointer_type tagged_pointer() const noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\mandates -\tcode{U} is a complete type. +\returns +An unspecified value \tcode{tp} of \tcode{tagged_pointer_type} type +such that for any specialization \tcode{DP} of \tcode{pointer_tag_pair} and +alignment value \tcode{A} for which +\begin{itemize} +\item \tcode{pointer_bits_available(A) >= DP::bits_requested} is \tcode{true}, +\item \tcode{is_sufficiently_aligned(ptr)} is \tcode{true}, and +\item \tcode{\exposid{tag-bit-width}(tag) <= DP::bits_requested} is \tcode{true}, +\end{itemize} +\tcode{DP::from_tagged(tp)} produces an object \tcode{dp} such that +\tcode{reinterpret_cast(dp.poin\-ter())} is equal to \tcode{ptr} and +\tcode{static_cast(dp.tag())} is equal to \tcode{tag}. +\begin{note} +This function returns an invalid pointer value\iref{basic.compound} +with implementation-defined behavior. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{from_tagged}% +\begin{itemdecl} +static pointer_tag_pair from_tagged(tagged_pointer_type p) noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\effects -Calls \tcode{delete[]} on \tcode{ptr}. +\returns +An object \tcode{dp} of type \tcode{pointer_tag_type}, such that +\begin{itemize} +\item +\tcode{reinterpret_cast(sp.pointer())} is equal to \tcode{dp.pointer()} and\\ +\tcode{static_cast(sp.tag())} is equal to \tcode{dp.tag()}, +if \tcode{p} is equal to \tcode{sp.tagged_pointer()} +for some object \tcode{sp} of a type that is a specialization of \tcode{pointer_tag_type}, +such that for some alignment value \tcode{A} +\begin{itemize} +\item \tcode{pointer_bits_available(A) >= bits_requested} is \tcode{true}, +\item \tcode{is_sufficiently_aligned(sp.pointer())} is \tcode{true}, and +\item \tcode{\exposid{tag-bit-width}(sp.tag()) <= bits_requested} is \tcode{true}, +\end{itemize} +\item +otherwise, the values of \tcode{dp.pointer()} and \tcode{dp.tag()} are unspecified. +\end{itemize} \end{itemdescr} -\rSec3[unique.ptr.single]{\tcode{unique_ptr} for single objects} +\rSec3[ptrtag.pair.accessors]{Accessors} + +\indexlibraryglobal{pointer}% +\begin{itemdecl} +constexpr pointer_type pointer() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The pointer value represented by \tcode{*this}. +\end{itemdescr} + +\indexlibraryglobal{tag}% +\begin{itemdecl} +constexpr tag_type tag() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The tag value represented by \tcode{*this}. +\end{itemdescr} + +\rSec3[ptrtag.pair.swap]{Swap} + +\indexlibraryglobal{swap}% +\begin{itemdecl} +constexpr void swap(pointer_tag_pair& o) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Exchanges the values of \tcode{*this} and \tcode{o}. +\end{itemdescr} + +\rSec3[ptrtag.pair.comp]{Comparisons} + +\indexlibrarymember{operator<=>}{pointer_tag_pair}% +\begin{itemdecl} +friend constexpr auto operator<=>(pointer_tag_pair lhs, pointer_tag_pair rhs) + noexcept requires @\libconcept{three_way_comparable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return pair(lhs.pointer(), lhs.tag()) <=> pair(rhs.pointer(), rhs.tag()); +\end{codeblock} + +\pnum +\recommended +%FIXME: These imperative instructions directly addressing compiler developers seem highly unusual. +%Don't we normally say something like "implementations should"? +%Same issue for operator==. +Directly compare the internal bit representations +if the expression \tcode{lhs.tag() <=> rhs.tag()} +results in a call to a built-in operator \tcode{<=>} +comparing values of type \tcode{tag_type}. + +\begin{note} +The result of comparing unrelated pointers is unspecified. +\end{note} +\end{itemdescr} + +\indexlibrarymember{operator==}{pointer_tag_pair}% +\begin{itemdecl} +friend constexpr bool operator==(pointer_tag_pair lhs, pointer_tag_pair rhs) + noexcept requires @\libconcept{equality_comparable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return pair(lhs.pointer(), lhs.tag()) == pair(rhs.pointer(), rhs.tag()); +\end{codeblock} + +\pnum +\recommended +Directly compare the internal bit representations +if the expression \tcode{lhs.tag() == rhs.tag()} +results in a call to a built-in operator \tcode{==} +comparing values of type \tcode{tag_type}. +\end{itemdescr} + +\rSec3[ptrtag.pair.get]{Tuple interface} + +\indexlibrarymember{get}{pointer_tag_pair}% +\begin{itemdecl} +template + constexpr tuple_element_t> + get(pointer_tag_pair p) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +%FIXME: is true +\tcode{I < 2}. + +\pnum +\returns +\begin{itemize} +\item \tcode{p.pointer()} if \tcode{I} is equal to zero, +\item \tcode{p.tag()} otherwise. +\end{itemize} +\end{itemdescr} + +\rSec1[smartptr]{Smart pointers} + +\rSec2[unique.ptr]{Unique-ownership pointers} + +\rSec3[unique.ptr.general]{General} + +\pnum +A \defn{unique pointer} is an object that owns another object and +manages that other object through a pointer. More precisely, a unique pointer +is an object \textit{u} that stores a pointer to a second object \textit{p} and +will dispose of \textit{p} when \textit{u} is itself destroyed (e.g., when +leaving block scope\iref{stmt.dcl}). In this context, \textit{u} is said +to \defn{own} \tcode{p}. + +\pnum +The mechanism by which \textit{u} disposes of \textit{p} is known as +\textit{p}'s associated \defn{deleter}, a function object whose correct +invocation results in \textit{p}'s appropriate disposition (typically its deletion). + +\pnum +Let the notation \textit{u.p} denote the pointer stored by \textit{u}, and +let \textit{u.d} denote the associated deleter. Upon request, \textit{u} can +\defn{reset} (replace) \textit{u.p} and \textit{u.d} with another pointer and +deleter, but properly disposes of its owned object via the associated +deleter before such replacement is considered completed. + +\pnum +Each object of a type \tcode{U} instantiated from the \tcode{unique_ptr} template +specified in \ref{unique.ptr} has the strict ownership semantics, specified above, +of a unique pointer. In partial satisfaction of these semantics, each such \tcode{U} +is \oldconcept{MoveConstructible} and \oldconcept{MoveAssignable}, but is not +\oldconcept{CopyConstructible} nor \oldconcept{CopyAssignable}. +The template parameter \tcode{T} of \tcode{unique_ptr} may be an incomplete type. + +\pnum +\begin{note} +The uses +of \tcode{unique_ptr} include providing exception safety for +dynamically allocated memory, passing ownership of dynamically allocated +memory to a function, and returning dynamically allocated memory from a +function. +\end{note} + +\rSec3[unique.ptr.dltr]{Default deleters} + +\rSec4[unique.ptr.dltr.general]{General} + +\pnum +The class template \tcode{default_delete} serves as the default deleter (destruction policy) +for the class template \tcode{unique_ptr}. + +\pnum +The template parameter \tcode{T} of \tcode{default_delete} may be +an incomplete type. + +\rSec4[unique.ptr.dltr.dflt]{\tcode{default_delete}} + +\begin{codeblock} +namespace std { + template struct default_delete { + constexpr default_delete() noexcept = default; + template constexpr default_delete(const default_delete&) noexcept; + constexpr void operator()(T*) const; + }; +} +\end{codeblock} + +\indexlibraryctor{default_delete}% +\begin{itemdecl} +template constexpr default_delete(const default_delete& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{U*} is implicitly convertible to \tcode{T*}. + +\pnum +\effects +Constructs a \tcode{default_delete} object +from another \tcode{default_delete} object. +\end{itemdescr} + +\indexlibrarymember{operator()}{default_delete}% +\begin{itemdecl} +constexpr void operator()(T* ptr) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{T} is a complete type. + +\pnum +\effects +Calls \keyword{delete} on \tcode{ptr}. +\end{itemdescr} + +\rSec4[unique.ptr.dltr.dflt1]{\tcode{default_delete}} + +\begin{codeblock} +namespace std { + template struct default_delete { + constexpr default_delete() noexcept = default; + template constexpr default_delete(const default_delete&) noexcept; + template constexpr void operator()(U* ptr) const; + }; +} +\end{codeblock} + +\indexlibraryctor{default_delete} +\begin{itemdecl} +template constexpr default_delete(const default_delete& other) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{U(*)[]} is convertible to \tcode{T(*)[]}. + +\pnum +\effects +Constructs a \tcode{default_delete} object from another \tcode{default_delete} object. +\end{itemdescr} + +\indexlibrarymember{operator()}{default_delete}% +\begin{itemdecl} +template constexpr void operator()(U* ptr) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{U(*)[]} is convertible to \tcode{T(*)[]}. + +\pnum +\mandates +\tcode{U} is a complete type. + +\pnum +\effects +Calls \tcode{delete[]} on \tcode{ptr}. +\end{itemdescr} + +\rSec3[unique.ptr.single]{\tcode{unique_ptr} for single objects} \rSec4[unique.ptr.single.general]{General} @@ -2470,6 +3139,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{*declval()} is a well-formed expression. + \pnum \mandates \tcode{reference_converts_from_temporary_v, decltype(\linebreak{}*declval())>} is \tcode{false}. @@ -2954,7 +3627,7 @@ \indexlibrarymember{operator<}{unique_ptr}% \begin{itemdecl} template - bool operator<(const unique_ptr& x, const unique_ptr& y); + constexpr bool operator<(const unique_ptr& x, const unique_ptr& y); \end{itemdecl} \begin{itemdescr} @@ -2986,7 +3659,7 @@ \indexlibrarymember{operator>}{unique_ptr}% \begin{itemdecl} template - bool operator>(const unique_ptr& x, const unique_ptr& y); + constexpr bool operator>(const unique_ptr& x, const unique_ptr& y); \end{itemdecl} \begin{itemdescr} @@ -2998,7 +3671,7 @@ \indexlibrarymember{operator<=}{unique_ptr}% \begin{itemdecl} template - bool operator<=(const unique_ptr& x, const unique_ptr& y); + constexpr bool operator<=(const unique_ptr& x, const unique_ptr& y); \end{itemdecl} \begin{itemdescr} @@ -3010,7 +3683,7 @@ \indexlibrarymember{operator>=}{unique_ptr}% \begin{itemdecl} template - bool operator>=(const unique_ptr& x, const unique_ptr& y); + constexpr bool operator>=(const unique_ptr& x, const unique_ptr& y); \end{itemdecl} \begin{itemdescr} @@ -3024,8 +3697,8 @@ template requires @\libconcept{three_way_comparable_with}@::pointer, typename unique_ptr::pointer> - compare_three_way_result_t::pointer, - typename unique_ptr::pointer> + constexpr compare_three_way_result_t::pointer, + typename unique_ptr::pointer> operator<=>(const unique_ptr& x, const unique_ptr& y); \end{itemdecl} @@ -3168,7 +3841,7 @@ class bad_weak_ptr : 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} @@ -3179,7 +3852,7 @@ \indexlibrarymember{what}{bad_weak_ptr}% \begin{itemdecl} -const char* what() const noexcept override; +constexpr const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} @@ -3211,69 +3884,69 @@ constexpr shared_ptr() noexcept; constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { } template - explicit shared_ptr(Y* p); + constexpr explicit shared_ptr(Y* p); template - shared_ptr(Y* p, D d); + constexpr shared_ptr(Y* p, D d); template - shared_ptr(Y* p, D d, A a); + constexpr shared_ptr(Y* p, D d, A a); template - shared_ptr(nullptr_t p, D d); + constexpr shared_ptr(nullptr_t p, D d); template - shared_ptr(nullptr_t p, D d, A a); + constexpr shared_ptr(nullptr_t p, D d, A a); template - shared_ptr(const shared_ptr& r, element_type* p) noexcept; + constexpr shared_ptr(const shared_ptr& r, element_type* p) noexcept; template - shared_ptr(shared_ptr&& r, element_type* p) noexcept; - shared_ptr(const shared_ptr& r) noexcept; + constexpr shared_ptr(shared_ptr&& r, element_type* p) noexcept; + constexpr shared_ptr(const shared_ptr& r) noexcept; template - shared_ptr(const shared_ptr& r) noexcept; - shared_ptr(shared_ptr&& r) noexcept; + constexpr shared_ptr(const shared_ptr& r) noexcept; + constexpr shared_ptr(shared_ptr&& r) noexcept; template - shared_ptr(shared_ptr&& r) noexcept; + constexpr shared_ptr(shared_ptr&& r) noexcept; template - explicit shared_ptr(const weak_ptr& r); + constexpr explicit shared_ptr(const weak_ptr& r); template - shared_ptr(unique_ptr&& r); + constexpr shared_ptr(unique_ptr&& r); // \ref{util.smartptr.shared.dest}, destructor - ~shared_ptr(); + constexpr ~shared_ptr(); // \ref{util.smartptr.shared.assign}, assignment - shared_ptr& operator=(const shared_ptr& r) noexcept; + constexpr shared_ptr& operator=(const shared_ptr& r) noexcept; template - shared_ptr& operator=(const shared_ptr& r) noexcept; - shared_ptr& operator=(shared_ptr&& r) noexcept; + constexpr shared_ptr& operator=(const shared_ptr& r) noexcept; + constexpr shared_ptr& operator=(shared_ptr&& r) noexcept; template - shared_ptr& operator=(shared_ptr&& r) noexcept; + constexpr shared_ptr& operator=(shared_ptr&& r) noexcept; template - shared_ptr& operator=(unique_ptr&& r); + constexpr shared_ptr& operator=(unique_ptr&& r); // \ref{util.smartptr.shared.mod}, modifiers - void swap(shared_ptr& r) noexcept; - void reset() noexcept; + constexpr void swap(shared_ptr& r) noexcept; + constexpr void reset() noexcept; template - void reset(Y* p); + constexpr void reset(Y* p); template - void reset(Y* p, D d); + constexpr void reset(Y* p, D d); template - void reset(Y* p, D d, A a); + constexpr void reset(Y* p, D d, A a); // \ref{util.smartptr.shared.obs}, observers - element_type* get() const noexcept; - T& operator*() const noexcept; - T* operator->() const noexcept; - element_type& operator[](ptrdiff_t i) const; - long use_count() const noexcept; - explicit operator bool() const noexcept; + constexpr element_type* get() const noexcept; + constexpr T& operator*() const noexcept; + constexpr T* operator->() const noexcept; + constexpr element_type& operator[](ptrdiff_t i) const; + constexpr long use_count() const noexcept; + constexpr explicit operator bool() const noexcept; template bool owner_before(const shared_ptr& b) const noexcept; template bool owner_before(const weak_ptr& b) const noexcept; size_t owner_hash() const noexcept; template - bool owner_equal(const shared_ptr& b) const noexcept; + constexpr bool owner_equal(const shared_ptr& b) const noexcept; template - bool owner_equal(const weak_ptr& b) const noexcept; + constexpr bool owner_equal(const weak_ptr& b) const noexcept; }; template @@ -3331,10 +4004,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}% @@ -3350,7 +4023,7 @@ \indexlibraryctor{shared_ptr}% \begin{itemdecl} -template explicit shared_ptr(Y* p); +template constexpr explicit shared_ptr(Y* p); \end{itemdecl} \begin{itemdescr} @@ -3401,10 +4074,10 @@ \indexlibraryctor{shared_ptr}% \begin{itemdecl} -template shared_ptr(Y* p, D d); -template shared_ptr(Y* p, D d, A a); -template shared_ptr(nullptr_t p, D d); -template shared_ptr(nullptr_t p, D d, A a); +template constexpr shared_ptr(Y* p, D d); +template constexpr shared_ptr(Y* p, D d, A a); +template constexpr shared_ptr(nullptr_t p, D d); +template constexpr shared_ptr(nullptr_t p, D d, A a); \end{itemdecl} \begin{itemdescr} @@ -3456,8 +4129,8 @@ \indexlibraryctor{shared_ptr}% \begin{itemdecl} -template shared_ptr(const shared_ptr& r, element_type* p) noexcept; -template shared_ptr(shared_ptr&& r, element_type* p) noexcept; +template constexpr shared_ptr(const shared_ptr& r, element_type* p) noexcept; +template constexpr shared_ptr(shared_ptr&& r, element_type* p) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3489,8 +4162,8 @@ \indexlibraryctor{shared_ptr}% \begin{itemdecl} -shared_ptr(const shared_ptr& r) noexcept; -template shared_ptr(const shared_ptr& r) noexcept; +constexpr shared_ptr(const shared_ptr& r) noexcept; +template constexpr shared_ptr(const shared_ptr& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3511,8 +4184,8 @@ \indexlibraryctor{shared_ptr}% \begin{itemdecl} -shared_ptr(shared_ptr&& r) noexcept; -template shared_ptr(shared_ptr&& r) noexcept; +constexpr shared_ptr(shared_ptr&& r) noexcept; +template constexpr shared_ptr(shared_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3533,7 +4206,7 @@ \indexlibraryctor{shared_ptr}% \indexlibraryglobal{weak_ptr}% \begin{itemdecl} -template explicit shared_ptr(const weak_ptr& r); +template constexpr explicit shared_ptr(const weak_ptr& r); \end{itemdecl} \begin{itemdescr} @@ -3559,7 +4232,7 @@ \indexlibraryctor{shared_ptr}% \indexlibraryglobal{unique_ptr}% \begin{itemdecl} -template shared_ptr(unique_ptr&& r); +template constexpr shared_ptr(unique_ptr&& r); \end{itemdecl} \begin{itemdescr} @@ -3581,7 +4254,7 @@ \indexlibrarydtor{shared_ptr}% \begin{itemdecl} -~shared_ptr(); +constexpr ~shared_ptr(); \end{itemdecl} \begin{itemdescr} @@ -3615,8 +4288,8 @@ \indexlibrarymember{operator=}{shared_ptr}% \begin{itemdecl} -shared_ptr& operator=(const shared_ptr& r) noexcept; -template shared_ptr& operator=(const shared_ptr& r) noexcept; +constexpr shared_ptr& operator=(const shared_ptr& r) noexcept; +template constexpr shared_ptr& operator=(const shared_ptr& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3647,8 +4320,8 @@ \indexlibrarymember{operator=}{shared_ptr}% \begin{itemdecl} -shared_ptr& operator=(shared_ptr&& r) noexcept; -template shared_ptr& operator=(shared_ptr&& r) noexcept; +constexpr shared_ptr& operator=(shared_ptr&& r) noexcept; +template constexpr shared_ptr& operator=(shared_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3663,7 +4336,7 @@ \indexlibrarymember{operator=}{shared_ptr}% \begin{itemdecl} -template shared_ptr& operator=(unique_ptr&& r); +template constexpr shared_ptr& operator=(unique_ptr&& r); \end{itemdecl} \begin{itemdescr} @@ -3680,7 +4353,7 @@ \indexlibrarymember{swap}{shared_ptr}% \begin{itemdecl} -void swap(shared_ptr& r) noexcept; +constexpr void swap(shared_ptr& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -3692,7 +4365,7 @@ \indexlibrarymember{reset}{shared_ptr}% \begin{itemdecl} -void reset() noexcept; +constexpr void reset() noexcept; \end{itemdecl} \begin{itemdescr} @@ -3703,7 +4376,7 @@ \indexlibrarymember{reset}{shared_ptr}% \begin{itemdecl} -template void reset(Y* p); +template constexpr void reset(Y* p); \end{itemdecl} \begin{itemdescr} @@ -3714,7 +4387,7 @@ \indexlibrarymember{reset}{shared_ptr}% \begin{itemdecl} -template void reset(Y* p, D d); +template constexpr void reset(Y* p, D d); \end{itemdecl} \begin{itemdescr} @@ -3725,7 +4398,7 @@ \indexlibrarymember{reset}{shared_ptr}% \begin{itemdecl} -template void reset(Y* p, D d, A a); +template constexpr void reset(Y* p, D d, A a); \end{itemdecl} \begin{itemdescr} @@ -3737,7 +4410,7 @@ \rSec4[util.smartptr.shared.obs]{Observers} \indexlibrarymember{get}{shared_ptr}% \begin{itemdecl} -element_type* get() const noexcept; +constexpr element_type* get() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3748,7 +4421,7 @@ \indexlibrarymember{operator*}{shared_ptr}% \begin{itemdecl} -T& operator*() const noexcept; +constexpr T& operator*() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3771,7 +4444,7 @@ \indexlibrarymember{operator->}{shared_ptr}% \begin{itemdecl} -T* operator->() const noexcept; +constexpr T* operator->() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3794,14 +4467,17 @@ \indexlibrarymember{operator[]}{shared_ptr}% \begin{itemdecl} -element_type& operator[](ptrdiff_t i) const; +constexpr element_type& operator[](ptrdiff_t i) const; \end{itemdecl} \begin{itemdescr} \pnum \expects -\tcode{get() != nullptr \&\& i >= 0}. -If \tcode{T} is \tcode{U[N]}, \tcode{i < N}. +\tcode{get() != nullptr} is \tcode{true}. + +\pnum +\hardexpects +$\tcode{i} \ge 0$. If \tcode{T} is \tcode{U[N]}, $\tcode{i} < \tcode{N}$. \pnum \returns @@ -3822,7 +4498,7 @@ \indexlibrarymember{use_count}{shared_ptr}% \begin{itemdecl} -long use_count() const noexcept; +constexpr long use_count() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3860,7 +4536,7 @@ \indexlibrarymember{operator bool}{shared_ptr}% \begin{itemdecl} -explicit operator bool() const noexcept; +constexpr explicit operator bool() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3904,9 +4580,9 @@ \indexlibrarymember{owner_equal}{shared_ptr}% \begin{itemdecl} template - bool owner_equal(const shared_ptr& b) const noexcept; + constexpr bool owner_equal(const shared_ptr& b) const noexcept; template - bool owner_equal(const weak_ptr& b) const noexcept; + constexpr bool owner_equal(const weak_ptr& b) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3935,13 +4611,13 @@ \indexlibraryglobal{allocate_shared}% \begin{itemdecl} template - shared_ptr make_shared(@\placeholdernc{args}@); + constexpr shared_ptr make_shared(@\placeholdernc{args}@); template - shared_ptr allocate_shared(const A& a, @\placeholdernc{args}@); + constexpr shared_ptr allocate_shared(const A& a, @\placeholdernc{args}@); template - shared_ptr make_shared_for_overwrite(@\placeholdernc{args}@); + constexpr shared_ptr make_shared_for_overwrite(@\placeholdernc{args}@); template - shared_ptr allocate_shared_for_overwrite(const A& a, @\placeholdernc{args}@); + constexpr shared_ptr allocate_shared_for_overwrite(const A& a, @\placeholdernc{args}@); \end{itemdecl} \begin{itemdescr} @@ -4077,9 +4753,9 @@ \indexlibraryglobal{allocate_shared}% \begin{itemdecl} template - shared_ptr make_shared(Args&&... args); // \tcode{T} is not array + constexpr shared_ptr make_shared(Args&&... args); // \tcode{T} is not array template - shared_ptr allocate_shared(const A& a, Args&&... args); // \tcode{T} is not array + constexpr shared_ptr allocate_shared(const A& a, Args&&... args); // \tcode{T} is not array \end{itemdecl} \begin{itemdescr} @@ -4111,22 +4787,22 @@ \indexlibraryglobal{make_shared}% \indexlibraryglobal{allocate_shared}% \begin{itemdecl} -template shared_ptr - make_shared(size_t N); // \tcode{T} is \tcode{U[]} +template + constexpr shared_ptr make_shared(size_t N); // \tcode{T} is \tcode{U[]} template - shared_ptr allocate_shared(const A& a, size_t N); // \tcode{T} is \tcode{U[]} + constexpr shared_ptr allocate_shared(const A& a, size_t N); // \tcode{T} is \tcode{U[]} \end{itemdecl} \begin{itemdescr} \pnum \constraints -\tcode{T} is of the form \tcode{U[]}. +\tcode{T} is an array of unknown bound. \pnum \returns -A \tcode{shared_ptr} to an object of type \tcode{U[N]} -with a default initial value, -where \tcode{U} is \tcode{remove_extent_t}. +A \tcode{shared_ptr} to an array of +\tcode{N} elements of type \tcode{remove_extent_t} +with a default initial value. \pnum \begin{example} @@ -4143,15 +4819,15 @@ \indexlibraryglobal{allocate_shared}% \begin{itemdecl} template - shared_ptr make_shared(); // \tcode{T} is \tcode{U[N]} + constexpr shared_ptr make_shared(); // \tcode{T} is \tcode{U[N]} template - shared_ptr allocate_shared(const A& a); // \tcode{T} is \tcode{U[N]} + constexpr shared_ptr allocate_shared(const A& a); // \tcode{T} is \tcode{U[N]} \end{itemdecl} \begin{itemdescr} \pnum \constraints -\tcode{T} is of the form \tcode{U[N]}. +\tcode{T} is an array of known bound. \pnum \returns @@ -4173,23 +4849,23 @@ \indexlibraryglobal{allocate_shared}% \begin{itemdecl} template - shared_ptr make_shared(size_t N, - const remove_extent_t& u); // \tcode{T} is \tcode{U[]} + constexpr shared_ptr make_shared(size_t N, + const remove_extent_t& u); // \tcode{T} is \tcode{U[]} template - shared_ptr allocate_shared(const A& a, size_t N, - const remove_extent_t& u); // \tcode{T} is \tcode{U[]} + constexpr shared_ptr allocate_shared(const A& a, size_t N, + const remove_extent_t& u); // \tcode{T} is \tcode{U[]} \end{itemdecl} \begin{itemdescr} \pnum \constraints -\tcode{T} is of the form \tcode{U[]}. +\tcode{T} is an array of unknown bound. \pnum \returns -A \tcode{shared_ptr} to an object of type \tcode{U[N]}, -where \tcode{U} is \tcode{remove_extent_t} and -each array element has an initial value of \tcode{u}. +A \tcode{shared_ptr} to an array of +\tcode{N} elements of type \tcode{remove_extent_t} +where each array element has an initial value of \tcode{u}. \pnum \begin{example} @@ -4208,16 +4884,16 @@ \indexlibraryglobal{allocate_shared}% \begin{itemdecl} template - shared_ptr make_shared(const remove_extent_t& u); // \tcode{T} is \tcode{U[N]} + constexpr shared_ptr make_shared(const remove_extent_t& u); // \tcode{T} is \tcode{U[N]} template - shared_ptr allocate_shared(const A& a, - const remove_extent_t& u); // \tcode{T} is \tcode{U[N]} + constexpr shared_ptr allocate_shared(const A& a, + const remove_extent_t& u); // \tcode{T} is \tcode{U[N]} \end{itemdecl} \begin{itemdescr} \pnum \constraints -\tcode{T} is of the form \tcode{U[N]}. +\tcode{T} is an array of known bound. \pnum \returns @@ -4231,7 +4907,7 @@ shared_ptr p = make_shared(1.0); // \tcode{shared_ptr} to a \tcode{double[1024]}, where each element is \tcode{1.0} shared_ptr q = make_shared({1.0, 0.0}); - // \tcode{shared_ptr} to a \tcode{double[6][2]}, where each double[2] element is \tcode{\{1.0, 0.0\}} + // \tcode{shared_ptr} to a \tcode{double[6][2]}, where each \tcode{double[2]} element is \tcode{\{1.0, 0.0\}} shared_ptr[4]> r = make_shared[4]>({1, 2}); // \tcode{shared_ptr} to a \tcode{vector[4]}, where each vector has contents \tcode{\{1, 2\}} \end{codeblock} @@ -4242,9 +4918,9 @@ \indexlibraryglobal{allocate_shared}% \begin{itemdecl} template - shared_ptr make_shared_for_overwrite(); + constexpr shared_ptr make_shared_for_overwrite(); template - shared_ptr allocate_shared_for_overwrite(const A& a); + constexpr shared_ptr allocate_shared_for_overwrite(const A& a); \end{itemdecl} \begin{itemdescr} @@ -4273,9 +4949,9 @@ \indexlibraryglobal{allocate_shared}% \begin{itemdecl} template - shared_ptr make_shared_for_overwrite(size_t N); + constexpr shared_ptr make_shared_for_overwrite(size_t N); template - shared_ptr allocate_shared_for_overwrite(const A& a, size_t N); + constexpr shared_ptr allocate_shared_for_overwrite(const A& a, size_t N); \end{itemdecl} \begin{itemdescr} @@ -4285,8 +4961,8 @@ \pnum \returns -A \tcode{shared_ptr} to an object of type \tcode{U[N]}, -where \tcode{U} is \tcode{remove_extent_t}. +A \tcode{shared_ptr} to an array of +\tcode{N} elements of type \tcode{remove_extent_t}. \pnum \begin{example} @@ -4302,7 +4978,7 @@ \indexlibrarymember{operator==}{shared_ptr}% \begin{itemdecl} template - bool operator==(const shared_ptr& a, const shared_ptr& b) noexcept; + constexpr bool operator==(const shared_ptr& a, const shared_ptr& b) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4314,7 +4990,7 @@ \indexlibrarymember{operator==}{shared_ptr}% \begin{itemdecl} template - bool operator==(const shared_ptr& a, nullptr_t) noexcept; + constexpr bool operator==(const shared_ptr& a, nullptr_t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4326,7 +5002,7 @@ \indexlibrarymember{operator<=>}{shared_ptr}% \begin{itemdecl} template - strong_ordering operator<=>(const shared_ptr& a, const shared_ptr& b) noexcept; + constexpr strong_ordering operator<=>(const shared_ptr& a, const shared_ptr& b) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4344,7 +5020,7 @@ \indexlibrarymember{operator<=>}{shared_ptr}% \begin{itemdecl} template - strong_ordering operator<=>(const shared_ptr& a, nullptr_t) noexcept; + constexpr strong_ordering operator<=>(const shared_ptr& a, nullptr_t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4360,7 +5036,7 @@ \indexlibrarymember{swap}{shared_ptr}% \begin{itemdecl} template - void swap(shared_ptr& a, shared_ptr& b) noexcept; + constexpr void swap(shared_ptr& a, shared_ptr& b) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4374,9 +5050,9 @@ \indexlibrarymember{static_pointer_cast}{shared_ptr}% \begin{itemdecl} template - shared_ptr static_pointer_cast(const shared_ptr& r) noexcept; + constexpr shared_ptr static_pointer_cast(const shared_ptr& r) noexcept; template - shared_ptr static_pointer_cast(shared_ptr&& r) noexcept; + constexpr shared_ptr static_pointer_cast(shared_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4404,9 +5080,9 @@ \indexlibrarymember{dynamic_pointer_cast}{shared_ptr}% \begin{itemdecl} template - shared_ptr dynamic_pointer_cast(const shared_ptr& r) noexcept; + constexpr shared_ptr dynamic_pointer_cast(const shared_ptr& r) noexcept; template - shared_ptr dynamic_pointer_cast(shared_ptr&& r) noexcept; + constexpr shared_ptr dynamic_pointer_cast(shared_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4441,9 +5117,9 @@ \indexlibrarymember{const_pointer_cast}{shared_ptr}% \begin{itemdecl} template - shared_ptr const_pointer_cast(const shared_ptr& r) noexcept; + constexpr shared_ptr const_pointer_cast(const shared_ptr& r) noexcept; template - shared_ptr const_pointer_cast(shared_ptr&& r) noexcept; + constexpr shared_ptr const_pointer_cast(shared_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4501,7 +5177,7 @@ \indexlibrarymember{get_deleter}{shared_ptr}% \begin{itemdecl} template - D* get_deleter(const shared_ptr& p) noexcept; + constexpr D* get_deleter(const shared_ptr& p) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4558,44 +5234,44 @@ // \ref{util.smartptr.weak.const}, constructors constexpr weak_ptr() noexcept; template - weak_ptr(const shared_ptr& r) noexcept; - weak_ptr(const weak_ptr& r) noexcept; + constexpr weak_ptr(const shared_ptr& r) noexcept; + constexpr weak_ptr(const weak_ptr& r) noexcept; template - weak_ptr(const weak_ptr& r) noexcept; - weak_ptr(weak_ptr&& r) noexcept; + constexpr weak_ptr(const weak_ptr& r) noexcept; + constexpr weak_ptr(weak_ptr&& r) noexcept; template - weak_ptr(weak_ptr&& r) noexcept; + constexpr weak_ptr(weak_ptr&& r) noexcept; // \ref{util.smartptr.weak.dest}, destructor - ~weak_ptr(); + constexpr ~weak_ptr(); // \ref{util.smartptr.weak.assign}, assignment - weak_ptr& operator=(const weak_ptr& r) noexcept; + constexpr weak_ptr& operator=(const weak_ptr& r) noexcept; template - weak_ptr& operator=(const weak_ptr& r) noexcept; + constexpr weak_ptr& operator=(const weak_ptr& r) noexcept; template - weak_ptr& operator=(const shared_ptr& r) noexcept; - weak_ptr& operator=(weak_ptr&& r) noexcept; + constexpr weak_ptr& operator=(const shared_ptr& r) noexcept; + constexpr weak_ptr& operator=(weak_ptr&& r) noexcept; template - weak_ptr& operator=(weak_ptr&& r) noexcept; + constexpr weak_ptr& operator=(weak_ptr&& r) noexcept; // \ref{util.smartptr.weak.mod}, modifiers - void swap(weak_ptr& r) noexcept; - void reset() noexcept; + constexpr void swap(weak_ptr& r) noexcept; + constexpr void reset() noexcept; // \ref{util.smartptr.weak.obs}, observers - long use_count() const noexcept; - bool expired() const noexcept; - shared_ptr lock() const noexcept; + constexpr long use_count() const noexcept; + constexpr bool expired() const noexcept; + constexpr shared_ptr lock() const noexcept; template bool owner_before(const shared_ptr& b) const noexcept; template bool owner_before(const weak_ptr& b) const noexcept; size_t owner_hash() const noexcept; template - bool owner_equal(const shared_ptr& b) const noexcept; + constexpr bool owner_equal(const shared_ptr& b) const noexcept; template - bool owner_equal(const weak_ptr& b) const noexcept; + constexpr bool owner_equal(const weak_ptr& b) const noexcept; }; template @@ -4628,9 +5304,9 @@ \indexlibraryctor{weak_ptr}% \begin{itemdecl} -weak_ptr(const weak_ptr& r) noexcept; -template weak_ptr(const weak_ptr& r) noexcept; -template weak_ptr(const shared_ptr& r) noexcept; +constexpr weak_ptr(const weak_ptr& r) noexcept; +template constexpr weak_ptr(const weak_ptr& r) noexcept; +template constexpr weak_ptr(const shared_ptr& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4653,8 +5329,8 @@ \indexlibraryctor{weak_ptr}% \begin{itemdecl} -weak_ptr(weak_ptr&& r) noexcept; -template weak_ptr(weak_ptr&& r) noexcept; +constexpr weak_ptr(weak_ptr&& r) noexcept; +template constexpr weak_ptr(weak_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4676,7 +5352,7 @@ \indexlibrarydtor{weak_ptr}% \begin{itemdecl} -~weak_ptr(); +constexpr ~weak_ptr(); \end{itemdecl} \begin{itemdescr} @@ -4690,9 +5366,9 @@ \indexlibrarymember{operator=}{weak_ptr}% \begin{itemdecl} -weak_ptr& operator=(const weak_ptr& r) noexcept; -template weak_ptr& operator=(const weak_ptr& r) noexcept; -template weak_ptr& operator=(const shared_ptr& r) noexcept; +constexpr weak_ptr& operator=(const weak_ptr& r) noexcept; +template constexpr weak_ptr& operator=(const weak_ptr& r) noexcept; +template constexpr weak_ptr& operator=(const shared_ptr& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4712,8 +5388,8 @@ \indexlibrarymember{operator=}{weak_ptr}% \begin{itemdecl} -weak_ptr& operator=(weak_ptr&& r) noexcept; -template weak_ptr& operator=(weak_ptr&& r) noexcept; +constexpr weak_ptr& operator=(weak_ptr&& r) noexcept; +template constexpr weak_ptr& operator=(weak_ptr&& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4729,7 +5405,7 @@ \rSec4[util.smartptr.weak.mod]{Modifiers} \indexlibrarymember{swap}{weak_ptr}% \begin{itemdecl} -void swap(weak_ptr& r) noexcept; +constexpr void swap(weak_ptr& r) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4740,7 +5416,7 @@ \indexlibrarymember{reset}{weak_ptr}% \begin{itemdecl} -void reset() noexcept; +constexpr void reset() noexcept; \end{itemdecl} \begin{itemdescr} @@ -4752,7 +5428,7 @@ \rSec4[util.smartptr.weak.obs]{Observers} \indexlibrarymember{use_count}{weak_ptr}% \begin{itemdecl} -long use_count() const noexcept; +constexpr long use_count() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -4765,7 +5441,7 @@ \indexlibrarymember{expired}{weak_ptr}% \begin{itemdecl} -bool expired() const noexcept; +constexpr bool expired() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -4776,7 +5452,7 @@ \indexlibrarymember{lock}{weak_ptr}% \begin{itemdecl} -shared_ptr lock() const noexcept; +constexpr shared_ptr lock() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -4819,9 +5495,9 @@ \indexlibrarymember{owner_equal}{weak_ptr}% \begin{itemdecl} template - bool owner_equal(const shared_ptr& b) const noexcept; + constexpr bool owner_equal(const shared_ptr& b) const noexcept; template - bool owner_equal(const weak_ptr& b) const noexcept; + constexpr bool owner_equal(const weak_ptr& b) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -4841,7 +5517,7 @@ \indexlibrarymember{swap}{weak_ptr}% \begin{itemdecl} template - void swap(weak_ptr& a, weak_ptr& b) noexcept; + constexpr void swap(weak_ptr& a, weak_ptr& b) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4953,13 +5629,13 @@ namespace std { struct owner_equal { template - bool operator()(const shared_ptr&, const shared_ptr&) const noexcept; + constexpr bool operator()(const shared_ptr&, const shared_ptr&) const noexcept; template - bool operator()(const shared_ptr&, const weak_ptr&) const noexcept; + constexpr bool operator()(const shared_ptr&, const weak_ptr&) const noexcept; template - bool operator()(const weak_ptr&, const shared_ptr&) const noexcept; + constexpr bool operator()(const weak_ptr&, const shared_ptr&) const noexcept; template - bool operator()(const weak_ptr&, const weak_ptr&) const noexcept; + constexpr bool operator()(const weak_ptr&, const weak_ptr&) const noexcept; using is_transparent = @\unspec@; }; @@ -4969,13 +5645,13 @@ \indexlibrarymember{operator()}{owner_equal}% \begin{itemdecl} template - bool operator()(const shared_ptr& x, const shared_ptr& y) const noexcept; + constexpr bool operator()(const shared_ptr& x, const shared_ptr& y) const noexcept; template - bool operator()(const shared_ptr& x, const weak_ptr& y) const noexcept; + constexpr bool operator()(const shared_ptr& x, const weak_ptr& y) const noexcept; template - bool operator()(const weak_ptr& x, const shared_ptr& y) const noexcept; + constexpr bool operator()(const weak_ptr& x, const shared_ptr& y) const noexcept; template - bool operator()(const weak_ptr& x, const weak_ptr& y) const noexcept; + constexpr bool operator()(const weak_ptr& x, const weak_ptr& y) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -5017,18 +5693,18 @@ template class enable_shared_from_this { protected: constexpr enable_shared_from_this() noexcept; - enable_shared_from_this(const enable_shared_from_this&) noexcept; - enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept; - ~enable_shared_from_this(); + constexpr enable_shared_from_this(const enable_shared_from_this&) noexcept; + constexpr enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept; + constexpr ~enable_shared_from_this(); public: - shared_ptr shared_from_this(); - shared_ptr shared_from_this() const; - weak_ptr weak_from_this() noexcept; - weak_ptr weak_from_this() const noexcept; + constexpr shared_ptr shared_from_this(); + constexpr shared_ptr shared_from_this() const; + constexpr weak_ptr weak_from_this() noexcept; + constexpr weak_ptr weak_from_this() const noexcept; private: - mutable weak_ptr weak_this; // \expos + mutable weak_ptr @\exposid{weak-this}@; // \expos }; } \end{codeblock} @@ -5040,18 +5716,18 @@ \indexlibraryctor{enable_shared_from_this}% \begin{itemdecl} constexpr enable_shared_from_this() noexcept; -enable_shared_from_this(const enable_shared_from_this&) noexcept; +constexpr enable_shared_from_this(const enable_shared_from_this&) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Value-initializes \tcode{weak_this}. +Value-initializes \exposid{weak-this}. \end{itemdescr} \indexlibrarymember{operator=}{enable_shared_from_this}% \begin{itemdecl} -enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept; +constexpr enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5061,34 +5737,34 @@ \pnum \begin{note} -\tcode{weak_this} is not changed. +\exposid{weak-this} is not changed. \end{note} \end{itemdescr} \indexlibraryglobal{shared_ptr}% \indexlibrarymember{shared_from_this}{enable_shared_from_this}% \begin{itemdecl} -shared_ptr shared_from_this(); -shared_ptr shared_from_this() const; +constexpr shared_ptr shared_from_this(); +constexpr shared_ptr shared_from_this() const; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{shared_ptr(weak_this)}. +\tcode{shared_ptr(\exposid{weak-this})}. \end{itemdescr} \indexlibraryglobal{weak_ptr}% \indexlibrarymember{weak_from_this}{enable_shared_from_this}% \begin{itemdecl} -weak_ptr weak_from_this() noexcept; -weak_ptr weak_from_this() const noexcept; +constexpr weak_ptr weak_from_this() noexcept; +constexpr weak_ptr weak_from_this() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{weak_this}. +\exposid{weak-this}. \end{itemdescr} \rSec2[util.smartptr.hash]{Smart pointer hash support} @@ -5167,12 +5843,12 @@ template class out_ptr_t { public: - explicit out_ptr_t(Smart&, Args...); + constexpr explicit out_ptr_t(Smart&, Args...); out_ptr_t(const out_ptr_t&) = delete; - ~out_ptr_t(); + constexpr ~out_ptr_t(); - operator Pointer*() const noexcept; + constexpr operator Pointer*() const noexcept; operator void**() const noexcept; private: @@ -5206,7 +5882,7 @@ \indexlibraryctor{out_ptr_t}% \begin{itemdecl} -explicit out_ptr_t(Smart& smart, Args... args); +constexpr explicit out_ptr_t(Smart& smart, Args... args); \end{itemdecl} \begin{itemdescr} @@ -5250,7 +5926,7 @@ \indexlibrarydtor{out_ptr_t}% \begin{itemdecl} -~out_ptr_t(); +constexpr ~out_ptr_t(); \end{itemdecl} \begin{itemdescr} @@ -5289,7 +5965,7 @@ \end{itemdescr} \begin{itemdecl} -operator Pointer*() const noexcept; +constexpr operator Pointer*() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -5349,7 +6025,7 @@ \indexlibraryglobal{out_ptr}% \begin{itemdecl} template - auto out_ptr(Smart& s, Args&&... args); + constexpr auto out_ptr(Smart& s, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -5360,7 +6036,7 @@ \pnum \returns -\tcode{out_ptr_t(s, std::forward(args)...)} +\tcode{out_ptr_t(s, std::forward(args)...)}. \end{itemdescr} \rSec3[inout.ptr.t]{Class template \tcode{inout_ptr_t}} @@ -5407,12 +6083,12 @@ template class inout_ptr_t { public: - explicit inout_ptr_t(Smart&, Args...); + constexpr explicit inout_ptr_t(Smart&, Args...); inout_ptr_t(const inout_ptr_t&) = delete; - ~inout_ptr_t(); + constexpr ~inout_ptr_t(); - operator Pointer*() const noexcept; + constexpr operator Pointer*() const noexcept; operator void**() const noexcept; private: @@ -5443,7 +6119,7 @@ \indexlibraryctor{inout_ptr_t}% \begin{itemdecl} -explicit inout_ptr_t(Smart& smart, Args... args); +constexpr explicit inout_ptr_t(Smart& smart, Args... args); \end{itemdecl} \begin{itemdescr} @@ -5472,7 +6148,7 @@ \indexlibrarydtor{inout_ptr_t}% \begin{itemdecl} -~inout_ptr_t(); +constexpr ~inout_ptr_t(); \end{itemdecl} \begin{itemdescr} @@ -5525,7 +6201,7 @@ \end{itemdescr} \begin{itemdecl} -operator Pointer*() const noexcept; +constexpr operator Pointer*() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -5585,7 +6261,7 @@ \indexlibraryglobal{inout_ptr}% \begin{itemdecl} template - auto inout_ptr(Smart& s, Args&&... args); + constexpr auto inout_ptr(Smart& s, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -5598,6 +6274,1563 @@ \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 = allocator_traits::pointer; + using const_pointer = 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.assign}, 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.assign]{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 owned object +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 +If +\tcode{allocator_traits::propagate_on_container_move_assignment::val\-ue} +is \tcode{false} and +\tcode{allocator_traits::is_always_equal::value} is \tcode{false}, +\tcode{is_move_con\-structible_v} 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. + +\item +Otherwise, +if the allocator needs updating or +if \tcode{\exposid{alloc} == other.\exposid{alloc}} is \tcode{true}, +\tcode{*this} takes ownership of the owned object of \tcode{other}. + +\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 the allocator in \tcode{*this}. + +\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(bool(*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(bool(*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 = allocator_traits::pointer; + using const_pointer = 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.assign}, 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{polymorphic}% +\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 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} 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{UU} 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{UU} 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, +calls \tcode{allocator_traits::destroy(p)}, +where \tcode{p} is a pointer of type \tcode{U*} to +the owned object and +\tcode{U} is the type of the owned object; +then the storage is deallocated. +\end{itemdescr} + +\rSec3[polymorphic.assign]{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 of type \tcode{U}, +where \tcode{U} is the type of the owned object in \tcode{other}, +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::propagate_on_container_move_assignment::val\-ue} +is \tcode{false} and +\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{other} is valueless, \tcode{*this} becomes valueless. + +\item +Otherwise, +if the allocator needs updating or +\tcode{\exposid{alloc} == other.\exposid{alloc}} is \tcode{true}, +\tcode{*this} takes ownership of the owned object of \tcode{other}. + +\item +Otherwise, +constructs a new owned object of type \tcode{U}, +where \tcode{U} is the type of the owned object in \tcode{other}, +with the owned object of +\tcode{other} as the argument as an rvalue, +using the allocator in \tcode{*this}. + +\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} @@ -6088,7 +8321,7 @@ \pnum \effects -Construct a \tcode{T} object in the storage +Constructs a \tcode{T} object in the storage whose address is represented by \tcode{p} by uses-allocator construction with allocator \tcode{*this} and constructor arguments \tcode{std::forward(args)...}. @@ -6211,9 +8444,9 @@ \pnum \remarks Calling the \tcode{set_default_resource} and -\tcode{get_default_resource} functions shall not incur a data race. +\tcode{get_default_resource} functions shall not incur a data race\iref{intro.races}. A call to the \tcode{set_default_resource} function -shall synchronize with subsequent calls to +synchronizes with subsequent calls to the \tcode{set_default_resource} and \tcode{get_default_resource} functions. \end{itemdescr} @@ -6293,11 +8526,11 @@ synchronized_pool_resource(const pool_options& opts, memory_resource* upstream); synchronized_pool_resource() - : synchronized_pool_resource(pool_options(), get_default_resource()) {} + : synchronized_pool_resource(pool_options(), get_default_resource()) {} explicit synchronized_pool_resource(memory_resource* upstream) - : synchronized_pool_resource(pool_options(), upstream) {} + : synchronized_pool_resource(pool_options(), upstream) {} explicit synchronized_pool_resource(const pool_options& opts) - : synchronized_pool_resource(opts, get_default_resource()) {} + : synchronized_pool_resource(opts, get_default_resource()) {} synchronized_pool_resource(const synchronized_pool_resource&) = delete; virtual ~synchronized_pool_resource(); @@ -6320,11 +8553,11 @@ unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream); unsynchronized_pool_resource() - : unsynchronized_pool_resource(pool_options(), get_default_resource()) {} + : unsynchronized_pool_resource(pool_options(), get_default_resource()) {} explicit unsynchronized_pool_resource(memory_resource* upstream) - : unsynchronized_pool_resource(pool_options(), upstream) {} + : unsynchronized_pool_resource(pool_options(), upstream) {} explicit unsynchronized_pool_resource(const pool_options& opts) - : unsynchronized_pool_resource(opts, get_default_resource()) {} + : unsynchronized_pool_resource(opts, get_default_resource()) {} unsynchronized_pool_resource(const unsynchronized_pool_resource&) = delete; virtual ~unsynchronized_pool_resource(); @@ -6409,9 +8642,8 @@ The resulting object will hold a copy of \tcode{upstream}, but will not own the resource to which \tcode{upstream} points. \begin{note} -The intention is that calls to \tcode{upstream->allocate()} -will be substantially fewer than calls to \tcode{this->allocate()} -in most cases. +The intention is that in most cases there will be substantially fewer +calls to \tcode{upstream->allocate()} than to \tcode{this->allocate()}. \end{note} The behavior of the pooling mechanism is tuned according to the value of the \tcode{opts} argument. @@ -6802,13 +9034,13 @@ using outer_allocator_type = OuterAlloc; using inner_allocator_type = @\seebelow@; - using value_type = typename OuterTraits::value_type; - using size_type = typename OuterTraits::size_type; - using difference_type = typename OuterTraits::difference_type; - using pointer = typename OuterTraits::pointer; - using const_pointer = typename OuterTraits::const_pointer; - using void_pointer = typename OuterTraits::void_pointer; - using const_void_pointer = typename OuterTraits::const_void_pointer; + using value_type = OuterTraits::value_type; + using size_type = OuterTraits::size_type; + using difference_type = OuterTraits::difference_type; + using pointer = OuterTraits::pointer; + using const_pointer = OuterTraits::const_pointer; + using void_pointer = OuterTraits::void_pointer; + using const_void_pointer = OuterTraits::const_void_pointer; using propagate_on_container_copy_assignment = @\seebelow@; using propagate_on_container_move_assignment = @\seebelow@; diff --git a/source/meta.tex b/source/meta.tex index d6bf2847cb..836ccd95fa 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -8,9 +8,10 @@ These facilities are summarized in \tref{meta.summary}. \begin{libsumtab}{Metaprogramming library summary}{meta.summary} -\ref{intseq} & Integer sequences & \tcode{} \\ \rowsep -\ref{type.traits} & Type traits & \tcode{} \\ \rowsep -\ref{ratio} & Rational arithmetic & \tcode{} \\ +\ref{intseq} & Integer sequences & \tcode{} \\ \rowsep +\ref{type.traits} & Type traits & \tcode{} \\ \rowsep +\ref{meta.reflection} & Reflection & \tcode{} \\ \rowsep +\ref{ratio} & Rational arithmetic & \tcode{} \\ \end{libsumtab} \rSec1[intseq]{Compile-time integer sequences} @@ -59,15 +60,56 @@ \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}. \end{note} \end{itemdescr} +\rSec2[intseq.binding]{Structured binding support} + +\indexlibraryglobal{tuple_size}% +\indexlibraryglobal{tuple_element}% +\begin{itemdecl} +template + struct tuple_size> + : integral_constant { }; + +template + struct tuple_element> { + using type = T; + }; +template + struct tuple_element> { + using type = T; + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +$\tcode{I} < \tcode{sizeof...(Values)}$. +\end{itemdescr} + +\indexlibrarymember{get}{integer_sequence}% +\begin{itemdecl} +template + constexpr T get(integer_sequence) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +$\tcode{I} < \tcode{sizeof...(Values)}$. + +\pnum +\returns +\tcode{Values...[I]}. +\end{itemdescr} + \rSec1[type.traits]{Metaprogramming and type traits} \rSec2[type.traits.general]{General} @@ -126,7 +168,7 @@ modifies a property of a type. It shall be a class template that takes one template type argument and, optionally, additional arguments that help -define the modification. It shall define a publicly accessible nested type +define the modification. It shall declare a publicly accessible nested type named \tcode{type}, which shall be a synonym for the modified type. \pnum @@ -152,7 +194,6 @@ \rSec2[meta.type.synop]{Header \tcode{} synopsis} \indexheader{type_traits}% -% FIXME: Many index entries missing. \begin{codeblock} // all freestanding namespace std { @@ -179,6 +220,7 @@ template struct is_union; template struct is_class; template struct is_function; + template struct is_reflection; // \ref{meta.unary.comp}, composite type categories template struct is_reference; @@ -200,6 +242,7 @@ template struct is_final; template struct is_aggregate; + template struct is_structural; template struct is_signed; template struct is_unsigned; template struct is_bounded_array; @@ -273,6 +316,9 @@ template struct is_nothrow_invocable; template struct is_nothrow_invocable_r; + template struct is_applicable; + template struct is_nothrow_applicable; + // \ref{meta.trans.cv}, const-volatile modifications template struct remove_const; template struct remove_volatile; @@ -282,17 +328,17 @@ template struct add_cv; template - using @\libglobal{remove_const_t}@ = typename remove_const::type; + using @\libglobal{remove_const_t}@ = remove_const::type; template - using @\libglobal{remove_volatile_t}@ = typename remove_volatile::type; + using @\libglobal{remove_volatile_t}@ = remove_volatile::type; template - using @\libglobal{remove_cv_t}@ = typename remove_cv::type; + using @\libglobal{remove_cv_t}@ = remove_cv::type; template - using @\libglobal{add_const_t}@ = typename add_const::type; + using @\libglobal{add_const_t}@ = add_const::type; template - using @\libglobal{add_volatile_t}@ = typename add_volatile::type; + using @\libglobal{add_volatile_t}@ = add_volatile::type; template - using @\libglobal{add_cv_t}@ = typename add_cv::type; + using @\libglobal{add_cv_t}@ = add_cv::type; // \ref{meta.trans.ref}, reference modifications template struct remove_reference; @@ -300,38 +346,38 @@ template struct add_rvalue_reference; template - using @\libglobal{remove_reference_t}@ = typename remove_reference::type; + using @\libglobal{remove_reference_t}@ = remove_reference::type; template - using @\libglobal{add_lvalue_reference_t}@ = typename add_lvalue_reference::type; + using @\libglobal{add_lvalue_reference_t}@ = add_lvalue_reference::type; template - using @\libglobal{add_rvalue_reference_t}@ = typename add_rvalue_reference::type; + using @\libglobal{add_rvalue_reference_t}@ = add_rvalue_reference::type; // \ref{meta.trans.sign}, sign modifications template struct make_signed; template struct make_unsigned; template - using @\libglobal{make_signed_t}@ = typename make_signed::type; + using @\libglobal{make_signed_t}@ = make_signed::type; template - using @\libglobal{make_unsigned_t}@ = typename make_unsigned::type; + using @\libglobal{make_unsigned_t}@ = make_unsigned::type; // \ref{meta.trans.arr}, array modifications template struct remove_extent; template struct remove_all_extents; template - using @\libglobal{remove_extent_t}@ = typename remove_extent::type; + using @\libglobal{remove_extent_t}@ = remove_extent::type; template - using @\libglobal{remove_all_extents_t}@ = typename remove_all_extents::type; + using @\libglobal{remove_all_extents_t}@ = remove_all_extents::type; // \ref{meta.trans.ptr}, pointer modifications template struct remove_pointer; template struct add_pointer; template - using @\libglobal{remove_pointer_t}@ = typename remove_pointer::type; + using @\libglobal{remove_pointer_t}@ = remove_pointer::type; template - using @\libglobal{add_pointer_t}@ = typename add_pointer::type; + using @\libglobal{add_pointer_t}@ = add_pointer::type; // \ref{meta.trans.other}, other transformations template struct type_identity; @@ -345,31 +391,34 @@ template struct common_reference; template struct underlying_type; template struct invoke_result; + template struct apply_result; template struct unwrap_reference; template struct unwrap_ref_decay; template - using @\libglobal{type_identity_t}@ = typename type_identity::type; + using @\libglobal{type_identity_t}@ = type_identity::type; template - using @\libglobal{remove_cvref_t}@ = typename remove_cvref::type; + using @\libglobal{remove_cvref_t}@ = remove_cvref::type; template - using @\libglobal{decay_t}@ = typename decay::type; + using @\libglobal{decay_t}@ = decay::type; template - using @\libglobal{enable_if_t}@ = typename enable_if::type; + using @\libglobal{enable_if_t}@ = enable_if::type; template - using @\libglobal{conditional_t}@ = typename conditional::type; + using @\libglobal{conditional_t}@ = conditional::type; template - using @\libglobal{common_type_t}@ = typename common_type::type; + using @\libglobal{common_type_t}@ = common_type::type; template - using @\libglobal{common_reference_t}@ = typename common_reference::type; + using @\libglobal{common_reference_t}@ = common_reference::type; template - using @\libglobal{underlying_type_t}@ = typename underlying_type::type; + using @\libglobal{underlying_type_t}@ = underlying_type::type; template - using @\libglobal{invoke_result_t}@ = typename invoke_result::type; + using @\libglobal{invoke_result_t}@ = invoke_result::type; + template + using @\libglobal{apply_result_t}@ = apply_result::type; template - using unwrap_reference_t = typename unwrap_reference::type; + using @\libglobal{unwrap_reference_t}@ = unwrap_reference::type; template - using unwrap_ref_decay_t = typename unwrap_ref_decay::type; + using @\libglobal{unwrap_ref_decay_t}@ = unwrap_ref_decay::type; template using @\libglobal{void_t}@ = void; @@ -407,6 +456,8 @@ constexpr bool @\libglobal{is_class_v}@ = is_class::value; template constexpr bool @\libglobal{is_function_v}@ = is_function::value; + template + constexpr bool @\libglobal{is_reflection_v}@ = is_reflection::value; // \ref{meta.unary.comp}, composite type categories template @@ -443,6 +494,8 @@ constexpr bool @\libglobal{is_final_v}@ = is_final::value; template constexpr bool @\libglobal{is_aggregate_v}@ = is_aggregate::value; + template + constexpr bool @\libglobal{is_structural_v}@ = is_structural::value; template constexpr bool @\libglobal{is_signed_v}@ = is_signed::value; template @@ -474,39 +527,31 @@ template constexpr bool @\libglobal{is_destructible_v}@ = is_destructible::value; template - constexpr bool is_trivially_constructible_v - = is_trivially_constructible::value; + constexpr bool @\libglobal{is_trivially_constructible_v}@ = is_trivially_constructible::value; template - constexpr bool is_trivially_default_constructible_v + constexpr bool @\libglobal{is_trivially_default_constructible_v}@ = is_trivially_default_constructible::value; template - constexpr bool is_trivially_copy_constructible_v - = is_trivially_copy_constructible::value; + constexpr bool @\libglobal{is_trivially_copy_constructible_v}@ = is_trivially_copy_constructible::value; template - constexpr bool is_trivially_move_constructible_v - = is_trivially_move_constructible::value; + constexpr bool @\libglobal{is_trivially_move_constructible_v}@ = is_trivially_move_constructible::value; template constexpr bool @\libglobal{is_trivially_assignable_v}@ = is_trivially_assignable::value; template - constexpr bool is_trivially_copy_assignable_v - = is_trivially_copy_assignable::value; + constexpr bool @\libglobal{is_trivially_copy_assignable_v}@ = is_trivially_copy_assignable::value; template - constexpr bool is_trivially_move_assignable_v - = is_trivially_move_assignable::value; + constexpr bool @\libglobal{is_trivially_move_assignable_v}@ = is_trivially_move_assignable::value; template constexpr bool @\libglobal{is_trivially_destructible_v}@ = is_trivially_destructible::value; template - constexpr bool is_nothrow_constructible_v - = is_nothrow_constructible::value; + constexpr bool @\libglobal{is_nothrow_constructible_v}@ = is_nothrow_constructible::value; template - constexpr bool is_nothrow_default_constructible_v + constexpr bool @\libglobal{is_nothrow_default_constructible_v}@ = is_nothrow_default_constructible::value; template - constexpr bool is_nothrow_copy_constructible_v - = is_nothrow_copy_constructible::value; + constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible::value; template - constexpr bool is_nothrow_move_constructible_v - = is_nothrow_move_constructible::value; + constexpr bool @\libglobal{is_nothrow_move_constructible_v}@ = is_nothrow_move_constructible::value; template constexpr bool @\libglobal{is_nothrow_assignable_v}@ = is_nothrow_assignable::value; template @@ -524,7 +569,7 @@ template constexpr bool @\libglobal{has_virtual_destructor_v}@ = has_virtual_destructor::value; template - constexpr bool has_unique_object_representations_v + constexpr bool @\libglobal{has_unique_object_representations_v}@ = has_unique_object_representations::value; template constexpr bool @\libglobal{reference_constructs_from_temporary_v}@ @@ -555,7 +600,7 @@ template constexpr bool @\libglobal{is_layout_compatible_v}@ = is_layout_compatible::value; template - constexpr bool is_pointer_interconvertible_base_of_v + constexpr bool @\libglobal{is_pointer_interconvertible_base_of_v}@ = is_pointer_interconvertible_base_of::value; template constexpr bool @\libglobal{is_invocable_v}@ = is_invocable::value; @@ -564,8 +609,11 @@ template constexpr bool @\libglobal{is_nothrow_invocable_v}@ = is_nothrow_invocable::value; template - constexpr bool is_nothrow_invocable_r_v - = is_nothrow_invocable_r::value; + constexpr bool @\libglobal{is_nothrow_invocable_r_v}@ = is_nothrow_invocable_r::value; + template + constexpr bool @\libglobal{is_applicable_v}@ = is_applicable::value; + template + constexpr bool @\libglobal{is_nothrow_applicable_v}@ = is_nothrow_applicable::value; // \ref{meta.logical}, logical operator traits template @@ -583,7 +631,8 @@ // \ref{meta.const.eval}, constant evaluation context constexpr bool is_constant_evaluated() noexcept; - consteval bool is_within_lifetime(const auto*) noexcept; + template + consteval bool is_within_lifetime(const T*) noexcept; } \end{codeblock} @@ -714,7 +763,11 @@ \indexlibraryglobal{is_function}% \tcode{template}\br \tcode{struct is_function;} & -\tcode{T} is a function type\iref{basic.compound} & \\ +\tcode{T} is a function type\iref{basic.compound} & \\ \rowsep +\indexlibraryglobal{is_reflection}% +\tcode{template}\br + \tcode{struct is_reflection;} & +\tcode{T} is \tcode{std::meta::info}\iref{basic.fundamental} & \\ \end{libreqtab3e} \rSec3[meta.unary.comp]{Composite type traits} @@ -867,7 +920,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 @@ -882,6 +935,12 @@ \tcode{T} is an aggregate type\iref{dcl.init.aggr} & \tcode{T} shall be an array type, a complete type, or \cv~\keyword{void}. \\ \rowsep +\indexlibraryglobal{is_structural}% +\tcode{template}\br + \tcode{struct is_structural;} & + \tcode{T} is a structural type\iref{temp.param} & + \tcode{remove_all_extents_t} shall be a complete type or \cv~\keyword{void}. \\ \rowsep + \indexlibrary{\idxcode{is_signed}!class}% \tcode{template}\br \tcode{struct is_signed;} & @@ -1227,6 +1286,8 @@ the initialization \tcode{T t(\exposidnc{VAL});} is well-formed and binds \tcode{t} to a temporary object whose lifetime is extended\iref{class.temporary}. + The full-expression of the variable initialization is + treated as an unevaluated operand\iref{expr.context}. Access checking is performed as if in a context unrelated to \tcode{T} and \tcode{U}. Only the validity of the immediate context of @@ -1250,6 +1311,8 @@ the initialization \tcode{T t = \exposidnc{VAL};} is well-formed and binds \tcode{t} to a temporary object whose lifetime is extended\iref{class.temporary}. + The full-expression of the variable initialization is + treated as an unevaluated operand\iref{expr.context}. Access checking is performed as if in a context unrelated to \tcode{T} and \tcode{U}. Only the validity of the immediate context of @@ -1318,6 +1381,8 @@ \begin{note} These tokens are never interpreted as a function declaration. \end{note} +The full-expression of the variable initialization is +treated as an unevaluated operand\iref{expr.context}. Access checking is performed as if in a context unrelated to \tcode{T} and any of the \tcode{Args}. Only the validity of the immediate context of the variable initialization is considered. @@ -1433,6 +1498,13 @@ \tcode{true_type} if the corresponding condition is true, otherwise \tcode{false_type}. +\pnum +Let \tcode{\placeholdernc{ELEMS-OF}(T)} be the parameter pack +\tcode{get<\exposid{N}>(declval())}, where \exposid{N} is the pack of +\tcode{size_t} template arguments of the specialization of +\tcode{index_sequence} denoted by +\tcode{make_index_sequence>>}. + \begin{libreqtab3f}{Type relationship predicates}{meta.rel} \\ \topline \lhdr{Template} & \chdr{Condition} & \rhdr{Comments} \\ \capsep @@ -1555,6 +1627,27 @@ is known not to throw any exceptions\iref{expr.unary.noexcept} & \tcode{Fn}, \tcode{R}, and all types in the template parameter pack \tcode{ArgTypes} shall be complete types, \cv{}~\keyword{void}, or + arrays of unknown bound. \\ \rowsep + +\indexlibraryglobal{is_applicable}% +\tcode{template}\br + \tcode{struct is_applicable;} & + \tcode{\exposconcept{tuple-like}} is \tcode{true} and + the expression + \tcode{\placeholdernc{INVOKE}(declval(), \placeholdernc{ELEMS-OF}(Tuple)...)} + is well-formed when treated as an unevaluated operand. & + \tcode{Fn} and \tcode{Tuple} + shall be complete types, \cv{}~\keyword{void}, or + arrays of unknown bound. \\ \rowsep + +\indexlibraryglobal{is_nothrow_applicable}% +\tcode{template}\br + \tcode{struct is_nothrow_applicable;} & + \tcode{is_applicable_v<}\br\tcode{Fn, Tuple>} is \tcode{true} and + the expression \tcode{\placeholdernc{INVOKE}(declval(), \placeholdernc{ELEMS-OF}(Tuple)...)} + is known not to throw any exceptions\iref{expr.unary.noexcept}. & + \tcode{Fn} and \tcode{Tuple} + shall be complete types, \cv{}~\keyword{void}, or arrays of unknown bound. \\ \end{libreqtab3f} @@ -1588,7 +1681,8 @@ \indexlibraryglobal{is_convertible}% \pnum The predicate condition for a template specialization \tcode{is_convertible} -shall be satisfied if and only if the return expression in the following code would be +shall be satisfied if and only if +the return statement\iref{stmt.return} in the following code would be well-formed, including any implicit conversions to the return type of the function: \begin{codeblock} @@ -1602,9 +1696,11 @@ array types, function types, and \cv{}~\keyword{void}. \end{note} Access checking is performed -in a context unrelated to \tcode{To} and \tcode{From}. Only the validity of -the immediate context of the \grammarterm{expression} of the \tcode{return} statement\iref{stmt.return} -(including initialization of the returned object or reference) is considered. +in a context unrelated to \tcode{To} and \tcode{From}. +The operand of the \tcode{return} statement +(including initialization of the returned object or reference, if any) +is treated as an unevaluated operand\iref{expr.context}, and +only the validity of its immediate context is considered. \begin{note} The initialization can result in side effects such as the @@ -1679,16 +1775,22 @@ \indexlibraryglobal{add_const}% \tcode{template\br struct add_const;} & - If \tcode{T} is a reference, function, or top-level const-qualified - type, then \tcode{type} denotes \tcode{T}, otherwise - \tcode{T const}. \\ \rowsep + The member typedef \tcode{type} denotes \tcode{const T}. +\begin{tailnote} +\keyword{const} has no effect when \tcode{T} is a reference, function, or +top-level const-qualified type. +\end{tailnote} +\\ \rowsep \indexlibraryglobal{add_volatile}% \tcode{template\br struct add_volatile;} & - If \tcode{T} is a reference, function, or top-level volatile-qualified - type, then \tcode{type} denotes \tcode{T}, otherwise - \tcode{T volatile}. \\ \rowsep + The member typedef \tcode{type} denotes \tcode{volatile T}. +\begin{tailnote} +\keyword{volatile} has no effect when \tcode{T} is a reference, function, or +top-level volatile-qualified type. +\end{tailnote} +\\ \rowsep \indexlibraryglobal{add_cv}% \tcode{template\br @@ -1939,7 +2041,7 @@ \tcode{template} \tcode{struct common_type;} & Unless this trait is specialized, - the member \tcode{type} is defined or omitted as specified below. + the member \tcode{type} is declared 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 @@ -1955,7 +2057,7 @@ \tcode{template} \tcode{struct \libglobal{common_reference};} & - The member \grammarterm{typedef-name} \tcode{type} is defined or omitted + The member \grammarterm{typedef-name} \tcode{type} is declared or omitted as specified below. Each type in the parameter pack \tcode{T} shall be complete or \cv{} \keyword{void}. \\ \rowsep @@ -1990,6 +2092,32 @@ are complete types, \cv{}~\keyword{void}, or arrays of unknown bound.\\ \rowsep +\tcode{template}\br + \tcode{struct \libglobal{apply_result};} + & + If \tcode{\exposconcept{tuple-like}} is \tcode{true} + and the expression + \tcode{\placeholdernc{INVOKE}(declval(), \placeholdernc{ELEMS-OF}(Tuple)...)}\iref{func.require} + is well-formed + when treated as an unevaluated operand\iref{term.unevaluated.operand}, + the member typedef \tcode{type} denotes the type + \tcode{decltype(\placeholdernc{INVOKE}(declval(), \placeholdernc{ELEMS-OF}(Tuple)...))}; + otherwise, there shall be no member \tcode{type}. + Access checking is performed as if in a context unrelated to \tcode{Fn} + and \tcode{Tuple}. + Only the validity of the immediate context of the expression is considered. + \begin{note} + The compilation of the expression can result in side effects + such as the instantiation of class template specializations + and function template specializations, + the generation of implicitly-defined functions, and so on. + Such side effects are not in the ``immediate context'' + and can result in the program being ill-formed. + \end{note} + \expects + \tcode{Fn} and \tcode{Tuple} are complete types, \cv{}~\keyword{void}, + or arrays of unknown bound.\\ \rowsep + \tcode{template} \tcode{struct \libglobal{unwrap_reference};} & If \tcode{T} is @@ -2065,7 +2193,7 @@ \pnum 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: +the member \tcode{type} shall be either declared or not present as follows: \begin{itemize} \item If \tcode{sizeof...(T)} is zero, there shall be no member \tcode{type}. @@ -2117,7 +2245,7 @@ \end{itemize} \pnum -Notwithstanding the provisions of \ref{meta.type.synop}, and +Notwithstanding the provisions of \ref{meta.rqmts}, and pursuant to \ref{namespace.std}, a program may specialize \tcode{common_type} for types \tcode{T1} and \tcode{T2} such that @@ -2138,7 +2266,7 @@ \pnum 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 +\tcode{T} of types, the member \tcode{type} shall be either declared or not present as follows: \begin{itemize} \item If \tcode{sizeof...(T)} is zero, there shall be no member \tcode{type}. @@ -2183,7 +2311,7 @@ \end{itemize} \pnum -Notwithstanding the provisions of \ref{meta.type.synop}, and +Notwithstanding the provisions of \ref{meta.rqmts}, and pursuant to \ref{namespace.std}, a program may partially specialize \tcode{basic_common_reference} for types \tcode{T} and \tcode{U} such that @@ -2208,7 +2336,7 @@ \pnum \begin{example} -Given these definitions: +Given these declarations: \begin{codeblock} using PF1 = bool (&)(); using PF2 = short (*)(long); @@ -2415,15 +2543,15 @@ static_assert( is_pointer_interconvertible_with_class( &C::b ) ); // Succeeds because, despite its appearance, \tcode{\&C::b} has type // ``pointer to member of \tcode{B} of type \tcode{int}''. -static_assert( is_pointer_interconvertible_with_class( &C::b ) ); - // Forces the use of class \tcode{C}, and fails. +static_assert( !is_pointer_interconvertible_with_class( &C::b ) ); + // Forces the use of class \tcode{C}, and the result is \tcode{false}. static_assert( is_corresponding_member( &C::a, &C::b ) ); // Succeeds because, despite its appearance, \tcode{\&C::a} and \tcode{\&C::b} have types // ``pointer to member of \tcode{A} of type \tcode{int}'' and // ``pointer to member of \tcode{B} of type \tcode{int}'', respectively. -static_assert( is_corresponding_member( &C::a, &C::b ) ); - // Forces the use of class \tcode{C}, and fails. +static_assert( !is_corresponding_member( &C::a, &C::b ) ); + // Forces the use of class \tcode{C}, and the result is \tcode{false}. \end{codeblock} \end{example} \end{note} @@ -2463,14 +2591,21 @@ \indexlibraryglobal{is_within_lifetime}% \begin{itemdecl} -consteval bool is_within_lifetime(const auto* p) noexcept; +template + consteval bool is_within_lifetime(const T* p) noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +\tcode{static_cast(p)} is well-formed. + \pnum \returns \tcode{true} if \tcode{p} is a pointer to an object that is -within its lifetime\iref{basic.life}; otherwise, \tcode{false}. +within its lifetime\iref{basic.life} and +\tcode{static_cast(p)} is a constant subexpression; +otherwise, \tcode{false}. \pnum \remarks @@ -2515,6 +2650,4426 @@ \end{example} \end{itemdescr} +\rSec1[meta.reflection]{Reflection} + +\rSec2[meta.syn]{Header \tcode{} synopsis} + +\indexheader{meta}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{meta.string.literal}, checking string literals + consteval bool is_string_literal(const char* p); + consteval bool is_string_literal(const wchar_t* p); + consteval bool is_string_literal(const char8_t* p); + consteval bool is_string_literal(const char16_t* p); + consteval bool is_string_literal(const char32_t* p); + + // \ref{meta.define.static}, promoting to static storage + namespace meta { + template + consteval info reflect_constant_string(R&& r); + template + consteval info reflect_constant_array(R&& r); + } + template + consteval const ranges::range_value_t* define_static_string(R&& r); + template + consteval span, @\seebelow@> define_static_array(R&& r); + template + consteval const remove_cvref_t* define_static_object(T&& r); +} + +namespace std::meta { + using info = decltype(^^::); + + // \ref{meta.reflection.exception}, class \tcode{exception} + class exception; + + // \ref{meta.reflection.operators}, operator representations + enum class operators { + @\seebelow@; + }; + using enum operators; + consteval operators operator_of(info r); + consteval string_view symbol_of(operators op); + consteval u8string_view u8symbol_of(operators op); + + // \ref{meta.reflection.names}, reflection names and locations + consteval bool has_identifier(info r); + + consteval string_view identifier_of(info r); + consteval u8string_view u8identifier_of(info r); + + consteval string_view display_string_of(info r); + consteval u8string_view u8display_string_of(info r); + + consteval source_location source_location_of(info r); + + // \ref{meta.reflection.queries}, reflection queries + consteval info type_of(info r); + consteval info object_of(info r); + consteval info constant_of(info r); + + consteval bool is_public(info r); + consteval bool is_protected(info r); + consteval bool is_private(info r); + + consteval bool is_virtual(info r); + consteval bool is_pure_virtual(info r); + consteval bool is_override(info r); + consteval bool is_final(info r); + + consteval bool is_deleted(info r); + consteval bool is_defaulted(info r); + consteval bool is_user_provided(info r); + consteval bool is_user_declared(info r); + consteval bool is_explicit(info r); + consteval bool is_noexcept(info r); + + consteval bool is_bit_field(info r); + consteval bool is_enumerator(info r); + consteval bool is_annotation(info r); + + consteval bool is_const(info r); + consteval bool is_volatile(info r); + consteval bool is_mutable_member(info r); + consteval bool is_lvalue_reference_qualified(info r); + consteval bool is_rvalue_reference_qualified(info r); + + consteval bool has_static_storage_duration(info r); + consteval bool has_thread_storage_duration(info r); + consteval bool has_automatic_storage_duration(info r); + + consteval bool has_internal_linkage(info r); + consteval bool has_module_linkage(info r); + consteval bool has_external_linkage(info r); + consteval bool has_c_language_linkage(info r); + consteval bool has_linkage(info r); + + consteval bool is_complete_type(info r); + consteval bool is_enumerable_type(info r); + + consteval bool is_variable(info r); + consteval bool is_type(info r); + consteval bool is_namespace(info r); + consteval bool is_type_alias(info r); + consteval bool is_namespace_alias(info r); + + consteval bool is_function(info r); + consteval bool is_conversion_function(info r); + consteval bool is_operator_function(info r); + consteval bool is_literal_operator(info r); + consteval bool is_special_member_function(info r); + consteval bool is_constructor(info r); + consteval bool is_default_constructor(info r); + consteval bool is_copy_constructor(info r); + consteval bool is_move_constructor(info r); + consteval bool is_assignment(info r); + consteval bool is_copy_assignment(info r); + consteval bool is_move_assignment(info r); + consteval bool is_destructor(info r); + + consteval bool is_function_parameter(info r); + consteval bool is_explicit_object_parameter(info r); + consteval bool has_default_argument(info r); + consteval bool is_vararg_function(info r); + + consteval bool is_template(info r); + consteval bool is_function_template(info r); + consteval bool is_variable_template(info r); + consteval bool is_class_template(info r); + consteval bool is_alias_template(info r); + consteval bool is_conversion_function_template(info r); + consteval bool is_operator_function_template(info r); + consteval bool is_literal_operator_template(info r); + consteval bool is_constructor_template(info r); + consteval bool is_concept(info r); + + consteval bool is_value(info r); + consteval bool is_object(info r); + + consteval bool is_structured_binding(info r); + + consteval bool is_class_member(info r); + consteval bool is_namespace_member(info r); + consteval bool is_nonstatic_data_member(info r); + consteval bool is_static_member(info r); + consteval bool is_base(info r); + + consteval bool has_default_member_initializer(info r); + + consteval bool has_parent(info r); + consteval info parent_of(info r); + + consteval info dealias(info r); + + consteval bool has_template_arguments(info r); + consteval info template_of(info r); + consteval vector template_arguments_of(info r); + consteval vector parameters_of(info r); + consteval info variable_of(info r); + consteval info return_type_of(info r); + + // \ref{meta.reflection.access.context}, access control context + struct access_context; + + // \ref{meta.reflection.access.queries}, member accessibility queries + consteval bool is_accessible(info r, access_context ctx); + consteval bool has_inaccessible_nonstatic_data_members(info r, access_context ctx); + consteval bool has_inaccessible_bases(info r, access_context ctx); + consteval bool has_inaccessible_subobjects(info r, access_context ctx); + + // \ref{meta.reflection.scope}, scope identification + consteval info current_function(); + consteval info current_class(); + consteval info current_namespace(); + + // \ref{meta.reflection.member.queries}, reflection member queries + consteval vector members_of(info r, access_context ctx); + consteval vector bases_of(info type, access_context ctx); + consteval vector static_data_members_of(info type, access_context ctx); + consteval vector nonstatic_data_members_of(info type, access_context ctx); + consteval vector subobjects_of(info type, access_context ctx); + consteval vector enumerators_of(info type_enum); + + // \ref{meta.reflection.layout}, reflection layout queries + struct member_offset; + consteval member_offset offset_of(info r); + consteval size_t size_of(info r); + consteval size_t alignment_of(info r); + consteval size_t bit_size_of(info r); + + // \ref{meta.reflection.annotation}, annotation reflection + consteval vector annotations_of(info item); + consteval vector annotations_of_with_type(info item, info type); + + // \ref{meta.reflection.extract}, value extraction + template + consteval T extract(info r); + + // \ref{meta.reflection.substitute}, reflection substitution + template + concept reflection_range = @\seebelow@; + + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval bool can_substitute(info templ, R&& arguments); + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval info substitute(info templ, R&& arguments); + + // \ref{meta.reflection.result}, expression result reflection + template + consteval info reflect_constant(T expr); + template + consteval info reflect_object(T& expr); + template + consteval info reflect_function(T& fn); + + // \ref{meta.reflection.define.aggregate}, class definition generation + struct data_member_options; + consteval info data_member_spec(info type, data_member_options options); + consteval bool is_data_member_spec(info r); + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval info define_aggregate(info type_class, R&& mdescrs); + + // associated with \ref{meta.unary.cat}, primary type categories + consteval bool is_void_type(info type); + consteval bool is_null_pointer_type(info type); + consteval bool is_integral_type(info type); + consteval bool is_floating_point_type(info type); + consteval bool is_array_type(info type); + consteval bool is_pointer_type(info type); + consteval bool is_lvalue_reference_type(info type); + consteval bool is_rvalue_reference_type(info type); + consteval bool is_member_object_pointer_type(info type); + consteval bool is_member_function_pointer_type(info type); + consteval bool is_enum_type(info type); + consteval bool is_union_type(info type); + consteval bool is_class_type(info type); + consteval bool is_function_type(info type); + consteval bool is_reflection_type(info type); + + // associated with \ref{meta.unary.comp}, composite type categories + consteval bool is_reference_type(info type); + consteval bool is_arithmetic_type(info type); + consteval bool is_fundamental_type(info type); + consteval bool is_object_type(info type); + consteval bool is_scalar_type(info type); + consteval bool is_compound_type(info type); + consteval bool is_member_pointer_type(info type); + + // associated with \ref{meta.unary.prop}, type properties + consteval bool is_const_type(info type); + consteval bool is_volatile_type(info type); + consteval bool is_trivially_copyable_type(info type); + consteval bool is_standard_layout_type(info type); + consteval bool is_empty_type(info type); + consteval bool is_polymorphic_type(info type); + consteval bool is_abstract_type(info type); + consteval bool is_final_type(info type); + consteval bool is_aggregate_type(info type); + consteval bool is_structural_type(info type); + consteval bool is_signed_type(info type); + consteval bool is_unsigned_type(info type); + consteval bool is_bounded_array_type(info type); + consteval bool is_unbounded_array_type(info type); + consteval bool is_scoped_enum_type(info type); + + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval bool is_constructible_type(info type, R&& type_args); + consteval bool is_default_constructible_type(info type); + consteval bool is_copy_constructible_type(info type); + consteval bool is_move_constructible_type(info type); + + consteval bool is_assignable_type(info type_dst, info type_src); + consteval bool is_copy_assignable_type(info type); + consteval bool is_move_assignable_type(info type); + + consteval bool is_swappable_with_type(info type1, info type2); + consteval bool is_swappable_type(info type); + + consteval bool is_destructible_type(info type); + + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval bool is_trivially_constructible_type(info type, R&& type_args); + consteval bool is_trivially_default_constructible_type(info type); + consteval bool is_trivially_copy_constructible_type(info type); + consteval bool is_trivially_move_constructible_type(info type); + + consteval bool is_trivially_assignable_type(info type_dst, info type_src); + consteval bool is_trivially_copy_assignable_type(info type); + consteval bool is_trivially_move_assignable_type(info type); + consteval bool is_trivially_destructible_type(info type); + + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval bool is_nothrow_constructible_type(info type, R&& type_args); + consteval bool is_nothrow_default_constructible_type(info type); + consteval bool is_nothrow_copy_constructible_type(info type); + consteval bool is_nothrow_move_constructible_type(info type); + + consteval bool is_nothrow_assignable_type(info type_dst, info type_src); + consteval bool is_nothrow_copy_assignable_type(info type); + consteval bool is_nothrow_move_assignable_type(info type); + + consteval bool is_nothrow_swappable_with_type(info type1, info type2); + consteval bool is_nothrow_swappable_type(info type); + + consteval bool is_nothrow_destructible_type(info type); + + consteval bool is_implicit_lifetime_type(info type); + + consteval bool has_virtual_destructor(info type); + + consteval bool has_unique_object_representations(info type); + + consteval bool reference_constructs_from_temporary(info type_dst, info type_src); + consteval bool reference_converts_from_temporary(info type_dst, info type_src); + + // associated with \ref{meta.unary.prop.query}, type property queries + consteval size_t rank(info type); + consteval size_t extent(info type, unsigned i = 0); + + // associated with \ref{meta.rel}, type relations + consteval bool is_same_type(info type1, info type2); + consteval bool is_base_of_type(info type_base, info type_derived); + consteval bool is_virtual_base_of_type(info type_base, info type_derived); + consteval bool is_convertible_type(info type_src, info type_dst); + consteval bool is_nothrow_convertible_type(info type_src, info type_dst); + consteval bool is_layout_compatible_type(info type1, info type2); + consteval bool is_pointer_interconvertible_base_of_type(info type_base, info type_derived); + + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval bool is_invocable_type(info type, R&& type_args); + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval bool is_invocable_r_type(info type_result, info type, R&& type_args); + + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval bool is_nothrow_invocable_type(info type, R&& type_args); + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval bool is_nothrow_invocable_r_type(info type_result, info type, R&& type_args); + + // associated with \ref{meta.trans.cv}, const-volatile modifications + consteval info remove_const(info type); + consteval info remove_volatile(info type); + consteval info remove_cv(info type); + consteval info add_const(info type); + consteval info add_volatile(info type); + consteval info add_cv(info type); + + // associated with \ref{meta.trans.ref}, reference modifications + consteval info remove_reference(info type); + consteval info add_lvalue_reference(info type); + consteval info add_rvalue_reference(info type); + + // associated with \ref{meta.trans.sign}, sign modifications + consteval info make_signed(info type); + consteval info make_unsigned(info type); + + // associated with \ref{meta.trans.arr}, array modifications + consteval info remove_extent(info type); + consteval info remove_all_extents(info type); + + // associated with \ref{meta.trans.ptr}, pointer modifications + consteval info remove_pointer(info type); + consteval info add_pointer(info type); + + // associated with \ref{meta.trans.other}, other transformations + consteval info remove_cvref(info type); + consteval info decay(info type); + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval info common_type(R&& type_args); + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval info common_reference(R&& type_args); + consteval info underlying_type(info type); + template<@\libconcept{reflection_range}@ R = initializer_list> + consteval info invoke_result(info type, R&& type_args); + consteval info unwrap_reference(info type); + consteval info unwrap_ref_decay(info type); + + consteval size_t tuple_size(info type); + consteval info tuple_element(size_t index, info type); + consteval bool is_applicable_type(info fn, info tuple); + consteval bool is_nothrow_applicable_type(info fn, info tuple); + consteval info apply_result(info fn, info tuple); + + consteval size_t variant_size(info type); + consteval info variant_alternative(size_t index, info type); + + consteval strong_ordering type_order(info type_a, info type_b); +} +\end{codeblock} + +\pnum +Unless otherwise specified, +each function, and each specialization of any function template, +specified in this header +is a designated addressable function\iref{namespace.std}. + +\pnum +When a function or function template specialization $F$ specified in this header +throws a \tcode{meta::exception} $E$, +\tcode{$E$.from()} is a reflection representing $F$ and +\tcode{$E$.where()} is a \tcode{source_location} +representing from where the call to $F$ originated. + +\pnum +The behavior of any function specified in namespace \tcode{std::meta} is +\impldef{behavior of any function in \tcode{std::meta} +for implementation-specific constructs} +when a reflection of a construct not otherwise specified by this document +is provided as an argument. +\begin{note} +Values of type \tcode{std::meta::info} +can represent implementation-specific constructs\iref{basic.fundamental}. +\end{note} +\begin{note} +Many of the functions specified in namespace \tcode{std::meta} +have semantics that can be affected by +the completeness of class types represented by reflection values. +For such functions, +for any reflection \tcode{r} such that \tcode{dealias(r)} +represents a specialization of a templated class with a reachable definition, +the specialization is implicitly instantiated\iref{temp.inst}. +\begin{example} +\begin{codeblock} +template +struct X { + T mem; +}; + +static_assert(size_of(^^X) == sizeof(int)); // instantiates \tcode{X} +\end{codeblock} +\end{example} +\end{note} + +\pnum +Any function in namespace \tcode{std::meta} +whose return type is \tcode{string_view} or \tcode{u8string_view} +returns an object \tcode{V} such that +\tcode{V.data()[V.size()]} equals \tcode{'\textbackslash 0'}. +Each element of the range +$\tcode{V.data()} + \crange{0}{\tcode{V.size()}}$ +is a potentially non-unique object with static storage duration that +is usable in constant expressions\iref{intro.object, expr.const}; +a pointer to such an element is not suitable for use as +a template argument for a constant template parameter of +pointer type\iref{temp.arg.nontype}. +\begin{example} +\begin{codeblock} +struct C { }; + +constexpr string_view sv = identifier_of(^^C); +static_assert(sv == "C"); +static_assert(sv.data()[0] == 'C'); +static_assert(sv.data()[1] == '@\textbackslash{}@0'); +\end{codeblock} +\end{example} + +\pnum +For the purpose of exposition, +throughout this clause \tcode{\caret\caret\placeholder{E}} is used +to indicate a reflection representing source construct \tcode{\placeholder{E}}. + +\rSec2[meta.string.literal]{Checking string literals} + +\indexlibraryglobal{is_string_literal}% +\begin{itemdecl} +consteval bool is_string_literal(const char* p); +consteval bool is_string_literal(const wchar_t* p); +consteval bool is_string_literal(const char8_t* p); +consteval bool is_string_literal(const char16_t* p); +consteval bool is_string_literal(const char32_t* p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{itemize} +\item + If \tcode{p} points to an unspecified object\iref{expr.const.core}, + \tcode{false}. +\item + Otherwise, if \tcode{p} points to a subobject + of a string literal object\iref{lex.string}, + \tcode{true}. +\item + Otherwise, \tcode{false}. +\end{itemize} +\end{itemdescr} + +\rSec2[meta.define.static]{Promoting to static storage} + +\pnum +The functions in this subclause promote compile-time storage into static storage. + +\indexlibraryglobal{reflect_constant_string}% +\begin{itemdecl} +template + consteval info reflect_constant_string(R&& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{CharT} be \tcode{ranges::range_value_t}. + +\pnum +\mandates +\tcode{CharT} is a character type\iref{basic.fundamental}. + +\pnum +Let $V$ be the pack of values of type \tcode{CharT} +whose elements are the corresponding elements of \tcode{r}, +except that if \tcode{r} is a reference to a string literal object, +then $V$ does not include the terminating \unicode{0000}{null} character of \tcode{r}. + +\pnum +Let $P$ be the template parameter object\iref{temp.param} +of type \tcode{const CharT[sizeof...(V) + 1]} +initialized with \tcode{\{$V$..., CharT()\}}. + +\pnum +\returns +\tcode{\reflexpr{$P$}}. + +\pnum +\begin{note} +$P$ is a potentially non-unique object\iref{intro.object}. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{reflect_constant_array}% +\begin{itemdecl} +template + consteval info reflect_constant_array(R&& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{U} be \tcode{ranges::range_value_t} and +\tcode{T} be \tcode{remove_all_extents_t}. + +\pnum +\mandates +\begin{itemize} +\item \tcode{T} is a structural type\iref{temp.param}, +\item \tcode{T} satisfies \libconcept{copy_constructible}, and +\item +if \tcode{U} is not an array type, then +\tcode{is_constructible_v>} is \tcode{true}. +\end{itemize} + +\pnum +Let $V$ be the pack of values of type \tcode{info} +of the same size as \tcode{r}, +where the $i^\text{th}$ element is +\begin{itemize} +\item +\tcode{reflect_constant_array(*$\tcode{\placeholder{it}}_i$)} +if \tcode{U} is an array type, +\item +\tcode{reflect_constant(static_cast(*$\tcode{\placeholder{it}}_i$))} +otherwise, +\end{itemize} +and $\tcode{\placeholder{it}}_i$ is an iterator to +the $i^\text{th}$ element of \tcode{r}. + +\pnum +Let $P$ be +\begin{itemize} +\item + the template parameter object\iref{temp.param} + of type \tcode{const T[sizeof...($V$)]}, + such that \tcode{$P$[$I$]} is template-argument-equivalent\iref{temp.type} + to the object represented by \tcode{$V$...[$I$]} + for all $I$ in the range \range{0}{sizeof...($V$)} + if \tcode{sizeof...($V$) > 0} is \tcode{true}, otherwise +\item + the template parameter object of type \tcode{const array} + initialized with \tcode{\{\}}. +\end{itemize} + +\pnum +\returns +\tcode{\reflexpr{$P$}}. + +\pnum +\throws +Any of +\begin{itemize} +\item +an exception thrown by any operation +on \tcode{r} or +on iterators and sentinels referring to \tcode{r}, +\item +an exception thrown +by the evaluation of any argument of \tcode{reflect_constant} or +by any evaluation of \tcode{reflect_constant_array}, or +\item +\tcode{meta::exception} +if any invocation of \tcode{reflect_constant} +would exit via an exception. +\end{itemize} + +\pnum +\begin{note} +When \tcode{r} is not empty, $P$ is a potentially non-unique object\iref{intro.object}. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{define_static_string}% +\begin{itemdecl} +template + consteval const ranges::range_value_t* define_static_string(R&& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return meta::extract*>(meta::reflect_constant_string(r)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{define_static_array}% +\begin{itemdecl} +template + consteval span, @\seebelow@> define_static_array(R&& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +using T = ranges::range_value_t; +meta::info array = meta::reflect_constant_array(r); +if (meta::is_array_type(meta::type_of(array))) { + return span(meta::extract(array), + meta::extent(meta::type_of(array))); +} else { + return span(static_cast(nullptr), 0); +} +\end{codeblock} + +\pnum +\remarks +If \tcode{ranges::size(r)} is a constant expression, +the second template argument of the returned \tcode{span} type +is \tcode{static_cast(ranges::size(r))}; +otherwise, it is \tcode{dynamic_extent}. +\end{itemdescr} + +\indexlibraryglobal{define_static_object}% +\begin{itemdecl} +template + consteval const remove_cvref_t* define_static_object(T&& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +using U = remove_cvref_t; +if constexpr (meta::is_class_type(^^U) || meta::is_union_type(^^U)) { + return addressof(meta::extract( + meta::reflect_constant(std::forward(t)))); +} else if constexpr (meta::is_array_type(^^U)) { + return addressof(meta::extract( + meta::reflect_constant_array(std::forward(t)))); +} else { + return define_static_array(span(addressof(t), 1)).data(); +} +\end{codeblock} + +\pnum +\begin{note} +For class types, +\tcode{define_static_object} provides +the address of the template parameter object\iref{temp.param} +that is template-argument equivalent to \tcode{t}. +\end{note} +\end{itemdescr} + +\rSec2[meta.reflection.exception]{Class \tcode{exception}} + +\indexlibraryglobal{exception}% +\begin{codeblock} +namespace std::meta { + class exception : public std::exception { + private: + optional @\exposidnc{what_}@; // \expos + u8string @\exposidnc{u8what_}@; // \expos + info @\exposidnc{from_}@; // \expos + source_location @\exposidnc{where_}@; // \expos + + public: + consteval exception(u8string_view what, info from, + source_location where = source_location::current()) noexcept; + + consteval exception(string_view what, info from, + source_location where = source_location::current()) noexcept; + + exception(const exception&) = default; + exception(exception&&) = default; + + exception& operator=(const exception&) = default; + exception& operator=(exception&&) = default; + + constexpr const char* what() const noexcept override; + consteval u8string_view u8what() const noexcept; + consteval info from() const noexcept; + consteval source_location where() const noexcept; + }; +} +\end{codeblock} + +\pnum +Reflection functions throw exceptions of type \tcode{meta::exception} +to signal an error. + +\indexlibraryctor{exception}% +\begin{itemdecl} +consteval exception(u8string_view what, info from, + source_location where = source_location::current()) noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Initializes +\exposid{u8what_} with \tcode{what}, +\exposid{from_} with \tcode{from}, and +\exposid{where_} with \tcode{where}. +If \tcode{what} can be represented in the ordinary literal encoding, +initializes \exposid{what_} with \tcode{what}, +transcoded from UTF-8 to the ordinary literal encoding. +Otherwise, \exposid{what_} is value-initialized. +\end{itemdescr} + +\indexlibraryctor{exception}% +\begin{itemdecl} +consteval exception(string_view what, info from, + source_location where = source_location::current()) noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\constantwhen +\tcode{what} designates a sequence of characters +that can be encoded in UTF-8. + +\pnum +\effects +Initializes +\exposid{what_} with \tcode{what}, +\exposid{u8what_} with \tcode{what} +transcoded from the ordinary literal encoding to UTF-8, +%FIXME: Oxford comma before "and" +\exposid{from_} with \tcode{from} and +\exposid{where_} with \tcode{where}. +\end{itemdescr} + +\indexlibrarymember{what}{exception}% +\begin{itemdecl} +constexpr const char* what() const noexcept override; +\end{itemdecl} +\begin{itemdescr} +\pnum +\constantwhen +\tcode{\exposid{what_}.has_value()} is \tcode{true}. + +\pnum +\returns +\tcode{\exposid{what_}->c_str()}. +\end{itemdescr} + +\indexlibrarymember{u8what}{exception}% +\begin{itemdecl} +consteval u8string_view u8what() const noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\returns +\exposid{u8what_}. +\end{itemdescr} + +\indexlibrarymember{from}{exception}% +\begin{itemdecl} +consteval info from() const noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\returns +\exposid{from_}. +\end{itemdescr} + +\indexlibrarymember{where}{exception}% +\begin{itemdecl} +consteval source_location where() const noexcept; +\end{itemdecl} +\begin{itemdescr} +\pnum +\returns +\exposid{where_}. +\end{itemdescr} + +\rSec2[meta.reflection.operators]{Operator representations} + +\begin{itemdecl} +enum class @\libglobal{operators}@ { + @\seebelow@; +}; +using enum operators; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The enumeration type \tcode{operators} specifies +constants used to identify operators that can be overloaded, +with the meanings listed in~\tref{meta.reflection.operators}. +The values of the constants are distinct. +\end{itemdescr} + +%TODO: double-check if this is the right table environment for the job +%TODO: What is the best way to index these enum members? +\begin{floattable}{Enum class \tcode{operators}}{meta.reflection.operators} +{lcc} +\topline +\lhdr{Constant} & +\chdr{Corresponding \grammarterm{operator-function-id}} & +\rhdr{Operator symbol name} \\ \capsep +\tcode{op_new} & \tcode{operator new} & \tcode{new} \\ \rowsep +\tcode{op_delete} & \tcode{operator delete} & \tcode{delete} \\ \rowsep +\tcode{op_array_new} & \tcode{operator new[]} & \tcode{new[]} \\ \rowsep +\tcode{op_array_delete} & \tcode{operator delete[]} & \tcode{delete[]} \\ \rowsep +\tcode{op_co_await} & \tcode{operator co_await} & \tcode{co_await} \\ \rowsep +\tcode{op_parentheses} & \tcode{operator()} & \tcode{()} \\ \rowsep +\tcode{op_square_brackets} & \tcode{operator[]} & \tcode{[]} \\ \rowsep +\tcode{op_arrow} & \tcode{operator->} & \tcode{->} \\ \rowsep +\tcode{op_arrow_star} & \tcode{operator->*} & \tcode{->*} \\ \rowsep +\tcode{op_tilde} & \tcode{operator\~} & \tcode{\~} \\ \rowsep +\tcode{op_exclamation} & \tcode{operator!} & \tcode{!} \\ \rowsep +\tcode{op_plus} & \tcode{operator+} & \tcode{+} \\ \rowsep +\tcode{op_minus} & \tcode{operator-} & \tcode{-} \\ \rowsep +\tcode{op_star} & \tcode{operator*} & \tcode{*} \\ \rowsep +\tcode{op_slash} & \tcode{operator/} & \tcode{/} \\ \rowsep +\tcode{op_percent} & \tcode{operator\%} & \tcode{\%} \\ \rowsep +\tcode{op_caret} & \tcode{operator\caret} & \tcode{\caret} \\ \rowsep +\tcode{op_ampersand} & \tcode{operator\&} & \tcode{\&} \\ \rowsep +\tcode{op_equals} & \tcode{operator=} & \tcode{=} \\ \rowsep +\tcode{op_pipe} & \tcode{operator|} & \tcode{|} \\ \rowsep +\tcode{op_plus_equals} & \tcode{operator+=} & \tcode{+=} \\ \rowsep +\tcode{op_minus_equals} & \tcode{operator-=} & \tcode{-=} \\ \rowsep +\tcode{op_star_equals} & \tcode{operator*=} & \tcode{*=} \\ \rowsep +\tcode{op_slash_equals} & \tcode{operator/=} & \tcode{/=} \\ \rowsep +\tcode{op_percent_equals} & \tcode{operator\%=} & \tcode{\%=} \\ \rowsep +\tcode{op_caret_equals} & \tcode{operator\caret=} & \tcode{\caret=} \\ \rowsep +\tcode{op_ampersand_equals} & \tcode{operator\&=} & \tcode{\&=} \\ \rowsep +\tcode{op_pipe_equals} & \tcode{operator|=} & \tcode{|=} \\ \rowsep +\tcode{op_equals_equals} & \tcode{operator==} & \tcode{==} \\ \rowsep +\tcode{op_exclamation_equals} & \tcode{operator!=} & \tcode{!=} \\ \rowsep +\tcode{op_less} & \tcode{operator<} & \tcode{<} \\ \rowsep +\tcode{op_greater} & \tcode{operator>} & \tcode{>} \\ \rowsep +\tcode{op_less_equals} & \tcode{operator<=} & \tcode{<=} \\ \rowsep +\tcode{op_greater_equals} & \tcode{operator>=} & \tcode{>=} \\ \rowsep +\tcode{op_spaceship} & \tcode{operator<=>} & \tcode{<=>} \\ \rowsep +\tcode{op_ampersand_ampersand} & \tcode{operator\&\&} & \tcode{\&\&} \\ \rowsep +\tcode{op_pipe_pipe} & \tcode{operator||} & \tcode{||} \\ \rowsep +\tcode{op_less_less} & \tcode{operator<<} & \tcode{<<} \\ \rowsep +\tcode{op_greater_greater} & \tcode{operator>>} & \tcode{>>} \\ \rowsep +\tcode{op_less_less_equals} & \tcode{operator<<=} & \tcode{<<=} \\ \rowsep +\tcode{op_greater_greater_equals} & \tcode{operator>>=} & \tcode{>>=} \\ \rowsep +\tcode{op_plus_plus} & \tcode{operator++} & \tcode{++} \\ \rowsep +\tcode{op_minus_minus} & \tcode{operator--} & \tcode{--} \\ \rowsep +\tcode{op_comma} & \tcode{operator,} & \tcode{,} \\ +\end{floattable} + +\indexlibraryglobal{operator_of}% +\begin{itemdecl} +consteval operators operator_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The value of the enumerator from \tcode{operators} +whose corresponding \grammarterm{operator-function-id} +is the unqualified name of the entity represented by \tcode{r}. + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{r} represents an operator function or operator function template. +\end{itemdescr} + +\indexlibraryglobal{symbol_of}% +\indexlibraryglobal{u8symbol_of}% +\begin{itemdecl} +consteval string_view symbol_of(operators op); +consteval u8string_view u8symbol_of(operators op); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{string_view} or \tcode{u8string_view} +containing the characters of the operator symbol name corresponding to \tcode{op}, +respectively encoded with the ordinary literal encoding or with UTF-8. + +\pnum +\throws +\tcode{meta::exception} unless +the value of \tcode{op} corresponds to one of the enumerators in \tcode{operators}. +\end{itemdescr} + +\rSec2[meta.reflection.names]{Reflection names and locations} + +\indexlibraryglobal{has_identifier}% +\begin{itemdecl} +consteval bool has_identifier(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{itemize} +\item + If \tcode{r} represents an entity + that has a typedef name for linkage purposes\iref{dcl.typedef}, + then \tcode{true}. +\item + Otherwise, if \tcode{r} represents an unnamed entity, + then \tcode{false}. +\item + Otherwise, if \tcode{r} represents a type alias, + then \tcode{!has_template_arguments(r)}. +\item + Otherwise, if \tcode{r} represents a type, + then \tcode{true} if + \begin{itemize} + \item + \tcode{r} represents a cv-unqualified class type and + \tcode{has_template_arguments(r)} is \tcode{false}, or + \item + \tcode{r} represents a cv-unqualified enumeration type. + \end{itemize} + Otherwise, \tcode{false}. +\item + Otherwise, if \tcode{r} represents a function, + then \tcode{true} if \tcode{has_template_arguments(r)} is \tcode{false} + and the function is not a + constructor, + destructor, + operator function, or + conversion function. + Otherwise, \tcode{false}. +\item + Otherwise, if \tcode{r} represents a template, + then \tcode{true} if \tcode{r} does not represent a + constructor template, + operator function template, + or conversion function template. + Otherwise, \tcode{false}. +\item + Otherwise, if \tcode{r} represents the $i^\text{th}$ parameter of a function $F$ + that is an (implicit or explicit) specialization of a templated function $T$ + and the $i^\text{th}$ parameter of the instantiated declaration of $T$ + whose template arguments are those of $F$ would be instantiated from a pack, + then \tcode{false}. +\item + Otherwise, if \tcode{r} represents the parameter $P$ of a function $F$, + then let $S$ be the set of declarations, + ignoring any explicit instantiations, + that are reachable from a point in the evaluation context + and that declare either $F$ or a templated function + of which $F$ is a specialization; + \tcode{true} if + \begin{itemize} + \item + there is a declaration $D$ in $S$ that introduces a name $N$ for either $P$ + or the parameter corresponding to $P$ + in the templated function that $D$ declares and + \item + no declaration in $S$ does so using any name other than $N$. + \end{itemize} + Otherwise, \tcode{false}. + \begin{example} +\begin{codeblock} +void fun(int); +constexpr std::meta::info r = parameters_of(^^fun)[0]; +static_assert(!has_identifier(r)); + +void fun(int x); +static_assert(has_identifier(r)); + +void fun(int x); +static_assert(has_identifier(r)); + +void poison() { + void fun(int y); +} +static_assert(!has_identifier(r)); +\end{codeblock} + \end{example} +\item + Otherwise, if \tcode{r} represents a variable, + then \tcode{false} if the declaration of that variable + was instantiated from a function parameter pack. + Otherwise, \tcode{!has_template_arguments(r)}. +\item + Otherwise, if \tcode{r} represents a structured binding, + then \tcode{false} if the declaration of that structured binding + was instantiated from a structured binding pack. + Otherwise, \tcode{true}. +\item + Otherwise, if \tcode{r} represents an + enumerator, + non-static-data member, + namespace, or + namespace alias, + then \tcode{true}. +\item + Otherwise, if \tcode{r} represents a direct base class relationship, + then \tcode{has_identifier(type_of(r))}. +\item + Otherwise, if \tcode{r} represents a data member description + $(T, N, A, W, \mathit{NUA}, \mathit{ANN})$\iref{class.mem.general}; + \tcode{true} if $N$ is not $\bot$. + Otherwise, \tcode{false}. +\item + Otherwise, \tcode{false}. +\end{itemize} +\end{itemdescr} + +\indexlibraryglobal{identifier_of}% +\indexlibraryglobal{u8identifier_of}% +\begin{itemdecl} +consteval string_view identifier_of(info r); +consteval u8string_view u8identifier_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $E$ be UTF-8 for \tcode{u8identifier_of}, +and otherwise the ordinary literal encoding. + +\pnum +\returns +An \ntmbs{}, encoded with $E$, +determined as follows: +\begin{itemize} +\item + If \tcode{r} represents an entity with a typedef name for linkage purposes, + then that name. +\item + Otherwise, if \tcode{r} represents a literal operator or literal operator template, + then the \grammarterm{ud-suffix} of the operator or operator template. +\item + Otherwise, if \tcode{r} represents the parameter $P$ of a function $F$, + then let $S$ be the set of declarations, + ignoring any explicit instantiations, + that are reachable from a point in the evaluation context + and that declare either $F$ + or a templated function of which $F$ is a specialization; + the name that was introduced by a declaration in $S$ + for the parameter corresponding to $P$. +\item + Otherwise, if \tcode{r} represents an entity, + then the identifier introduced by the declaration of that entity. +\item + Otherwise, if \tcode{r} represents a direct base class relationship, + then \tcode{identifier_of(type_of(r))} or \tcode{u8identifier_of(type_of(r))}, + respectively. +\item + Otherwise, \tcode{r} represents a data member description + $(T, N, A, W, \mathit{NUA}, \mathit{ANN})$\iref{class.mem.general}; + a \tcode{string_view} or \tcode{u8string_view}, respectively, + containing the identifier $N$. +\end{itemize} + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{has_identifier(r)} is \tcode{true} +and the identifier that would be returned (see above) +is representable by $E$. +\end{itemdescr} + +\indexlibraryglobal{display_string_of}% +\indexlibraryglobal{u8display_string_of}% +\begin{itemdecl} +consteval string_view display_string_of(info r); +consteval u8string_view u8display_string_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An +\impldef{the result of \tcode{display_string_of} and \tcode{u8display_string_of}} +\tcode{string_view} or \tcode{u8string_view}, respectively. + +\pnum +\recommended +Where possible, +implementations should return a string +suitable for identifying the represented construct. +\end{itemdescr} + +\indexlibraryglobal{source_location_of}% +\begin{itemdecl} +consteval source_location source_location_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{r} represents +a value, +a type other than a class type or an enumeration type, +the global namespace, or +a data member description, +then \tcode{source_location\{\}}. +Otherwise, an +\impldef{the value returned by \tcode{std::meta::source_location_of}} +\tcode{source_location} value. + +\pnum +\recommended +If \tcode{r} represents an entity with a definition +that is reachable from the evaluation context, +a value corresponding to a definition should be returned. +\end{itemdescr} + +\rSec2[meta.reflection.queries]{Reflection queries} + +\begin{itemdecl} +consteval bool @\exposid{has-type}@(info r); // \expos +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a +value, +annotation, +object, +variable, +function whose type does not contain an undeduced placeholder type +and that is not a constructor or destructor, +enumerator, +non-static data member, +unnamed bit-field, +direct base class relationship, +data member description, or +function parameter. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{type_of}% +\begin{itemdecl} +consteval info type_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{itemize} +\item + If \tcode{r} represents the $i^\text{th}$ parameter of a function $F$, + then the $i^\text{th}$ type + in the parameter-type-list of $F$\iref{dcl.fct}. +\item + Otherwise, if \tcode{r} represents a + value, + object, + variable, + function, + non-static data member, or + unnamed bit-field, + then the type of what is represented by \tcode{r}. +\item + Otherwise, if \tcode{r} represents an annotation, + then \tcode{type_of(constant_of(r))}. +\item + Otherwise, if \tcode{r} represents + an enumerator $N$ of an enumeration $E$, then: + \begin{itemize} + \item + If $E$ is defined by a declaration $D$ + that is reachable from a point $P$ in the evaluation context + and $P$ does not occur within an \grammarterm{enum-specifier} of $D$, + then a reflection of $E$. + \item + Otherwise, a reflection of the type of $N$ + prior to the closing brace of the \grammarterm{enum-specifier} + as specified in~\ref{dcl.enum}. + \end{itemize} +\item + Otherwise, if \tcode{r} represents + a direct base class relationship $(D, B)$, + then a reflection of $B$. +\item + Otherwise, for a data member description $(T, N, A, W, \mathit{NUA}, \mathit{ANN})$\iref{class.mem.general}, + a reflection of the type $T$. +\end{itemize} + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{\exposid{has-type}(r)} is \tcode{true}. +\end{itemdescr} + +\indexlibraryglobal{object_of}% +\begin{itemdecl} +consteval info object_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{itemize} +\item + If \tcode{r} represents an object, + then \tcode{r}. +\item + Otherwise, if \tcode{r} represents a reference, + then a reflection of the object referred to by that reference. +\item + Otherwise, \tcode{r} represents a variable; + a reflection of the object declared by that variable. +\end{itemize} + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{r} is a reflection representing either +\begin{itemize} +\item + an object with static storage duration\iref{basic.stc.general}, or +\item + a variable that either declares or refers to such an object, + and if that variable is a reference $R$, then either + \begin{itemize} + \item + $R$ is usable in constant expressions\iref{expr.const.init}, or + \item + the lifetime of $R$ began within the core constant expression + currently under evaluation. + \end{itemize} +\end{itemize} + +\pnum +\begin{example} +\begin{codeblock} +int x; +int& y = x; + +static_assert(^^x != ^^y); // OK, \tcode{r} and \tcode{y} are different variables, so their + // reflections compare different +static_assert(object_of(^^x) == object_of(^^y)); // OK, because \tcode{y} is a reference + // to \tcode{x}, their underlying objects are the same +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibraryglobal{constant_of}% +\begin{itemdecl} +consteval info constant_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $R$ be a constant expression of type \tcode{info} +such that \tcode{$R$ == r} is \tcode{true}. +If \tcode{r} represents an annotation, +then let $C$ be its underlying constant. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if constexpr (is_annotation(@$R$@)) { + return @$C$@; +} else if constexpr (is_array_type(type_of(@$R$@))) { + return reflect_constant_array([: @$R$@ :]); +} else if constexpr (is_function_type(type_of(@$R$@))) { + return reflect_function([: @$R$@ :]); +} else { + return reflect_constant([: @$R$@ :]); +} +\end{codeblock} + +\pnum +\throws +\tcode{meta::exception} unless +either \tcode{r} represents an annotation or +\tcode{[: $R$ :]} is a valid +\grammarterm{splice-expression}\iref{expr.prim.splice}. + +\pnum +\begin{example} +\begin{codeblock} +constexpr int x = 0; +constexpr int y = 0; + +static_assert(^^x != ^^y); // OK, \tcode{x} and \tcode{y} are different variables, + // so their reflections compare different + +static_assert(constant_of(^^x) == // OK, both \tcode{constant_of(\reflexpr{x})} and + constant_of(^^y)); // \tcode{constant_of(\reflexpr{y})} represent the value \tcode{0} + +static_assert(constant_of(^^x) == // OK, likewise + reflect_constant(0)); + +struct S { int m; }; +constexpr S s {42}; + +static_assert(is_object(constant_of(^^s)) && + is_object(reflect_object(s))); + +static_assert(constant_of(^^s) != // OK, template parameter object that is + reflect_object(s)); // template-argument-equivalent to \tcode{s} + // is a different object than \tcode{s} + +static_assert(constant_of(^^s) == + constant_of(reflect_object(s))); + +consteval info fn() { + constexpr int x = 42; + return ^^x; +} +constexpr info r = constant_of(fn()); // error: \tcode{x} is outside its lifetime +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibraryglobal{is_public}% +\indexlibraryglobal{is_protected}% +\indexlibraryglobal{is_private}% +\begin{itemdecl} +consteval bool is_public(info r); +consteval bool is_protected(info r); +consteval bool is_private(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents either +\begin{itemize} +\item + a class member or unnamed bit-field + that is public, protected, or private, respectively, or +\item + a direct base class relationship $(D, B)$ for which $B$ is, respectively, + a public, protected, or private base class of $D$. +\end{itemize} +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_virtual}% +\begin{itemdecl} +consteval bool is_virtual(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents either a virtual member function +or a direct base class relationship $(D, B)$ +for which $B$ is a virtual base class of $D$. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_pure_virtual}% +\indexlibraryglobal{is_override}% +\begin{itemdecl} +consteval bool is_pure_virtual(info r); +consteval bool is_override(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a member function that is pure virtual +or overrides another member function, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_final}% +\begin{itemdecl} +consteval bool is_final(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a final class or a final member function. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_deleted}% +\indexlibraryglobal{is_defaulted}% +\begin{itemdecl} +consteval bool is_deleted(info r); +consteval bool is_defaulted(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a function that is +a deleted function\iref{dcl.fct.def.delete} +or defaulted function\iref{dcl.fct.def.default}, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_user_provided}% +\indexlibraryglobal{is_user_declared}% +\begin{itemdecl} +consteval bool is_user_provided(info r); +consteval bool is_user_declared(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a function that is +user-provided or user-declared\iref{dcl.fct.def.default}, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_explicit}% +\begin{itemdecl} +consteval bool is_explicit(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a member function that is declared explicit. +Otherwise, \tcode{false}. +\begin{note} +If \tcode{r} represents a member function template that is declared explicit, +\tcode{is_explicit(r)} is still \tcode{false} +because in general, +such queries for templates cannot be answered. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{is_noexcept}% +\begin{itemdecl} +consteval bool is_noexcept(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a \tcode{noexcept} function type +or a function with a non-throwing exception specification\iref{except.spec}. +Otherwise, \tcode{false}. +\begin{note} +If \tcode{r} represents a function template that is declared \tcode{noexcept}, +\tcode{is_noexcept(r)} is still \tcode{false} +because in general, +such queries for templates cannot be answered. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{is_bit_field}% +\begin{itemdecl} +consteval bool is_bit_field(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a bit-field, +or if \tcode{r} represents a data member description +$(T, N, A, W, \mathit{NUA},\brk{} \mathit{ANN})$\iref{class.mem.general} +for which $W$ is not $\bot$. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_enumerator}% +\indexlibraryglobal{is_annotation}% +\begin{itemdecl} +consteval bool is_enumerator(info r); +consteval bool is_annotation(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents an enumerator or annotation, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_const}% +\indexlibraryglobal{is_volatile}% +\begin{itemdecl} +consteval bool is_const(info r); +consteval bool is_volatile(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $T$ be \tcode{type_of(r)} if \tcode{\exposid{has-type}(r)} is \tcode{true}. +Otherwise, let $T$ be \tcode{dealias(r)}. + +\pnum +\returns +\tcode{true} if $T$ represents a const or volatile type, respectively, +or a const- or volatile-qualified function type, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_mutable_member}% +\begin{itemdecl} +consteval bool is_mutable_member(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a \tcode{mutable} non-static data member. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_lvalue_reference_qualified}% +\indexlibraryglobal{is_rvalue_reference_qualified}% +\begin{itemdecl} +consteval bool is_lvalue_reference_qualified(info r); +consteval bool is_rvalue_reference_qualified(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $T$ be \tcode{type_of(r)} if \tcode{\exposid{has-type}(r)} is \tcode{true}. +Otherwise, let $T$ be \tcode{dealias(r)}. + +\pnum +\returns +\tcode{true} if $T$ represents an +lvalue- or rvalue-qualified function type, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{has_static_storage_duration}% +\indexlibraryglobal{has_thread_storage_duration}% +\indexlibraryglobal{has_automatic_storage_duration}% +\begin{itemdecl} +consteval bool has_static_storage_duration(info r); +consteval bool has_thread_storage_duration(info r); +consteval bool has_automatic_storage_duration(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents an object or variable that has +static, thread, or automatic storage duration, respectively\iref{basic.stc}. +Otherwise, \tcode{false}. +\begin{note} +It is not possible to have a reflection +representing an object or variable having dynamic storage duration. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{has_internal_linkage}% +\indexlibraryglobal{has_module_linkage}% +\indexlibraryglobal{has_external_linkage}% +\indexlibraryglobal{has_linkage}% +\begin{itemdecl} +consteval bool has_internal_linkage(info r); +consteval bool has_module_linkage(info r); +consteval bool has_external_linkage(info r); +consteval bool has_linkage(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a +variable, +function, +type, +template, or +namespace +whose name has +internal linkage, +module linkage, +external linkage, or +any linkage, respectively\iref{basic.link}. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{has_c_language_linkage}% +\begin{itemdecl} +consteval bool has_c_language_linkage(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a +variable, +function, or +function type +with C language linkage. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_complete_type}% +\begin{itemdecl} +consteval bool is_complete_type(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{is_type(r)} is \tcode{true} +and there is some point in the evaluation context +from which the type represented by \tcode{dealias(r)} +is not an incomplete type\iref{basic.types}. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_enumerable_type}% +\begin{itemdecl} +consteval bool is_enumerable_type(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +A type $T$ is \term{enumerable} from a point $P$ if either +\begin{itemize} +\item + $T$ is a class type complete at point $P$ or +\item + $T$ is an enumeration type defined by a declaration $D$ + such that $D$ is reachable from $P$ + but $P$ does not occur within an \grammarterm{enum-specifier} of $D$\iref{dcl.enum}. +\end{itemize} + +\pnum +\returns +\tcode{true} if \tcode{dealias(r)} represents a type that is enumerable +from some point in the evaluation context. +Otherwise, \tcode{false}. + +\pnum +\begin{example} +\begin{codeblock} +class S; +enum class E; +static_assert(!is_enumerable_type(^^S)); +static_assert(!is_enumerable_type(^^E)); + +class S { + void mfn() { + static_assert(is_enumerable_type(^^S)); + } + static_assert(!is_enumerable_type(^^S)); +}; +static_assert(is_enumerable_type(^^S)); + +enum class E { + A = is_enumerable_type(^^E) ? 1 : 2 +}; +static_assert(is_enumerable_type(^^E)); +static_assert(static_cast(E::A) == 2); +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibraryglobal{is_variable}% +\begin{itemdecl} +consteval bool is_variable(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a variable. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_type}% +\indexlibraryglobal{is_namespace}% +\begin{itemdecl} +consteval bool is_type(info r); +consteval bool is_namespace(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents an entity +whose underlying entity is a type or namespace, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_type_alias}% +\indexlibraryglobal{is_namespace_alias}% +\begin{itemdecl} +consteval bool is_type_alias(info r); +consteval bool is_namespace_alias(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a type alias or namespace alias, respectively. +Otherwise, \tcode{false}. +\begin{note} +A specialization of an alias template is a type alias. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{is_function}% +\begin{itemdecl} +consteval bool is_function(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a function. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_conversion_function}% +\indexlibraryglobal{is_operator_function}% +\indexlibraryglobal{is_literal_operator}% +\begin{itemdecl} +consteval bool is_conversion_function(info r); +consteval bool is_operator_function(info r); +consteval bool is_literal_operator(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a function that is a +conversion function\iref{class.conv.fct}, +operator function\iref{over.oper}, or +literal operator\iref{over.literal}, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_special_member_function}% +\indexlibraryglobal{is_constructor}% +\indexlibraryglobal{is_default_constructor}% +\indexlibraryglobal{is_copy_constructor}% +\indexlibraryglobal{is_move_constructor}% +\indexlibraryglobal{is_assignment}% +\indexlibraryglobal{is_copy_assignment}% +\indexlibraryglobal{is_move_assignment}% +\indexlibraryglobal{is_destructor}% +\begin{itemdecl} +consteval bool is_special_member_function(info r); +consteval bool is_constructor(info r); +consteval bool is_default_constructor(info r); +consteval bool is_copy_constructor(info r); +consteval bool is_move_constructor(info r); +consteval bool is_assignment(info r); +consteval bool is_copy_assignment(info r); +consteval bool is_move_assignment(info r); +consteval bool is_destructor(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a function that is a +special member function\iref{special}, +a constructor, +a default constructor, +a copy constructor, +a move constructor, +an assignment operator, +a copy assignment operator, +a move assignment operator, or +a destructor, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_function_parameter}% +\begin{itemdecl} +consteval bool is_function_parameter(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a function parameter. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_explicit_object_parameter}% +\begin{itemdecl} +consteval bool is_explicit_object_parameter(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a function parameter +that is an explicit object parameter\iref{dcl.fct}. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{has_default_argument}% +\begin{itemdecl} +consteval bool has_default_argument(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{r} represents a parameter $P$ of a function $F$, then: +\begin{itemize} +\item + If $F$ is a specialization of a templated function $T$, + then \tcode{true} if there exists a declaration $D$ of $T$ + that is reachable from a point in the evaluation context + and $D$ specifies a default argument + for the parameter of $T$ corresponding to $P$. + Otherwise, \tcode{false}. +\item + Otherwise, if there exists a declaration $D$ of $F$ + that is reachable from a point in the evaluation context + and $D$ specifies a default argument for $P$, + then \tcode{true}. +\end{itemize} +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_vararg_function}% +\begin{itemdecl} +consteval bool is_vararg_function(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a function or function type +that is a vararg function\iref{dcl.fct}. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_template}% +\begin{itemdecl} +consteval bool is_template(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a +function template, +class template, +variable template, +alias template, or +concept. +Otherwise, \tcode{false}. + +\pnum +\begin{note} +A template specialization is not a template. +For example, +\tcode{is_template(\brk{}\reflexpr{std::vector})} is \tcode{true} +but \tcode{is_template(\brk{}\reflexpr{std::vector})} is \tcode{false}. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{is_function_template}% +\indexlibraryglobal{is_variable_template}% +\indexlibraryglobal{is_class_template}% +\indexlibraryglobal{is_alias_template}% +\indexlibraryglobal{is_conversion_function_template}% +\indexlibraryglobal{is_operator_function_template}% +\indexlibraryglobal{is_literal_operator_template}% +\indexlibraryglobal{is_constructor_template}% +\indexlibraryglobal{is_concept}% +\begin{itemdecl} +consteval bool is_function_template(info r); +consteval bool is_variable_template(info r); +consteval bool is_class_template(info r); +consteval bool is_alias_template(info r); +consteval bool is_conversion_function_template(info r); +consteval bool is_operator_function_template(info r); +consteval bool is_literal_operator_template(info r); +consteval bool is_constructor_template(info r); +consteval bool is_concept(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a +function template, +variable template, +class template, +alias template, +conversion function template, +operator function template, +literal operator template, +constructor template, or +concept, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_value}% +\indexlibraryglobal{is_object}% +\begin{itemdecl} +consteval bool is_value(info r); +consteval bool is_object(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a value or object, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_structured_binding}% +\begin{itemdecl} +consteval bool is_structured_binding(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a structured binding. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{is_class_member}% +\indexlibraryglobal{is_namespace_member}% +\indexlibraryglobal{is_nonstatic_data_member}% +\indexlibraryglobal{is_static_member}% +\indexlibraryglobal{is_base}% +\begin{itemdecl} +consteval bool is_class_member(info r); +consteval bool is_namespace_member(info r); +consteval bool is_nonstatic_data_member(info r); +consteval bool is_static_member(info r); +consteval bool is_base(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a +class member, +namespace member, +non-static data member, +static member, or +direct base class relationship, respectively. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{has_default_member_initializer}% +\begin{itemdecl} +consteval bool has_default_member_initializer(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a non-static data member +that has a default member initializer. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{has_parent}% +\begin{itemdecl} +consteval bool has_parent(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{itemize} +\item + If \tcode{r} represents the global namespace, + then \tcode{false}. +\item + Otherwise, if \tcode{r} represents an entity that has C language linkage\iref{dcl.link}, + then \tcode{false}. +\item + Otherwise, if \tcode{r} represents an entity that has a + language linkage other than \Cpp{} language linkage, + then an + \impldef{the result of \tcode{std::meta::has_parent} for entities + with neither C nor \Cpp{} language linkage} + value. +\item + Otherwise, if \tcode{r} represents a type that is neither a class nor enumeration type, + then \tcode{false}. +\item + Otherwise, if \tcode{r} represents an entity or direct base class relationship, + then \tcode{true}. +\item + Otherwise, \tcode{false}. +\end{itemize} +\end{itemdescr} + +\indexlibraryglobal{parent_of}% +\begin{itemdecl} +consteval info parent_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{itemize} +\item + If \tcode{r} represents a non-static data member + that is a direct member of an anonymous union, + or an unnamed bit-field declared + within the \grammarterm{member-specification} of such a union, + then a reflection representing the innermost enclosing anonymous union. +\item + Otherwise, if \tcode{r} represents an enumerator, + then a reflection representing the corresponding enumeration type. +\item + Otherwise, if \tcode{r} represents a direct base class relationship $(D, B)$, + then a reflection representing $D$. +\item + Otherwise, let $E$ be a class, function, or namespace + whose class scope, function parameter scope, or namespace scope, respectively, + is the innermost such scope that either is, or encloses, + the target scope of a declaration of what is represented by \tcode{r}. + \begin{itemize} + \item + If $E$ is the function call operator of a closure type + for a \grammarterm{consteval-block-declaration}\iref{dcl.pre}, + then \tcode{parent_of(\brk{}parent_of(\reflexpr{$E$}))}. + \begin{note} + In this case, + the first \tcode{parent_of} will be the closure type, + so the second \tcode{parent_of} is necessary + to give the parent of that closure type. + \end{note} + \item + Otherwise, \tcode{\reflexpr{$E$}}. + \end{itemize} +\end{itemize} + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{has_parent(r)} is \tcode{true}. + +\pnum +\begin{example} +\begin{codeblock} +struct I { }; + +struct F : I { + union { + int o; + }; + + enum N { + A + }; +}; + +constexpr auto ctx = std::meta::access_context::current(); + +static_assert(parent_of(^^F) == ^^::); +static_assert(parent_of(bases_of(^^F, ctx)[0]) == ^^F); +static_assert(is_union_type(parent_of(^^F::o))); +static_assert(parent_of(^^F::N) == ^^F); +static_assert(parent_of(^^F::A) == ^^F::N); +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibraryglobal{dealias}% +\begin{itemdecl} +consteval info dealias(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{r} represents an entity, then +a reflection representing the underlying entity of what \tcode{r} represents. +Otherwise, \tcode{r}. + +\pnum +\begin{example} +\begin{codeblock} +using X = int; +using Y = X; +static_assert(dealias(^^int) == ^^int); +static_assert(dealias(^^X) == ^^int); +static_assert(dealias(^^Y) == ^^int); +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibraryglobal{has_template_arguments}% +\begin{itemdecl} +consteval bool has_template_arguments(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a specialization of a +function template, +variable template, +class template, or +an alias template. +Otherwise, \tcode{false}. +\end{itemdescr} + +\indexlibraryglobal{template_of}% +\begin{itemdecl} +consteval info template_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A reflection of the template of the specialization represented by \tcode{r}. + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{has_template_arguments(r)} is \tcode{true}. +\end{itemdescr} + +\indexlibraryglobal{template_arguments_of}% +\begin{itemdecl} +consteval vector template_arguments_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{vector} containing reflections +of the template arguments +of the template specialization represented by \tcode{r}, +in the order in which they appear in the corresponding template argument list. +For a given template argument $A$, +its corresponding reflection $R$ is determined as follows: +\begin{itemize} +\item + If $A$ denotes a type or type alias, + then $R$ is a reflection representing the underlying entity of $A$. + \begin{note} + $R$ always represents a type, never a type alias. + \end{note} +\item + Otherwise, if $A$ denotes a + class template, + variable template, + concept, or + alias template, + then $R$ is a reflection representing $A$. +\item + Otherwise, $A$ is a constant template argument\iref{temp.arg.nontype}. + Let $P$ be the corresponding template parameter. + \begin{itemize} + \item + If $P$ has reference type, + then $R$ is a reflection + representing the object or function referred to by $A$. + \item + Otherwise, if $P$ has class type, + then $R$ represents the corresponding template parameter object. + \item + Otherwise, $R$ is a reflection representing the value of $A$. + \end{itemize} +\end{itemize} + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{has_template_arguments(r)} is \tcode{true}. + +\pnum +\begin{example} +\begin{codeblock} +template struct Pair { }; +template struct Pair { }; +template using PairPtr = Pair; + +static_assert(template_of(^^Pair) == ^^Pair); +static_assert(template_of(^^Pair) == ^^Pair); +static_assert(template_arguments_of(^^Pair).size() == 2); +static_assert(template_arguments_of(^^Pair)[0] == ^^int); + +static_assert(template_of(^^PairPtr) == ^^PairPtr); +static_assert(template_arguments_of(^^PairPtr).size() == 1); + +struct S { }; +int i; +template class> + struct X { }; +constexpr auto T = ^^X<1, i, S{}, PairPtr>; +static_assert(is_value(template_arguments_of(T)[0])); +static_assert(is_object(template_arguments_of(T)[1])); +static_assert(is_object(template_arguments_of(T)[2])); +static_assert(template_arguments_of(T)[3] == ^^PairPtr); +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibraryglobal{parameters_of}% +\begin{itemdecl} +consteval vector parameters_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{itemize} +\item + If \tcode{r} represents a function $F$, + then a \tcode{vector} containing reflections of the parameters of $F$, + in the order in which they appear in a declaration of $F$. +\item + Otherwise, \tcode{r} represents a function type $T$; + a \tcode{vector} containing reflections of the types + in parameter-type-list\iref{dcl.fct} of $T$, + in the order in which they appear in the parameter-type-list. +\end{itemize} + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{r} represents a function or a function type. +\end{itemdescr} + +\indexlibraryglobal{variable_of}% +\begin{itemdecl} +consteval info variable_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The reflection of the parameter variable corresponding to \tcode{r}. + +\pnum +\throws +\tcode{meta::exception} unless +\begin{itemize} +\item + \tcode{r} represents a parameter of a function $F$ and +\item + there is a point $P$ in the evaluation context + for which the innermost non-block scope enclosing $P$ + is the function parameter scope\iref{basic.scope.param} + associated with $F$. +\end{itemize} +\end{itemdescr} + +\indexlibraryglobal{return_type_of}% +\begin{itemdecl} +consteval info return_type_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The reflection of the return type +of the function or function type represented by \tcode{r}. + +\pnum +\throws +\tcode{meta::exception} unless +either \tcode{r} represents a function +and \tcode{\exposid{has-type}(r)} is \tcode{true} +or \tcode{r} represents a function type. +\end{itemdescr} + +\rSec2[meta.reflection.scope]{Scope identification} + +\pnum +The functions in this subclause retrieve information +about where in the program they are invoked. + +\pnum +None of the functions in this subclause +is an addressable function\iref{namespace.std}. + +\pnum +Given a program point $P$, +let \tcode{\exposid{eval-point}($P$)} be the following program point: +\begin{itemize} +\item + If a potentially-evaluated subexpression\iref{intro.execution} + of a default member initializer $I$ + for a member of class $C$\iref{class.mem.general} + appears at $P$, + then a point determined as follows: + \begin{itemize} + \item + If an aggregate initialization is using $I$, + \tcode{\exposid{eval-point}($Q$)}, + where $Q$ is the point at which that aggregate initialization appears. + \item + Otherwise, if an initialization + by an inherited constructor\iref{class.inhctor.init} is using $I$, + a point whose immediate scope is the class scope corresponding to $C$. + \item + Otherwise, a point whose immediate scope + is the function parameter scope + corresponding to the constructor definition that is using $I$. + \end{itemize} + \item + Otherwise, if a potentially-evaluated subexpression + of a default argument\iref{dcl.fct.default} appears at $P$, + \tcode{\exposid{eval-point}($Q$)}, + where $Q$ is the point at which the invocation of the function\iref{expr.call} + using that default argument appears. + \item + Otherwise, if the immediate scope of $P$ + is a function parameter scope introduced by a declaration $D$, + and $P$ appears either before the locus of $D$ + or within the trailing \grammarterm{requires-clause} of $D$, + a point whose immediate scope is the innermost scope enclosing the locus of $D$ + that is not a template parameter scope. + \item + Otherwise, if the immediate scope of $P$ + is a function parameter scope + introduced by a \grammarterm{lambda-expression} $L$ + whose \grammarterm{lambda-introducer} appears at point $Q$, + and $P$ appears either within the \grammarterm{trailing-return-type} + or the trailing \grammarterm{requires-clause} of $L$, + \tcode{\exposid{eval-point}($Q$)}. + \item + Otherwise, if the innermost non-block scope enclosing $P$ + is the function parameter scope + introduced by a \grammarterm{consteval-block-declaration}\iref{dcl.pre}, + a point whose immediate scope is that inhabited + by the outermost \grammarterm{consteval-block-declaration} $D$ + containing $P$ such that each scope (if any) that intervenes between $P$ + and the function parameter scope introduced by $D$ is either + \begin{itemize} + \item + a block scope or + \item + a function parameter scope or lambda scope + introduced by a \grammarterm{consteval-block-declaration}. + \end{itemize} + \item + Otherwise, $P$. +\end{itemize} + +\pnum +Given a scope $S$, +let \tcode{\exposid{ctx-scope}($S$)} be the following scope: +\begin{itemize} +\item + If $S$ is a class scope or namespace scope, + $S$. +\item + Otherwise, if $S$ is a function parameter scope + introduced by the declaration of a function, + $S$. +\item + Otherwise, if $S$ is a lambda scope + introduced by a \grammarterm{lambda-expression} $L$, + the function parameter scope + corresponding to the call operator of the closure type of $L$. +\item + Otherwise, \tcode{\exposid{ctx-scope}($S'$)}, + where $S'$ is the parent scope of $S$. +\end{itemize} + +\pnum +Let \tcode{\exposid{CURRENT-SCOPE}($P$)} for a point $P$ be +a reflection representing the function, class, or namespace +whose corresponding +function parameter scope, +class scope, or +namespace scope, respectively, +is \tcode{\exposid{ctx-scope}($S$)}, +where $S$ is the immediate scope of \tcode{\exposid{eval-point}($P$)}. + +\indexlibraryglobal{current_function}% +\begin{itemdecl} +consteval info current_function(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +An invocation of \tcode{current_function} that appears at a program point $P$ +is value-dependent\iref{temp.dep.constexpr} +if \tcode{\exposid{eval-point}($P$)} +is enclosed by a scope corresponding to a templated entity. + +\pnum +Let $S$ be \tcode{\exposid{CURRENT-SCOPE}($P$)}, +where $P$ is the point at which the invocation of +\tcode{current_function} lexically appears. + +\pnum +\returns +$S$. + +\pnum +\throws +\tcode{meta::exception} unless $S$ represents a function. +\end{itemdescr} + +\indexlibraryglobal{current_class}% +\begin{itemdecl} +consteval info current_class(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +An invocation of \tcode{current_class} that appears at a program point $P$ +is value-dependent\iref{temp.dep.constexpr} +if \tcode{\exposid{eval-point}($P$)} +is enclosed by a scope corresponding to a templated entity. + +\pnum +Let $S$ be \tcode{\exposid{CURRENT-SCOPE}($P$)} +where $P$ is the point at which the invocation of +\tcode{current_class} lexically appears. + +\pnum +\returns +$S$ if $S$ represents a class. +Otherwise, \tcode{parent_of($S$)}. + +\pnum +\throws +\tcode{meta::exception} unless $S$ represents +either a class or a member function. +\end{itemdescr} + +\indexlibraryglobal{current_namespace}% +\begin{itemdecl} +consteval info current_namespace(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +An invocation of \tcode{current_namespace} that appears at a program point $P$ +is value-dependent\iref{temp.dep.constexpr} +if \tcode{\exposid{eval-point}($P$)} +is enclosed by a scope corresponding to a templated entity. + +\pnum +Let $S$ be \tcode{\exposid{CURRENT-SCOPE}($P$)} +where $P$ is the point at which the invocation of +\tcode{current_namespace} lexically appears. + +\pnum +\returns +$S$ if $S$ represents a namespace. +Otherwise, a reflection representing the nearest enclosing namespace +of the entity represented by $S$. +\end{itemdescr} + +\rSec2[meta.reflection.access.context]{Access control context} + +\pnum +The class \tcode{access_context} +represents a namespace, class, or function +from which queries pertaining to access rules may be performed, +as well as the designating class\iref{class.access.base}, if any. + +\indexlibraryglobal{access_context}% +\pnum +An \tcode{access_context} has an associated scope and designating class. + +\indexlibraryglobal{access_context}% +\begin{codeblock} +namespace std::meta { + struct access_context { + access_context() = delete; + + consteval info scope() const; + consteval info designating_class() const; + + static consteval access_context current() noexcept; + static consteval access_context unprivileged() noexcept; + static consteval access_context unchecked() noexcept; + consteval access_context via(info cls) const; + }; +} +\end{codeblock} + +\pnum +The type \tcode{access_context} is a structural, non-aggregate type. +A value \tcode{ac} of type \tcode{access_context} is consteval-only if +either \tcode{ac.scope()} or \tcode{ac.designating_class()} is consteval-only. +Two values \tcode{ac1} and \tcode{ac2} of type \tcode{access_context} +are template-argument-equivalent\iref{temp.type} +if \tcode{ac1.scope()} and \tcode{ac2.scope()} are template-argument-equivalent +and \tcode{ac1.designating_class()} and \tcode{ac2.designating_class()} +are template-argument-equivalent. + +\begin{itemdecl} +consteval info @\libmember{scope}{access_context}@() const; +consteval info @\libmember{designating_class}{access_context}@() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The \tcode{access_context}'s associated scope +and designating class, respectively. +\end{itemdescr} + +\begin{itemdecl} +static consteval access_context @\libmember{current}{access_context}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An \tcode{access_context} whose designating class is the null reflection +and whose scope is \tcode{\exposid{CURRENT-SCOPE}($P$)}, +where $P$ is the point at which the invocation of \tcode{current} lexically appears. + +\pnum +\remarks +\tcode{current} is not an addressable function\iref{namespace.std}. +An invocation of \tcode{current} that appears at a program point $P$ +is value-dependent\iref{temp.dep.constexpr} +if \tcode{\exposid{eval-point}\brk{}(\brk{}$P$)} is enclosed by a scope +corresponding to a templated entity. + +\pnum +\begin{example} +\begin{codeblock} +struct A { + int a = 0; + consteval A(int p) : a(p) {} +}; +struct B : A { + using A::A; + consteval B(int p, int q) : A(p * q) {} + info s = access_context::current().scope(); +}; +struct C : B { using B::B; }; + +struct Agg { + consteval bool eq(info rhs = access_context::current().scope()) { + return s == rhs; + } + info s = access_context::current().scope(); +}; + +namespace NS { + static_assert(Agg{}.s == access_context::current().scope()); + static_assert(Agg{}.eq()); + static_assert(B(1).s == ^^B); + static_assert(is_constructor(B{1, 2}.s) && parent_of(B{1, 2}.s) == ^^B); + static_assert(is_constructor(C{1, 2}.s) && parent_of(C{1, 2}.s) == ^^B); + + auto fn() -> [:is_namespace(access_context::current().scope()) ? ^^int : ^^bool:]; + static_assert(type_of(^^fn) == ^^auto()->int); + + template + struct TCls { + consteval bool fn() + requires (is_type(access_context::current().scope())) { + return true; // OK, scope is \tcode{TCls}. + } + }; + static_assert(TCls<0>{}.fn()); +} +\end{codeblock} +\end{example} +\end{itemdescr} + +\begin{itemdecl} +static consteval access_context @\libmember{unprivileged}{access_context}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An \tcode{access_context} whose designating class is the null reflection +and whose scope is the global namespace. +\end{itemdescr} + +\begin{itemdecl} +static consteval access_context @\libmember{unchecked}{access_context}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An \tcode{access_context} whose designating class and scope +are both the null reflection. +\end{itemdescr} + +\begin{itemdecl} +consteval access_context @\libmember{via}{access_context}@(info cls) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An \tcode{access_context} whose scope is \tcode{this->scope()} +and whose designating class is \tcode{cls}. + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{cls} is either the null reflection +or a reflection of a complete class type. +\end{itemdescr} + +\rSec2[meta.reflection.access.queries]{Member accessibility queries} + +\indexlibraryglobal{is_accessible}% +\begin{itemdecl} +consteval bool is_accessible(info r, access_context ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{\exposid{PARENT-CLS}(r)} be: +\begin{itemize} +\item If \tcode{parent_of(r)} represents a class $C$, then $C$. +\item Otherwise, \tcode{\exposid{PARENT-CLS}(parent_of(r))}. +\end{itemize} + +\pnum +Let \tcode{\exposid{DESIGNATING-CLS}(r, ctx)} be: +\begin{itemize} +\item If \tcode{ctx.designating_class()} represents a class $C$, then $C$. +\item Otherwise, \tcode{\exposid{PARENT-CLS}(r)}. +\end{itemize} + +\pnum +\returns +\begin{itemize} +\item + If \tcode{r} represents an unnamed bit-field $F$, + then \tcode{is_accessible($\tcode{r}_H$, ctx)}, + where $\tcode{r}_H$ represents a hypothetical non-static data member + of the class represented by \tcode{\exposid{PARENT-CLS}(r)} + with the same access as $F$. + \begin{note} + Unnamed bit-fields are treated as class members + for the purpose of \tcode{is_accessible}. + \end{note} +\item + Otherwise, if \tcode{r} does not represent a class member + or a direct base class relationship, + then \tcode{true}. +\item + Otherwise, if \tcode{r} represents + \begin{itemize} + \item + a class member that is not a (possibly indirect or variant) + member of \tcode{\exposid{DESIG\-NATING-CLS}(\brk{}r, ctx)} or + \item + a direct base class relationship such that \tcode{parent_of(r)} + does not represent \tcode{\exposid{DESIG\-NATING-CLS}(\brk{}r, ctx)} + or a (direct or indirect) base class thereof, + \end{itemize} + then \tcode{false}. +\item + Otherwise, if \tcode{ctx.scope()} is the null reflection, + then \tcode{true}. +\item + Otherwise, letting $P$ be a program point whose immediate scope is the + function parameter scope, class scope, or namespace scope + corresponding to the + function, class, or namespace + represented by \tcode{ctx.scope()}: + \begin{itemize} + \item + If \tcode{r} represents a direct base class relationship $(D, B)$, + then \tcode{true} if base class $B$ of \tcode{\exposid{DESIG\-NATING-CLS}(\brk{}r, ctx)} + is accessible at $P$\iref{class.access.base}; + otherwise \tcode{false}. + \item + Otherwise, \tcode{r} represents a class member $M$; + \tcode{true} if $M$ would be accessible at $P$ + with the designating class\iref{class.access.base} as \tcode{\exposid{DESIG\-NATING-CLS}(r, ctx)} + if the effect of any \grammarterm{using-declaration}s\iref{namespace.udecl} were ignored. + Otherwise, \tcode{false}. + \end{itemize} +\end{itemize} +\begin{note} +The definitions of when a class member or base class is accessible from a point $P$ +do not consider whether a declaration of that entity is reachable from $P$. +\end{note} + +\pnum +\throws +\tcode{meta::exception} if + \tcode{r} represents a class member + for which \tcode{\exposid{PARENT-CLS}(r)} is an incomplete class. + +\pnum +\begin{example} +\begin{codeblock} +consteval access_context fn() { + return access_context::current(); +} + +class Cls { + int mem; + friend consteval access_context fn(); +public: + static constexpr auto r = ^^mem; +}; + +static_assert(is_accessible(Cls::r, fn())); +static_assert(!is_accessible(Cls::r, access_context::current())); +static_assert(is_accessible(Cls::r, access_context::unchecked())); +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibraryglobal{has_inaccessible_nonstatic_data_members}% +\begin{itemdecl} +consteval bool has_inaccessible_nonstatic_data_members(info r, access_context ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{is_accessible($R$, ctx)} is \tcode{false} +for any $R$ in \tcode{nonstatic_data_members_of(\brk{}r, access_context\brk{}::unchecked())}. +Otherwise, \tcode{false}. + +\pnum +\throws +\tcode{meta::exception} if +\begin{itemize} +\item + the evaluation of + \tcode{nonstatic_data_members_of(r, access_context::unchecked())} + would exit via an exception or +\item + \tcode{r} represents a closure type. +\end{itemize} +\end{itemdescr} + +\indexlibraryglobal{has_inaccessible_bases}% +\begin{itemdecl} +consteval bool has_inaccessible_bases(info r, access_context ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{is_accessible($R$, ctx)} is \tcode{false} +for any $R$ in \tcode{bases_of(\brk{}r, access_context::\brk{}unchecked())}. +Otherwise, \tcode{false}. + +\pnum +\throws +\tcode{meta::exception} if the evaluation of +\tcode{bases_of(r, access_context::unchecked())} +would exit via an exception. +\end{itemdescr} + +\indexlibraryglobal{has_inaccessible_subobjects}% +\begin{itemdecl} +consteval bool has_inaccessible_subobjects(info r, access_context ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return has_inaccessible_bases(r, ctx) || has_inaccessible_nonstatic_data_members(r, ctx); +\end{codeblock} +\end{itemdescr} + +\rSec2[meta.reflection.member.queries]{Reflection member queries} + +\indexlibraryglobal{members_of}% +\begin{itemdecl} +consteval vector members_of(info r, access_context ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +A declaration $D$ \term{members-of-precedes} a point $P$ +if $D$ precedes either $P$ +or the point immediately following the \grammarterm{class-specifier} +of the outermost class for which $P$ is in a complete-class context. + +\pnum +A declaration $D$ of a member $M$ of a class or namespace $Q$ is +\term{$Q$-members-of-eligible} if +\begin{itemize} +\item + the host scope of $D$\iref{basic.scope.scope} + is the class scope or namespace scope associated with $Q$, +\item + $D$ is not a friend declaration, +\item + $M$ is not a closure type\iref{expr.prim.lambda.closure}, +\item + $M$ is not a specialization of a template\iref{temp.pre}, +\item + if $Q$ is a class that is not a closure type, + then $M$ is a direct member of $Q$\iref{class.mem.general} + that is not a variant member of a + nested anonymous union of $Q$\iref{class.union.anon}, and +\item + if $Q$ is a closure type, + then $M$ is a function call operator or function call operator template. +\end{itemize} +It is \impldef{whether declarations of some members of a closure type $Q$ +are $Q$-members-of-eligible} +whether declarations of other members of a closure type $Q$ +are $Q$-members-of-eligible. + +\pnum +A member $M$ of a class or namespace $Q$ is +\term{$Q$-members-of-representable} from a point $P$ +if a $Q$-members-of-eligible declaration of $M$ members-of-precedes $P$, +and $M$ is +\begin{itemize} +\item + a class or enumeration type, +\item + a type alias, +\item + a class template, function template, + variable template, alias template, or concept, +\item + a variable or reference $V$ + for which the type of $V$ does not contain an undeduced placeholder type, +\item + a function $F$ for which + \begin{itemize} + \item + the type of $F$ does not contain an undeduced placeholder type, + \item + the constraints (if any) of $F$ are satisfied, and + \item + if $F$ is a prospective destructor, + $F$ is the selected destructor\iref{class.dtor}, + \end{itemize} +\item + a non-static data member, +\item + a namespace, or +\item + a namespace alias. +\end{itemize} +\begin{note} +Examples of direct members that are not $Q$-members-of-representable +for any entity $Q$ include: +unscoped enumerators\iref{enum}, +partial specializations of templates\iref{temp.spec.partial}, and +closure types\iref{expr.prim.lambda.closure}. +\end{note} + +\pnum +\returns +A \tcode{vector} containing reflections of all members $M$ +of the entity $Q$ represented by \tcode{dealias(r)} for which +\begin{itemize} +\item + $M$ is $Q$-members-of-representable + from some point in the evaluation context and +\item + \tcode{is_accessible(\reflexpr{$M$}, ctx)} is \tcode{true}. +\end{itemize} +If \tcode{dealias(r)} represents a class $C$, +then the \tcode{vector} also contains reflections +representing all unnamed bit-fields $B$ +whose declarations inhabit the class scope corresponding to $C$ +for which \tcode{is_accessible(\reflexpr{$B$}, ctx)} is \tcode{true}. +Reflections of class members and unnamed bit-fields that are declared +appear in the order in which they are declared. +\begin{note} +Base classes are not members. +Implicitly-declared special members +appear after any user-declared members\iref{special}. +\end{note} + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{dealias(r)} is a reflection representing either +a class type that is complete from some point in the evaluation context +or a namespace. + +\pnum +\begin{example} +\begin{codeblock} +// TU1 +export module M; +namespace NS { + export int m; + static int l; +} +static_assert(members_of(^^NS, access_context::current()).size() == 2); + +// TU2 +import M; + +static_assert( // \tcode{NS::l} does not precede + members_of(^^NS, access_context::current()).size() == 1); // the \grammarterm{constant-expression}\iref{basic.lookup} + +class B {}; + +struct S : B { +private: + class I; +public: + int m; +}; + +static_assert( // 6 special members, + members_of(^^S, access_context::current()).size() == 7); // 1 public member, + // does not include base + +static_assert( // all of the above, + members_of(^^S, access_context::unchecked()).size() == 8); // as well as a reflection + // representing \tcode{S::I} +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibraryglobal{bases_of}% +\begin{itemdecl} +consteval vector bases_of(info type, access_context ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +Let $C$ be the class represented by \tcode{dealias(type)}. +A \tcode{vector} containing the reflections +of all the direct base class relationships $B$, if any, +of $C$ such that \tcode{is_accessible(\reflexpr{$B$}, ctx)} is \tcode{true}. +The direct base class relationships appear in the order in which +the corresponding base classes appear in the \grammarterm{base-specifier-list} of $C$. + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{dealias(type)} represents a class type +that is complete from some point in the evaluation context. +\end{itemdescr} + +\indexlibraryglobal{static_data_members_of}% +\begin{itemdecl} +consteval vector static_data_members_of(info type, access_context ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{vector} containing each element \tcode{e} of \tcode{members_of(type, ctx)} +such that \tcode{is_variable(e)} is \tcode{true}, +preserving their order. + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{dealias(type)} represents a class type +that is complete from some point in the evaluation context. +\end{itemdescr} + + +\indexlibraryglobal{nonstatic_data_members_of}% +\begin{itemdecl} +consteval vector nonstatic_data_members_of(info type, access_context ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{vector} containing each element \tcode{e} of \tcode{members_of(type, ctx)} +such that \tcode{is_nonstatic_data_member(e)} is \tcode{true}, +preserving their order. + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{dealias(type)} represents a class type +that is complete from some point in the evaluation context. +\end{itemdescr} + +\indexlibraryglobal{subobjects_of}% +\begin{itemdecl} +consteval vector subobjects_of(info type, access_context ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{vector} containing each element of \tcode{bases_of(type, ctx)} +followed by each element of \tcode{non\-static_data_mem\-bers_of(\brk{}type,\brk{} ctx)}, +preserving their order. + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{dealias(type)} represents a class type +that is complete from some point in the evaluation context. +\end{itemdescr} + +\indexlibraryglobal{enumerators_of}% +\begin{itemdecl} +consteval vector enumerators_of(info type_enum); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{vector} containing the reflections of each enumerator +of the enumeration represented by \tcode{dealias(type_enum)}, +in the order in which they are declared. + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{dealias(type_enum)} represents an enumeration type, +and \tcode{is_enumerable_type(\brk{}type_enum)} is \tcode{true}. +\end{itemdescr} + +\rSec2[meta.reflection.layout]{Reflection layout queries} + +\indexlibraryglobal{member_offset}% +\indexlibrarymember{member_offset}{total_bits}% +\begin{itemdecl} +struct member_offset { + ptrdiff_t bytes; + ptrdiff_t bits; + constexpr ptrdiff_t total_bits() const; + auto operator<=>(const member_offset&) const = default; +}; + +constexpr ptrdiff_t member_offset::total_bits() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{bytes * CHAR_BIT + bits}. +\end{itemdescr} + +\indexlibraryglobal{offset_of}% +\begin{itemdecl} +consteval member_offset offset_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $V$ be the offset in bits from the beginning of a complete object +of the type represented by \tcode{parent_of(r)} +to the subobject associated with the construct represented by \tcode{r}. + +\pnum +\returns +\tcode{\{$V$ / CHAR_BIT, $V$ \% CHAR_BIT\}}. + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{r} represents a non-static data member, +unnamed bit-field, or +direct base class relationship $(D, B)$ +for which either $B$ is not a virtual base class +or $D$ is not an abstract class. +\end{itemdescr} + +\indexlibraryglobal{size_of}% +\begin{itemdecl} +consteval size_t size_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If +\begin{itemize} +\item \tcode{r} represents a non-static data member of type $T$ or +a data member description $(T, N, A, W, \mathit{NUA},\brk{} \mathit{ANN})$ or +\item \tcode{dealias(r)} represents a type $T$, +\end{itemize} +then \tcode{sizeof($T$)} if $T$ is not a reference type +and \tcode{size_of(add_pointer(\brk{}\reflexpr{$T$}))} otherwise. +Otherwise, \tcode{size_of(type_of(r))}. +\begin{note} +It is possible that while \tcode{sizeof(char)\brk{} == size_of(\reflexpr{char})} +is \tcode{true}, +that \tcode{sizeof(char\&)\brk{} == size_of(\brk{}\reflexpr{char}\&)} +is \tcode{false}. +If \tcode{b} represents a direct base class relationship of an empty base class, +then \tcode{size_of(b) > 0} is \tcode{true}. +\end{note} + +\pnum +\throws +\tcode{meta::exception} unless +all of the following conditions are met: +\begin{itemize} +\item +\tcode{dealias(r)} is a reflection of a +type, +object, +value, +variable of non-reference type, +non-static data member that is not a bit-field, +direct base class relationship, or +data member description $(T, N, A, W, \mathit{NUA}, \mathit{ANN})$\iref{class.mem.general} +where $W$ is $\bot$. +\item +If \tcode{dealias(r)} represents a type, +then \tcode{is_complete_type(r)} is \tcode{true}. +\end{itemize} +\end{itemdescr} + +\indexlibraryglobal{alignment_of}% +\begin{itemdecl} +consteval size_t alignment_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{itemize} +\item + If \tcode{dealias(r)} represents a type $T$, + then \tcode{alignment_of(add_pointer(r))} if $T$ is a reference type + and the alignment requirement of $T$ otherwise. +\item + Otherwise, if \tcode{dealias(r)} represents a variable or object, + then the alignment requirement of the variable or object. +\item + Otherwise, if \tcode{r} represents a direct base class relationship, + then \tcode{alignment_of(type_of(r))}. +\item + Otherwise, if \tcode{r} represents a non-static data member $M$ of a class $C$, + then the alignment of the direct member subobject + corresponding to $M$ of a complete object of type $C$. +\item + Otherwise, \tcode{r} represents a data member description + $(T, N, A, W, \mathit{NUA}, \mathit{ANN})$\iref{class.mem.general}. + If $A$ is not $\bot$, + then the value $A$. + Otherwise, \tcode{alignment_of(\reflexpr{$T$})}. +\end{itemize} + +\pnum +\throws +\tcode{meta::exception} unless +all of the following conditions are met: +\begin{itemize} +\item +\tcode{dealias(r)} is a reflection of a +type, +object, +variable of non-reference type, +non-static data member that is not a bit-field, +direct base class relationship, or +data member description +$(T, N, A, W, \mathit{NUA}, \mathit{ANN})$\iref{class.mem.general} +where $W$ is $\bot$. +\item +If \tcode{dealias(r)} represents a type, +then \tcode{is_complete_type(r)} is \tcode{true}. +\end{itemize} +\end{itemdescr} + +\indexlibraryglobal{bit_size_of}% +\begin{itemdecl} +consteval size_t bit_size_of(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{itemize} +\item + If \tcode{r} represents + an unnamed bit-field + or a non-static data member that is a bit-field + with width $W$, + then $W$. +\item + Otherwise, if \tcode{r} represents a data member description + $(T, N, A, W, \mathit{NUA}, \mathit{ANN})$\iref{class.mem.general} + and $W$ is not $\bot$, + then $W$. +\item + Otherwise, \tcode{CHAR_BIT * size_of(r)}. +\end{itemize} + +\pnum +\throws +\tcode{meta::exception} unless +all of the following conditions are met: +\begin{itemize} +\item +\tcode{dealias(r)} is a reflection of a +type, +object, +value, +variable of non-reference type, +non-static data member, +unnamed bit-field, +direct base class relationship, or +data member description. +\item +If \tcode{dealias(r)} represents a type, +then \tcode{is_complete_type(r)} is \tcode{true}. +\end{itemize} +\end{itemdescr} + +\rSec2[meta.reflection.annotation]{Annotation reflection} + +\indexlibraryglobal{annotations_of}% +\begin{itemdecl} +consteval vector annotations_of(info item); +\end{itemdecl} + +\begin{itemdescr} +\pnum +For a function $F$, +let $S(F)$ be the set of declarations, +ignoring any explicit instantiations, +that declare either $F$ or +a templated function of which $F$ is a specialization. + +\pnum +\returns +A \tcode{vector} containing all of the reflections $R$ +representing each annotation applying to: +\begin{itemize} +\item + if \tcode{item} represents a function parameter $P$ of a function $F$, + then the declaration of $P$ in each declaration of $F$ in $S(F)$, +\item + otherwise, if \tcode{item} represents a function $F$, + then each declaration of $F$ in $S(F)$, +\item + otherwise, if \tcode{item} represents + a direct base class relationship $(D, B)$, + then the corresponding \grammarterm{base-specifier} + in the definition of $D$, +\item + otherwise, each declaration of the entity represented by \tcode{item}, +\end{itemize} +such that each specified declaration is reachable from either +some point in the evaluation context\iref{expr.const.reflect} or +a point immediately following the \grammarterm{class-specifier} +of the outermost class for which such a point is in a complete-class context. +For any two reflections $R_1$ and $R_2$ in the returned \tcode{vector}, +if the annotation represented by $R_1$ precedes the annotation represented by $R_2$, +then $R_1$ appears before $R_2$. +If $R_1$ and $R_2$ represent annotations from the same translation unit $T$, +any element in the returned \tcode{vector} between $R_1$ and $R_2$ +represents an annotation from $T$. +\begin{note} +The order in which two annotations appear is otherwise unspecified. +\end{note} + +\pnum +\throws +\tcode{meta::exception} unless +\tcode{item} represents a +type, +type alias, +variable, +function, +function parameter, +namespace, +enumerator, +direct base class relationship, or +non-static data member. + +\pnum +\begin{example} +\begin{codeblock} +[[=1]] void f(); +[[=2, =3]] void g(); +void g [[=4]] (); + +static_assert(annotations_of(^^f).size() == 1); +static_assert(annotations_of(^^g).size() == 3); +static_assert([: constant_of(annotations_of(^^g)[0]) :] == 2); +static_assert(extract(annotations_of(^^g)[1]) == 3); +static_assert(extract(annotations_of(^^g)[2]) == 4); + +struct Option { bool value; }; + +struct C { + [[=Option{true}]] int a; + [[=Option{false}]] int b; +}; + +static_assert(extract(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} @@ -7616,7 +8290,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 {}; @@ -7624,7 +8298,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} @@ -7679,7 +8353,7 @@ 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. @@ -7688,11 +8362,10 @@ 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 -performed instead for each element of the initializer list independently, -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, +instead performed as if +each element of the initializer list were the argument +for a separate parameter having type $\tcode{P}'$. +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}. @@ -7881,7 +8554,8 @@ is a class and \tcode{P} has the form -\grammarterm{simple-template-id}, +\grammarterm{simple-template-id} or +\opt{\keyword{typename}} \grammarterm{splice-specialization-specifier}, then the transformed \tcode{A} can be a derived class \tcode{D} of the @@ -7890,10 +8564,11 @@ Likewise, if \tcode{P} is a pointer to a class of the form -\grammarterm{simple-template-id}, +\grammarterm{simple-template-id} or +\opt{\keyword{typename}} \grammarterm{splice-specialization-specifier}, the transformed \tcode{A} can be a pointer to a -derived class \tcode{D} pointed to by the deduced +derived class \tcode{D} of the class pointed to by the deduced \tcode{A}. However, if there is a class \tcode{C} that is a (direct or indirect) base class of \tcode{D} and @@ -7926,8 +8601,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} @@ -8032,7 +8706,7 @@ \tcode{P}) with the type specified by the \grammarterm{conversion-type-id} of the \grammarterm{conversion-function-id} being looked up -(call it \tcode{A}) as described in~\ref{temp.deduct.type}. +(call it \tcode{A}), as described in~\ref{temp.deduct.type}. If the \grammarterm{conversion-function-id} is constructed during overload resolution\iref{over.match.funcs}, the rules in the remainder of this subclause apply. @@ -8212,18 +8886,16 @@ \end{itemize} \pnum -Using the resulting types -\tcode{P} -and -\tcode{A}, +If \tcode{A} was transformed from a function parameter pack and +\tcode{P} is not a parameter pack, +type deduction fails. +Otherwise, using the resulting types \tcode{P} and \tcode{A}, the deduction is then done as described in~\ref{temp.deduct.type}. If \tcode{P} is a function parameter pack, the type \tcode{A} of each remaining parameter type of the argument template is compared with the type \tcode{P} of the \grammarterm{declarator-id} of the function parameter pack. Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack. -Similarly, if \tcode{A} was transformed from a function parameter pack, -it is compared with each remaining parameter type of the parameter template. If deduction succeeds for a given type, the type from the argument template is considered to be at least as specialized as the type from the parameter template. @@ -8333,8 +9005,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}), @@ -8370,7 +9042,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 @@ -8382,7 +9054,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 @@ -8390,7 +9062,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. @@ -8406,7 +9078,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} @@ -8419,14 +9091,18 @@ \item The \grammarterm{nested-name-specifier} -of a type that was specified using a +of a type or template that was specified using a \grammarterm{qualified-id}. \item A \grammarterm{pack-index-specifier} or a \grammarterm{pack-index-expression}. \item +A \grammarterm{type-constraint}. +\item The \grammarterm{expression} of a \grammarterm{decltype-specifier}. \item -A non-type template argument or an array bound in which a subexpression +The \grammarterm{constant-expression} of a \grammarterm{splice-specifier}. +\item +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 @@ -8584,12 +9260,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 @@ -8606,6 +9282,7 @@ @\opt{TT}@ @\opt{TT}@ @\opt{TT}@ +@\opt{TT}@ @\opt{TT}@<> \end{codeblock} where @@ -8616,15 +9293,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 @@ -8640,22 +9317,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 @@ -8776,7 +9449,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} @@ -8858,8 +9531,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} @@ -8899,19 +9572,22 @@ \end{note} \pnum -If \tcode{P} has a form that contains \tcode{}, and -if the type of \tcode{i} differs from the type +If \tcode{P} has a form that contains \tcode{}, +deduction fails unless the type of \tcode{i} is the same as that of the corresponding template parameter -of the template named by the enclosing \grammarterm{simple-template-id}, -deduction fails. +\tcode{p} in the specialization (from \tcode{A}) +of the template named by the enclosing \grammarterm{simple-template-id} or +\grammarterm{splice-specialization-specifier}; +if the declared type of \tcode{i} contains a placeholder type, +the corresponding template argument for the purposes of +placeholder type deduction\iref{dcl.type.auto.deduct} +is an \grammarterm{id-expression} for \tcode{p}. If \tcode{P} has a form that contains \tcode{[i]}, and if the type of \tcode{i} is not an integral type, deduction fails. \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} @@ -8925,15 +9601,54 @@ template void f(A); void k1() { A<1> a; - f(a); // error: deduction fails for conversion from \tcode{int} to \tcode{short} - f<1>(a); // OK + f(a); // error: deduction fails for conversion from \tcode{int} to \tcode{short} + f<1>(a); // OK } template class B { }; template void g(B); void k2() { B<1> b; - g(b); // OK, cv-qualifiers are ignored on template parameter types + g(b); // OK, cv-qualifiers are ignored on template parameter types +} + +template struct C; +template void f(C *); +void g(C<0LL> *ap) { + f(ap); // OK, deduces \tcode{long long} value from \tcode{0LL} +} + +template struct D; +template void f(D *); +void g(D<0LL> *ap) { + f(ap); // OK, deduces \tcode{x} as an \tcode{int} value +} + +template struct E; +template void f(E *); +int v; +void g(E *bp) { + f(bp); // error: type \tcode{int} of \tcode{x} does not match the \tcode{int \&} type +} // of the template parameter in the \tcode{E} specialization of \tcode{E} + +template struct F; +template void f(F *); +int i; +void g(F *ap) { + f(ap); // OK, deduces \tcode{x} as a constant template parameter of type \tcode{const int \&} +} + +template struct G; +template long *f(G *); // \#1 +template short *f(G *); // \#2 + +const int j = 0; +short *g(G<(j)> *ap) { // OK, \tcode{q} has type \tcode{const int \&} + return f(ap); // OK, only \#2 matches +} + +long *g(G *ap) { // OK, \tcode{q} has type \tcode{int} + return f(ap); // OK, \#1 is more specialized } \end{codeblock} \end{example} @@ -8979,8 +9694,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. @@ -9029,12 +9743,12 @@ for explicit instantiations\iref{temp.explicit}, explicit specializations\iref{temp.expl.spec}, and certain friend declarations\iref{temp.friend}. This is also done to determine whether a deallocation function template specialization matches a placement -\tcode{operator new}\iref{basic.stc.dynamic.deallocation,expr.new}. +allocation function\iref{basic.stc.dynamic.deallocation,expr.new}. In all these cases, \tcode{P} is the type of the function template being considered as a potential match and \tcode{A} is either the function type from the declaration or the type of the deallocation function that would match the placement -\tcode{operator new} as described in~\ref{expr.new}. The +allocation function as described in~\ref{expr.new}. The deduction is done as described in~\ref{temp.deduct.type}. \pnum @@ -9117,8 +9831,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@ }; @@ -9134,8 +9847,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 index 4e8548b088..3d885dde58 100644 --- a/source/text.tex +++ b/source/text.tex @@ -10,8 +10,8 @@ \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{format} & Formatting & \tcode{} \\ \rowsep \ref{re} & Regular expressions library & \tcode{} \\ \rowsep \ref{text.c.strings} & Null-terminated sequence utilities & \tcode{}, \tcode{}, \tcode{}, \tcode{}, \tcode{} \\ @@ -25,7 +25,7 @@ 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 +for \tcode{char} and all signed and unsigned integer types in lieu of \tcode{\placeholder{integer-type}}. When a function is specified with a type placeholder of \tcode{\placeholder{floating-point-type}}, @@ -174,13 +174,18 @@ \begin{itemdescr} \pnum \effects +Let \tcode{T} be \tcode{\placeholder{floating-point-type}}. \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}. +The conversion specifier is \tcode{f} if +the absolute value of \tcode{value} is in the range \range{$l$}{$u$}, where +$l$ is the smallest value larger than or equal to $10^{-4}$ +that is representable by \tcode{T} and +$u$ is the largest value smaller than or equal to +$\tcode{numeric_limits::radix}^{\tcode{numeric_limits::digits + 1}}$ +rounded down to the nearest power of 10 representable by \tcode{T}, +otherwise \tcode{e}. \pnum \throws @@ -233,7 +238,7 @@ Nothing. \end{itemdescr} -\xrefc{7.21.6.1} +\xrefc{7.23.6.2} \rSec2[charconv.from.chars]{Primitive numeric input conversion} @@ -289,7 +294,10 @@ 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 +except that +no \tcode{"0b"} or \tcode{"0B"} prefix shall appear +if the value of \tcode{base} is 2, +no \tcode{"0x"} or \tcode{"0X"} prefix shall appear if the value of \tcode{base} is 16, and except that \tcode{'-'} is the only sign that may appear, @@ -348,7 +356,7 @@ Nothing. \end{itemdescr} -\xrefc{7.22.1.3, 7.22.1.4} +\xrefc{7.24.2.6, 7.24.2.8} \rSec1[localization]{Localization library} @@ -485,7 +493,7 @@ collate = 0x010, ctype = 0x020, monetary = 0x040, numeric = 0x080, time = 0x100, messages = 0x200, - all = collate | ctype | monetary | numeric | time | messages; + all = collate | ctype | monetary | numeric | time | messages; // \ref{locale.cons}, construct/copy/destroy locale() noexcept; @@ -803,7 +811,7 @@ 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}, +All one-argument constructors defined in this Clause are explicit, preventing their participation in implicit conversions. \pnum @@ -1086,13 +1094,13 @@ \begin{itemdescr} \pnum \effects -Compares two strings according to the \tcode{collate} facet. +Compares two strings according to the \tcode{std::collate} facet. \pnum \returns \begin{codeblock} -use_facet>(*this).compare(s1.data(), s1.data() + s1.size(), - s2.data(), s2.data() + s2.size()) < 0 +use_facet>(*this).compare(s1.data(), s1.data() + s1.size(), + s2.data(), s2.data() + s2.size()) < 0 \end{codeblock} \pnum @@ -1302,7 +1310,7 @@ \pnum The \tcode{put()} members make no provision for error reporting. -(Any failures of the OutputIterator argument can be extracted from +(Any failures of the \tcode{OutputIterator} argument can be extracted from the returned iterator.) The \tcode{get()} members take an \tcode{ios_base::iostate\&} argument whose value they ignore, @@ -1321,21 +1329,21 @@ namespace std { class ctype_base { public: - using mask = @\seebelow@; + using @\libmember{mask}{ctype_base}@ = @\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; + static constexpr mask @\libmember{space}{ctype_base}@ = 1 << 0; + static constexpr mask @\libmember{print}{ctype_base}@ = 1 << 1; + static constexpr mask @\libmember{cntrl}{ctype_base}@ = 1 << 2; + static constexpr mask @\libmember{upper}{ctype_base}@ = 1 << 3; + static constexpr mask @\libmember{lower}{ctype_base}@ = 1 << 4; + static constexpr mask @\libmember{alpha}{ctype_base}@ = 1 << 5; + static constexpr mask @\libmember{digit}{ctype_base}@ = 1 << 6; + static constexpr mask @\libmember{punct}{ctype_base}@ = 1 << 7; + static constexpr mask @\libmember{xdigit}{ctype_base}@ = 1 << 8; + static constexpr mask @\libmember{blank}{ctype_base}@ = 1 << 9; + static constexpr mask @\libmember{alnum}{ctype_base}@ = alpha | digit; + static constexpr mask @\libmember{graph}{ctype_base}@ = alnum | punct; }; } \end{codeblock} @@ -1351,44 +1359,44 @@ \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; - }; + class ctype : public locale::facet, public ctype_base { + public: + using @\libmember{char_type}{ctype}@ = charT; + + explicit ctype(size_t refs = 0); + + bool is(mask m, charT c) const; + const charT* is(const charT* low, const charT* high, mask* vec) const; + const charT* scan_is(mask m, const charT* low, const charT* high) const; + const charT* scan_not(mask m, const charT* low, const charT* high) const; + charT toupper(charT c) const; + const charT* toupper(charT* low, const charT* high) const; + charT tolower(charT c) const; + const charT* tolower(charT* low, const charT* high) const; + + charT widen(char c) const; + const char* widen(const char* low, const char* high, charT* to) const; + char narrow(charT c, char dfault) const; + const charT* narrow(const charT* low, const charT* high, char dfault, char* to) const; + + static locale::id @\libmember{id}{ctype}@; + + protected: + ~ctype(); + virtual bool do_is(mask m, charT c) const; + virtual const charT* do_is(const charT* low, const charT* high, mask* vec) const; + virtual const charT* do_scan_is(mask m, const charT* low, const charT* high) const; + virtual const charT* do_scan_not(mask m, const charT* low, const charT* high) const; + virtual charT do_toupper(charT) const; + virtual const charT* do_toupper(charT* low, const charT* high) const; + virtual charT do_tolower(charT) const; + virtual const charT* do_tolower(charT* low, const charT* high) const; + virtual charT do_widen(char) const; + virtual const char* do_widen(const char* low, const char* high, charT* dest) const; + virtual char do_narrow(charT, char dfault) const; + virtual const charT* do_narrow(const charT* low, const charT* high, + char dfault, char* dest) const; + }; } \end{codeblock} @@ -1682,15 +1690,15 @@ \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); + class ctype_byname : public ctype { + public: + using @\libmember{mask}{ctype_byname}@ = ctype::mask; + explicit ctype_byname(const char*, size_t refs = 0); + explicit ctype_byname(const string&, size_t refs = 0); - protected: - ~ctype_byname(); - }; + protected: + ~ctype_byname(); + }; } \end{codeblock} @@ -1702,46 +1710,46 @@ \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; - }; + class ctype : public locale::facet, public ctype_base { + public: + using @\libmember{char_type}{ctype}@ = char; + + explicit ctype(const mask* tab = nullptr, bool del = false, size_t refs = 0); + + bool is(mask m, char c) const; + const char* is(const char* low, const char* high, mask* vec) const; + const char* scan_is (mask m, const char* low, const char* high) const; + const char* scan_not(mask m, const char* low, const char* high) const; + + char toupper(char c) const; + const char* toupper(char* low, const char* high) const; + char tolower(char c) const; + const char* tolower(char* low, const char* high) const; + + char widen(char c) const; + const char* widen(const char* low, const char* high, char* to) const; + char narrow(char c, char dfault) const; + const char* narrow(const char* low, const char* high, char dfault, char* to) const; + + static locale::id @\libmember{id}{ctype}@; + static const size_t @\libmember{table_size}{ctype}@ = @\impdef@; + + const mask* table() const noexcept; + static const mask* classic_table() noexcept; + + protected: + ~ctype(); + virtual char do_toupper(char c) const; + virtual const char* do_toupper(char* low, const char* high) const; + virtual char do_tolower(char c) const; + virtual const char* do_tolower(char* low, const char* high) const; + + virtual char do_widen(char c) const; + virtual const char* do_widen(const char* low, const char* high, char* to) const; + virtual char do_narrow(char c, char dfault) const; + virtual const char* do_narrow(const char* low, const char* high, + char dfault, char* to) const; + }; } \end{codeblock} @@ -1792,7 +1800,7 @@ \pnum \expects Either \tcode{tbl == nullptr} is \tcode{true} or -\range{tbl}{tbl+table_size} is a valid range. +\range{tbl}{tbl + table_size} is a valid range. \pnum \effects @@ -1954,63 +1962,64 @@ \rSec5[locale.codecvt.general]{General} +\indexlibraryglobal{codecvt_base}% \indexlibraryglobal{codecvt}% \begin{codeblock} namespace std { class codecvt_base { public: - enum result { ok, partial, error, noconv }; + enum @\libmember{result}{codecvt_base}@ { @\libmember{ok}{codecvt_base}@, @\libmember{partial}{codecvt_base}@, @\libmember{error}{codecvt_base}@, @\libmember{noconv}{codecvt_base}@ }; }; template - class codecvt : public locale::facet, public codecvt_base { - public: - using 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; - }; + class codecvt : public locale::facet, public codecvt_base { + public: + using @\libmember{intern_type}{codecvt}@ = internT; + using @\libmember{extern_type}{codecvt}@ = externT; + using @\libmember{state_type}{codecvt}@ = stateT; + + explicit codecvt(size_t refs = 0); + + result out( + stateT& state, + const internT* from, const internT* from_end, const internT*& from_next, + externT* to, externT* to_end, externT*& to_next) const; + + result unshift( + stateT& state, + externT* to, externT* to_end, externT*& to_next) const; + + result in( + stateT& state, + const externT* from, const externT* from_end, const externT*& from_next, + internT* to, internT* to_end, internT*& to_next) const; + + int encoding() const noexcept; + bool always_noconv() const noexcept; + int length(stateT&, const externT* from, const externT* end, size_t max) const; + int max_length() const noexcept; + + static locale::id @\libmember{id}{codecvt}@; + + protected: + ~codecvt(); + virtual result do_out( + stateT& state, + const internT* from, const internT* from_end, const internT*& from_next, + externT* to, externT* to_end, externT*& to_next) const; + virtual result do_in( + stateT& state, + const externT* from, const externT* from_end, const externT*& from_next, + internT* to, internT* to_end, internT*& to_next) const; + virtual result do_unshift( + stateT& state, + externT* to, externT* to_end, externT*& to_next) const; + + virtual int do_encoding() const noexcept; + virtual bool do_always_noconv() const noexcept; + virtual int do_length(stateT&, const externT* from, const externT* end, size_t max) const; + virtual int do_max_length() const noexcept; + }; } \end{codeblock} @@ -2334,18 +2343,18 @@ \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)} +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 - 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)}. +returns the lesser of \tcode{max} and \tcode{(from_end - from)}. \end{itemdescr} \indexlibrarymember{codecvt}{do_max_length}% @@ -2369,14 +2378,14 @@ \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); + 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(); - }; + protected: + ~codecvt_byname(); + }; } \end{codeblock} @@ -2427,63 +2436,63 @@ \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; - }; + class num_get : public locale::facet { + public: + using @\libmember{char_type}{num_get}@ = charT; + using @\libmember{iter_type}{num_get}@ = InputIterator; + + explicit num_get(size_t refs = 0); + + iter_type get(iter_type in, iter_type end, ios_base&, + ios_base::iostate& err, bool& v) const; + iter_type get(iter_type in, iter_type end, ios_base&, + ios_base::iostate& err, long& v) const; + iter_type get(iter_type in, iter_type end, ios_base&, + ios_base::iostate& err, long long& v) const; + iter_type get(iter_type in, iter_type end, ios_base&, + ios_base::iostate& err, unsigned short& v) const; + iter_type get(iter_type in, iter_type end, ios_base&, + ios_base::iostate& err, unsigned int& v) const; + iter_type get(iter_type in, iter_type end, ios_base&, + ios_base::iostate& err, unsigned long& v) const; + iter_type get(iter_type in, iter_type end, ios_base&, + ios_base::iostate& err, unsigned long long& v) const; + iter_type get(iter_type in, iter_type end, ios_base&, + ios_base::iostate& err, float& v) const; + iter_type get(iter_type in, iter_type end, ios_base&, + ios_base::iostate& err, double& v) const; + iter_type get(iter_type in, iter_type end, ios_base&, + ios_base::iostate& err, long double& v) const; + iter_type get(iter_type in, iter_type end, ios_base&, + ios_base::iostate& err, void*& v) const; + + static locale::id @\libmember{id}{num_get}@; + + protected: + ~num_get(); + virtual iter_type do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& err, bool& v) const; + virtual iter_type do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& err, long& v) const; + virtual iter_type do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& err, long long& v) const; + virtual iter_type do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& err, unsigned short& v) const; + virtual iter_type do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& err, unsigned int& v) const; + virtual iter_type do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& err, unsigned long& v) const; + virtual iter_type do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& err, unsigned long long& v) const; + virtual iter_type do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& err, float& v) const; + virtual iter_type do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& err, double& v) const; + virtual iter_type do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& err, long double& v) const; + virtual iter_type do_get(iter_type, iter_type, ios_base&, + ios_base::iostate& err, void*& v) const; + }; } \end{codeblock} @@ -2806,35 +2815,35 @@ \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; - }; + class num_put : public locale::facet { + public: + using @\libmember{char_type}{num_put}@ = charT; + using @\libmember{iter_type}{num_put}@ = OutputIterator; + + explicit num_put(size_t refs = 0); + + iter_type put(iter_type s, ios_base& f, char_type fill, bool v) const; + iter_type put(iter_type s, ios_base& f, char_type fill, long v) const; + iter_type put(iter_type s, ios_base& f, char_type fill, long long v) const; + iter_type put(iter_type s, ios_base& f, char_type fill, unsigned long v) const; + iter_type put(iter_type s, ios_base& f, char_type fill, unsigned long long v) const; + iter_type put(iter_type s, ios_base& f, char_type fill, double v) const; + iter_type put(iter_type s, ios_base& f, char_type fill, long double v) const; + iter_type put(iter_type s, ios_base& f, char_type fill, const void* v) const; + + static locale::id @\libmember{id}{num_put}@; + + protected: + ~num_put(); + virtual iter_type do_put(iter_type, ios_base&, char_type fill, bool v) const; + virtual iter_type do_put(iter_type, ios_base&, char_type fill, long v) const; + virtual iter_type do_put(iter_type, ios_base&, char_type fill, long long v) const; + virtual iter_type do_put(iter_type, ios_base&, char_type fill, unsigned long) const; + virtual iter_type do_put(iter_type, ios_base&, char_type fill, unsigned long long) const; + virtual iter_type do_put(iter_type, ios_base&, char_type fill, double v) const; + virtual iter_type do_put(iter_type, ios_base&, char_type fill, long double v) const; + virtual iter_type do_put(iter_type, ios_base&, char_type fill, const void* v) const; + }; } \end{codeblock} @@ -3108,29 +3117,29 @@ \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} - }; + class numpunct : public locale::facet { + public: + using @\libmember{char_type}{numpunct}@ = charT; + using @\libmember{string_type}{numpunct}@ = basic_string; + + explicit numpunct(size_t refs = 0); + + char_type decimal_point() const; + char_type thousands_sep() const; + string grouping() const; + string_type truename() const; + string_type falsename() const; + + static locale::id @\libmember{id}{numpunct}@; + + protected: + ~numpunct(); // virtual + virtual char_type do_decimal_point() const; + virtual char_type do_thousands_sep() const; + virtual string do_grouping() const; + virtual string_type do_truename() const; // for \tcode{bool} + virtual string_type do_falsename() const; // for \tcode{bool} + }; } \end{codeblock} @@ -3226,7 +3235,7 @@ \indexlibrarymember{numpunct}{grouping}% \begin{itemdecl} -string grouping() const; +string grouping() const; \end{itemdecl} \begin{itemdescr} @@ -3329,18 +3338,18 @@ \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; + class numpunct_byname : public numpunct { + // this class is specialized for \tcode{char} and \keyword{wchar_t}. + public: + using @\libmember{char_type}{numpunct_byname}@ = charT; + using @\libmember{string_type}{numpunct_byname}@ = basic_string; - explicit numpunct_byname(const char*, size_t refs = 0); - explicit numpunct_byname(const string&, size_t refs = 0); + explicit numpunct_byname(const char*, size_t refs = 0); + explicit numpunct_byname(const string&, size_t refs = 0); - protected: - ~numpunct_byname(); - }; + protected: + ~numpunct_byname(); + }; } \end{codeblock} @@ -3354,27 +3363,27 @@ \begin{codeblock} namespace std { template - class collate : public locale::facet { - public: - using char_type = charT; - using string_type = basic_string; + class collate : public locale::facet { + public: + using @\libmember{char_type}{collate}@ = charT; + using @\libmember{string_type}{collate}@ = basic_string; - explicit collate(size_t refs = 0); + 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; + 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; + static locale::id @\libmember{id}{collate}@; - protected: - ~collate(); - virtual int do_compare(const charT* low1, const charT* high1, - const charT* low2, const charT* high2) const; - virtual string_type do_transform(const charT* low, const charT* high) const; - virtual long do_hash (const charT* low, const charT* high) const; - }; + 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} @@ -3492,16 +3501,16 @@ \begin{codeblock} namespace std { template - class collate_byname : public collate { - public: - using string_type = basic_string; + class collate_byname : public collate { + public: + using @\libmember{string_type}{collate_byname}@ = basic_string; - explicit collate_byname(const char*, size_t refs = 0); - explicit collate_byname(const string&, size_t refs = 0); + explicit collate_byname(const char*, size_t refs = 0); + explicit collate_byname(const string&, size_t refs = 0); - protected: - ~collate_byname(); - }; + protected: + ~collate_byname(); + }; } \end{codeblock} @@ -3528,57 +3537,58 @@ \rSec5[locale.time.get.general]{General} +\indexlibraryglobal{time_base}% \indexlibraryglobal{time_get}% \begin{codeblock} namespace std { class time_base { public: - enum dateorder { no_order, dmy, mdy, ymd, ydm }; + enum @\libmember{dateorder}{time_base}@ { @\libmember{no_order}{time_base}@, @\libmember{dmy}{time_base}@, @\libmember{mdy}{time_base}@, @\libmember{ymd}{time_base}@, @\libmember{ydm}{time_base}@ }; }; template> - class time_get : public locale::facet, public time_base { - public: - using char_type = charT; - using iter_type = InputIterator; - - explicit time_get(size_t refs = 0); + class time_get : public locale::facet, public time_base { + public: + using @\libmember{char_type}{time_get}@ = charT; + using @\libmember{iter_type}{time_get}@ = InputIterator; + + explicit time_get(size_t refs = 0); + + dateorder date_order() const { return do_date_order(); } + iter_type get_time(iter_type s, iter_type end, ios_base& f, + ios_base::iostate& err, tm* t) const; + iter_type get_date(iter_type s, iter_type end, ios_base& f, + ios_base::iostate& err, tm* t) const; + iter_type get_weekday(iter_type s, iter_type end, ios_base& f, + ios_base::iostate& err, tm* t) const; + iter_type get_monthname(iter_type s, iter_type end, ios_base& f, + ios_base::iostate& err, tm* t) const; + iter_type get_year(iter_type s, iter_type end, ios_base& f, + ios_base::iostate& err, tm* t) const; + iter_type get(iter_type s, iter_type end, ios_base& f, + ios_base::iostate& err, tm* t, char format, char modifier = 0) const; + iter_type get(iter_type s, iter_type end, ios_base& f, + ios_base::iostate& err, tm* t, const char_type* fmt, + const char_type* fmtend) const; + + static locale::id @\libmember{id}{time_get}@; - 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&, + 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_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; - }; + 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} @@ -3949,17 +3959,17 @@ \begin{codeblock} namespace std { template> - class time_get_byname : public time_get { - public: - using dateorder = time_base::dateorder; - using iter_type = InputIterator; + class time_get_byname : public time_get { + public: + using @\libmember{dateorder}{time_get_byname}@ = time_base::dateorder; + using @\libmember{iter_type}{time_get_byname}@ = InputIterator; - explicit time_get_byname(const char*, size_t refs = 0); - explicit time_get_byname(const string&, size_t refs = 0); + explicit time_get_byname(const char*, size_t refs = 0); + explicit time_get_byname(const string&, size_t refs = 0); - protected: - ~time_get_byname(); - }; + protected: + ~time_get_byname(); + }; } \end{codeblock} @@ -3971,26 +3981,26 @@ \begin{codeblock} namespace std { template> - class time_put : public locale::facet { - public: - using char_type = charT; - using iter_type = OutputIterator; + class time_put : public locale::facet { + public: + using @\libmember{char_type}{time_put}@ = charT; + using @\libmember{iter_type}{time_put}@ = OutputIterator; - explicit time_put(size_t refs = 0); + 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; + // 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; + static locale::id @\libmember{id}{time_put}@; - protected: - ~time_put(); - virtual iter_type do_put(iter_type s, ios_base&, char_type, const tm* t, - char format, char modifier) const; - }; + 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} @@ -4092,17 +4102,17 @@ \begin{codeblock} namespace std { template> - class time_put_byname : public time_put { - public: - using char_type = charT; - using iter_type = OutputIterator; + class time_put_byname : public time_put { + public: + using @\libmember{char_type}{time_put_byname}@ = charT; + using @\libmember{iter_type}{time_put_byname}@ = OutputIterator; - explicit time_put_byname(const char*, size_t refs = 0); - explicit time_put_byname(const string&, size_t refs = 0); + explicit time_put_byname(const char*, size_t refs = 0); + explicit time_put_byname(const string&, size_t refs = 0); - protected: - ~time_put_byname(); - }; + protected: + ~time_put_byname(); + }; } \end{codeblock} @@ -4134,30 +4144,30 @@ \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; - }; + class money_get : public locale::facet { + public: + using @\libmember{char_type}{money_get}@ = charT; + using @\libmember{iter_type}{money_get}@ = InputIterator; + using @\libmember{string_type}{money_get}@ = basic_string; + + explicit money_get(size_t refs = 0); + + iter_type get(iter_type s, iter_type end, bool intl, + ios_base& f, ios_base::iostate& err, + long double& units) const; + iter_type get(iter_type s, iter_type end, bool intl, + ios_base& f, ios_base::iostate& err, + string_type& digits) const; + + static locale::id @\libmember{id}{money_get}@; + + protected: + ~money_get(); + virtual iter_type do_get(iter_type, iter_type, bool, ios_base&, + ios_base::iostate& err, long double& units) const; + virtual iter_type do_get(iter_type, iter_type, bool, ios_base&, + ios_base::iostate& err, string_type& digits) const; + }; } \end{codeblock} @@ -4198,8 +4208,8 @@ 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, +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} @@ -4276,7 +4286,7 @@ \end{footnote} \begin{codeblock} for (int i = 0; i < n; ++i) - buf2[i] = src[find(atoms, atoms+sizeof(src), buf1[i]) - atoms]; + buf2[i] = src[find(atoms, atoms + sizeof(src), buf1[i]) - atoms]; buf2[n] = 0; sscanf(buf2, "%Lf", &units); \end{codeblock} @@ -4303,28 +4313,28 @@ \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; + class money_put : public locale::facet { + public: + using @\libmember{char_type}{money_put}@ = charT; + using @\libmember{iter_type}{money_put}@ = OutputIterator; + using @\libmember{string_type}{money_put}@ = basic_string; - explicit money_put(size_t refs = 0); + 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; + 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; + static locale::id @\libmember{id}{money_put}@; - protected: - ~money_put(); - virtual iter_type do_put(iter_type, bool, ios_base&, char_type fill, - long double units) const; - virtual iter_type do_put(iter_type, bool, ios_base&, char_type fill, - const string_type& digits) const; - }; + 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} @@ -4339,7 +4349,7 @@ \begin{itemdescr} \pnum \returns -\tcode{do_put(s, intl, f, loc, quant)}. +\tcode{do_put(s, intl, f, fill, quant)}. \end{itemdescr} \rSec5[locale.money.put.virtuals]{Virtual functions} @@ -4417,48 +4427,49 @@ \rSec5[locale.moneypunct.general]{General} +\indexlibraryglobal{money_base}% \indexlibraryglobal{moneypunct}% \begin{codeblock} namespace std { class money_base { public: - enum part { none, space, symbol, sign, value }; - struct pattern { char field[4]; }; + enum @\libmember{part}{money_base}@ { @\libmember{none}{money_base}@, @\libmember{space}{money_base}@, @\libmember{symbol}{money_base}@, @\libmember{sign}{money_base}@, @\libmember{value}{money_base}@ }; + struct @\libmember{pattern}{money_base}@ { char @\libmember{field}{money_base::pattern}@[4]; }; }; template - class moneypunct : public locale::facet, public money_base { - public: - using 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; - }; + class moneypunct : public locale::facet, public money_base { + public: + using @\libmember{char_type}{moneypunct}@ = charT; + using @\libmember{string_type}{moneypunct}@ = basic_string; + + explicit moneypunct(size_t refs = 0); + + charT decimal_point() const; + charT thousands_sep() const; + string grouping() const; + string_type curr_symbol() const; + string_type positive_sign() const; + string_type negative_sign() const; + int frac_digits() const; + pattern pos_format() const; + pattern neg_format() const; + + static locale::id @\libmember{id}{moneypunct}@; + static const bool @\libmember{intl}{moneypunct}@ = International; + + protected: + ~moneypunct(); + virtual charT do_decimal_point() const; + virtual charT do_thousands_sep() const; + virtual string do_grouping() const; + virtual string_type do_curr_symbol() const; + virtual string_type do_positive_sign() const; + virtual string_type do_negative_sign() const; + virtual int do_frac_digits() const; + virtual pattern do_pos_format() const; + virtual pattern do_neg_format() const; + }; } \end{codeblock} @@ -4468,7 +4479,7 @@ 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 +determines the $\tcode{i}^\text{th}$ component of the format. \begin{footnote} An array of \tcode{char}, rather than an array of \tcode{part}, @@ -4562,15 +4573,15 @@ \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; +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 @@ -4673,7 +4684,7 @@ \returns The number of digits after the decimal radix separator, if any. \begin{footnote} -In common U.S.\ locales, this is 2. +In common U.S. locales, this is 2. \end{footnote} \end{itemdescr} @@ -4710,16 +4721,16 @@ namespace std { template class moneypunct_byname : public moneypunct { - public: - using pattern = money_base::pattern; - using string_type = basic_string; + public: + using @\libmember{pattern}{moneypunct_byname}@ = money_base::pattern; + using @\libmember{string_type}{moneypunct_byname}@ = basic_string; - explicit moneypunct_byname(const char*, size_t refs = 0); - explicit moneypunct_byname(const string&, size_t refs = 0); + explicit moneypunct_byname(const char*, size_t refs = 0); + explicit moneypunct_byname(const string&, size_t refs = 0); - protected: - ~moneypunct_byname(); - }; + protected: + ~moneypunct_byname(); + }; } \end{codeblock} @@ -4735,36 +4746,37 @@ \rSec5[locale.messages.general]{General} +\indexlibraryglobal{messages_base}% \indexlibraryglobal{messages}% \begin{codeblock} namespace std { class messages_base { public: - using catalog = @\textit{unspecified signed integer type}@; + using @\libmember{catalog}{messages_base}@ = @\textit{unspecified signed integer type}@; }; template - class messages : public locale::facet, public messages_base { - public: - using char_type = charT; - using string_type = basic_string; + class messages : public locale::facet, public messages_base { + public: + using @\libmember{char_type}{messages}@ = charT; + using @\libmember{string_type}{messages}@ = basic_string; - explicit messages(size_t refs = 0); + 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; + 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; + static locale::id @\libmember{id}{messages}@; - protected: - ~messages(); - virtual catalog do_open(const string&, const locale&) const; - virtual string_type do_get(catalog, int set, int msgid, - const string_type& dfault) const; - virtual void do_close(catalog) const; - }; + 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} @@ -4879,17 +4891,17 @@ \begin{codeblock} namespace std { template - class messages_byname : public messages { - public: - using catalog = messages_base::catalog; - using string_type = basic_string; + class messages_byname : public messages { + public: + using @\libmember{catalog}{messages_byname}@ = messages_base::catalog; + using @\libmember{string_type}{messages_byname}@ = basic_string; - explicit messages_byname(const char*, size_t refs = 0); - explicit messages_byname(const string&, size_t refs = 0); + explicit messages_byname(const char*, size_t refs = 0); + explicit messages_byname(const string&, size_t refs = 0); - protected: - ~messages_byname(); - }; + protected: + ~messages_byname(); + }; } \end{codeblock} @@ -4900,13 +4912,6 @@ \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; @@ -4915,13 +4920,13 @@ 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@ +#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 @@ -5026,7 +5031,7 @@ \begin{codeblock} namespace std { struct text_encoding { - static constexpr size_t max_name_length = 63; + static constexpr size_t @\libmember{max_name_length}{text_encoding}@ = 63; // \ref{text.encoding.id}, enumeration \tcode{text_encoding::id} enum class id : int_least32_t { @@ -5432,264 +5437,264 @@ \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 + @\libmember{other}{text_encoding}@ = 1, + @\libmember{unknown}{text_encoding}@ = 2, + @\libmember{ASCII}{text_encoding}@ = 3, + @\libmember{ISOLatin1}{text_encoding}@ = 4, + @\libmember{ISOLatin2}{text_encoding}@ = 5, + @\libmember{ISOLatin3}{text_encoding}@ = 6, + @\libmember{ISOLatin4}{text_encoding}@ = 7, + @\libmember{ISOLatinCyrillic}{text_encoding}@ = 8, + @\libmember{ISOLatinArabic}{text_encoding}@ = 9, + @\libmember{ISOLatinGreek}{text_encoding}@ = 10, + @\libmember{ISOLatinHebrew}{text_encoding}@ = 11, + @\libmember{ISOLatin5}{text_encoding}@ = 12, + @\libmember{ISOLatin6}{text_encoding}@ = 13, + @\libmember{ISOTextComm}{text_encoding}@ = 14, + @\libmember{HalfWidthKatakana}{text_encoding}@ = 15, + @\libmember{JISEncoding}{text_encoding}@ = 16, + @\libmember{ShiftJIS}{text_encoding}@ = 17, + @\libmember{EUCPkdFmtJapanese}{text_encoding}@ = 18, + @\libmember{EUCFixWidJapanese}{text_encoding}@ = 19, + @\libmember{ISO4UnitedKingdom}{text_encoding}@ = 20, + @\libmember{ISO11SwedishForNames}{text_encoding}@ = 21, + @\libmember{ISO15Italian}{text_encoding}@ = 22, + @\libmember{ISO17Spanish}{text_encoding}@ = 23, + @\libmember{ISO21German}{text_encoding}@ = 24, + @\libmember{ISO60DanishNorwegian}{text_encoding}@ = 25, + @\libmember{ISO69French}{text_encoding}@ = 26, + @\libmember{ISO10646UTF1}{text_encoding}@ = 27, + @\libmember{ISO646basic1983}{text_encoding}@ = 28, + @\libmember{INVARIANT}{text_encoding}@ = 29, + @\libmember{ISO2IntlRefVersion}{text_encoding}@ = 30, + @\libmember{NATSSEFI}{text_encoding}@ = 31, + @\libmember{NATSSEFIADD}{text_encoding}@ = 32, + @\libmember{ISO10Swedish}{text_encoding}@ = 35, + @\libmember{KSC56011987}{text_encoding}@ = 36, + @\libmember{ISO2022KR}{text_encoding}@ = 37, + @\libmember{EUCKR}{text_encoding}@ = 38, + @\libmember{ISO2022JP}{text_encoding}@ = 39, + @\libmember{ISO2022JP2}{text_encoding}@ = 40, + @\libmember{ISO13JISC6220jp}{text_encoding}@ = 41, + @\libmember{ISO14JISC6220ro}{text_encoding}@ = 42, + @\libmember{ISO16Portuguese}{text_encoding}@ = 43, + @\libmember{ISO18Greek7Old}{text_encoding}@ = 44, + @\libmember{ISO19LatinGreek}{text_encoding}@ = 45, + @\libmember{ISO25French}{text_encoding}@ = 46, + @\libmember{ISO27LatinGreek1}{text_encoding}@ = 47, + @\libmember{ISO5427Cyrillic}{text_encoding}@ = 48, + @\libmember{ISO42JISC62261978}{text_encoding}@ = 49, + @\libmember{ISO47BSViewdata}{text_encoding}@ = 50, + @\libmember{ISO49INIS}{text_encoding}@ = 51, + @\libmember{ISO50INIS8}{text_encoding}@ = 52, + @\libmember{ISO51INISCyrillic}{text_encoding}@ = 53, + @\libmember{ISO54271981}{text_encoding}@ = 54, + @\libmember{ISO5428Greek}{text_encoding}@ = 55, + @\libmember{ISO57GB1988}{text_encoding}@ = 56, + @\libmember{ISO58GB231280}{text_encoding}@ = 57, + @\libmember{ISO61Norwegian2}{text_encoding}@ = 58, + @\libmember{ISO70VideotexSupp1}{text_encoding}@ = 59, + @\libmember{ISO84Portuguese2}{text_encoding}@ = 60, + @\libmember{ISO85Spanish2}{text_encoding}@ = 61, + @\libmember{ISO86Hungarian}{text_encoding}@ = 62, + @\libmember{ISO87JISX0208}{text_encoding}@ = 63, + @\libmember{ISO88Greek7}{text_encoding}@ = 64, + @\libmember{ISO89ASMO449}{text_encoding}@ = 65, + @\libmember{ISO90}{text_encoding}@ = 66, + @\libmember{ISO91JISC62291984a}{text_encoding}@ = 67, + @\libmember{ISO92JISC62991984b}{text_encoding}@ = 68, + @\libmember{ISO93JIS62291984badd}{text_encoding}@ = 69, + @\libmember{ISO94JIS62291984hand}{text_encoding}@ = 70, + @\libmember{ISO95JIS62291984handadd}{text_encoding}@ = 71, + @\libmember{ISO96JISC62291984kana}{text_encoding}@ = 72, + @\libmember{ISO2033}{text_encoding}@ = 73, + @\libmember{ISO99NAPLPS}{text_encoding}@ = 74, + @\libmember{ISO102T617bit}{text_encoding}@ = 75, + @\libmember{ISO103T618bit}{text_encoding}@ = 76, + @\libmember{ISO111ECMACyrillic}{text_encoding}@ = 77, + @\libmember{ISO121Canadian1}{text_encoding}@ = 78, + @\libmember{ISO122Canadian2}{text_encoding}@ = 79, + @\libmember{ISO123CSAZ24341985gr}{text_encoding}@ = 80, + @\libmember{ISO88596E}{text_encoding}@ = 81, + @\libmember{ISO88596I}{text_encoding}@ = 82, + @\libmember{ISO128T101G2}{text_encoding}@ = 83, + @\libmember{ISO88598E}{text_encoding}@ = 84, + @\libmember{ISO88598I}{text_encoding}@ = 85, + @\libmember{ISO139CSN369103}{text_encoding}@ = 86, + @\libmember{ISO141JUSIB1002}{text_encoding}@ = 87, + @\libmember{ISO143IECP271}{text_encoding}@ = 88, + @\libmember{ISO146Serbian}{text_encoding}@ = 89, + @\libmember{ISO147Macedonian}{text_encoding}@ = 90, + @\libmember{ISO150}{text_encoding}@ = 91, + @\libmember{ISO151Cuba}{text_encoding}@ = 92, + @\libmember{ISO6937Add}{text_encoding}@ = 93, + @\libmember{ISO153GOST1976874}{text_encoding}@ = 94, + @\libmember{ISO8859Supp}{text_encoding}@ = 95, + @\libmember{ISO10367Box}{text_encoding}@ = 96, + @\libmember{ISO158Lap}{text_encoding}@ = 97, + @\libmember{ISO159JISX02121990}{text_encoding}@ = 98, + @\libmember{ISO646Danish}{text_encoding}@ = 99, + @\libmember{USDK}{text_encoding}@ = 100, + @\libmember{DKUS}{text_encoding}@ = 101, + @\libmember{KSC5636}{text_encoding}@ = 102, + @\libmember{Unicode11UTF7}{text_encoding}@ = 103, + @\libmember{ISO2022CN}{text_encoding}@ = 104, + @\libmember{ISO2022CNEXT}{text_encoding}@ = 105, + @\libmember{UTF8}{text_encoding}@ = 106, + @\libmember{ISO885913}{text_encoding}@ = 109, + @\libmember{ISO885914}{text_encoding}@ = 110, + @\libmember{ISO885915}{text_encoding}@ = 111, + @\libmember{ISO885916}{text_encoding}@ = 112, + @\libmember{GBK}{text_encoding}@ = 113, + @\libmember{GB18030}{text_encoding}@ = 114, + @\libmember{OSDEBCDICDF0415}{text_encoding}@ = 115, + @\libmember{OSDEBCDICDF03IRV}{text_encoding}@ = 116, + @\libmember{OSDEBCDICDF041}{text_encoding}@ = 117, + @\libmember{ISO115481}{text_encoding}@ = 118, + @\libmember{KZ1048}{text_encoding}@ = 119, + @\libmember{UCS2}{text_encoding}@ = 1000, + @\libmember{UCS4}{text_encoding}@ = 1001, + @\libmember{UnicodeASCII}{text_encoding}@ = 1002, + @\libmember{UnicodeLatin1}{text_encoding}@ = 1003, + @\libmember{UnicodeJapanese}{text_encoding}@ = 1004, + @\libmember{UnicodeIBM1261}{text_encoding}@ = 1005, + @\libmember{UnicodeIBM1268}{text_encoding}@ = 1006, + @\libmember{UnicodeIBM1276}{text_encoding}@ = 1007, + @\libmember{UnicodeIBM1264}{text_encoding}@ = 1008, + @\libmember{UnicodeIBM1265}{text_encoding}@ = 1009, + @\libmember{Unicode11}{text_encoding}@ = 1010, + @\libmember{SCSU}{text_encoding}@ = 1011, + @\libmember{UTF7}{text_encoding}@ = 1012, + @\libmember{UTF16BE}{text_encoding}@ = 1013, + @\libmember{UTF16LE}{text_encoding}@ = 1014, + @\libmember{UTF16}{text_encoding}@ = 1015, + @\libmember{CESU8}{text_encoding}@ = 1016, + @\libmember{UTF32}{text_encoding}@ = 1017, + @\libmember{UTF32BE}{text_encoding}@ = 1018, + @\libmember{UTF32LE}{text_encoding}@ = 1019, + @\libmember{BOCU1}{text_encoding}@ = 1020, + @\libmember{UTF7IMAP}{text_encoding}@ = 1021, + @\libmember{Windows30Latin1}{text_encoding}@ = 2000, + @\libmember{Windows31Latin1}{text_encoding}@ = 2001, + @\libmember{Windows31Latin2}{text_encoding}@ = 2002, + @\libmember{Windows31Latin5}{text_encoding}@ = 2003, + @\libmember{HPRoman8}{text_encoding}@ = 2004, + @\libmember{AdobeStandardEncoding}{text_encoding}@ = 2005, + @\libmember{VenturaUS}{text_encoding}@ = 2006, + @\libmember{VenturaInternational}{text_encoding}@ = 2007, + @\libmember{DECMCS}{text_encoding}@ = 2008, + @\libmember{PC850Multilingual}{text_encoding}@ = 2009, + @\libmember{PCp852}{text_encoding}@ = 2010, + @\libmember{PC8CodePage437}{text_encoding}@ = 2011, + @\libmember{PC8DanishNorwegian}{text_encoding}@ = 2012, + @\libmember{PC862LatinHebrew}{text_encoding}@ = 2013, + @\libmember{PC8Turkish}{text_encoding}@ = 2014, + @\libmember{IBMSymbols}{text_encoding}@ = 2015, + @\libmember{IBMThai}{text_encoding}@ = 2016, + @\libmember{HPLegal}{text_encoding}@ = 2017, + @\libmember{HPPiFont}{text_encoding}@ = 2018, + @\libmember{HPMath8}{text_encoding}@ = 2019, + @\libmember{HPPSMath}{text_encoding}@ = 2020, + @\libmember{HPDesktop}{text_encoding}@ = 2021, + @\libmember{VenturaMath}{text_encoding}@ = 2022, + @\libmember{MicrosoftPublishing}{text_encoding}@ = 2023, + @\libmember{Windows31J}{text_encoding}@ = 2024, + @\libmember{GB2312}{text_encoding}@ = 2025, + @\libmember{Big5}{text_encoding}@ = 2026, + @\libmember{Macintosh}{text_encoding}@ = 2027, + @\libmember{IBM037}{text_encoding}@ = 2028, + @\libmember{IBM038}{text_encoding}@ = 2029, + @\libmember{IBM273}{text_encoding}@ = 2030, + @\libmember{IBM274}{text_encoding}@ = 2031, + @\libmember{IBM275}{text_encoding}@ = 2032, + @\libmember{IBM277}{text_encoding}@ = 2033, + @\libmember{IBM278}{text_encoding}@ = 2034, + @\libmember{IBM280}{text_encoding}@ = 2035, + @\libmember{IBM281}{text_encoding}@ = 2036, + @\libmember{IBM284}{text_encoding}@ = 2037, + @\libmember{IBM285}{text_encoding}@ = 2038, + @\libmember{IBM290}{text_encoding}@ = 2039, + @\libmember{IBM297}{text_encoding}@ = 2040, + @\libmember{IBM420}{text_encoding}@ = 2041, + @\libmember{IBM423}{text_encoding}@ = 2042, + @\libmember{IBM424}{text_encoding}@ = 2043, + @\libmember{IBM500}{text_encoding}@ = 2044, + @\libmember{IBM851}{text_encoding}@ = 2045, + @\libmember{IBM855}{text_encoding}@ = 2046, + @\libmember{IBM857}{text_encoding}@ = 2047, + @\libmember{IBM860}{text_encoding}@ = 2048, + @\libmember{IBM861}{text_encoding}@ = 2049, + @\libmember{IBM863}{text_encoding}@ = 2050, + @\libmember{IBM864}{text_encoding}@ = 2051, + @\libmember{IBM865}{text_encoding}@ = 2052, + @\libmember{IBM868}{text_encoding}@ = 2053, + @\libmember{IBM869}{text_encoding}@ = 2054, + @\libmember{IBM870}{text_encoding}@ = 2055, + @\libmember{IBM871}{text_encoding}@ = 2056, + @\libmember{IBM880}{text_encoding}@ = 2057, + @\libmember{IBM891}{text_encoding}@ = 2058, + @\libmember{IBM903}{text_encoding}@ = 2059, + @\libmember{IBM904}{text_encoding}@ = 2060, + @\libmember{IBM905}{text_encoding}@ = 2061, + @\libmember{IBM918}{text_encoding}@ = 2062, + @\libmember{IBM1026}{text_encoding}@ = 2063, + @\libmember{IBMEBCDICATDE}{text_encoding}@ = 2064, + @\libmember{EBCDICATDEA}{text_encoding}@ = 2065, + @\libmember{EBCDICCAFR}{text_encoding}@ = 2066, + @\libmember{EBCDICDKNO}{text_encoding}@ = 2067, + @\libmember{EBCDICDKNOA}{text_encoding}@ = 2068, + @\libmember{EBCDICFISE}{text_encoding}@ = 2069, + @\libmember{EBCDICFISEA}{text_encoding}@ = 2070, + @\libmember{EBCDICFR}{text_encoding}@ = 2071, + @\libmember{EBCDICIT}{text_encoding}@ = 2072, + @\libmember{EBCDICPT}{text_encoding}@ = 2073, + @\libmember{EBCDICES}{text_encoding}@ = 2074, + @\libmember{EBCDICESA}{text_encoding}@ = 2075, + @\libmember{EBCDICESS}{text_encoding}@ = 2076, + @\libmember{EBCDICUK}{text_encoding}@ = 2077, + @\libmember{EBCDICUS}{text_encoding}@ = 2078, + @\libmember{Unknown8BiT}{text_encoding}@ = 2079, + @\libmember{Mnemonic}{text_encoding}@ = 2080, + @\libmember{Mnem}{text_encoding}@ = 2081, + @\libmember{VISCII}{text_encoding}@ = 2082, + @\libmember{VIQR}{text_encoding}@ = 2083, + @\libmember{KOI8R}{text_encoding}@ = 2084, + @\libmember{HZGB2312}{text_encoding}@ = 2085, + @\libmember{IBM866}{text_encoding}@ = 2086, + @\libmember{PC775Baltic}{text_encoding}@ = 2087, + @\libmember{KOI8U}{text_encoding}@ = 2088, + @\libmember{IBM00858}{text_encoding}@ = 2089, + @\libmember{IBM00924}{text_encoding}@ = 2090, + @\libmember{IBM01140}{text_encoding}@ = 2091, + @\libmember{IBM01141}{text_encoding}@ = 2092, + @\libmember{IBM01142}{text_encoding}@ = 2093, + @\libmember{IBM01143}{text_encoding}@ = 2094, + @\libmember{IBM01144}{text_encoding}@ = 2095, + @\libmember{IBM01145}{text_encoding}@ = 2096, + @\libmember{IBM01146}{text_encoding}@ = 2097, + @\libmember{IBM01147}{text_encoding}@ = 2098, + @\libmember{IBM01148}{text_encoding}@ = 2099, + @\libmember{IBM01149}{text_encoding}@ = 2100, + @\libmember{Big5HKSCS}{text_encoding}@ = 2101, + @\libmember{IBM1047}{text_encoding}@ = 2102, + @\libmember{PTCP154}{text_encoding}@ = 2103, + @\libmember{Amiga1251}{text_encoding}@ = 2104, + @\libmember{KOI7switched}{text_encoding}@ = 2105, + @\libmember{BRF}{text_encoding}@ = 2106, + @\libmember{TSCII}{text_encoding}@ = 2107, + @\libmember{CP51932}{text_encoding}@ = 2108, + @\libmember{windows874}{text_encoding}@ = 2109, + @\libmember{windows1250}{text_encoding}@ = 2250, + @\libmember{windows1251}{text_encoding}@ = 2251, + @\libmember{windows1252}{text_encoding}@ = 2252, + @\libmember{windows1253}{text_encoding}@ = 2253, + @\libmember{windows1254}{text_encoding}@ = 2254, + @\libmember{windows1255}{text_encoding}@ = 2255, + @\libmember{windows1256}{text_encoding}@ = 2256, + @\libmember{windows1257}{text_encoding}@ = 2257, + @\libmember{windows1258}{text_encoding}@ = 2258, + @\libmember{TIS620}{text_encoding}@ = 2259, + @\libmember{CP50220}{text_encoding}@ = 2260 }; } \end{codeblock} @@ -5698,7 +5703,7 @@ 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 +the alias beginning with ``\tcode{cs}'', as follows: \begin{itemize} \item \tcode{csUnicode} is mapped to \tcode{text_encoding::id::UCS2}, @@ -5751,16 +5756,18 @@ template struct basic_format_string; - template struct @\exposid{runtime-format-string}@ { // \expos + template struct @\exposid{dynamic-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; + constexpr @\exposid{dynamic-format-string}@(basic_string_view s) noexcept : @\exposid{str}@(s) {} + @\exposid{dynamic-format-string}@(const @\exposid{dynamic-format-string}@&) = delete; + @\exposid{dynamic-format-string}@& operator=(const @\exposid{dynamic-format-string}@&) = delete; }; - @\exposid{runtime-format-string}@ runtime_format(string_view fmt) noexcept { return fmt; } - @\exposid{runtime-format-string}@ runtime_format(wstring_view fmt) noexcept { return fmt; } + constexpr @\exposid{dynamic-format-string}@ + dynamic_format(string_view fmt) noexcept { return fmt; } + constexpr @\exposid{dynamic-format-string}@ + dynamic_format(wstring_view fmt) noexcept { return fmt; } template using @\libglobal{format_string}@ = basic_format_string...>; @@ -5769,32 +5776,32 @@ // \ref{format.functions}, formatting functions template - string format(format_string fmt, Args&&... args); + constexpr string format(format_string fmt, Args&&... args); template - wstring format(wformat_string fmt, Args&&... args); + constexpr wstring format(wformat_string fmt, Args&&... args); template string format(const locale& loc, format_string fmt, Args&&... args); template wstring format(const locale& loc, wformat_string fmt, Args&&... args); - string vformat(string_view fmt, format_args args); - wstring vformat(wstring_view fmt, wformat_args args); + constexpr string vformat(string_view fmt, format_args args); + constexpr wstring vformat(wstring_view fmt, wformat_args args); string vformat(const locale& loc, string_view fmt, format_args args); wstring vformat(const locale& loc, wstring_view fmt, wformat_args args); template - Out format_to(Out out, format_string fmt, Args&&... args); + constexpr Out format_to(Out out, format_string fmt, Args&&... args); template - Out format_to(Out out, wformat_string fmt, Args&&... args); + constexpr Out format_to(Out out, wformat_string fmt, Args&&... args); template Out format_to(Out out, const locale& loc, format_string fmt, Args&&... args); template Out format_to(Out out, const locale& loc, wformat_string fmt, Args&&... args); template - Out vformat_to(Out out, string_view fmt, format_args args); + constexpr Out vformat_to(Out out, string_view fmt, format_args args); template - Out vformat_to(Out out, wstring_view fmt, wformat_args args); + constexpr Out vformat_to(Out out, wstring_view fmt, wformat_args args); template Out vformat_to(Out out, const locale& loc, string_view fmt, format_args args); template @@ -5805,11 +5812,13 @@ iter_difference_t size; }; template - format_to_n_result format_to_n(Out out, iter_difference_t n, - format_string fmt, Args&&... args); + constexpr 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); + constexpr format_to_n_result format_to_n(Out out, iter_difference_t n, + wformat_string fmt, + Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, const locale& loc, format_string fmt, @@ -5820,9 +5829,9 @@ Args&&... args); template - size_t formatted_size(format_string fmt, Args&&... args); + constexpr size_t formatted_size(format_string fmt, Args&&... args); template - size_t formatted_size(wformat_string fmt, Args&&... args); + constexpr size_t formatted_size(wformat_string fmt, Args&&... args); template size_t formatted_size(const locale& loc, format_string fmt, Args&&... args); template @@ -5868,7 +5877,7 @@ constexpr @\unspec@ format_kind = @\unspec@; template - requires @\libconcept{same_as}@> + requires @\libconcept{same_as}@> constexpr range_format format_kind = @\seebelow@; // \ref{format.range.formatter}, class template \tcode{range_formatter} @@ -5887,7 +5896,7 @@ struct formatter : @\exposid{range-default-formatter}@, R, charT> { }; template - requires (format_kind != range_format::disabled) + requires (format_kind != range_format::disabled) constexpr bool enable_nonlocking_formatter_optimization = false; // \ref{format.arguments}, arguments @@ -5898,10 +5907,10 @@ template class @\exposidnc{format-arg-store}@; // \expos template - @\exposid{format-arg-store}@ + constexpr @\exposid{format-arg-store}@ make_format_args(Args&... fmt_args); template - @\exposid{format-arg-store}@ + constexpr @\exposid{format-arg-store}@ make_wformat_args(Args&... args); // \ref{format.error}, class \tcode{format_error} @@ -6032,12 +6041,12 @@ 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}. +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 \iref{time.format}. +as described in~\ref{time.format}. \item For user-defined \tcode{formatter} specializations, the behavior of the \tcode{parse} member function @@ -6384,23 +6393,37 @@ the \defnx{locale-specific form}{locale-specific form!format string}. The \tcode{L} option is only valid for arithmetic types, and its effect depends upon the type. +A call to \tcode{format} on a given formatter specialization +is not a constant subexpression if the locale-specific form is specified. \begin{itemize} \item For integral types, the locale-specific form causes the context's locale to be used -to insert the appropriate digit group separator characters. +to insert the appropriate digit group separator characters +as if obtained with +\tcode{numpunct::grouping} and +\tcode{numpunct::thousands_sep}. \item For floating-point types, the locale-specific form causes the context's locale to be used -to insert the appropriate digit group and radix separator characters. +to insert the appropriate digit group and radix separator characters +as if obtained with +\tcode{numpunct::grouping}, +\tcode{numpunct::thousands_sep}, and +\tcode{numpunct::decimal_point}. \item For the textual representation of \tcode{bool}, the locale-specific form causes the context's locale to be used to insert the appropriate string as if obtained -with \tcode{numpunct::truename} or \tcode{numpunct::falsename}. +with \tcode{numpunct::truename} or \tcode{numpunct::\brk{}falsename}. \end{itemize} +If the string literal encoding is a Unicode encoding form and +the locale is among an implementation-defined set of locales, +each replacement that depends on the locale is performed as if +the replacement character sequence is converted to +the string literal encoding. \pnum The \fmtgrammarterm{type} determines how the data should be presented. @@ -6428,7 +6451,9 @@ 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 +Formatting is done as if by calling \tcode{to_chars} as specified, +transcoding the \tcode{to_chars} output to the wide literal encoding if +\tcode{charT} is \tcode{wchar_t}, and copying the output through the output iterator of the format context. \begin{note} Additional padding and adjustments are performed @@ -6636,12 +6661,10 @@ \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. +with the prefix \tcode{0x} inserted immediately before the output of \tcode{to_chars}. \\ \rowsep \tcode{P} & The same as \tcode{p}, @@ -6672,7 +6695,7 @@ public: template consteval basic_format_string(const T& s); - basic_format_string(@\exposid{runtime-format-string}@ s) noexcept : str(s.@\exposid{str}@) {} + constexpr basic_format_string(@\exposid{dynamic-format-string}@ s) noexcept : str(s.@\exposid{str}@) {} constexpr basic_string_view get() const noexcept { return @\exposid{str}@; } }; @@ -6694,13 +6717,19 @@ \pnum \remarks -A call to this function is not a core constant expression\iref{expr.const} +A call to this function is not a core constant expression\iref{expr.const.core} unless there exist \tcode{args} of types \tcode{Args} such that \exposid{str} is a format string for \tcode{args}. \end{itemdescr} \rSec2[format.functions]{Formatting functions} +\pnum +A call to any of the functions defined in this subclause +is a constant subexpression only if +each of the used \tcode{formatter} specializations +is a constexpr-enabled specialization\iref{format.formatter.spec}. + \pnum In the description of the functions, operator \tcode{+} is used for some of the iterator categories for which it does not have to be defined. @@ -6710,7 +6739,7 @@ \indexlibraryglobal{format}% \begin{itemdecl} template - string format(format_string fmt, Args&&... args); + constexpr string format(format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -6725,7 +6754,7 @@ \indexlibraryglobal{format}% \begin{itemdecl} template - wstring format(wformat_string fmt, Args&&... args); + constexpr wstring format(wformat_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -6769,8 +6798,8 @@ \indexlibraryglobal{vformat}% \begin{itemdecl} -string vformat(string_view fmt, format_args args); -wstring vformat(wstring_view fmt, wformat_args args); +constexpr string vformat(string_view fmt, format_args args); +constexpr wstring vformat(wstring_view fmt, wformat_args args); string vformat(const locale& loc, string_view fmt, format_args args); wstring vformat(const locale& loc, wstring_view fmt, wformat_args args); \end{itemdecl} @@ -6791,7 +6820,7 @@ \indexlibraryglobal{format_to}% \begin{itemdecl} template - Out format_to(Out out, format_string fmt, Args&&... args); + constexpr Out format_to(Out out, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -6806,7 +6835,7 @@ \indexlibraryglobal{format_to}% \begin{itemdecl} template - Out format_to(Out out, wformat_string fmt, Args&&... args); + constexpr Out format_to(Out out, wformat_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -6851,9 +6880,9 @@ \indexlibraryglobal{vformat_to}% \begin{itemdecl} template - Out vformat_to(Out out, string_view fmt, format_args args); + constexpr Out vformat_to(Out out, string_view fmt, format_args args); template - Out vformat_to(Out out, wstring_view fmt, wformat_args args); + constexpr Out vformat_to(Out out, wstring_view fmt, wformat_args args); template Out vformat_to(Out out, const locale& loc, string_view fmt, format_args args); template @@ -6893,11 +6922,13 @@ \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); + constexpr 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); + constexpr format_to_n_result format_to_n(Out out, iter_difference_t n, + wformat_string fmt, + Args&&... args); template format_to_n_result format_to_n(Out out, iter_difference_t n, const locale& loc, format_string fmt, @@ -6950,9 +6981,9 @@ \indexlibraryglobal{formatted_size}% \begin{itemdecl} template - size_t formatted_size(format_string fmt, Args&&... args); + constexpr size_t formatted_size(format_string fmt, Args&&... args); template - size_t formatted_size(wformat_string fmt, Args&&... args); + constexpr size_t formatted_size(wformat_string fmt, Args&&... args); template size_t formatted_size(const locale& loc, format_string fmt, Args&&... args); template @@ -7095,7 +7126,7 @@ 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} +Such specializations shall be usable in constant expressions\iref{expr.const.init} and have type \tcode{const bool}. \end{itemdescr} @@ -7151,12 +7182,14 @@ which modifies the state of the \tcode{formatter} to be as if the type of the \fmtgrammarterm{std-format-spec} parsed by the last call to \tcode{parse} were \tcode{?}. +A \defn{constexpr-enabled} specialization of \tcode{formatter} +has its \tcode{format} member function declared \tcode{constexpr}. Each header that declares the template \tcode{formatter} provides the following enabled specializations: \begin{itemize} \item \indexlibrary{\idxcode{formatter}!specializations!character types}% -The debug-enabled specializations +The debug-enabled and constexpr-enabled specializations \begin{codeblock} template<> struct formatter; template<> struct formatter; @@ -7166,7 +7199,7 @@ \item \indexlibrary{\idxcode{formatter}!specializations!string types}% For each \tcode{charT}, -the debug-enabled string type specializations +the debug-enabled and constexpr-enabled string type specializations \begin{codeblock} template<> struct formatter; template<> struct formatter; @@ -7178,27 +7211,37 @@ \end{codeblock} \item -\indexlibrary{\idxcode{formatter}!specializations!arithmetic types}% +\indexlibrary{\idxcode{formatter}!specializations!integer 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}, +for each \tcode{IntegerT} that is either +a signed or unsigned integer type or \tcode{bool}, +a constexpr-enabled specialization +\begin{codeblock} +template<> struct formatter; +\end{codeblock} + +\item +\indexlibrary{\idxcode{formatter}!specializations!floating-point types}% +For each \tcode{charT}, +for each \tcode{FloatingT} that is a cv-unqualified floating-point type, a specialization \begin{codeblock} -template<> struct formatter; +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 +the constexpr-enabled pointer type specialization \begin{codeblock} template<> struct formatter; +\end{codeblock} + +\item +For each \tcode{charT}, +the pointer type specializations +\begin{codeblock} template<> struct formatter; template<> struct formatter; \end{codeblock} @@ -7206,7 +7249,7 @@ 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}. +as described in~\ref{format.string.std}. \pnum Unless specified otherwise, for each type \tcode{T} for which @@ -7455,7 +7498,7 @@ class basic_format_parse_context { public: using char_type = charT; - using const_iterator = typename basic_string_view::const_iterator; + using const_iterator = basic_string_view::const_iterator; using iterator = const_iterator; private: @@ -7582,7 +7625,7 @@ \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}. +are not core constant expressions\iref{expr.const.core}. \end{itemdescr} \indexlibrarymember{check_arg_id}{basic_format_parse_context}% @@ -7609,7 +7652,7 @@ \pnum \remarks -A call to this function is a core constant expression\iref{expr.const} only if +A call to this function is a core constant expression\iref{expr.const.core} only if \tcode{id < num_args_} is \tcode{true}. \end{itemdescr} @@ -7699,11 +7742,11 @@ using char_type = charT; template using formatter_type = formatter; - basic_format_arg arg(size_t id) const noexcept; + constexpr basic_format_arg arg(size_t id) const noexcept; std::locale locale(); - iterator out(); - void advance_to(iterator it); + constexpr iterator out(); + constexpr void advance_to(iterator it); }; } \end{codeblock} @@ -7737,7 +7780,7 @@ \recommended For a given type \tcode{charT}, implementations should provide -a single instantiation of \tcode{basic_format_context} +a single specialization of \tcode{basic_format_context} for appending to \tcode{basic_string}, \tcode{vector}, @@ -7747,7 +7790,7 @@ \indexlibrarymember{arg}{basic_format_context}% \begin{itemdecl} -basic_format_arg arg(size_t id) const noexcept; +constexpr basic_format_arg arg(size_t id) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -7771,7 +7814,7 @@ \indexlibrarymember{out}{basic_format_context}% \begin{itemdecl} -iterator out(); +constexpr iterator out(); \end{itemdecl} \begin{itemdescr} @@ -7782,7 +7825,7 @@ \indexlibrarymember{advance_to}{basic_format_context}% \begin{itemdecl} -void advance_to(iterator it); +constexpr void advance_to(iterator it); \end{itemdecl} \begin{itemdescr} @@ -7840,7 +7883,7 @@ \indexlibraryglobal{format_kind} \begin{itemdecl} template - requires @\libconcept{same_as}@> + requires @\libconcept{same_as}@> constexpr range_format format_kind = @\seebelow@; \end{itemdecl} @@ -7888,7 +7931,7 @@ 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} +Such specializations shall be usable in constant expressions\iref{expr.const.init} and have type \tcode{const range_format}. \end{itemdescr} @@ -7917,9 +7960,9 @@ parse(ParseContext& ctx); template - requires @\libconcept{formattable}@, charT> && - @\libconcept{same_as}@>, T> - typename FormatContext::iterator + requires @\libconcept{formattable}@, charT> && + @\libconcept{same_as}@>, T> + constexpr typename FormatContext::iterator format(R&& r, FormatContext& ctx) const; }; } @@ -8088,9 +8131,9 @@ \indexlibrarymember{format}{range_formatter}% \begin{itemdecl} template - requires @\libconcept{formattable}@, charT> && - @\libconcept{same_as}@>, T> - typename FormatContext::iterator + requires @\libconcept{formattable}@, charT> && + @\libconcept{same_as}@>, T> + constexpr typename FormatContext::iterator format(R&& r, FormatContext& ctx) const; \end{itemdecl} @@ -8153,7 +8196,7 @@ parse(ParseContext& ctx); template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(@\exposid{maybe-const-r}@& elems, FormatContext& ctx) const; }; } @@ -8198,7 +8241,7 @@ \indexlibrarymemberexpos{format}{range-default-formatter}% \begin{itemdecl} template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(@\exposid{maybe-const-r}@& elems, FormatContext& ctx) const; \end{itemdecl} @@ -8229,7 +8272,7 @@ parse(ParseContext& ctx); template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(@\exposid{maybe-const-map}@& r, FormatContext& ctx) const; }; } @@ -8278,7 +8321,7 @@ \indexlibrarymemberexpos{format}{range-default-formatter}% \begin{itemdecl} template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(@\exposid{maybe-const-map}@& r, FormatContext& ctx) const; \end{itemdecl} @@ -8308,7 +8351,7 @@ parse(ParseContext& ctx); template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(@\exposid{maybe-const-set}@& r, FormatContext& ctx) const; }; } @@ -8344,7 +8387,7 @@ \indexlibrarymemberexpos{format}{range-default-formatter}% \begin{itemdecl} template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(@\exposid{maybe-const-set}@& r, FormatContext& ctx) const; \end{itemdecl} @@ -8371,7 +8414,7 @@ parse(ParseContext& ctx); template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(@\seebelow@& str, FormatContext& ctx) const; }; } @@ -8435,25 +8478,25 @@ class handle; private: - using char_type = typename Context::char_type; // \expos + using @\exposid{char-type}@ = Context::char_type; // \expos - variant, - const void*, handle> value; // \expos + const @\exposid{char-type}@*, basic_string_view<@\exposid{char-type}@>, + const void*, handle> @\exposid{value_}@; // \expos - template explicit basic_format_arg(T& v) noexcept; // \expos + template constexpr explicit basic_format_arg(T& v) noexcept; // \expos public: - basic_format_arg() noexcept; + constexpr basic_format_arg() noexcept; - explicit operator bool() const noexcept; + constexpr explicit operator bool() const noexcept; template - decltype(auto) visit(this basic_format_arg arg, Visitor&& vis); + constexpr decltype(auto) visit(this basic_format_arg arg, Visitor&& vis); template - R visit(this basic_format_arg arg, Visitor&& vis); + constexpr R visit(this basic_format_arg arg, Visitor&& vis); }; } \end{codeblock} @@ -8468,7 +8511,7 @@ \indexlibrary{\idxcode{basic_format_arg}!constructor|(}% \begin{itemdecl} -basic_format_arg() noexcept; +constexpr basic_format_arg() noexcept; \end{itemdecl} \begin{itemdescr} @@ -8478,7 +8521,7 @@ \end{itemdescr} \begin{itemdecl} -template explicit basic_format_arg(T& v) noexcept; +template constexpr explicit basic_format_arg(T& v) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8488,56 +8531,56 @@ \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}. +If \tcode{decay_t} is \tcode{\exposid{char-type}*} or \tcode{const \exposid{char-type}*}, +\tcode{static_cast(v)} points to an NTCTS\iref{defns.ntcts}. \pnum \effects Let \tcode{TD} be \tcode{remove_const_t}. \begin{itemize} \item -If \tcode{TD} is \tcode{bool} or \tcode{char_type}, -initializes \tcode{value} with \tcode{v}; +If \tcode{TD} is \tcode{bool} or \exposid{char-type}, +initializes \exposid{value_} with \tcode{v}; \item -otherwise, if \tcode{TD} is \tcode{char} and \tcode{char_type} is -\keyword{wchar_t}, initializes \tcode{value} with +otherwise, if \tcode{TD} is \tcode{char} and \exposid{char-type} is +\keyword{wchar_t}, initializes \exposid{value_} with \tcode{static_cast(static_cast(v))}; \item otherwise, if \tcode{TD} is a signed integer type\iref{basic.fundamental} and \tcode{sizeof(TD) <= sizeof(int)}, -initializes \tcode{value} with \tcode{static_cast(v)}; +initializes \exposid{value_} with \tcode{static_cast(v)}; \item otherwise, if \tcode{TD} is an unsigned integer type and \tcode{sizeof(TD) <= sizeof(unsigned int)}, initializes -\tcode{value} with \tcode{static_cast(v)}; +\exposid{value_} with \tcode{static_cast(v)}; \item otherwise, if \tcode{TD} is a signed integer type and \tcode{sizeof(TD) <= sizeof(long long int)}, initializes -\tcode{value} with \tcode{static_cast(v)}; +\exposid{value_} with \tcode{static_cast(v)}; \item otherwise, if \tcode{TD} is an unsigned integer type and \tcode{sizeof(TD) <= sizeof(unsigned long long int)}, initializes -\tcode{value} with +\exposid{value_} with \tcode{static_cast(v)}; \item otherwise, if \tcode{TD} is a standard floating-point type, -initializes \tcode{value} with \tcode{v}; +initializes \exposid{value_} with \tcode{v}; \item otherwise, if \tcode{TD} is a specialization of \tcode{basic_string_view} or \tcode{basic_string} and -\tcode{TD::value_type} is \tcode{char_type}, -initializes \tcode{value} with -\tcode{basic_string_view(v.data(), v.size())}; +\tcode{TD::value_type} is \exposid{char-type}, +initializes \exposid{value_} with +\tcode{basic_string_view<\exposid{char-type}>(v.data(), v.size())}; \item otherwise, if \tcode{decay_t} is -\tcode{char_type*} or \tcode{const char_type*}, -initializes \tcode{value} with \tcode{static_cast(v)}; +\tcode{\exposid{char-type}*} or \tcode{const \exposid{char-type}*}, +initializes \exposid{value_} with \tcode{static_cast(v)}; \item otherwise, if \tcode{is_void_v>} is \tcode{true} or \tcode{is_null_pointer_v} is \tcode{true}, -initializes \tcode{value} with \tcode{static_cast(v)}; +initializes \exposid{value_} with \tcode{static_cast(v)}; \item -otherwise, initializes \tcode{value} with \tcode{handle(v)}. +otherwise, initializes \exposid{value_} with \tcode{handle(v)}. \end{itemize} \begin{note} Constructing \tcode{basic_format_arg} from a pointer to a member is ill-formed @@ -8550,37 +8593,37 @@ \indexlibrarymember{operator bool}{basic_format_arg}% \begin{itemdecl} -explicit operator bool() const noexcept; +constexpr explicit operator bool() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{!holds_alternative(value)}. +\tcode{!holds_alternative(\exposid{value_})}. \end{itemdescr} \indexlibrarymember{visit}{basic_format_arg}% \begin{itemdecl} template - decltype(auto) visit(this basic_format_arg arg, Visitor&& vis); + constexpr 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));} +Equivalent to: \tcode{return arg.\exposid{value_}.visit(std::forward(vis));} \end{itemdescr} \indexlibrarymember{visit}{basic_format_arg}% \begin{itemdecl} template - R visit(this basic_format_arg arg, Visitor&& vis); + constexpr 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));} +Equivalent to: \tcode{return arg.\exposid{value_}.visit(std::forward(vis));} \end{itemdescr} \pnum @@ -8592,21 +8635,21 @@ namespace std { template class basic_format_arg::handle { - const void* ptr_; // \expos - void (*format_)(basic_format_parse_context&, - Context&, const void*); // \expos + const void* @\exposid{ptr_}@; // \expos + void (*@\exposid{format_}@)(basic_format_parse_context<@\exposid{char-type}@>&, + Context&, const void*); // \expos - template explicit handle(T& val) noexcept; // \expos + template constexpr explicit handle(T& val) noexcept; // \expos public: - void format(basic_format_parse_context&, Context& ctx) const; + constexpr void format(basic_format_parse_context<@\exposid{char-type}@>&, Context& ctx) const; }; } \end{codeblock} \indexlibraryctor{basic_format_arg::handle}% \begin{itemdecl} -template explicit handle(T& val) noexcept; +template constexpr explicit handle(T& val) noexcept; \end{itemdecl} \begin{itemdescr} @@ -8628,10 +8671,10 @@ \pnum \effects Initializes -\tcode{ptr_} with \tcode{addressof(val)} and -\tcode{format_} with +\exposid{ptr_} with \tcode{addressof(val)} and +\exposid{format_} with \begin{codeblock} -[](basic_format_parse_context& parse_ctx, +[](basic_format_parse_context<@\exposid{char-type}@>& parse_ctx, Context& format_ctx, const void* ptr) { typename Context::template formatter_type f; parse_ctx.advance_to(f.parse(parse_ctx)); @@ -8643,13 +8686,13 @@ \indexlibrarymember{format}{basic_format_arg::handle}% \begin{itemdecl} -void format(basic_format_parse_context& parse_ctx, Context& format_ctx) const; +constexpr void format(basic_format_parse_context<@\exposid{char-type}@>& parse_ctx, Context& format_ctx) const; \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{format_(parse_ctx, format_ctx, ptr_);} +Equivalent to: \tcode{\exposid{format_}(parse_ctx, format_ctx, \exposid{ptr_});} \end{itemdescr} \rSec3[format.arg.store]{Class template \exposid{format-arg-store}} @@ -8669,7 +8712,8 @@ \indexlibraryglobal{make_format_args}% \begin{itemdecl} template - @\exposid{format-arg-store}@ make_format_args(Args&... fmt_args); + constexpr @\exposid{format-arg-store}@ + make_format_args(Args&... fmt_args); \end{itemdecl} \begin{itemdescr} @@ -8690,7 +8734,8 @@ \indexlibraryglobal{make_wformat_args}% \begin{itemdecl} template - @\exposid{format-arg-store}@ make_wformat_args(Args&... args); + constexpr @\exposid{format-arg-store}@ + make_wformat_args(Args&... args); \end{itemdecl} \begin{itemdescr} @@ -8706,14 +8751,14 @@ namespace std { template class basic_format_args { - size_t size_; // \expos - const basic_format_arg* data_; // \expos + size_t @\exposid{size_}@; // \expos + const basic_format_arg* @\exposid{data_}@; // \expos public: template - basic_format_args(const @\exposid{format-arg-store}@& store) noexcept; + constexpr basic_format_args(const @\exposid{format-arg-store}@& store) noexcept; - basic_format_arg get(size_t i) const noexcept; + constexpr basic_format_arg get(size_t i) const noexcept; }; template @@ -8724,6 +8769,9 @@ \pnum An instance of \tcode{basic_format_args} provides access to formatting arguments. + +\pnum +\recommended Implementations should optimize the representation of \tcode{basic_format_args} for a small number of formatting arguments. @@ -8735,26 +8783,26 @@ \indexlibraryctor{basic_format_args}% \begin{itemdecl} template - basic_format_args(const @\exposid{format-arg-store}@& store) noexcept; + constexpr 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()}. +\exposid{size_} with \tcode{sizeof...(Args)} and +\exposid{data_} with \tcode{store.\exposid{args}.data()}. \end{itemdescr} \indexlibrarymember{get}{basic_format_args}% \begin{itemdecl} -basic_format_arg get(size_t i) const noexcept; +constexpr basic_format_arg get(size_t i) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{i < size_ ?\ data_[i] :\ basic_format_arg()}. +\tcode{i < \exposid{size_} ?\ \exposid{data_}[i] :\ basic_format_arg()}. \end{itemdescr} \rSec2[format.tuple]{Tuple formatter} @@ -8785,13 +8833,13 @@ parse(ParseContext& ctx); template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(@\seebelow@& elems, FormatContext& ctx) const; }; template constexpr bool enable_nonlocking_formatter_optimization<@\placeholder{pair-or-tuple}@> = - (enable_nonlocking_formatter_optimization && ...); + (enable_nonlocking_formatter_optimization> && ...); } \end{codeblock} @@ -8918,7 +8966,7 @@ \indexlibrarymember{format}{formatter}% \begin{itemdecl} template - typename FormatContext::iterator + constexpr typename FormatContext::iterator format(@\seebelow@& elems, FormatContext& ctx) const; \end{itemdecl} @@ -8965,8 +9013,8 @@ namespace std { class format_error : public runtime_error { public: - explicit format_error(const string& what_arg); - explicit format_error(const char* what_arg); + constexpr explicit format_error(const string& what_arg); + constexpr explicit format_error(const char* what_arg); }; } \end{codeblock} @@ -8977,7 +9025,7 @@ \indexlibraryctor{format_error}% \begin{itemdecl} -format_error(const string& what_arg); +constexpr format_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} @@ -8988,7 +9036,7 @@ \indexlibraryctor{format_error}% \end{itemdescr} \begin{itemdecl} -format_error(const char* what_arg); +constexpr format_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} @@ -9520,7 +9568,7 @@ // \ref{re.alg.replace}, function template \tcode{regex_replace} template + class traits, class charT, class ST, class SA> OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, @@ -9561,8 +9609,8 @@ // \ref{re.regiter}, class template \tcode{regex_iterator} template::value_type, - class traits = regex_traits> + class charT = typename iterator_traits::value_type, + class traits = regex_traits> class regex_iterator; using cregex_iterator = regex_iterator; @@ -9572,8 +9620,8 @@ // \ref{re.tokiter}, class template \tcode{regex_token_iterator} template::value_type, - class traits = regex_traits> + class charT = typename iterator_traits::value_type, + class traits = regex_traits> class regex_token_iterator; using cregex_token_iterator = regex_token_iterator; @@ -9927,7 +9975,7 @@ % \tcode{error_brace} & -The expression contains mismatched \verb|{| and \verb|}| \\ \rowsep +The expression contains mismatched \verb|{| and \verb|}|. \\ \rowsep % \tcode{error_badbrace} & @@ -10004,32 +10052,32 @@ \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; - }; + 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} @@ -10113,7 +10161,7 @@ \effects If \begin{codeblock} -typeid(use_facet>) == typeid(collate_byname) +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 @@ -10214,7 +10262,7 @@ 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} +ctype_base::mask m = convert(f); // \tcode{m == ctype_base::digit | ctype_base::upper} \end{codeblock} \end{example} \begin{example} @@ -10346,11 +10394,11 @@ 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; + using value_type = charT; + using traits_type = traits; + using string_type = traits::string_type; + using flag_type = regex_constants::syntax_option_type; + using locale_type = traits::locale_type; // \ref{re.synopt}, constants static constexpr flag_type icase = regex_constants::icase; @@ -10849,10 +10897,8 @@ template class sub_match : public pair { public: - using value_type = - typename iterator_traits::value_type; - using difference_type = - typename iterator_traits::difference_type; + using value_type = iterator_traits::value_type; + using difference_type = iterator_traits::difference_type; using iterator = BidirectionalIterator; using string_type = basic_string; @@ -11178,12 +11224,10 @@ 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 difference_type = iterator_traits::difference_type; + using size_type = allocator_traits::size_type; using allocator_type = Allocator; - using char_type = - typename iterator_traits::value_type; + using char_type = iterator_traits::value_type; using string_type = basic_string; // \ref{re.results.const}, construct/copy/destroy @@ -11542,9 +11586,9 @@ \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; + 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} @@ -11571,9 +11615,9 @@ \begin{itemdecl} template OutputIter format( - OutputIter out, - const basic_string& fmt, - regex_constants::match_flag_type flags = regex_constants::format_default) const; + OutputIter out, + const basic_string& fmt, + regex_constants::match_flag_type flags = regex_constants::format_default) const; \end{itemdecl} \begin{itemdescr} @@ -11589,8 +11633,8 @@ \begin{itemdecl} template basic_string format( - const basic_string& fmt, - regex_constants::match_flag_type flags = regex_constants::format_default) const; + const basic_string& fmt, + regex_constants::match_flag_type flags = regex_constants::format_default) const; \end{itemdecl} \begin{itemdescr} @@ -11614,8 +11658,8 @@ \indexlibrarymember{match_results}{format}% \begin{itemdecl} string_type format( - const char_type* fmt, - regex_constants::match_flag_type flags = regex_constants::format_default) const; + const char_type* fmt, + regex_constants::match_flag_type flags = regex_constants::format_default) const; \end{itemdecl} \begin{itemdescr} @@ -11689,8 +11733,8 @@ \indexlibrarymember{operator==}{match_results}% \begin{itemdecl} template -bool operator==(const match_results& m1, - const match_results& m2); + bool operator==(const match_results& m1, + const match_results& m2); \end{itemdecl} \begin{itemdescr} @@ -11901,7 +11945,7 @@ \begin{itemdescr} \pnum \returns -\tcode{regex_match(str, str + char_traits::length(str), e, flags)} +\tcode{regex_match(str, str + char_traits::length(str), e, flags)}. \end{itemdescr} \indexlibraryglobal{regex_match}% @@ -12096,7 +12140,7 @@ \indexlibraryglobal{regex_replace}% \begin{itemdecl} template + class traits, class charT, class ST, class SA> OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, @@ -12245,8 +12289,8 @@ 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 +defined. For any other iterator value a +\tcode{const match_results\&} is returned. The result of \tcode{operator->} on an end-of-sequence iterator is not defined. For any other iterator value a \tcode{const match_results*} is returned. It is impossible to store things into \tcode{regex_iterator}s. Two @@ -12258,8 +12302,8 @@ \begin{codeblock} namespace std { template::value_type, - class traits = regex_traits> + class charT = typename iterator_traits::value_type, + class traits = regex_traits> class regex_iterator { public: using regex_type = basic_regex; @@ -12284,7 +12328,7 @@ const value_type& operator*() const; const value_type* operator->() const; regex_iterator& operator++(); - regex_iterator operator++(int); + regex_iterator operator++(int) = default; private: BidirectionalIterator begin; // \expos @@ -12426,7 +12470,7 @@ 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}, +\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)}. @@ -12450,22 +12494,6 @@ \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} @@ -12529,8 +12557,8 @@ \begin{codeblock} namespace std { template::value_type, - class traits = regex_traits> + class charT = typename iterator_traits::value_type, + class traits = regex_traits> class regex_token_iterator { public: using regex_type = basic_regex; @@ -12591,7 +12619,7 @@ const value_type& operator*() const; const value_type* operator->() const; regex_token_iterator& operator++(); - regex_token_iterator operator++(int); + regex_token_iterator operator++(int) = default; private: using position_iterator = @@ -12610,7 +12638,7 @@ 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} +member \tcode{suffix}, the value of the member \tcode{suffix.matched} is \tcode{true}, \tcode{suffix.first} points to the beginning of the final sequence, and \tcode{suffix.second} points to the end of the final sequence. @@ -12768,22 +12796,7 @@ \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}. +\tcode{*this}. \end{itemdescr} \rSec2[re.grammar]{Modified ECMAScript regular expression grammar} @@ -13062,7 +13075,6 @@ \indexlibraryglobal{towupper}% \indexlibraryglobal{towctrans}% \indexlibraryglobal{wctrans}% -\indexlibraryglobal{WEOF}% \begin{codeblock} namespace std { using wint_t = @\seebelow@; @@ -13089,22 +13101,18 @@ wctrans_t wctrans(const char* property); } -#define WEOF @\seebelow@ +#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} +\xrefc{7.32} \rSec2[cwchar.syn]{Header \tcode{} synopsis} \indexheader{cwchar}% -\indexlibraryglobal{NULL}% -\indexlibraryglobal{WCHAR_MAX}% -\indexlibraryglobal{WCHAR_MIN}% -\indexlibraryglobal{WEOF}% \indexlibraryglobal{btowc}% \indexlibraryglobal{fgetwc}% \indexlibraryglobal{fgetws}% @@ -13169,6 +13177,8 @@ \indexlibraryglobal{wprintf}% \indexlibraryglobal{wscanf}% \begin{codeblock} +#define @\libmacro{__STDC_VERSION_WCHAR_H__}@ 202311L + namespace std { using size_t = @\textit{see \ref{support.types.layout}}@; // freestanding using mbstate_t = @\seebelow@; // freestanding @@ -13244,10 +13254,11 @@ 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 +#define @\libmacro{NULL}@ @\textit{see \ref{support.types.nullptr}}@ // freestanding +#define @\libmacro{WCHAR_MAX}@ @\seebelow@ // freestanding +#define @\libmacro{WCHAR_MIN}@ @\seebelow@ // freestanding +#define @\libmacro{WEOF}@ @\seebelow@ // freestanding +#define @\libmacro{WCHAR_WIDTH}@ @\seebelow@ // freestanding \end{codeblock} \pnum @@ -13263,7 +13274,7 @@ but they have the same behavior as in the C standard library\iref{library.c}. \end{note} -\xrefc{7.29} +\xrefc{7.31} \rSec2[cuchar.syn]{Header \tcode{} synopsis} @@ -13276,6 +13287,8 @@ \indexlibraryglobal{mbrtoc32}% \indexlibraryglobal{c32rtomb}% \begin{codeblock} +#define @\libmacro{__STDC_VERSION_UCHAR_H__}@ 202311L + namespace std { using mbstate_t = @\seebelow@; using size_t = @\textit{see \ref{support.types.layout}}@; @@ -13291,12 +13304,11 @@ \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}. +are the same as the C standard library header \libheader{uchar.h}, +except that it does not declare types +\keyword{char8_t}, \keyword{char16_t}, or \keyword{char32_t}. -\xrefc{7.28} +\xrefc{7.30} \rSec2[c.mb.wcs]{Multibyte / wide string and character conversion functions} @@ -13325,7 +13337,7 @@ 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} +\xrefc{7.24.8.2, 7.24.9, 7.31.6.3.1} \indexlibraryglobal{mbtowc}% \indexlibraryglobal{wctomb}% @@ -13346,19 +13358,20 @@ with other calls to the same function. \end{itemdescr} -\xrefc{7.22.7} +\xrefc{7.24.8} -\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); +size_t @\libglobal{mbrlen}@(const char* s, size_t n, mbstate_t* ps); +size_t @\libglobal{mbrtowc}@(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps); +size_t @\libglobal{wcrtomb}@(char* s, wchar_t wc, mbstate_t* ps); +size_t @\libglobal{mbrtoc8}@(char8_t* pc8, const char* s, size_t n, mbstate_t* ps); +size_t @\libglobal{c8rtomb}@(char* s, char8_t c8, mbstate_t* ps); +size_t @\libglobal{mbrtoc16}@(char16_t* pc16, const char* s, size_t n, mbstate_t* ps); +size_t @\libglobal{c16rtomb}@(char* s, char16_t c16, mbstate_t* ps); +size_t @\libglobal{mbrtoc32}@(char32_t* pc32, const char* s, size_t n, mbstate_t* ps); +size_t @\libglobal{c32rtomb}@(char* s, char32_t c32, mbstate_t* ps); +size_t @\libglobal{mbsrtowcs}@(wchar_t* dst, const char** src, size_t len, mbstate_t* ps); +size_t @\libglobal{wcsrtombs}@(char* dst, const wchar_t** src, size_t len, mbstate_t* ps); \end{itemdecl} \begin{itemdescr} @@ -13375,95 +13388,4 @@ 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} +\xrefc{7.30.2, 7.31.6.4, 7.31.6.5} diff --git a/source/threads.tex b/source/threads.tex index 212367adcd..14c5aa4285 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -293,9 +293,9 @@ \pnum A type \tcode{L} meets the \defnoldconcept{TimedLockable} requirements if it meets the \oldconcept{Lockable} requirements and the following expressions are well-formed and have the specified semantics -(\tcode{m} denotes a value of type \tcode{L}, \tcode{rel_time} denotes a value of an -instantiation of \tcode{duration}\iref{time.duration}, and \tcode{abs_time} denotes a value -of an instantiation of \tcode{time_point}\iref{time.point}). +(\tcode{m} denotes a value of type \tcode{L}, \tcode{rel_time} denotes a value of a +specialization of \tcode{duration}\iref{time.duration}, and \tcode{abs_time} denotes a value +of a specialization of \tcode{time_point}\iref{time.point}). \begin{itemdecl} m.try_lock_for(rel_time) @@ -534,10 +534,10 @@ class stop_source; // no-shared-stop-state indicator - struct nostopstate_t { + struct @\libglobal{nostopstate_t}@ { explicit nostopstate_t() = default; }; - inline constexpr nostopstate_t nostopstate{}; + inline constexpr nostopstate_t @\libglobal{nostopstate}@{}; // \ref{stopcallback}, class template \tcode{stop_callback} template @@ -557,7 +557,7 @@ class inplace_stop_callback; template - using stop_callback_for_t = T::template callback_type; + using @\libglobal{stop_callback_for_t}@ = T::template callback_type; } \end{codeblock} @@ -599,7 +599,7 @@ 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. +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: @@ -631,7 +631,6 @@ 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} If \tcode{t.stop_possible()} is \tcode{false}, there is no requirement @@ -835,7 +834,7 @@ class stop_token { public: template - using callback_type = stop_callback; + using @\libmember{callback_type}{stop_token}@ = stop_callback; stop_token() noexcept = default; @@ -919,6 +918,9 @@ // \ref{stopsource.mem}, member functions void swap(stop_source&) noexcept; + stop_token get_token() const noexcept; + bool stop_possible() const noexcept; + bool stop_requested() const noexcept; bool request_stop() noexcept; bool operator==(const stop_source& rhs) noexcept = default; @@ -1040,7 +1042,7 @@ template class stop_callback { public: - using callback_type = CallbackFn; + using @\libmember{callback_type}{stop_callback}@ = CallbackFn; // \ref{stopcallback.cons}, constructors and destructor template @@ -1130,6 +1132,7 @@ It provides a stop token interface, but also provides static information that a stop is never possible nor requested. +\indexlibraryglobal{never_stop_token}% \begin{codeblock} namespace std { class never_stop_token { @@ -1138,10 +1141,10 @@ }; public: template - using callback_type = @\exposid{callback-type}@; + using @\libmember{callback_type}{never_stop_token}@ = @\exposid{callback-type}@; - static constexpr bool stop_requested() noexcept { return false; } - static constexpr bool stop_possible() noexcept { return false; } + static constexpr bool @\libmember{stop_requested}{never_stop_token}@() noexcept { return false; } + static constexpr bool @\libmember{stop_possible}{never_stop_token}@() noexcept { return false; } bool operator==(const never_stop_token&) const = default; }; @@ -1158,12 +1161,13 @@ It references the stop state of its associated \tcode{inplace_stop_source} object\iref{stopsource.inplace}, if any. +\indexlibraryglobal{inplace_stop_token}% \begin{codeblock} namespace std { class inplace_stop_token { public: template - using callback_type = inplace_stop_callback; + using @\libmember{callback_type}{inplace_stop_token}@ = inplace_stop_callback; inplace_stop_token() = default; bool operator==(const inplace_stop_token&) const = default; @@ -1181,6 +1185,7 @@ \rSec3[stoptoken.inplace.mem]{Member functions} +\indexlibrarymember{swap}{inplace_stop_token}% \begin{itemdecl} void swap(inplace_stop_token& rhs) noexcept; \end{itemdecl} @@ -1191,6 +1196,7 @@ Exchanges the values of \exposid{stop-source} and \tcode{rhs.\exposid{stop-source}}. \end{itemdescr} +\indexlibrarymember{stop_requested}{inplace_stop_token}% \begin{itemdecl} bool stop_requested() const noexcept; \end{itemdecl} @@ -1212,6 +1218,7 @@ \end{note} \end{itemdescr} +\indexlibrarymember{stop_possible}{inplace_stop_token}% \begin{itemdecl} stop_possible() const noexcept; \end{itemdecl} @@ -1238,6 +1245,7 @@ \pnum The class \tcode{inplace_stop_source} models \exposconcept{stoppable-source}. +\indexlibraryglobal{inplace_stop_source}% \begin{codeblock} namespace std { class inplace_stop_source { @@ -1253,7 +1261,7 @@ // \ref{stopsource.inplace.mem}, stop handling constexpr inplace_stop_token get_token() const noexcept; - static constexpr bool stop_possible() noexcept { return true; } + static constexpr bool @\libmember{stop_possible}{inplace_stop_source}@() noexcept { return true; } bool stop_requested() const noexcept; bool request_stop() noexcept; }; @@ -1262,6 +1270,7 @@ \rSec3[stopsource.inplace.cons]{Constructors} +\indexlibraryctor{inplace_stop_source}% \begin{itemdecl} constexpr inplace_stop_source() noexcept; \end{itemdecl} @@ -1278,6 +1287,7 @@ \rSec3[stopsource.inplace.mem]{Member functions} +\indexlibrarymember{get_token}{inplace_stop_source}% \begin{itemdecl} constexpr inplace_stop_token get_token() const noexcept; \end{itemdecl} @@ -1289,6 +1299,7 @@ whose \exposid{stop-source} member is equal to \tcode{this}. \end{itemdescr} +\indexlibrarymember{stop_requested}{inplace_stop_source}% \begin{itemdecl} bool stop_requested() const noexcept; \end{itemdecl} @@ -1300,6 +1311,7 @@ has received a stop request; otherwise, \tcode{false}. \end{itemdescr} +\indexlibrarymember{request_stop}{inplace_stop_source}% \begin{itemdecl} bool request_stop() noexcept; \end{itemdecl} @@ -1318,12 +1330,13 @@ \rSec3[stopcallback.inplace.general]{General} +\indexlibraryglobal{inplace_stop_callback}% \begin{codeblock} namespace std { template class inplace_stop_callback { public: - using callback_type = CallbackFn; + using @\libmember{callback_type}{inplace_stop_callback}@ = CallbackFn; // \ref{stopcallback.inplace.cons}, constructors and destructor template @@ -1368,6 +1381,7 @@ \rSec3[stopcallback.inplace.cons]{Constructors and destructor} +\indexlibraryctor{inplace_stop_callback}% \begin{itemdecl} template explicit inplace_stop_callback(inplace_stop_token st, Initializer&& init) @@ -1385,6 +1399,7 @@ and executes a stoppable callback registration\iref{stoptoken.concepts}. \end{itemdescr} +\indexlibrarydtor{inplace_stop_callback}% \begin{itemdecl} ~inplace_stop_callback(); \end{itemdecl} @@ -1459,11 +1474,22 @@ public: // \ref{thread.thread.id}, class \tcode{thread::id} class id; + + // \ref{thread.attributes}, thread attributes + template<@\libconcept{same_as}@ T> + class name_hint; + template + name_hint(const T*) -> name_hint; + template + name_hint(basic_string) -> name_hint; + class stack_size_hint; + using native_handle_type = @\impdefnc@; // see~\ref{thread.req.native} // construct/copy/destroy thread() noexcept; - template explicit thread(F&& f, Args&&... args); + template + explicit thread(Args&&... args); ~thread(); thread(const thread&) = delete; thread(thread&&) noexcept; @@ -1484,6 +1510,108 @@ } \end{codeblock} +\rSec3[thread.attributes]{Thread attributes} + +\rSec4[thread.attributes.general]{General} + +\pnum +\defnx{Thread attributes}{thread attribute} +can be used to define additional implementation-defined behaviors +on a \tcode{thread} or \tcode{jthread} object. + +\pnum +The set of \defnadj{thread attribute}{types} contains +\tcode{thread::name_hint}, +\tcode{thread::stack_size_hint}, and +an \impldef{set of additional thread-attributes} set of additional thread-attributes. + +\pnum +When an object of a thread attribute type is passed to +a \tcode{thread} or \tcode{jthread} constructor, +it may affect the new thread's behavior. + +\rSec4[thread.attributes.hint]{Class \tcode{thread::name_hint}} + +\indexlibraryglobal{thread::name_hint}% +\begin{codeblock} +namespace std { + template<@\libconcept{same_as}@ T> + class thread::name_hint { + public: + constexpr explicit name_hint(basic_string_view n) noexcept; + name_hint(name_hint&&) = delete; + name_hint(const name_hint&) = delete; + + private: + basic_string_view @\exposidnc{name}@; // \expos + }; +} +\end{codeblock} + +\pnum +The \tcode{name_hint} thread attribute can be used to set the name of a thread +for debugging purposes or platform-specific display mechanisms. + +\recommended +Implementations should not store the value of the \tcode{name_hint} attribute +in the \tcode{thread} or \tcode{jthread} object. + +\recommended +\exposid{name} is interpreted as a string +in the associated character encoding +of \tcode{T}~(\tref{lex.string.literal}). + +\indexlibraryctor{thread::name_hint}% +\begin{itemdecl} +constexpr explicit name_hint(basic_string_view n) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{name} with \tcode{n}. +\end{itemdescr} + +\rSec4[thread.attributes.size]{Class \tcode{thread::stack_size_hint}} + +\indexlibraryglobal{thread::stack_size_hint}% +\begin{codeblock} +namespace std { + class thread::stack_size_hint { + public: + constexpr explicit stack_size_hint(size_t s) noexcept; + + private: + size_t @\exposidnc{size}@; // \expos + }; +} +\end{codeblock} + +\pnum +\tcode{stack_size_hint} can be used to configure a desired size in bytes +for platform-specific storage required for a thread. +\begin{note} +Such storage is typically used for variables with automatic storage duration. +\end{note} + +\pnum +The stack size set by the implementation may be adjusted up or down +to meet platform-specific requirements. + +\pnum +If \exposid{size} is zero, the thread attribute is ignored. + +\indexlibraryctor{thread::stack_size_hint}% +\begin{itemdecl} +constexpr explicit stack_size_hint(size_t s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \exposid{size} with \tcode{s}. +\end{itemdescr} + \rSec3[thread.thread.id]{Class \tcode{thread::id}} \indexlibraryglobal{thread::id}% @@ -1587,7 +1715,7 @@ \begin{itemdecl} template basic_ostream& - operator<< (basic_ostream& out, thread::id id); + operator<<(basic_ostream& out, thread::id id); \end{itemdecl} \begin{itemdescr} @@ -1660,21 +1788,56 @@ \indexlibraryctor{thread}% \begin{itemdecl} -template explicit thread(F&& f, Args&&... args); +template explicit thread(Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum \constraints -\tcode{remove_cvref_t} is not the same type as \tcode{thread}. +\begin{itemize} +\item +\tcode{Args} is not an empty pack, and +\item +\tcode{remove_cvref_t} is not the same type as \tcode{thread}. +\end{itemize} + +\pnum +Let $i$ be the smallest value such that +\tcode{decay_t} +is not a thread attribute type, +if such a value exists. +Then the following notation is used: +\begin{itemize} +\item +Let \tcode{F} be \tcode{Args...[$i$]}. +\item +Let \tcode{f} be \tcode{args...[$i$]}. +\item +Let \tcode{Attrs} be a pack of the types +\tcode{Args...[$j$]} for each $j$ +such that $0 \leq j < i$. +\item +Let \tcode{attrs} be a pack of the expressions +\tcode{args...[$j$]} for each $j$ +such that $0 \leq j < i$. +\item +Let \tcode{FArgs} be a pack of the types +\tcode{Args...[$j$]} for each $j$ +such that $i < j < \tcode{sizeof...(args)}$. +\item +Let \tcode{fargs} be a pack of the expressions +\tcode{args...[$j$]} for each $j$ +such that $i < j < \tcode{sizeof...(args)}$. +\end{itemize} \pnum \mandates -The following are all \tcode{true}: +The value $i$ exists, and the following are all \tcode{true}: \begin{itemize} \item \tcode{is_constructible_v, F>}, -\item \tcode{(is_constructible_v, Args> \&\& ...)}, and -\item \tcode{is_invocable_v, decay_t...>}. +\item \tcode{(is_constructible_v, FArgs> \&\& ...)}, +\item \tcode{is_invocable_v, decay_t...>}, and +\item no type is present more than once in the pack \tcode{remove_cvref_t}. \end{itemize} \pnum @@ -1682,7 +1845,7 @@ The new thread of execution executes \begin{codeblock} invoke(auto(std::forward(f)), // for \tcode{invoke}, see \ref{func.invoke} - auto(std::forward(args))...) + auto(std::forward(fargs))...) \end{codeblock} with the values produced by \tcode{auto} being materialized\iref{conv.rval} in the constructing thread. @@ -1693,6 +1856,10 @@ \end{note} If the invocation of \tcode{invoke} terminates with an uncaught exception, \tcode{terminate} is invoked\iref{except.terminate}. +\begin{note} +The parameters \tcode{attrs...} +can affect the behavior of the new thread\iref{thread.attributes}. +\end{note} \pnum \sync @@ -1936,9 +2103,14 @@ using id = thread::id; using native_handle_type = thread::native_handle_type; + template + using name_hint = thread::name_hint; + using stack_size_hint = thread::stack_size_hint; + // \ref{thread.jthread.cons}, constructors, move, and assignment jthread() noexcept; - template explicit jthread(F&& f, Args&&... args); + template + explicit jthread(Args&&... args); ~jthread(); jthread(const jthread&) = delete; jthread(jthread&&) noexcept; @@ -1965,7 +2137,7 @@ static unsigned int hardware_concurrency() noexcept; private: - stop_source ssource; // \expos + stop_source @\exposid{ssource}@; // \expos }; } \end{codeblock} @@ -1986,40 +2158,76 @@ \pnum \ensures \tcode{get_id() == id()} is \tcode{true} -and \tcode{ssource.stop_possible()} is \tcode{false}. +and \tcode{\exposid{ssource}.stop_possible()} is \tcode{false}. \end{itemdescr} \indexlibraryctor{jthread}% \begin{itemdecl} -template explicit jthread(F&& f, Args&&... args); +template explicit jthread(Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum \constraints -\tcode{remove_cvref_t} is not the same type as \tcode{jthread}. +\begin{itemize} +\item +\tcode{Args} is not an empty pack, and +\item +\tcode{remove_cvref_t} is not the same type as \tcode{jthread}. +\end{itemize} + +\pnum +Let $i$ be the smallest value such that +\tcode{decay_t} +is not a thread attribute type, +if such a value exists. +Then the following notation is used: +\begin{itemize} +\item +Let \tcode{F} be \tcode{Args...[$i$]}. +\item +Let \tcode{f} be \tcode{args...[$i$]}. +\item +Let \tcode{Attrs} be a pack of the types +\tcode{Args...[$j$]} for each $j$ +such that $0 \leq j < i$. +\item +Let \tcode{attrs} be a pack of the expressions +\tcode{args...[$j$]} for each $j$ +such that $0 \leq j < i$. +\item +Let \tcode{FArgs} be a pack of the types +\tcode{Args...[$j$]} for each $j$ +such that $i < j < \tcode{sizeof...(args)}$. +\item +Let \tcode{fargs} be a pack of the expressions +\tcode{args...[$j$]} for each $j$ +such that $i < j < \tcode{sizeof...(args)}$. +\end{itemize} \pnum \mandates -The following are all \tcode{true}: +The value $i$ exists, and the following are all \tcode{true}: \begin{itemize} \item \tcode{is_constructible_v, F>}, -\item \tcode{(is_constructible_v, Args> \&\& ...)}, and -\item \tcode{is_invocable_v, decay_t...> ||} \\ \tcode{is_invocable_v, stop_token, decay_t...>}. +\item \tcode{(is_constructible_v, FArgs> \&\& ...)}, +\item \tcode{is_invocable_v, decay_t...> ||} \\ + \tcode{is_invocable_v, stop_token, decay_t...>}, and +\item no type is present more than once in the pack \tcode{remove_cvref_t}. \end{itemize} \pnum \effects -Initializes \tcode{ssource}. +Initializes \exposid{ssource}. The new thread of execution executes \begin{codeblock} invoke(auto(std::forward(f)), get_stop_token(), // for \tcode{invoke}, see \ref{func.invoke} - auto(std::forward(args))...) + auto(std::forward(fargs))...) \end{codeblock} if that expression is well-formed, otherwise \begin{codeblock} -invoke(auto(std::forward(f)), auto(std::forward(args))...) +invoke(auto(std::forward(f)), auto(std::forward(fargs))...) \end{codeblock} with the values produced by \tcode{auto} being materialized\iref{conv.rval} in the constructing thread. @@ -2030,6 +2238,10 @@ \end{note} If the \tcode{invoke} expression exits via an exception, \tcode{terminate} is called. +\begin{note} +The parameters \tcode{attrs...} +can affect the behavior of the new thread\iref{thread.attributes}. +\end{note} \pnum \sync @@ -2039,7 +2251,7 @@ \pnum \ensures \tcode{get_id() != id()} is \tcode{true} -and \tcode{ssource.stop_possible()} is \tcode{true} +and \tcode{\exposid{ssource}.stop_possible()} is \tcode{true} and \tcode{*this} represents the newly started thread. \begin{note} The calling thread can make a stop request only once, @@ -2071,9 +2283,9 @@ \tcode{x.get_id() == id()} and \tcode{get_id()} returns the value of \tcode{x.get_id()} prior to the start of construction. -\tcode{ssource} has the value of \tcode{x.ssource} +\exposid{ssource} has the value of \tcode{x.\exposid{ssource}} prior to the start of construction -and \tcode{x.ssource.stop_possible()} is \tcode{false}. +and \tcode{x.\exposid{ssource}.stop_possible()} is \tcode{false}. \end{itemdescr} \indexlibrarydtor{jthread}% @@ -2109,7 +2321,7 @@ \ensures \tcode{get_id()} returns the value of \tcode{x.get_id()} prior to the assignment. -\tcode{ssource} has the value of \tcode{x.ssource} +\exposid{ssource} has the value of \tcode{x.\exposid{ssource}} prior to the assignment. \pnum @@ -2237,7 +2449,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return ssource;} +Equivalent to: \tcode{return \exposid{ssource};} \end{itemdescr} \indexlibrarymember{get_stop_token}{jthread}% @@ -2248,7 +2460,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return ssource.get_token();} +Equivalent to: \tcode{return \exposid{ssource}.get_token();} \end{itemdescr} \indexlibrarymember{request_stop}{jthread}% @@ -2259,7 +2471,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return ssource.request_stop();} +Equivalent to: \tcode{return \exposid{ssource}.request_stop();} \end{itemdescr} @@ -2382,6 +2594,10 @@ \rSec2[atomics.general]{General} +\pnum +Let \tcode{\placeholdernc{COPYCV}(FROM, TO)} be an alias for type \tcode{TO} +with the addition of \tcode{FROM}'s top-level cv-qualifiers. + \pnum Subclause \ref{atomics} describes components for fine-grained atomic access. This access is provided via operations on atomic objects. @@ -2390,330 +2606,354 @@ \indexheader{atomic}% \begin{codeblock} +// mostly freestanding namespace std { // \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 - constexpr T kill_dependency(T y) noexcept; // freestanding + enum class memory_order : @\unspecnc@; + inline constexpr memory_order memory_order_relaxed = memory_order::relaxed; + inline constexpr memory_order memory_order_acquire = memory_order::acquire; + inline constexpr memory_order memory_order_release = memory_order::release; + inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel; + inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst; } // \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@ +#define @\libmacro{ATOMIC_CHAR_LOCK_FREE}@ @\unspecnc@ +#define @\libmacro{ATOMIC_CHAR8_T_LOCK_FREE}@ @\unspecnc@ +#define @\libmacro{ATOMIC_CHAR16_T_LOCK_FREE}@ @\unspecnc@ +#define @\libmacro{ATOMIC_CHAR32_T_LOCK_FREE}@ @\unspecnc@ +#define @\libmacro{ATOMIC_WCHAR_T_LOCK_FREE}@ @\unspecnc@ +#define @\libmacro{ATOMIC_SHORT_LOCK_FREE}@ @\unspecnc@ +#define @\libmacro{ATOMIC_INT_LOCK_FREE}@ @\unspecnc@ +#define @\libmacro{ATOMIC_LONG_LOCK_FREE}@ @\unspecnc@ +#define @\libmacro{ATOMIC_LLONG_LOCK_FREE}@ @\unspecnc@ +#define @\libmacro{ATOMIC_POINTER_LOCK_FREE}@ @\unspecnc@ namespace std { // \ref{atomics.ref.generic}, class template \tcode{atomic_ref} - template struct atomic_ref; // freestanding - // \ref{atomics.ref.pointer}, partial specialization for pointers - template struct atomic_ref; // freestanding + template struct atomic_ref; // \ref{atomics.types.generic}, class template \tcode{atomic} - template struct atomic; // freestanding + template struct atomic; // \ref{atomics.types.pointer}, partial specialization for pointers - template struct atomic; // freestanding + template struct atomic; // \ref{atomics.nonmembers}, non-member functions template - bool atomic_is_lock_free(const volatile atomic*) noexcept; // freestanding + bool atomic_is_lock_free(const volatile atomic*) noexcept; template - bool atomic_is_lock_free(const atomic*) noexcept; // freestanding + bool atomic_is_lock_free(const atomic*) noexcept; template - void atomic_store(volatile atomic*, // freestanding - typename atomic::value_type) noexcept; + void atomic_store(volatile atomic*, typename atomic::value_type) noexcept; template - constexpr void atomic_store(atomic*, // freestanding - typename atomic::value_type) noexcept; + constexpr void atomic_store(atomic*, typename atomic::value_type) noexcept; template - void atomic_store_explicit(volatile atomic*, // freestanding - typename atomic::value_type, memory_order) noexcept; + void atomic_store_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; template - constexpr void atomic_store_explicit(atomic*, // freestanding - typename atomic::value_type, memory_order) noexcept; + constexpr void atomic_store_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; template - T atomic_load(const volatile atomic*) noexcept; // freestanding + T atomic_load(const volatile atomic*) noexcept; template - constexpr T atomic_load(const atomic*) noexcept; // freestanding + constexpr T atomic_load(const atomic*) noexcept; template - T atomic_load_explicit(const volatile atomic*, memory_order) noexcept; // freestanding + T atomic_load_explicit(const volatile atomic*, memory_order) noexcept; template - constexpr T atomic_load_explicit(const atomic*, memory_order) noexcept; // freestanding + constexpr T atomic_load_explicit(const atomic*, memory_order) noexcept; template - T atomic_exchange(volatile atomic*, // freestanding - typename atomic::value_type) noexcept; + T atomic_exchange(volatile atomic*, typename atomic::value_type) noexcept; template - constexpr T atomic_exchange(atomic*, // freestanding - typename atomic::value_type) noexcept; + constexpr T atomic_exchange(atomic*, typename atomic::value_type) noexcept; template - T atomic_exchange_explicit(volatile atomic*, // freestanding - typename atomic::value_type, memory_order) noexcept; + T atomic_exchange_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; template - constexpr T atomic_exchange_explicit(atomic*, // freestanding - typename atomic::value_type, + constexpr T atomic_exchange_explicit(atomic*, typename atomic::value_type, memory_order) noexcept; template - bool atomic_compare_exchange_weak(volatile atomic*, // freestanding + bool atomic_compare_exchange_weak(volatile atomic*, typename atomic::value_type*, typename atomic::value_type) noexcept; template - constexpr bool atomic_compare_exchange_weak(atomic*, // freestanding + constexpr bool atomic_compare_exchange_weak(atomic*, typename atomic::value_type*, typename atomic::value_type) noexcept; template - bool atomic_compare_exchange_strong(volatile atomic*, // freestanding + bool atomic_compare_exchange_strong(volatile atomic*, typename atomic::value_type*, typename atomic::value_type) noexcept; template - constexpr bool atomic_compare_exchange_strong(atomic*, // freestanding + constexpr bool atomic_compare_exchange_strong(atomic*, typename atomic::value_type*, typename atomic::value_type) noexcept; template - bool atomic_compare_exchange_weak_explicit(volatile atomic*, // freestanding + bool atomic_compare_exchange_weak_explicit(volatile atomic*, typename atomic::value_type*, typename atomic::value_type, memory_order, memory_order) noexcept; template - constexpr 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*, + typename atomic::value_type*, + typename atomic::value_type, + memory_order, memory_order) noexcept; template - bool atomic_compare_exchange_strong_explicit(volatile atomic*, // freestanding + bool atomic_compare_exchange_strong_explicit(volatile atomic*, typename atomic::value_type*, typename atomic::value_type, memory_order, memory_order) noexcept; template - constexpr 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*, + 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; + T atomic_fetch_add(volatile atomic*, typename atomic::difference_type) noexcept; template - constexpr T atomic_fetch_add(atomic*, // freestanding - typename atomic::difference_type) noexcept; + constexpr T atomic_fetch_add(atomic*, typename atomic::difference_type) noexcept; template - T atomic_fetch_add_explicit(volatile atomic*, // freestanding - typename atomic::difference_type, + T atomic_fetch_add_explicit(volatile atomic*, typename atomic::difference_type, memory_order) noexcept; template - constexpr T atomic_fetch_add_explicit(atomic*, // freestanding - typename atomic::difference_type, + constexpr T atomic_fetch_add_explicit(atomic*, typename atomic::difference_type, memory_order) noexcept; template - T atomic_fetch_sub(volatile atomic*, // freestanding - typename atomic::difference_type) noexcept; + T atomic_fetch_sub(volatile atomic*, typename atomic::difference_type) noexcept; template - constexpr T atomic_fetch_sub(atomic*, // freestanding - typename atomic::difference_type) noexcept; + constexpr T atomic_fetch_sub(atomic*, typename atomic::difference_type) noexcept; template - T atomic_fetch_sub_explicit(volatile atomic*, // freestanding - typename atomic::difference_type, + T atomic_fetch_sub_explicit(volatile atomic*, typename atomic::difference_type, memory_order) noexcept; template - constexpr T atomic_fetch_sub_explicit(atomic*, // freestanding - typename atomic::difference_type, + constexpr T atomic_fetch_sub_explicit(atomic*, typename atomic::difference_type, memory_order) noexcept; template - T atomic_fetch_and(volatile atomic*, // freestanding - typename atomic::value_type) noexcept; + T atomic_fetch_and(volatile atomic*, typename atomic::value_type) noexcept; template - constexpr T atomic_fetch_and(atomic*, // freestanding - typename atomic::value_type) noexcept; + constexpr T atomic_fetch_and(atomic*, typename atomic::value_type) noexcept; template - T atomic_fetch_and_explicit(volatile atomic*, // freestanding - typename atomic::value_type, + T atomic_fetch_and_explicit(volatile atomic*, typename atomic::value_type, memory_order) noexcept; template - constexpr T atomic_fetch_and_explicit(atomic*, // freestanding - typename atomic::value_type, + constexpr T atomic_fetch_and_explicit(atomic*, typename atomic::value_type, memory_order) noexcept; template - T atomic_fetch_or(volatile atomic*, // freestanding - typename atomic::value_type) noexcept; + T atomic_fetch_or(volatile atomic*, typename atomic::value_type) noexcept; template - constexpr T atomic_fetch_or(atomic*, // freestanding - typename atomic::value_type) noexcept; + constexpr T atomic_fetch_or(atomic*, typename atomic::value_type) noexcept; template - T atomic_fetch_or_explicit(volatile atomic*, // freestanding - typename atomic::value_type, + T atomic_fetch_or_explicit(volatile atomic*, typename atomic::value_type, memory_order) noexcept; template - constexpr T atomic_fetch_or_explicit(atomic*, // freestanding - typename atomic::value_type, + constexpr T atomic_fetch_or_explicit(atomic*, typename atomic::value_type, memory_order) noexcept; template - T atomic_fetch_xor(volatile atomic*, // freestanding - typename atomic::value_type) noexcept; + T atomic_fetch_xor(volatile atomic*, typename atomic::value_type) noexcept; template - constexpr T atomic_fetch_xor(atomic*, // freestanding - typename atomic::value_type) noexcept; + constexpr T atomic_fetch_xor(atomic*, typename atomic::value_type) noexcept; template - T atomic_fetch_xor_explicit(volatile atomic*, // freestanding - typename atomic::value_type, + T atomic_fetch_xor_explicit(volatile atomic*, typename atomic::value_type, memory_order) noexcept; template - constexpr T atomic_fetch_xor_explicit(atomic*, // freestanding - typename atomic::value_type, + constexpr T atomic_fetch_xor_explicit(atomic*, typename atomic::value_type, memory_order) noexcept; template - T atomic_fetch_max(volatile atomic*, // freestanding - typename atomic::value_type) noexcept; + T atomic_fetch_max(volatile atomic*, typename atomic::value_type) noexcept; template - constexpr T atomic_fetch_max(atomic*, // freestanding - typename atomic::value_type) noexcept; + constexpr T atomic_fetch_max(atomic*, typename atomic::value_type) noexcept; template - T atomic_fetch_max_explicit(volatile atomic*, // freestanding - typename atomic::value_type, + T atomic_fetch_max_explicit(volatile atomic*, typename atomic::value_type, memory_order) noexcept; template - constexpr T atomic_fetch_max_explicit(atomic*, // freestanding - typename atomic::value_type, - memory_order) noexcept; + constexpr T atomic_fetch_max_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; template - T atomic_fetch_min(volatile atomic*, // freestanding - typename atomic::value_type) noexcept; + T atomic_fetch_min(volatile atomic*, typename atomic::value_type) noexcept; template - constexpr T atomic_fetch_min(atomic*, // freestanding - typename atomic::value_type) noexcept; + constexpr T atomic_fetch_min(atomic*, typename atomic::value_type) noexcept; template - T atomic_fetch_min_explicit(volatile atomic*, // freestanding - typename atomic::value_type, + T atomic_fetch_min_explicit(volatile atomic*, typename atomic::value_type, memory_order) noexcept; template - constexpr T atomic_fetch_min_explicit(atomic*, // freestanding - typename atomic::value_type, - memory_order) noexcept; + constexpr T atomic_fetch_min_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; + + template + void atomic_store_add(volatile atomic*, typename atomic::difference_type) noexcept; + template + constexpr void atomic_store_add(atomic*, typename atomic::difference_type) noexcept; + template + void atomic_store_add_explicit(volatile atomic*, typename atomic::difference_type, + memory_order) noexcept; + template + constexpr void atomic_store_add_explicit(atomic*, typename atomic::difference_type, + memory_order) noexcept; + template + void atomic_store_sub(volatile atomic*, typename atomic::difference_type) noexcept; + template + constexpr void atomic_store_sub(atomic*, typename atomic::difference_type) noexcept; + template + void atomic_store_sub_explicit(volatile atomic*, typename atomic::difference_type, + memory_order) noexcept; + template + constexpr void atomic_store_sub_explicit(atomic*, typename atomic::difference_type, + memory_order) noexcept; + template + void atomic_store_and(volatile atomic*, typename atomic::value_type) noexcept; + template + constexpr void atomic_store_and(atomic*, typename atomic::value_type) noexcept; + template + void atomic_store_and_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; + template + constexpr void atomic_store_and_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; + template + void atomic_store_or(volatile atomic*, typename atomic::value_type) noexcept; + template + constexpr void atomic_store_or(atomic*, typename atomic::value_type) noexcept; + template + void atomic_store_or_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; + template + constexpr void atomic_store_or_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; template - void atomic_wait(const volatile atomic*, // freestanding - typename atomic::value_type) noexcept; + void atomic_store_xor(volatile atomic*, typename atomic::value_type) noexcept; template - constexpr void atomic_wait(const atomic*, // freestanding - typename atomic::value_type) noexcept; + constexpr void atomic_store_xor(atomic*, typename atomic::value_type) noexcept; template - void atomic_wait_explicit(const volatile atomic*, // freestanding - typename atomic::value_type, + void atomic_store_xor_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; + template + constexpr void atomic_store_xor_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; + template + void atomic_store_max(volatile atomic*, typename atomic::value_type) noexcept; + template + constexpr void atomic_store_max(atomic*, typename atomic::value_type) noexcept; + template + void atomic_store_max_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; + template + constexpr void atomic_store_max_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; + template + void atomic_store_min(volatile atomic*, typename atomic::value_type) noexcept; + template + constexpr void atomic_store_min(atomic*, typename atomic::value_type) noexcept; + template + void atomic_store_min_explicit(volatile atomic*, typename atomic::value_type, + memory_order) noexcept; + template + constexpr void atomic_store_min_explicit(atomic*, typename atomic::value_type, + memory_order) noexcept; + + template + void atomic_wait(const volatile atomic*, typename atomic::value_type) noexcept; + template + constexpr void atomic_wait(const atomic*, typename atomic::value_type) noexcept; + template + void atomic_wait_explicit(const volatile atomic*, typename atomic::value_type, memory_order) noexcept; template - constexpr void atomic_wait_explicit(const atomic*, // freestanding - typename atomic::value_type, + constexpr void atomic_wait_explicit(const atomic*, typename atomic::value_type, memory_order) noexcept; template - void atomic_notify_one(volatile atomic*) noexcept; // freestanding + void atomic_notify_one(volatile atomic*) noexcept; template - constexpr void atomic_notify_one(atomic*) noexcept; // freestanding + constexpr void atomic_notify_one(atomic*) noexcept; template - void atomic_notify_all(volatile atomic*) noexcept; // freestanding + void atomic_notify_all(volatile atomic*) noexcept; template - constexpr void atomic_notify_all(atomic*) noexcept; // freestanding + constexpr void atomic_notify_all(atomic*) noexcept; // \ref{atomics.alias}, type aliases - using atomic_bool = atomic; // freestanding - using atomic_char = atomic; // freestanding - using atomic_schar = atomic; // freestanding - using atomic_uchar = atomic; // freestanding - using atomic_short = atomic; // freestanding - using atomic_ushort = atomic; // freestanding - using atomic_int = atomic; // freestanding - using atomic_uint = atomic; // freestanding - using atomic_long = atomic; // freestanding - using atomic_ulong = atomic; // freestanding - using atomic_llong = atomic; // freestanding - using atomic_ullong = atomic; // freestanding - using atomic_char8_t = atomic; // freestanding - using atomic_char16_t = atomic; // freestanding - using atomic_char32_t = atomic; // freestanding - using atomic_wchar_t = atomic; // freestanding - - using atomic_int8_t = atomic; // freestanding - using atomic_uint8_t = atomic; // freestanding - using atomic_int16_t = atomic; // freestanding - using atomic_uint16_t = atomic; // freestanding - using atomic_int32_t = atomic; // freestanding - using atomic_uint32_t = atomic; // freestanding - using atomic_int64_t = atomic; // freestanding - using atomic_uint64_t = atomic; // freestanding - - using atomic_int_least8_t = atomic; // freestanding - using atomic_uint_least8_t = atomic; // freestanding - using atomic_int_least16_t = atomic; // freestanding - using atomic_uint_least16_t = atomic; // freestanding - using atomic_int_least32_t = atomic; // freestanding - using atomic_uint_least32_t = atomic; // freestanding - using atomic_int_least64_t = atomic; // freestanding - using atomic_uint_least64_t = atomic; // freestanding - - using atomic_int_fast8_t = atomic; // freestanding - using atomic_uint_fast8_t = atomic; // freestanding - using atomic_int_fast16_t = atomic; // freestanding - using atomic_uint_fast16_t = atomic; // freestanding - using atomic_int_fast32_t = atomic; // freestanding - using atomic_uint_fast32_t = atomic; // freestanding - using atomic_int_fast64_t = atomic; // freestanding - using atomic_uint_fast64_t = atomic; // freestanding - - using atomic_intptr_t = atomic; // freestanding - using atomic_uintptr_t = atomic; // freestanding - using atomic_size_t = atomic; // freestanding - using atomic_ptrdiff_t = atomic; // freestanding - using atomic_intmax_t = atomic; // freestanding - using atomic_uintmax_t = atomic; // freestanding - - using atomic_signed_lock_free = @\seebelow@; - using atomic_unsigned_lock_free = @\seebelow@; + using atomic_bool = atomic; + using atomic_char = atomic; + using atomic_schar = atomic; + using atomic_uchar = atomic; + using atomic_short = atomic; + using atomic_ushort = atomic; + using atomic_int = atomic; + using atomic_uint = atomic; + using atomic_long = atomic; + using atomic_ulong = atomic; + using atomic_llong = atomic; + using atomic_ullong = atomic; + using atomic_char8_t = atomic; + using atomic_char16_t = atomic; + using atomic_char32_t = atomic; + using atomic_wchar_t = atomic; + + using atomic_int8_t = atomic; + using atomic_uint8_t = atomic; + using atomic_int16_t = atomic; + using atomic_uint16_t = atomic; + using atomic_int32_t = atomic; + using atomic_uint32_t = atomic; + using atomic_int64_t = atomic; + using atomic_uint64_t = atomic; + + using atomic_int_least8_t = atomic; + using atomic_uint_least8_t = atomic; + using atomic_int_least16_t = atomic; + using atomic_uint_least16_t = atomic; + using atomic_int_least32_t = atomic; + using atomic_uint_least32_t = atomic; + using atomic_int_least64_t = atomic; + using atomic_uint_least64_t = atomic; + + using atomic_int_fast8_t = atomic; + using atomic_uint_fast8_t = atomic; + using atomic_int_fast16_t = atomic; + using atomic_uint_fast16_t = atomic; + using atomic_int_fast32_t = atomic; + using atomic_uint_fast32_t = atomic; + using atomic_int_fast64_t = atomic; + using atomic_uint_fast64_t = atomic; + + using atomic_intptr_t = atomic; + using atomic_uintptr_t = atomic; + using atomic_size_t = atomic; + using atomic_ptrdiff_t = atomic; + using atomic_intmax_t = atomic; + using atomic_uintmax_t = atomic; + + using atomic_signed_lock_free = @\seebelow@; // hosted + using atomic_unsigned_lock_free = @\seebelow@; // hosted // \ref{atomics.flag}, flag type and operations - struct atomic_flag; // freestanding - - bool atomic_flag_test(const volatile 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; - constexpr bool atomic_flag_test_explicit(const atomic_flag*, // freestanding - memory_order) noexcept; - bool atomic_flag_test_and_set(volatile 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; - constexpr bool atomic_flag_test_and_set_explicit(atomic_flag*, // freestanding - memory_order) noexcept; - void atomic_flag_clear(volatile 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 - constexpr void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept; // freestanding - - void atomic_flag_wait(const volatile 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; - constexpr void atomic_flag_wait_explicit(const atomic_flag*, // freestanding - bool, memory_order) noexcept; - void atomic_flag_notify_one(volatile atomic_flag*) noexcept; // freestanding - constexpr void atomic_flag_notify_one(atomic_flag*) noexcept; // freestanding - void atomic_flag_notify_all(volatile atomic_flag*) noexcept; // freestanding - constexpr void atomic_flag_notify_all(atomic_flag*) noexcept; // freestanding - #define ATOMIC_FLAG_INIT @\seebelownc@ // freestanding + struct atomic_flag; + + bool atomic_flag_test(const volatile atomic_flag*) noexcept; + constexpr bool atomic_flag_test(const atomic_flag*) noexcept; + bool atomic_flag_test_explicit(const volatile atomic_flag*, memory_order) noexcept; + constexpr bool atomic_flag_test_explicit(const atomic_flag*, memory_order) noexcept; + bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept; + constexpr bool atomic_flag_test_and_set(atomic_flag*) noexcept; + bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order) noexcept; + constexpr bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order) noexcept; + void atomic_flag_clear(volatile atomic_flag*) noexcept; + constexpr void atomic_flag_clear(atomic_flag*) noexcept; + void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept; + constexpr void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept; + + void atomic_flag_wait(const volatile atomic_flag*, bool) noexcept; + constexpr void atomic_flag_wait(const atomic_flag*, bool) noexcept; + void atomic_flag_wait_explicit(const volatile atomic_flag*, bool, memory_order) noexcept; + constexpr void atomic_flag_wait_explicit(const atomic_flag*, bool, memory_order) noexcept; + void atomic_flag_notify_one(volatile atomic_flag*) noexcept; + constexpr void atomic_flag_notify_one(atomic_flag*) noexcept; + void atomic_flag_notify_all(volatile atomic_flag*) noexcept; + constexpr void atomic_flag_notify_all(atomic_flag*) noexcept; + #define @\libmacro{ATOMIC_FLAG_INIT}@ @\seebelownc@ // \ref{atomics.fences}, fences - extern "C" constexpr void atomic_thread_fence(memory_order) noexcept; // freestanding - extern "C" constexpr void atomic_signal_fence(memory_order) noexcept; // freestanding + extern "C" constexpr void atomic_thread_fence(memory_order) noexcept; + extern "C" constexpr void atomic_signal_fence(memory_order) noexcept; } \end{codeblock} @@ -2765,12 +3005,10 @@ \indexlibraryglobal{atomic_intmax_t}% \indexlibraryglobal{atomic_uintmax_t}% \pnum -The type aliases \tcode{atomic_int$N$_t}, \tcode{atomic_uint$N$_t}, -\tcode{atomic_intptr_t}, and \tcode{atomic_uintptr_t} -are defined if and only if -\tcode{int$N$_t}, \tcode{uint$N$_t}, -\tcode{intptr_t}, and \tcode{uintptr_t} -are defined, respectively. +The type aliases \tcode{atomic_int$N$_t} and \tcode{atomic_uint$N$_t} +are declared if and only if +\tcode{int$N$_t} and \tcode{uint$N$_t} +are declared, respectively. \pnum \indexlibraryglobal{atomic_signed_lock_free}% @@ -2792,13 +3030,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}% @@ -2807,7 +3043,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} @@ -2825,15 +3061,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. @@ -2979,61 +3206,67 @@ \end{codeblock} \end{note} -\pnum -Atomic read-modify-write operations shall always read the last value -(in the modification order) written before the write associated with -the read-modify-write operation. +\begin{note} +An implementation that +translates to instruction sequences for a physical machine and +treats non-volatile atomic accesses as though they were volatile +does not produce out-of-thin-air values for a program free of undefined behavior. +An implementation that +performs only thread-at-a-time analysis in support of optimizations +that omit and merge non-volatile atomic accesses to the same object and +reorder non-volatile atomic accesses to different objects (when permitted by the as-if rule) and +otherwise treats non-volatile atomic accesses as though they were volatile +does not produce out-of-thin-air values for a program free of undefined behavior. +The possibility of out-of-thin-air values remains +for implementations not meeting these restrictions. +\end{note} \pnum -\recommended -The implementation should make atomic stores visible to atomic loads, -and atomic loads should observe atomic stores, -within a reasonable amount of time. - -\indexlibraryglobal{kill_dependency}% -\begin{itemdecl} -template - constexpr T kill_dependency(T y) noexcept; -\end{itemdecl} +\begin{note} +Unlike abstract machines, +physical machines are subject to instruction-execution and information-transfer latencies. +Physical machines carefully manage any speculative execution +so as to avoid generating out-of-thin-air values at the hardware level. +\end{note} -\begin{itemdescr} \pnum -\effects -The argument does not carry a dependency to the return -value\iref{intro.multithread}. +An atomic read-modify-write operation always reads the value +from the side effect that immediately precedes the side effect of the +read-modify-write operation in the modification order. \pnum -\returns -\tcode{y}. -\end{itemdescr} +An \defnadj{atomic}{modify-write operation} is +an atomic read-modify-write operation +with weaker synchronization requirements as specified in~\ref{atomics.fences}. +\begin{note} +The intent is for atomic modify-write operations +to be implemented using mechanisms that are not ordered, in hardware, +by the implementation of acquire fences. +No other semantic or hardware property +(e.g., that the mechanism is a far atomic operation) is implied. +\end{note} +\pnum +\recommended +The implementation should make atomic stores visible to atomic loads, +and atomic loads should observe atomic stores, +within a reasonable amount of time. \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 @@ -3138,17 +3371,21 @@ namespace std { template struct atomic_ref { private: - T* ptr; // \expos + T* @\exposid{ptr}@; // \expos public: using value_type = remove_cv_t; + using @\exposid{address-return-type}@ = @\placeholdernc{COPYCV}@(T, void)*; // \expos 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; constexpr explicit atomic_ref(T&); + explicit atomic_ref(T&&) = delete; constexpr atomic_ref(const atomic_ref&) noexcept; + template + constexpr atomic_ref(const atomic_ref&) noexcept; atomic_ref& operator=(const atomic_ref&) = delete; constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept; @@ -3170,25 +3407,25 @@ 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; + constexpr @\exposid{address-return-type}@ address() const noexcept; }; } \end{codeblock} \pnum An \tcode{atomic_ref} object applies atomic operations\iref{atomics.general} to -the object referenced by \tcode{*ptr} such that, +the object referenced by \tcode{*\exposid{ptr}} such that, for the lifetime\iref{basic.life} of the \tcode{atomic_ref} object, -the object referenced by \tcode{*ptr} is an atomic object\iref{intro.races}. +the object referenced by \tcode{*\exposid{ptr}} is an atomic object\iref{intro.races}. \pnum The program is ill-formed if \tcode{is_trivially_copyable_v} is \tcode{false}. \pnum -The lifetime\iref{basic.life} of an object referenced by \tcode{*ptr} +The lifetime\iref{basic.life} of an object referenced by \tcode{*\exposid{ptr}} shall exceed the lifetime of all \tcode{atomic_ref}s that reference the object. While any \tcode{atomic_ref} instances exist -that reference the \tcode{*ptr} object, +that reference the \tcode{*\exposid{ptr}} object, all accesses to that object shall exclusively occur through those \tcode{atomic_ref} instances. No subobject of the object referenced by \tcode{atomic_ref} @@ -3213,7 +3450,7 @@ \rSec3[atomics.ref.ops]{Operations} \indexlibrarymember{required_alignment}{atomic_ref}% -\indexlibrarymember{required_alignment}{atomic_ref}% +\indexlibrarymember{required_alignment}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{required_alignment}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{required_alignment}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} @@ -3224,22 +3461,21 @@ \pnum The alignment required for an object to be referenced by an atomic reference, which is at least \tcode{alignof(T)}. +For any type \tcode{U} similar to \tcode{T}, +the value of \tcode{required_alignment} +is the same as \tcode{atomic_ref>::required_alignment}. \pnum \begin{note} -Hardware could require an object -referenced by an \tcode{atomic_ref} -to have stricter alignment\iref{basic.align} -than other objects of type \tcode{T}. -Further, whether operations on an \tcode{atomic_ref} -are lock-free could depend on the alignment of the referenced object. -For example, lock-free operations on \tcode{std::complex} -could be supported only if aligned to \tcode{2*alignof(double)}. +An implementation can choose to define +\tcode{atomic_ref::required_alignment} +to a value greater than \tcode{alignof(T)} in order to ensure that +operations on all objects of type \tcode{atomic_ref} are lock-free. \end{note} \end{itemdescr} \indexlibrarymember{is_always_lock_free}{atomic_ref}% -\indexlibrarymember{is_always_lock_free}{atomic_ref}% +\indexlibrarymember{is_always_lock_free}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{is_always_lock_free}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{is_always_lock_free}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} @@ -3251,10 +3487,13 @@ The static data member \tcode{is_always_lock_free} is \tcode{true} if the \tcode{atomic_ref} type's operations are always lock-free, and \tcode{false} otherwise. +For any type \tcode{U} similar to \tcode{T}, +the value of \tcode{is_always_lock_free} +is the same as \tcode{atomic_ref>::is_always_lock_free}. \end{itemdescr} \indexlibrarymember{is_lock_free}{atomic_ref}% -\indexlibrarymember{is_lock_free}{atomic_ref}% +\indexlibrarymember{is_lock_free}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{is_lock_free}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{is_lock_free}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} @@ -3270,7 +3509,7 @@ \end{itemdescr} \indexlibraryctor{atomic_ref}% -\indexlibraryctor{atomic_ref}% +\indexlibraryctor{atomic_ref<\placeholder{pointer-type}>}% \indexlibrary{\idxcode{atomic_ref<\placeholder{integral-type}>}!constructor}% \indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point-type}>}!constructor}% \begin{itemdecl} @@ -3292,7 +3531,7 @@ \end{itemdescr} \indexlibraryctor{atomic_ref}% -\indexlibraryctor{atomic_ref}% +\indexlibraryctor{atomic_ref<\placeholder{pointer-type}>}% \indexlibrary{\idxcode{atomic_ref<\placeholder{integral-type}>}!constructor}% \indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point-type}>}!constructor}% \begin{itemdecl} @@ -3305,8 +3544,26 @@ \tcode{*this} references the object referenced by \tcode{ref}. \end{itemdescr} +\begin{itemdecl} +template + constexpr atomic_ref(const atomic_ref& ref) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{T} and \tcode{U} are similar types\iref{conv.qual}, and +\item \tcode{is_convertible_v} is \tcode{true}. +\end{itemize} + +\pnum +\ensures +\tcode{*this} references the object referenced by \tcode{ref}. +\end{itemdescr} + \indexlibrarymember{store}{atomic_ref}% -\indexlibrarymember{store}{atomic_ref}% +\indexlibrarymember{store}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{store}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{store}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} @@ -3328,13 +3585,13 @@ \pnum \effects -Atomically replaces the value referenced by \tcode{*ptr} +Atomically replaces the value referenced by \tcode{*\exposid{ptr}} with the value of \tcode{desired}. Memory is affected according to the value of \tcode{order}. \end{itemdescr} \indexlibrarymember{operator=}{atomic_ref}% -\indexlibrarymember{operator=}{atomic_ref}% +\indexlibrarymember{operator=}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{operator=}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{operator=}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} @@ -3356,7 +3613,7 @@ \end{itemdescr} \indexlibrarymember{load}{atomic_ref}% -\indexlibrarymember{load}{atomic_ref}% +\indexlibrarymember{load}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{load}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{load}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} @@ -3368,8 +3625,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 @@ -3378,11 +3634,11 @@ \pnum \returns -Atomically returns the value referenced by \tcode{*ptr}. +Atomically returns the value referenced by \tcode{*\exposid{ptr}}. \end{itemdescr} \indexlibrarymember{operator \placeholder{type}}{atomic_ref}% -\indexlibrarymember{operator T*}{atomic_ref}% +\indexlibrarymember{operator \placeholder{pointer-type}}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{operator \placeholder{integral-type}}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{operator \placeholder{floating-point-type}}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} @@ -3396,7 +3652,7 @@ \end{itemdescr} \indexlibrarymember{exchange}{atomic_ref}% -\indexlibrarymember{exchange}{atomic_ref}% +\indexlibrarymember{exchange}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{exchange}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{exchange}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} @@ -3411,37 +3667,37 @@ \pnum \effects -Atomically replaces the value referenced by \tcode{*ptr} +Atomically replaces the value referenced by \tcode{*\exposid{ptr}} with \tcode{desired}. Memory is affected according to the value of \tcode{order}. This operation is an atomic read-modify-write operation\iref{intro.multithread}. \pnum \returns -Atomically returns the value referenced by \tcode{*ptr} +Atomically returns the value referenced by \tcode{*\exposid{ptr}} immediately before the effects. \end{itemdescr} \indexlibrarymember{compare_exchange_weak}{atomic_ref}% -\indexlibrarymember{compare_exchange_weak}{atomic_ref}% +\indexlibrarymember{compare_exchange_weak}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{compare_exchange_weak}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{compare_exchange_weak}{atomic_ref<\placeholder{floating-point-type}>}% \indexlibrarymember{compare_exchange_strong}{atomic_ref}% -\indexlibrarymember{compare_exchange_strong}{atomic_ref}% +\indexlibrarymember{compare_exchange_strong}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{compare_exchange_strong}{atomic_ref<\placeholder{integral-type}>}% \indexlibrarymember{compare_exchange_strong}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} constexpr bool compare_exchange_weak(value_type& expected, value_type desired, - memory_order success, memory_order failure) const noexcept; + memory_order success, memory_order failure) const noexcept; constexpr bool compare_exchange_strong(value_type& expected, value_type desired, - memory_order success, memory_order failure) const noexcept; + memory_order success, memory_order failure) const noexcept; constexpr bool compare_exchange_weak(value_type& expected, value_type desired, - memory_order order = memory_order::seq_cst) const noexcept; + memory_order order = memory_order::seq_cst) const noexcept; constexpr bool compare_exchange_strong(value_type& expected, value_type desired, - memory_order order = memory_order::seq_cst) const noexcept; + memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3453,17 +3709,16 @@ \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 Retrieves the value in \tcode{expected}. It then atomically compares the value representation of -the value referenced by \tcode{*ptr} for equality +the value referenced by \tcode{*\exposid{ptr}} for equality with that previously retrieved from \tcode{expected}, -and if \tcode{true}, replaces the value referenced by \tcode{*ptr} +and if \tcode{true}, replaces the value referenced by \tcode{*\exposid{ptr}} with that in \tcode{desired}. If and only if the comparison is \tcode{true}, memory is affected according to the value of \tcode{success}, and @@ -3479,11 +3734,11 @@ If and only if the comparison is \tcode{false} then, after the atomic operation, the value in \tcode{expected} is replaced by -the value read from the value referenced by \tcode{*ptr} +the value read from the value referenced by \tcode{*\exposid{ptr}} during the atomic comparison. If the operation returns \tcode{true}, these operations are atomic read-modify-write operations\iref{intro.races} -on the value referenced by \tcode{*ptr}. +on the value referenced by \tcode{*\exposid{ptr}}. Otherwise, these operations are atomic load operations on that memory. \pnum @@ -3493,11 +3748,11 @@ \pnum \remarks A weak compare-and-exchange operation may fail spuriously. -That is, even when the contents of memory referred to -by \tcode{expected} and \tcode{ptr} are equal, +That is, even when the value representations referred to +by \tcode{expected} and \exposid{ptr} compare equal, it may return \tcode{false} and -store back to \tcode{expected} the same memory contents -that were originally there. +store back to \tcode{expected} +the same value representation that was originally there. \begin{note} This spurious failure enables implementation of compare-and-exchange on a broader class of machines, e.g., load-locked store-conditional machines. @@ -3520,8 +3775,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 @@ -3541,7 +3795,7 @@ \pnum \remarks This function is an atomic waiting operation\iref{atomics.wait} -on atomic object \tcode{*ptr}. +on atomic object \tcode{*\exposid{ptr}}. \end{itemdescr} \indexlibrarymember{notify_one}{atomic_ref}% @@ -3556,14 +3810,14 @@ \pnum \effects -Unblocks the execution of at least one atomic waiting operation on \tcode{*ptr} +Unblocks the execution of at least one atomic waiting operation on \tcode{*\exposid{ptr}} that is eligible to be unblocked\iref{atomics.wait} by this call, if any such atomic waiting operations exist. \pnum \remarks This function is an atomic notifying operation\iref{atomics.wait} -on atomic object \tcode{*ptr}. +on atomic object \tcode{*\exposid{ptr}}. \end{itemdescr} \indexlibrarymember{notify_all}{atomic_ref}% @@ -3578,24 +3832,24 @@ \pnum \effects -Unblocks the execution of all atomic waiting operations on \tcode{*ptr} +Unblocks the execution of all atomic waiting operations on \tcode{*\exposid{ptr}} that are eligible to be unblocked\iref{atomics.wait} by this call. \pnum \remarks This function is an atomic notifying operation\iref{atomics.wait} -on atomic object \tcode{*ptr}. +on atomic object \tcode{*\exposid{ptr}}. \end{itemdescr} \indexlibrarymember{address}{atomic_ref}% \begin{itemdecl} -constexpr T* address() const noexcept; +constexpr @\exposid{address-return-type}@ address() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{ptr}. +\exposid{ptr}. \end{itemdescr} \rSec3[atomics.ref.int]{Specializations for integral types} @@ -3615,24 +3869,28 @@ \pnum The program is ill-formed if \tcode{is_always_lock_free} is \tcode{false} and -\tcode{is_volatile_v} is \tcode{true}. +\tcode{is_volatile_v<\placeholder{integral-type}>} is \tcode{true}. \begin{codeblock} namespace std { template<> struct atomic_ref<@\placeholder{integral-type}@> { private: - @\placeholder{integral-type}@* ptr; // \expos + @\placeholder{integral-type}@* @\exposid{ptr}@; // \expos public: using value_type = remove_cv_t<@\placeholder{integral-type}@>; using difference_type = value_type; + using @\exposid{address-return-type}@ = @\placeholdernc{COPYCV}@(@\placeholder{integral-type}@, void)*; // \expos 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; constexpr explicit atomic_ref(@\placeholder{integral-type}@&); + explicit atomic_ref(@\placeholder{integral-type}@&&) = delete; constexpr atomic_ref(const atomic_ref&) noexcept; + template + constexpr atomic_ref(const atomic_ref&) noexcept; atomic_ref& operator=(const atomic_ref&) = delete; constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept; @@ -3666,6 +3924,21 @@ constexpr value_type fetch_min(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_add(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_sub(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_and(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_or(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_xor(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_max(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_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; @@ -3679,7 +3952,7 @@ 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; + constexpr @\exposid{address-return-type}@ address() const noexcept; }; } \end{codeblock} @@ -3712,15 +3985,15 @@ \pnum \effects -Atomically replaces the value referenced by \tcode{*ptr} with -the result of the computation applied to the value referenced by \tcode{*ptr} +Atomically replaces the value referenced by \tcode{*\exposid{ptr}} with +the result of the computation applied to the value referenced by \tcode{*\exposid{ptr}} and the given operand. Memory is affected according to the value of \tcode{order}. These operations are atomic read-modify-write operations\iref{intro.races}. \pnum \returns -Atomically, the value referenced by \tcode{*ptr} +Atomically, the value referenced by \tcode{*\exposid{ptr}} immediately before the effects. \pnum @@ -3737,9 +4010,56 @@ \pnum For \tcode{fetch_max} and \tcode{fetch_min}, the maximum and minimum -computation is performed as if by \tcode{max} and \tcode{min} algorithms -\iref{alg.min.max}, respectively, with the object value and the first -parameter as the arguments. +computation is performed as if by \tcode{max} and \tcode{min} +algorithms\iref{alg.min.max}, respectively, +with the object value and the first parameter as the arguments. +\end{itemdescr} + +\indexlibrarymember{store_add}{atomic_ref<\placeholder{integral-type}>}% +\indexlibrarymember{store_and}{atomic_ref<\placeholder{integral-type}>}% +\indexlibrarymember{store_max}{atomic_ref<\placeholder{integral-type}>}% +\indexlibrarymember{store_min}{atomic_ref<\placeholder{integral-type}>}% +\indexlibrarymember{store_or}{atomic_ref<\placeholder{integral-type}>}% +\indexlibrarymember{store_sub}{atomic_ref<\placeholder{integral-type}>}% +\begin{itemdecl} +constexpr void store_@\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 +\expects +\tcode{order} is \tcode{memory_order::relaxed}, +\tcode{memory_order::release}, or +\tcode{memory_order::seq_cst}. + +\pnum +\effects +Atomically replaces the value referenced by \tcode{*\exposid{ptr}} +with the result of the computation applied to +the value referenced by \tcode{*\exposid{ptr}} and the given \tcode{operand}. +Memory is affected according to the value of \tcode{order}. +These operations are atomic modify-write operations\iref{atomics.order}. + +\pnum +\remarks +Except for \tcode{store_max} and \tcode{store_min}, +for signed integer types, +the result is as if \tcode{*\exposid{ptr}} and parameters +were converted to their corresponding unsigned types, +the computation performed on those types, and +the result converted back to the signed type. +\begin{note} +There are no undefined results arising from the computation. +\end{note} +For \tcode{store_max} and \tcode{store_min}, +the maximum and minimum computation is performed +as if by \tcode{max} and \tcode{min} algorithms\iref{alg.min.max}, respectively, +with \tcode{*\exposid{ptr}} and the first parameter as the arguments. \end{itemdescr} \indexlibrarymember{operator+=}{atomic_ref<\placeholder{integral-type}>}% @@ -3769,62 +4089,92 @@ There are specializations of the \tcode{atomic_ref} class template for all floating-point types. For each such type \tcode{\placeholder{floating-point-type}}, -the specialization \tcode{atomic_ref<\placeholder{floating-\-point}>} provides +the specialization \tcode{atomic_ref<\placeholder{floating-\-point-type}>} 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}. +\tcode{is_volatile_v<\placeholder{floating-point-type}>} is \tcode{true}. \begin{codeblock} namespace std { template<> struct atomic_ref<@\placeholder{floating-point-type}@> { private: - @\placeholder{floating-point-type}@* ptr; // \expos + @\placeholder{floating-point-type}@* @\exposid{ptr}@; // \expos public: using value_type = remove_cv_t<@\placeholder{floating-point-type}@>; using difference_type = value_type; + using @\exposid{address-return-type}@ = @\placeholdernc{COPYCV}@(@\placeholder{floating-point-type}@, void)*; // \expos 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; constexpr explicit atomic_ref(@\placeholder{floating-point-type}@&); + explicit atomic_ref(@\placeholder{floating-point-type}@&&) = delete; constexpr atomic_ref(const atomic_ref&) noexcept; + template + constexpr atomic_ref(const atomic_ref&) noexcept; atomic_ref& operator=(const atomic_ref&) = delete; - constexpr void store(@\placeholdernc{floating-point-type}@, + 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 @\placeholdernc{floating-point-type}@() const noexcept; - - constexpr value_type exchange(@\placeholdernc{floating-point-type}@, - memory_order = memory_order::seq_cst) const noexcept; - constexpr bool compare_exchange_weak(value_type&, @\placeholdernc{floating-point-type}@, - memory_order, memory_order) const noexcept; - constexpr bool compare_exchange_strong(value_type&, @\placeholdernc{floating-point-type}@, - memory_order, memory_order) const noexcept; - constexpr bool compare_exchange_weak(value_type&, @\placeholdernc{floating-point-type}@, - memory_order = memory_order::seq_cst) const noexcept; - constexpr bool compare_exchange_strong(value_type&, @\placeholdernc{floating-point-type}@, - memory_order = memory_order::seq_cst) const noexcept; - - constexpr value_type fetch_add(@\placeholdernc{floating-point-type}@, + constexpr operator value_type() const noexcept; + + constexpr value_type exchange(value_type, memory_order = memory_order::seq_cst) const noexcept; - constexpr value_type fetch_sub(@\placeholdernc{floating-point-type}@, + 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_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 fetch_fmaximum(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_fminimum(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_fmaximum_num(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr value_type fetch_fminimum_num(value_type, + memory_order = memory_order::seq_cst) const noexcept; + + constexpr void store_add(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_sub(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_max(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_min(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_fmaximum(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_fminimum(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_fmaximum_num(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_fminimum_num(value_type, + memory_order = memory_order::seq_cst) const noexcept; constexpr value_type operator+=(value_type) const noexcept; constexpr value_type operator-=(value_type) const noexcept; - constexpr void wait(@\placeholdernc{floating-point-type}@, + 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{floating-point-type}@* address() const noexcept; + constexpr @\exposid{address-return-type}@ address() const noexcept; }; } \end{codeblock} @@ -3836,31 +4186,45 @@ \pnum The following operations perform arithmetic computations. The correspondence among key, operator, and computation is specified -in \tref{atomic.types.int.comp}. +in \tref{atomic.types.int.comp}, +except for the keys +\tcode{max}, +\tcode{min}, +\tcode{fmaximum}, +\tcode{fminimum}, +\tcode{fmaximum_num}, and +\tcode{fminimum_num}, +which are specified below. \indexlibrarymember{fetch_add}{atomic_ref<\placeholder{floating-point-type}>}% \indexlibrarymember{fetch_sub}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_fmaximum}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_fminimum}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_fmaximum_num}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_fminimum_num}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_max}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_min}{atomic_ref<\placeholder{floating-point-type}>}% \begin{itemdecl} constexpr value_type fetch_@\placeholdernc{key}@(value_type operand, - memory_order order = memory_order::seq_cst) const noexcept; + 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}. +\tcode{is_const_v<\placeholder{floating-point-type}>} is \tcode{false}. \pnum \effects -Atomically replaces the value referenced by \tcode{*ptr} with -the result of the computation applied to the value referenced by \tcode{*ptr} +Atomically replaces the value referenced by \tcode{*\exposid{ptr}} with +the result of the computation applied to the value referenced by \tcode{*\exposid{ptr}} and the given operand. Memory is affected according to the value of \tcode{order}. These operations are atomic read-modify-write operations\iref{intro.races}. \pnum \returns -Atomically, the value referenced by \tcode{*ptr} +Atomically, the value referenced by \tcode{*\exposid{ptr}} immediately before the effects. \pnum @@ -3872,8 +4236,129 @@ 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-\newline point-type}} +for atomic arithmetic operations on \tcode{\placeholder{floating-\brk{}point-type}} +may be different than the calling thread's floating-point environment. + +\pnum +\begin{itemize} +\item +For \tcode{fetch_fmaximum} and \tcode{fetch_fminimum}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum} and \tcode{fminimum}, respectively, +with \tcode{*\exposid{ptr}} and the first parameter as the arguments. +\item +For \tcode{fetch_fmaximum_num} and \tcode{fetch_fminimum_num}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively, +with \tcode{*\exposid{ptr}} and the first parameter as the arguments. +\item +For \tcode{fetch_max} and \tcode{fetch_min}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively, +with \tcode{*\exposid{ptr}} and the first parameter as the arguments, except that: +\begin{itemize} +\item +If both arguments are NaN, an unspecified NaN value is stored at \tcode{*\exposid{ptr}}. +\item +If exactly one argument is a NaN, +either the other argument or an unspecified NaN value is stored at \tcode{*\exposid{ptr}}; +it is unspecified which. +\item +If the arguments are differently signed zeros, +which of these values is stored at \tcode{*\exposid{ptr}} is unspecified. +\end{itemize} +\end{itemize} + +\pnum +\recommended +The implementation of \tcode{fetch_max} and \tcode{fetch_min} +should treat negative zero as smaller than positive zero. +\end{itemdescr} + +\indexlibrarymember{store_add}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_sub}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_min}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_max}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_fminimum}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_fmaximum}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_fminimum_num}{atomic_ref<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_fmaximum_num}{atomic_ref<\placeholder{floating-point-type}>}% +\begin{itemdecl} +constexpr void store_@\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{floating-point-type}>} is \tcode{false}. + +\pnum +\expects +\tcode{order} is \tcode{memory_order::relaxed}, +\tcode{memory_order::release}, or +\tcode{memory_order::seq_cst}. + +\pnum +\effects +Atomically replaces the value referenced by \tcode{*\exposid{ptr}} +with the result of the computation applied to +the value referenced by \tcode{*\exposid{ptr}} and the given \tcode{operand}. +Memory is affected according to the value of \tcode{order}. +These operations are atomic modify-write operations\iref{atomics.order}. + +\pnum +\remarks +If the result is not a representable value for its type\iref{expr.pre}, +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{numeric_limits<\placeholder{floating-point-type}>} +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}} may be different than the calling thread's floating-point environment. +The arithmetic rules of floating-point atomic modify-write operations +may be different from operations on floating-point types or +atomic floating-point types. +\begin{note} +Tree reductions are permitted for atomic modify-write operations. +\end{note} + +\pnum +\begin{itemize} +\item +For \tcode{store_fmaximum} and \tcode{store_fminimum}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum} and \tcode{fminimum}, respectively, +with \tcode{*\exposid{ptr}} and the first parameter as the arguments. +\item +For \tcode{store_fmaximum_num} and \tcode{store_fminimum_num}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum_num }and \tcode{fminimum_num}, respectively, +with \tcode{*\exposid{ptr}} and the first parameter as the arguments. +\item +For \tcode{store_max} and \tcode{store_min}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively, +with \tcode{*\exposid{ptr}} and the first parameter as the arguments, except that: +\begin{itemize} +\item +If both arguments are NaN, an unspecified NaN value is stored at \tcode{*\exposid{ptr}}. +\item +If exactly one argument is a NaN, +either the other argument or an unspecified NaN value is stored at \tcode{*\exposid{ptr}}, +it is unspecified which. +\item +If the arguments are differently signed zeros, +which of these values is stored at \tcode{*ptr} is unspecified. +\end{itemize} +\end{itemize} + +\pnum +\recommended +The implementation of \tcode{store_max} and \tcode{store_min} +should treat negative zero as smaller than positive zero. \end{itemdescr} \indexlibrarymember{operator+=}{atomic_ref<\placeholder{floating-point-type}>}% @@ -3885,7 +4370,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{is_const_v<\exposid{floating-point-type}>} is \tcode{false}. +\tcode{is_const_v<\placeholder{floating-point-type}>} is \tcode{false}. \pnum \effects @@ -3893,37 +4378,49 @@ \tcode{return fetch_\placeholder{key}(operand) \placeholdernc{op} operand;} \end{itemdescr} -\rSec3[atomics.ref.pointer]{Partial specialization for pointers} -\indexlibraryglobal{atomic_ref}% +\rSec3[atomics.ref.pointer]{Specialization for pointers} +\indexlibraryglobal{atomic_ref<\placeholder{pointer-type}>}% \pnum There are specializations of the \tcode{atomic_ref} class template for all pointer-to-object types. -For each such type \placeholder{pointer-type}, +For each such type \tcode{\placeholder{pointer-type}}, the specialization \tcode{atomic_ref<\placeholder{pointer-type}>} provides additional atomic operations appropriate to pointer types. +\pnum +Except during constant evaluation, +when an operation on an atomic pointer +would otherwise result in a pointer value \tcode{p} +that is not valid in the context of the evaluation\iref{basic.compound}, +that result instead is +\tcode{reinterpret_cast(reinterpret_cast(p))}. + \pnum The program is ill-formed if \tcode{is_always_lock_free} is \tcode{false} and -\tcode{is_volatile_v} is \tcode{true}. +\tcode{is_volatile_v<\placeholder{pointer-type}>} is \tcode{true}. \begin{codeblock} namespace std { - template struct atomic_ref<@\placeholder{pointer-type}@> { + template<> struct atomic_ref<@\placeholder{pointer-type}@> { private: - @\placeholder{pointer-type}@* ptr; // \expos + @\placeholder{pointer-type}@* @\exposid{ptr}@; // \expos public: using value_type = remove_cv_t<@\placeholder{pointer-type}@>; using difference_type = ptrdiff_t; + using @\exposid{address-return-type}@ = @\placeholdernc{COPYCV}@(@\placeholder{pointer-type}@, void)*; // \expos 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; constexpr explicit atomic_ref(@\placeholder{pointer-type}@&); + explicit atomic_ref(@\placeholder{pointer-type}@&&) = delete; constexpr atomic_ref(const atomic_ref&) noexcept; + template + constexpr atomic_ref(const atomic_ref&) noexcept; atomic_ref& operator=(const atomic_ref&) = delete; constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept; @@ -3951,6 +4448,15 @@ constexpr value_type fetch_min(value_type, memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_add(difference_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_sub(difference_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_max(value_type, + memory_order = memory_order::seq_cst) const noexcept; + constexpr void store_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; @@ -3961,7 +4467,7 @@ 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; + constexpr @\placeholder{address-return-type}@ address() const noexcept; }; } \end{codeblock} @@ -3975,13 +4481,13 @@ The correspondence among key, operator, and computation is specified in \tref{atomic.types.pointer.comp}. -\indexlibrarymember{fetch_add}{atomic_ref}% -\indexlibrarymember{fetch_sub}{atomic_ref}% -\indexlibrarymember{fetch_max}{atomic_ref}% -\indexlibrarymember{fetch_min}{atomic_ref}% +\indexlibrarymember{fetch_add}{atomic_ref<\placeholder{pointer-type}>}% +\indexlibrarymember{fetch_sub}{atomic_ref<\placeholder{pointer-type}>}% +\indexlibrarymember{fetch_max}{atomic_ref<\placeholder{pointer-type}>}% +\indexlibrarymember{fetch_min}{atomic_ref<\placeholder{pointer-type}>}% \begin{itemdecl} -constexpr value_type fetch_@\placeholdernc{key}@(difference_type operand, - memory_order order = memory_order::seq_cst) const noexcept; +constexpr value_type fetch_@\placeholdernc{key}@(@\seeabovenc@ operand, + memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -3995,15 +4501,15 @@ \pnum \effects -Atomically replaces the value referenced by \tcode{*ptr} with -the result of the computation applied to the value referenced by \tcode{*ptr} +Atomically replaces the value referenced by \tcode{*\exposid{ptr}} with +the result of the computation applied to the value referenced by \tcode{*\exposid{ptr}} and the given operand. Memory is affected according to the value of \tcode{order}. These operations are atomic read-modify-write operations\iref{intro.races}. \pnum \returns -Atomically, the value referenced by \tcode{*ptr} +Atomically, the value referenced by \tcode{*\exposid{ptr}} immediately before the effects. \pnum @@ -4024,8 +4530,55 @@ \end{note} \end{itemdescr} -\indexlibrarymember{operator+=}{atomic_ref}% -\indexlibrarymember{operator-=}{atomic_ref}% +\indexlibrarymember{store_add}{atomic_ref<\placeholder{pointer-type}>}% +\indexlibrarymember{store_sub}{atomic_ref<\placeholder{pointer-type}>}% +\indexlibrarymember{store_max}{atomic_ref<\placeholder{pointer-type}>}% +\indexlibrarymember{store_min}{atomic_ref<\placeholder{pointer-type}>}% +\begin{itemdecl} +constexpr void store_@\placeholdernc{key}@(@\seeabovenc@ 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{remove_pointer_t<\placeholder{pointer-type}>} is a complete object type. + +\pnum +\expects +\tcode{order} is \tcode{memory_order::relaxed}, +\tcode{memory_order::release}, or +\tcode{memory_order::seq_cst}. + +\pnum +\effects +Atomically replaces the value referenced by \tcode{*\exposid{ptr}} +with the result of the computation applied to +the value referenced by \tcode{*\exposid{ptr}} and the given \tcode{operand}. +Memory is affected according to the value of \tcode{order}. +These operations are atomic modify-write operations\iref{atomics.order}. + +\pnum +\remarks +The result may be an undefined address, +but the operations otherwise have no undefined behavior. +For \tcode{store_max} and \tcode{store_min}, +the \tcode{maximum} and \tcode{minimum} computation is performed +as if by \tcode{max} and \tcode{min} algorithms\iref{alg.min.max}, respectively, +with \tcode{*\exposid{ptr}} and the first parameter as the arguments. +\begin{note} +If the pointers point to different complete objects (or subobjects thereof), +the \tcode{<} operator does not establish +a strict weak ordering~(\tref{cpp17.lessthancomparable}, \ref{expr.rel}). +\end{note} +\end{itemdescr} + +\indexlibrarymember{operator+=}{atomic_ref<\placeholder{pointer-type}>}% +\indexlibrarymember{operator-=}{atomic_ref<\placeholder{pointer-type}>}% \begin{itemdecl} constexpr value_type operator @\placeholder{op}@=(difference_type operand) const noexcept; \end{itemdecl} @@ -4045,14 +4598,14 @@ common to integers and pointers to objects} \pnum -Let \placeholder{referred-type} -be \placeholder{pointer-type} +Let \tcode{\placeholder{referred-type}} +be \tcode{\placeholder{pointer-type}} for the specializations in \ref{atomics.ref.pointer} and -be \placeholder{integral-type} +be \tcode{\placeholder{integral-type}} for the specializations in \ref{atomics.ref.int}. -\indexlibrarymember{operator++}{atomic_ref}% +\indexlibrarymember{operator++}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{operator++}{atomic_ref<\placeholder{integral-type}>}% \begin{itemdecl} constexpr value_type operator++(int) const noexcept; @@ -4068,7 +4621,7 @@ Equivalent to: \tcode{return fetch_add(1);} \end{itemdescr} -\indexlibrarymember{operator--}{atomic_ref}% +\indexlibrarymember{operator--}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{operator--}{atomic_ref<\placeholder{integral-type}>}% \begin{itemdecl} constexpr value_type operator--(int) const noexcept; @@ -4084,7 +4637,7 @@ Equivalent to: \tcode{return fetch_sub(1);} \end{itemdescr} -\indexlibrarymember{operator++}{atomic_ref}% +\indexlibrarymember{operator++}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{operator++}{atomic_ref<\placeholder{integral-type}>}% \begin{itemdecl} constexpr value_type operator++() const noexcept; @@ -4100,7 +4653,7 @@ Equivalent to: \tcode{return fetch_add(1) + 1;} \end{itemdescr} -\indexlibrarymember{operator--}{atomic_ref}% +\indexlibrarymember{operator--}{atomic_ref<\placeholder{pointer-type}>}% \indexlibrarymember{operator--}{atomic_ref<\placeholder{integral-type}>}% \begin{itemdecl} constexpr value_type operator--() const noexcept; @@ -4179,7 +4732,7 @@ \item \tcode{is_move_constructible_v}, \item \tcode{is_copy_assignable_v}, \item \tcode{is_move_assignable_v}, or -\item \tcode{same_as>}, +\item \tcode{is_same_v>}, \end{itemize} is \tcode{false}. \begin{note} @@ -4360,8 +4913,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 @@ -4439,19 +4991,19 @@ bool compare_exchange_weak(T& expected, T desired, memory_order success, memory_order failure) volatile noexcept; constexpr bool compare_exchange_weak(T& expected, T desired, - memory_order success, memory_order failure) noexcept; + memory_order success, memory_order failure) noexcept; bool compare_exchange_strong(T& expected, T desired, memory_order success, memory_order failure) volatile noexcept; constexpr bool compare_exchange_strong(T& expected, T desired, - memory_order success, memory_order failure) noexcept; + memory_order success, memory_order failure) noexcept; bool compare_exchange_weak(T& expected, T desired, memory_order order = memory_order::seq_cst) volatile noexcept; constexpr bool compare_exchange_weak(T& expected, T desired, - memory_order order = memory_order::seq_cst) noexcept; + 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; constexpr bool compare_exchange_strong(T& expected, T desired, - memory_order order = memory_order::seq_cst) noexcept; + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4464,9 +5016,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 @@ -4488,7 +5039,7 @@ pointed to by \keyword{this} during the atomic comparison. If the operation returns \tcode{true}, these operations are atomic read-modify-write -operations\iref{intro.multithread} on the memory +operations\iref{intro.races} on the memory pointed to by \keyword{this}. Otherwise, these operations are atomic load operations on that memory. @@ -4532,6 +5083,7 @@ \end{example} \pnum +\recommended Implementations should ensure that weak compare-and-exchange operations do not consistently return \tcode{false} unless either the atomic object has value different from \tcode{expected} or there are concurrent modifications to the @@ -4540,9 +5092,11 @@ \pnum \remarks A weak compare-and-exchange operation may fail spuriously. That is, even when -the contents of memory referred to by \tcode{expected} and \keyword{this} are -equal, it may return \tcode{false} and store back to \tcode{expected} the same memory -contents that were originally there. +the value representations referred to by \tcode{expected} and \keyword{this} +compare equal, +it may return \tcode{false} and +store back to \tcode{expected} +the same value representation that was originally there. \begin{note} This spurious failure enables implementation of compare-and-exchange on a broader class of @@ -4615,12 +5169,16 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +For the \tcode{volatile} overload of this function, +\tcode{is_always_lock_free} is \tcode{true}. + \pnum \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 @@ -4652,6 +5210,11 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +For the \tcode{volatile} overload of this function, +\tcode{is_always_lock_free} is \tcode{true}. + \pnum \effects Unblocks the execution of at least one atomic waiting operation @@ -4672,7 +5235,12 @@ constexpr void notify_all() noexcept; \end{itemdecl} -\begin{itemdescr} +\begin{itemdescr} +\pnum +\constraints +For the \tcode{volatile} overload of this function, +\tcode{is_always_lock_free} is \tcode{true}. + \pnum \effects Unblocks the execution of all atomic waiting operations @@ -4688,23 +5256,10 @@ \indexlibrary{\idxcode{atomic<\placeholder{integral-type}>}}% \pnum There are specializations of the \tcode{atomic} -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}. +class template for +each character type\iref{basic.fundamental}, +each standard integer type, and +any other types needed by the typedefs in the header \libheaderref{cstdint}. For each such type \tcode{\placeholder{integral-type}}, the specialization \tcode{atomic<\placeholder{integral-type}>} provides additional atomic operations appropriate to integral types. \begin{note} @@ -4740,52 +5295,81 @@ @\placeholdernc{integral-type}@ exchange(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; constexpr @\placeholdernc{integral-type}@ exchange(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) noexcept; + memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, memory_order, memory_order) volatile noexcept; constexpr bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, - memory_order, memory_order) noexcept; + memory_order, memory_order) noexcept; bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, memory_order, memory_order) volatile noexcept; constexpr bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, - memory_order, memory_order) noexcept; + memory_order, memory_order) noexcept; bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; constexpr bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) noexcept; + 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; constexpr bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) noexcept; + memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_add(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; constexpr @\placeholdernc{integral-type}@ fetch_add(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) noexcept; + memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_sub(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; constexpr @\placeholdernc{integral-type}@ fetch_sub(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) noexcept; + memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_and(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; constexpr @\placeholdernc{integral-type}@ fetch_and(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) noexcept; + memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_or(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) volatile noexcept; + memory_order = memory_order::seq_cst) volatile noexcept; constexpr @\placeholdernc{integral-type}@ fetch_or(@\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) noexcept; + memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ fetch_xor(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; 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) noexcept; + @\placeholdernc{integral-type}@ fetch_max(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept; - constexpr @\placeholdernc{integral-type}@ fetch_max( @\placeholdernc{integral-type}@, - memory_order = memory_order::seq_cst) noexcept; - @\placeholdernc{integral-type}@ fetch_min( @\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; - constexpr @\placeholdernc{integral-type}@ fetch_min( @\placeholdernc{integral-type}@, + constexpr @\placeholdernc{integral-type}@ fetch_min(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) noexcept; + + void store_add(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_add(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) noexcept; + void store_sub(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_sub(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) noexcept; + void store_and(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_and(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) noexcept; + void store_or(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_or(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept; + void store_xor(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_xor(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) noexcept; + void store_max(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_max(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) noexcept; + void store_min(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_min(@\placeholdernc{integral-type}@, + memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{integral-type}@ operator++(int) volatile noexcept; constexpr @\placeholdernc{integral-type}@ operator++(int) noexcept; @@ -4884,8 +5468,10 @@ \indexlibrarymember{fetch_sub}{atomic<\placeholder{integral-type}>}% \indexlibrarymember{fetch_xor}{atomic<\placeholder{integral-type}>}% \begin{itemdecl} -T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) volatile noexcept; -constexpr T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) noexcept; +@\placeholder{integral-type}@ fetch_@\placeholdernc{key}@(@\placeholder{integral-type}@ operand, + memory_order order = memory_order::seq_cst) volatile noexcept; +constexpr @\placeholder{integral-type}@ fetch_@\placeholdernc{key}@(@\placeholder{integral-type}@ operand, + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4920,9 +5506,72 @@ \pnum For \tcode{fetch_max} and \tcode{fetch_min}, the maximum and minimum -computation is performed as if by \tcode{max} and \tcode{min} algorithms -\iref{alg.min.max}, respectively, with the object value and the first parameter -as the arguments. +computation is performed as if by \tcode{max} and \tcode{min} +algorithms\iref{alg.min.max}, respectively, +with the object value and the first parameter as the arguments. +\end{itemdescr} + +\indexlibraryglobal{atomic_store_add}% +\indexlibraryglobal{atomic_store_and}% +\indexlibraryglobal{atomic_store_max}% +\indexlibraryglobal{atomic_store_min}% +\indexlibraryglobal{atomic_store_or}% +\indexlibraryglobal{atomic_store_sub}% +\indexlibraryglobal{atomic_store_add_explicit}% +\indexlibraryglobal{atomic_store_and_explicit}% +\indexlibraryglobal{atomic_store_max_explicit}% +\indexlibraryglobal{atomic_store_min_explicit}% +\indexlibraryglobal{atomic_store_or_explicit}% +\indexlibraryglobal{atomic_store_sub_explicit}% +\indexlibrarymember{store_add}{atomic<\placeholder{integral-type}>}% +\indexlibrarymember{store_and}{atomic<\placeholder{integral-type}>}% +\indexlibrarymember{store_max}{atomic<\placeholder{integral-type}>}% +\indexlibrarymember{store_min}{atomic<\placeholder{integral-type}>}% +\indexlibrarymember{store_or}{atomic<\placeholder{integral-type}>}% +\indexlibrarymember{store_sub}{atomic<\placeholder{integral-type}>}% +\begin{itemdecl} +void store_@\placeholdernc{key}@(@\placeholder{integral-type}@ operand, + memory_order order = memory_order::seq_cst) volatile noexcept; +constexpr void store_@\placeholdernc{key}@(@\placeholder{integral-type}@ operand, + memory_order order = memory_order::seq_cst) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +For the \tcode{volatile} overload of this function, +\tcode{is_always_lock_free} is \tcode{true}. + +\pnum +\expects +\tcode{order} is +\tcode{memory_order::relaxed}, +\tcode{memory_order::release}, or +\tcode{memory_order::seq_cst}. + +\pnum +\effects +Atomically replaces the value pointed to by \tcode{this} +with the result of the computation applied to +the value pointed to by \tcode{this} and the given \tcode{operand}. +Memory is affected according to the value of \tcode{order}. +These operations are atomic modify-write operations\iref{atomics.order}. + +\pnum +\remarks +Except for \tcode{store_max} and \tcode{store_min}, +for signed integer types, the result is as if +the value pointed to by \tcode{this} and parameters +were converted to their corresponding unsigned types, +the computation performed on those types, and +the result converted back to the signed type. +\begin{note} +There are no undefined results arising from the computation. +\end{note} +For \tcode{store_max} and \tcode{store_min}, +the maximum and minimum computation is performed +as if by \tcode{max} and \tcode{min} algorithms\iref{alg.min.max}, respectively, +with the value pointed to by \tcode{this} and the first parameter as the arguments. \end{itemdescr} \indexlibrarymember{operator+=}{atomic}% @@ -4933,8 +5582,8 @@ \indexlibrarymember{operator"|=}{atomic<\placeholder{integral-type}>}% \indexlibrarymember{operator\caret=}{atomic<\placeholder{integral-type}>}% \begin{itemdecl} -T operator @\placeholder{op}@=(T operand) volatile noexcept; -constexpr T operator @\placeholder{op}@=(T operand) noexcept; +@\placeholder{integral-type}@ operator @\placeholder{op}@=(@\placeholder{integral-type}@ operand) volatile noexcept; +constexpr @\placeholder{integral-type}@ operator @\placeholder{op}@=(@\placeholder{integral-type}@ operand) noexcept; \end{itemdecl} \begin{itemdescr} @@ -4986,32 +5635,89 @@ @\placeholdernc{floating-point-type}@ exchange(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept; constexpr @\placeholdernc{floating-point-type}@ exchange(@\placeholdernc{floating-point-type}@, - memory_order = memory_order::seq_cst) noexcept; + 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; constexpr bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, - memory_order, memory_order) noexcept; + memory_order, memory_order) noexcept; bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, memory_order, memory_order) volatile noexcept; constexpr bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, - memory_order, memory_order) noexcept; + 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; constexpr bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, - memory_order = memory_order::seq_cst) noexcept; + 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; constexpr bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@, - memory_order = memory_order::seq_cst) noexcept; + 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; constexpr @\placeholdernc{floating-point-type}@ fetch_add(@\placeholdernc{floating-point-type}@, - memory_order = memory_order::seq_cst) noexcept; + 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; constexpr @\placeholdernc{floating-point-type}@ fetch_sub(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{floating-point-type}@ fetch_max(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr @\placeholdernc{floating-point-type}@ fetch_max(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{floating-point-type}@ fetch_min(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr @\placeholdernc{floating-point-type}@ fetch_min(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{floating-point-type}@ fetch_fmaximum(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr @\placeholdernc{floating-point-type}@ fetch_fmaximum(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{floating-point-type}@ fetch_fminimum(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr @\placeholdernc{floating-point-type}@ fetch_fminimum(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{floating-point-type}@ fetch_fmaximum_num( + @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept; + constexpr @\placeholdernc{floating-point-type}@ fetch_fmaximum_num( + @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept; + @\placeholdernc{floating-point-type}@ fetch_fminimum_num( + @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept; + constexpr @\placeholdernc{floating-point-type}@ fetch_fminimum_num( + @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept; + + void store_add(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_add(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; + void store_sub(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_sub(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; + void store_max(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_max(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; + void store_min(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_min(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; + void store_fmaximum(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_fmaximum(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept; + void store_fminimum(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_fminimum(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; + void store_fmaximum_num(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_fmaximum_num(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; + void store_fminimum_num(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_fminimum_num(@\placeholdernc{floating-point-type}@, + memory_order = memory_order::seq_cst) noexcept; @\placeholdernc{floating-point-type}@ operator+=(@\placeholder{floating-point-type}@) volatile noexcept; constexpr @\placeholdernc{floating-point-type}@ operator+=(@\placeholder{floating-point-type}@) noexcept; @@ -5041,7 +5747,15 @@ \pnum The following operations perform arithmetic addition and subtraction computations. The correspondence among key, operator, and computation is specified -in \tref{atomic.types.int.comp}. +in \tref{atomic.types.int.comp}, +except for the keys +\tcode{max}, +\tcode{min}, +\tcode{fmaximum}, +\tcode{fminimum}, +\tcode{fmaximum_num}, and +\tcode{fminimum_num}, +which are specified below. \indexlibraryglobal{atomic_fetch_add}% \indexlibraryglobal{atomic_fetch_sub}% @@ -5049,9 +5763,17 @@ \indexlibraryglobal{atomic_fetch_sub_explicit}% \indexlibrarymember{fetch_add}{atomic<\placeholder{floating-point-type}>}% \indexlibrarymember{fetch_sub}{atomic<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_fmaximum}{atomic<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_fminimum}{atomic<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_fmaximum_num}{atomic<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_fminimum_num}{atomic<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_max}{atomic<\placeholder{floating-point-type}>}% +\indexlibrarymember{fetch_min}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} -T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) volatile noexcept; -constexpr T fetch_@\placeholdernc{key}@(T operand, memory_order order = memory_order::seq_cst) noexcept; +@\placeholdernc{floating-point-type}@ fetch_@\placeholdernc{key}@(@\placeholder{floating-point-type}@ operand, + memory_order order = memory_order::seq_cst) volatile noexcept; +constexpr @\placeholdernc{floating-point-type}@ fetch_@\placeholdernc{key}@(@\placeholder{floating-point-type}@ operand, + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5082,6 +5804,138 @@ The floating-point environment\iref{cfenv} for atomic arithmetic operations on \tcode{\placeholder{floating-point-type}} may be different than the calling thread's floating-point environment. + +\pnum +\begin{itemize} +\item +For \tcode{fetch_fmaximum} and \tcode{fetch_fminimum}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum} and \tcode{fminimum}, respectively, +with the value pointed to by \tcode{this} and the first parameter +as the arguments. +\item +For \tcode{fetch_fmaximum_num} and \tcode{fetch_fminimum_num}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively, +with the value pointed to by \tcode{this} and the first parameter +as the arguments. +\item +For \tcode{fetch_max} and \tcode{fetch_min}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively, +with the value pointed to by \tcode{this} and the first parameter +as the arguments, except that: +\begin{itemize} +\item +If both arguments are NaN, +an unspecified NaN value replaces the value pointed to by \tcode{this}. +\item +If exactly one argument is a NaN, +either the other argument or an unspecified NaN value +replaces the value pointed to by \tcode{this}; it is unspecified which. +\item +If the arguments are differently signed zeros, +which of these values replaces the value pointed to by this is unspecified. +\end{itemize} +\end{itemize} + +\pnum +\recommended +The implementation of \tcode{fetch_max} and \tcode{fetch_min} +should treat negative zero as smaller than positive zero. +\end{itemdescr} + +\indexlibrarymember{store_max}{atomic<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_min}{atomic<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_fmaximum}{atomic<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_fminimum}{atomic<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_fmaximum_num}{atomic<\placeholder{floating-point-type}>}% +\indexlibrarymember{store_fminimum_num}{atomic<\placeholder{floating-point-type}>}% +\begin{itemdecl} +void store_@\placeholdernc{key}@(@\placeholdernc{floating-point-type}@ operand, + memory_order order = memory_order::seq_cst) volatile noexcept; +constexpr void store_@\placeholdernc{key}@(@\placeholdernc{floating-point-type}@ operand, + memory_order order = memory_order::seq_cst) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +For the \tcode{volatile} overload of this function, +\tcode{is_always_lock_free} is \tcode{true}. + +\pnum +\expects +\tcode{order} is +\tcode{memory_order::relaxed}, +\tcode{memory_order::release}, or +\tcode{memory_order::seq_cst}. + +\pnum +\effects +Atomically replaces the value pointed to by \tcode{this} +with the result of the computation applied to +the value pointed to by \tcode{this} and the given operand. +Memory is affected according to the value of \tcode{order}. +These operations are atomic modify-write operations\iref{atomics.order}. + +\pnum +\remarks +If the result is not a representable value for its type\iref{expr.pre} +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{numeric_limits<\placeholder{floating-point-type}>} +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}} +may be different than the calling thread's floating-point environment. +The arithmetic rules of floating-point atomic modify-write operations +may be different from operations on +floating-point types or atomic floating-point types. +\begin{note} +Tree reductions are permitted for atomic modify-write operations. +\end{note} + +\pnum +\begin{itemize} +\item +For \tcode{store_fmaximum} and \tcode{store_fminimum}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum} and \tcode{fminimum}, respectively, +with the value pointed to by \tcode{this} and +the first parameter as the arguments. +\item +For \tcode{store_fmaximum_num} and \tcode{store_fminimum_num}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively, +with the value pointed to by \tcode{this} and +the first parameter as the arguments. +\item +For \tcode{store_max} and \tcode{store_min}, +the maximum and minimum computation is performed +as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively, +with the value pointed to by \tcode{this} and +the first parameter as the arguments, except that: +\begin{itemize} +\item +If both arguments are NaN, +an unspecified NaN value replaces the value pointed to by \tcode{this}. +\item +If exactly one argument is a NaN, +either the other argument or an unspecified NaN value replaces +the value pointed to by \tcode{this}; +it is unspecified which. +\item +If the arguments are differently signed zeros, +which of these values replaces the value pointed to by \tcode{this} is unspecified. +\end{itemize} +\end{itemize} + +\pnum +\recommended +The implementation of \tcode{store_max} and \tcode{store_min} +should treat negative zero as smaller than positive zero. \end{itemdescr} \indexlibrarymember{operator+=}{atomic}% @@ -5089,8 +5943,8 @@ \indexlibrarymember{operator+=}{atomic<\placeholder{floating-point-type}>}% \indexlibrarymember{operator-=}{atomic<\placeholder{floating-point-type}>}% \begin{itemdecl} -T operator @\placeholder{op}@=(T operand) volatile noexcept; -constexpr T operator @\placeholder{op}@=(T operand) noexcept; +@\placeholder{floating-point-type}@ operator @\placeholder{op}@=(@\placeholder{floating-point-type}@ operand) volatile noexcept; +constexpr @\placeholder{floating-point-type}@ operator @\placeholder{op}@=(@\placeholder{floating-point-type}@ operand) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5152,11 +6006,11 @@ bool compare_exchange_weak(T*&, T*, memory_order = memory_order::seq_cst) volatile noexcept; constexpr bool compare_exchange_weak(T*&, T*, - memory_order = memory_order::seq_cst) noexcept; + memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_strong(T*&, T*, memory_order = memory_order::seq_cst) volatile noexcept; constexpr bool compare_exchange_strong(T*&, T*, - memory_order = memory_order::seq_cst) noexcept; + memory_order = memory_order::seq_cst) noexcept; T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept; constexpr T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept; @@ -5167,6 +6021,15 @@ T* fetch_min(T*, memory_order = memory_order::seq_cst) volatile noexcept; constexpr T* fetch_min(T*, memory_order = memory_order::seq_cst) noexcept; + void store_add(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_add(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept; + void store_sub(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_sub(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept; + void store_max(T*, memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_max(T*, memory_order = memory_order::seq_cst) noexcept; + void store_min(T*, memory_order = memory_order::seq_cst) volatile noexcept; + constexpr void store_min(T*, memory_order = memory_order::seq_cst) noexcept; + T* operator++(int) volatile noexcept; constexpr T* operator++(int) noexcept; T* operator--(int) volatile noexcept; @@ -5196,6 +6059,14 @@ Specializations of this partial specialization are standard-layout structs. They each have a trivial destructor. +\pnum +Except during constant evaluation, +when an operation on an atomic pointer +would otherwise result in a pointer value \tcode{p} +that is not valid in the context of the evaluation\iref{basic.compound}, +that result instead is +\tcode{reinterpret_cast(reinterpret_cast(p))}. + \pnum Descriptions are provided below only for members that differ from the primary template. @@ -5240,8 +6111,8 @@ \indexlibrarymember{fetch_min}{atomic}% \indexlibrarymember{fetch_sub}{atomic}% \begin{itemdecl} -T* fetch_@\placeholdernc{key}@(ptrdiff_t operand, memory_order order = memory_order::seq_cst) volatile noexcept; -constexpr T* fetch_@\placeholdernc{key}@(ptrdiff_t operand, memory_order order = memory_order::seq_cst) noexcept; +T* fetch_@\placeholdernc{key}@(@\seeabovenc@ operand, memory_order order = memory_order::seq_cst) volatile noexcept; +constexpr T* fetch_@\placeholdernc{key}@(@\seeabovenc@ operand, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5287,6 +6158,60 @@ \end{note} \end{itemdescr} +\indexlibraryglobal{atomic_store_add}% +\indexlibraryglobal{atomic_store_max}% +\indexlibraryglobal{atomic_store_min}% +\indexlibraryglobal{atomic_store_sub}% +\indexlibraryglobal{atomic_store_add_explicit}% +\indexlibraryglobal{atomic_store_max_explicit}% +\indexlibraryglobal{atomic_store_min_explicit}% +\indexlibraryglobal{atomic_store_sub_explicit}% +\indexlibrarymember{store_add}{atomic}% +\indexlibrarymember{store_max}{atomic}% +\indexlibrarymember{store_min}{atomic}% +\indexlibrarymember{store_sub}{atomic}% +\begin{itemdecl} +void store_@\placeholdernc{key}@(@\seeabovenc@ operand, memory_order order = memory_order::seq_cst) volatile noexcept; +constexpr void store_@\placeholdernc{key}@(@\seeabovenc@ operand, memory_order order = memory_order::seq_cst) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +For the \tcode{volatile} overload of this function, +\tcode{is_always_lock_free} is \tcode{true}. + +\pnum +\mandates +\tcode{T} is a complete object type. +\begin{note} +Pointer arithmetic on \tcode{void*} or function pointers is ill-formed. +\end{note} + +\pnum +\effects +Atomically replaces the value pointed to by \tcode{this} +with the result of the computation applied to +the value pointed to by \tcode{this} and the given \tcode{operand}. +Memory is affected according to the value of \tcode{order}. +These operations are atomic modify-write operations\iref{atomics.order}. + +\pnum +\remarks +The result may be an undefined address, +but the operations otherwise have no undefined behavior. +For \tcode{store_max} and \tcode{store_min}, +the maximum and minimum computation is performed +as if by \tcode{max} and \tcode{min} algorithms\iref{alg.min.max}, respectively, +with the value pointed to by \tcode{this} and +the first parameter as the arguments. +\begin{note} +If the pointers point to different complete objects (or subobjects thereof), +the \tcode{<} operator does not establish +a strict weak ordering~(\tref{cpp17.lessthancomparable}, \ref{expr.rel}). +\end{note} +\end{itemdescr} + \indexlibrarymember{operator+=}{atomic}% \indexlibrarymember{operator-=}{atomic}% \begin{itemdecl} @@ -5454,33 +6379,35 @@ constexpr atomic() noexcept; constexpr atomic(nullptr_t) noexcept : atomic() { } - atomic(shared_ptr desired) noexcept; + constexpr atomic(shared_ptr desired) noexcept; atomic(const atomic&) = delete; void operator=(const atomic&) = delete; - shared_ptr load(memory_order order = memory_order::seq_cst) const noexcept; - operator shared_ptr() const noexcept; - void store(shared_ptr desired, memory_order order = memory_order::seq_cst) noexcept; - void operator=(shared_ptr desired) noexcept; - void operator=(nullptr_t) noexcept; - - shared_ptr exchange(shared_ptr desired, - memory_order order = memory_order::seq_cst) noexcept; - bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, - memory_order success, memory_order failure) noexcept; - bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, - memory_order success, memory_order failure) noexcept; - bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, - memory_order order = memory_order::seq_cst) noexcept; - bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, - memory_order order = memory_order::seq_cst) noexcept; - - void wait(shared_ptr old, memory_order order = memory_order::seq_cst) const noexcept; - void notify_one() noexcept; - void notify_all() noexcept; + constexpr shared_ptr load(memory_order order = memory_order::seq_cst) const noexcept; + constexpr operator shared_ptr() const noexcept; + constexpr void store(shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + constexpr void operator=(shared_ptr desired) noexcept; + constexpr void operator=(nullptr_t) noexcept; + + constexpr shared_ptr exchange(shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + constexpr bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, + memory_order success, memory_order failure) noexcept; + constexpr bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, + memory_order success, memory_order failure) noexcept; + constexpr bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + constexpr bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + + constexpr void wait(shared_ptr old, + memory_order order = memory_order::seq_cst) const noexcept; + constexpr void notify_one() noexcept; + constexpr void notify_all() noexcept; private: - shared_ptr p; // \expos + shared_ptr @\exposid{p}@; // \expos }; } \end{codeblock} @@ -5493,12 +6420,12 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{p\{\}}. +Value-initializes \exposid{p}. \end{itemdescr} \indexlibraryctor{atomic>}% \begin{itemdecl} -atomic(shared_ptr desired) noexcept; +constexpr atomic(shared_ptr desired) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5520,7 +6447,7 @@ \indexlibrarymember{store}{atomic>}% \begin{itemdecl} -void store(shared_ptr desired, memory_order order = memory_order::seq_cst) noexcept; +constexpr void store(shared_ptr desired, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5534,13 +6461,13 @@ \pnum \effects Atomically replaces the value pointed to by \keyword{this} with -the value of \tcode{desired} as if by \tcode{p.swap(desired)}. +the value of \tcode{desired} as if by \tcode{\exposid{p}.swap(desired)}. Memory is affected according to the value of \tcode{order}. \end{itemdescr} \indexlibrarymember{operator=}{atomic>}% \begin{itemdecl} -void operator=(shared_ptr desired) noexcept; +constexpr void operator=(shared_ptr desired) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5551,7 +6478,7 @@ \indexlibrarymember{operator=}{atomic>}% \begin{itemdecl} -void operator=(nullptr_t) noexcept; +constexpr void operator=(nullptr_t) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5562,7 +6489,7 @@ \indexlibrarymember{load}{atomic>}% \begin{itemdecl} -shared_ptr load(memory_order order = memory_order::seq_cst) const noexcept; +constexpr shared_ptr load(memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -5570,8 +6497,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 @@ -5580,12 +6506,12 @@ \pnum \returns -Atomically returns \tcode{p}. +Atomically returns \exposid{p}. \end{itemdescr} \indexlibrarymember{operator shared_ptr}{atomic>}% \begin{itemdecl} -operator shared_ptr() const noexcept; +constexpr operator shared_ptr() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -5596,29 +6522,30 @@ \indexlibrarymember{exchange}{atomic>}% \begin{itemdecl} -shared_ptr exchange(shared_ptr desired, memory_order order = memory_order::seq_cst) noexcept; +constexpr shared_ptr exchange(shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Atomically replaces \tcode{p} with \tcode{desired} -as if by \tcode{p.swap(desired)}. +Atomically replaces \exposid{p} with \tcode{desired} +as if by \tcode{\exposid{p}.swap(desired)}. Memory is affected according to the value of \tcode{order}. This is an atomic read-modify-write operation\iref{intro.races}. \pnum \returns -Atomically returns the value of \tcode{p} immediately before the effects. +Atomically returns the value of \exposid{p} immediately before the effects. \end{itemdescr} \indexlibrarymember{compare_exchange_weak}{atomic>}% \indexlibrarymember{compare_exchange_strong}{atomic>}% \begin{itemdecl} -bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, - memory_order success, memory_order failure) noexcept; -bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, - memory_order success, memory_order failure) noexcept; +constexpr bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, + memory_order success, memory_order failure) noexcept; +constexpr bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, + memory_order success, memory_order failure) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5626,21 +6553,20 @@ \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 -If \tcode{p} is equivalent to \tcode{expected}, -assigns \tcode{desired} to \tcode{p} and +If \exposid{p} is equivalent to \tcode{expected}, +assigns \tcode{desired} to \exposid{p} and has synchronization semantics corresponding to the value of \tcode{success}, -otherwise assigns \tcode{p} to \tcode{expected} and +otherwise assigns \exposid{p} to \tcode{expected} and has synchronization semantics corresponding to the value of \tcode{failure}. \pnum \returns -\tcode{true} if \tcode{p} was equivalent to \tcode{expected}, +\tcode{true} if \exposid{p} was equivalent to \tcode{expected}, \tcode{false} otherwise. \pnum @@ -5666,8 +6592,8 @@ \indexlibrarymember{compare_exchange_weak}{atomic>}% \begin{itemdecl} -bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, - memory_order order = memory_order::seq_cst) noexcept; +constexpr bool compare_exchange_weak(shared_ptr& expected, shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5686,8 +6612,8 @@ \indexlibrarymember{compare_exchange_strong}{atomic>}% \begin{itemdecl} -bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, - memory_order order = memory_order::seq_cst) noexcept; +constexpr bool compare_exchange_strong(shared_ptr& expected, shared_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5706,7 +6632,7 @@ \indexlibrarymember{wait}{atomic>}% \begin{itemdecl} -void wait(shared_ptr old, memory_order order = memory_order::seq_cst) const noexcept; +constexpr void wait(shared_ptr old, memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -5714,8 +6640,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 @@ -5740,7 +6665,7 @@ \indexlibrarymember{notify_one}{atomic>}% \begin{itemdecl} -void notify_one() noexcept; +constexpr void notify_one() noexcept; \end{itemdecl} \begin{itemdescr} @@ -5757,7 +6682,7 @@ \indexlibrarymember{notify_all}{atomic>}% \begin{itemdecl} -void notify_all() noexcept; +constexpr void notify_all() noexcept; \end{itemdecl} \begin{itemdescr} @@ -5783,32 +6708,34 @@ bool is_lock_free() const noexcept; constexpr atomic() noexcept; - atomic(weak_ptr desired) noexcept; + constexpr atomic(weak_ptr desired) noexcept; atomic(const atomic&) = delete; void operator=(const atomic&) = delete; - weak_ptr load(memory_order order = memory_order::seq_cst) const noexcept; - operator weak_ptr() const noexcept; - void store(weak_ptr desired, memory_order order = memory_order::seq_cst) noexcept; - void operator=(weak_ptr desired) noexcept; - - weak_ptr exchange(weak_ptr desired, + constexpr weak_ptr load(memory_order order = memory_order::seq_cst) const noexcept; + constexpr operator weak_ptr() const noexcept; + constexpr void store(weak_ptr desired, memory_order order = memory_order::seq_cst) noexcept; - bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, - memory_order success, memory_order failure) noexcept; - bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, - memory_order success, memory_order failure) noexcept; - bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, - memory_order order = memory_order::seq_cst) noexcept; - bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, - memory_order order = memory_order::seq_cst) noexcept; - - void wait(weak_ptr old, memory_order order = memory_order::seq_cst) const noexcept; - void notify_one() noexcept; - void notify_all() noexcept; + constexpr void operator=(weak_ptr desired) noexcept; + + constexpr weak_ptr exchange(weak_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + constexpr bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, + memory_order success, memory_order failure) noexcept; + constexpr bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, + memory_order success, memory_order failure) noexcept; + constexpr bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + constexpr bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; + + constexpr void wait(weak_ptr old, + memory_order order = memory_order::seq_cst) const noexcept; + constexpr void notify_one() noexcept; + constexpr void notify_all() noexcept; private: - weak_ptr p; // \expos + weak_ptr @\exposid{p}@; // \expos }; } \end{codeblock} @@ -5821,12 +6748,12 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{p\{\}}. +Value-initializes \exposid{p}. \end{itemdescr} \indexlibraryctor{atomic>}% \begin{itemdecl} -atomic(weak_ptr desired) noexcept; +constexpr atomic(weak_ptr desired) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5848,7 +6775,7 @@ \indexlibrarymember{store}{atomic>}% \begin{itemdecl} -void store(weak_ptr desired, memory_order order = memory_order::seq_cst) noexcept; +constexpr void store(weak_ptr desired, memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5862,13 +6789,13 @@ \pnum \effects Atomically replaces the value pointed to by \keyword{this} with -the value of \tcode{desired} as if by \tcode{p.swap(desired)}. +the value of \tcode{desired} as if by \tcode{\exposid{p}.swap(desired)}. Memory is affected according to the value of \tcode{order}. \end{itemdescr} \indexlibrarymember{operator=}{atomic>}% \begin{itemdecl} -void operator=(weak_ptr desired) noexcept; +constexpr void operator=(weak_ptr desired) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5879,7 +6806,7 @@ \indexlibrarymember{load}{atomic>}% \begin{itemdecl} -weak_ptr load(memory_order order = memory_order::seq_cst) const noexcept; +constexpr weak_ptr load(memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -5887,8 +6814,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 @@ -5897,12 +6823,12 @@ \pnum \returns -Atomically returns \tcode{p}. +Atomically returns \exposid{p}. \end{itemdescr} \indexlibrarymember{operator weak_ptr}{atomic>}% \begin{itemdecl} -operator weak_ptr() const noexcept; +constexpr operator weak_ptr() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -5913,28 +6839,29 @@ \indexlibrarymember{exchange}{atomic>}% \begin{itemdecl} -weak_ptr exchange(weak_ptr desired, memory_order order = memory_order::seq_cst) noexcept; +constexpr weak_ptr exchange(weak_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Atomically replaces \tcode{p} with \tcode{desired} -as if by \tcode{p.swap(desired)}. +Atomically replaces \exposid{p} with \tcode{desired} +as if by \tcode{\exposid{p}.swap(desired)}. Memory is affected according to the value of \tcode{order}. This is an atomic read-modify-write operation\iref{intro.races}. \pnum \returns -Atomically returns the value of \tcode{p} immediately before the effects. +Atomically returns the value of \exposid{p} immediately before the effects. \end{itemdescr} \indexlibrarymember{compare_exchange_weak}{atomic>}% \begin{itemdecl} -bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, - memory_order success, memory_order failure) noexcept; -bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, - memory_order success, memory_order failure) noexcept; +constexpr bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, + memory_order success, memory_order failure) noexcept; +constexpr bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, + memory_order success, memory_order failure) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5942,21 +6869,20 @@ \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 -If \tcode{p} is equivalent to \tcode{expected}, -assigns \tcode{desired} to \tcode{p} and +If \exposid{p} is equivalent to \tcode{expected}, +assigns \tcode{desired} to \exposid{p} and has synchronization semantics corresponding to the value of \tcode{success}, -otherwise assigns \tcode{p} to \tcode{expected} and +otherwise assigns \exposid{p} to \tcode{expected} and has synchronization semantics corresponding to the value of \tcode{failure}. \pnum \returns -\tcode{true} if \tcode{p} was equivalent to \tcode{expected}, +\tcode{true} if \exposid{p} was equivalent to \tcode{expected}, \tcode{false} otherwise. \pnum @@ -5982,8 +6908,8 @@ \indexlibrarymember{compare_exchange_weak}{atomic>}% \begin{itemdecl} -bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, - memory_order order = memory_order::seq_cst) noexcept; +constexpr bool compare_exchange_weak(weak_ptr& expected, weak_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -6002,8 +6928,8 @@ \indexlibrarymember{compare_exchange_strong}{atomic>}% \begin{itemdecl} -bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, - memory_order order = memory_order::seq_cst) noexcept; +constexpr bool compare_exchange_strong(weak_ptr& expected, weak_ptr desired, + memory_order order = memory_order::seq_cst) noexcept; \end{itemdecl} \begin{itemdescr} @@ -6022,7 +6948,7 @@ \indexlibrarymember{wait}{atomic>}% \begin{itemdecl} -void wait(weak_ptr old, memory_order order = memory_order::seq_cst) const noexcept; +constexpr void wait(weak_ptr old, memory_order order = memory_order::seq_cst) const noexcept; \end{itemdecl} \begin{itemdescr} @@ -6030,8 +6956,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 @@ -6057,7 +6982,7 @@ \indexlibrarymember{notify_one}{atomic>}% \begin{itemdecl} -void notify_one() noexcept; +constexpr void notify_one() noexcept; \end{itemdecl} \begin{itemdescr} @@ -6074,7 +6999,7 @@ \indexlibrarymember{notify_all}{atomic>}% \begin{itemdecl} -void notify_all() noexcept; +constexpr void notify_all() noexcept; \end{itemdecl} \begin{itemdescr} @@ -6178,8 +7103,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 @@ -6267,8 +7191,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 @@ -6326,9 +7249,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} @@ -6356,7 +7278,9 @@ \pnum A release fence $A$ synchronizes with an acquire fence $B$ if there exist -atomic operations $X$ and $Y$, both operating on some atomic object +atomic operations $X$ and $Y$, +where $Y$ is not an atomic modify-write operation\iref{atomics.order}, +both operating on some atomic object $M$, such that $A$ is sequenced before $X$, $X$ modifies $M$, $Y$ is sequenced before $B$, and $Y$ reads the value written by $X$ or a value written by any side effect in the hypothetical release @@ -6389,7 +7313,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}; @@ -6429,18 +7353,19 @@ 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_CHAR8_T_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 @@ -6524,7 +7449,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 @@ -6534,7 +7459,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}. @@ -6542,7 +7467,7 @@ \pnum Each of the \grammarterm{using-declaration}s for \tcode{int$N$_t}, \tcode{uint$N$_t}, \tcode{intptr_t}, and \tcode{uintptr_t} -listed above is defined if and only if the implementation defines +listed above is declared if and only if the implementation declares the corresponding \grammarterm{typedef-name} in \ref{atomics.syn}. \pnum @@ -6674,7 +7599,7 @@ The implementation provides lock and unlock operations, as described below. For purposes of determining the existence of a data race, these behave as atomic operations\iref{intro.multithread}. The lock and unlock operations on -a single mutex appears to occur in a single total order. +a single mutex appear to occur in a single total order. \begin{note} This can be viewed as the modification order\iref{intro.multithread} of the @@ -6921,10 +7846,10 @@ \tcode{recursive_timed_mutex}, and \tcode{shared_timed_mutex}. They meet the requirements set out below. In this description, \tcode{m} denotes an object of a mutex type, -\tcode{rel_time} denotes an object of an -instantiation of \tcode{duration}\iref{time.duration}, and \tcode{abs_time} denotes an -object of an -instantiation of \tcode{time_point}\iref{time.point}. +\tcode{rel_time} denotes an object of a +specialization of \tcode{duration}\iref{time.duration}, and \tcode{abs_time} denotes an +object of a +specialization of \tcode{time_point}\iref{time.point}. \begin{note} The timed mutex types meet the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. @@ -7315,9 +8240,9 @@ shared mutex types\iref{thread.sharedmutex.requirements}, and additionally meet the requirements set out below. In this description, \tcode{m} denotes an object of a shared timed mutex type, -\tcode{rel_time} denotes an object of an instantiation of +\tcode{rel_time} denotes an object of a specialization of \tcode{duration}\iref{time.duration}, and -\tcode{abs_time} denotes an object of an instantiation of +\tcode{abs_time} denotes an object of a specialization of \tcode{time_point}\iref{time.point}. \begin{note} The shared timed mutex types meet the \oldconcept{SharedTimedLockable} @@ -7497,9 +8422,9 @@ struct adopt_lock_t { }; // assume the calling thread has already // obtained mutex ownership and manage it - inline constexpr defer_lock_t defer_lock { }; - inline constexpr try_to_lock_t try_to_lock { }; - inline constexpr adopt_lock_t adopt_lock { }; + inline constexpr defer_lock_t defer_lock { }; + inline constexpr try_to_lock_t try_to_lock { }; + inline constexpr adopt_lock_t adopt_lock { }; } \end{codeblock} @@ -7521,7 +8446,7 @@ lock_guard& operator=(const lock_guard&) = delete; private: - mutex_type& pm; // \expos + mutex_type& @\exposid{pm}@; // \expos }; } \end{codeblock} @@ -7531,7 +8456,7 @@ within a scope. A \tcode{lock_guard} object maintains ownership of a lockable object throughout the \tcode{lock_guard} object's lifetime\iref{basic.life}. The behavior of a program is undefined if the lockable object referenced by -\tcode{pm} does not exist for the entire lifetime of the \tcode{lock_guard} +\exposid{pm} does not exist for the entire lifetime of the \tcode{lock_guard} object. The supplied \tcode{Mutex} type shall meet the \oldconcept{BasicLockable} requirements\iref{thread.req.lockable.basic}. @@ -7543,7 +8468,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{pm} with \tcode{m}. Calls \tcode{m.lock()}. +Initializes \exposid{pm} with \tcode{m}. Calls \tcode{m.lock()}. \end{itemdescr} \indexlibraryctor{lock_guard}% @@ -7558,7 +8483,7 @@ \pnum \effects -Initializes \tcode{pm} with \tcode{m}. +Initializes \exposid{pm} with \tcode{m}. \pnum \throws @@ -7573,7 +8498,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{pm.unlock()} +Equivalent to: \tcode{\exposid{pm}.unlock()} \end{itemdescr} \rSec3[thread.lock.scoped]{Class template \tcode{scoped_lock}} @@ -7594,7 +8519,7 @@ scoped_lock& operator=(const scoped_lock&) = delete; private: - tuple pm; // \expos + tuple @\exposid{pm}@; // \expos }; } \end{codeblock} @@ -7604,7 +8529,7 @@ within a scope. A \tcode{scoped_lock} object maintains ownership of lockable objects throughout the \tcode{scoped_lock} object's lifetime\iref{basic.life}. The behavior of a program is undefined if the lockable objects referenced by -\tcode{pm} do not exist for the entire lifetime of the \tcode{scoped_lock} +\exposid{pm} do not exist for the entire lifetime of the \tcode{scoped_lock} object. \begin{itemize} \item @@ -7628,7 +8553,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{pm} with \tcode{tie(m...)}. +Initializes \exposid{pm} with \tcode{tie(m...)}. Then if \tcode{sizeof...(MutexTypes)} is \tcode{0}, no effects. Otherwise if \tcode{sizeof...(MutexTypes)} is \tcode{1}, then \tcode{m.lock()}. Otherwise, \tcode{lock(m...)}. @@ -7646,7 +8571,7 @@ \pnum \effects -Initializes \tcode{pm} with \tcode{tie(m...)}. +Initializes \exposid{pm} with \tcode{tie(m...)}. \pnum \throws @@ -7662,7 +8587,7 @@ \pnum \effects For all \tcode{i} in \range{0}{sizeof...(MutexTypes)}, -\tcode{get(pm).unlock()}. +\tcode{get(\exposid{pm}).unlock()}. \end{itemdescr} \rSec3[thread.lock.unique]{Class template \tcode{unique_lock}} @@ -7693,7 +8618,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(); @@ -7716,8 +8641,8 @@ mutex_type* mutex() const noexcept; private: - mutex_type* pm; // \expos - bool owns; // \expos + mutex_type* @\exposid{pm}@; // \expos + bool @\exposid{owns}@; // \expos }; } \end{codeblock} @@ -7728,8 +8653,8 @@ construction or after construction, and may be transferred, after acquisition, to another \tcode{unique_lock} object. Objects of type \tcode{unique_lock} are not copyable but are movable. The behavior of a program is undefined if the contained pointer -\tcode{pm} is not null and the lockable object pointed -to by \tcode{pm} does not exist for the entire remaining +\exposid{pm} is not null and the lockable object pointed +to by \exposid{pm} does not exist for the entire remaining lifetime\iref{basic.life} of the \tcode{unique_lock} object. The supplied \tcode{Mutex} type shall meet the \oldconcept{BasicLockable} requirements\iref{thread.req.lockable.basic}. @@ -7754,7 +8679,7 @@ \begin{itemdescr} \pnum \ensures -\tcode{pm == nullptr} and \tcode{owns == false}. +\tcode{\exposid{pm} == nullptr} and \tcode{\exposid{owns} == false}. \end{itemdescr} \indexlibraryctor{unique_lock}% @@ -7769,7 +8694,7 @@ \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == true}. +\tcode{\exposid{pm} == addressof(m)} and \tcode{\exposid{owns} == true}. \end{itemdescr} \indexlibraryctor{unique_lock}% @@ -7780,7 +8705,7 @@ \begin{itemdescr} \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == false}. +\tcode{\exposid{pm} == addressof(m)} and \tcode{\exposid{owns} == false}. \end{itemdescr} \indexlibraryctor{unique_lock}% @@ -7800,7 +8725,7 @@ \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == res}, +\tcode{\exposid{pm} == addressof(m)} and \tcode{o\exposid{owns}wns == res}, where \tcode{res} is the value returned by the call to \tcode{m.try_lock()}. \end{itemdescr} @@ -7816,7 +8741,7 @@ \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == true}. +\tcode{\exposid{pm} == addressof(m)} and \tcode{\exposid{owns} == true}. \pnum \throws @@ -7841,7 +8766,7 @@ \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == res}, +\tcode{\exposid{pm} == addressof(m)} and \tcode{\exposid{owns} == res}, where \tcode{res} is the value returned by the call to \tcode{m.try_lock_until(abs_time)}. \end{itemdescr} @@ -7863,7 +8788,7 @@ \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == res}, +\tcode{\exposid{pm} == addressof(m)} and \tcode{\exposid{owns} == res}, where \tcode{res} is the value returned by the call to \tcode{m.try_lock_for(rel_time)}. \end{itemdescr} @@ -7875,31 +8800,22 @@ \begin{itemdescr} \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}. +\tcode{\exposid{pm} == u_p.\exposid{pm}} and \tcode{\exposid{owns} == u_p.\exposid{owns}} (where \tcode{u_p} is the state of \tcode{u} just prior to this construction), \tcode{u.\exposid{pm} == 0} and \tcode{u.\exposid{owns} == false}. \end{itemdescr} \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}% @@ -7910,7 +8826,7 @@ \begin{itemdescr} \pnum \effects -If \tcode{owns} calls \tcode{pm->unlock()}. +If \exposid{owns} calls \tcode{\exposid{pm}->unlock()}. \end{itemdescr} \rSec4[thread.lock.unique.locking]{Locking} @@ -7923,22 +8839,22 @@ \begin{itemdescr} \pnum \effects -As if by \tcode{pm->lock()}. +As if by \tcode{\exposid{pm}->lock()}. \pnum \ensures -\tcode{owns == true}. +\tcode{\exposid{owns} == true}. \pnum \throws -Any exception thrown by \tcode{pm->lock()}. \tcode{system_error} when an exception +Any exception thrown by \tcode{\exposid{pm}->lock()}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. \pnum \errors \begin{itemize} -\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}. -\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} +\item \tcode{operation_not_permitted} --- if \exposid{pm} is \keyword{nullptr}. +\item \tcode{resource_deadlock_would_occur} --- if on entry \exposid{owns} is \tcode{true}. \end{itemize} \end{itemdescr} @@ -7956,27 +8872,27 @@ \pnum \effects -As if by \tcode{pm->try_lock()}. +As if by \tcode{\exposid{pm}->try_lock()}. \pnum \ensures -\tcode{owns == res}, where \tcode{res} is the value returned by -\tcode{pm->try_lock()}. +\tcode{\exposid{owns} == res}, where \tcode{res} is the value returned by +\tcode{\exposid{pm}->try_lock()}. \pnum \returns -The value returned by \tcode{pm->try_lock()}. +The value returned by \tcode{\exposid{pm}->try_lock()}. \pnum \throws -Any exception thrown by \tcode{pm->try_lock()}. \tcode{system_error} when an exception +Any exception thrown by \tcode{\exposid{pm}->try_lock()}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. \pnum \errors \begin{itemize} -\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}. -\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} +\item \tcode{operation_not_permitted} --- if \exposid{pm} is \keyword{nullptr}. +\item \tcode{resource_deadlock_would_occur} --- if on entry \exposid{owns} is \tcode{true}. \end{itemize} \end{itemdescr} @@ -7995,27 +8911,27 @@ \pnum \effects -As if by \tcode{pm->try_lock_until(abs_time)}. +As if by \tcode{\exposid{pm}->try_lock_until(abs_time)}. \pnum \ensures -\tcode{owns == res}, where \tcode{res} is the value returned by -\tcode{pm->try_lock_until(abs_time)}. +\tcode{\exposid{owns} == res}, where \tcode{res} is the value returned by +\tcode{\exposid{pm}->try_lock_until(abs_time)}. \pnum \returns -The value returned by \tcode{pm->try_lock_until(abs_time)}. +The value returned by \tcode{\exposid{pm}->try_lock_until(abs_time)}. \pnum \throws -Any exception thrown by \tcode{pm->try_lock_until(abstime)}. \tcode{system_error} when an +Any exception thrown by \tcode{\exposid{pm}->try_lock_until(abstime)}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. \pnum \errors \begin{itemize} -\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}. -\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is +\item \tcode{operation_not_permitted} --- if \exposid{pm} is \keyword{nullptr}. +\item \tcode{resource_deadlock_would_occur} --- if on entry \exposid{owns} is \tcode{true}. \end{itemize} \end{itemdescr} @@ -8033,26 +8949,26 @@ \pnum \effects -As if by \tcode{pm->try_lock_for(rel_time)}. +As if by \tcode{\exposid{pm}->try_lock_for(rel_time)}. \pnum \ensures -\tcode{owns == res}, where \tcode{res} is the value returned by \tcode{pm->try_lock_for(rel_time)}. +\tcode{\exposid{owns} == res}, where \tcode{res} is the value returned by \tcode{\exposid{pm}->try_lock_for(rel_time)}. \pnum \returns -The value returned by \tcode{pm->try_lock_for(rel_time)}. +The value returned by \tcode{\exposid{pm}->try_lock_for(rel_time)}. \pnum \throws -Any exception thrown by \tcode{pm->try_lock_for(rel_time)}. \tcode{system_error} when an +Any exception thrown by \tcode{\exposid{pm}->try_lock_for(rel_time)}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. \pnum \errors \begin{itemize} -\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}. -\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is +\item \tcode{operation_not_permitted} --- if \exposid{pm} is \keyword{nullptr}. +\item \tcode{resource_deadlock_would_occur} --- if on entry \exposid{owns} is \tcode{true}. \end{itemize} \end{itemdescr} @@ -8065,11 +8981,11 @@ \begin{itemdescr} \pnum \effects -As if by \tcode{pm->unlock()}. +As if by \tcode{\exposid{pm}->unlock()}. \pnum \ensures -\tcode{owns == false}. +\tcode{\exposid{owns} == false}. \pnum \throws @@ -8079,7 +8995,7 @@ \pnum \errors \begin{itemize} -\item \tcode{operation_not_permitted} --- if on entry \tcode{owns} is \tcode{false}. +\item \tcode{operation_not_permitted} --- if on entry \exposid{owns} is \tcode{false}. \end{itemize} \end{itemdescr} @@ -8104,11 +9020,11 @@ \begin{itemdescr} \pnum \ensures -\tcode{pm == 0} and \tcode{owns == false}. +\tcode{\exposid{pm} == 0} and \tcode{\exposid{owns} == false}. \pnum \returns -The previous value of \tcode{pm}. +The previous value of \exposid{pm}. \end{itemdescr} \indexlibrarymember{swap}{unique_lock}% @@ -8133,7 +9049,7 @@ \begin{itemdescr} \pnum \returns -\tcode{owns}. +\exposid{owns}. \end{itemdescr} \indexlibrarymember{operator bool}{unique_lock}% @@ -8155,7 +9071,7 @@ \begin{itemdescr} \pnum \returns -\tcode{pm}. +\exposid{pm}. \end{itemdescr} \rSec3[thread.lock.shared]{Class template \tcode{shared_lock}} @@ -8207,8 +9123,8 @@ mutex_type* mutex() const noexcept; private: - mutex_type* pm; // \expos - bool owns; // \expos + mutex_type* @\exposid{pm}@; // \expos + bool @\exposid{owns}@; // \expos }; } \end{codeblock} @@ -8219,8 +9135,8 @@ acquired at construction or after construction, and may be transferred, after acquisition, to another \tcode{shared_lock} object. Objects of type \tcode{shared_lock} are not copyable but are movable. The behavior of a program -is undefined if the contained pointer \tcode{pm} is not null and the lockable -object pointed to by \tcode{pm} does not exist for the entire remaining +is undefined if the contained pointer \exposid{pm} is not null and the lockable +object pointed to by \exposid{pm} does not exist for the entire remaining lifetime\iref{basic.life} of the \tcode{shared_lock} object. The supplied \tcode{Mutex} type shall meet the \oldconcept{SharedLockable} requirements\iref{thread.req.lockable.shared}. @@ -8245,7 +9161,7 @@ \begin{itemdescr} \pnum \ensures -\tcode{pm == nullptr} and \tcode{owns == false}. +\tcode{\exposid{pm} == nullptr} and \tcode{\exposid{owns} == false}. \end{itemdescr} \indexlibraryctor{shared_lock}% @@ -8260,7 +9176,7 @@ \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == true}. +\tcode{\exposid{pm} == addressof(m)} and \tcode{\exposid{owns} == true}. \end{itemdescr} \indexlibraryctor{shared_lock}% @@ -8271,7 +9187,7 @@ \begin{itemdescr} \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == false}. +\tcode{pm == addressof(m)} and \tcode{\exposid{owns} == false}. \end{itemdescr} \indexlibraryctor{shared_lock}% @@ -8286,7 +9202,7 @@ \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == res} +\tcode{\exposid{pm} == addressof(m)} and \tcode{\exposid{owns} == res} where \tcode{res} is the value returned by the call to \tcode{m.try_lock_shared()}. \end{itemdescr} @@ -8303,7 +9219,7 @@ \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == true}. +\tcode{\exposid{pm} == addressof(m)} and \tcode{\exposid{owns} == true}. \end{itemdescr} \indexlibraryctor{shared_lock}% @@ -8325,7 +9241,7 @@ \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == res} +\tcode{\exposid{pm} == addressof(m)} and \tcode{\exposid{owns} == res} where \tcode{res} is the value returned by the call to \tcode{m.try_lock_shared_until(abs_time)}. \end{itemdescr} @@ -8349,7 +9265,7 @@ \pnum \ensures -\tcode{pm == addressof(m)} and \tcode{owns == res} +\tcode{\exposid{pm} == addressof(m)} and \tcode{\exposid{owns} == res} where \tcode{res} is the value returned by the call to \tcode{m.try_lock_shared_for(rel_time)}. \end{itemdescr} @@ -8362,7 +9278,7 @@ \begin{itemdescr} \pnum \effects -If \tcode{owns} calls \tcode{pm->unlock_shared()}. +If \exposid{owns} calls \tcode{\exposid{pm}->unlock_shared()}. \end{itemdescr} \indexlibraryctor{shared_lock}% @@ -8373,9 +9289,9 @@ \begin{itemdescr} \pnum \ensures -\tcode{pm == sl_p.pm} and \tcode{owns == sl_p.owns} (where +\tcode{\exposid{pm} == sl_p.\exposid{pm}} and \tcode{\exposid{owns} == sl_p.\exposid{owns}} (where \tcode{sl_p} is the state of \tcode{sl} just prior to this construction), -\tcode{sl.pm == nullptr} and \tcode{sl.owns == false}. +\tcode{sl.\exposid{pm} == nullptr} and \tcode{sl.\exposid{owns} == false}. \end{itemdescr} \indexlibrarymember{operator=}{shared_lock}% @@ -8386,13 +9302,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} @@ -8405,22 +9319,22 @@ \begin{itemdescr} \pnum \effects -As if by \tcode{pm->lock_shared()}. +As if by \tcode{\exposid{pm}->lock_shared()}. \pnum \ensures -\tcode{owns == true}. +\tcode{\exposid{owns} == true}. \pnum \throws -Any exception thrown by \tcode{pm->lock_shared()}. +Any exception thrown by \tcode{\exposid{pm}->lock_shared()}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. \pnum \errors \begin{itemize} -\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}. -\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is +\item \tcode{operation_not_permitted} --- if \exposid{pm} is \keyword{nullptr}. +\item \tcode{resource_deadlock_would_occur} --- if on entry \exposid{owns} is \tcode{true}. \end{itemize} \end{itemdescr} @@ -8433,27 +9347,27 @@ \begin{itemdescr} \pnum \effects -As if by \tcode{pm->try_lock_shared()}. +As if by \tcode{\exposid{pm}->try_lock_shared()}. \pnum \ensures -\tcode{owns == res}, where \tcode{res} is the value returned by -the call to \tcode{pm->try_lock_shared()}. +\tcode{\exposid{owns} == res}, where \tcode{res} is the value returned by +the call to \tcode{\exposid{pm}->try_lock_shared()}. \pnum \returns -The value returned by the call to \tcode{pm->try_lock_shared()}. +The value returned by the call to \tcode{\exposid{pm}->try_lock_shared()}. \pnum \throws -Any exception thrown by \tcode{pm->try_lock_shared()}. +Any exception thrown by \tcode{\exposid{pm}->try_lock_shared()}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. \pnum \errors \begin{itemize} -\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}. -\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is +\item \tcode{operation_not_permitted} --- if \exposid{pm} is \keyword{nullptr}. +\item \tcode{resource_deadlock_would_occur} --- if on entry \exposid{owns} is \tcode{true}. \end{itemize} \end{itemdescr} @@ -8472,28 +9386,28 @@ \pnum \effects -As if by \tcode{pm->try_lock_shared_until(abs_time)}. +As if by \tcode{\exposid{pm}->try_lock_shared_until(abs_time)}. \pnum \ensures -\tcode{owns == res}, where \tcode{res} is the value returned by -the call to \tcode{pm->try_lock_shared_until(abs_time)}. +\tcode{\exposid{owns} == res}, where \tcode{res} is the value returned by +the call to \tcode{\exposid{pm}->try_lock_shared_until(abs_time)}. \pnum \returns The value returned by the call to -\tcode{pm->try_lock_shared_until(abs_time)}. +\tcode{\exposid{pm}->try_lock_shared_until(abs_time)}. \pnum \throws -Any exception thrown by \tcode{pm->try_lock_shared_until(abs_time)}. +Any exception thrown by \tcode{\exposid{pm}->try_lock_shared_until(abs_time)}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. \pnum \errors \begin{itemize} -\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}. -\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is +\item \tcode{operation_not_permitted} --- if \exposid{pm} is \keyword{nullptr}. +\item \tcode{resource_deadlock_would_occur} --- if on entry \exposid{owns} is \tcode{true}. \end{itemize} \end{itemdescr} @@ -8512,25 +9426,25 @@ \pnum \effects -As if by \tcode{pm->try_lock_shared_for(rel_time)}. +As if by \tcode{\exposid{pm}->try_lock_shared_for(rel_time)}. \pnum \ensures -\tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{pm->try_lock_shared_for(rel_time)}. +\tcode{\exposid{owns} == res}, where \tcode{res} is the value returned by the call to \tcode{\exposid{pm}->try_lock_shared_for(rel_time)}. \pnum \returns -The value returned by the call to \tcode{pm->try_lock_shared_for(rel_time)}. +The value returned by the call to \tcode{\exposid{pm}->try_lock_shared_for(rel_time)}. \pnum \throws -Any exception thrown by \tcode{pm->try_lock_shared_for(rel_time)}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. +Any exception thrown by \tcode{\exposid{pm}->try_lock_shared_for(rel_time)}. \tcode{system_error} when an exception is required\iref{thread.req.exception}. \pnum \errors \begin{itemize} -\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}. -\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is +\item \tcode{operation_not_permitted} --- if \exposid{pm} is \keyword{nullptr}. +\item \tcode{resource_deadlock_would_occur} --- if on entry \exposid{owns} is \tcode{true}. \end{itemize} \end{itemdescr} @@ -8543,11 +9457,11 @@ \begin{itemdescr} \pnum \effects -As if by \tcode{pm->unlock_shared()}. +As if by \tcode{\exposid{pm}->unlock_shared()}. \pnum \ensures -\tcode{owns == false}. +\tcode{\exposid{owns} == false}. \pnum \throws @@ -8556,7 +9470,7 @@ \pnum \errors \begin{itemize} -\item \tcode{operation_not_permitted} --- if on entry \tcode{owns} is +\item \tcode{operation_not_permitted} --- if on entry \exposid{owns} is \tcode{false}. \end{itemize} \end{itemdescr} @@ -8582,11 +9496,11 @@ \begin{itemdescr} \pnum \ensures -\tcode{pm == nullptr} and \tcode{owns == false}. +\tcode{\exposid{pm} == nullptr} and \tcode{\exposid{owns} == false}. \pnum \returns -The previous value of \tcode{pm}. +The previous value of \exposid{pm}. \end{itemdescr} \indexlibrarymember{swap}{shared_lock}% @@ -8611,7 +9525,7 @@ \begin{itemdescr} \pnum \returns -\tcode{owns}. +\exposid{owns}. \end{itemdescr} \indexlibrarymember{operator bool}{shared_lock}% @@ -8622,7 +9536,7 @@ \begin{itemdescr} \pnum \returns -\tcode{owns}. +\exposid{owns}. \end{itemdescr} \indexlibrarymember{mutex}{shared_lock}% @@ -8633,7 +9547,7 @@ \begin{itemdescr} \pnum \returns -\tcode{pm}. +\exposid{pm}. \end{itemdescr} \rSec2[thread.lock.algorithm]{Generic locking algorithms} @@ -8847,6 +9761,16 @@ \pnum Condition variable construction and destruction need not be synchronized. +\pnum +The definitions in \ref{thread.condition} +make use of the following exposition-only function: +\begin{codeblock} +template + chrono::steady_clock::time_point @\exposid{rel-to-abs}@(const Dur& rel_time) { + return chrono::steady_clock::now() + chrono::ceil(rel_time); + } +\end{codeblock} + \rSec2[condition.variable.syn]{Header \tcode{} synopsis} \indexheader{condition_variable}% @@ -8885,11 +9809,14 @@ \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 -the current thread have been destroyed. This notification is equivalent to: +thread exits. +This notification is sequenced after +all objects with thread storage duration associated with +the current thread have been destroyed and +is equivalent to: \begin{codeblock} -lk.unlock(); cond.notify_all(); +lk.unlock(); \end{codeblock} \pnum @@ -8933,17 +9860,17 @@ void wait(unique_lock& lock, Predicate pred); template cv_status wait_until(unique_lock& lock, - const chrono::time_point& abs_time); + chrono::time_point abs_time); template bool wait_until(unique_lock& lock, - const chrono::time_point& abs_time, + chrono::time_point abs_time, Predicate pred); template cv_status wait_for(unique_lock& lock, - const chrono::duration& rel_time); + chrono::duration rel_time); template bool wait_for(unique_lock& lock, - const chrono::duration& rel_time, + chrono::duration rel_time, Predicate pred); using native_handle_type = @\impdefnc@; // see~\ref{thread.req.native} @@ -9109,7 +10036,7 @@ \begin{itemdecl} template cv_status wait_until(unique_lock& lock, - const chrono::time_point& abs_time); + chrono::time_point abs_time); \end{itemdecl} \begin{itemdescr} @@ -9171,7 +10098,7 @@ \begin{itemdecl} template cv_status wait_for(unique_lock& lock, - const chrono::duration& rel_time); + chrono::duration rel_time); \end{itemdecl} \begin{itemdescr} @@ -9190,7 +10117,7 @@ \effects Equivalent to: \begin{codeblock} -return wait_until(lock, chrono::steady_clock::now() + rel_time); +return wait_until(lock, @\exposid{rel-to-abs}@(rel_time)); \end{codeblock} \pnum @@ -9222,7 +10149,7 @@ \begin{itemdecl} template bool wait_until(unique_lock& lock, - const chrono::time_point& abs_time, + chrono::time_point abs_time, Predicate pred); \end{itemdecl} @@ -9277,7 +10204,7 @@ \begin{itemdecl} template bool wait_for(unique_lock& lock, - const chrono::duration& rel_time, + chrono::duration rel_time, Predicate pred); \end{itemdecl} @@ -9300,7 +10227,7 @@ \effects Equivalent to: \begin{codeblock} -return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred)); +return wait_until(lock, @\exposid{rel-to-abs}@(rel_time), std::move(pred)); \end{codeblock} \pnum @@ -9373,24 +10300,24 @@ void wait(Lock& lock, Predicate pred); template - cv_status wait_until(Lock& lock, const chrono::time_point& abs_time); + cv_status wait_until(Lock& lock, chrono::time_point abs_time); template - bool wait_until(Lock& lock, const chrono::time_point& abs_time, + bool wait_until(Lock& lock, chrono::time_point abs_time, Predicate pred); template - cv_status wait_for(Lock& lock, const chrono::duration& rel_time); + cv_status wait_for(Lock& lock, chrono::duration rel_time); template - bool wait_for(Lock& lock, const chrono::duration& rel_time, Predicate pred); + bool wait_for(Lock& lock, chrono::duration rel_time, Predicate pred); // \ref{thread.condvarany.intwait}, interruptible waits template bool wait(Lock& lock, stop_token stoken, Predicate pred); template bool wait_until(Lock& lock, stop_token stoken, - const chrono::time_point& abs_time, Predicate pred); + chrono::time_point abs_time, Predicate pred); template bool wait_for(Lock& lock, stop_token stoken, - const chrono::duration& rel_time, Predicate pred); + chrono::duration rel_time, Predicate pred); }; } \end{codeblock} @@ -9515,7 +10442,7 @@ \indexlibrarymember{wait_until}{condition_variable_any}% \begin{itemdecl} template - cv_status wait_until(Lock& lock, const chrono::time_point& abs_time); + cv_status wait_until(Lock& lock, chrono::time_point abs_time); \end{itemdecl} \begin{itemdescr} @@ -9566,7 +10493,7 @@ \indexlibrarymember{wait_for}{condition_variable_any}% \begin{itemdecl} template - cv_status wait_for(Lock& lock, const chrono::duration& rel_time); + cv_status wait_for(Lock& lock, chrono::duration rel_time); \end{itemdecl} \begin{itemdescr} @@ -9574,7 +10501,7 @@ \effects Equivalent to: \begin{codeblock} -return wait_until(lock, chrono::steady_clock::now() + rel_time); +return wait_until(lock, @\exposid{rel-to-abs}@(rel_time)); \end{codeblock} \pnum @@ -9604,7 +10531,7 @@ \indexlibrarymember{wait_until}{condition_variable_any}% \begin{itemdecl} template - bool wait_until(Lock& lock, const chrono::time_point& abs_time, Predicate pred); + bool wait_until(Lock& lock, chrono::time_point abs_time, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -9634,7 +10561,7 @@ \indexlibrarymember{wait_for}{condition_variable_any}% \begin{itemdecl} template - bool wait_for(Lock& lock, const chrono::duration& rel_time, Predicate pred); + bool wait_for(Lock& lock, chrono::duration rel_time, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -9642,7 +10569,7 @@ \effects Equivalent to: \begin{codeblock} -return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred)); +return wait_until(lock, @\exposid{rel-to-abs}@(rel_time), std::move(pred)); \end{codeblock} \end{itemdescr} @@ -9700,7 +10627,7 @@ \begin{itemdecl} template bool wait_until(Lock& lock, stop_token stoken, - const chrono::time_point& abs_time, Predicate pred); + chrono::time_point abs_time, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -9738,7 +10665,7 @@ \pnum \throws -Timeout-related exceptions \iref{thread.req.timing}, +Timeout-related exceptions\iref{thread.req.timing}, or any exception thrown by \tcode{pred}. \pnum @@ -9753,7 +10680,7 @@ \begin{itemdecl} template bool wait_for(Lock& lock, stop_token stoken, - const chrono::duration& rel_time, Predicate pred); + chrono::duration rel_time, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -9761,8 +10688,7 @@ \effects Equivalent to: \begin{codeblock} -return wait_until(lock, std::move(stoken), chrono::steady_clock::now() + rel_time, - std::move(pred)); +return wait_until(lock, std::move(stoken), @\exposid{rel-to-abs}@(rel_time), std::move(pred)); \end{codeblock} \end{itemdescr} @@ -9820,7 +10746,7 @@ bool try_acquire_until(const chrono::time_point& abs_time); private: - ptrdiff_t counter; // \expos + ptrdiff_t @\exposid{counter}@; // \expos }; } \end{codeblock} @@ -9850,7 +10776,7 @@ \begin{itemdescr} \pnum \returns -The maximum value of \tcode{counter}. +The maximum value of \exposid{counter}. This value is greater than or equal to \tcode{least_max_value}. \end{itemdescr} @@ -9867,7 +10793,7 @@ \pnum \effects -Initializes \tcode{counter} with \tcode{desired}. +Initializes \exposid{counter} with \tcode{desired}. \pnum \throws @@ -9883,13 +10809,13 @@ \pnum \expects \tcode{update >= 0} is \tcode{true}, and -\tcode{update <= max() - counter} is \tcode{true}. +\tcode{update <= max() - \exposid{counter}} is \tcode{true}. \pnum \effects -Atomically execute \tcode{counter += update}. +Atomically execute \tcode{\exposid{counter} += update}. Then, unblocks any threads -that are waiting for \tcode{counter} to be greater than zero. +that are waiting for \exposid{counter} to be greater than zero. \pnum \sync @@ -9914,11 +10840,11 @@ \begin{itemdescr} \pnum \effects -Attempts to atomically decrement \tcode{counter} if it is positive, +Attempts to atomically decrement \exposid{counter} if it is positive, without blocking. -If \tcode{counter} is not decremented, there is no effect and +If \exposid{counter} is not decremented, there is no effect and \tcode{try_acquire} immediately returns. -An implementation may fail to decrement \tcode{counter} +An implementation may fail to decrement \exposid{counter} even if it is positive. \begin{note} This spurious failure is normally uncommon, but @@ -9931,7 +10857,7 @@ \pnum \returns -\tcode{true} if \tcode{counter} was decremented, otherwise \tcode{false}. +\tcode{true} if \exposid{counter} was decremented, otherwise \tcode{false}. \end{itemdescr} \indexlibrarymember{acquire}{counting_semaphore}% @@ -9947,7 +10873,7 @@ \item Evaluates \tcode{try_acquire()}. If the result is \tcode{true}, returns. \item \indextext{block (execution)}% -Blocks on \tcode{*this} until \tcode{counter} is greater than zero. +Blocks on \tcode{*this} until \exposid{counter} is greater than zero. \end{itemize} \pnum @@ -9980,7 +10906,7 @@ \item \indextext{block (execution)}% Blocks on \tcode{*this} - until \tcode{counter} is greater than zero or until the timeout expires. + until \exposid{counter} is greater than zero or until the timeout expires. If it is unblocked by the timeout expiring, returns \tcode{false}. \end{itemize} The timeout expires\iref{thread.req.timing} @@ -10050,7 +10976,7 @@ void arrive_and_wait(ptrdiff_t update = 1); private: - ptrdiff_t counter; // \expos + ptrdiff_t @\exposid{counter}@; // \expos }; } \end{codeblock} @@ -10073,7 +10999,7 @@ \begin{itemdescr} \pnum \returns -The maximum value of \tcode{counter} that the implementation supports. +The maximum value of \exposid{counter} that the implementation supports. \end{itemdescr} \indexlibraryctor{latch}% @@ -10089,7 +11015,7 @@ \pnum \effects -Initializes \tcode{counter} with \tcode{expected}. +Initializes \exposid{counter} with \tcode{expected}. \pnum \throws @@ -10105,12 +11031,12 @@ \pnum \expects \tcode{update >= 0} is \tcode{true}, and -\tcode{update <= counter} is \tcode{true}. +\tcode{update <= \exposid{counter}} is \tcode{true}. \pnum \effects -Atomically decrements \tcode{counter} by \tcode{update}. -If \tcode{counter} is equal to zero, +Atomically decrements \exposid{counter} by \tcode{update}. +If \exposid{counter} is equal to zero, unblocks all threads blocked on \tcode{*this}. \pnum @@ -10135,7 +11061,7 @@ \begin{itemdescr} \pnum \returns -With very low probability \tcode{false}. Otherwise \tcode{counter == 0}. +With very low probability \tcode{false}. Otherwise \tcode{\exposid{counter} == 0}. \end{itemdescr} \indexlibrarymember{wait}{latch}% @@ -10147,9 +11073,9 @@ \pnum \indextext{block (execution)}% \effects -If \tcode{counter} equals zero, returns immediately. +If \exposid{counter} equals zero, returns immediately. Otherwise, blocks on \tcode{*this} -until a call to \tcode{count_down} that decrements \tcode{counter} to zero. +until a call to \tcode{count_down} that decrements \exposid{counter} to zero. \pnum \throws @@ -10225,7 +11151,7 @@ void arrive_and_drop(); private: - CompletionFunction completion; // \expos + CompletionFunction @\exposid{completion}@; // \expos }; } \end{codeblock} @@ -10262,7 +11188,7 @@ The \defn{phase completion step} that is executed at the end of each phase has the following effects: \begin{itemize} -\item Invokes the completion function, equivalent to \tcode{completion()}. +\item Invokes the completion function, equivalent to \tcode{\exposid{completion}()}. \item Unblocks all threads that are blocked on the phase synchronization point. \end{itemize} The end of the completion step strongly happens before @@ -10290,7 +11216,7 @@ in addition to satisfying the requirements of \tcode{CompletionFunction}, it meets the \oldconcept{DefaultConstructible} requirements (\tref{cpp17.defaultconstructible}) and -\tcode{completion()} has no effects. +\tcode{\exposid{completion}()} has no effects. \pnum \tcode{barrier::arrival_token} is an unspecified type, @@ -10326,7 +11252,7 @@ \effects Sets both the initial expected count for each barrier phase and the current expected count for the first phase to \tcode{expected}. -Initializes \tcode{completion} with \tcode{std::move(f)}. +Initializes \exposid{completion} with \tcode{std::move(f)}. Starts the first phase. \begin{note} If \tcode{expected} is 0 this object can only be destroyed. @@ -10511,9 +11437,6 @@ template void swap(promise& x, promise& y) noexcept; - template - struct uses_allocator, Alloc>; - // \ref{futures.unique.future}, class template \tcode{future} template class future; template class future; @@ -10554,7 +11477,7 @@ \end{note} \pnum -The enum values of \tcode{future_errc} are distinct and not zero. +The enumerator values of \tcode{future_errc} are distinct and not zero. \rSec2[futures.errors]{Error handling} @@ -10609,7 +11532,7 @@ const char* what() const noexcept; private: - error_code ec_; // \expos + error_code @\exposid{ec_}@; // \expos }; } \end{codeblock} @@ -10622,7 +11545,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{ec_} with \tcode{make_error_code(e)}. +Initializes \exposid{ec_} with \tcode{make_error_code(e)}. \end{itemdescr} \indexlibrarymember{code}{future_error}% @@ -10633,7 +11556,7 @@ \begin{itemdescr} \pnum \returns -\tcode{ec_}. +\exposid{ec_}. \end{itemdescr} \indexlibrarymember{what}{future_error}% @@ -10791,9 +11714,6 @@ void set_value_at_thread_exit(@\seebelow@); void set_exception_at_thread_exit(exception_ptr p); }; - - template - struct uses_allocator, Alloc>; } \end{codeblock} @@ -10813,20 +11733,6 @@ they acquire a single mutex associated with the promise object while updating the promise object. -\indexlibrarymember{uses_allocator}{promise}% -\begin{itemdecl} -template - struct uses_allocator, Alloc> - : true_type { }; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{Alloc} meets -the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. -\end{itemdescr} - \indexlibraryctor{promise}% \begin{itemdecl} promise(); @@ -10877,7 +11783,7 @@ \begin{itemdescr} \pnum \effects -Abandons any shared state\iref{futures.state} and then as if +Equivalent to \tcode{promise(std::move(rhs)).swap(*this)}. \pnum @@ -11017,7 +11923,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 @@ -11052,7 +11958,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 @@ -11928,6 +12834,8 @@ packaged_task() noexcept; template explicit packaged_task(F&& f); + template + explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f); ~packaged_task(); // no copy @@ -11977,6 +12885,19 @@ explicit packaged_task(F&& f); \end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Equivalent to +\tcode{packaged_task(allocator_arg, allocator(), std::forward(f))}. +\end{itemdescr} + +\indexlibraryctor{packaged_task}% +\begin{itemdecl} +template + explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f); +\end{itemdecl} + \begin{itemdescr} \pnum \constraints @@ -11987,17 +12908,27 @@ \mandates \tcode{is_invocable_r_v\&, ArgTypes...>} is \tcode{true}. +\pnum +\expects +\tcode{Allocator} meets the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. + \pnum \effects +Let \tcode{A2} be +\tcode{allocator_traits::rebind_alloc<\unspec>} +and let \tcode{a2} be an object of type \tcode{A2} initialized with +\tcode{A2(a)}. 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)}. +Uses \tcode{a2} to allocate storage for the shared state and stores a copy +of \tcode{a2} in the shared state. \pnum \throws -Any exceptions thrown by the copy or move constructor of \tcode{f}, or -\tcode{bad_alloc} if memory for the internal data structures -cannot be allocated. +Any exceptions thrown by the initialization of the stored task. +If storage for the shared state cannot be allocated, any exception thrown by +\tcode{A2::allocate}. \end{itemdescr} \indexlibraryctor{packaged_task}% @@ -12054,12 +12985,12 @@ \begin{itemdescr} \pnum \effects -\begin{itemize} -\item -Releases any shared state\iref{futures.state}; -\item -calls \tcode{packaged_task(std::move(rhs)).swap(*this)}. -\end{itemize} +Equivalent to +\tcode{packaged_task(std::move(rhs)).swap(*this)}. + +\pnum +\returns +\tcode{*this}. \end{itemdescr} \indexlibrarydtor{packaged_task}% @@ -12183,7 +13114,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 @@ -12207,9 +13138,16 @@ \begin{itemdescr} \pnum \effects -As if \tcode{*this = packaged_task(std::move(f))}, where +Equivalent to: +\begin{codeblock} +if (!valid()) { + throw future_error(future_errc::no_state); +} +*this = packaged_task(allocator_arg, a, std::move(f)); +\end{codeblock} +where \tcode{f} is the task stored in -\tcode{*this}. +\tcode{*this} and \tcode{a} is the allocator stored in the shared state. \begin{note} This constructs a new shared state for \tcode{*this}. The old state is abandoned\iref{futures.state}. @@ -12218,9 +13156,7 @@ \pnum \throws \begin{itemize} -\item \tcode{bad_alloc} if memory for the new shared state cannot be allocated. -\item Any exception thrown by the move constructor of the task stored in the shared -state. +\item Any exception thrown by the \tcode{packaged_task} constructor. \item \tcode{future_error} with an error condition of \tcode{no_state} if \tcode{*this} has no shared state. \end{itemize} @@ -12560,7 +13496,7 @@ \indexlibraryglobal{rcu_retire}% \begin{itemdecl} template> -void rcu_retire(T* p, D d = D(), rcu_domain& dom = rcu_default_domain()); + void rcu_retire(T* p, D d = D(), rcu_domain& dom = rcu_default_domain()); \end{itemdecl} \begin{itemdescr} @@ -12728,6 +13664,8 @@ // \ref{saferecl.hp.holder.nonmem}, non-member functions hazard_pointer make_hazard_pointer(); void swap(hazard_pointer&, hazard_pointer&) noexcept; + void make_hazard_pointer_batch(span); + void clear_hazard_pointer_batch(span) noexcept; } \end{codeblock} @@ -13054,3 +13992,37 @@ \effects Equivalent to \tcode{a.swap(b)}. \end{itemdescr} + +\indexlibraryglobal{make_hazard_pointer_batch}% +\begin{itemdecl} +void make_hazard_pointer_batch(span batch); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If an exception is thrown, there are no effects. +Otherwise, for each element \tcode{e} of \tcode{batch} +such that \tcode{e.empty()} is \tcode{true}, +constructs a hazard pointer and makes \tcode{e} +the owner of that hazard pointer. + +\pnum +\throws +\tcode{bad_alloc} if memory for any of the newly-constructed hazard pointers +could not be allocated. +\end{itemdescr} + +\indexlibraryglobal{clear_hazard_pointer_batch}% +\begin{itemdecl} +void clear_hazard_pointer_batch(span batch) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +For each element \tcode{e} of \tcode{batch}, +if \tcode{e.empty()} is \tcode{false}, +destroys the hazard pointer owned by \tcode{e} and +makes \tcode{e} empty. +\end{itemdescr} diff --git a/source/time.tex b/source/time.tex index 877288f310..981798e5a4 100644 --- a/source/time.tex +++ b/source/time.tex @@ -25,12 +25,6 @@ \ref{ctime.syn} & C library time utilities & \tcode{} \\ \end{libsumtab} -\pnum -\indextext{STATICALLY-WIDEN@\exposid{STATICALLY-WIDEN}}% -Let \exposid{STATICALLY-WIDEN}\tcode{("...")} be -\tcode{"..."} if \tcode{charT} is \tcode{char} and -\tcode{L"..."} if \tcode{charT} is \keyword{wchar_t}. - \rSec1[time.syn]{Header \tcode{} synopsis} \indexheader{chrono}% @@ -166,19 +160,19 @@ minutes* offset = nullptr); // convenience typedefs - using nanoseconds = duration<@\term{signed integer type of at least 64 bits}@, nano>; - using microseconds = duration<@\term{signed integer type of at least 55 bits}@, micro>; - using milliseconds = duration<@\term{signed integer type of at least 45 bits}@, milli>; - using seconds = duration<@\term{signed integer type of at least 35 bits}@>; - using minutes = duration<@\term{signed integer type of at least 29 bits}@, ratio< 60>>; - using hours = duration<@\term{signed integer type of at least 23 bits}@, ratio<3600>>; - using days = duration<@\term{signed integer type of at least 25 bits}@, + using nanoseconds = duration<@\placeholder{signed integer type of at least 64 bits}@, nano>; + using microseconds = duration<@\placeholder{signed integer type of at least 55 bits}@, micro>; + using milliseconds = duration<@\placeholder{signed integer type of at least 45 bits}@, milli>; + using seconds = duration<@\placeholder{signed integer type of at least 35 bits}@>; + using minutes = duration<@\placeholder{signed integer type of at least 29 bits}@, ratio< 60>>; + using hours = duration<@\placeholder{signed integer type of at least 23 bits}@, ratio<3600>>; + using days = duration<@\placeholder{signed integer type of at least 25 bits}@, ratio_multiply, hours::period>>; - using weeks = duration<@\term{signed integer type of at least 22 bits}@, + using weeks = duration<@\placeholder{signed integer type of at least 22 bits}@, ratio_multiply, days::period>>; - using years = duration<@\term{signed integer type of at least 17 bits}@, + using years = duration<@\placeholder{signed integer type of at least 17 bits}@, ratio_multiply, days::period>>; - using months = duration<@\term{signed integer type of at least 20 bits}@, + using months = duration<@\placeholder{signed integer type of at least 20 bits}@, ratio_divide>>; // \ref{time.point.nonmember}, \tcode{time_point} arithmetic @@ -198,23 +192,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 @@ -806,9 +800,9 @@ strong_ordering operator<=>(const time_zone_link& x, const time_zone_link& y); // \ref{time.format}, formatting - template struct @\placeholder{local-time-format-t}@; // \expos + template struct @\exposid{local-time-format-t}@; // \expos template - @\placeholder{local-time-format-t}@ + @\exposid{local-time-format-t}@ local_time_format(local_time time, const string* abbrev = nullptr, const seconds* offset_sec = nullptr); } @@ -829,7 +823,7 @@ template struct formatter, charT>; template - struct formatter, charT>; + struct formatter, charT>; template struct formatter; template struct formatter; template struct formatter; @@ -846,7 +840,7 @@ template struct formatter; template struct formatter; template - struct formatter>, charT>; + struct formatter>, charT>; template struct formatter; template struct formatter; template @@ -1021,7 +1015,8 @@ \tcode{C1::is_steady} & \tcode{const bool} & \tcode{true} if \tcode{t1 <= t2} is always \tcode{true} and the time between clock - ticks is constant, otherwise \tcode{false}. \\ \rowsep + ticks is constant, otherwise \tcode{false}. + \tcode{C1::is_steady} shall be usable in constant expressions\iref{expr.const}. \\ \rowsep \tcode{C1::now()} & \tcode{C1::time_point} & @@ -1087,12 +1082,12 @@ \indexlibraryglobal{duration_values}% \begin{itemdecl} template - struct duration_values { - public: - static constexpr Rep zero() noexcept; - static constexpr Rep min() noexcept; - static constexpr Rep max() noexcept; - }; +struct duration_values { +public: + static constexpr Rep zero() noexcept; + static constexpr Rep min() noexcept; + static constexpr Rep max() noexcept; +}; \end{itemdecl} \pnum @@ -1248,10 +1243,10 @@ class duration { public: using rep = Rep; - using period = typename Period::type; + using period = Period::type; private: - rep rep_; // \expos + rep @\exposid{rep_}@; // \expos public: // \ref{time.duration.cons}, construct/copy/destroy @@ -1293,7 +1288,10 @@ \pnum \tcode{Rep} shall be an arithmetic type or a class emulating an arithmetic type. -If \tcode{duration} is instantiated with a \tcode{duration} type as the argument for the template +If a specialization of \tcode{duration} +is instantiated with +a cv-qualified type or a specialization of \tcode{duration} +as the argument for the template parameter \tcode{Rep}, the program is ill-formed. \pnum @@ -1307,7 +1305,7 @@ \pnum The defaulted copy constructor of \tcode{duration} shall be a constexpr function if and only if the required initialization -of the member \tcode{rep_} for copy and move, respectively, would +of the member \exposid{rep_} for copy and move, respectively, would be constexpr-suitable\iref{dcl.constexpr}. \pnum @@ -1345,7 +1343,7 @@ \pnum \effects -Initializes \tcode{rep_} with \tcode{r}. +Initializes \exposid{rep_} with \tcode{r}. \end{itemdescr} \indexlibraryctor{duration}% @@ -1357,13 +1355,17 @@ \begin{itemdescr} \pnum \constraints -No overflow is induced in the conversion and -\tcode{treat_as_floating_point_v} is \tcode{true} or both -\tcode{ratio_divide::den} is \tcode{1} and +\tcode{is_convertible_v} is \tcode{true}. +\tcode{ratio_divide} is a valid ratio specialization. +Either: +\begin{itemize} +\item \tcode{treat_as_floating_point_v} is \tcode{true}; or +\item \tcode{ratio_divide::den} is \tcode{1} and \tcode{treat_as_floating_point_v} is \tcode{false}. +\end{itemize} \begin{note} This -requirement prevents implicit truncation error when converting between +requirement prevents implicit truncation errors when converting between integral-based \tcode{duration} types. Such a construction could easily lead to confusion about the value of the \tcode{duration}. \end{note} @@ -1377,7 +1379,7 @@ \pnum \effects -Initializes \tcode{rep_} with \tcode{duration_cast(d).count()}. +Initializes \exposid{rep_} with \tcode{duration_cast(d).count()}. \end{itemdescr} \rSec2[time.duration.observer]{Observer} @@ -1390,7 +1392,7 @@ \begin{itemdescr} \pnum \returns -\tcode{rep_}. +\exposid{rep_}. \end{itemdescr} \rSec2[time.duration.arithmetic]{Arithmetic} @@ -1414,7 +1416,7 @@ \begin{itemdescr} \pnum \returns -\tcode{common_type_t(-rep_)}. +\tcode{common_type_t(-\exposid{rep_})}. \end{itemdescr} \indexlibrarymember{operator++}{duration}% @@ -1425,7 +1427,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{++rep_}. +Equivalent to: \tcode{++\exposid{rep_}}. \pnum \returns @@ -1440,7 +1442,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return duration(rep_++);} +Equivalent to: \tcode{return duration(\exposid{rep_}++);} \end{itemdescr} \indexlibrarymember{operator--}{duration}% @@ -1451,7 +1453,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{--rep_}. +Equivalent to: \tcode{--\exposid{rep_}}. \pnum \returns @@ -1466,7 +1468,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return duration(rep_-{}-);} +Equivalent to: \tcode{return duration(\exposid{rep_}-{}-);} \end{itemdescr} \indexlibrarymember{operator+=}{duration}% @@ -1477,7 +1479,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{rep_ += d.count()}. +Equivalent to: \tcode{\exposid{rep_} += d.count()}. \pnum \returns @@ -1492,7 +1494,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{rep_ -= d.count()}. +Equivalent to: \tcode{\exposid{rep_} -= d.count()}. \pnum \returns @@ -1507,7 +1509,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{rep_ *= rhs}. +Equivalent to: \tcode{\exposid{rep_} *= rhs}. \pnum \returns @@ -1522,7 +1524,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{rep_ /= rhs}. +Equivalent to: \tcode{\exposid{rep_} /= rhs}. \pnum \returns @@ -1537,7 +1539,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{rep_ \%= rhs}. +Equivalent to: \tcode{\exposid{rep_} \%= rhs}. \pnum \returns @@ -1552,7 +1554,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{rep_ \%= rhs.count()}. +Equivalent to: \tcode{\exposid{rep_} \%= rhs.count()}. \pnum \returns @@ -2220,11 +2222,11 @@ public: using clock = Clock; using duration = Duration; - using rep = typename duration::rep; - using period = typename duration::period; + using rep = duration::rep; + using period = duration::period; private: - duration d_; // \expos + duration @\exposid{d_}@; // \expos public: // \ref{time.point.cons}, construct @@ -2265,7 +2267,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{d_} with \tcode{duration::zero()}. +Initializes \exposid{d_} with \tcode{duration::zero()}. Such a \tcode{time_point} object represents the epoch. \end{itemdescr} @@ -2277,7 +2279,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{d_} with \tcode{d}. +Initializes \exposid{d_} with \tcode{d}. Such a \tcode{time_point} object represents the epoch \tcode{+ d}. \end{itemdescr} @@ -2294,7 +2296,7 @@ \pnum \effects -Initializes \tcode{d_} with \tcode{t.time_since_epoch()}. +Initializes \exposid{d_} with \tcode{t.time_since_epoch()}. \end{itemdescr} \rSec2[time.point.observer]{Observer} @@ -2307,7 +2309,7 @@ \begin{itemdescr} \pnum \returns -\tcode{d_}. +\exposid{d_}. \end{itemdescr} \rSec2[time.point.arithmetic]{Arithmetic} @@ -2320,7 +2322,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{++d_}. +Equivalent to: \tcode{++\exposid{d_}}. \pnum \returns @@ -2335,7 +2337,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return time_point\{d_++\};} +Equivalent to: \tcode{return time_point\{\exposid{d_}++\};} \end{itemdescr} \indexlibrarymember{operator--}{time_point}% @@ -2346,7 +2348,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{--d_}. +Equivalent to: \tcode{--\exposid{d_}}. \pnum \returns @@ -2361,7 +2363,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{return time_point\{d_-{}-\};} +Equivalent to: \tcode{return time_point\{\exposid{d_}-{}-\};} \end{itemdescr} \indexlibrarymember{operator+=}{time_point}% @@ -2372,7 +2374,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{d_ += d}. +Equivalent to: \tcode{\exposid{d_} += d}. \pnum \returns @@ -2387,7 +2389,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{d_ -= d}. +Equivalent to: \tcode{\exposid{d_} -= d}. \pnum \returns @@ -2655,8 +2657,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} @@ -2743,7 +2745,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L%F %T}"), tp); +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L%F %T}"), tp); \end{codeblock} \pnum @@ -2939,7 +2941,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L%F %T}"), t); +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L%F %T}"), t); \end{codeblock} \pnum @@ -3145,7 +3147,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L%F %T}"), t); +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L%F %T}"), t); \end{codeblock} \pnum @@ -3308,7 +3310,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L%F %T}"), t); +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L%F %T}"), t); \end{codeblock} \pnum @@ -3431,7 +3433,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L%F %T}"), t); +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L%F %T}"), t); \end{codeblock} \end{itemdescr} @@ -3535,6 +3537,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{os << sys_time{lt.time_since_epoch()}} is a valid expression. + \pnum \effects \begin{codeblock} @@ -3954,7 +3960,7 @@ \begin{codeblock} namespace std::chrono { class day { - unsigned char d_; // \expos + unsigned char @\exposid{d_}@; // \expos public: day() = default; constexpr explicit day(unsigned d) noexcept; @@ -3997,7 +4003,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{d_} with \tcode{d}. +Initializes \exposid{d_} with \tcode{d}. The value held is unspecified if \tcode{d} is not in the range \crange{0}{255}. \end{itemdescr} @@ -4009,7 +4015,7 @@ \begin{itemdescr} \pnum \effects -\tcode{++d_}. +\tcode{++\exposid{d_}}. \pnum \returns @@ -4039,7 +4045,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{--d_}. +Equivalent to: \tcode{--\exposid{d_}}. \pnum \returns @@ -4099,7 +4105,7 @@ \begin{itemdescr} \pnum \returns -\tcode{d_}. +\exposid{d_}. \end{itemdescr} \indexlibrarymember{ok}{day}% @@ -4110,7 +4116,7 @@ \begin{itemdescr} \pnum \returns -\tcode{1 <= d_ \&\& d_ <= 31}. +\tcode{1 <= \exposid{d_} \&\& \exposid{d_} <= 31}. \end{itemdescr} \rSec3[time.cal.day.nonmembers]{Non-member functions} @@ -4194,8 +4200,8 @@ Equivalent to: \begin{codeblock} return os << (d.ok() ? - format(@\placeholder{STATICALLY-WIDEN}@("{:%d}"), d) : - format(@\placeholder{STATICALLY-WIDEN}@("{:%d} is not a valid day"), d)); + format(@\exposid{STATICALLY-WIDEN}@("{:%d}"), d) : + format(@\exposid{STATICALLY-WIDEN}@("{:%d} is not a valid day"), d)); \end{codeblock} \end{itemdescr} @@ -4247,7 +4253,7 @@ \begin{codeblock} namespace std::chrono { class month { - unsigned char m_; // \expos + unsigned char @\exposid{m_}@; // \expos public: month() = default; constexpr explicit month(unsigned m) noexcept; @@ -4290,7 +4296,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{m_} with \tcode{m}. +Initializes \exposid{m_} with \tcode{m}. The value held is unspecified if \tcode{m} is not in the range \crange{0}{255}. \end{itemdescr} @@ -4392,7 +4398,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_}. +\exposid{m_}. \end{itemdescr} \indexlibrarymember{ok}{month}% @@ -4403,7 +4409,7 @@ \begin{itemdescr} \pnum \returns -\tcode{1 <= m_ \&\& m_ <= 12}. +\tcode{1 <= \exposid{m_} \&\& \exposid{m_} <= 12}. \end{itemdescr} \rSec3[time.cal.month.nonmembers]{Non-member functions} @@ -4507,8 +4513,8 @@ Equivalent to: \begin{codeblock} return os << (m.ok() ? - format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L%b}"), m) : - format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{} is not a valid month"), + format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L%b}"), m) : + format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{} is not a valid month"), static_cast(m))); \end{codeblock} \end{itemdescr} @@ -4550,7 +4556,7 @@ \begin{codeblock} namespace std::chrono { class year { - short y_; // \expos + short @\exposid{y_}@; // \expos public: year() = default; constexpr explicit year(int y) noexcept; @@ -4600,7 +4606,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{y_} with \tcode{y}. +Initializes \exposid{y_} with \tcode{y}. The value held is unspecified if \tcode{y} is not in the range \crange{-32767}{32767}. \end{itemdescr} @@ -4612,7 +4618,7 @@ \begin{itemdescr} \pnum \effects -\tcode{++y_}. +\tcode{++\exposid{y_}}. \pnum \returns @@ -4642,7 +4648,7 @@ \begin{itemdescr} \pnum \effects -\tcode{--y_}. +\tcode{--\exposid{y_}}. \pnum \returns @@ -4713,7 +4719,7 @@ \begin{itemdescr} \pnum \returns -\tcode{year\{-y_\}}. +\tcode{year\{-\exposid{y_}\}}. \end{itemdescr} \indexlibrarymember{is_leap}{year}% @@ -4724,7 +4730,7 @@ \begin{itemdescr} \pnum \returns -\tcode{y_ \% 4 == 0 \&\& (y_ \% 100 != 0 || y_ \% 400 == 0)}. +\tcode{\exposid{y_} \% 4 == 0 \&\& (\exposid{y_} \% 100 != 0 || \exposid{y_} \% 400 == 0)}. \end{itemdescr} \indexlibrarymember{operator int}{year}% @@ -4735,7 +4741,7 @@ \begin{itemdescr} \pnum \returns -\tcode{y_}. +\exposid{y_}. \end{itemdescr} \indexlibrarymember{ok}{year}% @@ -4746,7 +4752,7 @@ \begin{itemdescr} \pnum \returns -\tcode{min().y_ <= y_ \&\& y_ <= max().y_}. +\tcode{min().\exposid{y_} <= \exposid{y_} \&\& \exposid{y_} <= max().\exposid{y_}}. \end{itemdescr} \indexlibrarymember{min}{year}% @@ -4852,8 +4858,8 @@ Equivalent to: \begin{codeblock} return os << (y.ok() ? - format(@\placeholder{STATICALLY-WIDEN}@("{:%Y}"), y) : - format(@\placeholder{STATICALLY-WIDEN}@("{:%Y} is not a valid year"), y)); + format(@\exposid{STATICALLY-WIDEN}@("{:%Y}"), y) : + format(@\exposid{STATICALLY-WIDEN}@("{:%Y} is not a valid year"), y)); \end{codeblock} \end{itemdescr} @@ -4905,7 +4911,7 @@ \begin{codeblock} namespace std::chrono { class weekday { - unsigned char wd_; // \expos + unsigned char @\exposid{wd_}@; // \expos public: weekday() = default; constexpr explicit weekday(unsigned wd) noexcept; @@ -4959,7 +4965,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{wd_} with \tcode{wd == 7 ?\ 0 :\ wd}. +Initializes \exposid{wd_} with \tcode{wd == 7 ?\ 0 :\ wd}. The value held is unspecified if \tcode{wd} is not in the range \crange{0}{255}. \end{itemdescr} @@ -4972,13 +4978,13 @@ \pnum \effects Computes what day of the week corresponds to the \tcode{sys_days} \tcode{dp}, -and initializes that day of the week in \tcode{wd_}. +and initializes that day of the week in \exposid{wd_}. \pnum \begin{example} If \tcode{dp} represents 1970-01-01, the constructed \tcode{weekday} represents Thursday -by storing \tcode{4} in \tcode{wd_}. +by storing \tcode{4} in \exposid{wd_}. \end{example} \end{itemdescr} @@ -4991,7 +4997,7 @@ \pnum \effects Computes what day of the week corresponds to the \tcode{local_days} \tcode{dp}, -and initializes that day of the week in \tcode{wd_}. +and initializes that day of the week in \exposid{wd_}. \pnum \ensures @@ -5097,7 +5103,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wd_}. +\exposid{wd_}. \end{itemdescr} \indexlibrarymember{iso_encoding}{weekday}% @@ -5108,7 +5114,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wd_ == 0u ?\ 7u :\ wd_}. +\tcode{\exposid{wd_} == 0u ?\ 7u :\ \exposid{wd_}}. \end{itemdescr} \indexlibrarymember{ok}{weekday}% @@ -5119,7 +5125,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wd_ <= 6}. +\tcode{\exposid{wd_} <= 6}. \end{itemdescr} \indexlibrarymember{operator[]}{weekday}% @@ -5154,7 +5160,7 @@ \begin{itemdescr} \pnum \returns -\tcode{x.wd_ == y.wd_}. +\tcode{x.\exposid{wd_} == y.\exposid{wd_}}. \end{itemdescr} \indexlibrarymember{operator+}{weekday}% @@ -5166,7 +5172,7 @@ \pnum \returns \begin{codeblock} -weekday{modulo(static_cast(x.wd_) + y.count(), 7)} +weekday{modulo(static_cast(x.@\exposid{wd_}@) + y.count(), 7)} \end{codeblock} where \tcode{modulo(n, 7)} computes the remainder of \tcode{n} divided by 7 using Euclidean division. \begin{note} @@ -5234,9 +5240,9 @@ Equivalent to: \begin{codeblock} return os << (wd.ok() ? - format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L%a}"), wd) : - format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{} is not a valid weekday"), - static_cast(wd.wd_))); + format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L%a}"), wd) : + format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{} is not a valid weekday"), + static_cast(wd.@\exposid{wd_}@))); \end{codeblock} \end{itemdescr} @@ -5277,8 +5283,8 @@ \begin{codeblock} namespace std::chrono { class weekday_indexed { - chrono::weekday wd_; // \expos - unsigned char index_; // \expos + chrono::weekday @\exposid{wd_}@; // \expos + unsigned char @\exposid{index_}@; // \expos public: weekday_indexed() = default; @@ -5324,7 +5330,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{wd_} with \tcode{wd} and \tcode{index_} with \tcode{index}. +Initializes \exposid{wd_} with \tcode{wd} and \exposid{index_} with \tcode{index}. The values held are unspecified if \tcode{!wd.ok()} or \tcode{index} is not in the range \crange{0}{7}. \end{itemdescr} @@ -5336,7 +5342,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wd_}. +\exposid{wd_}. \end{itemdescr} \indexlibrarymember{index}{weekday_indexed}% @@ -5347,7 +5353,7 @@ \begin{itemdescr} \pnum \returns -\tcode{index_}. +\exposid{index_}. \end{itemdescr} \indexlibrarymember{ok}{weekday_indexed}% @@ -5358,7 +5364,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wd_.ok() \&\& 1 <= index_ \&\& index_ <= 5}. +\tcode{\exposid{wd_}.ok() \&\& 1 <= \exposid{index_} \&\& \exposid{index_} <= 5}. \end{itemdescr} \rSec3[time.cal.wdidx.nonmembers]{Non-member functions} @@ -5388,8 +5394,8 @@ \begin{codeblock} auto i = wdi.index(); return os << (i >= 1 && i <= 5 ? - format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L}[{}]"), wdi.weekday(), i) : - format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L}[{} is not a valid index]"), + format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L}[{}]"), wdi.weekday(), i) : + format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L}[{} is not a valid index]"), wdi.weekday(), i)); \end{codeblock} \end{itemdescr} @@ -5402,9 +5408,9 @@ \begin{codeblock} namespace std::chrono { class weekday_last { - chrono::weekday wd_; // \expos + chrono::weekday @\exposid{wd_}@; // \expos - public: + public: constexpr explicit weekday_last(const chrono::weekday& wd) noexcept; constexpr chrono::weekday weekday() const noexcept; @@ -5441,7 +5447,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{wd_} with \tcode{wd}. +Initializes \exposid{wd_} with \tcode{wd}. \end{itemdescr} \indexlibrarymember{weekday_last}{weekday}% @@ -5452,7 +5458,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wd_}. +\exposid{wd_}. \end{itemdescr} \indexlibrarymember{ok}{weekday_last}% @@ -5463,7 +5469,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wd_.ok()}. +\tcode{\exposid{wd_}.ok()}. \end{itemdescr} \rSec3[time.cal.wdlast.nonmembers]{Non-member functions} @@ -5491,7 +5497,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L}[last]"), wdl.weekday()); +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L}[last]"), wdl.weekday()); \end{codeblock} \end{itemdescr} @@ -5503,8 +5509,8 @@ \begin{codeblock} namespace std::chrono { class month_day { - chrono::month m_; // \expos - chrono::day d_; // \expos + chrono::month @\exposid{m_}@; // \expos + chrono::day @\exposid{d_}@; // \expos public: month_day() = default; @@ -5536,7 +5542,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{m_} with \tcode{m}, and \tcode{d_} with \tcode{d}. +Initializes \exposid{m_} with \tcode{m}, and \exposid{d_} with \tcode{d}. \end{itemdescr} \indexlibrarymember{month}{month_day}% @@ -5547,7 +5553,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_}. +\exposid{m_}. \end{itemdescr} \indexlibrarymember{day}{month_day}% @@ -5558,7 +5564,7 @@ \begin{itemdescr} \pnum \returns -\tcode{d_}. +\exposid{d_}. \end{itemdescr} \indexlibrarymember{ok}{month_day}% @@ -5570,11 +5576,11 @@ \pnum \returns \tcode{true} if -\tcode{m_.ok()} is \tcode{true}, -\tcode{1d <= d_}, and -\tcode{d_} is less than or equal to the number of days in month \tcode{m_}; +\tcode{\exposid{m_}.ok()} is \tcode{true}, +\tcode{1d <= \exposid{d_}}, and +\exposid{d_} is less than or equal to the number of days in month \exposid{m_}; otherwise returns \tcode{false}. -When \tcode{m_ == February}, +When \tcode{\exposid{m_} == February}, the number of days is considered to be 29. \end{itemdescr} @@ -5618,7 +5624,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L}/{}"), +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L}/{}"), md.month(), md.day()); \end{codeblock} \end{itemdescr} @@ -5658,7 +5664,7 @@ \begin{codeblock} namespace std::chrono { class month_day_last { - chrono::month m_; // \expos + chrono::month @\exposid{m_}@; // \expos public: constexpr explicit month_day_last(const chrono::month& m) noexcept; @@ -5696,7 +5702,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{m_} with \tcode{m}. +Initializes \exposid{m_} with \tcode{m}. \end{itemdescr} \indexlibrarymember{month}{month_day_last}% @@ -5707,7 +5713,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_}. +\exposid{m_}. \end{itemdescr} \indexlibrarymember{ok}{month_day_last}% @@ -5718,7 +5724,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_.ok()}. +\tcode{\exposid{m_}.ok()}. \end{itemdescr} \indexlibrarymember{operator==}{month_day_last}% @@ -5755,7 +5761,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L}/last"), mdl.month()); +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L}/last"), mdl.month()); \end{codeblock} \end{itemdescr} @@ -5767,8 +5773,8 @@ \begin{codeblock} namespace std::chrono { class month_weekday { - chrono::month m_; // \expos - chrono::weekday_indexed wdi_; // \expos + chrono::month @\exposid{m_}@; // \expos + chrono::weekday_indexed @\exposid{wdi_}@; // \expos public: constexpr month_weekday(const chrono::month& m, const chrono::weekday_indexed& wdi) noexcept; @@ -5807,7 +5813,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{m_} with \tcode{m}, and \tcode{wdi_} with \tcode{wdi}. +Initializes \exposid{m_} with \tcode{m}, and \exposid{wdi_} with \tcode{wdi}. \end{itemdescr} \indexlibrarymember{month}{month_weekday}% @@ -5818,7 +5824,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_}. +\exposid{m_}. \end{itemdescr} \indexlibrarymember{weekday_indexed}{month_weekday}% @@ -5829,7 +5835,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wdi_}. +\exposid{wdi_}. \end{itemdescr} \indexlibrarymember{ok}{month_weekday}% @@ -5840,7 +5846,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_.ok() \&\& wdi_.ok()}. +\tcode{\exposid{m_}.ok() \&\& \exposid{wdi_}.ok()}. \end{itemdescr} \rSec3[time.cal.mwd.nonmembers]{Non-member functions} @@ -5868,7 +5874,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L}/{:L}"), +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L}/{:L}"), mwd.month(), mwd.weekday_indexed()); \end{codeblock} \end{itemdescr} @@ -5881,8 +5887,8 @@ \begin{codeblock} namespace std::chrono { class month_weekday_last { - chrono::month m_; // \expos - chrono::weekday_last wdl_; // \expos + chrono::month @\exposid{m_}@; // \expos + chrono::weekday_last @\exposid{wdl_}@; // \expos public: constexpr month_weekday_last(const chrono::month& m, const chrono::weekday_last& wdl) noexcept; @@ -5923,7 +5929,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{m_} with \tcode{m}, and \tcode{wdl_} with \tcode{wdl}. +Initializes \exposid{m_} with \tcode{m}, and \exposid{wdl_} with \tcode{wdl}. \end{itemdescr} \indexlibrarymember{month}{month_weekday_last}% @@ -5934,7 +5940,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_}. +\exposid{m_}. \end{itemdescr} \indexlibrarymember{weekday_last}{month_weekday_last}% @@ -5945,7 +5951,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wdl_}. +\exposid{wdl_}. \end{itemdescr} \indexlibrarymember{ok}{month_weekday_last}% @@ -5956,7 +5962,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_.ok() \&\& wdl_.ok()}. +\tcode{\exposid{m_}.ok() \&\& \exposid{wdl_}.ok()}. \end{itemdescr} \rSec3[time.cal.mwdlast.nonmembers]{Non-member functions} @@ -5984,7 +5990,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L}/{:L}"), +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L}/{:L}"), mwdl.month(), mwdl.weekday_last()); \end{codeblock} \end{itemdescr} @@ -5997,8 +6003,8 @@ \begin{codeblock} namespace std::chrono { class year_month { - chrono::year y_; // \expos - chrono::month m_; // \expos + chrono::year @\exposid{y_}@; // \expos + chrono::month @\exposid{m_}@; // \expos public: year_month() = default; @@ -6037,7 +6043,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{y_} with \tcode{y}, and \tcode{m_} with \tcode{m}. +Initializes \exposid{y_} with \tcode{y}, and \exposid{m_} with \tcode{m}. \end{itemdescr} \indexlibrarymember{year}{year_month}% @@ -6048,7 +6054,7 @@ \begin{itemdescr} \pnum \returns -\tcode{y_}. +\exposid{y_}. \end{itemdescr} \indexlibrarymember{month}{year_month}% @@ -6059,7 +6065,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_}. +\exposid{m_}. \end{itemdescr} \indexlibrarymember{operator+=}{year_month}% @@ -6146,7 +6152,7 @@ \begin{itemdescr} \pnum \returns -\tcode{y_.ok() \&\& m_.ok()}. +\tcode{\exposid{y_}.ok() \&\& \exposid{m_}.ok()}. \end{itemdescr} \rSec3[time.cal.ym.nonmembers]{Non-member functions} @@ -6298,7 +6304,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{}/{:L}"), +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{}/{:L}"), ym.year(), ym.month()); \end{codeblock} \end{itemdescr} @@ -6340,9 +6346,9 @@ \begin{codeblock} namespace std::chrono { class year_month_day { - chrono::year y_; // \expos - chrono::month m_; // \expos - chrono::day d_; // \expos + chrono::year @\exposid{y_}@; // \expos + chrono::month @\exposid{m_}@; // \expos + chrono::day @\exposid{d_}@; // \expos public: year_month_day() = default; @@ -6395,9 +6401,9 @@ \pnum \effects Initializes -\tcode{y_} with \tcode{y}, -\tcode{m_} with \tcode{m}, and -\tcode{d_} with \tcode{d}. +\exposid{y_} with \tcode{y}, +\exposid{m_} with \tcode{m}, and +\exposid{d_} with \tcode{d}. \end{itemdescr} \indexlibraryctor{year_month_day}% @@ -6409,9 +6415,9 @@ \pnum \effects Initializes -\tcode{y_} with \tcode{ymdl.year()}, -\tcode{m_} with \tcode{ymdl.month()}, and -\tcode{d_} with \tcode{ymdl.day()}. +\exposid{y_} with \tcode{ymdl.year()}, +\exposid{m_} with \tcode{ymdl.month()}, and +\exposid{d_} with \tcode{ymdl.day()}. \begin{note} This conversion from \tcode{year_month_day_last} to \tcode{year_month_day} can be more efficient than converting a \tcode{year_month_day_last} to a \tcode{sys_days}, @@ -6533,7 +6539,7 @@ \begin{itemdescr} \pnum \returns -\tcode{y_}. +\exposid{y_}. \end{itemdescr} \indexlibrarymember{month}{year_month_day}% @@ -6544,7 +6550,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_}. +\exposid{m_}. \end{itemdescr} \indexlibrarymember{day}{year_month_day}% @@ -6555,7 +6561,7 @@ \begin{itemdescr} \pnum \returns -\tcode{d_}. +\exposid{d_}. \end{itemdescr} \indexlibrarymember{operator sys_days}{year_month_day}% @@ -6570,8 +6576,8 @@ returns a \tcode{sys_days} holding a count of days from the \tcode{sys_days} epoch to \tcode{*this} (a negative value if \tcode{*this} represents a date prior to the \tcode{sys_days} epoch). -Otherwise, if \tcode{y_.ok() \&\& m_.ok()} is \tcode{true}, -returns \tcode{sys_days\{y_/m_/1d\} + (d_ - 1d)}. +Otherwise, if \tcode{\exposid{y_}.ok() \&\& \exposid{m_}.ok()} is \tcode{true}, +returns \tcode{sys_days\{\exposid{y_}/\exposid{m_}/1d\} + (\exposid{d_} - 1d)}. Otherwise the value returned is unspecified. \pnum @@ -6609,9 +6615,9 @@ \begin{itemdescr} \pnum \returns -If \tcode{y_.ok()} is \tcode{true}, -and \tcode{m_.ok()} is \tcode{true}, -and \tcode{d_} is in the range \crange{1d}{(y_/m_/last).day()}, +If \tcode{\exposid{y_}.ok()} is \tcode{true}, +and \tcode{\exposid{m_}.ok()} is \tcode{true}, +and \exposid{d_} is in the range \crange{1d}{(\exposid{y_}/\exposid{m_}/last).day()}, then returns \tcode{true}; otherwise returns \tcode{false}. \end{itemdescr} @@ -6762,8 +6768,8 @@ Equivalent to: \begin{codeblock} return os << (ymd.ok() ? - format(@\placeholder{STATICALLY-WIDEN}@("{:%F}"), ymd) : - format(@\placeholder{STATICALLY-WIDEN}@("{:%F} is not a valid date"), ymd)); + format(@\exposid{STATICALLY-WIDEN}@("{:%F}"), ymd) : + format(@\exposid{STATICALLY-WIDEN}@("{:%F} is not a valid date"), ymd)); \end{codeblock} \end{itemdescr} @@ -6804,8 +6810,8 @@ \begin{codeblock} namespace std::chrono { class year_month_day_last { - chrono::year y_; // \expos - chrono::month_day_last mdl_; // \expos + chrono::year @\exposid{y_}@; // \expos + chrono::month_day_last @\exposid{mdl_}@; // \expos public: constexpr year_month_day_last(const chrono::year& y, @@ -6855,7 +6861,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{y_} with \tcode{y} and \tcode{mdl_} with \tcode{mdl}. +Initializes \exposid{y_} with \tcode{y} and \exposid{mdl_} with \tcode{mdl}. \end{itemdescr} \indexlibrarymember{operator+=}{year_month_day_last}% @@ -6942,7 +6948,7 @@ \begin{itemdescr} \pnum \returns -\tcode{y_}. +\exposid{y_}. \end{itemdescr} \indexlibrarymember{month}{year_month_day_last}% @@ -6953,7 +6959,7 @@ \begin{itemdescr} \pnum \returns -\tcode{mdl_.month()}. +\tcode{\exposid{mdl_}.month()}. \end{itemdescr} \indexlibrarymember{month_day_last}{year_month_day_last}% @@ -6964,7 +6970,7 @@ \begin{itemdescr} \pnum \returns -\tcode{mdl_}. +\exposid{mdl_}. \end{itemdescr} \indexlibrarymember{day}{year_month_day_last}% @@ -7017,7 +7023,7 @@ \begin{itemdescr} \pnum \returns -\tcode{y_.ok() \&\& mdl_.ok()}. +\tcode{\exposid{y_}.ok() \&\& \exposid{mdl_}.ok()}. \end{itemdescr} \rSec3[time.cal.ymdlast.nonmembers]{Non-member functions} @@ -7157,7 +7163,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{}/{:L}"), +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{}/{:L}"), ymdl.year(), ymdl.month_day_last()); \end{codeblock} \end{itemdescr} @@ -7170,9 +7176,9 @@ \begin{codeblock} namespace std::chrono { class year_month_weekday { - chrono::year y_; // \expos - chrono::month m_; // \expos - chrono::weekday_indexed wdi_; // \expos + chrono::year @\exposid{y_}@; // \expos + chrono::month @\exposid{m_}@; // \expos + chrono::weekday_indexed @\exposid{wdi_}@; // \expos public: year_month_weekday() = default; @@ -7225,7 +7231,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{y_} with \tcode{y}, \tcode{m_} with \tcode{m}, and \tcode{wdi_} with \tcode{wdi}. +Initializes \exposid{y_} with \tcode{y}, \exposid{m_} with \tcode{m}, and \exposid{wdi_} with \tcode{wdi}. \end{itemdescr} \indexlibraryctor{year_month_weekday}% @@ -7341,7 +7347,7 @@ \begin{itemdescr} \pnum \returns -\tcode{y_}. +\exposid{y_}. \end{itemdescr} \indexlibrarymember{month}{year_month_weekday}% @@ -7352,7 +7358,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_}. +\exposid{m_}. \end{itemdescr} \indexlibrarymember{weekday}{year_month_weekday}% @@ -7363,7 +7369,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wdi_.weekday()}. +\tcode{\exposid{wdi_}.weekday()}. \end{itemdescr} \indexlibrarymember{index}{year_month_weekday}% @@ -7374,7 +7380,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wdi_.index()}. +\tcode{\exposid{wdi_}.index()}. \end{itemdescr} \indexlibrarymember{weekday_indexed}{year_month_weekday}% @@ -7385,7 +7391,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wdi_}. +\exposid{wdi_}. \end{itemdescr} \indexlibrarymember{operator sys_days}{year_month_weekday}% @@ -7396,7 +7402,7 @@ \begin{itemdescr} \pnum \returns -If \tcode{y_.ok() \&\& m_.ok() \&\& wdi_.weekday().ok()}, +If \tcode{\exposid{y_}.ok() \&\& \exposid{m_}.ok() \&\& \exposid{wdi_}.weekday().ok()}, returns a \tcode{sys_days} that represents the date \tcode{(index() - 1) * 7} days after the first \tcode{weekday()} of \tcode{year()/month()}. @@ -7427,9 +7433,9 @@ \pnum \returns If any of -\tcode{y_.ok()}, -\tcode{m_.ok()}, or -\tcode{wdi_.ok()} +\tcode{\exposid{y_}.ok()}, +\tcode{\exposid{m_}.ok()}, or +\tcode{\exposid{wdi_}.ok()} is \tcode{false}, returns \tcode{false}. Otherwise, if \tcode{*this} represents a valid date, returns \tcode{true}. @@ -7553,7 +7559,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{}/{:L}/{:L}"), +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{}/{:L}/{:L}"), ymwd.year(), ymwd.month(), ymwd.weekday_indexed()); \end{codeblock} \end{itemdescr} @@ -7566,9 +7572,9 @@ \begin{codeblock} namespace std::chrono { class year_month_weekday_last { - chrono::year y_; // \expos - chrono::month m_; // \expos - chrono::weekday_last wdl_; // \expos + chrono::year @\exposid{y_}@; // \expos + chrono::month @\exposid{m_}@; // \expos + chrono::weekday_last @\exposid{wdl_}@; // \expos public: constexpr year_month_weekday_last(const chrono::year& y, const chrono::month& m, @@ -7618,7 +7624,7 @@ \begin{itemdescr} \pnum \effects -Initializes \tcode{y_} with \tcode{y}, \tcode{m_} with \tcode{m}, and \tcode{wdl_} with \tcode{wdl}. +Initializes \exposid{y_} with \tcode{y}, \exposid{m_} with \tcode{m}, and \exposid{wdl_} with \tcode{wdl}. \end{itemdescr} \indexlibrarymember{operator+=}{year_month_weekday_last}% @@ -7705,7 +7711,7 @@ \begin{itemdescr} \pnum \returns -\tcode{y_}. +\exposid{y_}. \end{itemdescr} \indexlibrarymember{month}{year_month_weekday_last}% @@ -7716,7 +7722,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m_}. +\exposid{m_}. \end{itemdescr} \indexlibrarymember{weekday}{year_month_weekday_last}% @@ -7727,7 +7733,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wdl_.weekday()}. +\tcode{\exposid{wdl_}.weekday()}. \end{itemdescr} \indexlibrarymember{weekday_last}{year_month_weekday_last}% @@ -7738,7 +7744,7 @@ \begin{itemdescr} \pnum \returns -\tcode{wdl_}. +\exposid{wdl_}. \end{itemdescr} \indexlibrarymember{operator sys_days}{year_month_weekday_last}% @@ -7774,7 +7780,7 @@ \begin{itemdescr} \pnum \returns -\tcode{y_.ok() \&\& m_.ok() \&\& wdl_.ok()}. +\tcode{\exposid{y_}.ok() \&\& \exposid{m_}.ok() \&\& \exposid{wdl_}.ok()}. \end{itemdescr} \rSec3[time.cal.ymwdlast.nonmembers]{Non-member functions} @@ -7901,7 +7907,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{}/{:L}/{:L}"), +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{}/{:L}/{:L}"), ymwdl.year(), ymwdl.month(), ymwdl.weekday_last()); \end{codeblock} \end{itemdescr} @@ -8422,11 +8428,11 @@ constexpr precision to_duration() const noexcept; private: - bool is_neg; // \expos - chrono::hours h; // \expos - chrono::minutes m; // \expos - chrono::seconds s; // \expos - precision ss; // \expos + bool @\exposid{is-neg}@; // \expos + chrono::hours @\exposid{h_}@; // \expos + chrono::minutes @\exposid{m_}@; // \expos + chrono::seconds @\exposid{s_}@; // \expos + precision @\exposid{ss_}@; // \expos }; } \end{codeblock} @@ -8528,20 +8534,23 @@ which represents the \tcode{Duration d} with precision \tcode{precision}. \begin{itemize} \item - Initializes \tcode{is_neg} with \tcode{d < Duration::zero()}. + Initializes \exposid{is-neg} with \tcode{d < Duration::zero()}. + Let \tcode{\placeholder{ABS_D}} represent + \tcode{-d} if \exposid{is-neg} is \tcode{true} and + \tcode{d} otherwise. \item - Initializes \tcode{h} with \tcode{duration_cast(abs(d))}. + Initializes \exposid{h_} with \tcode{duration_cast(\placeholder{ABS_D})}. \item - Initializes \tcode{m} - with \tcode{duration_cast(abs(d) - hours())}. + Initializes \exposid{m_} + with \tcode{duration_cast(\placeholder{ABS_D} - hours())}. \item - Initializes \tcode{s} - with \tcode{duration_cast(abs(d) - hours() - minutes())}. + Initializes \exposid{s_} + with \tcode{duration_cast(\placeholder{ABS_D} - hours() - minutes())}. \item If \tcode{treat_as_floating_point_v} is \tcode{true}, - initializes \tcode{ss} with \tcode{abs(d) - hours() - minutes() - seconds()}. - Otherwise, initializes \tcode{ss} - with \tcode{duration_cast(abs(d) - hours() - minutes() - seconds())}. + initializes \exposid{ss_} with \tcode{\placeholder{ABS_D}\linebreak{} - hours() - minutes() - seconds()}. + Otherwise, initializes \exposid{ss_} + with \tcode{duration_cast(\placeholder{ABS_D} - hours() - minutes() - seconds())}. \end{itemize} \begin{note} When \tcode{precision::rep} is integral and @@ -8564,7 +8573,7 @@ \begin{itemdescr} \pnum \returns -\tcode{is_neg}. +\exposid{is-neg}. \end{itemdescr} \indexlibrarymember{hours}{hh_mm_ss}% @@ -8575,7 +8584,7 @@ \begin{itemdescr} \pnum \returns -\tcode{h}. +\exposid{h_}. \end{itemdescr} \indexlibrarymember{minutes}{hh_mm_ss}% @@ -8586,7 +8595,7 @@ \begin{itemdescr} \pnum \returns -\tcode{m}. +\exposid{m_}. \end{itemdescr} \indexlibrarymember{seconds}{hh_mm_ss}% @@ -8597,7 +8606,7 @@ \begin{itemdescr} \pnum \returns -\tcode{s}. +\exposid{s_}. \end{itemdescr} \indexlibrarymember{subseconds}{hh_mm_ss}% @@ -8608,7 +8617,7 @@ \begin{itemdescr} \pnum \returns -\tcode{ss}. +\exposid{ss_}. \end{itemdescr} \indexlibrarymember{to_duration}{hh_mm_ss}% @@ -8619,8 +8628,8 @@ \begin{itemdescr} \pnum \returns -If \tcode{is_neg}, returns \tcode{-(h + m + s + ss)}, -otherwise returns \tcode{h + m + s + ss}. +If \exposid{is-neg}, returns \tcode{-(\exposid{h_} + \exposid{m_} + \exposid{s_} + \exposid{ss_})}, +otherwise returns \tcode{\exposid{h_} + \exposid{m_} + \exposid{s_} + \exposid{ss_}}. \end{itemdescr} \indexlibrarymember{operator precision}{hh_mm_ss}% @@ -8638,8 +8647,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} @@ -8647,7 +8656,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L%T}"), hms); +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L%T}"), hms); \end{codeblock} \pnum @@ -9246,11 +9255,11 @@ \begin{codeblock} namespace std::chrono { struct sys_info { - sys_seconds begin; - sys_seconds end; - seconds offset; - minutes save; - string abbrev; + sys_seconds begin; + sys_seconds end; + seconds offset; + minutes save; + string abbrev; }; } \end{codeblock} @@ -9633,10 +9642,10 @@ using duration = common_type_t; private: - TimeZonePtr zone_; // \expos - sys_time tp_; // \expos + TimeZonePtr @\exposid{zone_}@; // \expos + sys_time @\exposid{tp_}@; // \expos - using traits = zoned_traits; // \expos + using @\exposid{traits_}@ = zoned_traits; // \expos public: zoned_time(); @@ -9743,12 +9752,12 @@ \begin{itemdescr} \pnum \constraints -\tcode{traits::default_zone()} is a well-formed expression. +\tcode{\exposid{traits_}::default_zone()} is a well-formed expression. \pnum \effects -Initializes \tcode{zone_} with \tcode{traits::default_zone()} and -default constructs \tcode{tp_}. +Initializes \exposid{zone_} with \tcode{\exposid{traits_}::default_zone()} and +default constructs \exposid{tp_}. \end{itemdescr} \begin{itemdecl} @@ -9758,11 +9767,11 @@ \begin{itemdescr} \pnum \constraints -\tcode{traits::default_zone()} is a well-formed expression. +\tcode{\exposid{traits_}::default_zone()} is a well-formed expression. \pnum \effects -Initializes \tcode{zone_} with \tcode{traits::default_zone()} and \tcode{tp_} with \tcode{st}. +Initializes \exposid{zone_} with \tcode{\exposid{traits_}::default_zone()} and \exposid{tp_} with \tcode{st}. \end{itemdescr} \begin{itemdecl} @@ -9776,8 +9785,8 @@ \pnum \effects -Initializes \tcode{zone_} with \tcode{std::move(z)} and -default constructs \tcode{tp_}. +Initializes \exposid{zone_} with \tcode{std::move(z)} and +default constructs \exposid{tp_}. \end{itemdescr} \begin{itemdecl} @@ -9787,13 +9796,13 @@ \begin{itemdescr} \pnum \constraints -\tcode{traits::locate_zone(string_view\{\})} is a well-formed expression and -\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(string_view\{\})}. +\tcode{\exposid{traits_}::locate_zone(string_view\{\})} is a well-formed expression and +\tcode{zoned_time} is constructible from the return type of \tcode{\exposid{traits_}::locate_zone(string_view\{\})}. \pnum \effects -Initializes \tcode{zone_} with \tcode{traits::locate_zone(name)} and -default constructs \tcode{tp_}. +Initializes \exposid{zone_} with \tcode{\exposid{traits_}::locate_zone(name)} and +default constructs \exposid{tp_}. \end{itemdescr} \begin{itemdecl} @@ -9808,7 +9817,7 @@ \pnum \effects -Initializes \tcode{zone_} with \tcode{y.zone_} and \tcode{tp_} with \tcode{y.tp_}. +Initializes \exposid{zone_} with \tcode{y.\exposid{zone_}} and \exposid{tp_} with \tcode{y.\exposid{tp_}}. \end{itemdescr} \begin{itemdecl} @@ -9822,7 +9831,7 @@ \pnum \effects -Initializes \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{st}. +Initializes \exposid{zone_} with \tcode{std::move(z)} and \exposid{tp_} with \tcode{st}. \end{itemdescr} \begin{itemdecl} @@ -9832,11 +9841,11 @@ \begin{itemdescr} \pnum \constraints -\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(name)} and \tcode{st}. +\tcode{zoned_time} is constructible from the return type of \tcode{\exposid{traits_}::locate_zone(name)} and \tcode{st}. \pnum \effects -Equivalent to construction with \tcode{\{traits::locate_zone(name), st\}}. +Equivalent to construction with \tcode{\{\exposid{traits_}::locate_zone(name), st\}}. \end{itemdescr} \begin{itemdecl} @@ -9859,7 +9868,7 @@ \pnum \effects -Initializes \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{zone_->to_sys(tp)}. +Initializes \exposid{zone_} with \tcode{std::move(z)} and \exposid{tp_} with \tcode{\exposid{zone_}->to_sys(tp)}. \end{itemdescr} \begin{itemdecl} @@ -9869,11 +9878,11 @@ \begin{itemdescr} \pnum \constraints -\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(name)} and \tcode{tp}. +\tcode{zoned_time} is constructible from the return type of \tcode{\exposid{traits_}::locate_zone(name)} and \tcode{tp}. \pnum \effects -Equivalent to construction with \tcode{\{traits::locate_zone(name), tp\}}. +Equivalent to construction with \tcode{\{\exposid{traits_}::locate_zone(name), tp\}}. \end{itemdescr} \begin{itemdecl} @@ -9896,7 +9905,7 @@ \pnum \effects -Initializes \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{zone_->to_sys(tp, c)}. +Initializes \exposid{zone_} with \tcode{std::move(z)} and \exposid{tp_} with \tcode{\exposid{zone_}->to_sys(tp, c)}. \end{itemdescr} \begin{itemdecl} @@ -9907,11 +9916,11 @@ \pnum \constraints \tcode{zoned_time} is constructible from -the return type of \tcode{traits::locate_zone(name)}, \tcode{local_time}, and \tcode{choose}. +the return type of \tcode{\exposid{traits_}::locate_zone(name)}, \tcode{local_time}, and \tcode{choose}. \pnum \effects -Equivalent to construction with \tcode{\{traits::locate_zone(name), tp, c\}}. +Equivalent to construction with \tcode{\{\exposid{traits_}::locate_zone(name), tp, c\}}. \end{itemdescr} \begin{itemdecl} @@ -9930,7 +9939,7 @@ \pnum \effects -Initializes \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{y.tp_}. +Initializes \exposid{zone_} with \tcode{std::move(z)} and \exposid{tp_} with \tcode{y.\exposid{tp_}}. \end{itemdescr} \begin{itemdecl} @@ -9966,12 +9975,12 @@ \pnum \constraints \tcode{zoned_time} is constructible from -the return type of \tcode{traits::locate_zone(name)} and +the return type of \tcode{\exposid{traits_}::locate_zone(name)} and the type \tcode{zoned_time}. \pnum \effects -Equivalent to construction with \tcode{\{traits::locate_zone(name), y\}}. +Equivalent to construction with \tcode{\{\exposid{traits_}::locate_zone(name), y\}}. \end{itemdescr} \begin{itemdecl} @@ -9983,13 +9992,13 @@ \pnum \constraints \tcode{zoned_time} is constructible from -the return type of \tcode{traits::locate_zone(name)}, +the return type of \tcode{\exposid{traits_}::locate_zone(name)}, the type \tcode{zoned_time}, and the type \tcode{choose}. \pnum \effects -Equivalent to construction with \tcode{\{traits::locate_zone(name), y, c\}}. +Equivalent to construction with \tcode{\{\exposid{traits_}::locate_zone(name), y, c\}}. \pnum \begin{note} @@ -10062,7 +10071,7 @@ \begin{itemdescr} \pnum \returns -\tcode{zone_}. +\exposid{zone_}. \end{itemdescr} \indexlibrarymember{get_local_time}{zoned_time}% @@ -10073,7 +10082,7 @@ \begin{itemdescr} \pnum \returns -\tcode{zone_->to_local(tp_)}. +\tcode{\exposid{zone_}->to_local(\exposid{tp_})}. \end{itemdescr} \indexlibrarymember{get_sys_time}{zoned_time}% @@ -10084,7 +10093,7 @@ \begin{itemdescr} \pnum \returns -\tcode{tp_}. +\exposid{tp_}. \end{itemdescr} \indexlibrarymember{get_info}{zoned_time}% @@ -10095,7 +10104,7 @@ \begin{itemdescr} \pnum \returns -\tcode{zone_->get_info(tp_)}. +\tcode{\exposid{zone_}->get_info(\exposid{tp_})}. \end{itemdescr} \rSec3[time.zone.zonedtime.nonmembers]{Non-member functions} @@ -10110,7 +10119,7 @@ \begin{itemdescr} \pnum \returns -\tcode{x.zone_ == y.zone_ \&\& x.tp_ == y.tp_}. +\tcode{x.\exposid{zone_} == y.\exposid{zone_} \&\& x.\exposid{tp_} == y.\exposid{tp_}}. \end{itemdescr} \indexlibrarymember{operator<<}{zoned_time}% @@ -10126,7 +10135,7 @@ \effects Equivalent to: \begin{codeblock} -return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@("{:L%F %T %Z}"), t); +return os << format(os.getloc(), @\exposid{STATICALLY-WIDEN}@("{:L%F %T %Z}"), t); \end{codeblock} \end{itemdescr} @@ -10783,15 +10792,21 @@ the locale's alternate time representation. \\ \rowsep \tcode{\%y} & -The last two decimal digits of the year. -If the result is a single digit it is prefixed by \tcode{0}. +The last two decimal digits of the year, +regardless of the sign of the year. +If the result is a single digit, it is prefixed by \tcode{0}. The modified command \tcode{\%Oy} produces the locale's alternative representation. The modified command \tcode{\%Ey} produces the locale's alternative representation of offset from \tcode{\%EC} (year only). +\begin{tailexample} +\begin{codeblock} +cout << format("{:%C %y}", -1976y); // prints \tcode{-20 76} +\end{codeblock} +\end{tailexample} \\ \rowsep \tcode{\%Y} & The year as a decimal number. -If the result is less than four digits +If the result is less than four digits, it is left-padded with \tcode{0} to four digits. The modified command \tcode{\%EY} produces the locale's alternative full year representation. @@ -10816,7 +10831,8 @@ \end{LongTable} \pnum -If the \fmtgrammarterm{chrono-specs} is omitted, +Unless otherwise specified, +if the \fmtgrammarterm{chrono-specs} is omitted, the chrono object is formatted as if by streaming it to \tcode{basic_ostring\-stream os} with the formatting locale imbued @@ -10960,17 +10976,17 @@ \indexlibrary{local-time-format-t@\exposid{local-time-format-t}}% \begin{codeblock} -template struct @\placeholder{local-time-format-t}@ { // \expos - local_time time; // \expos - const string* abbrev; // \expos - const seconds* offset_sec; // \expos +template struct @\exposid{local-time-format-t}@ { // \expos + local_time @\exposid{time_}@; // \expos + const string* @\exposid{abbrev_}@; // \expos + const seconds* @\exposid{offset-sec}@; // \expos }; \end{codeblock} \indexlibraryglobal{local_time_format}% \begin{itemdecl} template - @\placeholder{local-time-format-t}@ + @\exposid{local-time-format-t}@ local_time_format(local_time time, const string* abbrev = nullptr, const seconds* offset_sec = nullptr); \end{itemdecl} @@ -10984,7 +11000,7 @@ \indexlibrary{\idxcode{formatter}!specializations!chrono::local-time-format-t@\tcode{chrono::\exposid{local-time-format-t}}}% \begin{itemdecl} template - struct formatter, charT>; + struct formatter, charT>; \end{itemdecl} \begin{itemdescr} @@ -10998,16 +11014,16 @@ 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. +it is replaced with \tcode{*f.\exposid{abbrev_}} +if \tcode{f.\exposid{abbrev_}} is not a null pointer value. If \tcode{\%Z} is used -and \tcode{f.abbrev} is a null pointer value, +and \tcode{f.\exposid{abbrev_}} is a null pointer value, an exception of type \tcode{format_error} is thrown. If \tcode{\%z} (or a modified variant of \tcode{\%z}) is used, -it is formatted with the value of \tcode{*f.offset_sec} -if \tcode{f.offset_sec} is not a null pointer value. +it is formatted with the value of \tcode{*f.\exposid{offset-sec}} +if \tcode{f.\exposid{offset-sec}} is not a null pointer value. If \tcode{\%z} (or a modified variant of \tcode{\%z}) is used -and \tcode{f.offset_sec} is a null pointer value, +and \tcode{f.\exposid{offset-sec}} is a null pointer value, then an exception of type \tcode{format_error} is thrown. \end{itemdescr} @@ -11015,7 +11031,7 @@ \begin{codeblock} template struct formatter, charT> - : formatter>, charT> { + : formatter>, charT> { template typename FormatContext::iterator format(const chrono::zoned_time& tp, FormatContext& ctx) const; @@ -11035,7 +11051,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} @@ -11459,7 +11475,8 @@ The modified command \tcode{\%EX} interprets the locale's alternate time representation. \\ \rowsep \tcode{\%y} & -The last two decimal digits of the year. +The last two decimal digits of the year, +regardless of the sign of the year. If the century is not otherwise specified (e.g., with \tcode{\%C}), values in the range \crange{69}{99} @@ -11472,6 +11489,12 @@ Leading zeroes are permitted but not required. The modified commands \tcode{\%Ey} and \tcode{\%Oy} interpret the locale's alternative representation. +\begin{tailexample} +\begin{codeblock} +year y; +istringstream{"-20 76"} >> parse("%3C %y", y); // \tcode{y == -1976y} is \tcode{true} +\end{codeblock} +\end{tailexample} \\ \rowsep \tcode{\%Y} & The year as a decimal number. @@ -11606,28 +11629,32 @@ \rSec1[ctime.syn]{Header \tcode{} synopsis} \indexheader{ctime}% -\indexlibraryglobal{CLOCKS_PER_SEC}% -\indexlibraryglobal{NULL}% -\indexlibraryglobal{TIME_UTC}% -\indexlibraryglobal{asctime}% \indexlibraryglobal{clock_t}% \indexlibraryglobal{clock}% -\indexlibraryglobal{ctime}% \indexlibraryglobal{difftime}% \indexlibraryglobal{gmtime}% +\indexlibraryglobal{gmtime_r}% \indexlibraryglobal{localtime}% +\indexlibraryglobal{localtime_r}% \indexlibraryglobal{mktime}% \indexlibraryglobal{size_t}% \indexlibraryglobal{strftime}% \indexlibraryglobal{time_t}% \indexlibraryglobal{timespec_get}% +\indexlibraryglobal{timespec_getres}% \indexlibraryglobal{timespec}% \indexlibraryglobal{time}% +\indexlibraryglobal{timegm}% \indexlibraryglobal{tm}% \begin{codeblock} -#define NULL @\textit{see \ref{support.types.nullptr}}@ -#define CLOCKS_PER_SEC @\seebelow@ -#define TIME_UTC @\seebelow@ +#define @\libmacro{__STDC_VERSION_TIME_H__}@ 202311L + +#define @\libmacro{NULL}@ @\textit{see \ref{support.types.nullptr}}@ +#define @\libmacro{CLOCKS_PER_SEC}@ @\seebelow@ +#define @\libmacro{TIME_UTC}@ @\seebelow@ +#define @\libmacro{TIME_MONOTONIC}@ @\seebelow@ // optional +#define @\libmacro{TIME_ACTIVE}@ @\seebelow@ // optional +#define @\libmacro{TIME_THREAD_ACTIVE}@ @\seebelow@ // optional namespace std { using size_t = @\textit{see \ref{support.types.layout}}@; @@ -11640,12 +11667,14 @@ clock_t clock(); double difftime(time_t time1, time_t time0); time_t mktime(tm* timeptr); + time_t timegm(tm* timeptr); time_t time(time_t* timer); int timespec_get(timespec* ts, int base); - char* asctime(const tm* timeptr); - char* ctime(const time_t* timer); + int timespec_getres(timespec* ts, int base); tm* gmtime(const time_t* timer); + tm* gmtime_r(const time_t* timer, tm* buf); tm* localtime(const time_t* timer); + tm* localtime_r(const time_t* timer, tm* buf); size_t strftime(char* s, size_t maxsize, const char* format, const tm* timeptr); } \end{codeblock} @@ -11660,8 +11689,8 @@ \end{footnote} \pnum -The functions \tcode{asctime}, \tcode{ctime}, \tcode{gmtime}, and +The functions \tcode{gmtime} and \tcode{localtime} are not required to avoid data races\iref{res.on.data.races}. -\xrefc{7.27} +\xrefc{7.29} diff --git a/source/uax31.tex b/source/uax31.tex index ee0bb9c2a1..6574a48637 100644 --- a/source/uax31.tex +++ b/source/uax31.tex @@ -18,27 +18,31 @@ \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. -For \Cpp{} we add the character \unicode{005f}{low line}, or \tcode{_}, -to the set of permitted \tcode{} characters, -the \tcode{} set is empty, and -the \tcode{} characters are unmodified. +\UAX{31} also specifies some standard profiles, +including the Mathematical Compatibility Notation profile. +For \Cpp{} we apply the Mathematical Compatibility Notation profile, +and we add the character \unicode{005f}{low line}, or \tcode{_}, +to the set of permitted \tcode{} characters. +The \tcode{} set is empty. In the grammar used in \UAX{31}, this is -\begin{codeblock} +\begin{outputblock} := * - := XID_Start + @\textrm{\ucode{005f}}@ - := + XID_Continue -\end{codeblock} + := XID_Start + ID_Compat_Math_Start + @\textrm{\ucode{005f}}@ + := + XID_Continue + ID_Compat_Math_Continue +\end{outputblock} \pnum This is described in the \Cpp{} grammar in \ref{lex.name}, @@ -46,17 +50,6 @@ \grammarterm{identifier-start} or \grammarterm{identifier} followed by \grammarterm{identifier-continue}. -\rSec2[uaxid.def.rfmt]{R1a Restricted format characters} - -\pnum -If an implementation of \UAX{31} wishes to allow format characters -such as \unicode{200d}{zero width joiner} or \unicode{200c}{zero width non-joiner} -it must define a profile allowing them, or -describe precisely which combinations are permitted. - -\pnum -\Cpp{} does not allow format characters in identifiers, so this does not apply. - \rSec2[uaxid.def.stable]{R1b Stable identifiers} \pnum diff --git a/source/ub.tex b/source/ub.tex new file mode 100644 index 0000000000..8267694f37 --- /dev/null +++ b/source/ub.tex @@ -0,0 +1,2004 @@ +%!TEX root = std.tex +\infannex{ub}{Core undefined behavior} + +\rSec1[ub.general]{General} + +\pnum +This Annex documents +undefined behavior explicitly called out in +\ref{intro} through \ref{\lastcorechapter} +using the following phrases: +\begin{itemize} +\item is undefined +\item the behavior is undefined +\item the behavior of the program is undefined +\item has undefined behavior +\item have undefined behavior +\item result has undefined behavior +\item results in undefined behavior +\end{itemize} +Undefined behavior that is implicit is not covered by this annex. +Each entry contains +a title, +a cross-reference, +a summary of the circumstances, +and code examples. +The code examples are not intended +to exhaustively cover all possible ways of invoking that case. + +\rSec1[ub.basic]{\ref*{basic}: Basics} + +\ubdescription{intro.object.implicit.create} + +\pnum +For each operation that is specified as implicitly creating objects, +that operation implicitly creates and starts the lifetime +of zero or more objects of implicit-lifetime types\iref{basic.types} +in its specified region of storage +if doing so would result in the program having defined behavior. +If no such set of objects would give the program defined behavior, +the behavior of the program is undefined. + +\pnum +\begin{example} +\begin{codeblock} +void f() +{ + void *p = malloc(sizeof(int) + sizeof(float)); + *reinterpret_cast(p) = 0; + *reinterpret_cast(p) = 0.0f; // undefined behavior, cannot create + // both \tcode{int} and \tcode{float} in same place +} +\end{codeblock} +\end{example} + +\ubdescription{intro.object.implicit.pointer} + +\pnum +After implicitly creating objects within a specified region of storage, +some operations are described as producing a pointer to a +suitable created object\iref{basic.types}. +These operations select one of the implicitly-created objects +whose address is the address of the start of the region of storage, +and produce a pointer value that points to that object, +if that value would result in the program having defined behavior. +If no such pointer value would give the program defined behavior, +the behavior of the program is undefined. + +\pnum +\begin{example} +\begin{codeblock} +#include +struct X { + int a, b; + ~X() = delete; // deleted destructor makes \tcode{X} a non-implicit-lifetime class +}; + +X* make_x() { + X* p = (X*)std::malloc(sizeof(struct X)); // Cannot implicitly create an object because \tcode{X} + // is not an implicit-lifetime class. + p->a = 1; // undefined behavior, no set of objects give us defined behavior + return p; +} +\end{codeblock} +\end{example} +\begin{example} +\begin{codeblock} +#include + +struct X { + int a; +}; + +struct Y { + int x; +}; + +Y* make_y() { + X* p1 = (X*)std::malloc(sizeof(struct X)); // object \#1 + p1->a = 1; + Y* p2 = (Y*)p1; + p2->x = 2; // undefined behavior, \tcode{p2} points to an in-lifetime object of type \tcode{X}, + // which is not similar to \tcode{Y}\iref{expr.ref} + return p2; +} +\end{codeblock} +\end{example} + +\ubdescription{basic.align.object.alignment} + +\pnum +All instances of a type must be created in storage +that meets the alignment requirement of that type. + +\pnum +\begin{example} +\begin{codeblock} +struct alignas(4) S {}; + +void make_misaligned() +{ + alignas(S) char s[sizeof(S) + 1]; + new (&s+1) S(); // undefined behavior, \tcode{\&s+1} will yield a pointer to + // a \tcode{char} which is $1$ byte away from an address with + // an alignment of $4$ and so cannot have an alignment of $4$ +} +\end{codeblock} +\end{example} + +\ubdescription{lifetime.outside.pointer.delete} + +\pnum +For a pointer pointing to an object outside of its lifetime, +behavior is undefined if the object will be or was of a class type +with a non-trivial destructor +and the pointer is used as the operand of a \grammarterm{delete-expression}. + +\pnum +\begin{example} +\begin{codeblock} +struct S { + float f = 0; + ~S() {} +}; + +void f() { + S* p = new S; + p->~S(); + delete p; // undefined behavior, operand of \tcode{delete}, lifetime has ended and \tcode{S} + // has a non-trivial destructor +} +\end{codeblock} +\end{example} + +\ubdescription{lifetime.outside.pointer.member} + +\pnum +For a pointer pointing to an object outside of its lifetime, behavior is +undefined if the pointer is used to access a non-static data member or call a +non-static member function of the object. + +\pnum +\begin{example} +\begin{codeblock} +struct S { + float f = 0; +}; + +float f() { + S s; + S* p = &s; + s.~S(); + return p->f; // undefined behavior, accessing non-static data member after end of lifetime +} +\end{codeblock} +\end{example} + +\ubdescription{lifetime.outside.pointer.virtual} + +\pnum +For a pointer pointing to an object outside of its lifetime, behavior is +undefined if the pointer is implicitly converted\iref{conv.ptr} to a pointer +to a virtual base class (or base class of a virtual base class). + +\pnum +\begin{example} +\begin{codeblock} +struct B {}; +struct D : virtual B {}; +void f() { + D d; + D* p = &d; + d.~D(); + B* b = p; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{lifetime.outside.pointer.dynamic.cast} + +\pnum +For a pointer pointing to an object outside of its lifetime, behavior is +undefined if the pointer is used as the operand of a +\tcode{dynamic_cast}\iref{expr.dynamic.cast}. + +\pnum +\begin{example} +\begin{codeblock} +struct B { virtual ~B() = default; }; +struct D : B {}; +void f() +{ + D d; + B* bp = &d; + d.~D(); + D* dp = dynamic_cast(bp); // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{lifetime.outside.glvalue.access} + +\pnum +Behavior is undefined if a glvalue referring to an object +outside of its lifetime is used to access the object. + +\pnum +\begin{example} +\begin{codeblock} +void f() { + int x = int{10}; + using T = int; + x.~T(); + int y = x; // undefined behavior, glvalue used to access the + // object after the lifetime has ended +} +\end{codeblock} +\end{example} + +\ubdescription{lifetime.outside.glvalue.member} + +\pnum +Behavior is undefined if a glvalue referring to an object +outside of its lifetime is used to call +a non-static member function of the object. + +\pnum +\begin{example} +\begin{codeblock} +struct A { + void f() {} +}; + +void f() { + A a; + a.~A(); + a.f(); // undefined behavior, glvalue used to access a non-static member + // function after the lifetime has ended +} +\end{codeblock} +\end{example} + +\ubdescription{lifetime.outside.glvalue.virtual} + +\pnum +Behavior is undefined if a glvalue referring to an object +outside of its lifetime is bound to a reference to a virtual base class. + +\pnum +\begin{example} +\begin{codeblock} +struct B {}; +struct D : virtual B { +}; + +void f() { + D d; + d.~D(); + B& b = d; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{lifetime.outside.glvalue.dynamic.cast} + +\pnum +Behavior is undefined if a glvalue referring to an object outside of its +lifetime is used as the operand of a +\keyword{dynamic_cast} or as the operand of \keyword{typeid}. + +\pnum +\begin{example} +\begin{codeblock} +struct B { virtual ~B(); }; +struct D : virtual B {}; + +void f() { + D d; + B& br = d; + d.~D(); + D& dr = dynamic_cast(br); // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{original.type.implicit.destructor} + +\pnum +The behavior is undefined if +a non-trivial implicit destructor call +occurs when the type of the object inhabiting the associated storage +is not the original type associated with that storage. + +\pnum +\begin{example} +\begin{codeblock} +class T {}; + +struct B { + ~B(); +}; + +void h() { + B b; + new (&b) T; +} // undefined behavior at block exit +\end{codeblock} +\end{example} + +\ubdescription{creating.within.const.complete.obj} + +\pnum +Creating a new object within the storage that a const complete object +with static, thread, or automatic storage duration occupies, +or within the storage that such a const object used to occupy +before its lifetime ended, results in undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +struct B { + B(); + ~B(); +}; + +const B b; + +void h() { + b.~B(); + new (const_cast(&b)) const B; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{basic.indet.value} + +\pnum +When the result of an evaluation is an indeterminate value +(but not just an erroneous value) the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +void g() { + int x [[ indeterminate ]]; + int y = x; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{basic.stc.alloc.dealloc.constraint} + +\pnum +If the behavior of an allocation or deallocation function +does not satisfy the semantic constraints specified +in~\ref{basic.stc.dynamic.allocation} +and~\ref{basic.stc.dynamic.deallocation}, +the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +#include +void* operator new(std::size_t sz) { + if (sz == 0) + return nullptr; // undefined behavior, should return non-null pointer + + return std::malloc(1); // undefined behavior, if successful should return allocation with + // length in bytes is at least as large as the requested size +} +void operator delete(void* ptr) noexcept { + throw 0; // undefined behavior, terminates by throwing an exception +} +\end{codeblock} +\end{example} + +\ubdescription{basic.stc.alloc.zero.dereference} + +\pnum +The pointer returned when invoking an allocation function with a size of zero +cannot be dereferenced. + +\pnum +\begin{example} +\begin{codeblock} +void test() +{ + char* c = static_cast(operator new(0z)); + c[0] = 'X'; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{basic.compound.invalid.pointer} + +\pnum +Indirection or the invocation of a deallocation function +with a pointer value referencing storage that has been freed +has undefined behavior. +(Most other uses of such a pointer have implementation-defined behavior.) + +\pnum +\begin{example} +\begin{codeblock} +void f() +{ + int *x = new int{5}; + delete x; + int y = *x; // undefined behavior + delete x; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{intro.execution.unsequenced.modification} + +\pnum +If a side effect on a memory location\iref{intro.memory} +is unsequenced relative to either another side effect +on the same memory location +or 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. + +\pnum +\begin{example} +\begin{codeblock} +void g(int i) { + i = 7, i++, i++; // \tcode{i} becomes 9 + + 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 +} +\end{codeblock} +\end{example} + +\ubdescription{intro.races.data} + +\pnum +The execution of a program contains a data race +if it contains two potentially concurrent conflicting actions, +at least one of which is not atomic, +and neither happens before the other, +except for the special case for signal handlers +described in~\ref{intro.races}. +Any such data race results in undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +int count = 0; +auto f = [&] { count++; }; +std::thread t1{f}, t2{f}, t3{f}; +// undefined behavior, \tcode{t1}, \tcode{t2} and \tcode{t3} have a data race on access of variable \tcode{count} +\end{codeblock} +\end{example} + +\ubdescription{intro.progress.stops} + +\pnum +The behavior is undefined if a thread of execution +that has not terminated stops making execution steps. + +\pnum +\begin{example} +\begin{codeblock} +bool stop() { return false; } + +void busy_wait_thread() { + while (!stop()); // undefined behavior, thread makes no progress but the loop +} // is not trivial because \tcode{stop()} is not a constant expression + +int main() { + std::thread t(busy_wait_thread); + t.join(); +} +\end{codeblock} +\end{example} + +\ubdescription{basic.start.main.exit.during.destruction} + +\pnum +If \tcode{std::exit} is called to +end a program during the destruction of an object with static or thread storage duration, the program has +undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +#include + +struct Exiter { + ~Exiter() { std::exit(0); } +}; + +Exiter ex; + +int main() {} +// undefined behavior when destructor of static variable \tcode{ex} is called it will call \tcode{std::exit} +\end{codeblock} +\end{example} + +\ubdescription{basic.start.term.use.after.destruction} + +\pnum +If a function contains a block-scope object of static +or thread storage duration that has been destroyed +and the function is called +during the destruction of an object with static or thread storage duration, +the program has undefined behavior if the flow of control +passes through the definition of the previously destroyed block-scope object. +Likewise, the behavior is undefined if the block-scope object +is used indirectly (i.e., through a pointer) after its destruction. + +\pnum +\begin{example} +\begin{codeblock} +struct A {}; +void f() { + static A a; +} + +struct B { + B() { f(); } +}; +struct C { + ~C() { f(); } +}; + +C c; +B b; // call to \tcode{f()} in constructor begins lifetime of \tcode{a} + +int main() {} +// undefined behavior, static objects are destructed in reverse order, in this case \tcode{a} then \tcode{b} and +// finally \tcode{c}. When the destructor of \tcode{c} is called, it calls \tcode{f()} which passes through the definition of +// previously destroyed block-scope object +\end{codeblock} +\end{example} + +\rSec1[ub.expr]{\ref*{expr}: Expressions} + +\ubdescription{expr.expr.eval} + +\pnum +If during the evaluation of an expression, +the result is not mathematically defined +or not in the range of representable values for its type, +the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +#include +int main() { + // Assuming $32$-bit \tcode{int}, the range of values is: $-2,147,483,648$ to $2,147,483,647$. + int x1 = std::numeric_limits::max() + 1; + // undefined behavior, $2,147,483,647 + 1$ is not representable as an \tcode{int} + int x2 = std::numeric_limits::min() / -1; + // undefined behavior, $-2,147,483,648 / -1$ is not representable as an \tcode{int} +} +\end{codeblock} +\end{example} + +\ubdescription{expr.basic.lvalue.strict.aliasing.violation} + +\pnum +If a program attempts to access\iref{defns.access} the stored value of an object +whose dynamic type is $T$ through a glvalue +whose type is not similar\iref{conv.qual} to $T$ +(or its corresponding signed or unsigned types) +the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +int foo(float* f, int* i) { + *i = 1; + *f = 0.f; // undefined behavior, glvalue is not similar to \tcode{int} + + return *i; +} + +int main() { + int x = 0; + + x = foo(reinterpret_cast(&x), &x); +} +\end{codeblock} +\end{example} + +\ubdescription{expr.basic.lvalue.union.initialization} + +\pnum +If a program invokes a defaulted copy/move constructor or +defaulted copy/move assignment operator of a union +with an argument that is not an object of a similar type +within its lifetime, the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +union U { int x; }; +void f() +{ + char u[sizeof(U)]; + U o = reinterpret_cast(u); // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{expr.type.reference.lifetime} + +\pnum +Evaluating a reference when an equivalent use of a pointer denoting the same object +would be invalid has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +void g() +{ + int* ip = new int(5); + int& i = *ip; + delete ip; + i; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{conv.lval.valid.representation} + +\pnum +Performing an +lvalue-to-rvalue conversion +on an object whose +value representation +is not valid for its type +has undefined behavior. + +\pnum +\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} + +\ubdescription{conv.double.out.of.range} + +\pnum +Converting a floating-point value to a type +that cannot represent the value has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +#include + +int main() { + // Assuming 32-bit \tcode{int}, 32-bit \tcode{float} and 64-bit \tcode{double}. + double d2 = std::numeric_limits::max(); + float f = d2; // undefined behavior on systems where the range of representable values + // of \tcode{float} is \tcode{[-max,+max]}; on systems where the range of representable + // values is \tcode{[-inf,+inf]} this would not be undefined behavior + int i = d2; // undefined behavior, the max value of \tcode{double} is not representable as \tcode{int} +} +\end{codeblock} +\end{example} + +\ubdescription{conv.fpint.float.not.represented} + +\pnum +When converting a floating-point value to an integer type, if +the value is not representable in the destination type, the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +#include + +int main() { + // Assuming $32$-bit \tcode{int}, the range of values is: $-2,147,483,648$ to + // $2,147,483,647$. Assuming $32$-bit \tcode{float} and $64$-bit \tcode{double}. + double d = (double)std::numeric_limits::max() + 1; + int x1 = d; // undefined behavior, $2,147,483,647 + 1$ is not representable as \tcode{int} +} +\end{codeblock} +\end{example} + +\ubdescription{conv.fpint.int.not.represented} + +\pnum +When converting a value of integer or unscoped enumeration type +to a floating-point type, +if the value is not representable in the destination type +the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +int main() { + unsigned long long x2 = -1; + float f = x2; // undefined behavior on systems where \tcode{f} does not include + // a representation for infinity and the maximum value for \tcode{float} + // is smaller than the maximum value for \tcode{unsigned long long} +} +\end{codeblock} +\end{example} + +\ubdescription{conv.ptr.virtual.base} + +\pnum +Converting +a pointer to a derived class \tcode{D} +to +a pointer to a virtual base class \tcode{B} +that does not point to +a valid object +within its lifetime +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +struct B {}; +struct D : virtual B {}; +void f() +{ + D ds[1]; + B* b = &ds[1]; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{conv.member.missing.member} + +\pnum +The conversion of +a pointer to a member of a base class +to a pointer to member of a derived class +that could not contain that member +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +struct B {}; +struct D1 : B { int d1; }; +struct D2 : B {}; +void f() +{ + int (D1::*pd1) = &D1::d1; + int (B::*pb) = static_cast(pd1); + int (D2::*pd2) = pb; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{expr.call.different.type} + +\pnum +Calling a function through an expression whose +function type is not call-compatible with +the function type of the called +function's definition results in undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +using f_float = int (*)(float); +using f_int = int (*)(int); + +int f1(float) { return 10; } + +int f2(int) { return 20; } + +int main() { + return reinterpret_cast(f1)(20); // undefined behavior, the function type of the expression + // is different from the called function's definition +} +\end{codeblock} +\end{example} + +\ubdescription{expr.ref.member.not.similar} + +\pnum +In a class member access \tcode{E1.E2}, +where \tcode{E2} is a non-static member, +the behavior is undefined +if \tcode{E1} refers to an object +whose type is not similar +to the type of the expression \tcode{E1}. + +\pnum +\begin{example} +\begin{codeblock} +struct A { int i; }; +struct B { int j; }; +A a; +int x = reinterpret_cast(a).j; // undefined behavior +\end{codeblock} +\end{example} + +\ubdescription{expr.dynamic.cast.pointer.lifetime} + +\pnum +Evaluating a \keyword{dynamic_cast} on a non-null pointer +that points to an object (of polymorphic type) of the wrong type +or to an object not within its lifetime +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +struct B { virtual ~B(); }; +void f() { + B bs[1]; + B* dp = dynamic_cast(bs+1); // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{expr.dynamic.cast.glvalue.lifetime} + +\pnum +Evaluating a \keyword{dynamic_cast} on a reference +that denotes an object (of polymorphic type) +of a type that is not similar to the referenced type +or an object not within its lifetime +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +struct B { virtual ~B(); }; +void f() { + B bs[1]; + B& dr = dynamic_cast(bs[1]); // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{expr.static.cast.base.class} + +\pnum +A glvalue of type \tcode{B} +can be cast to the type ``reference to \tcode{D}'' +if \tcode{B} is a base class of \tcode{D}, +otherwise the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +struct B {}; +struct D1 : B {}; +struct D2 : B {}; + +void f() { + D1 d; + B &b = d; + static_cast(b); // undefined behavior, base class object of type \tcode{D1} not \tcode{D2} +} +\end{codeblock} +\end{example} + +\ubdescription{expr.static.cast.enum.outside.range} + +\pnum +If the enumeration type does not have a fixed underlying type, +the value is unchanged if the original value +is within the range of the enumeration values\iref{dcl.enum}, +and otherwise, the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +enum A { e1 = 1, e2 }; + +void f() { + enum A a = static_cast(4); // undefined behavior, $4$ is not within the range of enumeration values +} +\end{codeblock} +\end{example} + +\ubdescription{expr.static.cast.fp.outside.range} + +\pnum +An explicit conversion of a floating-point value +that is outside the range of the target type +has undefined behavior. + +\pnum +\begin{example} +If \tcode{float} does not adhere to \IsoFloatUndated{} +and cannot represent positive infinity, +a sufficiently large \tcode{double} value will be +outside the (finite) range of \tcode{float}. +\begin{codeblock} +void f() { + double d = FLT_MAX; + d *= 16; + float f = static_cast(d); // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{expr.static.cast.downcast.wrong.derived.type} + +\pnum +Casting from a pointer to a base class to a pointer to a derived class +when there is no enclosing object of that derived class at the +specified location has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +struct B {}; +struct D1 : B {}; +struct D2 : B {}; + +void f() { + B *bp = new D1; + static_cast(bp); // undefined behavior, base class object of type \tcode{D1} not \tcode{D2} +} +\end{codeblock} +\end{example} + +\ubdescription{expr.static.cast.does.not.contain.original.member} + +\pnum +A +pointer to member of derived class \tcode{D} +can be cast to +a pointer to member of base class \tcode{B} +(with certain restrictions on \cv{} qualifiers) +as long as \tcode{B} contains the original member, +or is a base or derived class of the class +containing the original member; +otherwise the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +struct A { + char c; +}; + +struct B { + int i; +}; + +struct D : A, B {}; + +int main() { + char D::*p1 = &D::c; + char B::*p2 = static_cast(p1); // undefined behavior, \tcode{B} does not contain the + // original member \tcode{c} +} +\end{codeblock} +\end{example} + +\ubdescription{expr.unary.dereference} + +\pnum +Dereferencing a pointer that does not point to an object or function +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +int f() +{ + int *p = nullptr; + return *p; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{expr.new.non.allocating.null} + +\pnum +If the allocation function is a non-allocating form\iref{new.delete.placement} +that returns null, the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +#include +[[nodiscard]] void* operator new(std::size_t size, void* ptr) noexcept { + return nullptr; // undefined behavior, should return non-null pointer +} +\end{codeblock} +\end{example} +\begin{example} +\begin{codeblock} +#include + +struct A { + int x; +}; + +int main() { + char *p = nullptr; + A *a = new (p) A; // undefined behavior, non-allocating new returning nullptr +} +\end{codeblock} +\end{example} + +\ubdescription{expr.delete.mismatch} + +\pnum +Using array delete on the result of a single object new expression +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +int* x = new int; +delete[] x; // undefined behavior, allocated using single object new expression +\end{codeblock} +\end{example} + +\ubdescription{expr.delete.array.mismatch} + +\pnum +Using single object delete on the result of an array new expression has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +int* x = new int[10]; +delete x; // undefined behavior, allocated using array new expression +\end{codeblock} +\end{example} + +\ubdescription{expr.delete.dynamic.type.differ} + +\pnum +If the static type of the object to be deleted +is different from its dynamic type +and the selected deallocation function +is not a destroying operator delete, +the static type shall be a base class +of the dynamic type of the object to be deleted +and the static type shall have a virtual destructor +or the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +struct B { + int a; +}; + +struct D : public B { + int b; +}; + +void f() { + B* b = new D; + delete b; // undefined behavior, no virtual destructor +} +\end{codeblock} +\end{example} + +\ubdescription{expr.delete.dynamic.array.dynamic.type.differ} + +\pnum +In an array delete expression, +if the dynamic type of the object to be deleted differs +from its static type, the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +struct B { + virtual ~B(); + void operator delete[](void*, std::size_t); +}; + +struct D : B { + void operator delete[](void*, std::size_t); +}; + +void f(int i) { + D* dp = new D[i]; + delete[] dp; // uses \tcode{D::operator delete[](void*, std::size_t)} + B* bp = new D[i]; + delete[] bp; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{expr.mptr.oper.not.contain.member} + +\pnum +Abbreviating \grammarterm{pm-expression}.*\grammarterm{cast-expression} +as \tcode{E1.*E2}, \tcode{E1} is called the object expression. +If the dynamic type of \tcode{E1} does not contain the member +to which \tcode{E2} refers, the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +struct B {}; +struct D : B { + int x; +}; + +void f() { + B *b = new B; + D *d = static_cast(b); + int D::*p = &D::x; + (*d).*p = 1; // undefined behavior, dynamic type \tcode{B} does not contain \tcode{x} +} +\end{codeblock} +\end{example} + +\ubdescription{expr.mptr.oper.member.func.null} + +\pnum +If the second operand in a \tcode{.*} expression is the null +member pointer value\iref{conv.mem}, the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +struct S { + int f(); +}; + +void f() { + S cs; + int (S::*pm)() = nullptr; + (cs.*pm)(); // undefined behavior, the second operand is null +} +\end{codeblock} +\end{example} + +\ubdescription{expr.mul.div.by.zero} + +\pnum +Division by zero has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +int main() { + int x = 1 / 0; // undefined behavior, division by zero + double d = 1.0 / 0.0; // undefined behavior on systems where the range of + // representable values of \tcode{double} is \tcode{[-max,+max]}, on systems where + // representable values is \tcode{[-inf,+inf]} this would not be undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{expr.mul.representable.type.result} + +\pnum +If the +quotient \tcode{a/b} +is representable in the type of the result, +\tcode{(a/b)*b + a\%b} +is equal to \tcode{a}; +otherwise, the behavior of both \tcode{a/b} and \tcode{a\%b} is undefined. + +\pnum +\begin{example} +\begin{codeblock} +#include + +int main() { + int x = std::numeric_limits::min() / -1; + // Assuming \tcode{LP64} $-2,147,483,648$ which when divided by $-1$ + // gives us $2,147,483,648$ which is not representable by \tcode{int}. +} +\end{codeblock} +\end{example} + +\ubdescription{expr.add.out.of.bounds} + +\pnum +Creating an out of bounds pointer has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +static const int arrs[10]{}; + +int main() { + const int *y = arrs + 11; // undefined behavior, creating an out of bounds pointer +} +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +static const int arrs[10][10]{}; + +int main() { + const int(*y)[10] = arrs + 11; // undefined behavior, creating an out of bounds pointer +} +\end{codeblock} +\end{example} + +\ubdescription{expr.add.sub.diff.pointers} + +\pnum +Subtracting pointers that are not part of the same array +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +#include +void f() { + int x[2]; + int y[2]; + int* p1 = x; + int* p2 = y; + std::ptrdiff_t off = p1 - p2; // undefined behavior, \tcode{p1} and \tcode{p2} point to different arrays +} +\end{codeblock} +\end{example} + +\ubdescription{expr.add.not.similar} + +\pnum +For addition or subtraction of two expressions $P$ and $Q$, +if $P$ or $Q$ have type ``pointer to \cv{}~\tcode{T}'', where \tcode{T} and the array +element type are not similar\iref{conv.rval}, the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +struct S { int i; }; +struct T : S { double d; }; + +void f(const S* s, std::size_t count) { + for (const S* end = s + count; s != end; ++s) { + // undefined behavior, \tcode{T} is not similar to \tcode{S} but \tcode{s} points to a \tcode{T[]} + @\commentellip@ + } +} + +int main() { + T test[5]; + f(test, 5); +} +\end{codeblock} +\end{example} + +\ubdescription{expr.shift.neg.and.width} + +\pnum +Shifting by a negative amount or equal or greater than +the bit-width of a type has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +int y = 1 << -1; // undefined behavior, shift is negative + +static_assert(sizeof(int) == 4 && CHAR_BIT == 8); +int y1 = 1 << 32; // undefined behavior, shift is equal to the bit width of \tcode{int} +int y2 = 1 >> 32; // undefined behavior, shift is equal to the bit width of \tcode{int} +\end{codeblock} +\end{example} + +\ubdescription{expr.assign.overlap} + +\pnum +Overlap in the storage between the source and destination +can result in undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +int x = 1; +char* c = reinterpret_cast(&x); +x = *c; // undefined behavior, source overlaps storage of destination +\end{codeblock} +\end{example} + +\rSec1[ub.stmt]{\ref*{stmt}: Statements} + +\ubdescription{stmt.return.flow.off} + +\pnum +Flowing off the end of a function other +than \tcode{main} or a coroutine results in undefined behavior if the return type +is not \cv{}~\keyword{void}. + +\pnum +\begin{example} +\begin{codeblock} +int f(int x) { + if (x) + return 1; + // undefined behavior if \tcode{x} is \tcode{0} +} + +void b() { + int x = f(0); // undefined behavior, using \tcode{0} as an argument will cause \tcode{f(...)} to flow + // off the end without a \tcode{return} statement +} +\end{codeblock} +\end{example} + +\ubdescription{stmt.return.coroutine.flow.off} + +\pnum +Flowing off the end of a coroutine function body +that does not return \tcode{void} has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +#include +#include +#include +#include + +class resumable { + public: + struct promise_type; + using coro_handle = std::coroutine_handle; + resumable(coro_handle handle) : handle_(handle) { assert(handle); } + resumable(resumable&) = delete; + resumable(resumable&&) = delete; + bool resume() { + if (not handle_.done()) + handle_.resume(); + return not handle_.done(); + } + ~resumable() { handle_.destroy(); } + const char* return_val(); + + private: + coro_handle handle_; +}; + +struct resumable::promise_type { + using coro_handle = std::coroutine_handle; + const char* string_; + auto get_return_object() { return coro_handle::from_promise(*this); } + auto initial_suspend() { return std::suspend_always(); } + auto final_suspend() noexcept { return std::suspend_always(); } + void unhandled_exception() { std::terminate(); } + void return_value(const char* string) { string_ = string; } +}; + +const char* resumable::return_val() { + return handle_.promise().string_; +} + +resumable foo() { + std::cout << "Hello" << std::endl; + co_await std::suspend_always(); + // undefined behavior, falling off the end of coroutine that does not return \tcode{void} +} + +int main() { + resumable res = foo(); + while (res.resume()) + ; + std::cout << res.return_val() << std::endl; +} +\end{codeblock} +\end{example} + +\ubdescription{stmt.dcl.local.static.init.recursive} + +\pnum +If control re-enters the declaration recursively while the +variable is being initialized, the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +int foo(int i) { + static int s = foo(2 * i); // undefined behavior, recursive call + return i + 1; +} +\end{codeblock} +\end{example} + +\rSec1[ub.dcl]{\ref*{dcl}: Declarations} + +\ubdescription{dcl.type.cv.modify.const.obj} + +\pnum +Any attempt to modify a const object during its lifetime results in +undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +const int* ciq = new const int(3); // initialized as required +int* iq = const_cast(ciq); // cast required +*iq = 4; // undefined behavior, modifies a const object +\end{codeblock} +\end{example} + +\ubdescription{dcl.type.cv.access.volatile} + +\pnum +If an attempt is made to access an object +defined with a volatile-qualified type +through the use of a non-volatile glvalue, +the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +volatile int x = 0; +int& y = const_cast(x); +std::cout << y; // undefined behavior, accessing volatile through non-volatile glvalue +\end{codeblock} +\end{example} + +\ubdescription{dcl.ref.incompatible.function} + +\pnum +Initializing a reference to a function +with a value that is a function +that is not call-compatible\iref{expr.call} +with the type of the reference +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +void f(float x); +void (&g)(int) = reinterpret_cast(f); // undefined behavior +\end{codeblock} +\end{example} + +\ubdescription{dcl.ref.incompatible.type} + +\pnum +Initializing a reference to an object +with a value that is not +type-accessible\iref{basic.lval} through +the type of the reference +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +float g; +int& i = reinterpret_cast(g); // undefined behavior +\end{codeblock} +\end{example} + +\ubdescription{dcl.ref.uninitialized.reference} + +\pnum +Evaluating a reference +prior to initializing that +reference has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +extern int &ir1; +int i2 = ir1; // undefined behavior, \tcode{ir1} not yet initialized +int i3 = 17; +int &ir1 = i3; +\end{codeblock} +\end{example} + +\ubdescription{dcl.fct.def.coroutine.resume.not.suspended} + +\pnum +Invoking a resumption member function for a coroutine +that is not suspended +results in undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +#include + +struct minig { + struct promise_type { + int val; + minig get_return_object() { return {*this}; } + constexpr suspend_always initial_suspend() noexcept { return {}; } + constexpr suspend_always final_suspend() noexcept { return {}; } + constexpr void return_void() noexcept {} + [[noreturn]] void unhandled_exception() noexcept { throw; } + suspend_always yield_value(int v) noexcept { + val = v; + return {}; + } + }; + using HDL = coroutine_handle; + HDL coro; + minig(promise_type& p) : coro(HDL::from_promise(p)) {} + ~minig() { coro.destroy(); } + bool move_next() { + coro.resume(); + return !coro.done(); + } + int current_value() { return coro.promise().val; } +}; + +static minig f(int n) { + for (int i = 0; i < n; ++i) + co_yield i; +} + +int main() { + auto g = f(10); + int sum = 0; + while (g.move_next()) + sum += g.current_value(); + + g.move_next(); // undefined behavior, will call \tcode{coro.resume()} but \tcode{final_suspend} + // has already returned, even though it returned \tcode{suspend_always} + + return sum; +} +\end{codeblock} +\end{example} + +\ubdescription{dcl.fct.def.coroutine.destroy.not.suspended} + +\pnum +Invoking \tcode{destroy()} on a coroutine that is not suspended has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +#include + +struct minig { + struct promise_type { + int val; + minig get_return_object() { return {*this}; } + constexpr suspend_always initial_suspend() noexcept { return {}; } + constexpr suspend_always final_suspend() noexcept { return {}; } + constexpr void return_void() noexcept {} + [[noreturn]] void unhandled_exception() { throw; } + suspend_always yield_value(int v) noexcept { + val = v; + return {}; + } + }; + using HDL = coroutine_handle; + HDL coro; + minig(promise_type& p) : coro(HDL::from_promise(p)) {} + ~minig() { coro.destroy(); } + bool move_next() { + coro.resume(); + return !coro.done(); + } + int current_value() { + // this coroutine is not suspended therefore a call to destroy has undefined behavior + coro.destroy(); + return coro.promise().val; + } +}; + +static minig f(int n) { + for (int i = 0; i < n; ++i) + co_yield i; +} + +int main() { + auto g = f(10); + int sum = 0; + while (g.move_next()) + sum += g.current_value(); + + return sum; +} +\end{codeblock} +\end{example} + +\ubdescription{dcl.attr.assume.false} + +\pnum +If an assumption expression would not evaluate to true at the point where it +appears the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +int g(int x) { + [[assume(x >= 0)]]; + return x/32; +} + +int f() { + return g(-10); // undefined behavior, assumption in \tcode{g} is \tcode{false} +} +\end{codeblock} +\end{example} + +\ubdescription{dcl.attr.noreturn.eventually.returns} + +\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. + +\pnum +\begin{example} +\begin{codeblock} +[[noreturn]] void f(int i) { + if (i > 0) + throw "positive"; +} + +int main() { + f(0); // undefined behavior, returns from a \tcode{[[noreturn]]} function +} +\end{codeblock} +\end{example} + +\rSec1[ub.class]{\ref*{class}: Classes} + +\ubdescription{class.dtor.no.longer.exists} + +\pnum +Once a destructor is invoked for an object, +the object's lifetime has ended; +the behavior is undefined if the +destructor is invoked for an object whose lifetime has ended. + +\pnum +\begin{example} +\begin{codeblock} +struct A { + ~A() {} +}; + +int main() { + A a; + a.~A(); +} // undefined behavior, lifetime of \tcode{a} already ended before implicit destructor +\end{codeblock} +\end{example} + +\ubdescription{class.abstract.pure.virtual} + +\pnum +Calling a pure virtual function from a constructor or destructor +in an abstract class has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +struct B { + virtual void f() = 0; + B() { + f(); // undefined behavior, \tcode{f} is pure virtual and is being called from the constructor + } +}; + +struct D : B { + void f() override; +}; +\end{codeblock} +\end{example} + +\ubdescription{class.base.init.mem.fun} + +\pnum +Calling a member function +before all the \grammarterm{mem-initializer}s +for base classes have completed +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +class A { +public: + A(int); +}; + +class B : public A { + int j; + +public: + int f(); + B() + : A(f()), // undefined behavior, calls member function but base \tcode{A} not yet initialized + j(f()) {} // defined, bases are all initialized +}; + +class C { +public: + C(int); +}; + +class D : public B, C { + int i; + +public: + D() + : C(f()), // undefined behavior, calls member function but base \tcode{C} not yet initialized + i(f()) {} // defined, bases are all initialized +}; +\end{codeblock} +\end{example} + +\ubdescription{class.cdtor.before.ctor} + +\pnum +For an object with a non-trivial constructor, +referring to any non-static member or base class of the object +before the constructor begins execution results in undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +struct W { + int j; +}; +struct X : public virtual W {}; +struct Y { + int *p; + X x; + Y() : p(&x.j) { // undefined behavior, \tcode{x} is not yet constructed + } +}; +\end{codeblock} +\end{example} + +\ubdescription{class.cdtor.after.dtor} + +\pnum +For an object with a non-trivial destructor, +referring to any non-static member or base class of the object +after the destructor finishes execution +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +struct X { + int i; + ~X(); // non-trivial +}; +X& g() +{ + static X x; + return x; +} +void f() +{ + X* px = &g(); + px->~X(); + int j = px->i; // undefined behavior +} +\end{codeblock} +\end{example} + +\ubdescription{class.cdtor.convert.pointer} + +\pnum +Converting a pointer to a base class of an object, +when construction of that object has not started +or destruction of that object has finished, +has undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +struct A { }; +struct B : virtual A { }; +struct C : B { }; +struct D : virtual A { D(A*); }; +struct X { X(A*); }; + +struct E : C, D, X { + E() : D(this), // undefined behavior, upcast from \tcode{E*} to \tcode{A*} might use path \tcode{E*} $\rightarrow$ \tcode{D*} $\rightarrow$ \tcode{A*} + // but \tcode{D} is not constructed + + // ``\tcode{D((C*)this)}\!'' would be defined, \tcode{E*} $\rightarrow$ \tcode{C*} is defined because \tcode{E()} has started, + // and \tcode{C*} $\rightarrow$ \tcode{A*} is defined because \tcode{C} is fully constructed + + X(this) {} // defined, upon construction of \tcode{X}, \tcode{C/B/D/A} sublattice is fully constructed +}; +\end{codeblock} +\end{example} + +\ubdescription{class.cdtor.form.pointer} + +\pnum +When forming a pointer to +a direct non-static member of a class, +construction must have started +and destruction must not have finished +otherwise the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +struct A { + int i = 0; +}; +struct B { + int *p; + A a; + B() : p(&a.i) {} // undefined behavior +}; +\end{codeblock} +\end{example} + +\ubdescription{class.cdtor.virtual.not.x} + +\pnum +When a virtual function is called directly or indirectly +from a constructor or from a destructor, +including during the construction or destruction +of the class's non-static data members, +and the object to which the call applies +is the object (call it \tcode{x}) under construction or destruction, +the function called is the final overrider in the constructor's or destructor's class +and not one overriding it in a more-derived class. +If the virtual function call uses an explicit class member access\iref{expr.ref} +and the object expression refers to the complete object of \tcode{x} +or one of that object's base class subobjects +but not \tcode{x} or one of its base class subobjects, +the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +struct V { + virtual void f(); + virtual void g(); +}; + +struct A : virtual V { + virtual void f(); +}; + +struct B : virtual V { + virtual void g(); + B(V *, A *); +}; + +struct D : A, B { + virtual void f(); + virtual void g(); + D() : B((A *)this, this) {} +}; + +B::B(V *v, A *a) { + f(); // calls \tcode{V::f}, not \tcode{A::f} + g(); // calls \tcode{B::g}, not \tcode{D::g} + v->g(); // \tcode{v} is base of \tcode{B}, the call is defined, calls \tcode{B::g} + a->f(); // undefined behavior, \tcode{a}'s type not a base of \tcode{B} +} +\end{codeblock} +\end{example} + +\ubdescription{class.cdtor.typeid} + +\pnum +If the operand of \tcode{typeid} refers to +the object under construction or destruction and the static type of the operand is neither the constructor or +destructor's class nor one of its bases, the behavior is undefined. + +\pnum +\begin{example} +\begin{codeblock} +struct V { + virtual void f(); +}; + +struct A : virtual V {}; +struct B : virtual V { + B(V *, A *); +}; + +struct D : A, B { + D() : B((A *)this, this) {} +}; + +B::B(V *v, A *a) { + typeid(*this); // \tcode{std::type_info} for \tcode{B} + typeid(*v); // defined, \tcode{*v} has type \tcode{V}, a base of \tcode{B} yields \tcode{std::type_info} for \tcode{B} + typeid(*a); // undefined behavior, type \tcode{A} not a base of \tcode{B} +} +\end{codeblock} +\end{example} + +\ubdescription{class.cdtor.dynamic.cast} + +\pnum +If the operand of the \tcode{dynamic_cast} +refers to the object under construction or destruction +and the static type of the operand +is not a pointer to or object of +the constructor or destructor's own class or one of its bases, +the \tcode{dynamic_cast} results in undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +struct V { + virtual void f(); +}; + +struct A : virtual V {}; +struct B : virtual V { + B(V *, A *); +}; + +struct D : A, B { + D() : B((A *)this, this) {} +}; + +B::B(V *v, A *a) { + dynamic_cast(v); // defined, \tcode{v} of type \tcode{V*}, \tcode{V} base of \tcode{B} results in \tcode{B*} + dynamic_cast(a); // undefined behavior, \tcode{a} has type \tcode{A*}, \tcode{A} not a base of \tcode{B} +} +\end{codeblock} +\end{example} + +\rSec1[ub.temp]{\ref*{temp}: Templates} + +\ubdescription{temp.inst.inf.recursion} + +\pnum +The result of an infinite recursion in template instantiation is undefined. + +\pnum +\begin{example} +\begin{codeblock} +template +class X { + X *p; // OK + X a; // implicit instantiation of \tcode{X} requires + // the implicit instantiation of \tcode{X} which requires + // the implicit instantiation of \tcode{X} which \ldots +}; + +int main() { + X x; // undefined behavior, instantiation will lead to infinite recursion +} +\end{codeblock} +\end{example} + +\rSec1[ub.except]{\ref*{except}: Exception handling} + +\ubdescription{except.handle.handler.ctor.dtor} + +\pnum +Referring to any non-static member or base class of an object +in the handler for a \grammarterm{function-try-block} +of a constructor or destructor for that object +results in undefined behavior. + +\pnum +\begin{example} +\begin{codeblock} +#include + +struct A { + A() try : x(0 ? 1 : throw 1) { + } catch (int) { + std::cout << "y: " << y << std::endl; // undefined behavior, referring to non-static member \tcode{y} in + // the handler of function-try-block + } + int x; + int y = 42; +}; +\end{codeblock} +\end{example} diff --git a/source/utilities.tex b/source/utilities.tex index 688d827f86..a4b767dce7 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -93,8 +93,22 @@ template constexpr underlying_type_t to_underlying(T value) noexcept; - // \ref{utility.unreachable}, unreachable + // \ref{utility.undefined}, undefined behavior [[noreturn]] void unreachable(); + void observable_checkpoint() noexcept; + + // \ref{const.wrap.class}, class template \tcode{constant_wrapper} + template + struct constant_wrapper; + + template + concept @\defexposconceptnc{constexpr-param}@ = // \expos + requires { typename constant_wrapper; }; + + struct @\exposidnc{cw-operators}@; // \expos + + template + constexpr auto @\libglobal{cw}@ = constant_wrapper{}; // \ref{intseq}, compile-time integer sequences% \indexlibraryglobal{index_sequence}% @@ -113,6 +127,21 @@ template using index_sequence_for = make_index_sequence; + // \ref{intseq.binding}, structured binding support + template struct tuple_size; + template struct tuple_element; + + template + struct tuple_size>; + + template + struct tuple_element>; + template + struct tuple_element>; + + template + constexpr T get(integer_sequence) noexcept; + // \ref{pairs}, class template \tcode{pair} template struct pair; @@ -136,8 +165,8 @@ template constexpr bool operator==(const pair&, const pair&); template - constexpr common_comparison_category_t<@\placeholder{synth-three-way-result}@, - @\placeholder{synth-three-way-result}@> + constexpr common_comparison_category_t<@\exposid{synth-three-way-result}@, + @\exposid{synth-three-way-result}@> operator<=>(const pair&, const pair&); template @@ -150,9 +179,6 @@ constexpr @\seebelow@ make_pair(T1&&, T2&&); // \ref{pair.astuple}, tuple-like access to pair - template struct tuple_size; - template struct tuple_element; - template struct tuple_size>; template struct tuple_element>; @@ -212,14 +238,20 @@ }; template constexpr in_place_index_t in_place_index{}; - // \tcode{nontype} argument tag% -\indexlibraryglobal{nontype_t}% -\indexlibraryglobal{nontype} - template - struct nontype_t { - 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} @@ -249,7 +281,7 @@ \pnum \effects -Exchanges values stored in two locations. +Exchanges the values of \tcode{a} and \tcode{b}. \pnum \remarks @@ -348,19 +380,19 @@ }; void g() { - shared_ptr sp1 = factory(2, 1.414); // error: 2 will not bind to \tcode{int\&} + shared_ptr sp1 = factory(2, 1.414); // error: \tcode{2} will not bind to \tcode{int\&} int i = 2; shared_ptr sp2 = factory(i, 1.414); // OK } \end{codeblock} In the first call to \tcode{factory}, -\tcode{A1} is deduced as \tcode{int}, so 2 is forwarded +\tcode{A1} is deduced as \tcode{int}, so \tcode{2} is forwarded to \tcode{A}'s constructor as an rvalue. In the second call to \tcode{factory}, \tcode{A1} is deduced as \tcode{int\&}, so \tcode{i} is forwarded to \tcode{A}'s constructor as an lvalue. In both cases, \tcode{A2} is deduced as \tcode{double}, so -1.414 is forwarded to \tcode{A}'s constructor as an rvalue. +\tcode{1.414} is forwarded to \tcode{A}'s constructor as an rvalue. \end{example} \end{itemdescr} @@ -530,8 +562,8 @@ \begin{itemdescr} \pnum \mandates -Both \tcode{T} and \tcode{U} are standard integer types or -extended integer types\iref{basic.fundamental}. +Each of \tcode{T} and \tcode{U} is +a signed or unsigned integer type\iref{basic.fundamental}. \pnum \effects @@ -569,8 +601,8 @@ \begin{itemdescr} \pnum \mandates -Both \tcode{T} and \tcode{U} are standard integer types or -extended integer types\iref{basic.fundamental}. +Each of \tcode{T} and \tcode{U} is +a signed or unsigned integer type\iref{basic.fundamental}. \pnum \effects @@ -632,8 +664,8 @@ \begin{itemdescr} \pnum \mandates -Both \tcode{T} and \tcode{R} are standard integer types or -extended integer types\iref{basic.fundamental}. +Each of \tcode{T} and \tcode{R} is +a signed or unsigned integer type\iref{basic.fundamental}. \pnum \effects @@ -670,7 +702,7 @@ \tcode{static_cast>(value)}. \end{itemdescr} -\rSec2[utility.unreachable]{Function \tcode{unreachable}} +\rSec2[utility.undefined]{Undefined behavior} \indexlibraryglobal{unreachable}% \begin{itemdecl} @@ -704,6 +736,289 @@ \end{example} \end{itemdescr} +\indexlibraryglobal{observable_checkpoint}% +\begin{itemdecl} +void observable_checkpoint() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Establishes an observable checkpoint\iref{intro.abstract}. +\end{itemdescr} + +\rSec2[const.wrap.class]{Class template \tcode{constant_wrapper}} + +\begin{codeblock} +namespace std { + struct @\exposidnc{cw-operators}@ { // \expos + // unary operators + template<@\exposconcept{constexpr-param}@ T> + friend constexpr auto operator+(T) noexcept -> constant_wrapper<(+T::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ T> + friend constexpr auto operator-(T) noexcept -> constant_wrapper<(-T::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ T> + friend constexpr auto operator~(T) noexcept -> constant_wrapper<(~T::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ T> + friend constexpr auto operator!(T) noexcept -> constant_wrapper<(!T::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ T> + friend constexpr auto operator&(T) noexcept -> constant_wrapper<(&T::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ T> + friend constexpr auto operator*(T) noexcept -> constant_wrapper<(*T::value)> + { return {}; } + + // binary operators + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator+(L, R) noexcept -> constant_wrapper<(L::value + R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator-(L, R) noexcept -> constant_wrapper<(L::value - R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator*(L, R) noexcept -> constant_wrapper<(L::value * R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator/(L, R) noexcept -> constant_wrapper<(L::value / R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator%(L, R) noexcept -> constant_wrapper<(L::value % R::value)> + { return {}; } + + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator<<(L, R) noexcept -> constant_wrapper<(L::value << R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator>>(L, R) noexcept -> constant_wrapper<(L::value >> R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator&(L, R) noexcept -> constant_wrapper<(L::value & R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator|(L, R) noexcept -> constant_wrapper<(L::value | R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator^(L, R) noexcept -> constant_wrapper<(L::value ^ R::value)> + { return {}; } + + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + requires (!is_constructible_v || + !is_constructible_v) + friend constexpr auto operator&&(L, R) noexcept + -> constant_wrapper<(L::value && R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + requires (!is_constructible_v || + !is_constructible_v) + friend constexpr auto operator||(L, R) noexcept + -> constant_wrapper<(L::value || R::value)> + { return {}; } + + // comparisons + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator<=>(L, R) noexcept + -> constant_wrapper<(L::value <=> R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator<(L, R) noexcept -> constant_wrapper<(L::value < R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator<=(L, R) noexcept -> constant_wrapper<(L::value <= R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator==(L, R) noexcept -> constant_wrapper<(L::value == R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator!=(L, R) noexcept -> constant_wrapper<(L::value != R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator>(L, R) noexcept -> constant_wrapper<(L::value > R::value)> + { return {}; } + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator>=(L, R) noexcept -> constant_wrapper<(L::value >= R::value)> + { return {}; } + + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator,(L, R) noexcept = delete; + template<@\exposconcept{constexpr-param}@ L, @\exposconcept{constexpr-param}@ R> + friend constexpr auto operator->*(L, R) noexcept -> constant_wrapper*(R::value)> + { return {}; } + + // pseudo-mutators + template<@\exposconcept{constexpr-param}@ T> + constexpr auto operator++(this T) noexcept + -> constant_wrapper<(++T::value)> { return {}; } + template<@\exposconcept{constexpr-param}@ T> + constexpr auto operator++(this T, int) noexcept + -> constant_wrapper<(T::value++)> { return {}; } + template<@\exposconcept{constexpr-param}@ T> + constexpr auto operator--(this T) noexcept + -> constant_wrapper<(--T::value)> { return {}; } + template<@\exposconcept{constexpr-param}@ T> + constexpr auto operator--(this T, int) noexcept + -> constant_wrapper<(T::value--)> { return {}; } + + template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> + constexpr auto operator+=(this T, R) noexcept + -> constant_wrapper<(T::value += R::value)> { return {}; } + template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> + constexpr auto operator-=(this T, R) noexcept + -> constant_wrapper<(T::value -= R::value)> { return {}; } + template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> + constexpr auto operator*=(this T, R) noexcept + -> constant_wrapper<(T::value *= R::value)> { return {}; } + template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> + constexpr auto operator/=(this T, R) noexcept + -> constant_wrapper<(T::value /= R::value)> { return {}; } + template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> + constexpr auto operator%=(this T, R) noexcept + -> constant_wrapper<(T::value %= R::value)> { return {}; } + template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> + constexpr auto operator&=(this T, R) noexcept + -> constant_wrapper<(T::value &= R::value)> { return {}; } + template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> + constexpr auto operator|=(this T, R) noexcept + -> constant_wrapper<(T::value |= R::value)> { return {}; } + template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> + constexpr auto operator^=(this T, R) noexcept + -> constant_wrapper<(T::value ^= R::value)> { return {}; } + template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> + constexpr auto operator<<=(this T, R) noexcept + -> constant_wrapper<(T::value <<= R::value)> { return {}; } + template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> + constexpr auto operator>>=(this T, R) noexcept + -> constant_wrapper<(T::value >>= R::value)> { return {}; } + }; + + template + struct @\libglobal{constant_wrapper}@ : @\exposid{cw-operators}@ { + static constexpr decltype(auto) value = (X); + using type = constant_wrapper; + using value_type = decltype(X); + + template<@\exposconcept{constexpr-param}@ R> + constexpr auto operator=(R) const noexcept + -> constant_wrapper<(value = R::value)> { return {}; } + + constexpr operator decltype(value)() const noexcept { return value; } + + template + static constexpr decltype(auto) operator()(Args&&... args) noexcept(@\seebelow@); + template + static constexpr decltype(auto) operator[](Args&&... args) noexcept(@\seebelow@); + }; +} +\end{codeblock} + +\pnum +The class template \tcode{constant_wrapper} aids in metaprogramming by ensuring +that the evaluation of expressions comprised entirely of \tcode{constant_wrapper} +are core constant expressions\iref{expr.const.core}, +regardless of the context in which they appear. +In particular, this enables use of \tcode{constant_wrapper} values +that are passed as arguments to constexpr functions to be used in constant expressions. + +\pnum +If a specialization of \tcode{constant_wrapper} is instantiated with a type \tcode{T} +such that \tcode{is_same_v} is \tcode{false}, +the program is ill-formed. +\begin{note} +The second template parameter to \tcode{constant_wrapper} is present +to aid argument-dependent lookup\iref{basic.lookup.argdep} +in finding overloads for which \tcode{constant_wrapper}'s wrapped value is a suitable argument, +but for which the \tcode{constant_wrapper} itself is not. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} + constexpr auto initial_phase(auto quantity_1, auto quantity_2) { + return quantity_1 + quantity_2; + } + + constexpr auto middle_phase(auto tbd) { + return tbd; + } + + void final_phase(auto gathered, auto available) { + if constexpr (gathered == available) + std::cout << "Profit!\n"; + } + + void impeccable_underground_planning() { + auto gathered_quantity = middle_phase(initial_phase(std::cw<42>, std::cw<13>)); + static_assert(gathered_quantity == 55); + auto all_available = std::cw<55>; + final_phase(gathered_quantity, all_available); + } + + void deeply_flawed_underground_planning() { + constexpr auto gathered_quantity = middle_phase(initial_phase(42, 13)); + constexpr auto all_available = 55; + final_phase(gathered_quantity, all_available); // error: \tcode{gathered == available} + // is not a constant expression + } +\end{codeblock} +\end{example} + +\indexlibrarymember{operator()}{constant_wrapper}% +\begin{itemdecl} +template + static constexpr decltype(auto) operator()(Args&&... args) noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{\placeholder{call-expr}} be +\tcode{constant_wrapper<\placeholder{INVOKE}(value, remove_cvref_t::value...)>\{\}} +if all types in \tcode{remove_cvref_t...} satisfy \exposconcept{constexpr-param} and +\tcode{constant_wrapper<\placeholder{INVOKE}(val\-ue, remove_cvref_t::value...)>} is a valid type, +otherwise let \tcode{\placeholder{call-expr}} be \tcode{\placeholder{INVOKE}(value, std::forward(args)...)}. + +\pnum +\constraints +\tcode{\placeholder{call-expr}} is a valid expression. + +\pnum +\effects +Equivalent to: \tcode{return \placeholder{call-expr};} + +\pnum +\remarks +The exception specification is equivalent to \tcode{noexcept(\placeholder{call-expr})}. +\end{itemdescr} + +\indexlibrarymember{operator[]}{constant_wrapper}% +\begin{itemdecl} +template + static constexpr decltype(auto) operator[](Args&&... args) noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{\placeholder{subscr-expr}} be +\tcode{constant_wrapper::value...]>\{\}} +if all types in \tcode{remove_cvref_t...} satisfy \exposconcept{constexpr-param} and +\tcode{constant_wrapper::value...]>} is a valid type, +otherwise let \tcode{\placeholder{subscr-expr}} be \tcode{value[std::forward(args)...]}. + +\pnum +\constraints +\tcode{\placeholder{subscr-expr}} is a valid expression. + +\pnum +\effects +Equivalent to: \tcode{return \placeholder{subscr-expr};} + +\pnum +\remarks +The exception specification is equivalent to \tcode{noexcept(\placeholder{subscr-expr})}. +\end{itemdescr} + \rSec1[pairs]{Pairs} \rSec2[pairs.general]{General} @@ -778,7 +1093,7 @@ \end{codeblock} \pnum -Constructors and member functions of \tcode{pair} do not throw exceptions unless one of +Member functions of \tcode{pair} do not throw exceptions unless one of the element-wise operations specified to be called for that operation throws an exception. @@ -1291,8 +1606,8 @@ \indexlibrarymember{operator<=>}{pair}% \begin{itemdecl} template - constexpr common_comparison_category_t<@\placeholder{synth-three-way-result}@, - @\placeholder{synth-three-way-result}@> + constexpr common_comparison_category_t<@\exposid{synth-three-way-result}@, + @\exposid{synth-three-way-result}@> operator<=>(const pair& x, const pair& y); \end{itemdecl} @@ -1301,8 +1616,8 @@ \effects Equivalent to: \begin{codeblock} -if (auto c = @\placeholdernc{synth-three-way}@(x.first, y.first); c != 0) return c; -return @\placeholdernc{synth-three-way}@(x.second, y.second); +if (auto c = @\exposidnc{synth-three-way}@(x.first, y.first); c != 0) return c; +return @\exposidnc{synth-three-way}@(x.second, y.second); \end{codeblock} \end{itemdescr} @@ -1381,7 +1696,7 @@ $\tcode{I} < 2$. \pnum -\ctype +\result The type \tcode{T1} if \tcode{I} is 0, otherwise the type \tcode{T2}. \end{itemdescr} @@ -1485,8 +1800,8 @@ the class template \tcode{tuple} that can be instantiated with any number of arguments. Each template argument specifies the type of an element in the \tcode{tuple}. Consequently, tuples are -heterogeneous, fixed-size collections of values. An instantiation of \tcode{tuple} with -two arguments is similar to an instantiation of \tcode{pair} with the same two arguments. +heterogeneous, fixed-size collections of values. A specialization of \tcode{tuple} with +two arguments behaves similarly to a specialization of \tcode{pair} with the same two arguments. See~\ref{pairs}. \pnum @@ -1522,7 +1837,7 @@ // \tcode{ignore} struct @\exposidnc{ignore-type}@ { // \expos - constexpr const @\exposid{ignore-type}@ + constexpr const @\exposid{ignore-type}@& operator=(const auto &) const noexcept { return *this; } }; inline constexpr @\exposid{ignore-type}@ ignore; @@ -1542,7 +1857,8 @@ // \ref{tuple.apply}, calling a function with a tuple of arguments template - constexpr decltype(auto) apply(F&& f, Tuple&& t) noexcept(@\seebelow@); + constexpr apply_result_t apply(F&& f, Tuple&& t) + noexcept(is_nothrow_applicable_v); template constexpr T make_from_tuple(Tuple&& t); @@ -1560,7 +1876,7 @@ struct tuple_element>; template - using @\libglobal{tuple_element_t}@ = typename tuple_element::type; + using @\libglobal{tuple_element_t}@ = tuple_element::type; // \ref{tuple.elem}, element access template @@ -1586,7 +1902,7 @@ template constexpr bool operator==(const tuple&, const UTuple&); template - constexpr common_comparison_category_t<@\placeholdernc{synth-three-way-result}@...> + constexpr common_comparison_category_t<@\exposidnc{synth-three-way-result}@...> operator<=>(const tuple&, const tuple&); template constexpr @\seebelownc@ operator<=>(const tuple&, const UTuple&); @@ -1634,9 +1950,11 @@ public: // \ref{tuple.cnstr}, \tcode{tuple} construction constexpr explicit(@\seebelow@) tuple(); - constexpr explicit(@\seebelow@) tuple(const Types&...); // only if \tcode{sizeof...(Types) >= 1} + constexpr explicit(@\seebelow@) tuple(const Types&...) // only if \tcode{sizeof...(Types) >= 1} + noexcept(@\seebelow@); template - constexpr explicit(@\seebelow@) tuple(UTypes&&...); // only if \tcode{sizeof...(Types) >= 1} + constexpr explicit(@\seebelow@) tuple(UTypes&&...) // only if \tcode{sizeof...(Types) >= 1} + noexcept(@\seebelow@); tuple(const tuple&) = default; tuple(tuple&&) = default; @@ -1812,7 +2130,8 @@ \indexlibraryctor{tuple}% \begin{itemdecl} -constexpr explicit(@\seebelow@) tuple(const Types&...); +constexpr explicit(@\seebelow@) tuple(const Types&...) + noexcept((is_nothrow_copy_constructible_v && ...)); \end{itemdecl} \begin{itemdescr} @@ -1836,7 +2155,8 @@ \indexlibraryctor{tuple}% \begin{itemdecl} -template constexpr explicit(@\seebelow@) tuple(UTypes&&... u); +template constexpr explicit(@\seebelow@) tuple(UTypes&&... u) + noexcept((is_nothrow_constructible_v && ...)); \end{itemdecl} \begin{itemdescr} @@ -1927,7 +2247,7 @@ \begin{itemdescr} \pnum -Let \tcode{I} be the pack \tcode{0, 1, ..., (sizeof...(Types) - 1)}.\newline +Let \tcode{I} be the pack \tcode{0, 1, $\dotsc$, (sizeof...(Types) - 1)}.\newline Let \tcode{\exposid{FWD}(u)} be \tcode{static_cast(u)}. \pnum @@ -2016,7 +2336,7 @@ \begin{itemdescr} \pnum -Let \tcode{I} be the pack \tcode{0, 1, \ldots, (sizeof...(Types) - 1)}. +Let \tcode{I} be the pack \tcode{0, 1, $\dotsc$, (sizeof...(Types) - 1)}. \pnum \constraints @@ -2116,7 +2436,8 @@ \pnum \effects -Equivalent to the preceding constructors except that each element is constructed with +Equivalent to the preceding constructors +except that each element of non-reference type is constructed with uses-allocator construction\iref{allocator.uses.construction}. \end{itemdescr} @@ -2440,7 +2761,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)))>} @@ -2477,7 +2798,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)))>} @@ -2661,7 +2982,8 @@ \indexlibraryglobal{apply}% \begin{itemdecl} template - constexpr decltype(auto) apply(F&& f, Tuple&& t) noexcept(@\seebelow@); + constexpr apply_result_t apply(F&& f, Tuple&& t) + noexcept(is_nothrow_applicable_v); \end{itemdecl} \begin{itemdescr} @@ -2669,12 +2991,10 @@ \effects Given the exposition-only function template: \begin{codeblock} -namespace std { - template - constexpr decltype(auto) @\placeholdernc{apply-impl}@(F&& f, Tuple&& t, index_sequence) { - // \expos - return @\placeholdernc{INVOKE}@(std::forward(f), get(std::forward(t))...); // see \ref{func.require} - } +template +constexpr decltype(auto) @\placeholdernc{apply-impl}@(F&& f, Tuple&& t, index_sequence) { + // \expos + return @\placeholdernc{INVOKE}@(std::forward(f), get(std::forward(t))...); // see \ref{func.require} } \end{codeblock} Equivalent to: @@ -2682,15 +3002,6 @@ return @\placeholdernc{apply-impl}@(std::forward(f), std::forward(t), make_index_sequence>>{}); \end{codeblock} - -\pnum -\remarks -Let \tcode{I} be the pack -\tcode{0, 1, ..., (tuple_size_v> - 1)}. -The exception specification is equivalent to: -\begin{codeblock} -noexcept(invoke(std::forward(f), get(std::forward(t))...)) -\end{codeblock} \end{itemdescr} \indexlibraryglobal{make_from_tuple}% @@ -2711,12 +3022,10 @@ \effects Given the exposition-only function template: \begin{codeblock} -namespace std { - template - requires is_constructible_v(declval()))...> - constexpr T @\placeholdernc{make-from-tuple-impl}@(Tuple&& t, index_sequence) { // \expos - return T(get(std::forward(t))...); - } +template + requires is_constructible_v(declval()))...> +constexpr T @\placeholdernc{make-from-tuple-impl}@(Tuple&& t, index_sequence) { // \expos + return T(get(std::forward(t))...); } \end{codeblock} Equivalent to: @@ -2768,7 +3077,7 @@ $\tcode{I} < \tcode{sizeof...(Types)}$. \pnum -\ctype +\result \tcode{TI} is the type of the $\tcode{I}^\text{th}$ element of \tcode{Types}, where indexing is zero-based. @@ -2808,6 +3117,7 @@ the template is available when any of the headers \libheaderref{array}, +\libheaderref{complex}, \libheaderref{ranges}, or \libheaderref{utility} are included. @@ -2822,13 +3132,14 @@ \pnum Let \tcode{TE} denote \tcode{tuple_element_t} of the cv-unqualified type \tcode{T}. Then each specialization of the template meets the \oldconcept{TransformationTrait} requirements\iref{meta.rqmts} -with a member typedef \tcode{type} that names the type \tcode{add_const_t}. +with a member typedef \tcode{type} that names the type \tcode{const TE}. \pnum In addition to being available via inclusion of the \libheader{tuple} header, the template is available when any of the headers \libheaderref{array}, +\libheaderref{complex}, \libheaderref{ranges}, or \libheaderref{utility} are included. @@ -2972,10 +3283,10 @@ \indexlibrarymember{operator<=>}{tuple}% \begin{itemdecl} template - constexpr common_comparison_category_t<@\placeholder{synth-three-way-result}@...> + constexpr common_comparison_category_t<@\exposid{synth-three-way-result}@...> operator<=>(const tuple& t, const tuple& u); template - constexpr common_comparison_category_t<@\placeholder{synth-three-way-result}@...> + constexpr common_comparison_category_t<@\exposid{synth-three-way-result}@...> operator<=>(const tuple& t, const UTuple& u); \end{itemdecl} @@ -2993,7 +3304,7 @@ returns \tcode{strong_ordering::equal}. Otherwise, equivalent to: \begin{codeblock} -if (auto c = @\placeholder{synth-three-way}@(get<0>(t), get<0>(u)); c != 0) return c; +if (auto c = @\exposid{synth-three-way}@(get<0>(t), get<0>(u)); c != 0) return c; return @$\tcode{t}_\mathrm{tail}$@ <=> @$\tcode{u}_\mathrm{tail}$@; \end{codeblock} where $\tcode{r}_\mathrm{tail}$ for some \tcode{r} @@ -3056,6 +3367,9 @@ \tcode{tuple, UQual>...>} denotes a type. \end{itemize} + +\pnum +\result The member \grammarterm{typedef-name} \tcode{type} denotes the type \tcode{tuple, \linebreak{}UQual>...>}. \end{itemdescr} @@ -3084,7 +3398,10 @@ \item \tcode{tuple...>} denotes a type. \end{itemize} -The member \grammarterm{typedef-name} \tcode{type} denotes the type + +\pnum +\result +The member \grammarterm{typedef-name} \tcode{type} denotes the type\\ \tcode{tuple...>}. \end{itemdescr} @@ -3169,15 +3486,21 @@ namespace std { // \ref{optional.optional}, class template \tcode{optional} template - class optional; // partially freestanding + class optional; // partially freestanding + + // \ref{optional.optional.ref}, partial specialization of \tcode{optional} for lvalue reference types + template + class optional; // partially freestanding template constexpr bool ranges::enable_view> = true; template constexpr auto format_kind> = range_format::disabled; + template + constexpr bool ranges::enable_borrowed_range> = true; template - concept @\defexposconcept{is-derived-from-optional}@ = requires(const T& t) { // \expos + concept @\defexposconceptnc{is-derived-from-optional}@ = requires(const T& t) { // \expos [](const optional&){ }(t); }; @@ -3224,7 +3547,7 @@ template constexpr bool operator>=(const optional&, const U&); template constexpr bool operator>=(const T&, const optional&); template - requires (!@\exposconcept{is-derived-from-optional}@) && @\libconcept{three_way_comparable_with}@ + requires (!@\exposconcept{is-derived-from-optional}@) && @\libconcept{three_way_comparable_with}@ constexpr compare_three_way_result_t operator<=>(const optional&, const U&); @@ -3330,7 +3653,9 @@ constexpr void reset() noexcept; private: - T* val; // \expos + union { + remove_cv_t @\exposidnc{val}@; // \expos + }; }; template @@ -3339,22 +3664,24 @@ \end{codeblock} \pnum -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}}, +An instance of \tcode{optional} is said to +\defnx{contain a value}{contain a value!\idxcode{optional}} +when and only when +its member \exposid{val} is active\iref{class.union.general}; +\exposid{val} is referred to as its +\defnx{contained value}{contained value!\idxcode{optional}}. +An optional object's 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}. - -\pnum -When an \tcode{optional} object contains a value, -member \tcode{val} points to the contained value. \pnum -\tcode{T} shall be a type -other than \cv{} \tcode{in_place_t} or \cv{} \tcode{nullopt_t} -that meets the \oldconcept{Destructible} requirements (\tref{cpp17.destructible}). +A type \tcode{X} is a +\defnx{valid contained type}{valid contained type!\idxcode{optional}} for \tcode{optional} +if \tcode{X} is an lvalue reference type or a complete non-array object type, +and \tcode{remove_cvref_t} is a type other than \tcode{in_place_t} or \tcode{nullopt_t}. +If a specialization of \tcode{optional} is instantiated with a type \tcode{T} +that is not a valid contained type for \tcode{optional}, the program is ill-formed. +If \tcode{T} is an object type, +\tcode{T} shall meet the \oldconcept{Destructible} requirements (\tref{cpp17.destructible}). \rSec3[optional.ctor]{Constructors} @@ -3395,8 +3722,8 @@ \begin{itemdescr} \pnum \effects -If \tcode{rhs} contains a value, direct-non-list-initializes the contained value -with \tcode{*rhs}. +If \tcode{rhs} contains a value, direct-non-list-initializes \exposid{val} +with \tcode{rhs.\exposid{val}}. \pnum \ensures @@ -3426,8 +3753,8 @@ \pnum \effects -If \tcode{rhs} contains a value, direct-non-list-initializes the contained value -with \tcode{std::move(*rhs)}. +If \tcode{rhs} contains a value, direct-non-list-initializes \exposid{val} +with \tcode{std::move(rhs.\exposid{val})}. \tcode{rhs.has_value()} is unchanged. \pnum @@ -3458,7 +3785,8 @@ \pnum \effects -Direct-non-list-initializes the contained value with \tcode{std::forward(args)...}. +Direct-non-list-initializes \exposid{val} +with \tcode{std::forward(args)...}. \pnum \ensures @@ -3486,7 +3814,8 @@ \pnum \effects -Direct-non-list-initializes the contained value with \tcode{il, std::forward(args)...}. +Direct-non-list-initializes \exposid{val} +with \tcode{il, std::forward(args)...}. \pnum \ensures @@ -3519,7 +3848,8 @@ \pnum \effects -Direct-non-list-initializes the contained value with \tcode{std::forward(v)}. +Direct-non-list-initializes \exposid{val} +with \tcode{std::forward(v)}. \pnum \ensures @@ -3556,7 +3886,8 @@ \pnum \effects If \tcode{rhs} contains a value, -direct-non-list-initializes the contained value with \tcode{*rhs}. +direct-non-list-initializes \exposid{val} +with \tcode{rhs.operator*()}. \pnum \ensures @@ -3591,7 +3922,8 @@ \pnum \effects If \tcode{rhs} contains a value, -direct-non-list-initializes the contained value with \tcode{std::move(*rhs)}. +direct-non-list-initializes \exposid{val} +with \tcode{std::move(rhs).operator*()}. \tcode{rhs.has_value()} is unchanged. \pnum @@ -3620,10 +3952,9 @@ \begin{itemdescr} \pnum \effects -If \tcode{is_trivially_destructible_v != true} and \tcode{*this} contains a value, calls -\begin{codeblock} -val->T::~T() -\end{codeblock} +If \tcode{is_trivially_destructible_v} is \tcode{false} +and \tcode{*this} contains a value, +calls \tcode{\exposid{val}.T::\~T()}. \pnum \remarks @@ -3640,7 +3971,7 @@ \begin{itemdescr} \pnum \effects -If \tcode{*this} contains a value, calls \tcode{val->T::\~T()} to destroy the contained value; otherwise no effect. +If \tcode{*this} contains a value, calls \tcode{\exposid{val}.T::\~T()} to destroy the contained value; otherwise no effect. \pnum \ensures @@ -3665,12 +3996,12 @@ {\tcode{*this} does not contain a value} \rowhdr{\tcode{rhs} contains a value} & -assigns \tcode{*rhs} to the contained value & -direct-non-list-initializes the contained value with \tcode{*rhs} \\ +assigns \tcode{rhs.\exposid{val}} to \exposid{val} & +direct-non-list-initializes \exposid{val} with \tcode{rhs.\exposid{val}} \\ \rowsep \rowhdr{\tcode{rhs} does not contain a value} & -destroys the contained value by calling \tcode{val->T::\~T()} & +destroys the contained value by calling \tcode{\exposid{val}.T::\~T()} & no effect \\ \end{lib2dtab2} @@ -3717,12 +4048,12 @@ {\tcode{*this} does not contain a value} \rowhdr{\tcode{rhs} contains a value} & -assigns \tcode{std::move(*rhs)} to the contained value & -direct-non-list-initializes the contained value with \tcode{std::move(*rhs)} \\ +assigns \tcode{std::move(rhs.\exposid{val})} to \exposid{val} & +direct-non-list-initializes \exposid{val} with \tcode{std::move(rhs.\exposid{val})} \\ \rowsep \rowhdr{\tcode{rhs} does not contain a value} & -destroys the contained value by calling \tcode{val->T::\~T()} & +destroys the contained value by calling \tcode{\exposid{val}.T::\~T()} & no effect \\ \end{lib2dtab2} @@ -3744,9 +4075,9 @@ \pnum If any exception is thrown, the result of the expression \tcode{this->has_value()} remains unchanged. If an exception is thrown during the call to \tcode{T}'s move constructor, -the state of \tcode{*rhs.val} is determined by the exception safety guarantee of \tcode{T}'s move constructor. +the state of \tcode{rhs.\exposid{val}} is determined by the exception safety guarantee of \tcode{T}'s move constructor. If an exception is thrown during the call to \tcode{T}'s move assignment, -the state of \tcode{*val} and \tcode{*rhs.val} is determined by the exception safety guarantee of \tcode{T}'s move assignment. +the states of \exposid{val} and \tcode{rhs.\exposid{val}} are determined by the exception safety guarantee of \tcode{T}'s move assignment. If \tcode{is_trivially_move_constructible_v \&\&} \tcode{is_trivially_move_assignable_v \&\&} \tcode{is_trivially_destructible_v} is \tcode{true}, @@ -3770,7 +4101,10 @@ \pnum \effects -If \tcode{*this} contains a value, assigns \tcode{std::forward(v)} to the contained value; otherwise direct-non-list-initializes the contained value with \tcode{std::forward(v)}. +If \tcode{*this} contains a value, +assigns \tcode{std::forward(v)} to \exposid{val}; +otherwise direct-non-list-initializes \exposid{val} +with \tcode{std::forward(v)}. \pnum \ensures @@ -3782,7 +4116,9 @@ \pnum \remarks -If any exception is thrown, the result of the expression \tcode{this->has_value()} remains unchanged. If an exception is thrown during the call to \tcode{T}'s constructor, the state of \tcode{v} is determined by the exception safety guarantee of \tcode{T}'s constructor. If an exception is thrown during the call to \tcode{T}'s assignment, the state of \tcode{*val} and \tcode{v} is determined by the exception safety guarantee of \tcode{T}'s assignment. +If any exception is thrown, the result of the expression \tcode{this->has_value()} remains unchanged. If an exception is thrown during the call to \tcode{T}'s constructor, the state of \tcode{v} is determined by the exception safety guarantee of \tcode{T}'s constructor. If an exception is thrown during the call to \tcode{T}'s assignment, +the states of \exposid{val} and \tcode{v} are +determined by the exception safety guarantee of \tcode{T}'s assignment. \end{itemdescr} \indexlibrarymember{operator=}{optional}% @@ -3811,12 +4147,12 @@ {\tcode{*this} does not contain a value} \rowhdr{\tcode{rhs} contains a value} & -assigns \tcode{*rhs} to the contained value & -direct-non-list-initializes the contained value with \tcode{*rhs} \\ +assigns \tcode{rhs.operator*()} to \exposid{val} & +direct-non-list-initializes \exposid{val} with \tcode{rhs.operator*()} \\ \rowsep \rowhdr{\tcode{rhs} does not contain a value} & -destroys the contained value by calling \tcode{val->T::\~T()} & +destroys the contained value by calling \tcode{\exposid{val}.T::\~T()} & no effect \\ \end{lib2dtab2} @@ -3833,10 +4169,10 @@ If any exception is thrown, the result of the expression \tcode{this->has_value()} remains unchanged. If an exception is thrown during the call to \tcode{T}'s constructor, -the state of \tcode{*rhs.val} is determined by +the state of \tcode{rhs.\exposid{val}} is determined by the exception safety guarantee of \tcode{T}'s constructor. If an exception is thrown during the call to \tcode{T}'s assignment, -the state of \tcode{*val} and \tcode{*rhs.val} is determined by +the states of \exposid{val} and \tcode{rhs.\exposid{val}} are determined by the exception safety guarantee of \tcode{T}'s assignment. \end{itemdescr} @@ -3867,12 +4203,12 @@ {\tcode{*this} does not contain a value} \rowhdr{\tcode{rhs} contains a value} & -assigns \tcode{std::move(*rhs)} to the contained value & -direct-non-list-initializes the contained value with \tcode{std::move(*rhs)} \\ +assigns \tcode{std::move(rhs).op\-erator*()} to \exposid{val} & +direct-non-list-initializes \exposid{val} with \tcode{std::move(rhs).opera\-tor*()} \\ \rowsep \rowhdr{\tcode{rhs} does not contain a value} & -destroys the contained value by calling \tcode{val->T::\~T()} & +destroys the contained value by calling \tcode{\exposid{val}.T::\~T()} & no effect \\ \end{lib2dtab2} @@ -3889,10 +4225,10 @@ If any exception is thrown, the result of the expression \tcode{this->has_value()} remains unchanged. If an exception is thrown during the call to \tcode{T}'s constructor, -the state of \tcode{*rhs.val} is determined by +the state of \tcode{rhs.\exposid{val}} is determined by the exception safety guarantee of \tcode{T}'s constructor. If an exception is thrown during the call to \tcode{T}'s assignment, -the state of \tcode{*val} and \tcode{*rhs.val} is determined by +the states of \exposid{val} and \tcode{rhs.\exposid{val}} are determined by the exception safety guarantee of \tcode{T}'s assignment. \end{itemdescr} @@ -3903,13 +4239,13 @@ \begin{itemdescr} \pnum -\mandates +\constraints \tcode{is_constructible_v} is \tcode{true}. \pnum \effects -Calls \tcode{*this = nullopt}. Then direct-non-list-initializes the contained value -with \tcode{std::forward\brk{}(args)...}. +Calls \tcode{*this = nullopt}. Then direct-non-list-initializes \exposid{val} +with \tcode{std::forward(args\brk{})...}. \pnum \ensures @@ -3917,7 +4253,7 @@ \pnum \returns -A reference to the new contained value. +\exposid{val}. \pnum \throws @@ -3925,7 +4261,9 @@ \pnum \remarks -If an exception is thrown during the call to \tcode{T}'s constructor, \tcode{*this} does not contain a value, and the previous \tcode{*val} (if any) has been destroyed. +If an exception is thrown during the call to \tcode{T}'s constructor, +\tcode{*this} does not contain a value, and +the previous \exposid{val} (if any) has been destroyed. \end{itemdescr} \indexlibrarymember{emplace}{optional}% @@ -3940,8 +4278,8 @@ \pnum \effects -Calls \tcode{*this = nullopt}. Then direct-non-list-initializes the contained value with -\tcode{il, std::\brk{}forward(args)...}. +Calls \tcode{*this = nullopt}. Then direct-non-list-initializes \exposid{val} with +\tcode{il, std::forward(\brk{}args)...}. \pnum \ensures @@ -3949,7 +4287,7 @@ \pnum \returns -A reference to the new contained value. +\exposid{val}. \pnum \throws @@ -3957,7 +4295,9 @@ \pnum \remarks -If an exception is thrown during the call to \tcode{T}'s constructor, \tcode{*this} does not contain a value, and the previous \tcode{*val} (if any) has been destroyed. +If an exception is thrown during the call to \tcode{T}'s constructor, +\tcode{*this} does not contain a value, and +the previous \exposid{val} (if any) has been destroyed. \end{itemdescr} \rSec3[optional.swap]{Swap} @@ -3984,17 +4324,17 @@ {\tcode{*this} does not contain a value} \rowhdr{\tcode{rhs} contains a value} & -calls \tcode{swap(*(*this), *rhs)} & -direct-non-list-initializes the contained value of \tcode{*this} -with \tcode{std::move(*rhs)}, -followed by \tcode{rhs.val->T::\~T()}; +calls \tcode{swap(\exposid{val}, rhs.\exposid{val})} & +direct-non-list-initializes \exposid{val} +with \tcode{std::move(rhs.\exposid{val})}, +followed by \tcode{rhs.\exposid{val}.T::\~T()}; postcondition is that \tcode{*this} contains a value and \tcode{rhs} does not contain a value \\ \rowsep \rowhdr{\tcode{rhs} does not contain a value} & -direct-non-list-initializes the contained value of \tcode{rhs} -with \tcode{std::move(*(*this))}, -followed by \tcode{val->T::\~T()}; +direct-non-list-initializes \tcode{rhs.\exposid{val}} +with \tcode{std::move(\exposid{val})}, +followed by \tcode{\exposid{val}.T::\~T()}; postcondition is that \tcode{*this} does not contain a value and \tcode{rhs} contains a value & no effect \\ \end{lib2dtab2} @@ -4013,9 +4353,9 @@ \pnum If any exception is thrown, the results of the expressions \tcode{this->has_value()} and \tcode{rhs.has_value()} remain unchanged. If an exception is thrown during the call to function \tcode{swap}, -the state of \tcode{*val} and \tcode{*rhs.val} is determined by the exception safety guarantee of \tcode{swap} for lvalues of \tcode{T}. +the states of \exposid{val} and \tcode{rhs.\exposid{val}} are determined by the exception safety guarantee of \tcode{swap} for lvalues of \tcode{T}. If an exception is thrown during the call to \tcode{T}'s move constructor, -the state of \tcode{*val} and \tcode{*rhs.val} is determined by the exception safety guarantee of \tcode{T}'s move constructor. +the states of \exposid{val} and \tcode{rhs.\exposid{val}} are determined by the exception safety guarantee of \tcode{T}'s move constructor. \end{itemdescr} \rSec3[optional.iterators]{Iterator support} @@ -4081,12 +4421,12 @@ \begin{itemdescr} \pnum -\expects -\tcode{*this} contains a value. +\hardexpects +\tcode{has_value()} is \tcode{true}. \pnum \returns -\tcode{val}. +\tcode{addressof(\exposid{val})}. \pnum \remarks @@ -4101,12 +4441,12 @@ \begin{itemdescr} \pnum -\expects -\tcode{*this} contains a value. +\hardexpects +\tcode{has_value()} is \tcode{true}. \pnum \returns -\tcode{*val}. +\exposid{val}. \pnum \remarks @@ -4121,12 +4461,12 @@ \begin{itemdescr} \pnum -\expects -\tcode{*this} contains a value. +\hardexpects +\tcode{has_value()} is \tcode{true}. \pnum \effects -Equivalent to: \tcode{return std::move(*val);} +Equivalent to: \tcode{return std::move(\exposid{val});} \end{itemdescr} \indexlibrarymember{operator bool}{optional}% @@ -4170,7 +4510,7 @@ \effects Equivalent to: \begin{codeblock} -return has_value() ? *val : throw bad_optional_access(); +return has_value() ? @\exposid{val}@ : throw bad_optional_access(); \end{codeblock} \end{itemdescr} @@ -4186,7 +4526,7 @@ \effects Equivalent to: \begin{codeblock} -return has_value() ? std::move(*val) : throw bad_optional_access(); +return has_value() ? std::move(@\exposid{val}@) : throw bad_optional_access(); \end{codeblock} \end{itemdescr} @@ -4204,7 +4544,7 @@ \effects Equivalent to: \begin{codeblock} -return has_value() ? **this : static_cast(std::forward(v)); +return has_value() ? @\exposid{val}@ : static_cast(std::forward(v)); \end{codeblock} \end{itemdescr} @@ -4222,7 +4562,7 @@ \effects Equivalent to: \begin{codeblock} -return has_value() ? std::move(**this) : static_cast(std::forward(v)); +return has_value() ? std::move(@\exposid{val}@) : static_cast(std::forward(v)); \end{codeblock} \end{itemdescr} @@ -4236,7 +4576,7 @@ \begin{itemdescr} \pnum -Let \tcode{U} be \tcode{invoke_result_t}. +Let \tcode{U} be \tcode{invoke_result_t}. \pnum \mandates @@ -4247,7 +4587,7 @@ Equivalent to: \begin{codeblock} if (*this) { - return invoke(std::forward(f), *val); + return invoke(std::forward(f), @\exposid{val}@); } else { return remove_cvref_t(); } @@ -4262,7 +4602,7 @@ \begin{itemdescr} \pnum -Let \tcode{U} be \tcode{invoke_result_t}. +Let \tcode{U} be \tcode{invoke_result_t}. \pnum \mandates @@ -4273,7 +4613,7 @@ Equivalent to: \begin{codeblock} if (*this) { - return invoke(std::forward(f), std::move(*val)); + return invoke(std::forward(f), std::move(@\exposid{val}@)); } else { return remove_cvref_t(); } @@ -4288,15 +4628,14 @@ \begin{itemdescr} \pnum -Let \tcode{U} be \tcode{remove_cv_t>}. +Let \tcode{U} be \tcode{remove_cv_t>}. \pnum \mandates -\tcode{U} is a non-array object type -other than \tcode{in_place_t} or \tcode{nullopt_t}. +\tcode{U} is a valid contained type for \tcode{optional}. The declaration \begin{codeblock} -U u(invoke(std::forward(f), *val)); +U u(invoke(std::forward(f), @\exposid{val}@)); \end{codeblock} is well-formed for some invented variable \tcode{u}. \begin{note} @@ -4307,7 +4646,7 @@ \returns If \tcode{*this} contains a value, an \tcode{optional} object whose contained value is direct-non-list-initialized with -\tcode{invoke(std::forward(f), *val)}; +\tcode{invoke(std::forward(f), \exposid{val})}; otherwise, \tcode{optional()}. \end{itemdescr} @@ -4320,15 +4659,14 @@ \begin{itemdescr} \pnum Let \tcode{U} be -\tcode{remove_cv_t>}. +\tcode{remove_cv_t>}. \pnum \mandates -\tcode{U} is a non-array object type -other than \tcode{in_place_t} or \tcode{nullopt_t}. +\tcode{U} is a valid contained type for \tcode{optional}. The declaration \begin{codeblock} -U u(invoke(std::forward(f), std::move(*val))); +U u(invoke(std::forward(f), std::move(@\exposid{val}@))); \end{codeblock} is well-formed for some invented variable \tcode{u}. \begin{note} @@ -4339,7 +4677,7 @@ \returns If \tcode{*this} contains a value, an \tcode{optional} object whose contained value is direct-non-list-initialized with -\tcode{invoke(std::forward(f), std::move(*val))}; +\tcode{invoke(std::forward(f), std::move(\exposid{val}))}; otherwise, \tcode{optional()}. \end{itemdescr} @@ -4351,7 +4689,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 @@ -4378,7 +4716,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 @@ -4407,7 +4745,7 @@ \begin{itemdescr} \pnum \effects -If \tcode{*this} contains a value, calls \tcode{val->T::\~T()} to destroy the contained value; +If \tcode{*this} contains a value, calls \tcode{\exposid{val}.T::\~T()} to destroy the contained value; otherwise no effect. \pnum @@ -4415,116 +4753,697 @@ \tcode{*this} does not contain a value. \end{itemdescr} -\rSec2[optional.nullopt]{No-value state indicator} +\rSec2[optional.optional.ref]{Partial specialization of \tcode{optional} for reference types} -\indexlibraryglobal{nullopt_t}% -\indexlibraryglobal{nullopt}% -\begin{itemdecl} -struct nullopt_t{@\seebelow@}; -inline constexpr nullopt_t nullopt(@\unspec@); -\end{itemdecl} +\rSec3[optional.optional.ref.general]{General} +\begin{codeblock} +namespace std { + template + class optional { + public: + using value_type = T; + using iterator = @\impdefnc@; // present only if \tcode{T} is an object type other than an array + // of unknown bound; see~\ref{optional.ref.iterators} -\pnum -The struct \tcode{nullopt_t} is an empty class type used as a unique type to indicate the state of not containing a value for \tcode{optional} objects. -In particular, \tcode{optional} has a constructor with \tcode{nullopt_t} as a single argument; -this indicates that an optional object not containing a value shall be constructed. + // \ref{optional.ref.ctor}, constructors + constexpr optional() noexcept = default; + constexpr optional(nullopt_t) noexcept : optional() {} + constexpr optional(const optional& rhs) noexcept = default; -\pnum -Type \tcode{nullopt_t} shall not have a default constructor or an initializer-list constructor, and shall not be an aggregate. + template + constexpr explicit optional(in_place_t, Arg&& arg); + template + constexpr explicit(@\seebelow@) optional(U&& u) noexcept(@\seebelow@); + template + constexpr explicit(@\seebelow@) optional(optional& rhs) noexcept(@\seebelow@); + template + constexpr explicit(@\seebelow@) optional(const optional& rhs) noexcept(@\seebelow@); + template + constexpr explicit(@\seebelow@) optional(optional&& rhs) noexcept(@\seebelow@); + template + constexpr explicit(@\seebelow@) optional(const optional&& rhs) noexcept(@\seebelow@); -\rSec2[optional.bad.access]{Class \tcode{bad_optional_access}} + constexpr ~optional() = default; -\begin{codeblock} -namespace std { - class bad_optional_access : public exception { - public: - // see \ref{exception} for the specification of the special member functions - const char* what() const noexcept override; + // \ref{optional.ref.assign}, assignment + constexpr optional& operator=(nullopt_t) noexcept; + constexpr optional& operator=(const optional& rhs) noexcept = default; + + template constexpr T& emplace(U&& u) noexcept(@\seebelow@); + + // \ref{optional.ref.swap}, swap + constexpr void swap(optional& rhs) noexcept; + + // \ref{optional.ref.iterators}, iterator support + constexpr auto begin() const noexcept; + constexpr auto end() const noexcept; + + // \ref{optional.ref.observe}, observers + constexpr T* operator->() const noexcept; + constexpr T& operator*() const noexcept; + constexpr explicit operator bool() const noexcept; + constexpr bool has_value() const noexcept; + constexpr T& value() const; // freestanding-deleted + template> + constexpr remove_cv_t value_or(U&& u) const; + + // \ref{optional.ref.monadic}, monadic operations + template constexpr auto and_then(F&& f) const; + template constexpr optional> transform(F&& f) const; + template constexpr optional or_else(F&& f) const; + + // \ref{optional.ref.mod}, modifiers + constexpr void reset() noexcept; + + private: + T* @\exposidnc{val}@ = nullptr; // \expos + + // \ref{optional.ref.expos}, exposition only helper functions + template + constexpr void @\exposidnc{convert-ref-init-val}@(U&& u); // \expos }; } \end{codeblock} \pnum -The class \tcode{bad_optional_access} defines the type of objects thrown as exceptions to report the situation where an attempt is made to access the value of an optional object that does not contain a value. - -\indexlibrarymember{what}{bad_optional_access}% -\begin{itemdecl} -const char* what() const noexcept override; -\end{itemdecl} +An object of type \tcode{optional} +\defnx{contains a value}{contains a value!\idxcode{optional.ref}} +if and only if \tcode{\exposidnc{val} != nullptr} is \tcode{true}. +When an \tcode{optional} contains a value, +the \defnx{contained value}{contained value!\idxcode{optional.ref}} +is a reference to \tcode{*\exposid{val}}. -\begin{itemdescr} \pnum -\returns -An \impldef{return value of \tcode{bad_optional_access::what}} \ntbs{}. -\end{itemdescr} +Each type \tcode{optional} is a trivially copyable class\iref{class.prop}. -\rSec2[optional.relops]{Relational operators} +\rSec3[optional.ref.ctor]{Constructors} -\indexlibrarymember{operator==}{optional}% \begin{itemdecl} -template constexpr bool operator==(const optional& x, const optional& y); +template + constexpr explicit optional(in_place_t, Arg&& arg); \end{itemdecl} \begin{itemdescr} \pnum \constraints -The expression \tcode{*x == *y} is well-formed and -its result is convertible to \tcode{bool}. -\begin{note} -\tcode{T} need not be \oldconcept{EqualityComparable}. -\end{note} +\begin{itemize} +\item \tcode{is_constructible_v} is \tcode{true}, and +\item \tcode{reference_constructs_from_temporary_v} is \tcode{false}. +\end{itemize} \pnum -\returns -If \tcode{x.has_value() != y.has_value()}, \tcode{false}; otherwise if \tcode{x.has_value() == false}, \tcode{true}; otherwise \tcode{*x == *y}. +\effects +Equivalent to: \tcode{\exposid{convert-ref-init-val}(std::forward(arg))}. \pnum -\remarks -Specializations of this function template -for which \tcode{*x == *y} is a core constant expression -are constexpr functions. +\ensures +\tcode{*this} contains a value. \end{itemdescr} -\indexlibrarymember{operator"!=}{optional}% \begin{itemdecl} -template constexpr bool operator!=(const optional& x, const optional& y); +template + constexpr explicit(!is_convertible_v) + optional(U&& u) noexcept(is_nothrow_constructible_v); \end{itemdecl} \begin{itemdescr} \pnum \constraints -The expression \tcode{*x != *y} is well-formed and -its result is convertible to \tcode{bool}. +\begin{itemize} +\item \tcode{is_same_v, optional>} 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 -\returns -If \tcode{x.has_value() != y.has_value()}, \tcode{true}; -otherwise, if \tcode{x.has_value() == false}, \tcode{false}; -otherwise \tcode{*x != *y}. +\effects +Equivalent to: \tcode{\exposid{convert-ref-init-val}(std::forward(u))}. + +\pnum +\ensures +\tcode{*this} contains a value. \pnum \remarks -Specializations of this function template -for which \tcode{*x != *y} is a core constant expression -are constexpr functions. + This constructor is defined as deleted if +\begin{codeblock} +reference_constructs_from_temporary_v +\end{codeblock} + is \tcode{true}. \end{itemdescr} -\indexlibrarymember{operator<}{optional}% \begin{itemdecl} -template constexpr bool operator<(const optional& x, const optional& y); +template + constexpr explicit(!is_convertible_v) + optional(optional& rhs) noexcept(is_nothrow_constructible_v); \end{itemdecl} \begin{itemdescr} \pnum \constraints -\tcode{*x < *y} is well-formed -and its result is convertible to \tcode{bool}. - -\pnum -\returns -If \tcode{!y}, \tcode{false}; -otherwise, if \tcode{!x}, \tcode{true}; -otherwise \tcode{*x < *y}. +\begin{itemize} +\item \tcode{is_same_v, optional>} is \tcode{false}, +\item \tcode{is_same_v} is \tcode{false}, and +\item \tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (rhs.has_value()) @\exposid{convert-ref-init-val}@(rhs.operator*()); +\end{codeblock} + +\pnum +\remarks +This constructor is defined as deleted if +\begin{codeblock} +reference_constructs_from_temporary_v +\end{codeblock} +is \tcode{true}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr explicit(!is_convertible_v) + optional(const optional& rhs) noexcept(is_nothrow_constructible_v); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{is_same_v, optional>} is \tcode{false}, +\item \tcode{is_same_v} is \tcode{false}, and +\item \tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (rhs.has_value()) @\exposid{convert-ref-init-val}@(rhs.operator*()); +\end{codeblock} + +\pnum +\remarks +This constructor is defined as deleted if +\begin{codeblock} +reference_constructs_from_temporary_v +\end{codeblock} +is \tcode{true}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr explicit(!is_convertible_v) + optional(optional&& rhs) noexcept(is_nothrow_constructible_v); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{is_same_v, optional>} is \tcode{false}, +\item \tcode{is_same_v} is \tcode{false}, and +\item \tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (rhs.has_value()) @\exposid{convert-ref-init-val}@(std::move(rhs).operator*()); +\end{codeblock} + +\pnum +\remarks +This constructor is defined as deleted if +\begin{codeblock} +reference_constructs_from_temporary_v +\end{codeblock} +is \tcode{true}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr explicit(!is_convertible_v) + optional(const optional&& rhs) noexcept(is_nothrow_constructible_v); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{is_same_v, optional>} is \tcode{false}, +\item \tcode{is_same_v} is \tcode{false}, and +\item \tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (rhs.has_value()) @\exposid{convert-ref-init-val}@(std::move(rhs).operator*()); +\end{codeblock} + +\pnum +\remarks +This constructor is defined as deleted if +\begin{codeblock} +reference_constructs_from_temporary_v +\end{codeblock} +is \tcode{true}. +\end{itemdescr} + +\rSec3[optional.ref.assign]{Assignment} + +\begin{itemdecl} +constexpr optional& operator=(nullopt_t) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Assigns \tcode{nullptr} to \exposid{val}. + +\pnum +\ensures +\tcode{*this} does not contain a value. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\begin{itemdecl} +template + constexpr T& emplace(U&& u) noexcept(is_nothrow_constructible_v); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{is_constructible_v} is \tcode{true}, and +\item \tcode{reference_constructs_from_temporary_v} is \tcode{false}. +\end{itemize} + +\pnum +\effects +Equivalent to: \tcode{\exposid{convert-ref-init-val}(std::forward(u))}. + +\pnum +\returns +\tcode{*\exposid{val}}. +\end{itemdescr} + +\rSec3[optional.ref.swap]{Swap} + +\begin{itemdecl} +constexpr void swap(optional& rhs) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{std::swap(\exposid{val}, rhs.\exposid{val})}. +\end{itemdescr} + +\rSec3[optional.ref.iterators]{Iterator support} + +\begin{itemdecl} +using iterator = @\impdefnc@; // present only if \tcode{T} is an object type other than an array + // of unknown bound +\end{itemdecl} + +\begin{itemdescr} +\pnum +This type +models \libconcept{contiguous_iterator}\iref{iterator.concept.contiguous}, +meets the \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators}, +and meets 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}. + +\pnum +All requirements on container iterators\iref{container.reqmts} apply to +\tcode{optional::iterator}. +\end{itemdescr} + +\begin{itemdecl} +constexpr auto begin() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is an object type other than an array of unknown bound. + +\pnum +\returns + An object \tcode{i} of type \tcode{iterator}, such that + \tcode{i} is an iterator referring to \tcode{*\exposid{val}} + if \tcode{has_value()} is \tcode{true}, and + a past-the-end iterator value otherwise. +\end{itemdescr} + +\begin{itemdecl} +constexpr auto end() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is an object type other than an array of unknown bound. + +\pnum +\returns +\tcode{begin() + has_value()}. +\end{itemdescr} + +\rSec3[optional.ref.observe]{Observers} + +\begin{itemdecl} +constexpr T* operator->() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\hardexpects +\tcode{has_value()} is \tcode{true}. + +\pnum +\returns +\exposid{val}. + +\end{itemdescr} + +\begin{itemdecl} +constexpr T& operator*() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\hardexpects +\tcode{has_value()} is \tcode{true}. + +\pnum +\returns +\tcode{*\exposid{val}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr explicit operator bool() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{val} != nullptr}. +\end{itemdescr} + +\begin{itemdecl} +constexpr bool has_value() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{val} != nullptr}. +\end{itemdescr} + +\begin{itemdecl} +constexpr T& value() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return has_value() ? *@\exposid{val}@ : throw bad_optional_access(); +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +template> constexpr remove_cv_t value_or(U&& u) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is a non-array object type. + +\pnum + Let \tcode{X} be \tcode{remove_cv_t}. + +\pnum +\mandates +\tcode{is_constructible_v \&\& is_convertible_v} is \tcode{true}. + +\pnum +\effects + Equivalent to: +\begin{codeblock} +return has_value() ? *@\exposid{val}@ : static_cast(std::forward(u)); +\end{codeblock} + +\pnum +\remarks +The return type is unspecified if +\tcode{T} is an array type or a non-object type. +\begin{note} +This is to avoid the declaration being ill-formed. +\end{note} +\end{itemdescr} + +\rSec3[optional.ref.monadic]{Monadic operations} + +\begin{itemdecl} +template constexpr auto and_then(F&& f) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{U} be \tcode{invoke_result_t}. + +\pnum +\mandates +\tcode{remove_cvref_t} is a specialization of \tcode{optional}. + +\pnum +\effects + Equivalent to: +\begin{codeblock} +if (has_value()) { + return invoke(std::forward(f), *@\exposid{val}@); +} else { + return remove_cvref_t(); +} +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +template + constexpr optional>> transform(F&& f) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum + Let \tcode{U} be \tcode{remove_cv_t>}. + +\pnum +\mandates +\tcode{U} is a valid contained type for \tcode{optional}. +The declaration +\begin{codeblock} +U u(invoke(std::forward(f), *@\exposid{val}@)); +\end{codeblock} +is well-formed for some invented variable \tcode{u}. +\begin{note} +There is no requirement that \tcode{U} is movable\iref{dcl.init.general}. +\end{note} + +\pnum +\returns +If \tcode{*this} contains a value, an \tcode{optional} object +whose contained value is direct-non-list-initialized with +\tcode{invoke(std::forward(f), *\exposid{val})}; +otherwise, \tcode{optional()}. +\end{itemdescr} + +\begin{itemdecl} +template constexpr optional or_else(F&& f) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{F} models \tcode{\libconcept{invocable}}. + +\pnum +\mandates +\tcode{is_same_v>, optional>} is \tcode{true}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (has_value()) { + return *@\exposid{val}@; +} else { + return std::forward(f)(); +} +\end{codeblock} +\end{itemdescr} + +\rSec3[optional.ref.mod]{Modifiers} + +\begin{itemdecl} +constexpr void reset() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Assigns \tcode{nullptr} to \exposid{val}. + +\pnum +\ensures +\tcode{*this} does not contain a value. +\end{itemdescr} + +\rSec3[optional.ref.expos]{Exposition only helper functions} + +\begin{itemdecl} +template + constexpr void @\exposid{convert-ref-init-val}@(U&& u); // \expos +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Creates a variable \tcode{r} as if by \tcode{T\& r(std::forward(u));} +and then initializes \exposid{val} with \tcode{addressof(r)}. +\end{itemdescr} + +\rSec2[optional.nullopt]{No-value state indicator} + +\indexlibraryglobal{nullopt_t}% +\indexlibraryglobal{nullopt}% +\begin{itemdecl} +struct nullopt_t{@\seebelow@}; +inline constexpr nullopt_t nullopt(@\unspec@); +\end{itemdecl} + +\pnum +The struct \tcode{nullopt_t} is an empty class type used as a unique type to indicate the state of not containing a value for \tcode{optional} objects. +In particular, \tcode{optional} has a constructor with \tcode{nullopt_t} as a single argument; +this indicates that an optional object not containing a value shall be constructed. + +\pnum +Type \tcode{nullopt_t} does not have +a default constructor or an initializer-list constructor, and +is not an aggregate. +\tcode{nullopt_t} models \libconcept{copyable} and +\tcode{\libconcept{three_way_comparable}}. + +\rSec2[optional.bad.access]{Class \tcode{bad_optional_access}} + +\begin{codeblock} +namespace std { + class bad_optional_access : public exception { + public: + // see \ref{exception} for the specification of the special member functions + constexpr const char* what() const noexcept override; + }; +} +\end{codeblock} + +\pnum +The class \tcode{bad_optional_access} defines the type of objects thrown as exceptions to report the situation where an attempt is made to access the value of an optional object that does not contain a value. + +\indexlibrarymember{what}{bad_optional_access}% +\begin{itemdecl} +constexpr const char* what() const noexcept override; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +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} + +\indexlibrarymember{operator==}{optional}% +\begin{itemdecl} +template constexpr bool operator==(const optional& x, const optional& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{*x == *y} is well-formed and +its result is convertible to \tcode{bool}. +\begin{note} +\tcode{T} need not be \oldconcept{EqualityComparable}. +\end{note} + +\pnum +\returns +If \tcode{x.has_value() != y.has_value()}, \tcode{false}; otherwise if \tcode{x.has_value() == false}, \tcode{true}; otherwise \tcode{*x == *y}. + +\pnum +\remarks +Specializations of this function template +for which \tcode{*x == *y} is a core constant expression +are constexpr functions. +\end{itemdescr} + +\indexlibrarymember{operator"!=}{optional}% +\begin{itemdecl} +template constexpr bool operator!=(const optional& x, const optional& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{*x != *y} is well-formed and +its result is convertible to \tcode{bool}. + +\pnum +\returns +If \tcode{x.has_value() != y.has_value()}, \tcode{true}; +otherwise, if \tcode{x.has_value() == false}, \tcode{false}; +otherwise \tcode{*x != *y}. + +\pnum +\remarks +Specializations of this function template +for which \tcode{*x != *y} is a core constant expression +are constexpr functions. +\end{itemdescr} + +\indexlibrarymember{operator<}{optional}% +\begin{itemdecl} +template constexpr bool operator<(const optional& x, const optional& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{*x < *y} is well-formed +and its result is convertible to \tcode{bool}. + +\pnum +\returns +If \tcode{!y}, \tcode{false}; +otherwise, if \tcode{!x}, \tcode{true}; +otherwise \tcode{*x < *y}. \pnum \remarks @@ -4667,7 +5586,12 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? *x == v : false;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return *x == v; +return false; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator==}{optional}% @@ -4684,7 +5608,12 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? v == *x : false;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return v == *x; +return false; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator"!=}{optional}% @@ -4701,7 +5630,12 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? *x != v : true;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return *x != v; +return true; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator"!=}{optional}% @@ -4718,7 +5652,12 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? v != *x : true;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return v != *x; +return true; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator<}{optional}% @@ -4735,7 +5674,12 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? *x < v : true;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return *x < v; +return true; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator<}{optional}% @@ -4752,7 +5696,12 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? v < *x : false;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return v < *x; +return false; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator>}{optional}% @@ -4769,7 +5718,12 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? *x > v : false;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return *x > v; +return false; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator>}{optional}% @@ -4786,7 +5740,12 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? v > *x : true;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return v > *x; +return true; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator<=}{optional}% @@ -4803,7 +5762,12 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? *x <= v : true;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return *x <= v; +return true; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator<=}{optional}% @@ -4820,7 +5784,12 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? v <= *x : false;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return v <= *x; +return false; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator>=}{optional}% @@ -4837,7 +5806,12 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? *x >= v : false;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return *x >= v; +return false; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator>=}{optional}% @@ -4854,13 +5828,18 @@ \pnum \effects -Equivalent to: \tcode{return x.has_value() ? v >= *x : true;} +Equivalent to: +\begin{codeblock} +if (x.has_value()) + return v >= *x; +return true; +\end{codeblock} \end{itemdescr} \indexlibrarymember{operator<=>}{optional}% \begin{itemdecl} template - requires (!@\exposconcept{is-derived-from-optional}@) && @\libconcept{three_way_comparable_with}@ + requires (!@\exposconcept{is-derived-from-optional}@) && @\libconcept{three_way_comparable_with}@ constexpr compare_three_way_result_t operator<=>(const optional& x, const U& v); \end{itemdecl} @@ -4882,8 +5861,10 @@ \begin{itemdescr} \pnum \constraints -\tcode{is_move_constructible_v} is \tcode{true} and -\tcode{is_swappable_v} is \tcode{true}. +\begin{codeblock} +is_reference_v || (is_move_constructible_v && is_swappable_v) +\end{codeblock} +is \tcode{true}. \pnum \effects @@ -4897,8 +5878,14 @@ \begin{itemdescr} \pnum -\returns -\tcode{optional>(std::forward(v))}. +\constraints +The call to \tcode{make_optional} does not use +an explicit \grammarterm{template-argument-list} that +begins with a type \grammarterm{template-argument}. + +\pnum +\effects +Equivalent to: \tcode{return optional>(std::forward(v));} \end{itemdescr} \indexlibraryglobal{make_optional}% @@ -4983,7 +5970,7 @@ template struct variant_alternative; // \notdef template struct variant_alternative; template - using @\libglobal{variant_alternative_t}@ = typename variant_alternative::type; + using @\libglobal{variant_alternative_t}@ = variant_alternative::type; template struct variant_alternative>; @@ -5086,7 +6073,7 @@ public: // \ref{variant.ctor}, constructors constexpr variant() noexcept(@\seebelow@); - constexpr variant(const variant&); + constexpr variant(const variant&) noexcept(@\seebelow@); constexpr variant(variant&&) noexcept(@\seebelow@); template @@ -5201,7 +6188,7 @@ \indexlibraryctor{variant}% \begin{itemdecl} -constexpr variant(const variant& w); +constexpr variant(const variant& w) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -5214,7 +6201,8 @@ \pnum \throws -Any exception thrown by direct-initializing any $\tcode{T}_i$ for all $i$. +Any exception thrown by +the initialization of the contained value. \pnum \remarks @@ -5222,6 +6210,8 @@ \tcode{is_copy_constructible_v<$\tcode{T}_i$>} is \tcode{true} for all $i$. If \tcode{is_trivially_copy_constructible_v<$\tcode{T}_i$>} is \tcode{true} for all $i$, this constructor is trivial. +The exception specification is equivalent to the logical \logop{and} of +\tcode{is_nothrow_copy_constructible_v<$\tcode{T}_i$>} for all $i$. \end{itemdescr} \indexlibraryctor{variant}% @@ -5243,7 +6233,8 @@ \pnum \throws -Any exception thrown by move-constructing any $\tcode{T}_i$ for all $i$. +Any exception thrown by +the initialization of the contained value. \pnum \remarks @@ -5311,7 +6302,8 @@ \pnum \throws -Any exception thrown by the initialization of the selected alternative $\tcode{T}_j$. +Any exception thrown by +the initialization of the contained value. \pnum \remarks @@ -5345,7 +6337,8 @@ \pnum \throws -Any exception thrown by calling the selected constructor of \tcode{T}. +Any exception thrown by +the initialization of the contained value. \pnum \remarks @@ -5378,7 +6371,8 @@ \pnum \throws -Any exception thrown by calling the selected constructor of \tcode{T}. +Any exception thrown by +the initialization of the contained value. \pnum \remarks @@ -5412,7 +6406,8 @@ \pnum \throws -Any exception thrown by calling the selected constructor of $\tcode{T}_I$. +Any exception thrown by +the initialization of the contained value. \pnum \remarks @@ -5445,6 +6440,11 @@ \ensures \tcode{index()} is \tcode{I}. +\pnum +\throws +Any exception thrown by +the initialization of the contained value. + \pnum \remarks If $\tcode{T}_I$'s selected constructor is a constexpr constructor, this @@ -5908,7 +6908,7 @@ Let \tcode{VA} denote \tcode{variant_alternative} of the cv-unqualified type \tcode{T}. Then each specialization of the template meets the \oldconcept{TransformationTrait} requirements\iref{meta.rqmts} with a -member typedef \tcode{type} that names the type \tcode{add_const_t}. +member typedef \tcode{type} that names the type \tcode{const VA::type}. \end{itemdescr} \indexlibraryglobal{variant_alternative}% @@ -5922,7 +6922,7 @@ $\tcode{I} < \tcode{sizeof...(Types)}$. \pnum -\ctype +\result The type $\tcode{T}_I$. \end{itemdescr} @@ -6384,7 +7384,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} @@ -6395,13 +7395,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} @@ -6448,6 +7450,9 @@ \indexheader{any}% \begin{codeblock} +#include // see \ref{initializer.list.syn} +#include // see \ref{typeinfo.syn} + namespace std { // \ref{any.bad.any.cast}, class \tcode{bad_any_cast} class bad_any_cast; @@ -7317,12 +8322,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 @@ -7338,7 +8343,7 @@ \indexlibraryctor{bad_expected_access}% \begin{itemdecl} -explicit bad_expected_access(E e); +constexpr explicit bad_expected_access(E e); \end{itemdecl} \begin{itemdescr} @@ -7349,8 +8354,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} @@ -7361,8 +8366,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} @@ -7373,13 +8378,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}} @@ -7389,28 +8396,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}} @@ -7485,6 +8494,7 @@ constexpr T&& operator*() && noexcept; constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; + constexpr bool has_error() const noexcept; constexpr const T& value() const &; // freestanding-deleted constexpr T& value() &; // freestanding-deleted constexpr const T&& value() const &&; // freestanding-deleted @@ -7525,10 +8535,10 @@ friend constexpr bool operator==(const expected&, const unexpected&); private: - bool @\exposid{has_val}@; // \expos + bool @\exposid{has_val}@; // \expos union { - T @\exposid{val}@; // \expos - E @\exposid{unex}@; // \expos + remove_cv_t @\exposid{val}@; // \expos + E @\exposid{unex}@; // \expos }; }; } @@ -7754,7 +8764,9 @@ \item \tcode{is_same_v, in_place_t>} is \tcode{false}; and \item -\tcode{is_same_v>} is \tcode{false}; and +\tcode{is_same_v, expected>} is \tcode{false}; and +\item +\tcode{is_same_v, unexpect_t>} is \tcode{false}; and \item \tcode{remove_cvref_t} is not a specialization of \tcode{unexpected}; and \item @@ -8001,6 +9013,17 @@ \tcode{is_nothrow_move_constructible_v || is_nothrow_move_constructible_v} is \tcode{true}. \end{itemize} + +\pnum +This operator is trivial if: +\begin{itemize} +\item \tcode{is_trivially_copy_constructible_v} is \tcode{true}, and +\item \tcode{is_trivially_copy_assignable_v} is \tcode{true}, and +\item \tcode{is_trivially_destructible_v} is \tcode{true}, and +\item \tcode{is_trivially_copy_constructible_v} is \tcode{true}, and +\item \tcode{is_trivially_copy_assignable_v} is \tcode{true}, and +\item \tcode{is_trivially_destructible_v} is \tcode{true}. +\end{itemize} \end{itemdescr} \indexlibrarymember{operator=}{expected}% @@ -8058,6 +9081,17 @@ is_nothrow_move_assignable_v && is_nothrow_move_constructible_v && is_nothrow_move_assignable_v && is_nothrow_move_constructible_v \end{codeblock} + +\pnum +This operator is trivial if: +\begin{itemize} +\item \tcode{is_trivially_move_constructible_v} is \tcode{true}, and +\item \tcode{is_trivially_move_assignable_v} is \tcode{true}, and +\item \tcode{is_trivially_destructible_v} is \tcode{true}, and +\item \tcode{is_trivially_move_constructible_v} is \tcode{true}, and +\item \tcode{is_trivially_move_assignable_v} is \tcode{true}, and +\item \tcode{is_trivially_destructible_v} is \tcode{true}. +\end{itemize} \end{itemdescr} \indexlibrarymember{operator=}{expected}% @@ -8252,7 +9286,7 @@ throw; } } else { - T tmp(std::move(@\exposid{val}@)); + remove_cv_t tmp(std::move(@\exposid{val}@)); destroy_at(addressof(@\exposid{val}@)); try { construct_at(addressof(@\exposid{unex}@), std::move(rhs.@\exposid{unex}@)); @@ -8301,7 +9335,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{true}. \pnum @@ -8317,7 +9351,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{true}. \pnum @@ -8333,7 +9367,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{true}. \pnum @@ -8354,6 +9388,18 @@ \exposid{has_val}. \end{itemdescr} +\indexlibrarymember{has_error}{expected}% +\begin{itemdecl} +constexpr bool has_error() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\tcode{return !has_value();} +\end{itemdescr} + \indexlibrarymember{value}{expected}% \begin{itemdecl} constexpr const T& value() const &; @@ -8404,7 +9450,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{false}. \pnum @@ -8420,7 +9466,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{false}. \pnum @@ -8513,7 +9559,7 @@ \pnum \mandates \tcode{U} is a specialization of \tcode{expected} and -\tcode{is_same_v} is \tcode{true}. +\tcode{is_same_v} is \tcode{true}. \pnum \effects @@ -8544,7 +9590,7 @@ \pnum \mandates \tcode{U} is a specialization of \tcode{expected} and -\tcode{is_same_v} is \tcode{true}. +\tcode{is_same_v} is \tcode{true}. \pnum \effects @@ -8574,7 +9620,7 @@ \pnum \mandates \tcode{G} is a specialization of \tcode{expected} and -\tcode{is_same_v} is \tcode{true}. +\tcode{is_same_v} is \tcode{true}. \pnum \effects @@ -8605,7 +9651,7 @@ \pnum \mandates \tcode{G} is a specialization of \tcode{expected} and -\tcode{is_same_v} is \tcode{true}. +\tcode{is_same_v} is \tcode{true}. \pnum \effects @@ -8803,7 +9849,9 @@ \pnum \returns -\tcode{x.has_value() \&\& static_cast(*x == v)}. +If \tcode{x.has_value()} is \tcode{true}, +\tcode{*x == v}; +otherwise \tcode{false}. \end{itemdescr} \indexlibrarymember{operator==}{expected}% @@ -8819,7 +9867,9 @@ \pnum \returns -\tcode{!x.has_value() \&\& static_cast(x.error() == e.error())}. +If \tcode{!x.has_value()} is \tcode{true}, +\tcode{x.error() == e.error()}; +otherwise \tcode{false}. \end{itemdescr} \rSec2[expected.void]{Partial specialization of \tcode{expected} for \tcode{void} types} @@ -8827,96 +9877,98 @@ \rSec3[expected.void.general]{General} \begin{codeblock} -template requires is_void_v -class expected { -public: - using @\libmember{value_type}{expected}@ = T; - using @\libmember{error_type}{expected}@ = E; - using @\libmember{unexpected_type}{expected}@ = unexpected; - - template - using @\libmember{rebind}{expected}@ = expected; - - // \ref{expected.void.cons}, constructors - constexpr expected() noexcept; - constexpr expected(const expected&); - constexpr expected(expected&&) noexcept(@\seebelow@); - template - constexpr explicit(@\seebelow@) expected(const expected&); - template - constexpr explicit(@\seebelow@) expected(expected&&); - - template - constexpr explicit(@\seebelow@) expected(const unexpected&); - template - constexpr explicit(@\seebelow@) expected(unexpected&&); - - constexpr explicit expected(in_place_t) noexcept; - template - constexpr explicit expected(unexpect_t, Args&&...); - template - constexpr explicit expected(unexpect_t, initializer_list, Args&&...); - - - // \ref{expected.void.dtor}, destructor - constexpr ~expected(); - - // \ref{expected.void.assign}, assignment - constexpr expected& operator=(const expected&); - constexpr expected& operator=(expected&&) noexcept(@\seebelow@); - template - constexpr expected& operator=(const unexpected&); - template - constexpr expected& operator=(unexpected&&); - constexpr void emplace() noexcept; - - // \ref{expected.void.swap}, swap - constexpr void swap(expected&) noexcept(@\seebelow@); - friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y))); - - // \ref{expected.void.obs}, observers - constexpr explicit operator bool() const noexcept; - constexpr bool has_value() const noexcept; - constexpr void operator*() const noexcept; - constexpr void value() const &; // freestanding-deleted - constexpr void value() &&; // freestanding-deleted - constexpr const E& error() const & noexcept; - constexpr E& error() & noexcept; - constexpr const E&& error() const && noexcept; - constexpr E&& error() && noexcept; - template constexpr E error_or(G&&) const &; - template constexpr E error_or(G&&) &&; - - // \ref{expected.void.monadic}, monadic operations - template constexpr auto and_then(F&& f) &; - template constexpr auto and_then(F&& f) &&; - template constexpr auto and_then(F&& f) const &; - template constexpr auto and_then(F&& f) const &&; - template constexpr auto or_else(F&& f) &; - template constexpr auto or_else(F&& f) &&; - template constexpr auto or_else(F&& f) const &; - template constexpr auto or_else(F&& f) const &&; - template constexpr auto transform(F&& f) &; - template constexpr auto transform(F&& f) &&; - template constexpr auto transform(F&& f) const &; - template constexpr auto transform(F&& f) const &&; - template constexpr auto transform_error(F&& f) &; - template constexpr auto transform_error(F&& f) &&; - template constexpr auto transform_error(F&& f) const &; - template constexpr auto transform_error(F&& f) const &&; - - // \ref{expected.void.eq}, equality operators - template requires is_void_v - friend constexpr bool operator==(const expected& x, const expected& y); - template - friend constexpr bool operator==(const expected&, const unexpected&); - -private: - bool @\exposid{has_val}@; // \expos - union { - E @\exposid{unex}@; // \expos +namespace std { + template requires is_void_v + class expected { + public: + using @\libmember{value_type}{expected}@ = T; + using @\libmember{error_type}{expected}@ = E; + using @\libmember{unexpected_type}{expected}@ = unexpected; + + template + using @\libmember{rebind}{expected}@ = expected; + + // \ref{expected.void.cons}, constructors + constexpr expected() noexcept; + constexpr expected(const expected&); + constexpr expected(expected&&) noexcept(@\seebelow@); + template + constexpr explicit(@\seebelow@) expected(const expected&); + template + constexpr explicit(@\seebelow@) expected(expected&&); + + template + constexpr explicit(@\seebelow@) expected(const unexpected&); + template + constexpr explicit(@\seebelow@) expected(unexpected&&); + + constexpr explicit expected(in_place_t) noexcept; + template + constexpr explicit expected(unexpect_t, Args&&...); + template + constexpr explicit expected(unexpect_t, initializer_list, Args&&...); + + // \ref{expected.void.dtor}, destructor + constexpr ~expected(); + + // \ref{expected.void.assign}, assignment + constexpr expected& operator=(const expected&); + constexpr expected& operator=(expected&&) noexcept(@\seebelow@); + template + constexpr expected& operator=(const unexpected&); + template + constexpr expected& operator=(unexpected&&); + constexpr void emplace() noexcept; + + // \ref{expected.void.swap}, swap + constexpr void swap(expected&) noexcept(@\seebelow@); + friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y))); + + // \ref{expected.void.obs}, observers + constexpr explicit operator bool() const noexcept; + constexpr bool has_value() const noexcept; + constexpr bool has_error() const noexcept; + constexpr void operator*() const noexcept; + constexpr void value() const &; // freestanding-deleted + constexpr void value() &&; // freestanding-deleted + constexpr const E& error() const & noexcept; + constexpr E& error() & noexcept; + constexpr const E&& error() const && noexcept; + constexpr E&& error() && noexcept; + template constexpr E error_or(G&&) const &; + template constexpr E error_or(G&&) &&; + + // \ref{expected.void.monadic}, monadic operations + template constexpr auto and_then(F&& f) &; + template constexpr auto and_then(F&& f) &&; + template constexpr auto and_then(F&& f) const &; + template constexpr auto and_then(F&& f) const &&; + template constexpr auto or_else(F&& f) &; + template constexpr auto or_else(F&& f) &&; + template constexpr auto or_else(F&& f) const &; + template constexpr auto or_else(F&& f) const &&; + template constexpr auto transform(F&& f) &; + template constexpr auto transform(F&& f) &&; + template constexpr auto transform(F&& f) const &; + template constexpr auto transform(F&& f) const &&; + template constexpr auto transform_error(F&& f) &; + template constexpr auto transform_error(F&& f) &&; + template constexpr auto transform_error(F&& f) const &; + template constexpr auto transform_error(F&& f) const &&; + + // \ref{expected.void.eq}, equality operators + template requires is_void_v + friend constexpr bool operator==(const expected& x, const expected& y); + template + friend constexpr bool operator==(const expected&, const unexpected&); + + private: + bool @\exposid{has_val}@; // \expos + union { + E @\exposid{unex}@; // \expos + }; }; -}; +} \end{codeblock} \pnum @@ -9129,7 +10181,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} @@ -9201,6 +10253,13 @@ This operator is defined as deleted unless \tcode{is_copy_assignable_v} is \tcode{true} and \tcode{is_copy_constructible_v} is \tcode{true}. + +\pnum +This operator is trivial if +\tcode{is_trivially_copy_constructible_v}, +\tcode{is_trivially_copy_assigna\-ble_v}, and +\tcode{is_trivially_destructible_v} +are all \tcode{true}. \end{itemdescr} \indexlibrarymember{operator=}{expected}% @@ -9240,6 +10299,13 @@ \remarks The exception specification is equivalent to \tcode{is_nothrow_move_constructible_v \&\& is_nothrow_move_assignable_v}. + +\pnum +This operator is trivial if +\tcode{is_trivially_move_constructible_v}, +\tcode{is_trivially_move_assigna\-ble_v}, and +\tcode{is_trivially_destructible_v} +are all \tcode{true}. \end{itemdescr} \indexlibrarymember{operator=}{expected}% @@ -9365,6 +10431,18 @@ \exposid{has_val}. \end{itemdescr} +\indexlibrarymember{has_error}{expected}% +\begin{itemdecl} +constexpr bool has_error() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\tcode{return !has_value();} +\end{itemdescr} + \indexlibrarymember{operator*}{expected}% \begin{itemdecl} constexpr void operator*() const noexcept; @@ -9372,7 +10450,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{true}. \end{itemdescr} @@ -9416,7 +10494,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{false}. \pnum @@ -9432,7 +10510,7 @@ \begin{itemdescr} \pnum -\expects +\hardexpects \tcode{has_value()} is \tcode{false}. \pnum @@ -9493,7 +10571,7 @@ \pnum \mandates \tcode{U} is a specialization of \tcode{expected} and -\tcode{is_same_v} is \tcode{true}. +\tcode{is_same_v} is \tcode{true}. \pnum \effects @@ -9523,7 +10601,7 @@ \pnum \mandates \tcode{U} is a specialization of \tcode{expected} and -\tcode{is_same_v} is \tcode{true}. +\tcode{is_same_v} is \tcode{true}. \pnum \effects @@ -9549,7 +10627,7 @@ \pnum \mandates \tcode{G} is a specialization of \tcode{expected} and -\tcode{is_same_v} is \tcode{true}. +\tcode{is_same_v} is \tcode{true}. \pnum \effects @@ -9576,7 +10654,7 @@ \pnum \mandates \tcode{G} is a specialization of \tcode{expected} and -\tcode{is_same_v} is \tcode{true}. +\tcode{is_same_v} is \tcode{true}. \pnum \effects @@ -9741,7 +10819,8 @@ \pnum \returns If \tcode{x.has_value()} does not equal \tcode{y.has_value()}, \tcode{false}; -otherwise \tcode{x.has_value() || static_cast(x.error() == y.error())}. +otherwise if \tcode{x.has_value()} is \tcode{true}, \tcode{true}; +otherwise \tcode{x.error() == y.error()}. \end{itemdescr} \indexlibrarymember{operator==}{expected}% @@ -9758,7 +10837,9 @@ \pnum \returns -\tcode{!x.has_value() \&\& static_cast(x.error() == e.error())}. +If \tcode{!x.has_value()} is \tcode{true}, +\tcode{x.error() == e.error()}; +otherwise \tcode{false}. \end{itemdescr} \rSec1[bitset]{Bitsets} @@ -9805,13 +10886,18 @@ // bit reference class reference { public: - constexpr reference(const reference&) = default; + constexpr reference(const reference& x) noexcept; constexpr ~reference(); constexpr reference& operator=(bool x) noexcept; // for \tcode{b[i] = x;} - constexpr reference& operator=(const reference&) noexcept; // for \tcode{b[i] = b[j];} - constexpr bool operator~() const noexcept; // flips the bit + constexpr reference& operator=(const reference& x) noexcept; // for \tcode{b[i] = b[j];} + constexpr const reference& operator=(bool x) const noexcept; constexpr operator bool() const noexcept; // for \tcode{x = b[i];} + constexpr bool operator~() const noexcept; constexpr reference& flip() noexcept; // for \tcode{b[i].flip();} + + friend constexpr void swap(reference x, reference y) noexcept; + friend constexpr void swap(reference x, bool& y) noexcept; + friend constexpr void swap(bool& x, reference y) noexcept; }; // \ref{bitset.cons}, constructors @@ -9860,52 +10946,153 @@ constexpr bool operator[](size_t pos) const; constexpr reference operator[](size_t pos); - constexpr unsigned long to_ulong() const; - constexpr unsigned long long to_ullong() const; - template, - class Allocator = allocator> - constexpr basic_string - to_string(charT zero = charT('0'), charT one = charT('1')) const; + constexpr unsigned long to_ulong() const; + constexpr unsigned long long to_ullong() const; + template, + class Allocator = allocator> + constexpr basic_string + to_string(charT zero = charT('0'), charT one = charT('1')) const; + + // observers + constexpr size_t count() const noexcept; + constexpr size_t size() const noexcept; + constexpr bool operator==(const bitset& rhs) const noexcept; + constexpr bool test(size_t pos) const; + constexpr bool all() const noexcept; + constexpr bool any() const noexcept; + constexpr bool none() const noexcept; + }; + + // \ref{bitset.hash}, hash support + template struct hash; + template struct hash>; +} +\end{codeblock} + +\pnum +The class template +\tcode{bitset} +describes an object that can store a sequence consisting of a fixed number of +bits, \tcode{N}. + +\pnum +Each bit represents either the value zero (reset) or one (set). +To +\term{toggle} +a bit is to change the value zero to one, or the value one to +zero. +Each bit has a non-negative position \tcode{pos}. +When converting +between an object of type +\tcode{bitset} +and a value of some +integral type, bit position \tcode{pos} corresponds to the +\term{bit value} +\tcode{1 << pos}. +The integral value corresponding to two +or more bits is the sum of their bit values. + +\pnum +\tcode{reference} +is a class that simulates a reference to a single bit in the sequence. + +\indexlibraryctor{bitset::reference}% +\begin{itemdecl} +constexpr reference::reference(const reference& x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{*this} to refer to the same bit as \tcode{x}. +\end{itemdescr} + +\indexlibrarydtor{bitset::reference}% +\begin{itemdecl} +constexpr reference::~reference(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +None. +\end{itemdescr} + +\indexlibrarymember{operator=}{bitset::reference}% +\begin{itemdecl} +constexpr reference& reference::operator=(bool x) noexcept; +constexpr reference& reference::operator=(const reference& x) noexcept; +constexpr const reference& reference::operator=(bool x) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Sets the bit referred to by \tcode{*this} if \tcode{bool(x)} is \tcode{true}, +and clears it otherwise. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator bool}{bitset::reference}% +\begin{itemdecl} +constexpr reference::operator bool() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if the value of the bit referred to by \tcode{*this} is one, +\tcode{false} otherwise. +\end{itemdescr} + +\indexlibrarymember{operator\~{}}{bitset::reference}% +\begin{itemdecl} +constexpr bool reference::operator~() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{!bool(*this)}. +\end{itemdescr} - // observers - constexpr size_t count() const noexcept; - constexpr size_t size() const noexcept; - constexpr bool operator==(const bitset& rhs) const noexcept; - constexpr bool test(size_t pos) const; - constexpr bool all() const noexcept; - constexpr bool any() const noexcept; - constexpr bool none() const noexcept; - }; +\indexlibrarymember{swap}{bitset::reference}% +\begin{itemdecl} +constexpr void swap(reference x, reference y) noexcept; +constexpr void swap(reference x, bool& y) noexcept; +constexpr void swap(bool& x, reference y) noexcept; +\end{itemdecl} - // \ref{bitset.hash}, hash support - template struct hash; - template struct hash>; -} +\begin{itemdescr} +\pnum +\effects +Exchanges the values denoted by \tcode{x} and \tcode{y} as if by: + +\begin{codeblock} +bool b = x; +x = y; +y = b; \end{codeblock} +\end{itemdescr} +\indexlibrarymember{flip}{bitset::reference}% +\begin{itemdecl} +constexpr reference& reference::flip() noexcept; +\end{itemdecl} + +\begin{itemdescr} \pnum -The class template -\tcode{bitset} -describes an object that can store a sequence consisting of a fixed number of -bits, \tcode{N}. +\effects +Equivalent to \tcode{*this = !*this}. \pnum -Each bit represents either the value zero (reset) or one (set). -To -\term{toggle} -a bit is to change the value zero to one, or the value one to -zero. -Each bit has a non-negative position \tcode{pos}. -When converting -between an object of class -\tcode{bitset} -and a value of some -integral type, bit position \tcode{pos} corresponds to the -\term{bit value} -\tcode{1 << pos}. -The integral value corresponding to two -or more bits is the sum of their bit values. +\returns +\tcode{*this}. +\end{itemdescr} \pnum The functions described in \ref{template.bitset} can report three kinds of @@ -10029,6 +11216,15 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{is_array_v} is \tcode{false}, +\item \tcode{is_trivially_copyable_v} is \tcode{true}, +\item \tcode{is_standard_layout_v} is \tcode{true}, and +\item \tcode{is_trivially_default_constructible_v} is \tcode{true}. +\end{itemize} + \pnum \effects As if by: @@ -10306,8 +11502,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{pos} is valid. +\hardexpects +\tcode{pos < size()} is \tcode{true}. \pnum \returns @@ -10326,8 +11522,8 @@ \begin{itemdescr} \pnum -\expects -\tcode{pos} is valid. +\hardexpects +\tcode{pos < size()} is \tcode{true}. \pnum \returns @@ -10646,6 +11842,9 @@ \indexlibraryglobal{unwrap_ref_decay}% \indexlibraryglobal{unwrap_ref_decay_t}% \begin{codeblock} +#include // see \ref{initializer.list.syn} +#include // see \ref{typeinfo.syn} + namespace std { // \ref{func.invoke}, invoke template @@ -10763,9 +11962,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 } @@ -10890,19 +12087,20 @@ A \defnadj{callable}{object} is an object of a callable type. \pnum -A \defnx{call wrapper type}{call wrapper!type} is a type that holds a callable object -and supports a call operation that forwards to that object. +A \defnx{call wrapper type}{call wrapper!type} is a type that holds +a \defnadj{target}{object}, +which is either +a callable object or +an object representing a callable object, +and supports a call operation that forwards to that callable object. \pnum A \defn{call wrapper} is an object of a call wrapper type. -\pnum -A \defn{target object} is the callable object held by a call wrapper. - \pnum A call wrapper type may additionally hold a sequence of objects and references -that may be passed as arguments to the target object. +that may be passed as arguments to the callable object. These entities are collectively referred to as \defnx{bound argument entities}{bound argument entity}. @@ -11447,7 +12645,7 @@ \indexlibrarymember{operator()}{plus<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) + std::forward(u)); + -> decltype(std::forward(t) + std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -11489,7 +12687,7 @@ \indexlibrarymember{operator()}{minus<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) - std::forward(u)); + -> decltype(std::forward(t) - std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -11531,7 +12729,7 @@ \indexlibrarymember{operator()}{multiplies<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) * std::forward(u)); + -> decltype(std::forward(t) * std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -11573,7 +12771,7 @@ \indexlibrarymember{operator()}{divides<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) / std::forward(u)); + -> decltype(std::forward(t) / std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -11615,7 +12813,7 @@ \indexlibrarymember{operator()}{modulus<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) % std::forward(u)); + -> decltype(std::forward(t) % std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -11657,7 +12855,7 @@ \indexlibrarymember{operator()}{negate<>}% \begin{itemdecl} template constexpr auto operator()(T&& t) const - -> decltype(-std::forward(t)); + -> decltype(-std::forward(t)); \end{itemdecl} \begin{itemdescr} @@ -11725,7 +12923,7 @@ \indexlibrarymember{operator()}{equal_to<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) == std::forward(u)); + -> decltype(std::forward(t) == std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -11767,7 +12965,7 @@ \indexlibrarymember{operator()}{not_equal_to<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) != std::forward(u)); + -> decltype(std::forward(t) != std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -11809,7 +13007,7 @@ \indexlibrarymember{operator()}{greater<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) > std::forward(u)); + -> decltype(std::forward(t) > std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -11851,7 +13049,7 @@ \indexlibrarymember{operator()}{less<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) < std::forward(u)); + -> decltype(std::forward(t) < std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -11893,7 +13091,7 @@ \indexlibrarymember{operator()}{greater_equal<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) >= std::forward(u)); + -> decltype(std::forward(t) >= std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -11935,7 +13133,7 @@ \indexlibrarymember{operator()}{less_equal<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) <= std::forward(u)); + -> decltype(std::forward(t) <= std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -12072,7 +13270,7 @@ \begin{codeblock} struct ranges::greater { template - constexpr bool operator()(T&& t, U&& u) const; + constexpr bool operator()(T&& t, U&& u) const; using is_transparent = @\unspecnc@; }; @@ -12244,7 +13442,7 @@ \indexlibrarymember{operator()}{logical_and<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) && std::forward(u)); + -> decltype(std::forward(t) && std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -12286,7 +13484,7 @@ \indexlibrarymember{operator()}{logical_or<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) || std::forward(u)); + -> decltype(std::forward(t) || std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -12328,7 +13526,7 @@ \indexlibrarymember{operator()}{logical_not<>}% \begin{itemdecl} template constexpr auto operator()(T&& t) const - -> decltype(!std::forward(t)); + -> decltype(!std::forward(t)); \end{itemdecl} \begin{itemdescr} @@ -12379,7 +13577,7 @@ \indexlibrarymember{operator()}{bit_and<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) & std::forward(u)); + -> decltype(std::forward(t) & std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -12421,7 +13619,7 @@ \indexlibrarymember{operator()}{bit_or<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) | std::forward(u)); + -> decltype(std::forward(t) | std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -12463,7 +13661,7 @@ \indexlibrarymember{operator()}{bit_xor<>}% \begin{itemdecl} template constexpr auto operator()(T&& t, U&& u) const - -> decltype(std::forward(t) ^ std::forward(u)); + -> decltype(std::forward(t) ^ std::forward(u)); \end{itemdecl} \begin{itemdescr} @@ -12504,7 +13702,7 @@ \indexlibrarymember{operator()}{bit_not<>}% \begin{itemdecl} template constexpr auto operator()(T&& t) const - -> decltype(~std::forward(t)); + -> decltype(~std::forward(t)); \end{itemdecl} \begin{itemdescr} @@ -12600,9 +13798,9 @@ \pnum \returns -A perfect forwarding call wrapper\iref{func.require} \tcode{g} that -does not have state entities, and -has the call pattern \tcode{!invoke(f, call_args...)}. +A perfect forwarding call wrapper\iref{func.require} \tcode{g} +whose target object is a copy of \tcode{cw}, and +whose call pattern is \tcode{!invoke(f, call_args...)}. \end{itemdescr} \rSec2[func.bind.partial]{Function templates \tcode{bind_front} and \tcode{bind_back}} @@ -12722,8 +13920,9 @@ \pnum \returns -A perfect forwarding call wrapper\iref{func.require} \tcode{g} that -does not have a target object, and has the call pattern: +A perfect forwarding call wrapper\iref{func.require} \tcode{g} +whose target object is a copy of \tcode{cw}, and +whose call pattern is: \begin{itemize} \item \tcode{invoke(f, bound_args..., call_args...)} @@ -12734,7 +13933,7 @@ \end{itemize} \pnum -throws +\throws Any exception thrown by the initialization of \tcode{bound_args}. \end{itemdescr} @@ -12942,13 +14141,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} @@ -13013,18 +14210,19 @@ \pnum Let \tcode{t} be an object of a type that is a specialization of -\tcode{function}, \tcode{copyable_function}, or \tcode{move_only_function}, +\tcode{function}, \tcode{copyable_function}, \tcode{move_only_function}, +or \tcode{function_ref}, such that the target object \tcode{x} of \tcode{t} has a type that is a specialization of -\tcode{function}, \tcode{copyable_function}, or \tcode{move_only_function}. +\tcode{function}, \tcode{copyable_function}, \tcode{move_only_function}, +or \tcode{function_ref}. Each argument of the invocation of \tcode{x} evaluated as part of the invocation of \tcode{t} may alias an argument in the same position in the invocation of \tcode{t} that has the same type, even if the corresponding parameter is not of reference type. \begin{example} \begin{codeblock} -move_only_function - f{copyable_function{[](T) {}}}; +move_only_function f{copyable_function{[](T) {}}}; T t; f(t); // it is unspecified how many copies of \tcode{T} are made \end{codeblock} @@ -13121,17 +14319,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} @@ -13229,8 +14416,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 @@ -13373,8 +14559,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 @@ -13549,7 +14734,7 @@ public: using result_type = R; - // \ref{func.wrap.move.ctor}, constructors, assignment, and destructor + // \ref{func.wrap.move.ctor}, constructors, assignments, and destructor move_only_function() noexcept; move_only_function(nullptr_t) noexcept; move_only_function(move_only_function&&) noexcept; @@ -13596,7 +14781,7 @@ for which \tcode{is_nothrow_move_constructible_v} is \tcode{true}. \end{note} -\rSec4[func.wrap.move.ctor]{Constructors, assignment, and destructor} +\rSec4[func.wrap.move.ctor]{Constructors, assignments, and destructor} \indextext{move_only_function::is-callable-from@\tcode{move_only_function::\exposid{is-callable-from}}}% \begin{itemdecl} @@ -13679,12 +14864,12 @@ \tcode{*this} has no target object if any of the following hold: \begin{itemize} \item -\tcode{f} is a null function pointer value, or +\tcode{f} is a null function pointer value, \item \tcode{f} is a null member pointer value, or \item \tcode{remove_cvref_t} is a specialization of -the \tcode{move_only_function} class template, +the \tcode{move_only_function} or \tcode{copyable_function} class template, and \tcode{f} has no target object. \end{itemize} Otherwise, \tcode{*this} has a target object of type \tcode{VT} @@ -13942,7 +15127,7 @@ public: using result_type = R; - // \ref{func.wrap.copy.ctor}, constructors, assignments, and destructors + // \ref{func.wrap.copy.ctor}, constructors, assignments, and destructor copyable_function() noexcept; copyable_function(nullptr_t) noexcept; copyable_function(const copyable_function&); @@ -13991,7 +15176,7 @@ for which \tcode{is_nothrow_move_constructible_v} is \tcode{true}. \end{note} -\rSec4[func.wrap.copy.ctor]{Constructors, assignments, and destructors} +\rSec4[func.wrap.copy.ctor]{Constructors, assignments, and destructor} \indextext{copyable_function::is-callable-from@\tcode{copyable_function::\exposid{is-callable-from}}}% \begin{itemdecl} @@ -14370,9 +15555,11 @@ // \ref{func.wrap.ref.ctor}, constructors and assignment operators template function_ref(F*) noexcept; template constexpr function_ref(F&&) noexcept; - template constexpr function_ref(nontype_t) noexcept; - template constexpr function_ref(nontype_t, U&&) noexcept; - template constexpr function_ref(nontype_t, @\cv{}@ T*) noexcept; + template constexpr function_ref(constant_wrapper) noexcept; + template + constexpr function_ref(constant_wrapper, U&&) noexcept; + template + constexpr function_ref(constant_wrapper, @\cv{}@ T*) noexcept; constexpr function_ref(const function_ref&) noexcept = default; constexpr function_ref& operator=(const function_ref&) noexcept = default; @@ -14383,19 +15570,19 @@ private: template - static constexpr bool @\exposidnc{is-invocable-using}@ = @\seebelownc@; // \expos + static constexpr bool @\exposidnc{is-invocable-using}@ = @\seebelownc@; // \expos - R (*@\exposidnc{thunk-ptr}@)(@\exposidnc{BoundEntityType}@, Args&&...) noexcept(@\placeholdernc{noex}@); // \expos - @\exposidnc{BoundEntityType}@ @\exposidnc{bound-entity}@; // \expos + R (*@\exposidnc{thunk-ptr}@)(@\exposidnc{BoundEntityType}@, ArgTypes&&...) noexcept(@\placeholdernc{noex}@); // \expos + @\exposidnc{BoundEntityType}@ @\exposidnc{bound-entity}@; // \expos }; // \ref{func.wrap.ref.deduct}, deduction guides template function_ref(F*) -> function_ref; - template - function_ref(nontype_t) -> function_ref<@\seebelow@>; - template - function_ref(nontype_t, T&&) -> function_ref<@\seebelow@>; + template + function_ref(constant_wrapper) -> function_ref<@\seebelow@>; + template + function_ref(constant_wrapper, T&&) -> function_ref<@\seebelow@>; } \end{codeblock} @@ -14404,7 +15591,7 @@ \tcode{function_ref} stores a pointer to function \exposid{thunk-ptr} and an object \exposid{bound-entity}. -\exposid{bound-entity} has +The object \exposid{bound-entity} has an unspecified trivially copyable type \exposid{BoundEntityType}, that models \libconcept{copyable} and is capable of storing a pointer to object value or a pointer to function value. @@ -14417,10 +15604,12 @@ that models \libconcept{copyable}. \pnum -Within \ref{func.wrap.ref}, +Within subclause~\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. +\begin{codeblock} +decltype((@\placeholder{call-args}@))... +\end{codeblock} +denote \tcode{ArgTypes\&\&...} respectively. \rSec4[func.wrap.ref.ctor]{Constructors and assignment operators} @@ -14443,6 +15632,25 @@ \end{codeblock} \end{itemdescr} +\indextext{function_ref::is-convertible-from-specialization@\tcode{function_ref::\exposid{is-convertible-from-\brk{}specialization}}}% +\begin{itemdecl} +template + static constexpr bool @\exposid{is-convertible-from-specialization}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +If \tcode{F} denotes a specialization +\tcode{function_ref} +for some placeholders \cvqual{cv2} and \placeholder{noex2}, +\tcode{\exposid{is-convertible-from-specialization}} is equal to: +\begin{codeblock} +is_convertible_v && +is_convertible_v. +\end{codeblock} +Otherwise, \tcode{\exposid{is-convertible-from-specialization}} is \tcode{false}. +\end{itemdescr} + \indexlibraryctor{function_ref}% \begin{itemdecl} template function_ref(F* f) noexcept; @@ -14490,32 +15698,62 @@ \pnum \effects -Initializes -\exposid{bound-entity} with \tcode{addressof(f)}, and +If \tcode{\exposid{is-convertible-from-specialization}>} +is \tcode{false}, +initializes +\exposid{bound-en\-tity} with \tcode{addressof(f)}, and \exposid{thunk-ptr} with the address of a function \tcode{\placeholder{thunk}} such that -\tcode{\placeholder{thunk}(\exposid{bound-entity}, \placeholder{call-args}...)} +\tcode{\placeholder{thunk}(\exposid{bound-\brk{}entity}, \placeholder{call-args}...)} is expression-equivalent\iref{defns.expression.equivalent} to \tcode{invoke_r(static_cast<\cv{} T\&>(f), \placeholder{call-args}...)}. +Otherwise, initializes \exposid{bound-entity} +with the value of \tcode{f.\exposid{bound-entity}} and +\exposid{thunk-\brk{}ptr} with the value of \tcode{f.\exposid{thunk-ptr}}. + +\pnum +\remarks +If \tcode{remove_cvref_t} is a specialization of \tcode{function_ref}, +an implementation may initialize \exposid{bound-entity} +with the value of \tcode{f.\exposid{bound-entity}} and \exposid{thunk-ptr} +with the value of \tcode{f.\exposid{thunk-ptr}}. +\begin{example} +\begin{codeblock} +void f1(std::string); +void f2(std::string); + +function_ref r1(&f1); +function_ref r2(r1); +r2(""); // \tcode{f1} is invoked +r1 = &f2; +r2(""); // it is unspecified if \tcode{f1} or \tcode{f2} is invoked +\end{codeblock} +\end{example} \end{itemdescr} \indexlibraryctor{function_ref}% \begin{itemdecl} -template constexpr function_ref(nontype_t) noexcept; +template constexpr function_ref(constant_wrapper f) noexcept; \end{itemdecl} \begin{itemdescr} -\pnum -Let \tcode{F} be \tcode{decltype(f)}. - \pnum \constraints -\tcode{\exposid{is-invocable-using}} is \tcode{true}. +\tcode{\exposid{is-invocable-using}} is \tcode{true}. \pnum \mandates +\begin{itemize} +\item If \tcode{is_pointer_v || is_member_pointer_v} is \tcode{true}, -then \tcode{f != nullptr} is \tcode{true}. +then \tcode{f.value != nullptr} is \tcode{true}, and +\item +if \tcode{ArgTypes} is not an empty pack and +all types in \tcode{remove_cvref_t...} +satisfy \exposconcept{constexpr-param} then +\tcode{constant_wrapper<\placeholdernc{INVOKE}(f.value, remove_cvref_t::\newline value...)>} +is not a valid type. +\end{itemize} \pnum \effects @@ -14526,31 +15764,30 @@ such that \tcode{\placeholder{thunk}(\exposid{bound-entity}, \placeholder{call-args}...)} is expression-equivalent\iref{defns.expression.equivalent} to -\tcode{invoke_r(f, \placeholder{call-args}...)}. +\tcode{invoke_r(f.value, \placeholder{call-args}...)}. \end{itemdescr} \indexlibraryctor{function_ref}% \begin{itemdecl} -template - constexpr function_ref(nontype_t, U&& obj) noexcept; +template + constexpr function_ref(constant_wrapper f, U&& obj) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -Let \tcode{T} be \tcode{remove_reference_t} and -\tcode{F} be \tcode{decltype(f)}. +Let \tcode{T} be \tcode{remove_reference_t}. \pnum \constraints \begin{itemize} \item \tcode{is_rvalue_reference_v} is \tcode{false}, and -\item \tcode{\exposid{is-invocable-using}} is \tcode{true}. +\item \tcode{\exposid{is-invocable-using}} is \tcode{true}. \end{itemize} \pnum \mandates If \tcode{is_pointer_v || is_member_pointer_v} is \tcode{true}, -then \tcode{f != nullptr} is \tcode{true}. +then \tcode{f.value != nullptr} is \tcode{true}. \pnum \effects @@ -14560,27 +15797,24 @@ such that \tcode{\placeholder{thunk}(\exposid{bound-entity}, \placeholder{call-args}...)} is expression-equivalent\iref{defns.expression.equivalent} to -\tcode{invoke_r(f, static_cast<\cv{} T\&>(obj), \placeholder{call-args}...)}. +\tcode{invoke_r(f.value, static_cast<\cv{} T\&>(obj), \placeholder{call-args}...)}. \end{itemdescr} \indexlibraryctor{function_ref}% \begin{itemdecl} -template - constexpr function_ref(nontype_t, @\cv{}@ T* obj) noexcept; +template + constexpr function_ref(constant_wrapper f, @\cv{}@ T* obj) noexcept; \end{itemdecl} \begin{itemdescr} -\pnum -Let \tcode{F} be \tcode{decltype(f)}. - \pnum \constraints -\tcode{\exposid{is-invocable-using}} is \tcode{true}. +\tcode{\exposid{is-invocable-using}} is \tcode{true}. \pnum \mandates If \tcode{is_pointer_v || is_member_pointer_v} is \tcode{true}, -then \tcode{f != nullptr} is \tcode{true}. +then \tcode{f.value != nullptr} is \tcode{true}. \pnum \expects @@ -14595,7 +15829,7 @@ such that \tcode{\placeholder{thunk}(\exposid{bound-entity}, \placeholder{call-args}...)} is expression-equivalent\iref{defns.expression.equivalent} to -\tcode{invoke_r(f, obj, \placeholder{call-args}...)}. +\tcode{invoke_r(f.value, obj, \placeholder{call-args}...)}. \end{itemdescr} \indexlibrarymember{operator=}{function_ref}% @@ -14607,9 +15841,9 @@ \pnum \constraints \begin{itemize} -\item \tcode{T} is not the same type as \tcode{function_ref}, +\item \tcode{\exposid{is-convertible-from-specialization}} is \tcode{false}, \item \tcode{is_pointer_v} is \tcode{false}, and -\item \tcode{T} is not a specialization of \tcode{nontype_t}. +\item \tcode{T} is not a specialization of \tcode{constant_wrapper}. \end{itemize} \end{itemdescr} @@ -14641,13 +15875,13 @@ \end{itemdescr} \begin{itemdecl} -template - function_ref(nontype_t) -> function_ref<@\seebelow@>; +template + function_ref(constant_wrapper) -> function_ref<@\seebelow@>; \end{itemdecl} \begin{itemdescr} \pnum -Let \tcode{F} be \tcode{remove_pointer_t}. +Let \tcode{F} be \tcode{remove_pointer_t}. \pnum \constraints @@ -14659,14 +15893,11 @@ \end{itemdescr} \begin{itemdecl} -template - function_ref(nontype_t, T&&) -> function_ref<@\seebelow@>; +template + function_ref(constant_wrapper, T&&) -> function_ref<@\seebelow@>; \end{itemdecl} \begin{itemdescr} -\pnum -Let \tcode{F} be \tcode{decltype(f)}. - \pnum \constraints %FIXME: R and E should be defined outside of these constraints. @@ -14681,7 +15912,7 @@ in which case let \tcode{R} be \tcode{invoke_result_t}, \tcode{A...} be an empty pack, and -\tcode{E} be \tcode{false}, or +\tcode{E} be \tcode{true}, or \item \tcode{F} is of the form \tcode{R(*)(G, A...) noexcept(E)} for a type \tcode{G}. @@ -15083,6 +16314,12 @@ template constexpr int bit_width(T x) noexcept; + // \ref{bit.shift}, shifting + template + constexpr T shl(T x, S s) noexcept; + template + constexpr T shr(T x, S s) noexcept; + // \ref{bit.rotate}, rotating template constexpr T rotl(T x, int s) noexcept; @@ -15101,6 +16338,16 @@ template constexpr int popcount(T x) noexcept; + // \ref{bit.permute}, permutation + template + constexpr T bit_reverse(T x) noexcept; + template + constexpr T bit_repeat(T x, int l); + template + constexpr T bit_compress(T x, T m) noexcept; + template + constexpr T bit_expand(T x, T m) noexcept; + // \ref{bit.endian}, endian enum class endian { little = @\seebelow@, @@ -15127,6 +16374,11 @@ \item \tcode{is_trivially_copyable_v} is \tcode{true}. \end{itemize} +\pnum +\constantwhen +Neither \tcode{To} nor \tcode{From} +has constexpr-unknown representation\iref{expr.const.core}. + \pnum \returns An object of type \tcode{To}. @@ -15134,10 +16386,11 @@ 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. +Every trivially copyable object +among the result and each object created within it +acquires the value representation produced; +if any such object does not receive a value, +the behavior is undefined. 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 @@ -15161,19 +16414,6 @@ 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. - -\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}} @@ -15254,7 +16494,7 @@ \remarks A function call expression that violates the precondition in the \expects element -is not a core constant expression\iref{expr.const}. +is not a core constant expression\iref{expr.const.core}. \end{itemdescr} \indexlibraryglobal{bit_floor}% @@ -15295,6 +16535,48 @@ \end{itemdescr} +\rSec2[bit.shift]{Shifting} + +\pnum +Within this subclause, +the result $r$ of an arithmetic operation is +first represented in a hypothetical integer type with sufficient range, +then converted to \tcode{T} as if by \tcode{static_cast($r$)}. + +\indexlibraryglobal{shl}% +\begin{itemdecl} +template + constexpr T shl(T x, S s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +Each of \tcode{T} and \tcode{S} +is a signed or unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +$x \times 2^s$ rounded towards negative infinity. +\end{itemdescr} + +\indexlibraryglobal{shr}% +\begin{itemdecl} +template + constexpr T shr(T x, S s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +Each of \tcode{T} and \tcode{S} +is a signed or unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +$x \times 2^{-s}$ rounded towards negative infinity. +\end{itemdescr} + \rSec2[bit.rotate]{Rotating} \pnum @@ -15445,6 +16727,156 @@ The number of \tcode{1} bits in the value of \tcode{x}. \end{itemdescr} +\rSec2[bit.permute]{Permutation} + +\pnum +In the following descriptions, +\begin{itemize} +\item +let $N$ denote the value of \tcode{numeric_limits::digits}, +\item +let $\alpha_n$ denote the value of the $n^\text{th}$ least significant bit +in the base-2 representation of an integer $\alpha$, +so that $\alpha$ equals $\sum_{n=0}^{N-1} \alpha_n 2^n$, and +\item +let $\sigma(\alpha, n) = \sum_{k=0}^{n-1} \alpha_k$ +be the count of one-bits among the lowest $n$ bits of $\alpha$. +\end{itemize} + +\indexlibraryglobal{bit_reverse}% +\begin{itemdecl} +template + constexpr T bit_reverse(T x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is an unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +$\mathsf{reverse}(x)$, where +$\mathsf{reverse}$ is given by \eqref{bit.permute.reverse}, and +$x$ is \tcode{x}. +\begin{formula}{bit.permute.reverse} +\mathsf{reverse}(x) = \sum_{n=0}^{N-1} x_n \, 2^{N-n-1} +\end{formula} + +\pnum +\begin{note} +\tcode{bit_reverse(bit_reverse(x))} equals \tcode{x}. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{bit_repeat}% +\begin{itemdecl} +template + constexpr T bit_repeat(T x, int l); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is an unsigned integer type\iref{basic.fundamental}. + +\pnum +\expects +\tcode{l} is greater than zero. + +\pnum +\returns +$\mathsf{repeat}(x, l)$, where +$\mathsf{repeat}$ is given by \eqref{bit.permute.repeat}, +$x$ is \tcode{x}, and +$l$ is \tcode{l}. +\begin{formula}{bit.permute.repeat} +\mathsf{repeat}(x, l) = \sum_{n=0}^{N-1} x_{(n \bmod l)} \, 2^n +\end{formula} + +\pnum +\throws +Nothing. + +\pnum +\remarks +A function call expression that violates the precondition in the \expects +element is not a core constant expression\iref{expr.const.core}. + +\pnum +\begin{example} +\tcode{bit_repeat(uint32_t\{0xc\}, 4)} equals \tcode{0xcccccccc}. +\end{example} +\end{itemdescr} + +\indexlibraryglobal{bit_compress}% +\begin{itemdecl} +template + constexpr T bit_compress(T x, T m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is an unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +$\mathsf{compress}(x, m)$, where +$\mathsf{compress}$ is given by \eqref{bit.permute.compress}, +$x$ is \tcode{x}, and +$m$ is \tcode{m}. +\begin{formula}{bit.permute.compress} +\mathsf{compress}(x, m) = + \sum_{n=0}^{N-1} m_n x_n \, 2^{\sigma(m, n)} +\end{formula} + +\pnum +\begin{example} +\tcode{bit_compress(0b\placeholder{ABCD}, 0b0101)} equals +\tcode{0b00\placeholder{BD}} +for any bits +\tcode{\placeholder{A}}, +\tcode{\placeholder{B}}, +\tcode{\placeholder{C}}, and +\tcode{\placeholder{D}}. +\end{example} +\end{itemdescr} + +\indexlibraryglobal{bit_expand}% +\begin{itemdecl} +template + constexpr T bit_expand(T x, T m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is an unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +$\mathsf{expand}(x, m)$, where +$\mathsf{expand}$ is given by \eqref{bit.permute.expand}, +$x$ is \tcode{x}, and +$m$ is \tcode{m}. +\begin{formula}{bit.permute.expand} +\mathsf{expand}(x, m) = + \sum_{n=0}^{N-1} m_n \, x_{\sigma(m, n)} \, 2^n +\end{formula} + +\pnum +\begin{example} +\tcode{bit_expand(0b\placeholder{ABCD}, 0b0101)} equals +\tcode{0b0\placeholder{C}0\placeholder{D}} +for any bits +\tcode{\placeholder{A}}, +\tcode{\placeholder{B}}, +\tcode{\placeholder{C}}, and +\tcode{\placeholder{D}}. +\end{example} +\end{itemdescr} + \rSec2[bit.endian]{Endian} \pnum @@ -15485,11 +16917,13 @@ \indexheader{stdbit.h}% \begin{codeblock} -#define @\libglobal{__STDC_VERSION_STDBIT_H__}@ 202311L +// all freestanding + +#define @\libmacro{__STDC_VERSION_STDBIT_H__}@ 202311L -#define @\libglobal{__STDC_ENDIAN_BIG__}@ @\seebelow@ -#define @\libglobal{__STDC_ENDIAN_LITTLE__}@ @\seebelow@ -#define @\libglobal{__STDC_ENDIAN_NATIVE__}@ @\seebelow@ +#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); @@ -15597,7 +17031,7 @@ 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} +specified in \xrefc{7.18}. \pnum \mandates @@ -15608,4 +17042,4 @@ the contents and meaning of the header \libheader{stdbit.h} are the same as the C standard library header \tcode{}. -\xref{\IsoCUndated{}:2024, 7.18} %% TODO: change to \xrefc{7.18} +\xrefc{7.18} diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index 6484384dc1..b0ed29aaaf 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -19,6 +19,381 @@ % % \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.defs} +\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} @@ -76,6 +451,12 @@ \removedxref{type.index.members} \removedxref{type.index.hash} +% CWG 2843 removed [uaxid.def.rfmt] +\removedxref{uaxid.def.rfmt} + +% P3016R6 Resolve inconsistencies in begin/end for valarray and braced intializers +\removedxref{support.initlist.range} + %%% Renamed sections. %%% Examples: % @@ -98,10 +479,37 @@ \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} + +% P3348R3 C++26 should refer to C23 not C17 +\removedxref{diff.header.assert.h} +\removedxref{diff.header.stdalign.h} +\removedxref{diff.header.stdbool.h} diff --git a/source/xrefprev b/source/xrefprev index 72e4f16ee5..c59156d80d 100644 --- a/source/xrefprev +++ b/source/xrefprev @@ -1,3072 +1,2757 @@ -\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 +uaxid.def.rfmt +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 5a61d41830..280fc1d423 100755 --- a/tools/check-output.sh +++ b/tools/check-output.sh @@ -36,34 +36,34 @@ 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/eq://;s/idx.*\..//' | + sed 's/}//g' | sed 's/^tab://;s/fig://;s/eq://;s/ub://;s/ubx://;s/ifndr://;s/ifndrx://;s/idx.*\..//' | grep -v '^[a-z.0-9]*$' | sed 's/^\(.*\)$/bad label \1/' | fail || failed=1 # Find grammar index entries missing a definition cat std-grammarindex.ind | - awk 'BEGIN { def=1 } /^ .item/ { if (def==0) { gsub("[{},]", "", item); print item } item=$NF; def=0; next } /hyperindexformat/ { def=1 }' | + awk 'BEGIN { def=1 } /^ .item/ { if (def==0) { gsub("[{},]", "", item); print item } item=$NF; def=0; next } /hyper(x{0,1})indexformat/ { def=1 }' | grep -v -- '-keyword$' | # xxx-keyword is special 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 }' | + 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 } /hyper(x{0,1})indexformat/ { 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/' | + sed 's/.hyper\(x\{0,1\}\)indexformat/\nhyperindexformat/;s/.hyperpage/\nhyperpage/g' | awk 'BEGIN { def=1 } /^ .item/ { if (def==0) { gsub("[{},]", "", item); print item } item=$NF; def=0; next } /hyperindexformat/ { def=1 }' | sed 's/^\(.*\)$/concept \1 has no definition/' | fail || failed=1 # Find undecorated concept names in code blocks patt="`cat std-conceptindex.ind | - sed 's/.hyperindexformat/\nhyperindexformat/;s/.hyperpage/\nhyperpage/' | + sed 's/.hyper\(x\{0,1\}\)indexformat/\nhyperindexformat/;s/.hyperpage/\nhyperpage/' | sed -n 's/^ .item.*{\([-a-z_]*\)}.*$/\1/p;s/^ .item.*frenchspacing \([a-z_]*\)}.*$/\1/p'`" patt="`echo $patt | sed 's/ /\\\\|/g'`" @@ -86,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. -function indexentries() { sed 's,\\glossaryentry{\(.*\)@.*,\1,' "$1" | LANG=C sort; } +# Cross references since C++17. +# Note: xrefprev should contain a sorted list of C++17 labels. +function indexentries() { sed 's,\\glossaryentry{\(.*\)@.*,\1,' "$1" | LC_ALL=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 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 336a38f1bc..779e1f7686 100755 --- a/tools/check-source.sh +++ b/tools/check-source.sh @@ -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 @@ -84,7 +87,7 @@ grep -n 'U+' $texfiles | fail 'use \\unicode or \\ucode or \\uname instead' || failed=1 # Discourage double-wrapping \tcode{\exposid{data_}} -grep -n '\\tcode{\\exposid{[a-zA-Z0-9_]*}}' $texfiles | +grep -n '\\tcode{\\exposid{[a-zA-Z0-9_-]*}}' $texfiles | fail 'double-wrapped \\exposid in \\tcode' || failed=1 # Hex digits inside \ucode and \unicode must be lowercase so that \textsc works @@ -94,9 +97,17 @@ grep -n 'unicode{[^}]*[^0-9a-f}][^}]*}' $texfiles | fail 'use lowercase hex digits inside \\unicode' || failed=1 # Use \iref instead of "(\ref", except for subclause ranges -grep -n '.(\\ref' $texfiles | grep -v -- "--" | +grep -n '.(\\ref{' $texfiles | grep -v -- "--" | fail 'use \\iref instead of (\\ref' || failed=1 +# \iref cannot be at the start of a line +grep -n '^\\iref' $texfiles | + fail '\\iref must be flush against the preceding word, not at the start of a line' || failed=1 + +# \iref cannot be preceded by space +grep -n ' \\iref' $texfiles | + fail '\\iref must not be preceded by space' || failed=1 + # Use \xrefc instead of "ISO C x.y.z" grep -n "^ISO C [0-9]*\." $texfiles | fail 'use \\xrefc instead' || failed=1 @@ -122,11 +133,15 @@ grep -ne 'template\s\+<' $texlib | # In library declarations, constexpr should not follow explicit grep -ne '\bexplicit\b.*\bconstexpr\b' $texlib | - fail 'explicit constexpr' || failed=1 + fail 'wrong order: explicit constexpr' || failed=1 # In library declarations, static should not follow constexpr grep -ne '\bconstexpr\b.*\sstatic\s' $texlib | - fail 'constexpr static' || failed=1 + fail 'wrong order: constexpr static' || failed=1 + +# In library declarations, type aliases should not use typename +grep -ne "using.*= typename" $texlib | + fail 'type alias with typename' || failed=1 # "Class" heading without namespace for f in $texlib; do @@ -140,6 +155,9 @@ done | grep -F -ne ') const&' $texlib | fail 'no space between cv-qualifier and ref-qualifier' || failed=1 +grep -n '\\\(def\)\?\(lib\|expos\)concept{[a-z0-9_-]*[^a-z0-9_}-][a-z0-9_-]*}' $texlib | + fail 'bad concept name' || failed=1 + # \begin{example/note} with non-whitespace in front on the same line. grep -ne '^.*[^ ]\s*\\\(begin\|end\){\(example\|note\)}' $texfiles | fail "non-whitespace before note/example begins" || failed=1 @@ -194,9 +212,9 @@ done | fail '"shall", "should", or "may" inside a note' || failed=1 # Comma after e.g. and i.e. -grep -n "e\.g\.[^,]" $texfiles | +grep -nP "e\.g\.(?!,)" $texfiles | fail '"e.g." must be followed by a comma' -grep -n "i\.e\.[^,]" $texfiles | +grep -nP "i\.e\.(?!,)" $texfiles | fail '"i.e." must be followed by a comma' @@ -245,7 +263,7 @@ done | fail 'subclause without siblings' || failed=1 for f in $texlibdesc; do sed -n '/begin{itemdescr}/,/end{itemdescr}/{=;p;}' < $f | sed '/^[0-9]\+$/{N;s/\n/:/;}' | sed "s/.*/$f:&/" | - awk -F: '$3 ~ /^\\pnum/ { seenpnum=1; next } $3 ~ /^\\index/ { next } $3 ~ /^\\(constraints|mandates|expects|effects|sync|ensures|returns|throws|complexity|remarks|errors|recommended)/ { if(seenpnum == 0) { print $0 } } { seenpnum=0 }' + awk -F: '$3 ~ /^\\pnum/ { seenpnum=1; next } $3 ~ /^\\index/ { next } $3 ~ /^\\(constraints|mandates|constantwhen|expects|hardexpects|effects|sync|ensures|returns|throws|complexity|remarks|errors|recommended)/ { if(seenpnum == 0) { print $0 } } { seenpnum=0 }' done | fail '\\pnum missing' || failed=1 diff --git a/tools/gitconfig.sh b/tools/gitconfig.sh index 9a6d697447..b0488b1b9e 100755 --- a/tools/gitconfig.sh +++ b/tools/gitconfig.sh @@ -1,3 +1,16 @@ #!/bin/sh git config diff.orderFile .gitorder git config diff.c++draft.xfuncname '\\rSec[0-9]+(\[.*\])\{' + +precommit="$(git rev-parse --git-dir)/hooks/pre-commit" + +test -f "${precommit}" && exit +read -p "Install 'make check' pre-commit hook? [Y/n] " hook +if [ -z "${hook}" -o "${hook}" = "y" -o "${hook}" = "Y" ]; then + cat < "${precommit}" +#!/bin/sh +cd \$(git rev-parse --show-toplevel)/source +make check +EOF + chmod +x "${precommit}" +fi diff --git a/tools/makereport b/tools/makereport index 2cccd3cad7..aa19b3c3ab 100755 --- a/tools/makereport +++ b/tools/makereport @@ -60,11 +60,10 @@ h1,h2,h3,h4,h5,h6 { color:#111; line-height: 135%; } -h4,h5,h6{ font-weight: bold; } h1{ font-size:2.5em; } h2{ font-size:2em; border-bottom:1px solid silver; padding-bottom: 5px; } h3{ font-size:1.5em; margin: 1em 0 0.5em 0; } -h4{ font-size:1.2em; } +h4{ font-size:1.2em; margin: 1em 0 0.5em 0; } h5{ font-size:1em; } h6{ font-size:0.9em; } 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; }