diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000000..e6fa6d7203 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,73 @@ +# A workflow to run our check script. + +name: check + +on: [pull_request, push] + +defaults: + run: + shell: bash + working-directory: source + +jobs: + run-checks: + name: Run checks on ${{matrix.cfg.name}} + runs-on: ${{matrix.cfg.os}} + + strategy: + matrix: + cfg: + - { name: 'Linux', os: 'ubuntu-24.04' } + - { name: 'MacOS', os: 'macos-15' } + + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: install GNU tools + if: matrix.cfg.os == 'macos-15' + run: | + brew install gnu-sed + 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-15' + run: brew update + + - name: update-apt-cache + if: matrix.cfg.os == 'ubuntu-24.04' + run: sudo apt-get update + + - name: install (Linux) + 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-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 environ layouts enumitem l3packages l3kernel imakeidx splitindex xstring + + - name: make (Linux) + if: matrix.cfg.os == 'ubuntu-24.04' + run: make quiet + + - name: make (MacOS) + 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-24.04' + uses: actions/upload-artifact@v4 + with: + name: draft-snapshot + path: source/std.pdf diff --git a/.gitignore b/.gitignore index 133ada281d..9286aae13e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.aux std.pdf +std-gram.ext *.idx *.toc *.log @@ -9,10 +10,15 @@ std.pdf *.ilg *.ind *.tmp +*.gls +*.glo .DS_Store *.fdb_latexmk *.fls +*.xtr .tags .tags_sorted_by_file tools/sections *.synctex.gz +*.synctex* +.check.stamp diff --git a/.gitorder b/.gitorder new file mode 100644 index 0000000000..edc39fbf98 --- /dev/null +++ b/.gitorder @@ -0,0 +1,45 @@ +source/std.tex +source/layout.tex +source/styles.tex +source/macros.tex +source/tables.tex +source/cover-*.tex +source/front.tex +source/preface.tex +source/intro.tex +source/lex.tex +source/basic.tex +source/expressions.tex +source/statements.tex +source/declarations.tex +source/modules.tex +source/classes.tex +source/overloading.tex +source/templates.tex +source/exceptions.tex +source/preprocessor.tex +source/lib-intro.tex +source/support.tex +source/concepts.tex +source/diagnostics.tex +source/memory.tex +source/meta.tex +source/utilities.tex +source/containers.tex +source/iterators.tex +source/ranges.tex +source/algorithms.tex +source/strings.tex +source/text.tex +source/numerics.tex +source/time.tex +source/iostreams.tex +source/threads.tex +source/exec.tex +source/grammar.tex +source/limits.tex +source/compatibility.tex +source/future.tex +source/uax31.tex +source/back.tex +source/xrefdelta.tex diff --git a/README.rst b/README.rst index e221df9fb2..c737a81a71 100644 --- a/README.rst +++ b/README.rst @@ -11,7 +11,7 @@ Get involved: - `How to submit an editorial issue `_ - `How to tell if an issue is editorial `_ -- `How to submit a new issue/defect report `_ for non-editorial issues +- `How to submit a new issue/defect report `_ for non-editorial issues More information about the C++ standard can be found at `isocpp.org `_. @@ -22,57 +22,83 @@ 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 + sudo tlmgr install latexmk isodate substr relsize ulem fixme rsfs extract layouts enumitem l3packages l3kernel imakeidx splitindex xstring ------------- -Instructions ------------- +--------------------------------------- +Getting Started on Debian-based Systems +--------------------------------------- -To typeset the draft document, from the ``source`` directory: +Install the following packages:: -#. run ``latexmk -pdf std`` + sudo apt-get install latexmk texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended lmodern -That's it! You should now have an ``std.pdf`` containing the typeset draft. +------------------------- +Getting Started on Fedora +------------------------- + +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 + +----------------------------- +Getting Started on Arch Linux +----------------------------- + +Install the following packages:: + + pacman -S make texlive-latexextra texlive-binextra texlive-plaingeneric texlive-fontsrecommended -Alternative instructions -======================== +----------------------------- +Getting Started on Microsoft Windows +----------------------------- -If you can't use latexmk for some reason, you can use the Makefiles instead: +Install Perl (for example, using a `Cygwin installation `_ and adding perl. +See `sample instructions `_ for more details) -#. run ``make rebuild`` -#. run ``make reindex`` +Install `MiKTeX `_ -If you can't use latexmk or make for some reason, you can run LaTeX manually instead: +Alternatively, you can `install WSL `_ +and a Linux distribution, +and follow the instructions for Linux above. -#. run ``pdflatex std`` until there are no more changed labels or changed tables -#. run ``makeindex generalindex`` -#. run ``makeindex libraryindex`` -#. run ``makeindex grammarindex`` -#. run ``makeindex impldefindex`` -#. run ``pdflatex std`` twice more. +------------ +Instructions +------------ + +To typeset the draft document, from the ``source`` directory run:: + + make + +That's it! You should now have an ``std.pdf`` containing the typeset draft. Generated input files ===================== To regenerate figures from .dot files, run:: - dot -o -Tpdf + make For example:: - dot -ofigstreampos.pdf -Tpdf figstreampos.dot + 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:: -To regenerate the grammar appendix, run the following from the source -directory:: + ../tools/check-source.sh - ../tools/makegram +After typesetting the document, +you can also check the output for further problems with:: -To regenerate the cross-references appendix, run the following from -the source directory:: + ../tools/check-output.sh - ../tools/makexref +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/.gitattributes b/papers/.gitattributes new file mode 100644 index 0000000000..0afd26b375 --- /dev/null +++ b/papers/.gitattributes @@ -0,0 +1 @@ +*.pdf -diff diff --git a/papers/n4431.pdf b/papers/n4431.pdf new file mode 100644 index 0000000000..2e4fe5587d Binary files /dev/null and b/papers/n4431.pdf differ diff --git a/papers/n4432.html b/papers/n4432.html new file mode 100644 index 0000000000..28daf8e4b1 --- /dev/null +++ b/papers/n4432.html @@ -0,0 +1,428 @@ +N4432 +

N4432 Editor's Report -- Working Draft, Standard for Programming Language C++

+ +

2015-04-10
+Richard Smith
+Google Inc
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to Jonathan Wakely for providing many editorial fixes.

+ +

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

+ +

New Papers

+ +
    +
  • N4431 is the current working draft. It replaces N4296.
  • +
  • N4432 is this Editor's Report for the current working draft.
  • +
+ +

Notable Changes to Issues and Papers as Moved

+ +

No motions have been voted into the working draft since N4296.

+ +

Other Notable Editorial Changes:

+ +

2013-04 CWG motion 4 moved that the proposed resolution of CWG1531 be adopted. +However, due to an oversight, the motion stated that the resolution be taken +from N3539 (which contains no wording for this issue) instead of the intended +N3674. As a result, no modification was made to the standard for this issue. +As the changes are editorial in nature, and the intent of the committee is +clear, this Working Draft incorporates the changes for CWG1531 specified in +N3674.

+ +

A bug has been fixed that resulted in cross-references to definitions +(in [intro.defs] and [definitions]) missing the final number from their +section.

+ +

Minor Editorial Fixes

+ +

A log of all editorial fixes made since N4296 is below:

+ +
commit 47bd8e96cf0528cab40c467cf65da25e7bd70bf5
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Apr 9 13:23:27 2015 -0700
+
+    Add back redundant 'of arithmetic type' requirement at request of lib-37799.
+
+commit 8866e4d6d43bc4b7456852e64a2838681a9c77d3
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Apr 8 19:13:26 2015 -0700
+
+    CWG1531 Definition of "access" (verb)
+
+    This was supposed to be moved by 201304 CWG motion 4, but that motion
+    referred to N3539, which did not have wording for this issue, so it
+    was technically never moved. However, the clear intent of the committee
+    was to move this resolution and the resolution is editorial in nature.
+
+    Fixes #464.
+
+commit 44e17b8279de070a676a2bcfb7a590aa541f4a5f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Apr 8 17:41:21 2015 -0700
+
+    [xref] Fix cross-references to definitions to be numbered correctly.
+
+commit 80eaed01b588b21032541fcd6abb36bc516a7c00
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Apr 8 13:29:51 2015 -0700
+
+    Update CD cover to match latest ISO copyright notice.
+
+commit f961a9bed91a875108aa8c31a8dc6f14378b645d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Apr 8 12:02:15 2015 -0700
+
+    [c.math] Fix use of undefined term "arithmetic argument" to the intended "argument of arithmetic type".
+
+    Remove the resulting "of arithmetic type" in two places where the type
+    is constrained to be a specific arithmetic type later in the same
+    sentence.
+
+commit c40cc1478a486ff5bc69bb4bb0184bca2aa901bc
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Apr 8 11:51:39 2015 -0700
+
+    [basic.fundamental] Fix misleading and miscapitalized "that is" in footnote.
+
+commit f4cb613217ea77ebbc2ee91bd3bb55e00043dd89
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Apr 8 11:17:52 2015 -0700
+
+    [dcl.dcl] Use a less contentious example for static_assert.
+
+commit 43d9b349778d1c158cba0da61f2b3bb12dd55a19
+Author: Aaron Ballman <aaron@aaronballman.com>
+Date:   Wed Apr 8 17:31:14 2015 -0400
+
+    Adding a bullet to [except.terminate] for condition variables
+
+commit 50954bd1eb218fc3477940ef988b6ed9b83de3cc
+Author: Nathan W. Panike <nathan.panike@gmail.com>
+Date:   Tue Apr 7 07:27:40 2015 -0400
+
+    Fix formatting of P
+
+commit 0b7593f0e716910bab7c1511533b2f9b5a886de1
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Sun Apr 5 12:25:27 2015 +0000
+
+    [support.start.term] Add missing semicolon.
+
+commit 3698294637162bd746c1ce84e99bff9d7104c313
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Apr 1 18:38:26 2015 +0100
+
+    [iterator.operations], [is.heap] Remove indentation in itemdecl.
+
+commit bb810fa01fc903133b3217e1556bb1fefb58b6fe
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Fri Apr 3 11:53:24 2015 +0200
+
+    [basic.align], [syserr] Add missing semicolons.
+
+commit 5c4a33067cf73deac00a6f56a323107d5e25440c
+Author: Zhihao Yuan <lichray@gmail.com>
+Date:   Wed Apr 1 20:31:18 2015 -0400
+
+    [thread.lock.shared.cons] fix typos
+
+    From stl@
+
+commit d8d996265fcd2a656d03db1b0a448b6116870d1e
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Apr 1 14:43:19 2015 +0100
+
+    [bad.cast], [bad.typeid] Remove indentation in itemdecl.
+
+commit 8a91772aba47bdcbe3b2a57340d7ced656d44dd9
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Apr 1 14:39:11 2015 +0100
+
+    [bad.alloc] Remove indentation in itemdecl.
+
+commit 5dc7260ff4192beedf708dc45c9ba915daedaba1
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Mar 30 10:39:42 2015 +0100
+
+    [futures.async] Use American English spelling of "behavior"
+
+    Fixes #463.
+
+commit 5780ff8b184add41664bfb62cb5bee935907be8f
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Sat Mar 7 03:38:14 2015 -0500
+
+    Correct link in basic_ostream::flush() description
+
+    flush() "Behaves as an unformatted output function", but the link is to [ostream.formatted.reqmts]. Should link to [ostream.unformatted] like others in the same section.
+
+commit 5599ece8d063beab627a983aada25cfbdb1eeac7
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 27 15:51:20 2015 +0000
+
+    [unique.ptr], [func.require] Remove hyphens from "lvalue-reference"
+    and "rvalue-reference".
+
+    Fixes #446.
+
+commit 6e2e0a7ac9c17debedaf7b5c3b6143ba51644bd2
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Feb 23 21:12:15 2015 +0000
+
+    [locale.codecvt.virtuals] Use code font for integer literals.
+
+commit ae28126e4a088d44901debf7edf561b01502fa53
+Author: Mitsuru Kariya <kariya_mitsuru@hotmail.com>
+Date:   Fri Feb 13 01:02:15 2015 +0900
+
+    [swappable.requirements] add comma
+
+commit 70550aa2e9ea62bf53130f26778dbeb9cbef7b46
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jan 26 11:48:27 2015 -0800
+
+    [string::assign] Add missing comma in expression. Thanks to
+    tomalakgeretkal for reporting this.
+
+    Fixes #434
+
+commit ff1809d09d24895bd19b4ef5a886893dc0fcb3f4
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Thu Jan 15 22:20:29 2015 +0800
+
+    [temp.deduct] Correct "void ()(const int, int[5])"
+
+commit e1fffe915cd926bcc810e0a0f4c5bf91d51ff222
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jan 7 16:44:07 2015 +0000
+
+    [template.valarray] Use injected-class-name in valarray.
+
+    Reported by Akira Takahashi. Fixes #345.
+
+commit 6168263c640b1c93aedc1d174a46ef7b57b0f423
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Dec 18 10:33:56 2014 -0800
+
+    [dcl.spec.auto] Add implied word "trailing-return-type" to clarify the
+    meaning of this sentence.
+
+commit 9099ef8515e45d8751e9d400ca206f755e8cdbed
+Author: Andrew Sutton <andrew.n.sutton@gmail.com>
+Date:   Wed Dec 17 14:15:00 2014 -0500
+
+    [stmt.ranged] Change italics to grammarterm.
+
+commit 4938a49bff99d11e0249126c656439d01998fc7b
+Author: Andrew Sutton <andrew.n.sutton@gmail.com>
+Date:   Wed Dec 17 14:10:11 2014 -0500
+
+    [stmt.ranged] Fix terminal formatting in BNF.
+
+commit 8b86d944c43c2cdf7e1784f9002d5bb544eb17d4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 13 23:58:36 2014 +0000
+
+    [{i,o}stream.manip] Remove redundant "namespace std"
+
+commit 668cad579f3fe748e717594ffdda7de7c2e0f41e
+Author: Foo Bar <tkoeppe@google.com>
+Date:   Sat Dec 13 23:15:43 2014 +0000
+
+    [dcl.link] Fix indentation of example code
+
+commit ac5c5dc798052fc5a080cdd9893de31bf0447065
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Dec 9 17:22:21 2014 -0800
+
+    [dcl.fct] Format '...' in fixed-width font in the grammar and when it's
+    later referred to in the text.
+
+commit bbd976ee7671481ef56521ded59a6bb3f12ba3bf
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sat Dec 6 18:56:19 2014 +0800
+
+    [expr.sizeof] redundant wording
+
+    "an enumeration type whose underlying type is not fixed before all its enumerators have been declared" is an incomplete type.
+
+commit 5e4fe90be52ddebf0314b4d98837408910a895b9
+Author: Mitsuru Kariya <kariya_mitsuru@hotmail.com>
+Date:   Tue Dec 2 03:20:43 2014 +0900
+
+    [re.regiter.incr] fix typo
+
+    The fuction position() is a member of the match_results, not a member of the sub_match.
+
+commit 4025fe4b1a5ae3ef18c4095be7f054336f22a179
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 30 15:17:20 2014 -0800
+
+    Editorial fixes from review by Mike Miller.
+
+commit 32ab3eccb7d58a1f2bac90ba336d9f11bea8e4b2
+Author: rkawulak <Robert.Kawulak@gmail.com>
+Date:   Sat Nov 29 20:58:36 2014 +0100
+
+    Added missing line breaks for wording incorporated from N4230.
+
+commit fd6afa3df49878d0f97575cc89b869b07132e959
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 26 18:16:04 2014 -0800
+
+    [basic.stc.auto] Fix apparent contradiction: the `static` implied by
+    `thread_local` is not explicit, so this wording could be read as
+    claiming that `thread_local` local variables have automatic storage
+    duration, contradicting wording in several other parts of the standard
+    and the design intent.
+
+commit 7b28103a5857c141b559744a287b835f797992c5
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 24 12:28:58 2014 -0800
+
+    [unord.map.cnstr] Fix misapplication of edit for LWG2230.
+
+    Reported by Alisdair Meredith.
+
+commit bc3a17ab763eab648a78dcdd17bede890c26ad03
+Author: Kevin M. Godby <kevin@godby.org>
+Date:   Thu Nov 20 18:36:05 2014 -0600
+
+    Fixes issue #409: undefined behavior index entry.
+
+commit 3a8fed91a2cff07758e95843a796f73f44224c3a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Nov 19 23:48:49 2014 +0000
+
+    [func.wrap.func.inv] Add missing semi-colon.
+
+    Reported by Stephan T. Lavavej. Fixes #408.
+
diff --git a/papers/n4432.md b/papers/n4432.md new file mode 100644 index 0000000000..d97fabb384 --- /dev/null +++ b/papers/n4432.md @@ -0,0 +1,302 @@ +# N4432 Editor's Report -- Working Draft, Standard for Programming Language C++ + +2015-04-10 +Richard Smith +Google Inc +`` + +## Acknowledgements + +Special thanks to Jonathan Wakely for providing many editorial fixes. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and those who have provided pull requests with fixes. + +## New Papers + + * N4431 is the current working draft. It replaces N4296. + * N4432 is this Editor's Report for the current working draft. + +### Notable Changes to Issues and Papers as Moved + +No motions have been voted into the working draft since N4296. + +### Other Notable Editorial Changes: + +2013-04 CWG motion 4 moved that the proposed resolution of CWG1531 be adopted. +However, due to an oversight, the motion stated that the resolution be taken +from N3539 (which contains no wording for this issue) instead of the intended +N3674. As a result, no modification was made to the standard for this issue. +As the changes are editorial in nature, and the intent of the committee is +clear, this Working Draft incorporates the changes for CWG1531 specified in +N3674. + +A bug has been fixed that resulted in cross-references to definitions +(in [intro.defs] and [definitions]) missing the final number from their +section. + +## Minor Editorial Fixes + +A log of all editorial fixes made since N4296 is below: + + commit 47bd8e96cf0528cab40c467cf65da25e7bd70bf5 + Author: Richard Smith + Date: Thu Apr 9 13:23:27 2015 -0700 + + Add back redundant 'of arithmetic type' requirement at request of lib-37799. + + commit 8866e4d6d43bc4b7456852e64a2838681a9c77d3 + Author: Richard Smith + Date: Wed Apr 8 19:13:26 2015 -0700 + + CWG1531 Definition of "access" (verb) + + This was supposed to be moved by 201304 CWG motion 4, but that motion + referred to N3539, which did not have wording for this issue, so it + was technically never moved. However, the clear intent of the committee + was to move this resolution and the resolution is editorial in nature. + + Fixes #464. + + commit 44e17b8279de070a676a2bcfb7a590aa541f4a5f + Author: Richard Smith + Date: Wed Apr 8 17:41:21 2015 -0700 + + [xref] Fix cross-references to definitions to be numbered correctly. + + commit 80eaed01b588b21032541fcd6abb36bc516a7c00 + Author: Richard Smith + Date: Wed Apr 8 13:29:51 2015 -0700 + + Update CD cover to match latest ISO copyright notice. + + commit f961a9bed91a875108aa8c31a8dc6f14378b645d + Author: Richard Smith + Date: Wed Apr 8 12:02:15 2015 -0700 + + [c.math] Fix use of undefined term "arithmetic argument" to the intended "argument of arithmetic type". + + Remove the resulting "of arithmetic type" in two places where the type + is constrained to be a specific arithmetic type later in the same + sentence. + + commit c40cc1478a486ff5bc69bb4bb0184bca2aa901bc + Author: Richard Smith + Date: Wed Apr 8 11:51:39 2015 -0700 + + [basic.fundamental] Fix misleading and miscapitalized "that is" in footnote. + + commit f4cb613217ea77ebbc2ee91bd3bb55e00043dd89 + Author: Richard Smith + Date: Wed Apr 8 11:17:52 2015 -0700 + + [dcl.dcl] Use a less contentious example for static_assert. + + commit 43d9b349778d1c158cba0da61f2b3bb12dd55a19 + Author: Aaron Ballman + Date: Wed Apr 8 17:31:14 2015 -0400 + + Adding a bullet to [except.terminate] for condition variables + + commit 50954bd1eb218fc3477940ef988b6ed9b83de3cc + Author: Nathan W. Panike + Date: Tue Apr 7 07:27:40 2015 -0400 + + Fix formatting of P + + commit 0b7593f0e716910bab7c1511533b2f9b5a886de1 + Author: FrankHB + Date: Sun Apr 5 12:25:27 2015 +0000 + + [support.start.term] Add missing semicolon. + + commit 3698294637162bd746c1ce84e99bff9d7104c313 + Author: Jonathan Wakely + Date: Wed Apr 1 18:38:26 2015 +0100 + + [iterator.operations], [is.heap] Remove indentation in itemdecl. + + commit bb810fa01fc903133b3217e1556bb1fefb58b6fe + Author: Eelis van der Weegen + Date: Fri Apr 3 11:53:24 2015 +0200 + + [basic.align], [syserr] Add missing semicolons. + + commit 5c4a33067cf73deac00a6f56a323107d5e25440c + Author: Zhihao Yuan + Date: Wed Apr 1 20:31:18 2015 -0400 + + [thread.lock.shared.cons] fix typos + + From stl@ + + commit d8d996265fcd2a656d03db1b0a448b6116870d1e + Author: Jonathan Wakely + Date: Wed Apr 1 14:43:19 2015 +0100 + + [bad.cast], [bad.typeid] Remove indentation in itemdecl. + + commit 8a91772aba47bdcbe3b2a57340d7ced656d44dd9 + Author: Jonathan Wakely + Date: Wed Apr 1 14:39:11 2015 +0100 + + [bad.alloc] Remove indentation in itemdecl. + + commit 5dc7260ff4192beedf708dc45c9ba915daedaba1 + Author: Jonathan Wakely + Date: Mon Mar 30 10:39:42 2015 +0100 + + [futures.async] Use American English spelling of "behavior" + + Fixes #463. + + commit 5780ff8b184add41664bfb62cb5bee935907be8f + Author: timsong-cpp + Date: Sat Mar 7 03:38:14 2015 -0500 + + Correct link in basic_ostream::flush() description + + flush() "Behaves as an unformatted output function", but the link is to [ostream.formatted.reqmts]. Should link to [ostream.unformatted] like others in the same section. + + commit 5599ece8d063beab627a983aada25cfbdb1eeac7 + Author: Jonathan Wakely + Date: Fri Feb 27 15:51:20 2015 +0000 + + [unique.ptr], [func.require] Remove hyphens from "lvalue-reference" + and "rvalue-reference". + + Fixes #446. + + commit 6e2e0a7ac9c17debedaf7b5c3b6143ba51644bd2 + Author: Jonathan Wakely + Date: Mon Feb 23 21:12:15 2015 +0000 + + [locale.codecvt.virtuals] Use code font for integer literals. + + commit ae28126e4a088d44901debf7edf561b01502fa53 + Author: Mitsuru Kariya + Date: Fri Feb 13 01:02:15 2015 +0900 + + [swappable.requirements] add comma + + commit 70550aa2e9ea62bf53130f26778dbeb9cbef7b46 + Author: Richard Smith + Date: Mon Jan 26 11:48:27 2015 -0800 + + [string::assign] Add missing comma in expression. Thanks to + tomalakgeretkal for reporting this. + + Fixes #434 + + commit ff1809d09d24895bd19b4ef5a886893dc0fcb3f4 + Author: S. B. Tam + Date: Thu Jan 15 22:20:29 2015 +0800 + + [temp.deduct] Correct "void ()(const int, int[5])" + + commit e1fffe915cd926bcc810e0a0f4c5bf91d51ff222 + Author: Jonathan Wakely + Date: Wed Jan 7 16:44:07 2015 +0000 + + [template.valarray] Use injected-class-name in valarray. + + Reported by Akira Takahashi. Fixes #345. + + commit 6168263c640b1c93aedc1d174a46ef7b57b0f423 + Author: Richard Smith + Date: Thu Dec 18 10:33:56 2014 -0800 + + [dcl.spec.auto] Add implied word "trailing-return-type" to clarify the + meaning of this sentence. + + commit 9099ef8515e45d8751e9d400ca206f755e8cdbed + Author: Andrew Sutton + Date: Wed Dec 17 14:15:00 2014 -0500 + + [stmt.ranged] Change italics to grammarterm. + + commit 4938a49bff99d11e0249126c656439d01998fc7b + Author: Andrew Sutton + Date: Wed Dec 17 14:10:11 2014 -0500 + + [stmt.ranged] Fix terminal formatting in BNF. + + commit 8b86d944c43c2cdf7e1784f9002d5bb544eb17d4 + Author: Thomas Köppe + Date: Sat Dec 13 23:58:36 2014 +0000 + + [{i,o}stream.manip] Remove redundant "namespace std" + + commit 668cad579f3fe748e717594ffdda7de7c2e0f41e + Author: Foo Bar + Date: Sat Dec 13 23:15:43 2014 +0000 + + [dcl.link] Fix indentation of example code + + commit ac5c5dc798052fc5a080cdd9893de31bf0447065 + Author: Richard Smith + Date: Tue Dec 9 17:22:21 2014 -0800 + + [dcl.fct] Format '...' in fixed-width font in the grammar and when it's + later referred to in the text. + + commit bbd976ee7671481ef56521ded59a6bb3f12ba3bf + Author: S. B. Tam + Date: Sat Dec 6 18:56:19 2014 +0800 + + [expr.sizeof] redundant wording + + "an enumeration type whose underlying type is not fixed before all its enumerators have been declared" is an incomplete type. + + commit 5e4fe90be52ddebf0314b4d98837408910a895b9 + Author: Mitsuru Kariya + Date: Tue Dec 2 03:20:43 2014 +0900 + + [re.regiter.incr] fix typo + + The fuction position() is a member of the match_results, not a member of the sub_match. + + commit 4025fe4b1a5ae3ef18c4095be7f054336f22a179 + Author: Richard Smith + Date: Sun Nov 30 15:17:20 2014 -0800 + + Editorial fixes from review by Mike Miller. + + commit 32ab3eccb7d58a1f2bac90ba336d9f11bea8e4b2 + Author: rkawulak + Date: Sat Nov 29 20:58:36 2014 +0100 + + Added missing line breaks for wording incorporated from N4230. + + commit fd6afa3df49878d0f97575cc89b869b07132e959 + Author: Richard Smith + Date: Wed Nov 26 18:16:04 2014 -0800 + + [basic.stc.auto] Fix apparent contradiction: the `static` implied by + `thread_local` is not explicit, so this wording could be read as + claiming that `thread_local` local variables have automatic storage + duration, contradicting wording in several other parts of the standard + and the design intent. + + commit 7b28103a5857c141b559744a287b835f797992c5 + Author: Richard Smith + Date: Mon Nov 24 12:28:58 2014 -0800 + + [unord.map.cnstr] Fix misapplication of edit for LWG2230. + + Reported by Alisdair Meredith. + + commit bc3a17ab763eab648a78dcdd17bede890c26ad03 + Author: Kevin M. Godby + Date: Thu Nov 20 18:36:05 2014 -0600 + + Fixes issue #409: undefined behavior index entry. + + commit 3a8fed91a2cff07758e95843a796f73f44224c3a + Author: Jonathan Wakely + Date: Wed Nov 19 23:48:49 2014 +0000 + + [func.wrap.func.inv] Add missing semi-colon. + + Reported by Stephan T. Lavavej. Fixes #408. diff --git a/papers/n4527.pdf b/papers/n4527.pdf new file mode 100644 index 0000000000..68b9e15e1c Binary files /dev/null and b/papers/n4527.pdf differ diff --git a/papers/n4528.html b/papers/n4528.html new file mode 100644 index 0000000000..425336c0a1 --- /dev/null +++ b/papers/n4528.html @@ -0,0 +1,384 @@ +N4528 +

N4528 Editor's Report -- Working Draft, Standard for Programming Language C++

+ +

2015-05-22
+Richard Smith
+Google Inc
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Very special thanks to Dawn Perchik, who performed nearly all the edits for +motions moved at Lenexa (any errors are mine).

+ +

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

+ +

New Papers

+ +
    +
  • N4527 is the current working draft. It replaces N4431.
  • +
  • N4528 is this Editor's Report for the current working draft.
  • +
+ +

Notable Changes to Issues and Papers as Moved

+ +

LWG motion 16

+ +

Subclause +[thread.sharedtimedmutex.requirements], "Shared timed mutex types", +remains nested directly under +[thread.mutex.requirements], "Mutex requirements", +rather than being made a subclause of +[thread.sharedmutex.requirements], "Shared mutex types". +This is consistent with the existing treatment of the sibling +subclauses "Mutex types" and "Timed mutex types".

+ +

Other Notable Editorial Changes:

+ +

No major editorial changes have been made since N4431.

+ +

Minor Editorial Fixes

+ +

A log of all editorial fixes made since N4431 is below:

+ +
commit fa7a721afa87126a59a74bfe2e7344a92d4ebc44
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat May 9 14:50:47 2015 -0500
+
+    [dcl.spec.auto] Deduction of auto in direct-list-initialization from a
+    double-braced init list will always fail. Use a more specific term here
+    to avoid suggesting otherwise.
+
+commit 84161dfb53dbc90564ec28da6e50d29c8bc379bd
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat May 9 09:41:12 2015 -0500
+
+    [class.union] Fix example to not use an ill-formed empty anonymous union.
+
+commit 1cfd96e0913891a1ebe491f66dd7ff88ed671901
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri May 8 10:11:30 2015 -0500
+
+    Punctuation following canonical type strings, such as "pointer to int",
+    go outside the quotation marks, because the quotation marks are part of
+    the technical content. Punctuation stays inside other quotation marks.
+
+commit 8ea266298379028a842d8d496441c0cec2e941a4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Apr 14 03:15:18 2015 -0700
+
+    [intro.defs] Formatting fixes and addition of some cross-references.
+
+commit d7544f51553e7db455a67aa014967f8ac079433c
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri May 8 17:56:24 2015 +0100
+
+    [c.math] Add rand to index of library names.
+
+commit df5a2ddc32934e7539063997888d1fc6c1189d0f
+Author: AbleBacon <AbleBacon@users.noreply.github.com>
+Date:   Wed May 6 11:41:17 2015 -0500
+
+    Update intro.tex
+
+commit cfabe9354fe3fdc8e93dbc0ddc082102f385c0db
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Sun May 3 00:36:50 2015 +0800
+
+    [char.traits.require]: Use "class template" instead of "struct template".
+
+commit 3b580b26fe49d01e352d6c24fc054ad586c76f78
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Sun May 3 00:36:05 2015 +0800
+
+    [char.traits]: Use "class template" instead of "struct template".
+
+commit 95c971d52cee1558d607703a209ea70b84d6aa93
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Sun May 3 00:34:33 2015 +0800
+
+    [char.traits.specializations]: Use "class template" instead of "template struct".
+
+commit ed49c8a8cc7b9899ce2ace9020e4eb6ee426ca25
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Sun May 3 00:32:36 2015 +0800
+
+    [allocator.requirements]: Use "class template" instead of "template struct".
+
+commit eb009db79c0563aefffc923722639467fd98a88a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Apr 28 12:35:36 2015 +0100
+
+    [support.exception] Add reference to [depr.uncaught].
+
+    [ostream::sentry] Use uncaught_exceptions() instead of deprecated
+    uncaught_exception().
+
+commit 81c3fb58df9b03098aee3cc0c78647e304833c21
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Wed Apr 15 00:23:04 2015 +0200
+
+    [re.badexp] Remove redundant colon.
+
+commit 6ebd25d6958ac69eddc0664f4fe9581006249dc2
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sun Jan 25 21:31:36 2015 +0800
+
+    [valarray.syn] Footnote should reference Annex B.
+
+commit bcda144f2d9c33dcdd8ca9b2879f5e3f660b69cc
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Sat Dec 27 19:30:34 2014 -0800
+
+    [util.smartptr.enab] Fix test of shared ownership in example.
+
+commit 248c164a7d0f335732e15e521ab8101301ce804b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Apr 14 12:41:05 2015 +0100
+
+    [containers] Consistency cleanups (cf. Issue #400): Ordering of members, whitespace
+
+commit d27b3932b4cba931730bdd5b78fc2968a49f0afa
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 6 10:34:18 2014 -0600
+
+    Fix formatting of DECAY_COPY
+
+commit 51a00b7c7e98c7b0b117f2e01dbba95d4a8543a7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 1 22:25:05 2014 +0100
+
+    [strings] Fix spacing around index entry.
+
+commit d8073a6030e14683a7d8e4f393a81f3ae7e4419b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 1 22:18:42 2014 +0100
+
+    [strings] Add line break to table caption.
+
+commit 1186a38e8aa92fa33123dc46b02a10a60d710ff4
+Author: Aaron Jacobs <aaronjjacobs@gmail.com>
+Date:   Thu Sep 18 13:36:12 2014 +1000
+
+    [unord.req] Made intro wording for Table 103 more consistent.
+
+    Both internally (it was inconsistent in "value" vs. "object") and externally
+    (Tables 100 and 102 use "value"). While I was at it, fixed capitalization of
+    the word "table" and fixed up TeX formatting.
+
+commit 9416ba8a051ef247c9b865edbb7b4ecd8771e7b8
+Author: Aaron Jacobs <aaronjjacobs@gmail.com>
+Date:   Thu Sep 18 13:30:30 2014 +1000
+
+    [associative.reqmts] Made Table 102 consistent in the use of u.
+
+    In other tables of requirements, the identifier 'u' is used for
+    variables being declared. Made that the case here, too.
+
+commit 32279827a46305adb2219cc1317b491818f2978b
+Author: Aaron Jacobs <aaronjjacobs@gmail.com>
+Date:   Thu Sep 18 13:27:20 2014 +1000
+
+     [sequence.reqmts] Made Table 100 consistent in the use of u.
+
+    In other tables of requirements, the identifier 'u' is used for
+    variables being declared. Made that the case here, too.
+
+commit 79f8b319b0bcecefaf47c13807b68f2b085f18ef
+Author: Aaron Jacobs <aaronjjacobs@gmail.com>
+Date:   Thu Sep 18 13:17:56 2014 +1000
+
+    [allocator.requirements] Made Tables 27/28 consistent in the use of u.
+
+    In other tables of requirements, the identifier 'u' is used for
+    variables being declared. Made that the case here, too. This
+    necessitated a reflow of other variable names.
+
+commit 9f9d2e712ce5b99034e2b24a5bebe7c25aeecbfd
+Author: Aaron Jacobs <aaronjjacobs@gmail.com>
+Date:   Thu Sep 18 11:57:16 2014 +1000
+
+    [containers] Made phrasing for "a value of type X" more consistent.
+
+commit 6eae2a23986d866474826f4e17f935cdf28394b1
+Author: Aaron Jacobs <aaronjjacobs@gmail.com>
+Date:   Thu Sep 18 11:35:01 2014 +1000
+
+    [allocator.requirements] Fixed types for a, a1, a2 in Table 27.
+
+    It doesn't make sense to re-use values of type X& when declaring a new
+    X, as in the use of these variables in Table 28.
+
+commit f0fba72c0d49e855f5615bc2c0d387dae14fcfa6
+Author: Aaron Jacobs <aaronjjacobs@gmail.com>
+Date:   Thu Sep 18 11:48:40 2014 +1000
+
+    [allocator.requirements] Removed unused variables V and v in Table 27.
+
+commit d2afc9a9b06e8fc495d94506620e54c0b62b36fc
+Author: Aaron Jacobs <aaronjjacobs@gmail.com>
+Date:   Thu Sep 18 11:45:50 2014 +1000
+
+    [allocator.requirements] Removed unused variables r and s in Table 27.
+
+commit 763d486babd897123e2194e6e170864befdc2bcc
+Author: Aaron Jacobs <aaronjjacobs@gmail.com>
+Date:   Thu Sep 18 11:41:26 2014 +1000
+
+    [allocator.requirements] Removed unused variable t in Table 27.
+
+commit ea164769bb932efd4c72a0ec060bf3ca719c4a87
+Author: Aaron Jacobs <aaronjjacobs@gmail.com>
+Date:   Thu Sep 18 11:33:58 2014 +1000
+
+    [allocator.requirements] Removed unused variable a3 in Table 27.
+
+commit 99c10dbdf0534b149f3a8aae51099cb97ef12f39
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Mar 22 21:05:36 2015 +0000
+
+    Consistency cleanups in [containers] (cf. Issue #400). This part of the cleanup changes only whitespace: inserted before commas, removed after namespace braces, improved indentation consistency, removed some extraneous linebreaks for things that fit well on one line
+
+commit 284772e40896fe702dbec79477af2735624565fe
+Author: cpplearner <cpplearner@outlook.com>
+Date:   Fri Nov 7 20:10:19 2014 +0800
+
+    [priqueue.special] fix typo
+
+    N4140 23.6.4.4 [priqueue.special] says "template <class T, class Container, Compare>". It should say "template <class T, class Container, class Compare>".
+
+commit 0eff4c29bd0655dbe13ac5acf3411060803da69e
+Author: Kazutoshi SATODA <k_satoda@f2.dion.ne.jp>
+Date:   Sat Aug 2 19:40:22 2014 +0900
+
+    Make the note for both two conditions, not for just the latter of two
+
+    as the note says "Under these conditions...".
+
+    This changes numbering of the items in the note from "(4.2.1) ..." to
+    "(4.3) ...".
+
diff --git a/papers/n4528.md b/papers/n4528.md new file mode 100644 index 0000000000..13f98d9ca4 --- /dev/null +++ b/papers/n4528.md @@ -0,0 +1,258 @@ +# N4528 Editor's Report -- Working Draft, Standard for Programming Language C++ + +2015-05-22 +Richard Smith +Google Inc +`` + +## Acknowledgements + +Very special thanks to Dawn Perchik, who performed nearly all the edits for +motions moved at Lenexa (any errors are mine). + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and those who have provided pull requests with fixes. + +## New Papers + + * N4527 is the current working draft. It replaces N4431. + * N4528 is this Editor's Report for the current working draft. + +### Notable Changes to Issues and Papers as Moved + +#### LWG motion 16 + +Subclause +[thread.sharedtimedmutex.requirements], "Shared timed mutex types", +remains nested directly under +[thread.mutex.requirements], "Mutex requirements", +rather than being made a subclause of +[thread.sharedmutex.requirements], "Shared mutex types". +This is consistent with the existing treatment of the sibling +subclauses "Mutex types" and "Timed mutex types". + +### Other Notable Editorial Changes: + +No major editorial changes have been made since N4431. + +## Minor Editorial Fixes + +A log of all editorial fixes made since N4431 is below: + + commit fa7a721afa87126a59a74bfe2e7344a92d4ebc44 + Author: Richard Smith + Date: Sat May 9 14:50:47 2015 -0500 + + [dcl.spec.auto] Deduction of auto in direct-list-initialization from a + double-braced init list will always fail. Use a more specific term here + to avoid suggesting otherwise. + + commit 84161dfb53dbc90564ec28da6e50d29c8bc379bd + Author: Richard Smith + Date: Sat May 9 09:41:12 2015 -0500 + + [class.union] Fix example to not use an ill-formed empty anonymous union. + + commit 1cfd96e0913891a1ebe491f66dd7ff88ed671901 + Author: Richard Smith + Date: Fri May 8 10:11:30 2015 -0500 + + Punctuation following canonical type strings, such as "pointer to int", + go outside the quotation marks, because the quotation marks are part of + the technical content. Punctuation stays inside other quotation marks. + + commit 8ea266298379028a842d8d496441c0cec2e941a4 + Author: Richard Smith + Date: Tue Apr 14 03:15:18 2015 -0700 + + [intro.defs] Formatting fixes and addition of some cross-references. + + commit d7544f51553e7db455a67aa014967f8ac079433c + Author: Jonathan Wakely + Date: Fri May 8 17:56:24 2015 +0100 + + [c.math] Add rand to index of library names. + + commit df5a2ddc32934e7539063997888d1fc6c1189d0f + Author: AbleBacon + Date: Wed May 6 11:41:17 2015 -0500 + + Update intro.tex + + commit cfabe9354fe3fdc8e93dbc0ddc082102f385c0db + Author: FrankHB + Date: Sun May 3 00:36:50 2015 +0800 + + [char.traits.require]: Use "class template" instead of "struct template". + + commit 3b580b26fe49d01e352d6c24fc054ad586c76f78 + Author: FrankHB + Date: Sun May 3 00:36:05 2015 +0800 + + [char.traits]: Use "class template" instead of "struct template". + + commit 95c971d52cee1558d607703a209ea70b84d6aa93 + Author: FrankHB + Date: Sun May 3 00:34:33 2015 +0800 + + [char.traits.specializations]: Use "class template" instead of "template struct". + + commit ed49c8a8cc7b9899ce2ace9020e4eb6ee426ca25 + Author: FrankHB + Date: Sun May 3 00:32:36 2015 +0800 + + [allocator.requirements]: Use "class template" instead of "template struct". + + commit eb009db79c0563aefffc923722639467fd98a88a + Author: Jonathan Wakely + Date: Tue Apr 28 12:35:36 2015 +0100 + + [support.exception] Add reference to [depr.uncaught]. + + [ostream::sentry] Use uncaught_exceptions() instead of deprecated + uncaught_exception(). + + commit 81c3fb58df9b03098aee3cc0c78647e304833c21 + Author: Eelis van der Weegen + Date: Wed Apr 15 00:23:04 2015 +0200 + + [re.badexp] Remove redundant colon. + + commit 6ebd25d6958ac69eddc0664f4fe9581006249dc2 + Author: S. B. Tam + Date: Sun Jan 25 21:31:36 2015 +0800 + + [valarray.syn] Footnote should reference Annex B. + + commit bcda144f2d9c33dcdd8ca9b2879f5e3f660b69cc + Author: Arthur O'Dwyer + Date: Sat Dec 27 19:30:34 2014 -0800 + + [util.smartptr.enab] Fix test of shared ownership in example. + + commit 248c164a7d0f335732e15e521ab8101301ce804b + Author: Thomas Köppe + Date: Tue Apr 14 12:41:05 2015 +0100 + + [containers] Consistency cleanups (cf. Issue #400): Ordering of members, whitespace + + commit d27b3932b4cba931730bdd5b78fc2968a49f0afa + Author: Thomas Köppe + Date: Thu Nov 6 10:34:18 2014 -0600 + + Fix formatting of DECAY_COPY + + commit 51a00b7c7e98c7b0b117f2e01dbba95d4a8543a7 + Author: Thomas Köppe + Date: Fri Aug 1 22:25:05 2014 +0100 + + [strings] Fix spacing around index entry. + + commit d8073a6030e14683a7d8e4f393a81f3ae7e4419b + Author: Thomas Köppe + Date: Fri Aug 1 22:18:42 2014 +0100 + + [strings] Add line break to table caption. + + commit 1186a38e8aa92fa33123dc46b02a10a60d710ff4 + Author: Aaron Jacobs + Date: Thu Sep 18 13:36:12 2014 +1000 + + [unord.req] Made intro wording for Table 103 more consistent. + + Both internally (it was inconsistent in "value" vs. "object") and externally + (Tables 100 and 102 use "value"). While I was at it, fixed capitalization of + the word "table" and fixed up TeX formatting. + + commit 9416ba8a051ef247c9b865edbb7b4ecd8771e7b8 + Author: Aaron Jacobs + Date: Thu Sep 18 13:30:30 2014 +1000 + + [associative.reqmts] Made Table 102 consistent in the use of u. + + In other tables of requirements, the identifier 'u' is used for + variables being declared. Made that the case here, too. + + commit 32279827a46305adb2219cc1317b491818f2978b + Author: Aaron Jacobs + Date: Thu Sep 18 13:27:20 2014 +1000 + + [sequence.reqmts] Made Table 100 consistent in the use of u. + + In other tables of requirements, the identifier 'u' is used for + variables being declared. Made that the case here, too. + + commit 79f8b319b0bcecefaf47c13807b68f2b085f18ef + Author: Aaron Jacobs + Date: Thu Sep 18 13:17:56 2014 +1000 + + [allocator.requirements] Made Tables 27/28 consistent in the use of u. + + In other tables of requirements, the identifier 'u' is used for + variables being declared. Made that the case here, too. This + necessitated a reflow of other variable names. + + commit 9f9d2e712ce5b99034e2b24a5bebe7c25aeecbfd + Author: Aaron Jacobs + Date: Thu Sep 18 11:57:16 2014 +1000 + + [containers] Made phrasing for "a value of type X" more consistent. + + commit 6eae2a23986d866474826f4e17f935cdf28394b1 + Author: Aaron Jacobs + Date: Thu Sep 18 11:35:01 2014 +1000 + + [allocator.requirements] Fixed types for a, a1, a2 in Table 27. + + It doesn't make sense to re-use values of type X& when declaring a new + X, as in the use of these variables in Table 28. + + commit f0fba72c0d49e855f5615bc2c0d387dae14fcfa6 + Author: Aaron Jacobs + Date: Thu Sep 18 11:48:40 2014 +1000 + + [allocator.requirements] Removed unused variables V and v in Table 27. + + commit d2afc9a9b06e8fc495d94506620e54c0b62b36fc + Author: Aaron Jacobs + Date: Thu Sep 18 11:45:50 2014 +1000 + + [allocator.requirements] Removed unused variables r and s in Table 27. + + commit 763d486babd897123e2194e6e170864befdc2bcc + Author: Aaron Jacobs + Date: Thu Sep 18 11:41:26 2014 +1000 + + [allocator.requirements] Removed unused variable t in Table 27. + + commit ea164769bb932efd4c72a0ec060bf3ca719c4a87 + Author: Aaron Jacobs + Date: Thu Sep 18 11:33:58 2014 +1000 + + [allocator.requirements] Removed unused variable a3 in Table 27. + + commit 99c10dbdf0534b149f3a8aae51099cb97ef12f39 + Author: Thomas Köppe + Date: Sun Mar 22 21:05:36 2015 +0000 + + Consistency cleanups in [containers] (cf. Issue #400). This part of the cleanup changes only whitespace: inserted before commas, removed after namespace braces, improved indentation consistency, removed some extraneous linebreaks for things that fit well on one line + + commit 284772e40896fe702dbec79477af2735624565fe + Author: cpplearner + Date: Fri Nov 7 20:10:19 2014 +0800 + + [priqueue.special] fix typo + + N4140 23.6.4.4 [priqueue.special] says "template ". It should say "template ". + + commit 0eff4c29bd0655dbe13ac5acf3411060803da69e + Author: Kazutoshi SATODA + Date: Sat Aug 2 19:40:22 2014 +0900 + + Make the note for both two conditions, not for just the latter of two + + as the note says "Under these conditions...". + + This changes numbering of the items in the note from "(4.2.1) ..." to + "(4.3) ...". diff --git a/papers/n4566.html b/papers/n4566.html new file mode 100644 index 0000000000..bf8be1adf1 --- /dev/null +++ b/papers/n4566.html @@ -0,0 +1,608 @@ +n4566 +

N4566 Editor's Report -- Working Draft, Standard for Programming Language C++

+ +

2015-11-09
+Richard Smith
+Google Inc
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Very special thanks to Dawn Perchik, who performed nearly all the edits for +motions moved at Kona (any errors are mine).

+ +

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

+ +

New papers

+ +
    +
  • N4567 is the current working draft. It replaces N4527.
  • +
  • N4566 is this Editor's Report for the current working draft.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolutions from 21 issues applied, resolving 23 issues:

+ + + +

CWG motion 2: P0001R1 "Remove Deprecated Use of the register Keyword"

+ +

CWG motion 3: P0002R1 "Remove Deprecated operator++(bool)"

+ +

CWG motion 4: P0012R1 "Make exception specifications be part of the type system, version 5"

+ +

CWG motion 5: P0061R1 "__has_include for C++17"

+ +

CWG motion 6: P0134R0 "Introducing a name for brace-or-equal-initializers for non-static data members"

+ +

CWG motion 7: P0136R1 "Rewording inheriting constructors (core issue 1941 et al)"

+ +

Library working group motions

+ +

LWG motion 1: Library issue resolutions for 34 issues applied:

+ + + +

LWG motion 2: Library issue resolutions for 4 issues applied:

+ + + +

LWG motion 3: P0004R1 "Remove Deprecated iostreams aliases"

+ +

LWG motion 4: P0006R0 "Adopt Type Traits Variable Templates for C++17"

+ +

LWG motion 5: P0092R1 "Polishing <chrono>"

+ +

LWG motion 6: P0007R1 "Constant View: A proposal for a std::as_const helper function template"

+ +

LWG motion 7: P0156R0 "Variadic lock_guard (rev 3)"

+ +

LWG motion 9: P0074R0 "Making std::owner_less more flexible"

+ +

LWG motion 10: P0013R1 "Logical type traits rev 2" (plus _v templates as LWG motion 4 was applied)

+ +

Editorial changes to papers as moved

+ +

CWG motion 1, issue 1990

+ +

Italicized the term "conversion function" in its definition (and added index entry).

+ +

CWG motion 3

+ +

The Annex C entry was added into a section for Clause 5 [expr], instead of a +section for Clause D [depr], because that is where the normative wording for +this feature used to live.

+ +

CWG motion 4

+ +

The change to [except.spec] 15.4p1 could not be applied, but the current +wording is correct. Editorially fixed formatting errors in wording, +reformatted text for consistency and readability, and fixed use of +macros.

+ +

The change in the formulation of function pointer decay that avoids +suggesting that only possibly-throwing functions decay has been applied +to two more places in [except.handle].

+ +

Minor editorial fixes

+ +

A log of all editorial fixes made since N4527 is below:

+ +
commit de6f56a818884092d4ce4aa5e49af9f357007901
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 4 14:28:15 2015 -0800
+
+    [dcl.constexpr] Consistently describe rules for validity of constexpr
+    function definitions as "requirements" so that the cross-references
+    to this definition use the same term as the definition itself.
+
+commit 4dbad61e6eee2552c29e1c50c4d34db906d25009
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Oct 7 14:32:19 2015 -0700
+
+    [cstdint.syn] <cstdint> defines no functions; don't suggest that it does.
+
+commit f853831b14614a47d6ea11d29837c88d6ef4bb8a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 9 01:11:45 2015 -0800
+
+    [meta.logical] Improve formatting for consistency with other library
+    clauses.
+
+commit c49db1de03a6a777e827d62eeeaa6523a0a22f5f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Oct 24 11:24:36 2015 -0700
+
+    [dcl.init.list] Update example to reflect that binding a temporary to a
+    reference is ill-formed; this also applies to std::initializer_list
+    initialization, which is specified as performing a reference binding.
+
+commit be5adfba61b146272b23442cd2fdef5bd94485f9
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Oct 29 13:27:32 2015 -0700
+
+    [over.load] Added cross references to function/array vs. pointer in overloading
+
+commit c54cf0dcbf00cf2f16c9da8535abc939ac4321ad
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Oct 28 18:28:17 2015 -0700
+
+    [expr] Add missing indexes for definitions, and make others consistent.
+
+    Indexes were added for the following definitions:
+    [expr.const] constant expression
+    [expr.const] core constant expression
+    [expr.const] integral constant expression
+    [expr.const] converted constant expression
+    [gram.expr] built-in operators
+    [expr.call] virtual function call
+    [expr.call] default argument promotion
+    [expr.new] allocated type
+    [expr.prim.lambda] implicit capture
+
+commit 283dae57ee352153cd2954c98e6e1c747d137a29
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Oct 28 16:02:39 2015 -0700
+
+    [gram.expr] Add an index to the definition of "composite pointer type"
+
+commit d550da35efc7b8b410a19fd25317521f538c5f7c
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Oct 28 15:51:38 2015 -0700
+
+    [gram.expr] Add an index to definition of term "cv-combined type"
+
+commit b2fcd697f378a212f2e6dc5225c74a2b7566be76
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Oct 28 15:43:34 2015 -0700
+
+    [unord.req] Change object to value to match cleanup after merge with LWG2059.
+
+    Referenced cleanup is "[unord.req] Made intro wording for Table 103 more consistent."
+
+commit 9fb82225f03cda7f1ee5427b87f986e7b010ff47
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Oct 22 16:06:22 2015 -0700
+
+    [dcl.array] Fix typo; multiple array declaratiors create a
+    multidimensional array type, not necessarily a multidimensional
+    array object.
+
+commit 3454b4dd7003a9104755c6640beb9389ee385644
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Oct 21 17:56:46 2015 -0700
+
+    [diff.cpp11] Add a note that default member initializers for aggregates
+    is a breaking change compared to C++11.
+
+    Fixes CWG2114.
+
+commit e00fab806aef1855364bc416265b74e5da94aa99
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Oct 21 17:44:42 2015 -0700
+
+    [temp.class.spec.match] Repeat a portion of an example so we don't
+    separate the declaration and use of some template specializations
+    by several pages.
+
+    Fixes CWG2035.
+
+commit 2d4e4e771e6722e26f099eddf25721036a603a9e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Oct 21 17:38:49 2015 -0700
+
+    [dcl.attr.grammar] Remove grammar ambiguity from balanced-token-seq.
+
+commit 2bbbce9326e265227c5651e9c5a7689f23f5d7e0
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Oct 21 13:06:29 2015 -0700
+
+    Update some cross-references from [class.union] to [class.union.anon].
+
+commit 3cb61dafd6c79a0556ccb7e8e02c45e4f30c348f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Oct 21 12:30:53 2015 -0700
+
+    [class.union] Split wording for anonymous unions to a new subclause,
+    [class.union.anon].
+
+commit 15124e411210030af3f85173014d09f72ce82741
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Oct 21 09:42:02 2015 -1000
+
+    [class.union] Make terms "union-like class" and "variant member" indexed definitions.
+
+commit e1961df118a01532677b22335f2e0d739addfe76
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Tue Oct 20 22:29:31 2015 -1000
+
+    [diff.cpp14.depr] Fix hard coded reference to Annex D.
+
+commit 94762ac9a220c9be2ab7091d786a9ed72e0e5fb0
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Oct 20 18:25:00 2015 -0700
+
+    [except.spec] Fix capitalization mismatch at start of bullets.
+
+commit 6dc1fe0e83a5b592b55d7bb6d1454b340bd7a202
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Oct 7 13:38:37 2015 -0700
+
+    [new.delete.array] Add missing changes from LWG206.
+
+    The relevant editor's report indicates that the wording changes were
+    reworded, but that rewording lost a normative requirement (that a
+    replacement `operator new[](size_t, nothrow_t)` returns a pointer
+    as if produced by calling `operator new[](size_t)`).
+
+    Fixes #543.
+
+commit 777e2a9aacd404db27f7563212cd12c3f571f9ac
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Sep 30 11:06:56 2015 -0700
+
+    [temp.dep] Remove duplicate 'if'.
+
+commit 37776fa9f469e563f3288835e9e6c9d6fb7a2f88
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Sep 28 12:25:21 2015 +0100
+
+    [thread.condition.condvar] wait() cannot timeout.
+
+commit 059b074a86953da500b9aa18c59c93adcb984d3c
+Author: Daniel Frey <d.frey@gmx.de>
+Date:   Fri Sep 18 19:58:15 2015 +0200
+
+    Change "typename decay<F>::type" to "decay_t<F>"
+
+    Looks like this one was overlooked when `decay_t` (and the other `_t` helpers) were introduced.
+
+commit 540d881be3c46693529273649aacb9fc830bb987
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Sep 16 10:40:40 2015 +0100
+
+    [library.general] Fix typo.
+
+    Fixes: #538
+
+commit 8210be74e8b92f6c841fb330dcfbe28d553a1eed
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Mon Sep 14 14:34:33 2015 +0800
+
+    [tuple.assign] Fix typo
+
+    Fixed redundant ')'.
+
+commit 24264e56e289991f247daed172d9a6960a85395b
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Aug 25 19:56:42 2015 +0100
+
+    [util.smartptr.shared.const] Add missing period.
+
+commit 4e01e8ce7f6667692b799c828c85b7306745225f
+Author: andypea <andrew.punnett@gmail.com>
+Date:   Tue Aug 18 17:24:29 2015 +1200
+
+    [ext.manip] Replace a colon with a semi-colon.
+
+commit d36ffa694a8a8460398aa2a75be1b8dcf8b720c4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jul 21 11:56:46 2015 -0700
+
+    [class.protected] Update example to match CWG1873.
+
+    Fixes #527.
+
+commit 6bc0318540e528031dac40fb54eee3c93a856616
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 9 17:56:12 2015 -0700
+
+    [dcl.enum] Fix italicization of non-definition of "underlying type".
+
+commit 6739a892b2d92410f56a0b6d6055082f287031dc
+Author: Aaron Ballman <aaron@aaronballman.com>
+Date:   Mon Jul 13 14:16:03 2015 -0400
+
+    cv-unqualified is not a grammar term in this context, similar to other uses in the same paragraph.
+
+commit b6d6cec80404d88f553868fa8167d3d68b87cdd2
+Author: Aaron Ballman <aaron@aaronballman.com>
+Date:   Mon Jul 20 14:30:06 2015 -0400
+
+    Another ODR spelling change. Should be the last one.
+
+commit 33345c9e46db667b41e8b708db6d79f35fbfeffa
+Author: Aaron Ballman <aaron@aaronballman.com>
+Date:   Mon Jul 20 13:54:20 2015 -0400
+
+    Unify the spelling of one-definition rule to be consistent.
+
+commit 968cc327f6e217609596763711225cd51f3e9865
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jul 17 10:26:08 2015 +0100
+
+    [ostream.seeks] Fix nesting of itemdecl inside itemdescr.
+
+    Reported by Stephan T. Lavavej. Fixes #524.
+
+commit f60466ccd45df1e560403d8482e9c08df7a97248
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sat Jul 11 17:12:34 2015 +0100
+
+    [allocator.adaptor.members] Use code font for class name.
+
+commit bc293b7d32a2dde11bd0f60a92d5371acff1f3d0
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sat Jul 11 16:46:49 2015 +0100
+
+    [allocator.adaptor.members] Add space after comma.
+
+commit efc600e757239d00baf759efac7cd979fe0152b3
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 9 17:41:00 2015 -0700
+
+    [dcl.fct.def.delete], [dcl.constexpr], [class.friend]: Replace "implicitly inline" with "implicitly an inline function", because the latter is the term defined in 7.1.2.
+
+commit 299ec33999ca8d57ce40d5663373d8da46de0baa
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 5 17:44:43 2015 -0700
+
+    [namespace.udecl] Remove incorrect example.
+
+    CWG36 (still open) notes that this example is incorrect, but was left in
+    the standard, confusing people for 17 years. Remove the example rather
+    than fixing it to match the normative text, because the validity of this
+    code is still under dispute.
+
+commit 90352854d99ee3e3b2f935bba47c6749365d52d8
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Mon Jun 29 13:21:25 2015 -0700
+
+    [class.union] Change "but not" to "but it shall not have" as suggested by Hubert Tong.
+
+commit c62428ecedb6ddc076e3d1b37e9e2bfad591b7bc
+Author: Aaron Ballman <aaron@aaronballman.com>
+Date:   Fri Jun 26 15:19:38 2015 -0400
+
+    Align declarations
+
+commit 05deea2df70aee5fa37e7a91b041a86bd8723d01
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Jun 19 08:57:08 2015 -0700
+
+    Fix references in CWG1780 as per discussion on c++std-core.
+
+commit e6e356c0ba3ba0e552f4f924e166fcab53b9a2a1
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 16 12:49:16 2015 -0700
+
+    Update Annex A and Annex F to reflect recent changes.
+
+commit 93570180234ec5b99df4a2b13835c34b35734ae9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu May 28 10:18:19 2015 -0700
+
+    [ratio.arithmetic] Improve indentation of comment in example.
+
+commit 9330d4ae5a23be00d61caea4eeaad8184421fbec
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jun 7 12:45:20 2015 -0700
+
+    [except.spec] Remove spurious parens in example.
+
+commit 093c1eebd3e2a1682331e8b1bd16677cbdb79d6f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue May 26 18:41:29 2015 +0100
+
+    [streambuf], [istream], [iostreamclass], [ostream] These are class templates not classes.
+
+commit 6f009e72cf5dc2b1de0ac6a1d7abce63ebd4526d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue May 26 18:37:56 2015 +0100
+
+    [streambuf] Use injected class name for basic_streambuf.
+
+commit c99b9246e43bdf60b79fd406f3774c226a3f3433
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri May 22 18:07:38 2015 +0100
+
+    [support.dynamic] LWG2458 remove correct signatures
+
+commit 2c4c7a5b9098a6231bf3885fe96fbc9deb2f047f
+Author: Maurice Bos <m-ou.se@m-ou.se>
+Date:   Fri May 8 11:32:55 2015 +0200
+
+    s/template classes/class templates/
+
diff --git a/papers/n4566.md b/papers/n4566.md new file mode 100644 index 0000000000..9c29ef4b57 --- /dev/null +++ b/papers/n4566.md @@ -0,0 +1,476 @@ +# N4566 Editor's Report -- Working Draft, Standard for Programming Language C++ + +2015-11-09 +Richard Smith +Google Inc +`` + +## Acknowledgements + +Very special thanks to Dawn Perchik, who performed nearly all the edits for +motions moved at Kona (any errors are mine). + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and those who have provided pull requests with fixes. + +## New papers + + * [N4567](http://wg21.link/n4567) is the current working draft. It replaces [N4527](http://wg21.link/n4527). + * N4566 is this Editor's Report for the current working draft. + +### Motions incorporated into working draft + +#### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p0164r0) from 21 issues applied, resolving 23 issues: + + * [1274](http://wg21.link/cwg1274) + * [1391](http://wg21.link/cwg1391) + * [1722](http://wg21.link/cwg1722) + * [1847](http://wg21.link/cwg1847) (no changes, resolved by 1391) + * [1863](http://wg21.link/cwg1863) + * [1949](http://wg21.link/cwg1949) + * [1975](http://wg21.link/cwg1975) (wording removed by CWG motion 4) + * [1981](http://wg21.link/cwg1981) + * [1990](http://wg21.link/cwg1990) + * [2000](http://wg21.link/cwg2000) + * [2004](http://wg21.link/cwg2004) + * [2006](http://wg21.link/cwg2006) + * [2015](http://wg21.link/cwg2015) + * [2016](http://wg21.link/cwg2016) (no changes, resolved by 1990) + * [2019](http://wg21.link/cwg2019) + * [2024](http://wg21.link/cwg2024) + * [2026](http://wg21.link/cwg2026) + * [2027](http://wg21.link/cwg2027) + * [2031](http://wg21.link/cwg2031) + * [2052](http://wg21.link/cwg2052) + * [2075](http://wg21.link/cwg2075) + * [2101](http://wg21.link/cwg2101) + * [2120](http://wg21.link/cwg2120) + +CWG motion 2: [P0001R1 "Remove Deprecated Use of the `register` Keyword"](http://wg21.link/p0001r1) + +CWG motion 3: [P0002R1 "Remove Deprecated `operator++(bool)`"](http://wg21.link/p0002r1) + +CWG motion 4: [P0012R1 "Make exception specifications be part of the type system, version 5"](http://wg21.link/p0012r1) + +CWG motion 5: [P0061R1 "`__has_include` for C++17"](http://wg21.link/p0061r1) + +CWG motion 6: [P0134R0 "Introducing a name for *brace-or-equal-initializers* for non-static data members"](http://wg21.link/p0134r0) + +CWG motion 7: [P0136R1 "Rewording inheriting constructors (core issue 1941 et al)"](http://wg21.link/p0136r1) + +#### Library working group motions + +LWG motion 1: [Library issue resolutions](http://wg21.link/p0165r0) for 34 issues applied: + + * [1169](http://wg21.link/lwg1169) + * [2072](http://wg21.link/lwg2072) + * [2101](http://wg21.link/lwg2101) + * [2111](http://wg21.link/lwg2111) + * [2119](http://wg21.link/lwg2119) + * [2127](http://wg21.link/lwg2127) + * [2133](http://wg21.link/lwg2133) + * [2156](http://wg21.link/lwg2156) + * [2218](http://wg21.link/lwg2218) + * [2219](http://wg21.link/lwg2219) + * [2244](http://wg21.link/lwg2244) + * [2250](http://wg21.link/lwg2250) + * [2259](http://wg21.link/lwg2259) + * [2336](http://wg21.link/lwg2336) + * [2353](http://wg21.link/lwg2353) + * [2367](http://wg21.link/lwg2367) + * [2380](http://wg21.link/lwg2380) + * [2384](http://wg21.link/lwg2384) + * [2385](http://wg21.link/lwg2385) + * [2435](http://wg21.link/lwg2435) + * [2447](http://wg21.link/lwg2447) + * [2462](http://wg21.link/lwg2462) + * [2466](http://wg21.link/lwg2466) + * [2469](http://wg21.link/lwg2469) + * [2473](http://wg21.link/lwg2473) + * [2476](http://wg21.link/lwg2476) + * [2477](http://wg21.link/lwg2477) + * [2483](http://wg21.link/lwg2483) + * [2484](http://wg21.link/lwg2484) + * [2485](http://wg21.link/lwg2485) + * [2486](http://wg21.link/lwg2486) + * [2487](http://wg21.link/lwg2487) + * [2489](http://wg21.link/lwg2489) + * [2492](http://wg21.link/lwg2492) + * Note: [2181](http://wg21.link/lwg2181) resolution from P0165R0 was *not* applied by this motion + +LWG motion 2: [Library issue resolutions](http://wg21.link/p0165r0) for 4 issues applied: + + * [2224](http://wg21.link/lwg2224) + * [2234](http://wg21.link/lwg2234) + * [2273](http://wg21.link/lwg2273) + * [2495](http://wg21.link/lwg2495) + +LWG motion 3: [P0004R1 "Remove Deprecated `iostreams` aliases"](http://wg21.link/p0004r1) + +LWG motion 4: [P0006R0 "Adopt Type Traits Variable Templates for C++17"](http://wg21.link/p0006r0) + +LWG motion 5: [P0092R1 "Polishing ``"](http://wg21.link/p0092r1) + +LWG motion 6: [P0007R1 "Constant View: A proposal for a `std::as_const` helper function template"](http://wg21.link/p0007r1) + +LWG motion 7: [P0156R0 "Variadic `lock_guard` (rev 3)"](http://wg21.link/p0156r0) + +LWG motion 9: [P0074R0 "Making `std::owner_less` more flexible"](http://wg21.link/p0074r0) + +LWG motion 10: [P0013R1 "Logical type traits rev 2"](http://wg21.link/p0013r1) (plus `_v` templates as LWG motion 4 was applied) + +### Editorial changes to papers as moved + +#### CWG motion 1, issue 1990 + +Italicized the term "conversion function" in its definition (and added index entry). + +#### CWG motion 3 + +The Annex C entry was added into a section for Clause 5 [expr], instead of a +section for Clause D [depr], because that is where the normative wording for +this feature used to live. + +#### CWG motion 4 + +The change to [except.spec] 15.4p1 could not be applied, but the current +wording is correct. Editorially fixed formatting errors in wording, +reformatted text for consistency and readability, and fixed use of +macros. + +The change in the formulation of function pointer decay that avoids +suggesting that only possibly-throwing functions decay has been applied +to two more places in [except.handle]. + +## Minor editorial fixes + +A log of all editorial fixes made since N4527 is below: + + commit de6f56a818884092d4ce4aa5e49af9f357007901 + Author: Richard Smith + Date: Wed Nov 4 14:28:15 2015 -0800 + + [dcl.constexpr] Consistently describe rules for validity of constexpr + function definitions as "requirements" so that the cross-references + to this definition use the same term as the definition itself. + + commit 4dbad61e6eee2552c29e1c50c4d34db906d25009 + Author: Richard Smith + Date: Wed Oct 7 14:32:19 2015 -0700 + + [cstdint.syn] defines no functions; don't suggest that it does. + + commit f853831b14614a47d6ea11d29837c88d6ef4bb8a + Author: Richard Smith + Date: Mon Nov 9 01:11:45 2015 -0800 + + [meta.logical] Improve formatting for consistency with other library + clauses. + + commit c49db1de03a6a777e827d62eeeaa6523a0a22f5f + Author: Richard Smith + Date: Sat Oct 24 11:24:36 2015 -0700 + + [dcl.init.list] Update example to reflect that binding a temporary to a + reference is ill-formed; this also applies to std::initializer_list + initialization, which is specified as performing a reference binding. + + commit be5adfba61b146272b23442cd2fdef5bd94485f9 + Author: Dawn Perchik + Date: Thu Oct 29 13:27:32 2015 -0700 + + [over.load] Added cross references to function/array vs. pointer in overloading + + commit c54cf0dcbf00cf2f16c9da8535abc939ac4321ad + Author: Dawn Perchik + Date: Wed Oct 28 18:28:17 2015 -0700 + + [expr] Add missing indexes for definitions, and make others consistent. + + Indexes were added for the following definitions: + [expr.const] constant expression + [expr.const] core constant expression + [expr.const] integral constant expression + [expr.const] converted constant expression + [gram.expr] built-in operators + [expr.call] virtual function call + [expr.call] default argument promotion + [expr.new] allocated type + [expr.prim.lambda] implicit capture + + commit 283dae57ee352153cd2954c98e6e1c747d137a29 + Author: Dawn Perchik + Date: Wed Oct 28 16:02:39 2015 -0700 + + [gram.expr] Add an index to the definition of "composite pointer type" + + commit d550da35efc7b8b410a19fd25317521f538c5f7c + Author: Dawn Perchik + Date: Wed Oct 28 15:51:38 2015 -0700 + + [gram.expr] Add an index to definition of term "cv-combined type" + + commit b2fcd697f378a212f2e6dc5225c74a2b7566be76 + Author: Dawn Perchik + Date: Wed Oct 28 15:43:34 2015 -0700 + + [unord.req] Change object to value to match cleanup after merge with LWG2059. + + Referenced cleanup is "[unord.req] Made intro wording for Table 103 more consistent." + + commit 9fb82225f03cda7f1ee5427b87f986e7b010ff47 + Author: Richard Smith + Date: Thu Oct 22 16:06:22 2015 -0700 + + [dcl.array] Fix typo; multiple array declaratiors create a + multidimensional array type, not necessarily a multidimensional + array object. + + commit 3454b4dd7003a9104755c6640beb9389ee385644 + Author: Richard Smith + Date: Wed Oct 21 17:56:46 2015 -0700 + + [diff.cpp11] Add a note that default member initializers for aggregates + is a breaking change compared to C++11. + + Fixes CWG2114. + + commit e00fab806aef1855364bc416265b74e5da94aa99 + Author: Richard Smith + Date: Wed Oct 21 17:44:42 2015 -0700 + + [temp.class.spec.match] Repeat a portion of an example so we don't + separate the declaration and use of some template specializations + by several pages. + + Fixes CWG2035. + + commit 2d4e4e771e6722e26f099eddf25721036a603a9e + Author: Richard Smith + Date: Wed Oct 21 17:38:49 2015 -0700 + + [dcl.attr.grammar] Remove grammar ambiguity from balanced-token-seq. + + commit 2bbbce9326e265227c5651e9c5a7689f23f5d7e0 + Author: Richard Smith + Date: Wed Oct 21 13:06:29 2015 -0700 + + Update some cross-references from [class.union] to [class.union.anon]. + + commit 3cb61dafd6c79a0556ccb7e8e02c45e4f30c348f + Author: Richard Smith + Date: Wed Oct 21 12:30:53 2015 -0700 + + [class.union] Split wording for anonymous unions to a new subclause, + [class.union.anon]. + + commit 15124e411210030af3f85173014d09f72ce82741 + Author: Dawn Perchik + Date: Wed Oct 21 09:42:02 2015 -1000 + + [class.union] Make terms "union-like class" and "variant member" indexed definitions. + + commit e1961df118a01532677b22335f2e0d739addfe76 + Author: Dawn Perchik + Date: Tue Oct 20 22:29:31 2015 -1000 + + [diff.cpp14.depr] Fix hard coded reference to Annex D. + + commit 94762ac9a220c9be2ab7091d786a9ed72e0e5fb0 + Author: Richard Smith + Date: Tue Oct 20 18:25:00 2015 -0700 + + [except.spec] Fix capitalization mismatch at start of bullets. + + commit 6dc1fe0e83a5b592b55d7bb6d1454b340bd7a202 + Author: Richard Smith + Date: Wed Oct 7 13:38:37 2015 -0700 + + [new.delete.array] Add missing changes from LWG206. + + The relevant editor's report indicates that the wording changes were + reworded, but that rewording lost a normative requirement (that a + replacement `operator new[](size_t, nothrow_t)` returns a pointer + as if produced by calling `operator new[](size_t)`). + + Fixes #543. + + commit 777e2a9aacd404db27f7563212cd12c3f571f9ac + Author: Richard Smith + Date: Wed Sep 30 11:06:56 2015 -0700 + + [temp.dep] Remove duplicate 'if'. + + commit 37776fa9f469e563f3288835e9e6c9d6fb7a2f88 + Author: Jonathan Wakely + Date: Mon Sep 28 12:25:21 2015 +0100 + + [thread.condition.condvar] wait() cannot timeout. + + commit 059b074a86953da500b9aa18c59c93adcb984d3c + Author: Daniel Frey + Date: Fri Sep 18 19:58:15 2015 +0200 + + Change "typename decay::type" to "decay_t" + + Looks like this one was overlooked when `decay_t` (and the other `_t` helpers) were introduced. + + commit 540d881be3c46693529273649aacb9fc830bb987 + Author: Jonathan Wakely + Date: Wed Sep 16 10:40:40 2015 +0100 + + [library.general] Fix typo. + + Fixes: #538 + + commit 8210be74e8b92f6c841fb330dcfbe28d553a1eed + Author: FrankHB + Date: Mon Sep 14 14:34:33 2015 +0800 + + [tuple.assign] Fix typo + + Fixed redundant ')'. + + commit 24264e56e289991f247daed172d9a6960a85395b + Author: Jonathan Wakely + Date: Tue Aug 25 19:56:42 2015 +0100 + + [util.smartptr.shared.const] Add missing period. + + commit 4e01e8ce7f6667692b799c828c85b7306745225f + Author: andypea + Date: Tue Aug 18 17:24:29 2015 +1200 + + [ext.manip] Replace a colon with a semi-colon. + + commit d36ffa694a8a8460398aa2a75be1b8dcf8b720c4 + Author: Richard Smith + Date: Tue Jul 21 11:56:46 2015 -0700 + + [class.protected] Update example to match CWG1873. + + Fixes #527. + + commit 6bc0318540e528031dac40fb54eee3c93a856616 + Author: Richard Smith + Date: Thu Jul 9 17:56:12 2015 -0700 + + [dcl.enum] Fix italicization of non-definition of "underlying type". + + commit 6739a892b2d92410f56a0b6d6055082f287031dc + Author: Aaron Ballman + Date: Mon Jul 13 14:16:03 2015 -0400 + + cv-unqualified is not a grammar term in this context, similar to other uses in the same paragraph. + + commit b6d6cec80404d88f553868fa8167d3d68b87cdd2 + Author: Aaron Ballman + Date: Mon Jul 20 14:30:06 2015 -0400 + + Another ODR spelling change. Should be the last one. + + commit 33345c9e46db667b41e8b708db6d79f35fbfeffa + Author: Aaron Ballman + Date: Mon Jul 20 13:54:20 2015 -0400 + + Unify the spelling of one-definition rule to be consistent. + + commit 968cc327f6e217609596763711225cd51f3e9865 + Author: Jonathan Wakely + Date: Fri Jul 17 10:26:08 2015 +0100 + + [ostream.seeks] Fix nesting of itemdecl inside itemdescr. + + Reported by Stephan T. Lavavej. Fixes #524. + + commit f60466ccd45df1e560403d8482e9c08df7a97248 + Author: Jonathan Wakely + Date: Sat Jul 11 17:12:34 2015 +0100 + + [allocator.adaptor.members] Use code font for class name. + + commit bc293b7d32a2dde11bd0f60a92d5371acff1f3d0 + Author: Jonathan Wakely + Date: Sat Jul 11 16:46:49 2015 +0100 + + [allocator.adaptor.members] Add space after comma. + + commit efc600e757239d00baf759efac7cd979fe0152b3 + Author: Richard Smith + Date: Thu Jul 9 17:41:00 2015 -0700 + + [dcl.fct.def.delete], [dcl.constexpr], [class.friend]: Replace "implicitly inline" with "implicitly an inline function", because the latter is the term defined in 7.1.2. + + commit 299ec33999ca8d57ce40d5663373d8da46de0baa + Author: Richard Smith + Date: Sun Jul 5 17:44:43 2015 -0700 + + [namespace.udecl] Remove incorrect example. + + CWG36 (still open) notes that this example is incorrect, but was left in + the standard, confusing people for 17 years. Remove the example rather + than fixing it to match the normative text, because the validity of this + code is still under dispute. + + commit 90352854d99ee3e3b2f935bba47c6749365d52d8 + Author: Dawn Perchik + Date: Mon Jun 29 13:21:25 2015 -0700 + + [class.union] Change "but not" to "but it shall not have" as suggested by Hubert Tong. + + commit c62428ecedb6ddc076e3d1b37e9e2bfad591b7bc + Author: Aaron Ballman + Date: Fri Jun 26 15:19:38 2015 -0400 + + Align declarations + + commit 05deea2df70aee5fa37e7a91b041a86bd8723d01 + Author: Dawn Perchik + Date: Fri Jun 19 08:57:08 2015 -0700 + + Fix references in CWG1780 as per discussion on c++std-core. + + commit e6e356c0ba3ba0e552f4f924e166fcab53b9a2a1 + Author: Richard Smith + Date: Tue Jun 16 12:49:16 2015 -0700 + + Update Annex A and Annex F to reflect recent changes. + + commit 93570180234ec5b99df4a2b13835c34b35734ae9 + Author: Richard Smith + Date: Thu May 28 10:18:19 2015 -0700 + + [ratio.arithmetic] Improve indentation of comment in example. + + commit 9330d4ae5a23be00d61caea4eeaad8184421fbec + Author: Richard Smith + Date: Sun Jun 7 12:45:20 2015 -0700 + + [except.spec] Remove spurious parens in example. + + commit 093c1eebd3e2a1682331e8b1bd16677cbdb79d6f + Author: Jonathan Wakely + Date: Tue May 26 18:41:29 2015 +0100 + + [streambuf], [istream], [iostreamclass], [ostream] These are class templates not classes. + + commit 6f009e72cf5dc2b1de0ac6a1d7abce63ebd4526d + Author: Jonathan Wakely + Date: Tue May 26 18:37:56 2015 +0100 + + [streambuf] Use injected class name for basic_streambuf. + + commit c99b9246e43bdf60b79fd406f3774c226a3f3433 + Author: Jonathan Wakely + Date: Fri May 22 18:07:38 2015 +0100 + + [support.dynamic] LWG2458 remove correct signatures + + commit 2c4c7a5b9098a6231bf3885fe96fbc9deb2f047f + Author: Maurice Bos + Date: Fri May 8 11:32:55 2015 +0200 + + s/template classes/class templates/ diff --git a/papers/n4567.pdf b/papers/n4567.pdf new file mode 100644 index 0000000000..7eb593aa74 Binary files /dev/null and b/papers/n4567.pdf differ diff --git a/papers/n4582.pdf b/papers/n4582.pdf new file mode 100644 index 0000000000..7e05d04803 Binary files /dev/null and b/papers/n4582.pdf differ diff --git a/papers/n4583.html b/papers/n4583.html new file mode 100644 index 0000000000..cbee83c259 --- /dev/null +++ b/papers/n4583.html @@ -0,0 +1,1239 @@ +n4583 +

N4583 Editor's Report -- Working Draft, Standard for Programming Language C++

+ +

2016-03-18
+Richard Smith
+Google Inc
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Very special thanks to Dawn Perchik, who performed the edits for +many of the motions moved at Jacksonville, +to Jonathan Wakely, who performed many of the edits for integrating the +Filesystem TS, and +to Walter Brown, for providing the Mathematical Special Functions IS +in LaTeX format. +Any errors are mine.

+ +

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

+ +

New papers

+ +
    +
  • N4582 is the current working draft. It replaces N4567.
  • +
  • N4583 is this Editor's Report for the current working draft.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolutions from 14 issues applied, resolving 15 issues:

+ +
    +
  • 1734 Nontrivial deleted copy functions
  • +
  • 1895 Deleted conversions in conditional operator operands
  • +
  • 1930 init-declarator-list vs member-declarator-list
  • +
  • 1932 Bit-field results of conditional operators (no changes, resolved by 1895)
  • +
  • 1955 #elif with invalid controlling expression
  • +
  • 2001 non-directive is underspecified
  • +
  • 2008 Default template-arguments underspecified
  • +
  • 2017 Flowing off end is not equivalent to no-expression return (with normative correction, see below)
  • +
  • 2082 Referring to parameters in unevaluated operands of default arguments
  • +
  • 2084 NSDMIs and deleted union default constructors
  • +
  • 2093 Qualification conversion for pointer-to-member handler matching
  • +
  • 2099 Inferring the bound of an array static data member
  • +
  • 2124 Signature of constructor template
  • +
  • 2130 Over-aligned types in new-expressions
  • +
  • 2157 Further disambiguation of enumeration elaborated-type-specifier
  • +
+ +

CWG motion 2: Core issue resolutions from 48 issues applied, resolving 49 issues:

+ +
    +
  • 212 Implicit instantiation is not described clearly enough
  • +
  • 238 Precision and accuracy constraints on floating point
  • +
  • 242 Interpretation of old-style casts
  • +
  • 1284 Should the lifetime of an array be independent of that of its elements?
  • +
  • 1315 Restrictions on non-type template arguments in partial specializations
  • +
  • 1496 Triviality with deleted and missing default constructors
  • +
  • 1638 Declaring an explicit specialization of a scoped enumeration
  • +
  • 1872 Instantiations of constexpr templates that cannot appear in constant expressions
  • +
  • 1992 new (std::nothrow) int[N] can throw
  • +
  • 2012 Lifetime of references
  • +
  • 2032 Default template-arguments of variable templates
  • +
  • 2033 Redundant restriction on partial specialization argument
  • +
  • 2038 Document C++14 incompatibility of new braced deduction rule
  • +
  • 2039 Constant conversions to bool
  • +
  • 2040 trailing-return-type no longer ambiguous
  • +
  • 2041 Namespace for explicit class template specialization
  • +
  • 2044 decltype(auto) and void
  • +
  • 2047 Coordinating “throws anything” specifications
  • +
  • 2061 Inline namespace after simplifications
  • +
  • 2063 Type/nontype hiding in class scope
  • +
  • 2064 Conflicting specifications for dependent decltype-specifiers
  • +
  • 2066 Does type-dependent imply value-dependent? (no changes, resolved by 2109)
  • +
  • 2068 When can/must a defaulted virtual destructor be defined?
  • +
  • 2069 Do destructors have names?
  • +
  • 2071 typedef with no declarator
  • +
  • 2079 [[ appearing in a balanced-token-seq
  • +
  • 2085 Invalid example of adding special member function via default argument
  • +
  • 2095 Capturing rvalue references to functions by copy
  • +
  • 2096 Constraints on literal unions
  • +
  • 2098 Is uncaught_exceptions() per-thread?
  • +
  • 2104 Internal-linkage constexpr references and ODR requirements
  • +
  • 2106 Unclear restrictions on use of function-type template arguments
  • +
  • 2107 Lifetime of temporaries for default arguments in array copying
  • +
  • 2109 Value dependence underspecified
  • +
  • 2113 Incomplete specification of types for declarators
  • +
  • 2122 Glvalues of void type
  • +
  • 2129 Non-object prvalues and constant expressions
  • +
  • 2140 Lvalue-to-rvalue conversion of std::nullptr_t
  • +
  • 2141 Ambiguity in new-expression with elaborated-type-specifier
  • +
  • 2146 Scalar object vs memory location in definition of “unsequenced”
  • +
  • 2147 Initializer-list arguments and pack deduction
  • +
  • 2153 pure-specifier in friend declaration
  • +
  • 2154 Ambiguity of pure-specifier
  • +
  • 2156 Definition of enumeration declared by using-declaration
  • +
  • 2163 Labels in constexpr functions
  • +
  • 2167 Non-member references with lifetimes within the current evaluation
  • +
  • 2175 Ambiguity with attribute in conversion operator declaration
  • +
  • 2176 Destroying the returned object when a destructor throws
  • +
  • 2180 Virtual bases in destructors and defaulted assignment operators
  • +
+ +

CWG motion 3: P0188R1 "Wording for [[fallthrough]] attribute"

+ +

CWG motion 4: P0189R1 "Wording for [[nodiscard]] attribute"

+ +

CWG motion 5: P0212R1 "Wording for [[maybe_unused]] attribute"

+ +

CWG motion 6: P0017R1 "Extension to aggregate initialization"

+ +

CWG motion 7: P0170R1 "Wording for constexpr lambda"

+ +

CWG motion 8: P0036R0 "Unary folds and empty parameter packs"

+ +

CWG motion 9: P0184R0 "Generalizing the range-based for loop"

+ +

CWG motion 10: P0018R3 "Lambda capture of *this by value as [=, \*this]"

+ +

CWG motion 11: P0138R2 "Construction rules for enum class values"

+ +

CWG motion 12: P0245R1 "Hexadecimal floating literals for C++" (with normative correction, see below)

+ +

Core motions added a total of 7 pages to Clause 1-16.

+ +

Library working group motions

+ +

LWG motion 1: Library issue resolutions for 3 issues in "Ready" status applied:

+ +
    +
  • 2276 Missing requirement on std::promise::set_exception
  • +
  • 2523 std::promise synopsis shows two set_value_at_thread_exit()'s for no apparent reason
  • +
  • 2537 Constructors for priority_queue taking allocators should call make_heap
  • +
  • Note: 2253 resolution from P0165R1 was not applied by this motion
  • +
  • Note: 2255 resolution from P0165R1 was not applied by this motion
  • +
+ +

LWG motion 2: Library issue resolutions for 20 issues in "Tentatively Ready" status applied:

+ +
    +
  • 2192 Validity and return type of std::abs(0u) is unclear
  • +
  • 2450 {greater,less,greater_equal,less_equal}<void> do not yield a total order for pointers
  • +
  • 2520 N4089 broke initializing unique_ptr<T[]> from a nullptr
  • +
  • 2545 Simplify wording for bind without explicitly specified return type
  • +
  • 2557 Logical operator traits are broken in the zero-argument case
  • +
  • 2559 Error in LWG 2234's resolution
  • +
  • 2560 is_constructible underspecified when applied to a function type
  • +
  • 2565 std::function's move constructor should guarantee nothrow for reference_wrappers and function pointers
  • +
  • 2566 Requirements on the first template parameter of container adaptors
  • +
  • 2571 §[map.modifiers]/2 imposes nonsensical requirement on insert(InputIterator, InputIterator)
  • +
  • 2572 The remarks for shared_ptr::operator* should apply to cv-qualified void as well
  • +
  • 2576 istream_iterator and ostream_iterator should use std::addressof
  • +
  • 2577 {shared,unique}_lock should use std::addressof
  • +
  • 2579 Inconsistency wrt Allocators in basic_string assignment vs. basic_string::assign
  • +
  • 2581 Specialization of <type_traits> variable templates should be prohibited
  • +
  • 2582 §[res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traits
  • +
  • 2583 There is no way to supply an allocator for basic_string(str, pos)
  • +
  • 2585 forward_list::resize(size_type, const value_type&) effects incorrect
  • +
  • 2586 Wrong value category used in scoped_allocator_adaptor::construct()
  • +
  • 2590 Aggregate initialization for std::array
  • +
+ +

LWG motion 3 applies to the Library Fundamentals TS

+ +

LWG motion 4: P0024R2 "The Parallelism TS should be standardized"

+ +

LWG motion 5: P0226R1 "Mathematical special functions for C++17"

+ +

LWG motion 6: P0220R1 "Adopt library fundamentals v1 TS components for C++17" (incompletely applied, see below)

+ +

LWG motion 7: P0218R1 "Adopt the file system TS for C++17"

+ +

LWG motion 8: P0033R1 "Re-enabling shared_from_this"

+ +

LWG motion 9: P0005R4 "Adopt not_fn from library fundamentals v2 TS for C++17"

+ +

LWG motion 10: P0152R1 "constexpr atomic::is_always_lock_free"

+ +

LWG motion 11: P0185R1 "Adding {nothrow_}swappable traits"

+ +

LWG motion 12: P0253R1 "Fixing a design mistake in the searchers interface"

+ +

LWG motion 13: P0025R0 "An algorithm to "clamp" a value between a pair of boundary values" (see below)

+ +

LWG motion 14: P0154R1 "constexpr std::hardware_{constructive,destructive}_interference_size"

+ +

LWG motion 15: P0030R1 "Proposal to introduce a 3-argument overload to std::hypot"

+ +

LWG motion 16: P0031R0 "Proposal to add constexpr modifiers to reverse_iterator, move_iterator, array and range access" +and LWG2296 "std::addressof should be constexpr"

+ +

LWG motion 17: P0272R1 "Give std::string a non-const .data() member function"

+ +

LWG motion 18: P0077R2 "is_callable, the missing INVOKE related trait"

+ +

Library motions added a total of 120 pages to Clause 17-30.

+ +

Notable changes to papers as moved

+ +

CWG motion 1, issue 2017

+ +

Corrected normative wording suggesting that reaching the end of a constructor, +destructor, or function with cv-qualified void return type would result in +undefined behavior. These cases were not covered by the wording in the issue +because they are not functions with a void return type.

+ +

CWG motion 12 (hexadecimal floating literals)

+ +

The wording for this proposal omitted an essential update to the pp-number +grammar production, which is necessary to avoid a literal such as 0x1.0p+0 +being split into three tokens at the + character. The grammar has also been +editorially refactored to reduce duplication between hexadecimal floating +literals and hexadecimal integer literals.

+ +

LWG motion 4 (parallelism TS)

+ +

std::sequential, std::par, and std::par_vec were not listed in the +synopsis of any library header. They have been added to the synopsis of +<execution_policy>, based on the clear intent of their placement within the +wording.

+ +

[execpol.synopsis] was renamed to [execpol.syn] for consistency with other +synopsis subclauses.

+ +

[algorithms.parallel.exec]: fixed incorrect claims that certain well-formed +constructs with defined (but undesirable or unspecified) behavior are an error, +or undefined, in examples.

+ +

[exception.list]: added missing synopsis for <exception_list> header.

+ +

[numerics.defns]: rephrased definition of GENERALIZED_SUM in terms of +GENERALIZED_NONCOMMUTATIVE_SUM to reduce redundancy.

+ +

Contrary to the editing instructions in section 25.NaN.5 (sic), parallel +overloads of for_each and for_each_n were not added to the synopsis of +<algorithm> as they would conflict with the overloads added in section +25.2.4.

+ +

LWG motion 6 (lib fundamentals TS)

+ +

The changes to shared_ptr have not been applied, as it is unclear +exactly what changes should be made. The TS provides alternative wording +for some subsections, but some of the differences are due to changes in +the TS and some are due to changes in the working paper. Replacing the +sections in the working paper with the sections from the TS would regress +some functionality, so this portion of this motion has been returned to +LWG for a more precise specification.

+ +

LWG motion 11 (is_{nothrow_}swappable)

+ +

Changed new uses of is_{nothrow_}swappable<T>::value to instead use +is_{nothrow_}swappable_v<T>.

+ +

LWG motion 13 (clamp)

+ +

Note that the paper voted into, and applied to, the working draft was +P0025R0, +not the most recent draft of this paper, +P0025R1. +This appears to be an oversight; LWG is encouraged to prepare an issue +to apply the changes from P0025R0 to P0025R1.

+ +

LWG motion 17 (non-const std::string::data)

+ +

Fix Annex C change to correctly describe the change that was made.

+ +

Minor editorial fixes

+ +

A log of all editorial fixes made since N4567 is below:

+ +
commit f487d12b9834740c09bc92a8de45e9a712648089
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Mar 19 09:17:19 2016 -0700
+
+    Minor editorial fixes throughout the library found in review by Dawn Perchik.
+
+commit f45829932dcc765578acb25667451a7b398bbde5
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 18 03:06:42 2016 -0700
+
+    [headers] Reflow header table to 4 columns.
+
+commit e59a2dd20a8c7badb492a18589483fbd378594c9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 18 02:57:01 2016 -0700
+
+    [input.output] Add <filesystem> to summary of this Clause.
+    [headers] Add <filesystem> to list of library headers.
+
+    Fixes #648
+
+commit 0fead0abfc147c5560b80e424d8128c1a613934b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 18 02:13:16 2016 -0700
+
+    [fs] Remove apparent claim that FAT is the only filesystem used on
+    memory cards or flash cards. Even if that were true, it's not relevant
+    to the C++ standard.
+
+commit 5cb56ad5e3626f40a7d5d5962806a895cd61c4a2
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 17 10:46:52 2016 -0700
+
+    [fs] Minor fixes: formatting, style issues, over-reaching notes.
+
+commit 00697914242de485ce611da25e0f482f57882ca6
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Mar 17 22:44:33 2016 -0400
+
+    [definitions] alphasort remaining library definitions
+
+    On more careful review, a couple more definitions were
+    mildly out of order.  This patch properly sorts the
+    whole of clause 17.3 [definitions].
+
+commit 2d4a73fe2aadf7bb1ba3f3c7f0b4984e80ecc2f2
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Mar 17 21:17:44 2016 -0400
+
+    [defns.const.subexpr] Place defintition in alphabetical order
+
+    The defintions introduced in clauses 1.3 and 17.3 are
+    ordered alphabetically, other than the trailing
+    definition for 'constant subexpression', that I am
+    guessing was added at a later date.  This change
+    simply moves it into the correctly sorted place in
+    the sequence.
+
+commit d0755fad96a62af94691adf065b5864530cc611a
+Author: Zhihao Yuan <lichray@gmail.com>
+Date:   Thu Mar 17 20:09:02 2016 -0500
+
+    [dcl.init.aggr] Fix an example in extended init.
+
+commit 5450aabc5d3a434a4beb9d0577ddb4bc0358718a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 17 09:30:23 2016 -0700
+
+    [func.not_fn] Use teletype font for concept name.
+
+commit 864d1f8107436b7d9b0d7719e2e47944f3b4b338
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 17 09:14:25 2016 -0700
+
+    [alg.clamp] Add clamp to <algorithm> synopsis and reorder it before
+    lexicographical comparisons to match the synopsis order.
+
+commit 7844267fee0e7c745be0af01754a7d64bf7f7c55
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 17 07:59:09 2016 -0700
+
+    [func.searchers.boyer_moore_horspool.creation] Fix typo
+    boyer_moore_searcher_horspool and manually wrap overfull hbox.
+
+commit f1fb15be9c46e4662d2e3af1bfe3e70d8612bf97
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 17 07:20:39 2016 -0700
+
+    [utilities], [containers] Replace 'is_nothrow_swappable<T>::value' with
+    'is_nothrow_swappable_v<T>' and likewise for 'is_swappable'.
+
+commit f44bf31c6ad300683df2b810ee46ec95f5ecab15
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Mar 17 10:14:49 2016 -0400
+
+    [diff.cpp11.expr] Move removal of bool++ from C++14 compatibility annex to C++17 annex
+
+    This change was clearly introduced in C++17, at the same meeting
+    as removing the meaning of the register keyword.  I can see no
+    Core issue tied to this removal being resolved as a DR against
+    14 or earlier.
+
+    I have confirmed that paper p0002r1 applied this to the C++17
+    annex, but was listed as a change in annex D rather than clause
+    5 - the latter change seeming the consistent editorial policy
+    for removed Core features, so retained.
+
+commit 6914707917b05ad4e4e46b6eca015d1d799f651e
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Mar 16 15:47:27 2016 +0000
+
+    [fs.def.parent] Split into two definitions using \\defncontext
+
+commit 971cbbc8986c11bceba95e5bfec1547651888cc0
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 17 13:46:00 2016 +0000
+
+    [filesystems] Adjust table layout and references
+
+commit e9e443ad270f5b4c16c525dbeff7dd1ed4fdf7f0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Mar 17 13:29:12 2016 +0000
+
+    [dcl.attr] Fix wrong source encoding
+
+commit 63c062fbf8eb7e07016f5e0bf5f96fd460f6c01c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 14 14:37:24 2016 -0700
+
+    [expr.prim.lambda] Add missing linebreak before new
+      simple-capture ::= *this
+    grammar production.
+
+commit c13d24e396a587a545bab9b5347f1bf7233b3f86
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Mon Mar 14 11:23:40 2016 -0700
+
+    [expr.prim.lambda] Use \CppXIV instead of \Cpp14.
+
+commit 2fe4e865014b4eb1b10f1bf24c6ce2ad13ea0528
+Author: Ondřej Majerech <majerech.o@gmail.com>
+Date:   Wed Apr 15 00:44:32 2015 +0200
+
+    [lex, dcl.decl] Use \nontermdef and \grammarterm more consistently.
+
+commit 1da521ef8a399f4c1d6bb30893fe18a7fcaafc84
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Mar 12 17:47:32 2016 +0000
+
+    [strings] Formatting and whitespace harmonization
+
+commit 924863b47bc3e5be39142126baa2ce1096a5659e
+Author: cpplearner <cpplearner@outlook.com>
+Date:   Sun Mar 13 01:31:02 2016 +0800
+
+    [valarray.members] add missing \end{itemdescr} and \begin{itemdescr}
+
+commit 332b3edda5424496542e406d8ec4d272198edad4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Mar 8 13:23:35 2016 +0000
+
+    [utilities] Add some hyphenation hints for long inline expressions
+
+commit d598cb6588b550709593a14721c091cadc976d6a
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Sat Mar 12 18:12:50 2016 +0800
+
+    Fix wrong reference
+
+    Change for `&&` in [diff.cpp03.expr] should refer to [expr.log.and] rather than [expr.log.or].
+
+commit 6139ef913c12760c15346a04aac92d01013f6509
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 11 15:17:00 2016 -0800
+
+    Move all std::basic_string subclauses under [string.classes] in
+    preparation for adding a sibling clause for string_view.
+
+commit 69bc5713208c0a30c30913d5112ed8512e8c7e2d
+Author: MikeHerrick <mjh@edg.com>
+Date:   Thu Mar 10 14:18:23 2016 -0500
+
+    Add missing "*" in example.
+
+commit 4f0b604ca12ffa960a923473b2106e973d42a18d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Mar 10 01:09:12 2016 +0000
+
+    [macros] Make \Cpp work in PDF bookmarks again
+
+commit 4f094359f43e7b97afbe7038e89adde78161db91
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 9 17:04:09 2016 -0800
+
+    [lex.ppnumber] Add p+ and P+ as valid components of a pp-number token.
+    This edit was missed from P0245R1, but was intended and is a fundamental
+    part of the proposal.
+
+commit 9ca4d1dccf2a09261de94b99ea3c78d1cd4b1228
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 9 17:02:46 2016 -0800
+
+    [lex.literal] Reuse hexadecimal-prefix and hexadecimal-digit-sequence to specify the form of a hexadecimal-literal.
+
+commit 875037be77746139e90f02da33700baf014984b3
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 9 15:25:18 2016 -0800
+
+    [dcl.attr] Reorder [[noreturn]] after [[nodiscard]] to put attribute sections in alphabetical order.
+
+commit aab51a5c2e57779b55a9d7cf59521512017f4469
+Author: Jakub Wilk <jwilk@jwilk.net>
+Date:   Wed Mar 9 16:47:38 2016 +0100
+
+    [temp.variadic] Fix typo "evalutes"
+
+commit aae5ada0b13aa9ae618ada206be1d8bbb499691b
+Author: Jakub Wilk <jwilk@jwilk.net>
+Date:   Wed Mar 9 16:45:08 2016 +0100
+
+    [re.alg.match] Fix typo "otherwis"
+
+commit 66eaea094e5b8e1d3aaf85827f75dc0f4bba1af6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Mar 7 23:16:29 2016 +0000
+
+    [diff] Use \Cpp macro
+
+commit 7a33e38692f60fa5968c4d751899319b3a57fedf
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 5 17:05:01 2015 +0000
+
+    [macros] Change \Cpp macro to look nicer
+
+commit 43b65fb672406bcaaef4cd18d77b2e8846513414
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Mar 4 23:21:26 2016 +0000
+
+    [lex] Remove spurious whitespace
+
+commit be071acabed55cbcd88d96c6f17ba7d0c1bad158
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 5 18:39:22 2015 +0000
+
+    Use textual angle brackets in body text
+
+commit cc003c2ba4ffb430a85823a237e6e6a3173fee0c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 2 06:46:52 2016 -0800
+
+    [dcl.align] Remove "other than <list of types>" from example that
+    actually works for all types, per CWG discussion.
+
+commit 97b037322d5bd76ca32ee4376e201261b16cb94b
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Tue Mar 1 17:16:51 2016 -0800
+
+    Unify the formatting of "Equivalent to" be consistent.
+
+commit d8463494a40c6d733c22ff4850db0dbe31813b43
+Author: faisal vali <faisalv@yahoo.com>
+Date:   Sat Feb 27 11:41:31 2016 -0600
+
+    Delete the redundant 'update' when describing actions upon independent memory locations.  The definition of 'access' includes modifying a location per 1.3.1/access.
+
+commit f35f6e7c5e2a46965b5dff18eb8f7ed50145f910
+Author: Jakub Wilk <jwilk@jwilk.net>
+Date:   Thu Feb 25 13:46:46 2016 +0100
+
+    [futures.shared_future] Remove duplicated word "shared"
+
+commit cdd1377fc24d02d784d83ad83fae0f9610e8971b
+Author: Jakub Wilk <jwilk@jwilk.net>
+Date:   Thu Feb 25 13:51:10 2016 +0100
+
+    [conv.qual] Fix typo "desecender"
+
+commit 8ebbcaebe13ed8ab0545cdf54c4f46e4d7130338
+Author: Jakub Wilk <jwilk@jwilk.net>
+Date:   Thu Feb 25 13:52:34 2016 +0100
+
+    [diff.class] Fix typo "choise"
+
+commit 66f77b68bda58169ec65a1095a68d6e483bbb6f4
+Author: Kazutoshi SATODA <k_satoda@f2.dion.ne.jp>
+Date:   Sat Feb 13 20:42:56 2016 +0900
+
+    Uniform "ones' complement" and "two's complement"
+
+    "one's complement" is inconsistent with the C standard.
+    "1's complement" and "2's complement" are also inconsistent.
+
+commit 4ad54d82b27e441ead663c692c65597ee8a96254
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Wed Feb 10 22:06:15 2016 +0100
+
+    [gram.key] Remove unreferenced original-namespace-name nonterminal.
+
+commit 7838080df6f4dcb2784f432bfd5abe09391fc163
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Wed Feb 10 22:04:55 2016 +0100
+
+    [gram.key] Make BNF for namespace-name the same as in [gram.dcl] and [namespace.def].
+
+commit 7798b417ae3a512281e62aa779882fbaf6fbf780
+Author: Marshall Clow <marshall@idio.com>
+Date:   Tue Feb 9 14:40:52 2016 -0800
+
+    Swap effects of `basic_regex::operator=` and `assign`
+
+    Currently, `basic_regex::operator=` is defined in terms of assign. This is different from what `basic_string` (and possibly others) do.
+    Swap the descriptions so that `assign` is now defined in terms of `operator=`. No functional change to either is intended.
+
+commit 820981d9b2ac715c926322f649c6ae3ba56bce08
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Sun Feb 7 00:16:37 2016 +0800
+
+    [unique.ptr.runtime.ctor] Fix format
+
+    Add missing `\tcode` in [unique.ptr.runtime.ctor]/2.2.
+
+commit be271b03bf445565a1d8bfcdd013b394f81acb5e
+Author: Marshall Clow <marshall@idio.com>
+Date:   Thu Feb 4 10:22:20 2016 -0800
+
+    Remove incorrect "shall"
+
+    while looking at LWG issue #2589, I noticed that L2554 says "`match_results` shall satisfy the ...".
+    In general, we use "shall" to place requirements on user code, not on library code.
+    Change to just say "satisfies", rather than "shall satisfy"
+
+commit 1aa9db108aed9defea71e226399e05e1717e887f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Feb 1 14:48:04 2016 -0800
+
+    [temp.res] Fix self-contradiction in paragraph describing when a template
+    with valid specializations can be diagnosed.
+
+    Also convert to bulleted form for clarity.
+
+commit a9c79d87f28c0ee53179ce46b97c23af92e67dfc
+Author: Hubert Tong <hstong@ibm>
+Date:   Fri Jan 29 12:54:41 2016 -0500
+
+    [terminate] Fix typo "terminate_handleri"
+
+commit a495f2445eaf2eb5c4c7562734fd2e346b8cbbdb
+Author: morinmorin <mimomorin@gmail.com>
+Date:   Wed Jan 27 00:45:41 2016 +0900
+
+    [support.types] Remove "field", which is not a defined term in C++.
+
+commit e69c75e23694c67b6351b75eae2627ef9dcd4e44
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Tue Jan 26 23:33:55 2016 +0800
+
+    [defns.const.subexpr] Remove superfluous words
+
+commit 356f765cc2ff2623d6de4855956d0abfaae5ec9a
+Author: Stephan Bergmann <sbergman@redhat.com>
+Date:   Mon Jan 18 17:04:06 2016 +0100
+
+    Missing closing parenthesis
+
+commit b91c5766274ec1c60b5e90b1258f067bb9272b14
+Author: Aaron Ballman <aaron@aaronballman.com>
+Date:   Thu Jan 14 10:59:48 2016 -0500
+
+    Adding a note about what a member subobject is
+
+commit d50dd6328c03377e382718d8dae8696ac1028af7
+Author: Aaron Ballman <aaron@aaronballman.com>
+Date:   Mon Jan 11 15:38:15 2016 -0500
+
+    Making identifier label into a definition.
+
+commit f56239c3df9c4a3ed21b6382e1af66f2c24872e5
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Sat Jan 9 12:56:49 2016 -0500
+
+    [expr.const] adjust note
+
+    Array bounds now use "converted constant expressions of type std::size_t", not integral constant expressions.
+
+commit 87ef71b8e72c5867bfb6d2f7ea59c0b459fc17fe
+Author: Frank Columbo <columbo@gmx-topmail.de>
+Date:   Sat Jan 9 17:24:05 2016 +0100
+
+    [dcl.type.cv]/6 "program behavior" vs "behavior"
+
+    [dcl.type.cv]/6 reads
+
+    > If an attempt is made to refer to an object defined with a volatile-qualified type through the use of a glvalue with
+    a non-volatile-qualified type, the program behavior is undefined.
+
+    This is probably meant to use the much more idiomatic phrase "the behavior is undefined". A distinction between well-definedness of the program's and the implementation's behavior would presumably be inappropriate, anyway.
+
+commit 9c123b4655276a806d218d28107c76d5f7c9bda9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jan 6 11:27:10 2016 -0800
+
+    [stmt.label] Clarify what it means for labels to be in their own name space.
+
+commit 09b0265c5f194f91ae8b9a28781e13eff29c6d67
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Fri Jan 1 20:39:22 2016 -0500
+
+    [c.files] cinttypes synopsis refers to SCNX* macros which do not exist
+
+commit de0bfd210a4f6837c13a9a846219922f45b4ffe1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Dec 21 20:30:56 2015 +0000
+
+    [macros, atomic] Align placeholders
+
+commit 2e0156c630f10131121b2b485b171b3c59354654
+Author: Arcoth <columbo@gmx-topmail.de>
+Date:   Mon Sep 28 22:04:25 2015 +0100
+
+    [over.best.ics] Fix a typo in "user-defined conversion sequence"
+
+commit 5add43af6ed8219f156ceb5ffc0a02b6ca6cd613
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Wed Dec 16 22:49:10 2015 -0500
+
+    [diff.library] add missing NULL <cstdio> and correct counts
+
+commit f09023e775f4aa827efed9b7bf04c4b01f76f16b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 19 13:45:03 2015 +0000
+
+    [algorithms] Improve typographic consistency of complexity expressions
+
+commit b1f17ea952a582dc028c27094e205c98bf48d6b2
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 19 00:01:18 2015 +0000
+
+    [complex] Clarify the range of return values of log
+
+commit 176ac169e3a9637bd8a029ac4b5afe6df3f963f6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 18 23:59:06 2015 +0000
+
+    [complex.numbers] Make whitespace and capitalization more consistent
+
+commit 1810a1c177f57893c078ab506a283dc64a6e6a7b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 18 21:10:08 2015 +0000
+
+    [alg.transform] Relayout list of requirements as itemization
+
+commit 98ffdab9bcb02757b5dd3cdaa3be78fe31bde8fc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 18 14:37:46 2015 +0000
+
+    [macros] Add space into \range and remove preposterous linebreaks.
+
+commit 0475290dfbba9bfe1df4056a9b8e4d60299fc5a2
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 11 15:38:00 2015 +0000
+
+    [atomics] Remove incomplete mention of "inttypes.h" and reword table headers
+
+commit a7d10e342fe482e84c0379881842de8b0b136fbf
+Author: K-ballo <k@fusionfenix.com>
+Date:   Sat Nov 21 21:59:33 2015 -0300
+
+    [futures.async] Use code font for "std::async"
+
+commit ab47599ef9fbcb3682de414be55315c1c6be5a92
+Author: Stephan Bergmann <sbergman@redhat.com>
+Date:   Thu Aug 21 15:16:07 2014 +0200
+
+    Typographic fixes, spacing after \opt
+
+    * occurrences of "\opt \terminal{" apparently always require "\opt{}" to not eat
+      the intervening space (despite the \xspace in the definition of \opt)
+
+    * cleaned up two occurrences of "\opt\ " (in
+
+        noptr-abstract-pack-declarator \terminal{[} constant-expression\opt\ \terminal{]} attribute-specifier-seq\opt\br
+
+      in declarators.tex and grammar.tex) to consistenly use "\opt{}" instead
+
+    * cleaned up two occurrences of "\opt{}" (in
+
+        pp-tokens\opt{} new-line
+
+      in grammar.tex and preprocessor.tex) that did not need the "{}"
+
+commit 4926f71c3749dacf3a6ee3b6d34cfc110e66c48b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 11 11:20:56 2015 +0000
+
+    [lib-intro, utilities] Apply \placeholder macro
+
+commit 63305182f3c7efba1dbcaf35d1799e2fc95611b4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 11 10:37:01 2015 +0000
+
+    [iterators, locales] Apply \placeholder macro
+
+commit 79d9ef81fce6ac8c6288a442a7f3a806111cd239
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Dec 8 14:30:52 2015 -0800
+
+    [basic.link] Reword sentence to make it more obvious how it's supposed
+    to be parsed.
+
+commit 439e6dd8689cf87b1f69622bdf85595d715e6740
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 5 13:16:11 2015 +0000
+
+    [utilities] Whitespace fixes around punctuators
+
+commit f370968913b102a864b8e884d9dad7d7ad698ee4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 5 13:43:15 2015 +0000
+
+    [diagnostics] Whitespace fixes around punctuators
+
+commit 45a0bac65d40819ac7b8c776035871790545d21a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 5 13:40:00 2015 +0000
+
+    [containers] Whitespace fixes around punctuators
+
+commit 985442177aeff5266ca61c00251b1817241e3df1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 1 22:11:23 2014 +0100
+
+    [localization] Change bold-slanted font to simple italics. This removes
+    LaTeX "missing font" warning and is also perfectly sufficient to mark
+    "variable code". Apply consistently to a second use case, too.
+
+commit f52687ef470178f0499b575b01eaf407a5d579bd
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Fri Dec 4 23:33:15 2015 -0500
+
+    [func.wrap.func.con] Fix error in note
+
+    This note should be talking about the callable object being wrapped, i.e., f, rather than its "target", which makes no sense for arbitrary callable objects. This seems to be a copy/paste error from the very similar note in the copy constructor's description a few paragraphs above.
+
+commit 9ff5696dcdaa08ff5a45a09674d72798c77beb36
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Dec 4 18:39:47 2015 -0800
+
+    [class.inhctor.init] Fix typo in example.
+
+commit 1a8c2e9664479485f6a007d112f3e3a2582af259
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Dec 4 18:18:44 2015 -0800
+
+    [class.inhctor.init] Add missing closing paren from P0136R1.
+
+commit 4839a73c30a2647e09094c0a513a5ccb9d715046
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Dec 4 18:01:40 2015 -0800
+
+    [containers] Fix whitespace issues in container overviews.
+
+    Replace '> >' with '>>' in template parameter lists.
+    Fix horizontal alignment issues after /implementation defined/ types.
+    Make horizontal alignment within "types" sections consistent across all
+    the container types.
+
+commit ee12083756d86a993993b9fce4554bde6250048d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Dec 4 16:53:34 2015 -0800
+
+    [stmt.ranged] Repeat grammar snippet to clarify what we mean by a
+    "range-based for statement", and improve formatting to match that of
+    [stmt.for].
+
+    Also add some missing italics for grammar terms in [stmt.for].
+
+commit 1d77bb33667df24eeff26cf09b94840e7daadbce
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Apr 14 17:06:15 2015 +0100
+
+    [containers] Make intra-synopsis comments consistent
+
+commit 348289cab8b6b915b74097349cebe502b44941d4
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Nov 25 20:25:59 2015 +0000
+
+    [propagation] use code font for exception_ptr
+
+commit 6db40e3d34384a12af641ffb969ebe369977e0cf
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 23 17:16:26 2015 -0800
+
+    [replacement.functions] Remove reference to sized nothrow operator
+    delete functions, which were removed by LWG2458.
+
+commit fddf2bf31c36a037cb309966996779c026f5cd68
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 23 17:07:01 2015 -0800
+
+    Fix alignment issues involving /see below/ and /implementation-defined/
+    placeholders in library text.
+
+commit 5ca060ccacdcf956dca0827df6e71a84a34a05a7
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 23 16:24:41 2015 -0800
+
+    Fix horizontal alignment around /unspecified/ placeholders in the library.
+
+    This adds the \itcorr command which can be used to insert spacing
+    corresponding to the width of the italic correction for the current
+    font (and \itcorr[-1] which can be used to remove said spacing).
+
+commit 6ff1290d603e56e18e452c490feeaa5f525f68b0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 23 20:54:13 2015 +0000
+
+    [xref] Update xrefs following 7bcdb21 and 3449445
+
+commit 34494450b68ba9e2cb3dc8650fc2cf27277faef4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 20 21:02:06 2015 +0000
+
+    [diagnostics] Turn synopses into numbered sections
+
+commit 7bcdb21bb22d62c61cd45fc811e141981bf39d37
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 20 20:40:16 2015 +0000
+
+    [support] Turn synopses into numbered sections
+
+commit 36c13aa344d35ddfcf9410f92dcfcf0051cf95dc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 20 12:20:16 2015 +0000
+
+    [library] Fix index entry
+
+commit f76be1182f5fb5aeaef1ea92de65e2109d0230e7
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Thu Nov 19 21:18:54 2015 +0100
+
+    [except.ctor] Remove broken and unnecessary index entry.
+
+commit be24c457b2f6bdf0bd709cbdf082ca648619f4de
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sun May 10 18:32:55 2015 +0200
+
+    [time.clock.system] Remove periods from impldef index entries.
+
+commit 325f7dbd48b688120e6ee06e395831cca9b54a5e
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sun Apr 19 23:39:13 2015 +0200
+
+    [defns.blocked] Use correct character for index subentry.
+
+commit e0d53e979ce2c45350f94a25a8a8a4d9819a7714
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sun Apr 19 22:19:22 2015 +0200
+
+    [dcl.ref] Move an index entry closer to what it indexes.
+
+commit aa8c0b3cbf097c40d1667c20888411325ec967e9
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sun Apr 19 21:57:33 2015 +0200
+
+    [over.over] Make index entry for overloaded function consistent with the one in [expr.unary.op].
+
+commit a4b28063a1f9ed5f0e65fc1ff22fd76280cfd707
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sun Apr 19 21:24:31 2015 +0200
+
+    [gram, gram.key, lex.ppnumber] Use \indextext instead of \index.
+
+commit e525c60ebaf2e54d19642614372cdc7ce768e606
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sun Apr 19 12:12:43 2015 +0200
+
+    [intro] Fix index entry that uses !see instead of |see.
+
+commit d557517f82a30cb0aa991f99f12d09b75742551d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 19 18:42:44 2015 +0000
+
+    [locale.id] Add missing \tcode
+
+commit 45201e86de1f68c2ddb84b1dc90d961e97a9195f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Nov 19 13:34:06 2015 +0000
+
+    [rand.adapt.general] apply ref fix from LWG 2181
+
+commit 54a256349e104cbaffe7bc3f1e41b3dd75837444
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Nov 19 11:25:28 2015 +0000
+
+    [headers] Add <shared_mutex> to Table 14.
+
+    Also update total number of headers and add [diff.cpp11.library].
+
+commit 3e355a55199d77949fa2010f867d6afa3764c7ba
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Nov 19 11:10:24 2015 +0000
+
+    [time.point.cast] replaces braces with parentheses
+
+    Fixes #562.
+
+commit faf6ce008124ccaeaf8f77d31f3fb72bd2fcafdd
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Nov 19 11:00:06 2015 +0000
+
+    [memory.syn] add default argument to owner_less
+
+    Also change class-key to 'struct' to match later definition.
+
+commit 27d6d806169ed7b4b0c12c760c78879b8f95290c
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Fri Oct 23 02:49:09 2015 -0400
+
+    [fstream.members] Fix "returns returns".
+
+commit 4d69bcb2f0c8fea313fdc653c01e2f736525b976
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Nov 18 11:29:44 2015 +0000
+
+    [allocator.requirements], [res.on.arguments] qualify std::move
+
+commit a82e553e2be894227523f57692b6f44358f92cd9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 18 01:17:46 2015 +0000
+
+    [utility] Make spelling of 'cv void' more consistent
+
+commit 6ee833203b85e4d8f5c5d89b9ba47cf8689ff3fb
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 18 01:17:07 2015 +0000
+
+    [class] Clarify 'cv-void class members'
+
+commit 35267c4c08272f3c618c8e9106b811af09c2734d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sun Nov 15 11:55:25 2015 +0000
+
+    [sequences.general] Promote header synopses to rSec2
+
+commit 20e643f0402d7b4900604343a2a8c3f36a26c2f8
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sun Nov 15 11:32:17 2015 +0000
+
+    [stack.syn] Move <stack> synopsis after <queue> synopsis
+
+commit bcef6cb3c5321f88ec12d5a342c40bc2f56a7b8f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 9 23:59:23 2015 -0500
+
+    [dcl.init.ref] Replace normative note with actual note.
+
+commit 837fc82bba927a1c3427c83fa99851a78570f345
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 13 14:04:03 2015 -0800
+
+    Turn off ligature formation in \texttt. In a couple of places, we were
+    rendering << or >> as guillemets.
+
+commit 4c21b190c7201486d70699261521fc6c78054f8e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 13 13:53:05 2015 -0800
+
+    Use microtype package; this allows us to word wrap less often.
+
+commit a764b26ebddd3571a78b7b117156ebe27d84245d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 13 11:55:28 2015 -0800
+
+    [util.smartptr.ownerless] Italicize "unspecified".
+
+commit 70c3b9f3a950022cd4531decbff8fbd29b4a208c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 13 11:55:04 2015 -0800
+
+    Remove unwanted spaces after /unspecified/ in library synopses.
+
+commit 6e6edc1f620ab0e17102556cb65819c572ae655f
+Author: Mitsuru Kariya <kariya_mitsuru@hotmail.com>
+Date:   Thu Sep 17 12:33:48 2015 +0900
+
+    Refine "Index of library names" for operator<< and operator>>
+
+commit f4efabd91987982442d36e26e0003d752850d6a2
+Author: Stephan Bergmann <sbergman@redhat.com>
+Date:   Tue Jul 14 11:26:38 2015 +0200
+
+    Local definition of "char-like type" from Clause 21 referenced in Clause 28
+
+    ...so drop "In this Clause" from the definition in [strings.general] and add a
+    reference to the first use in [re.general].
+
+    See <https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/dGc1exSnPps>
+    "Local definition of "char-like type" from Clause 21 referenced in Clause 28"
+    for a discussion of this (presumably editorial) issue.
+
+commit 5f62a33f50c8d3fd736d552d41b860189cdb5ba7
+Author: Zhihao Yuan <lichray@gmail.com>
+Date:   Thu May 7 16:05:37 2015 -0500
+
+    No qualified std::fclose call
+
+commit 2fe773b9dfe80f3ac5349e7040d352e9d9cf8b26
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Apr 14 17:06:15 2015 +0100
+
+    [containers] Minor whitespace and ordering improvements
+
+commit 4779c8ac3dcd91ee4387969f863a5f40b587c0fb
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Apr 1 17:47:37 2015 +0100
+
+    Update Table 121. Rename [fstreams]. Move [fstreams]/2.
+
+commit 98ca118b5a91e81d63f4e782f1e4c657137c692c
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Sep 23 10:11:38 2014 +0100
+
+    [file.streams] Change sub-clauses to rSec2, similar to [string.streams]
+
+    Promote [c.files] to rSec1.
+
+commit f41da80744bd5da13cc9dc19fc0d572889a78b63
+Author: cpplearner <cpplearner@outlook.com>
+Date:   Sun Oct 12 17:04:50 2014 +0800
+
+    [diff.expr] replace "declare" with "define"
+
+    It is always legal in C++ to declare new types in a sizeof expression or cast expression, but you can't *define* a new type in an expression.
+
+commit 93838cd1d5a673efb313783971a94b73112d1b06
+Author: Kazutoshi SATODA <k_satoda@f2.dion.ne.jp>
+Date:   Sat Aug 2 17:18:46 2014 +0900
+
+    Uniform notation of distance(first, last) to (last - first)
+
+    As allowed in 25.1 [algorithms.general] p12, to express the same things
+    as same.
+
diff --git a/papers/n4583.md b/papers/n4583.md new file mode 100644 index 0000000000..c01af986b0 --- /dev/null +++ b/papers/n4583.md @@ -0,0 +1,1100 @@ +# N4583 Editor's Report -- Working Draft, Standard for Programming Language C++ + +2016-03-09 +Richard Smith +Google Inc +`` + +## Acknowledgements + +Very special thanks to Dawn Perchik, who performed many all the edits for +motions moved at Jacksonville (any errors are mine). + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and those who have provided pull requests with fixes. + +## New papers + + * [N4582](http://wg21.link/n4582) is the current working draft. It replaces [N4567](http://wg21.link/n4567). + * N4583 is this Editor's Report for the current working draft. + +### Motions incorporated into working draft + +#### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p0167r2) from 14 issues applied, resolving 15 issues: + + * [1734](http://wg21.link/cwg1734) Nontrivial deleted copy functions + * [1895](http://wg21.link/cwg1895) Deleted conversions in conditional operator operands + * [1930](http://wg21.link/cwg1930) *init-declarator-list* vs *member-declarator-list* + * [1932](http://wg21.link/cwg1932) Bit-field results of conditional operators **(no changes, resolved by 1895)** + * [1955](http://wg21.link/cwg1955) `#elif` with invalid controlling expression + * [2001](http://wg21.link/cwg2001) *non-directive* is underspecified + * [2008](http://wg21.link/cwg2008) Default *template-arguments* underspecified + * [2017](http://wg21.link/cwg2017) Flowing off end is not equivalent to no-expression `return` **(with normative correction, see below)** + * [2082](http://wg21.link/cwg2082) Referring to parameters in unevaluated operands of default arguments + * [2084](http://wg21.link/cwg2084) NSDMIs and deleted union default constructors + * [2093](http://wg21.link/cwg2093) Qualification conversion for pointer-to-member handler matching + * [2099](http://wg21.link/cwg2099) Inferring the bound of an array static data member + * [2124](http://wg21.link/cwg2124) Signature of constructor template + * [2130](http://wg21.link/cwg2130) Over-aligned types in *new-expression*s + * [2157](http://wg21.link/cwg2157) Further disambiguation of enumeration *elaborated-type-specifier* + +CWG motion 2: [Core issue resolutions](http://wg21.link/p0263r1) from 48 issues applied, resolving 49 issues: + + * [212](http://wg21.link/cwg212) Implicit instantiation is not described clearly enough + * [238](http://wg21.link/cwg238) Precision and accuracy constraints on floating point + * [242](http://wg21.link/cwg242) Interpretation of old-style casts + * [1284](http://wg21.link/cwg1284) Should the lifetime of an array be independent of that of its elements? + * [1315](http://wg21.link/cwg1315) Restrictions on non-type template arguments in partial specializations + * [1496](http://wg21.link/cwg1496) Triviality with deleted and missing default constructors + * [1638](http://wg21.link/cwg1638) Declaring an explicit specialization of a scoped enumeration + * [1872](http://wg21.link/cwg1872) Instantiations of constexpr templates that cannot appear in constant expressions + * [1992](http://wg21.link/cwg1992) `new (std::nothrow) int[N]` can throw + * [2012](http://wg21.link/cwg2012) Lifetime of references + * [2032](http://wg21.link/cwg2032) Default template-arguments of variable templates + * [2033](http://wg21.link/cwg2033) Redundant restriction on partial specialization argument + * [2038](http://wg21.link/cwg2038) Document C++14 incompatibility of new braced deduction rule + * [2039](http://wg21.link/cwg2039) Constant conversions to `bool` + * [2040](http://wg21.link/cwg2040) *trailing-return-type* no longer ambiguous + * [2041](http://wg21.link/cwg2041) Namespace for explicit class template specialization + * [2044](http://wg21.link/cwg2044) `decltype(auto)` and `void` + * [2047](http://wg21.link/cwg2047) Coordinating “throws anything” specifications + * [2061](http://wg21.link/cwg2061) Inline namespace after simplifications + * [2063](http://wg21.link/cwg2063) Type/nontype hiding in class scope + * [2064](http://wg21.link/cwg2064) Conflicting specifications for dependent *decltype-specifier*s + * [2066](http://wg21.link/cwg2066) Does type-dependent imply value-dependent? **(no changes, resolved by 2109)** + * [2068](http://wg21.link/cwg2068) When can/must a defaulted virtual destructor be defined? + * [2069](http://wg21.link/cwg2069) Do destructors have names? + * [2071](http://wg21.link/cwg2071) typedef with no declarator + * [2079](http://wg21.link/cwg2079) `[[` appearing in a *balanced-token-seq* + * [2085](http://wg21.link/cwg2085) Invalid example of adding special member function via default argument + * [2095](http://wg21.link/cwg2095) Capturing rvalue references to functions by copy + * [2096](http://wg21.link/cwg2096) Constraints on literal unions + * [2098](http://wg21.link/cwg2098) Is `uncaught_exceptions()` per-thread? + * [2104](http://wg21.link/cwg2104) Internal-linkage constexpr references and ODR requirements + * [2106](http://wg21.link/cwg2106) Unclear restrictions on use of function-type template arguments + * [2107](http://wg21.link/cwg2107) Lifetime of temporaries for default arguments in array copying + * [2109](http://wg21.link/cwg2109) Value dependence underspecified + * [2113](http://wg21.link/cwg2113) Incomplete specification of types for declarators + * [2122](http://wg21.link/cwg2122) Glvalues of `void` type + * [2129](http://wg21.link/cwg2129) Non-object prvalues and constant expressions + * [2140](http://wg21.link/cwg2140) Lvalue-to-rvalue conversion of `std::nullptr_t` + * [2141](http://wg21.link/cwg2141) Ambiguity in new-expression with elaborated-type-specifier + * [2146](http://wg21.link/cwg2146) Scalar object vs memory location in definition of “unsequenced” + * [2147](http://wg21.link/cwg2147) Initializer-list arguments and pack deduction + * [2153](http://wg21.link/cwg2153) *pure-specifier* in `friend` declaration + * [2154](http://wg21.link/cwg2154) Ambiguity of *pure-specifier* + * [2156](http://wg21.link/cwg2156) Definition of enumeration declared by *using-declaration* + * [2163](http://wg21.link/cwg2163) Labels in constexpr functions + * [2167](http://wg21.link/cwg2167) Non-member references with lifetimes within the current evaluation + * [2175](http://wg21.link/cwg2175) Ambiguity with attribute in conversion operator declaration + * [2176](http://wg21.link/cwg2176) Destroying the returned object when a destructor throws + * [2180](http://wg21.link/cwg2180) Virtual bases in destructors and defaulted assignment operators + +CWG motion 3: [P0188R1 "Wording for `[[fallthrough]]` attribute"](http://wg21.link/p0188r1) + +CWG motion 4: [P0189R1 "Wording for `[[nodiscard]]` attribute"](http://wg21.link/p0189r1) + +CWG motion 5: [P0212R1 "Wording for `[[maybe_unused]]` attribute"](http://wg21.link/p0212r1) + +CWG motion 6: [P0017R1 "Extension to aggregate initialization"](http://wg21.link/p0017r1) + +CWG motion 7: [P0170R1 "Wording for constexpr lambda"](http://wg21.link/p0170r1) + +CWG motion 8: [P0036R0 "Unary folds and empty parameter packs"](http://wg21.link/p0036r0) + +CWG motion 9: [P0184R0 "Generalizing the range-based for loop"](http://wg21.link/p0184r0) + +CWG motion 10: [P0018R3 "Lambda capture of `*this` by value as `[=, \*this]`"](http://wg21.link/p0018r3) + +CWG motion 11: [P0138R2 "Construction rules for `enum class` values"](http://wg21.link/p0138r2) + +CWG motion 12: [P0245R1 "Hexadecimal floating literals for C++"](http://wg21.link/p0245r1) **(with normative correction, see below)** + +Core motions added a total of 7 pages to Clause 1-16. + +#### Library working group motions + +LWG motion 1: [Library issue resolutions](http://wg21.link/p0165r1) for 3 issues in "Ready" status applied: + + * [2276](http://wg21.link/lwg2276) Missing requirement on `std::promise::set_exception` + * [2523](http://wg21.link/lwg2523) `std::promise` synopsis shows two `set_value_at_thread_exit()`'s for no apparent reason + * [2537](http://wg21.link/lwg2537) Constructors for `priority_queue` taking allocators should call `make_heap` + * Note: [2253](http://wg21.link/lwg2253) resolution from P0165R1 was *not* applied by this motion + * Note: [2255](http://wg21.link/lwg2255) resolution from P0165R1 was *not* applied by this motion + +LWG motion 2: [Library issue resolutions](http://wg21.link/p0165r1) for 20 issues in "Tentatively Ready" status applied: + +* [2192](http://wg21.link/lwg2192) Validity and return type of `std::abs(0u)` is unclear +* [2450](http://wg21.link/lwg2450) `{greater,less,greater_equal,less_equal}` do not yield a total order for pointers +* [2520](http://wg21.link/lwg2520) N4089 broke initializing `unique_ptr` from a `nullptr` +* [2545](http://wg21.link/lwg2545) Simplify wording for `bind` without explicitly specified return type +* [2557](http://wg21.link/lwg2557) Logical operator traits are broken in the zero-argument case +* [2559](http://wg21.link/lwg2559) Error in LWG 2234's resolution +* [2560](http://wg21.link/lwg2560) `is_constructible` underspecified when applied to a function type +* [2565](http://wg21.link/lwg2565) `std::function`'s move constructor should guarantee nothrow for `reference_wrapper`s and function pointers +* [2566](http://wg21.link/lwg2566) Requirements on the first template parameter of container adaptors +* [2571](http://wg21.link/lwg2571) §[map.modifiers]/2 imposes nonsensical requirement on `insert(InputIterator, InputIterator)` +* [2572](http://wg21.link/lwg2572) The remarks for `shared_ptr::operator*` should apply to *cv*-qualified `void` as well +* [2576](http://wg21.link/lwg2576) `istream_iterator` and `ostream_iterator` should use `std::addressof` +* [2577](http://wg21.link/lwg2577) `{shared,unique}_lock` should use `std::addressof` +* [2579](http://wg21.link/lwg2579) Inconsistency wrt Allocators in `basic_string` assignment vs. `basic_string::assign` +* [2581](http://wg21.link/lwg2581) Specialization of `` variable templates should be prohibited +* [2582](http://wg21.link/lwg2582) §[res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traits +* [2583](http://wg21.link/lwg2583) There is no way to supply an allocator for `basic_string(str, pos)` +* [2585](http://wg21.link/lwg2585) `forward_list::resize(size_type, const value_type&)` effects incorrect +* [2586](http://wg21.link/lwg2586) Wrong value category used in `scoped_allocator_adaptor::construct()` +* [2590](http://wg21.link/lwg2590) Aggregate initialization for `std::array` + +LWG motion 3 applies to the Library Fundamentals TS + +LWG motion 4: [P0024R2 "The Parallelism TS should be standardized"](http://wg21.link/p0024r2) + +LWG motion 5: [P0226R1 "Mathematical special functions for C++17"](http://wg21.link/p0226r1) + +LWG motion 6: [P0220R1 "Adopt library fundamentals v1 TS components for C++17"](http://wg21.link/p0220r1) **(incompletely applied, see below)** + +LWG motion 7: [P0218R1 "Adopt the file system TS for C++17"](http://wg21.link/p0218r1) + +LWG motion 8: [P0033R1 "Re-enabling `shared_from_this`"](http://wg21.link/p0033r1) + +LWG motion 9: [P0005R4 "Adopt `not_fn` from library fundamentals v2 TS for C++17"](http://wg21.link/p0005r4) + +LWG motion 10: [P0152R1 "`constexpr atomic::is_always_lock_free`"](http://wg21.link/p0152r1) + +LWG motion 11: [P0185R1 "Adding `{nothrow_}swappable` traits"](http://wg21.link/p0185r1) + +LWG motion 12: [P0253R1 "Fixing a design mistake in the searchers interface"](http://wg21.link/p0253r1) + +LWG motion 13: [P0025R0 "An algorithm to "clamp" a value between a pair of boundary values"](http://wg21.link/p0025r0) **(see below)** + +LWG motion 14: [P0154R1 "`constexpr std::hardware_{constructive,destructive}_interference_size`"](http://wg21.link/p0154r1) + +LWG motion 15: [P0030R1 "Proposal to introduce a 3-argument overload to `std::hypot`"](http://wg21.link/p0030r1) + +LWG motion 16: [P0031R0 "Proposal to add `constexpr` modifiers to `reverse_iterator`, `move_iterator`, `array` and range access"](http://wg21.link/p0031r0) +and [LWG2296 "`std::addressof` should be `constexpr`"](http://wg21.link/lwg2296) + +LWG motion 17: [P0272R1 "Give `std::string` a non-const `.data()` member function"](http://wg21.link/p0272r1) + +LWG motion 18: [P0077R2 "`is_callable`, the missing *INVOKE* related trait"](http://wg21.link/p0077r2) + +Library motions added a total of 120 pages to Clause 17-30. + +### Notable changes to papers as moved + +#### CWG motion 1, issue 2017 + +Corrected normative wording suggesting that reaching the end of a constructor, +destructor, or function with cv-qualified `void` return type would result in +undefined behavior. These cases were not covered by the wording in the issue +because they are not functions with a `void` return type. + +#### CWG motion 12 (hexadecimal floating literals) + +The wording for this proposal omitted an essential update to the *pp-number* +grammar production, which is necessary to avoid a literal such as `0x1.0p+0` +being split into three tokens at the `+` character. The grammar has also been +editorially refactored to reduce duplication between hexadecimal floating +literals and hexadecimal integer literals. + +#### LWG motion 4 (parallelism TS) + +`std::sequential`, `std::par`, and `std::par_vec` were not listed in the +synopsis of any library header. They have been added to the synopsis of +``, based on the clear intent of their placement within the +wording. + +\[execpol.synopsis] was renamed to \[execpol.syn] for consistency with other +synopsis subclauses. + +\[algorithms.parallel.exec]: fixed incorrect claims that certain well-formed +constructs with defined (but undesirable or unspecified) behavior are an error, +or undefined, in examples. + +\[exception.list]: added missing synopsis for `` header. + +\[numerics.defns]: rephrased definition of *GENERALIZED_SUM* in terms of +*GENERALIZED_NONCOMMUTATIVE_SUM* to reduce redundancy. + +Contrary to the editing instructions in section 25.NaN.5 (sic), parallel +overloads of `for_each` and `for_each_n` were not added to the synopsis of +`` as they would conflict with the overloads added in section +25.2.4. + +#### LWG motion 6 (lib fundamentals TS) + +The changes to `shared_ptr` have **not** been applied, as it is unclear +exactly what changes should be made. The TS provides alternative wording +for some subsections, but some of the differences are due to changes in +the TS and some are due to changes in the working paper. Replacing the +sections in the working paper with the sections from the TS would regress +some functionality, so this portion of this motion has been returned to +LWG for a more precise specification. + +#### LWG motion 11 (`is_{nothrow_}swappable`) + +Changed new uses of `is_{nothrow_}swappable::value` to instead use +`is_{nothrow_}swappable_v`. + +#### LWG motion 13 (`clamp`) + +Note that the paper voted into, and applied to, the working draft was +[P0025R0](http://wg21.link/p0025r0), +not the most recent draft of this paper, +[P0025R1](http://wg21.link/p0025r1). +This appears to be an oversight; LWG is encouraged to prepare an issue +to apply the changes from P0025R0 to P0025R1. + +#### LWG motion 17 (non-const `std::string::data`) + +Fix Annex C change to correctly describe the change that was made. + +## Minor editorial fixes + +A log of all editorial fixes made since N4567 is below: + + commit f487d12b9834740c09bc92a8de45e9a712648089 + Author: Richard Smith + Date: Sat Mar 19 09:17:19 2016 -0700 + + Minor editorial fixes throughout the library found in review by Dawn Perchik. + + commit f45829932dcc765578acb25667451a7b398bbde5 + Author: Richard Smith + Date: Fri Mar 18 03:06:42 2016 -0700 + + [headers] Reflow header table to 4 columns. + + commit e59a2dd20a8c7badb492a18589483fbd378594c9 + Author: Richard Smith + Date: Fri Mar 18 02:57:01 2016 -0700 + + [input.output] Add to summary of this Clause. + [headers] Add to list of library headers. + + Fixes #648 + + commit 0fead0abfc147c5560b80e424d8128c1a613934b + Author: Richard Smith + Date: Fri Mar 18 02:13:16 2016 -0700 + + [fs] Remove apparent claim that FAT is the only filesystem used on + memory cards or flash cards. Even if that were true, it's not relevant + to the C++ standard. + + commit 5cb56ad5e3626f40a7d5d5962806a895cd61c4a2 + Author: Richard Smith + Date: Thu Mar 17 10:46:52 2016 -0700 + + [fs] Minor fixes: formatting, style issues, over-reaching notes. + + commit 00697914242de485ce611da25e0f482f57882ca6 + Author: Alisdair Meredith + Date: Thu Mar 17 22:44:33 2016 -0400 + + [definitions] alphasort remaining library definitions + + On more careful review, a couple more definitions were + mildly out of order. This patch properly sorts the + whole of clause 17.3 [definitions]. + + commit 2d4a73fe2aadf7bb1ba3f3c7f0b4984e80ecc2f2 + Author: Alisdair Meredith + Date: Thu Mar 17 21:17:44 2016 -0400 + + [defns.const.subexpr] Place defintition in alphabetical order + + The defintions introduced in clauses 1.3 and 17.3 are + ordered alphabetically, other than the trailing + definition for 'constant subexpression', that I am + guessing was added at a later date. This change + simply moves it into the correctly sorted place in + the sequence. + + commit d0755fad96a62af94691adf065b5864530cc611a + Author: Zhihao Yuan + Date: Thu Mar 17 20:09:02 2016 -0500 + + [dcl.init.aggr] Fix an example in extended init. + + commit 5450aabc5d3a434a4beb9d0577ddb4bc0358718a + Author: Richard Smith + Date: Thu Mar 17 09:30:23 2016 -0700 + + [func.not_fn] Use teletype font for concept name. + + commit 864d1f8107436b7d9b0d7719e2e47944f3b4b338 + Author: Richard Smith + Date: Thu Mar 17 09:14:25 2016 -0700 + + [alg.clamp] Add clamp to synopsis and reorder it before + lexicographical comparisons to match the synopsis order. + + commit 7844267fee0e7c745be0af01754a7d64bf7f7c55 + Author: Richard Smith + Date: Thu Mar 17 07:59:09 2016 -0700 + + [func.searchers.boyer_moore_horspool.creation] Fix typo + boyer_moore_searcher_horspool and manually wrap overfull hbox. + + commit f1fb15be9c46e4662d2e3af1bfe3e70d8612bf97 + Author: Richard Smith + Date: Thu Mar 17 07:20:39 2016 -0700 + + [utilities], [containers] Replace 'is_nothrow_swappable::value' with + 'is_nothrow_swappable_v' and likewise for 'is_swappable'. + + commit f44bf31c6ad300683df2b810ee46ec95f5ecab15 + Author: Alisdair Meredith + Date: Thu Mar 17 10:14:49 2016 -0400 + + [diff.cpp11.expr] Move removal of bool++ from C++14 compatibility annex to C++17 annex + + This change was clearly introduced in C++17, at the same meeting + as removing the meaning of the register keyword. I can see no + Core issue tied to this removal being resolved as a DR against + 14 or earlier. + + I have confirmed that paper p0002r1 applied this to the C++17 + annex, but was listed as a change in annex D rather than clause + 5 - the latter change seeming the consistent editorial policy + for removed Core features, so retained. + + commit 6914707917b05ad4e4e46b6eca015d1d799f651e + Author: Jonathan Wakely + Date: Wed Mar 16 15:47:27 2016 +0000 + + [fs.def.parent] Split into two definitions using \\defncontext + + commit 971cbbc8986c11bceba95e5bfec1547651888cc0 + Author: Jonathan Wakely + Date: Thu Mar 17 13:46:00 2016 +0000 + + [filesystems] Adjust table layout and references + + commit e9e443ad270f5b4c16c525dbeff7dd1ed4fdf7f0 + Author: Thomas Köppe + Date: Thu Mar 17 13:29:12 2016 +0000 + + [dcl.attr] Fix wrong source encoding + + commit 63c062fbf8eb7e07016f5e0bf5f96fd460f6c01c + Author: Richard Smith + Date: Mon Mar 14 14:37:24 2016 -0700 + + [expr.prim.lambda] Add missing linebreak before new + simple-capture ::= *this + grammar production. + + commit c13d24e396a587a545bab9b5347f1bf7233b3f86 + Author: Dawn Perchik + Date: Mon Mar 14 11:23:40 2016 -0700 + + [expr.prim.lambda] Use \CppXIV instead of \Cpp14. + + commit 2fe4e865014b4eb1b10f1bf24c6ce2ad13ea0528 + Author: Ondřej Majerech + Date: Wed Apr 15 00:44:32 2015 +0200 + + [lex, dcl.decl] Use \nontermdef and \grammarterm more consistently. + + commit 1da521ef8a399f4c1d6bb30893fe18a7fcaafc84 + Author: Thomas Köppe + Date: Sat Mar 12 17:47:32 2016 +0000 + + [strings] Formatting and whitespace harmonization + + commit 924863b47bc3e5be39142126baa2ce1096a5659e + Author: cpplearner + Date: Sun Mar 13 01:31:02 2016 +0800 + + [valarray.members] add missing \end{itemdescr} and \begin{itemdescr} + + commit 332b3edda5424496542e406d8ec4d272198edad4 + Author: Thomas Köppe + Date: Tue Mar 8 13:23:35 2016 +0000 + + [utilities] Add some hyphenation hints for long inline expressions + + commit d598cb6588b550709593a14721c091cadc976d6a + Author: FrankHB + Date: Sat Mar 12 18:12:50 2016 +0800 + + Fix wrong reference + + Change for `&&` in [diff.cpp03.expr] should refer to [expr.log.and] rather than [expr.log.or]. + + commit 6139ef913c12760c15346a04aac92d01013f6509 + Author: Richard Smith + Date: Fri Mar 11 15:17:00 2016 -0800 + + Move all std::basic_string subclauses under [string.classes] in + preparation for adding a sibling clause for string_view. + + commit 69bc5713208c0a30c30913d5112ed8512e8c7e2d + Author: MikeHerrick + Date: Thu Mar 10 14:18:23 2016 -0500 + + Add missing "*" in example. + + commit 4f0b604ca12ffa960a923473b2106e973d42a18d + Author: Thomas Köppe + Date: Thu Mar 10 01:09:12 2016 +0000 + + [macros] Make \Cpp work in PDF bookmarks again + + commit 4f094359f43e7b97afbe7038e89adde78161db91 + Author: Richard Smith + Date: Wed Mar 9 17:04:09 2016 -0800 + + [lex.ppnumber] Add p+ and P+ as valid components of a pp-number token. + This edit was missed from P0245R1, but was intended and is a fundamental + part of the proposal. + + commit 9ca4d1dccf2a09261de94b99ea3c78d1cd4b1228 + Author: Richard Smith + Date: Wed Mar 9 17:02:46 2016 -0800 + + [lex.literal] Reuse hexadecimal-prefix and hexadecimal-digit-sequence to specify the form of a hexadecimal-literal. + + commit 875037be77746139e90f02da33700baf014984b3 + Author: Richard Smith + Date: Wed Mar 9 15:25:18 2016 -0800 + + [dcl.attr] Reorder [[noreturn]] after [[nodiscard]] to put attribute sections in alphabetical order. + + commit aab51a5c2e57779b55a9d7cf59521512017f4469 + Author: Jakub Wilk + Date: Wed Mar 9 16:47:38 2016 +0100 + + [temp.variadic] Fix typo "evalutes" + + commit aae5ada0b13aa9ae618ada206be1d8bbb499691b + Author: Jakub Wilk + Date: Wed Mar 9 16:45:08 2016 +0100 + + [re.alg.match] Fix typo "otherwis" + + commit 66eaea094e5b8e1d3aaf85827f75dc0f4bba1af6 + Author: Thomas Köppe + Date: Mon Mar 7 23:16:29 2016 +0000 + + [diff] Use \Cpp macro + + commit 7a33e38692f60fa5968c4d751899319b3a57fedf + Author: Thomas Köppe + Date: Sat Dec 5 17:05:01 2015 +0000 + + [macros] Change \Cpp macro to look nicer + + commit 43b65fb672406bcaaef4cd18d77b2e8846513414 + Author: Thomas Köppe + Date: Fri Mar 4 23:21:26 2016 +0000 + + [lex] Remove spurious whitespace + + commit be071acabed55cbcd88d96c6f17ba7d0c1bad158 + Author: Thomas Köppe + Date: Sat Dec 5 18:39:22 2015 +0000 + + Use textual angle brackets in body text + + commit cc003c2ba4ffb430a85823a237e6e6a3173fee0c + Author: Richard Smith + Date: Wed Mar 2 06:46:52 2016 -0800 + + [dcl.align] Remove "other than " from example that + actually works for all types, per CWG discussion. + + commit 97b037322d5bd76ca32ee4376e201261b16cb94b + Author: Dawn Perchik + Date: Tue Mar 1 17:16:51 2016 -0800 + + Unify the formatting of "Equivalent to" be consistent. + + commit d8463494a40c6d733c22ff4850db0dbe31813b43 + Author: faisal vali + Date: Sat Feb 27 11:41:31 2016 -0600 + + Delete the redundant 'update' when describing actions upon independent memory locations. The definition of 'access' includes modifying a location per 1.3.1/access. + + commit f35f6e7c5e2a46965b5dff18eb8f7ed50145f910 + Author: Jakub Wilk + Date: Thu Feb 25 13:46:46 2016 +0100 + + [futures.shared_future] Remove duplicated word "shared" + + commit cdd1377fc24d02d784d83ad83fae0f9610e8971b + Author: Jakub Wilk + Date: Thu Feb 25 13:51:10 2016 +0100 + + [conv.qual] Fix typo "desecender" + + commit 8ebbcaebe13ed8ab0545cdf54c4f46e4d7130338 + Author: Jakub Wilk + Date: Thu Feb 25 13:52:34 2016 +0100 + + [diff.class] Fix typo "choise" + + commit 66f77b68bda58169ec65a1095a68d6e483bbb6f4 + Author: Kazutoshi SATODA + Date: Sat Feb 13 20:42:56 2016 +0900 + + Uniform "ones' complement" and "two's complement" + + "one's complement" is inconsistent with the C standard. + "1's complement" and "2's complement" are also inconsistent. + + commit 4ad54d82b27e441ead663c692c65597ee8a96254 + Author: Eelis van der Weegen + Date: Wed Feb 10 22:06:15 2016 +0100 + + [gram.key] Remove unreferenced original-namespace-name nonterminal. + + commit 7838080df6f4dcb2784f432bfd5abe09391fc163 + Author: Eelis van der Weegen + Date: Wed Feb 10 22:04:55 2016 +0100 + + [gram.key] Make BNF for namespace-name the same as in [gram.dcl] and [namespace.def]. + + commit 7798b417ae3a512281e62aa779882fbaf6fbf780 + Author: Marshall Clow + Date: Tue Feb 9 14:40:52 2016 -0800 + + Swap effects of `basic_regex::operator=` and `assign` + + Currently, `basic_regex::operator=` is defined in terms of assign. This is different from what `basic_string` (and possibly others) do. + Swap the descriptions so that `assign` is now defined in terms of `operator=`. No functional change to either is intended. + + commit 820981d9b2ac715c926322f649c6ae3ba56bce08 + Author: FrankHB + Date: Sun Feb 7 00:16:37 2016 +0800 + + [unique.ptr.runtime.ctor] Fix format + + Add missing `\tcode` in [unique.ptr.runtime.ctor]/2.2. + + commit be271b03bf445565a1d8bfcdd013b394f81acb5e + Author: Marshall Clow + Date: Thu Feb 4 10:22:20 2016 -0800 + + Remove incorrect "shall" + + while looking at LWG issue #2589, I noticed that L2554 says "`match_results` shall satisfy the ...". + In general, we use "shall" to place requirements on user code, not on library code. + Change to just say "satisfies", rather than "shall satisfy" + + commit 1aa9db108aed9defea71e226399e05e1717e887f + Author: Richard Smith + Date: Mon Feb 1 14:48:04 2016 -0800 + + [temp.res] Fix self-contradiction in paragraph describing when a template + with valid specializations can be diagnosed. + + Also convert to bulleted form for clarity. + + commit a9c79d87f28c0ee53179ce46b97c23af92e67dfc + Author: Hubert Tong + Date: Fri Jan 29 12:54:41 2016 -0500 + + [terminate] Fix typo "terminate_handleri" + + commit a495f2445eaf2eb5c4c7562734fd2e346b8cbbdb + Author: morinmorin + Date: Wed Jan 27 00:45:41 2016 +0900 + + [support.types] Remove "field", which is not a defined term in C++. + + commit e69c75e23694c67b6351b75eae2627ef9dcd4e44 + Author: S. B. Tam + Date: Tue Jan 26 23:33:55 2016 +0800 + + [defns.const.subexpr] Remove superfluous words + + commit 356f765cc2ff2623d6de4855956d0abfaae5ec9a + Author: Stephan Bergmann + Date: Mon Jan 18 17:04:06 2016 +0100 + + Missing closing parenthesis + + commit b91c5766274ec1c60b5e90b1258f067bb9272b14 + Author: Aaron Ballman + Date: Thu Jan 14 10:59:48 2016 -0500 + + Adding a note about what a member subobject is + + commit d50dd6328c03377e382718d8dae8696ac1028af7 + Author: Aaron Ballman + Date: Mon Jan 11 15:38:15 2016 -0500 + + Making identifier label into a definition. + + commit f56239c3df9c4a3ed21b6382e1af66f2c24872e5 + Author: timsong-cpp + Date: Sat Jan 9 12:56:49 2016 -0500 + + [expr.const] adjust note + + Array bounds now use "converted constant expressions of type std::size_t", not integral constant expressions. + + commit 87ef71b8e72c5867bfb6d2f7ea59c0b459fc17fe + Author: Frank Columbo + Date: Sat Jan 9 17:24:05 2016 +0100 + + [dcl.type.cv]/6 "program behavior" vs "behavior" + + [dcl.type.cv]/6 reads + + > If an attempt is made to refer to an object defined with a volatile-qualified type through the use of a glvalue with + a non-volatile-qualified type, the program behavior is undefined. + + This is probably meant to use the much more idiomatic phrase "the behavior is undefined". A distinction between well-definedness of the program's and the implementation's behavior would presumably be inappropriate, anyway. + + commit 9c123b4655276a806d218d28107c76d5f7c9bda9 + Author: Richard Smith + Date: Wed Jan 6 11:27:10 2016 -0800 + + [stmt.label] Clarify what it means for labels to be in their own name space. + + commit 09b0265c5f194f91ae8b9a28781e13eff29c6d67 + Author: Sergey Zubkov + Date: Fri Jan 1 20:39:22 2016 -0500 + + [c.files] cinttypes synopsis refers to SCNX* macros which do not exist + + commit de0bfd210a4f6837c13a9a846219922f45b4ffe1 + Author: Thomas Köppe + Date: Mon Dec 21 20:30:56 2015 +0000 + + [macros, atomic] Align placeholders + + commit 2e0156c630f10131121b2b485b171b3c59354654 + Author: Arcoth + Date: Mon Sep 28 22:04:25 2015 +0100 + + [over.best.ics] Fix a typo in "user-defined conversion sequence" + + commit 5add43af6ed8219f156ceb5ffc0a02b6ca6cd613 + Author: Sergey Zubkov + Date: Wed Dec 16 22:49:10 2015 -0500 + + [diff.library] add missing NULL and correct counts + + commit f09023e775f4aa827efed9b7bf04c4b01f76f16b + Author: Thomas Köppe + Date: Sat Dec 19 13:45:03 2015 +0000 + + [algorithms] Improve typographic consistency of complexity expressions + + commit b1f17ea952a582dc028c27094e205c98bf48d6b2 + Author: Thomas Köppe + Date: Sat Dec 19 00:01:18 2015 +0000 + + [complex] Clarify the range of return values of log + + commit 176ac169e3a9637bd8a029ac4b5afe6df3f963f6 + Author: Thomas Köppe + Date: Fri Dec 18 23:59:06 2015 +0000 + + [complex.numbers] Make whitespace and capitalization more consistent + + commit 1810a1c177f57893c078ab506a283dc64a6e6a7b + Author: Thomas Köppe + Date: Fri Dec 18 21:10:08 2015 +0000 + + [alg.transform] Relayout list of requirements as itemization + + commit 98ffdab9bcb02757b5dd3cdaa3be78fe31bde8fc + Author: Thomas Köppe + Date: Fri Dec 18 14:37:46 2015 +0000 + + [macros] Add space into \range and remove preposterous linebreaks. + + commit 0475290dfbba9bfe1df4056a9b8e4d60299fc5a2 + Author: Thomas Köppe + Date: Fri Dec 11 15:38:00 2015 +0000 + + [atomics] Remove incomplete mention of "inttypes.h" and reword table headers + + commit a7d10e342fe482e84c0379881842de8b0b136fbf + Author: K-ballo + Date: Sat Nov 21 21:59:33 2015 -0300 + + [futures.async] Use code font for "std::async" + + commit ab47599ef9fbcb3682de414be55315c1c6be5a92 + Author: Stephan Bergmann + Date: Thu Aug 21 15:16:07 2014 +0200 + + Typographic fixes, spacing after \opt + + * occurrences of "\opt \terminal{" apparently always require "\opt{}" to not eat + the intervening space (despite the \xspace in the definition of \opt) + + * cleaned up two occurrences of "\opt\ " (in + + noptr-abstract-pack-declarator \terminal{[} constant-expression\opt\ \terminal{]} attribute-specifier-seq\opt\br + + in declarators.tex and grammar.tex) to consistenly use "\opt{}" instead + + * cleaned up two occurrences of "\opt{}" (in + + pp-tokens\opt{} new-line + + in grammar.tex and preprocessor.tex) that did not need the "{}" + + commit 4926f71c3749dacf3a6ee3b6d34cfc110e66c48b + Author: Thomas Köppe + Date: Fri Dec 11 11:20:56 2015 +0000 + + [lib-intro, utilities] Apply \placeholder macro + + commit 63305182f3c7efba1dbcaf35d1799e2fc95611b4 + Author: Thomas Köppe + Date: Fri Dec 11 10:37:01 2015 +0000 + + [iterators, locales] Apply \placeholder macro + + commit 79d9ef81fce6ac8c6288a442a7f3a806111cd239 + Author: Richard Smith + Date: Tue Dec 8 14:30:52 2015 -0800 + + [basic.link] Reword sentence to make it more obvious how it's supposed + to be parsed. + + commit 439e6dd8689cf87b1f69622bdf85595d715e6740 + Author: Thomas Köppe + Date: Sat Dec 5 13:16:11 2015 +0000 + + [utilities] Whitespace fixes around punctuators + + commit f370968913b102a864b8e884d9dad7d7ad698ee4 + Author: Thomas Köppe + Date: Sat Dec 5 13:43:15 2015 +0000 + + [diagnostics] Whitespace fixes around punctuators + + commit 45a0bac65d40819ac7b8c776035871790545d21a + Author: Thomas Köppe + Date: Sat Dec 5 13:40:00 2015 +0000 + + [containers] Whitespace fixes around punctuators + + commit 985442177aeff5266ca61c00251b1817241e3df1 + Author: Thomas Köppe + Date: Fri Aug 1 22:11:23 2014 +0100 + + [localization] Change bold-slanted font to simple italics. This removes + LaTeX "missing font" warning and is also perfectly sufficient to mark + "variable code". Apply consistently to a second use case, too. + + commit f52687ef470178f0499b575b01eaf407a5d579bd + Author: timsong-cpp + Date: Fri Dec 4 23:33:15 2015 -0500 + + [func.wrap.func.con] Fix error in note + + This note should be talking about the callable object being wrapped, i.e., f, rather than its "target", which makes no sense for arbitrary callable objects. This seems to be a copy/paste error from the very similar note in the copy constructor's description a few paragraphs above. + + commit 9ff5696dcdaa08ff5a45a09674d72798c77beb36 + Author: Richard Smith + Date: Fri Dec 4 18:39:47 2015 -0800 + + [class.inhctor.init] Fix typo in example. + + commit 1a8c2e9664479485f6a007d112f3e3a2582af259 + Author: Richard Smith + Date: Fri Dec 4 18:18:44 2015 -0800 + + [class.inhctor.init] Add missing closing paren from P0136R1. + + commit 4839a73c30a2647e09094c0a513a5ccb9d715046 + Author: Richard Smith + Date: Fri Dec 4 18:01:40 2015 -0800 + + [containers] Fix whitespace issues in container overviews. + + Replace '> >' with '>>' in template parameter lists. + Fix horizontal alignment issues after /implementation defined/ types. + Make horizontal alignment within "types" sections consistent across all + the container types. + + commit ee12083756d86a993993b9fce4554bde6250048d + Author: Richard Smith + Date: Fri Dec 4 16:53:34 2015 -0800 + + [stmt.ranged] Repeat grammar snippet to clarify what we mean by a + "range-based for statement", and improve formatting to match that of + [stmt.for]. + + Also add some missing italics for grammar terms in [stmt.for]. + + commit 1d77bb33667df24eeff26cf09b94840e7daadbce + Author: Thomas Köppe + Date: Tue Apr 14 17:06:15 2015 +0100 + + [containers] Make intra-synopsis comments consistent + + commit 348289cab8b6b915b74097349cebe502b44941d4 + Author: Jonathan Wakely + Date: Wed Nov 25 20:25:59 2015 +0000 + + [propagation] use code font for exception_ptr + + commit 6db40e3d34384a12af641ffb969ebe369977e0cf + Author: Richard Smith + Date: Mon Nov 23 17:16:26 2015 -0800 + + [replacement.functions] Remove reference to sized nothrow operator + delete functions, which were removed by LWG2458. + + commit fddf2bf31c36a037cb309966996779c026f5cd68 + Author: Richard Smith + Date: Mon Nov 23 17:07:01 2015 -0800 + + Fix alignment issues involving /see below/ and /implementation-defined/ + placeholders in library text. + + commit 5ca060ccacdcf956dca0827df6e71a84a34a05a7 + Author: Richard Smith + Date: Mon Nov 23 16:24:41 2015 -0800 + + Fix horizontal alignment around /unspecified/ placeholders in the library. + + This adds the \itcorr command which can be used to insert spacing + corresponding to the width of the italic correction for the current + font (and \itcorr[-1] which can be used to remove said spacing). + + commit 6ff1290d603e56e18e452c490feeaa5f525f68b0 + Author: Thomas Köppe + Date: Mon Nov 23 20:54:13 2015 +0000 + + [xref] Update xrefs following 7bcdb21 and 3449445 + + commit 34494450b68ba9e2cb3dc8650fc2cf27277faef4 + Author: Thomas Köppe + Date: Fri Nov 20 21:02:06 2015 +0000 + + [diagnostics] Turn synopses into numbered sections + + commit 7bcdb21bb22d62c61cd45fc811e141981bf39d37 + Author: Thomas Köppe + Date: Fri Nov 20 20:40:16 2015 +0000 + + [support] Turn synopses into numbered sections + + commit 36c13aa344d35ddfcf9410f92dcfcf0051cf95dc + Author: Thomas Köppe + Date: Fri Nov 20 12:20:16 2015 +0000 + + [library] Fix index entry + + commit f76be1182f5fb5aeaef1ea92de65e2109d0230e7 + Author: Eelis van der Weegen + Date: Thu Nov 19 21:18:54 2015 +0100 + + [except.ctor] Remove broken and unnecessary index entry. + + commit be24c457b2f6bdf0bd709cbdf082ca648619f4de + Author: Eelis van der Weegen + Date: Sun May 10 18:32:55 2015 +0200 + + [time.clock.system] Remove periods from impldef index entries. + + commit 325f7dbd48b688120e6ee06e395831cca9b54a5e + Author: Eelis van der Weegen + Date: Sun Apr 19 23:39:13 2015 +0200 + + [defns.blocked] Use correct character for index subentry. + + commit e0d53e979ce2c45350f94a25a8a8a4d9819a7714 + Author: Eelis van der Weegen + Date: Sun Apr 19 22:19:22 2015 +0200 + + [dcl.ref] Move an index entry closer to what it indexes. + + commit aa8c0b3cbf097c40d1667c20888411325ec967e9 + Author: Eelis van der Weegen + Date: Sun Apr 19 21:57:33 2015 +0200 + + [over.over] Make index entry for overloaded function consistent with the one in [expr.unary.op]. + + commit a4b28063a1f9ed5f0e65fc1ff22fd76280cfd707 + Author: Eelis van der Weegen + Date: Sun Apr 19 21:24:31 2015 +0200 + + [gram, gram.key, lex.ppnumber] Use \indextext instead of \index. + + commit e525c60ebaf2e54d19642614372cdc7ce768e606 + Author: Eelis van der Weegen + Date: Sun Apr 19 12:12:43 2015 +0200 + + [intro] Fix index entry that uses !see instead of |see. + + commit d557517f82a30cb0aa991f99f12d09b75742551d + Author: Thomas Köppe + Date: Thu Nov 19 18:42:44 2015 +0000 + + [locale.id] Add missing \tcode + + commit 45201e86de1f68c2ddb84b1dc90d961e97a9195f + Author: Jonathan Wakely + Date: Thu Nov 19 13:34:06 2015 +0000 + + [rand.adapt.general] apply ref fix from LWG 2181 + + commit 54a256349e104cbaffe7bc3f1e41b3dd75837444 + Author: Jonathan Wakely + Date: Thu Nov 19 11:25:28 2015 +0000 + + [headers] Add to Table 14. + + Also update total number of headers and add [diff.cpp11.library]. + + commit 3e355a55199d77949fa2010f867d6afa3764c7ba + Author: Jonathan Wakely + Date: Thu Nov 19 11:10:24 2015 +0000 + + [time.point.cast] replaces braces with parentheses + + Fixes #562. + + commit faf6ce008124ccaeaf8f77d31f3fb72bd2fcafdd + Author: Jonathan Wakely + Date: Thu Nov 19 11:00:06 2015 +0000 + + [memory.syn] add default argument to owner_less + + Also change class-key to 'struct' to match later definition. + + commit 27d6d806169ed7b4b0c12c760c78879b8f95290c + Author: timsong-cpp + Date: Fri Oct 23 02:49:09 2015 -0400 + + [fstream.members] Fix "returns returns". + + commit 4d69bcb2f0c8fea313fdc653c01e2f736525b976 + Author: Jonathan Wakely + Date: Wed Nov 18 11:29:44 2015 +0000 + + [allocator.requirements], [res.on.arguments] qualify std::move + + commit a82e553e2be894227523f57692b6f44358f92cd9 + Author: Thomas Köppe + Date: Wed Nov 18 01:17:46 2015 +0000 + + [utility] Make spelling of 'cv void' more consistent + + commit 6ee833203b85e4d8f5c5d89b9ba47cf8689ff3fb + Author: Thomas Köppe + Date: Wed Nov 18 01:17:07 2015 +0000 + + [class] Clarify 'cv-void class members' + + commit 35267c4c08272f3c618c8e9106b811af09c2734d + Author: Jonathan Wakely + Date: Sun Nov 15 11:55:25 2015 +0000 + + [sequences.general] Promote header synopses to rSec2 + + commit 20e643f0402d7b4900604343a2a8c3f36a26c2f8 + Author: Jonathan Wakely + Date: Sun Nov 15 11:32:17 2015 +0000 + + [stack.syn] Move synopsis after synopsis + + commit bcef6cb3c5321f88ec12d5a342c40bc2f56a7b8f + Author: Thomas Köppe + Date: Sat May 9 23:59:23 2015 -0500 + + [dcl.init.ref] Replace normative note with actual note. + + commit 837fc82bba927a1c3427c83fa99851a78570f345 + Author: Richard Smith + Date: Fri Nov 13 14:04:03 2015 -0800 + + Turn off ligature formation in \texttt. In a couple of places, we were + rendering << or >> as guillemets. + + commit 4c21b190c7201486d70699261521fc6c78054f8e + Author: Richard Smith + Date: Fri Nov 13 13:53:05 2015 -0800 + + Use microtype package; this allows us to word wrap less often. + + commit a764b26ebddd3571a78b7b117156ebe27d84245d + Author: Richard Smith + Date: Fri Nov 13 11:55:28 2015 -0800 + + [util.smartptr.ownerless] Italicize "unspecified". + + commit 70c3b9f3a950022cd4531decbff8fbd29b4a208c + Author: Richard Smith + Date: Fri Nov 13 11:55:04 2015 -0800 + + Remove unwanted spaces after /unspecified/ in library synopses. + + commit 6e6edc1f620ab0e17102556cb65819c572ae655f + Author: Mitsuru Kariya + Date: Thu Sep 17 12:33:48 2015 +0900 + + Refine "Index of library names" for operator<< and operator>> + + commit f4efabd91987982442d36e26e0003d752850d6a2 + Author: Stephan Bergmann + Date: Tue Jul 14 11:26:38 2015 +0200 + + Local definition of "char-like type" from Clause 21 referenced in Clause 28 + + ...so drop "In this Clause" from the definition in [strings.general] and add a + reference to the first use in [re.general]. + + See + "Local definition of "char-like type" from Clause 21 referenced in Clause 28" + for a discussion of this (presumably editorial) issue. + + commit 5f62a33f50c8d3fd736d552d41b860189cdb5ba7 + Author: Zhihao Yuan + Date: Thu May 7 16:05:37 2015 -0500 + + No qualified std::fclose call + + commit 2fe773b9dfe80f3ac5349e7040d352e9d9cf8b26 + Author: Thomas Köppe + Date: Tue Apr 14 17:06:15 2015 +0100 + + [containers] Minor whitespace and ordering improvements + + commit 4779c8ac3dcd91ee4387969f863a5f40b587c0fb + Author: Jonathan Wakely + Date: Wed Apr 1 17:47:37 2015 +0100 + + Update Table 121. Rename [fstreams]. Move [fstreams]/2. + + commit 98ca118b5a91e81d63f4e782f1e4c657137c692c + Author: Jonathan Wakely + Date: Tue Sep 23 10:11:38 2014 +0100 + + [file.streams] Change sub-clauses to rSec2, similar to [string.streams] + + Promote [c.files] to rSec1. + + commit f41da80744bd5da13cc9dc19fc0d572889a78b63 + Author: cpplearner + Date: Sun Oct 12 17:04:50 2014 +0800 + + [diff.expr] replace "declare" with "define" + + It is always legal in C++ to declare new types in a sizeof expression or cast expression, but you can't *define* a new type in an expression. + + commit 93838cd1d5a673efb313783971a94b73112d1b06 + Author: Kazutoshi SATODA + Date: Sat Aug 2 17:18:46 2014 +0900 + + Uniform notation of distance(first, last) to (last - first) + + As allowed in 25.1 [algorithms.general] p12, to express the same things + as same. diff --git a/papers/n4593.html b/papers/n4593.html new file mode 100644 index 0000000000..00608a3528 --- /dev/null +++ b/papers/n4593.html @@ -0,0 +1,1009 @@ +n4593 +

N4593 Editor's Report -- Working Draft, Standard for Programming Language C++

+ +

2016-05-30
+Richard Smith
+Google Inc
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

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

+ +

New papers

+ +
    +
  • N4594 is the current working draft. It replaces N4582.
  • +
  • N4593 is this Editor's Report for the current working draft.
  • +
+ +

Motions incorporated into working draft

+ +

This revision contains only editorial changes relative to N4582.

+ +

Notable editorial changes since N4582

+ +
    +
  • Rearranged subclause hierarchy of [class] to nest topics related to class members under [class.mem]; significant editorial rewording of [class.mem].
  • +
  • Added subclauses of [expr.prim] for the different topics covered therein.
  • +
  • Reordered subclauses of [utilities]: [intseq] moved earlier so it is grouped with the other components of <utility>
  • +
  • Systematic cleanup of formatting of Effects: paragraphs.
  • +
  • Reinstated missing fix for CWG908.
  • +
  • Updated uses of type traits, replacing foo<T>::type with foo_t<T> and foo<T>::value with foo_v<T>.
  • +
+ +

Minor editorial fixes

+ +

A log of all editorial fixes made since N4582 is below:

+ +
commit ab81f6044bebb78b10af5adead693ab61f993564
+Author: Marshall Clow <marshall@idio.com>
+Date:   Mon May 30 16:04:10 2016 -0700
+
+    [allocator.requirements] Fix other incorrect variable names in Table 28 (#732)
+
+commit 761e32e13be05e5615e103b93ca3744d23348e42
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Tue May 31 07:03:00 2016 +0800
+
+    [util.smartptr.enab] make p6 appear in its own line (#728)
+
+    Currently p6 appears in the same line as p5.
+
+commit 93bd500d72ca9a2246e9650c8bd4dafa1a3bfd06
+Author: Faisal Vali <faisalv@yahoo.com>
+Date:   Mon May 30 17:59:06 2016 -0500
+
+    [class.virtual] This seems like it should be a note: it is the only standardese that mentions dynamic binding and object-oriented programming (#725)
+
+commit e7ed06f377de8a6290e9b5fe372d1ed4018adb2d
+Author: Faisal Vali <faisalv@yahoo.com>
+Date:   Mon May 30 17:58:31 2016 -0500
+
+    [class.abstract] The intro para seems like it should be a note - nothing seems prescriptive about it. (#724)
+
+commit d0fbc8b31a740a9206e9fa030aff5a7962e15fc3
+Author: Faisal Vali <faisalv@yahoo.com>
+Date:   Mon May 30 17:57:44 2016 -0500
+
+    [class.member.lookup] 'overloading resolution' sounds odd - every other reference to the process uses 'overload resolution' (#723)
+
+commit 4e86203d582991750be400a2e64da0ccedd6d08f
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon May 30 18:56:58 2016 -0400
+
+    [ext.manip] fix typo in put_money description (#717)
+
+    There's no way `os << put_money(...)` could be a formatted *input* function; presumably a formatted *output* function is meant. Also add cross reference to [ostream.formatted.reqmts].
+
+commit d4c4a314a3037c2d7b21565ecd0bc96de988ac52
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon May 30 18:39:13 2016 -0400
+
+    [algorithms] [numeric.ops] Crossref "writable" (#706)
+
+    Add cross-references to [iterator.requirements.general] for "writable"
+    for [alg.replace], [alg.fill], [alg.partitions], [partial.sum] and
+    [adjacent.difference].
+
+    Fixes #697.
+
+commit 0560bab1b1fc2eb55fb5fa8f447fc6b1445b6f0c
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon May 30 18:38:19 2016 -0400
+
+    [alg.random.sample] reword and add cross-reference (#705)
+
+    MeowIterator is not a named requirement, so reworded as "shall satisfy
+    the requirements of a meow iterator", consistent with the wording in
+    [algorithms.general]/5. Added cross-references to [meow.iterators], and
+    to [iterator.requirements.general] for "writable".
+
+    Partially addresses #697 and #696.
+
+commit 8c1fef8f8f6c190f12f744c568bb1b92de70c579
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Mon May 30 18:31:53 2016 -0400
+
+    [meta.unary.prop] Consistent formatting for 'void' (#684)
+
+    * [meta.unary.prop] Consistent formatting for 'void'
+
+    Fixes #544.
+
+    Update all use of 'void' in type traits tables to use the codified
+    form \tcode{void}.  There was one use of the phrase "void types"
+    that I deliberately chose to not touch.
+
+    A second issue I stumbled over in this edit was inconsistent use
+    of cv-qualified vs. \cv-qualfied.  The latter seemed preferable,
+    so I applied that formatting consistently through this file for
+    all uses of cv-qualified that were not otherwise participating
+    in mark-up.
+
+    * Fix formatting of cv-qualifiers
+
+commit 89f6b37254b74ac5781d50f092d5163ee5a226fa
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon May 30 23:28:29 2016 +0100
+
+    Improve consistency of complexity descriptions (#636)
+
+    * [algorithms] Improve consistency of complexity descriptions
+
+    * [containers] Improve consistency of complexity descriptions
+
+commit e8acf77a28388f3e4caaad979a1f79d7ac8c78c8
+Author: Kazutoshi SATODA <k_satoda@f2.dion.ne.jp>
+Date:   Tue May 31 07:26:17 2016 +0900
+
+    [diff.cpp11] Supply a compatibility note for CWG1560 (#530)
+
+commit b1879656aa540c6249e658af7a33108a63c4f961
+Author: Marshall Clow <marshall@idio.com>
+Date:   Fri May 27 12:01:23 2016 -0700
+
+    [allocator.requirements] Fix incorrect variable references (#727)
+
+    Two move operations for the allocators refer to `a` or `a1`, though the code uses `u`.  Fix the description to match the code.
+    Also, change the phrase "equals" to "is equal to", which matches other uses in the standard (see [unique.ptr]/4.1 for an example).
+
+commit 118e6d9510c5030cc7214ae63de7838108bb42e6
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 11 18:30:40 2016 +0100
+
+    [directory_iterator.members] [rec.dir.itr.members] fix "skip_permissions_denied"
+
+commit f7cbf1b60470ca1fc7d3efa92c0224c707213cf9
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sun May 1 14:29:36 2016 -0400
+
+    deque should not reference vector
+
+    Deque introduces itself in terms of vector, to describe the idea of
+    random access iterators.  This is perhaps more confusing that simply
+    directing the reader to the clause for random access iterators.  For
+    C++17 we introduce the category of contiguous iterators for vector,
+    array, and string, and we do not want to confuse the reader into bad
+    assumptions.  Meanwhile, the notion of iterators is much more widely
+    understood than in 1998, so pointing directly to the appropriate
+    clause is more likely to help the reader than a potentially misleading analogy.
+
+commit 6251fa16f6dcf4f95f7eaf0df75793a08db30d6a
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Thu Apr 28 20:00:25 2016 -0500
+
+    Remove the semicolon in "Returns: expr;" (#718)
+
+commit dd19e2ef4964f15b209322e32b792ef2c3429837
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Apr 28 17:41:35 2016 -0700
+
+    Revert "[memory.polymorphic.allocator] Coding style fixes (and minor rewording of p8)"
+
+    This reverts commit 2d900093b196229acbda984d254b141bc98f6adc.
+
+    That commit removed fixes for formatting issues that resulted in text
+    overflowing the right margin of the page (and in some cases overflowing
+    the page entirely).
+
+commit 40363dba5923e1b41c06877931362fc3e05e4b96
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Apr 28 17:28:39 2016 -0700
+
+    [expr.delete] Clarify how an "otherwise" binds and remove a redundant cross-reference.
+
+commit 4b1e2e02dd73fec42d5b25fbf274095957133430
+Author: Geoff Romer <gromer@google.com>
+Date:   Tue Apr 26 15:26:08 2016 -0700
+
+    [fs.op.permissions] Clean up apparent stray HTML formatting
+
+commit ebebd8d2dffe5432334aaa4b2cd72930a6e816da
+Author: Hubert Tong <hstong@ca.ibm.com>
+Date:   Mon Apr 18 22:44:03 2016 -0400
+
+    Add name "high" to locale::narrow in [category.ctype]
+
+    In [locale.ctype.members], the returns clause for locale::narrow refers
+    to "high". For correct binding, the corresponding parameter should be
+    named as such.
+
+commit 6c3c605365daa66476ff687c840d74b15e49cf03
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sun Apr 17 16:27:27 2016 -0400
+
+    [meta.rel] Fix for for INVOKE in table 54
+
+    Fix the font for the use of INVOKE in the two new additions
+    to table 54, is_callable and is_nothrow_callable.  Considered
+    adding a new \invoke command and applying that consistently,
+    but decided I am not a LaTeX hacker yet, and took the easy
+    way out.
+
+commit 3137a4cd43807559136b0c725a72abdd70edf7ff
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Apr 15 19:51:27 2016 -0700
+
+    Fix definition and uses of "value initialize*"/"value-initialize*" (#708)
+
+    Fixes #708.
+
+commit 3d05daec1068246d2a55812c0c14204d067f2417
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Apr 15 19:39:29 2016 -0700
+
+    Un-\term "allocation function" and "deallocation function" (#707)
+
+    Fixes #707.
+
+commit 196a629c1eae78eaaacab483d6cdfe945f9b7962
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Apr 15 18:49:06 2016 -0700
+
+    Minor edits to library discovered while fixing \effects clauses
+
+    * fix punctuation in \returns
+    * add missing \tcodes
+    * break long lines
+
+commit 4d548679bc5550714c5afb04030627cab9f36968
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Apr 15 18:39:20 2016 -0700
+
+    Use "As if by" in \effects which lack a code introduction (#694 part 2)
+
+    Fixes #694.
+
+commit b98ba7337b53392d2bd5561559cc1b0b4d62695d
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Apr 15 16:51:08 2016 -0700
+
+    Fix \effects throughout the library (#694 part 1)
+
+    Fixes include:
+    * insert ':' before codeblocks (#694)
+    * fix punctuation and capitalization
+    * turn long \tcode'd code into codeblocks
+    * fix inconsistencies
+    * other minor edits in \effects clauses noticed while scanning thru source
+
+    Fixes #694.
+
+commit e138cdd1ccdea98e5367e6c43ea7907d432f518a
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Apr 15 13:26:08 2016 -0700
+
+    [input.output] Fix coding style of iostreams to match rest of library
+
+commit 2400aa57386c7adf2215f5674b51d51a6485f9d7
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 18:50:49 2016 -0700
+
+    [allocator.requirements] Fix missing colon for "u" in Table 27 (#195)
+
+    Fixes #195.
+
+commit 19f19981e808a9f6fb7c96c35cb8d5c1bf53629f
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 18:47:04 2016 -0700
+
+    [re.results] Add missing reference (#201)
+
+    Fixes #201.
+
+commit 8e98a59012743cd32fcdaf2183e772a0bc223144
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 18:38:24 2016 -0700
+
+    [thread.lock.unique.cons] Fix tense of "own" (#204)
+
+    Fixes #204.
+
+commit 3d4cd42bac33862b949d0fa68620c5b8fcc00374
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 18:34:37 2016 -0700
+
+    [temp.deduct.type] Add missing "of" (#217)
+
+    Fixes #217.
+
+commit 7067dbba9d3fed9a357de5590b1aba286b95ee07
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 18:28:13 2016 -0700
+
+    Un-grammarterm "parameter-type-list" (#213)
+
+    Fixes #213.
+
+commit 150cd4eac8feb0394256e393b7df205078fff15a
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 18:17:40 2016 -0700
+
+    [algorithms.general] Fix indenting of shuffle (#233)
+
+    Fixes #233.
+
+commit 006d596c631212226229c4a326e356b367b1b08a
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 18:05:28 2016 -0700
+
+    [temp.deduct.type] Fix template deduction example (#241)
+
+    Fixes #241.
+
+commit 341a474adb085a9c7a201ad0b628ed80b889bce4
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 17:27:09 2016 -0700
+
+    Hyphenate "default initializ*" (#337)
+
+    Fixes #337.
+
+commit 4714def6bef384788cff2da555060c4ecd5dfcc6
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 17:18:49 2016 -0700
+
+    [time.duration.nonmember] Fix missing \tcode in \returns (#406)
+
+    Fixes #406.
+
+commit e76648fba7bb44de8656848cbcf1279e0618729c
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 17:08:46 2016 -0700
+
+    [basic.start.dynamic, temp.inst] Don't hyphenate "side-effects"
+
+    Fixes #475.
+
+commit c2be17ea9b55fc46cef5732375a9218fdd82ee79
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 17:03:14 2016 -0700
+
+    [unique.ptr.single.ctor, tuple.elem] Add "a" before "non-reference type"
+
+    Fixes #460.
+
+commit 6d0e110ae5b0cf9fcc073091a28850551ecf30d5
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 16:24:23 2016 -0700
+
+    [memory.polymorphic.allocator.class] Fix cross-reference to [memory.polymorphic.allocator.ctor]
+
+commit a05bcde4a0de9ef92bef94dc13d25efcd9bb4e87
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 16:19:29 2016 -0700
+
+    [memory.polymorphic.allocator.mem] Fix wording "construct an object X at p"
+
+commit db237d65285f176d794bb0434d42133c708d7f45
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 15:19:19 2016 -0700
+
+    [memory.resource.prot] Clarify that "it" is the dynamic_cast expression in the note in p7
+
+    Fixes #695.
+
+commit 71627c6ee935cde503891bdfe4a5d4ccd598ccc2
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 14:59:13 2016 -0700
+
+    [memory] Split up monolithic Latex lines for readability
+
+commit 2d900093b196229acbda984d254b141bc98f6adc
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 13:53:23 2016 -0700
+
+    [memory.polymorphic.allocator] Coding style fixes (and minor rewording of p8)
+
+commit 84acafc98008c32b9b70a67b9bc8a220a0ac4939
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 12:49:07 2016 -0700
+
+    [memory.polymorphic.allocator] Add references and add/fix comments in synopsis (#699)
+
+    Fixes #699.
+
+commit 35423415cc532c8053e64696c85bc291962bedd7
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 11:10:32 2016 -0700
+
+    [class.directory_entry] Rename m_path to pathobject for consistency
+
+commit 5e49026b0383feae8f6e21dd95871eeeea733e41
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 14 11:01:32 2016 -0700
+
+    [memory] Rename m_resource to memory_rsrc for consistency
+
+commit 3f72ecddae95fd2a2f485019da16e02c928aef2f
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 13 22:09:28 2016 -0700
+
+    [memory.polymorphic.allocator.mem] Fix wording of "constructing a std::pair<T1,T2> object at p"
+
+commit f88ca1d56ad40e57357cb5b88daf53d2d4ad5e34
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 13 21:47:54 2016 -0700
+
+    [memory.polymorphic.allocator] Move description in synopsis to function details as a note.
+
+commit 9b189835ce28223ff18f3d24437a931497f09388
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 13 17:36:23 2016 -0700
+
+    [sf.cmath] Reference parameters in Returns clauses by adding "where $n$ is |n|".
+
+commit e5e95300c796f056ba9d9f5284b3b4e2e530cf45
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 13 17:12:50 2016 -0700
+
+    [sf.cmath] Reformat clauses to be more consistent with the rest of the library.
+
+commit ad9ada121cff0d82c0f5aa3b764b905952699dbe
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 13 17:00:54 2016 -0700
+
+    [sf.cmath] Replace "Returns: The X functions return" with "Returns:" for consistency.
+
+commit 08b872a9c9f38ebf172322874765ed499b3df6c2
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 13 15:53:22 2016 -0700
+
+    [string::find, string::rfind] Change "obtain:" to "hold:" for consistency.
+
+commit 7f9d7f759df375a916e312cb41f194397c7754c9
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 13 15:49:30 2016 -0700
+
+    Editorial fixes to 2016-02 LWG Motion 6, P0220R1 (except section 7)
+
+commit e5723da0ae260544b6800eddb8f9ee151f5754c1
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 13 14:20:01 2016 -0700
+
+    [temp.deduct.partial, temp.class.spec.match] Italicise "at least as specialized" and add indexes to 'more specialized'.
+
+    Fixes #318.
+
+commit 1f1e67cc7409d5229d4c2463603a990b85d5e5da
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Wed Apr 13 18:07:59 2016 +0800
+
+    [tuple.cnstr] fix the position of \end{itemdescr}
+
+commit 5e3b57dc2b3b8862b47c61aea114611a178ede90
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Tue Apr 12 20:47:10 2016 -0700
+
+    [dcl.fct.def.delete] CWG908 Deleted global allocation and deallocation functions
+
+    Reapplied CWG908 which went missing from the spec.  Fixes #908.
+
+commit 65368d8cb23125382e7c32ec5e98ef5bf1959332
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Tue Apr 12 21:30:59 2016 -0400
+
+    [tuple.helper] prefer to use tuple_element_t (#686)
+
+    Prefer to use the _t alias to the old trait::type formulation
+    when specifying the place-holder name for defining
+    tuple_element of a cv-qualified type.  This neatly sidesteps
+    the question of whether there is a missing typename in the
+    subsequent usage, or whether that would be implied in the
+    use of the place-holder.
+
+commit 882ea1e02ee0331ee4c29ab7d170e40c22f02818
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Tue Apr 12 21:30:18 2016 -0400
+
+    [unique.ptr.special] prefer use of common_type_t (#685)
+
+    The preferred style since C++14 is to use the _t alias
+    rather than the trait::type formulation for transformation
+    traits.  As a second fix, the types in the common_type
+    instantiation are, in turn, dependant types so require a
+    leading typename keyword.  I double-checked elsewhere and
+    we are consistent to use typename where requrired inside
+    other expressions, even though it is frequently omitted
+    when the named type is used within the surrounding
+    English text.
+
+commit ba934a1680408460197f3051e6e8cb90bf4807fa
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Tue Apr 12 21:24:19 2016 -0400
+
+    [intseq] consolidate <utility> docs (#682)
+
+    This change consolidates some of the sprawl occurring in clause 20,
+    by moving the integer sequence utilities, which are part of the <utility>
+    header, adjacent to the rest of the <utility> documentation, between
+    the main <utility> doc and pair, while retaining the pair doc as a
+    separate subsection adjacent to <tuple>.
+
+    Considered making the integer sequences a subsection nested in 2.2,
+    but decided that it must have been pulled out into its own separate
+    sub-clause for a reason.
+
+commit 920b2702a8ad5456d86945ed6a8690390bcf4de8
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Tue Apr 12 21:21:25 2016 -0400
+
+    [meta.unary.prop] add missing \ in is_swappable. (#681)
+
+commit a2e4bc75e7e0ce13d900d81d1ef823bc74788496
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Apr 12 15:04:51 2016 -0700
+
+    [dcl.ambig.res] Combine example into the paragraph that it's an example
+    of, to parallel the other paragraphs in this subclause.
+
+commit 94d61601737fef05d03b66ed4b07145817948acb
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Apr 12 14:58:12 2016 -0700
+
+    [dcl.ambig.res] Avoid suggesting "disambiguation" that changes the
+    meaning of the program. Remove redundant sentence that obscures the
+    meaning of the type-id versus function-style cast disambiguation rule.
+    Remove example that actually contains no ambiguity, and merge and
+    slightly extend remaining examples.
+
+commit 0586a06705d7ba332771f47cb98ab09ea36988a1
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Apr 7 17:32:50 2016 -0700
+
+    [string.view] Revert a few editorial changes made to Effects clauses.
+
+commit a07e7b28e414959208a302851c93070e070b3964
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Apr 6 17:14:41 2016 -0700
+
+    [index] Use case-insensitive sorting for index entries __cplusplus and
+    __has_include relative to other __BLAH__ index entries.
+
+commit eae7daa089306263adfc8edd127ca34f89d41818
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Apr 6 16:53:25 2016 -0700
+
+    [index] Fix some bad collation and confusing index entries.
+
+    Fixes #677, fixes #678.
+
+commit 6193ae3c50b0bfb0c87248f646a8c89f216fb9b9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Apr 6 14:43:23 2016 -0700
+
+    [expr.prim] Update cross-references after splitting of [expr.prim].
+
+commit 6acc681752d7ea1d84809a057293f29e5355f86f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Apr 4 16:09:21 2016 -0700
+
+    [expr.prim] Add hierarchical structure to this subclause.
+
+commit e9f86cb475b8f154deaee4fb6dce7f5860d50333
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Apr 4 13:44:48 2016 -0700
+
+    [intro.execution] Add missing paragraph number.
+
+commit 43470c82ca13a067274a0f592e81f3ffa2fb7f94
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Mar 29 13:20:32 2016 -0700
+
+    [namespace.def] Remove content-free introductory sentence.
+
+commit 04798c768c124dfed38056137e3fc67a9b9a8ba8
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Mar 29 13:10:35 2016 -0700
+
+    [class.mem] Move sibling subclauses describing class members into [class.mem].
+
+commit 53b83358b9549ab8c9af386fdd5ce33e7a22c0e9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Mar 29 12:32:54 2016 -0700
+
+    [class.mem] Clarify that member templates and their specializations are
+    in fact class members, that static_assert declarations are valid within
+    classes despite not introducing member names, and that alias-declarations
+    can be used to introduce nested types. Give complete definitions for
+    these terms:
+
+      data member, member function, static member, static member function,
+      static data member, non-static member, non-static dat amember,
+      non-static member function
+
+commit 4d1ede227c6105ea420ea3c72649ab5ce977ff1d
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 6 16:22:26 2016 -0700
+
+    Editorial fixes to 2016-02 LWG Motion 6, P0220R1: string_view (section 7)
+
+commit bc54ae08d34baf3ae1cff792a7934b9a1a815c75
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 6 16:17:04 2016 -0700
+
+    [optional.object.swap] Clarify wording in throws clause from "P0220R1: optional (section 5)"
+
+commit 68024dc30a6167a909e8b3d9715d7ca6ba64373b
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 6 15:50:47 2016 -0700
+
+    [util.smartptr.shared] Fix coding style in example.
+
+commit a98f587f740832f76492ef4fc4298d2c241c4362
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Apr 6 15:12:27 2016 -0700
+
+    [fs.op.equivalent, fs.op.is_empty] Add \pnum after \begin{itemdescr}.
+
+commit b5b160293358fb7d85d5c123b74c004436debd8e
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Tue Apr 5 16:25:48 2016 -0700
+
+    [sf.cmath] Rename section names to be consistent.
+
+commit bdc58da8212536f8ba7a865f17663a600da690e2
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Tue Apr 5 15:34:22 2016 -0700
+
+    [sf.cmath] Fix bulleted lists.
+
+commit a33789a5b77f990d6f1ab419a0f0a7b0cf02c888
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Tue Apr 5 11:33:53 2016 -0700
+
+    [func.searchers] Use bullets to clarify wording when two iterators are returned.
+
+commit 3e4a7320116d341199bbc8b6da1b9f062d3663b6
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Apr 5 13:18:16 2016 +0100
+
+    [new.delete.array] Add \brk to overlong lines
+
+commit dcfdd5ccba47bf8b663420c55eadfd3ddc60eebe
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Apr 5 13:16:00 2016 +0100
+
+    [allocator.requirements] Add \brk in table cell
+
+commit 4b8a9975a36e13675dd0c2e882d5809dd78fc8ba
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Apr 5 11:06:47 2016 +0100
+
+    [ifstream.members], [ofstream.members], [fstream.members] Place \ref consistently
+
+commit 6619d83b8cb4badcf14982f61aa25aa7a3589b19
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Apr 5 10:47:06 2016 +0100
+
+    [fs.op.file_size] Add parentheses around reference
+
+commit 6513551002967d7844c0050ecd39a68339afced2
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 31 11:14:41 2016 +0100
+
+    [path.op.absolute] Add cross-reference to [fs.def.absolute.path].
+
+commit e3c65c85d858e76a517671a05e102d23fe395bcb
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 31 11:13:51 2016 +0100
+
+    [path.op.funcs] Add cross-reference to [fs.def.race].
+
+commit 4ecda2996fc40c32bdba829b5bccdea19a1d6df8
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 31 11:03:43 2016 +0100
+
+    [path.native.obs] Add cross-reference to [fs.def.native].
+
+commit 5d086beb992d6ba9fb1537752381295c17d7578a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 31 10:57:35 2016 +0100
+
+    [path.construct], [path.assign], [path.append], [path.concat] Change references to [path.cvt].
+
+commit afae63cb0536ab2f74dc0f5fb1f78ec8d36ae195
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 31 10:39:23 2016 +0100
+
+    [filesystems] Fix references to [fs.err.report].
+
+commit 8f8f90bbc0c6607998d80f2ca0951b040ec5e160
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Mon Apr 4 16:14:17 2016 -0700
+
+    [move.iterator],[unique.ptr.special] Use "Let ... denote" instead of "Let ... be" for consistency.
+
+    Patch from webrown.cpp@gmail.com.
+
+commit 67dd2ad74b14b78ceca34d44f22dca7ceb4787b2
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Mon Apr 4 16:56:28 2016 -0700
+
+    [unique.ptr.special] Move ',' outside of \tcode{}.
+
+commit eb6d427e325f4ddb19280da10ebb387ba8498575
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Mon Apr 4 16:53:07 2016 -0700
+
+    Use \placeholder{} for some placeholders variables used in library code.
+
+    Patch from webrown.cpp@gmail.com.
+
+commit 510ccf3d7e6f5d3a4b24391982789d59c18533c5
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Mon Apr 4 16:16:50 2016 -0700
+
+    [tuple.helper] Add missing pnum before remarks clause.
+
+    Patch from webrown.cpp@gmail.com.
+
+commit be071c84245573e44ed833eb928e048e4b3a8d67
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Mon Apr 4 15:31:47 2016 -0700
+
+    Consistently employ _t/_v suffixes when mentioning any type trait's resulting type/value.
+
+    Additional fixes for #221.
+    Patch from webrown.cpp@gmail.com.
+
+commit d73bc8590380dc7b9153a6810cafd4ccd1aeae1e
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Mon Apr 4 14:16:20 2016 -0700
+
+    [fs.definitions] Fix capitalization in note.
+
+commit b2e75616611648378bb2a444371b5eaca0dea324
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Mon Apr 4 13:31:26 2016 -0700
+
+    Editorial fixes to 2016-02 LWG Motion 7, P0218r1
+
+commit b4b1df0a2618e78b4b8682bbdd5c8798564d7595
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sat Apr 2 21:33:04 2016 +0200
+
+    [string.view, alg.random.sample, numerics] Use \bigoh.
+
+commit 38dff8d7226f82cd959d3944b8440d4c434cb3cb
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Wed Mar 30 19:25:43 2016 +0200
+
+    [sf.cmath] Use \indextext and \indexlibrary instead of \index.
+
+commit 0b1e789cc76be4fbbad81f41bbc60651908c19ad
+Author: Aaron Ballman <aaron@aaronballman.com>
+Date:   Tue Mar 29 12:27:10 2016 -0400
+
+    [cpp.replace] Remove a bogus grammar term that make object-like and function-like appear to be definitions when they are not.
+
+commit 57b661f537e5530ad989b5b64a14b91684e81ede
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Mar 30 21:30:18 2016 +0100
+
+    [numerics] Use simpler table for header content
+
+commit 0212b785871620b4971c4645c8a9539ad789ba33
+Author: JF Bastien <jfb@chromium.org>
+Date:   Mon Mar 28 10:59:51 2016 -0700
+
+    Move index text
+
+commit d5d0a7ebfd39f5e359b59214de530b1a755897bb
+Author: JF Bastien <jfb@chromium.org>
+Date:   Mon Mar 28 10:54:48 2016 -0700
+
+    Index entries for [hardware.interference]
+
+commit 703d892264af814a64140b17ffe2bf6ae9274dde
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 24 12:26:57 2016 -0700
+
+    [expr.prim.lambda] Add index entry for example of *this capture.
+
+commit 53c8e9ad3622645e1b5199d68c400c1768903a31
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Thu Mar 24 12:39:34 2016 +0100
+
+    [intro.object] Refer to 'name' as a term, not a grammar term.
+
+commit 5c8435cbf3721eefc02eae58543adc73b51d889f
+Author: Aaron Ballman <aaron@aaronballman.com>
+Date:   Tue Mar 22 14:03:28 2016 -0400
+
+    [class.mfct.non-static] Remove bogus grammar term
+
+commit f7493766fdfbb7ea8b8bc616c75f2397e1ce1cac
+Author: Aaron Ballman <aaron@aaronballman.com>
+Date:   Mon Mar 21 15:18:56 2016 -0400
+
+    [class.mem, class.mfct.non-static] Convert nonstatic to non-static since the hyphenated use is the more common term.
+
+commit 2ceb76014e572abbb1637313342ad4af94cefcbb
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Wed Mar 23 13:15:05 2016 +0800
+
+    [numarray] Use "compound assignment". Fix missing title in [gslice.array.comp.assign].
+
+    Signed-off-by: FrankHB <frankhb1989@gmail.com>
+
+commit 74a404b60c34585ff9f92ef784e238dbdcc7310f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Mar 22 14:31:39 2016 -0700
+
+    Fix makegram script to produce the same output with BSD sed and GNU sed.
+
+    The commands in gramb.sed do nothing in BSD sed, but add undesirable
+    extra blank lines with GNU sed, so just remove that part of the process.
+
+commit b8c01f9f267eb931d4fb07cdfc7bd9bb83a67efe
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon Mar 21 19:00:28 2016 -0400
+
+    [inclusive.scan] Add missing template parameter.
+
+    The `T init` overload for `inclusive_scan` is missing a template parameter `class T`. Also fixed the `<numeric>` synopsis in [numeric.ops.overview].
+
+commit 4d3cc5cc701a7ca3b07cc051d2ac629e10427205
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Mar 21 22:45:13 2016 +0000
+
+    [algorithms] Use \Cpp macro
+
+commit 9a7d2ce161de7bf7bf39c6bbfd5ba331ca02edb8
+Author: Mitsuru Kariya <kariya_mitsuru@hotmail.com>
+Date:   Tue Mar 22 01:42:31 2016 +0900
+
+    [expr.prim.lambda] Replace EM-SPACE(U+2003) with space(U+0020)
+
+commit 549a6117a842861ff976139ecc0f97823301fe8c
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Tue Mar 22 00:38:24 2016 +0800
+
+    [class.conv.fct] add \tcode{} around `*`
+
+commit 0d1fb8353c72ce3d139fd743a114e90d4ac05a88
+Author: Kevin M. Godby <kevin@godby.org>
+Date:   Tue Apr 14 10:40:31 2015 -0500
+
+    Replaced \note with \remark and \notes with \remarks.
+
+commit 78bcd5a97b39cd4c22a5eae9f62d2f96d5af33ad
+Author: Aaron Ballman <aaron@aaronballman.com>
+Date:   Mon Mar 21 10:27:25 2016 -0400
+
+    [expr.new] Terminate a parenthetical
+
+commit b75f6aeb2ed18b710484a0a4336b37ec2605cb48
+Author: Frank Columbo <columbo@gmx-topmail.de>
+Date:   Tue Jan 19 00:22:53 2016 +0000
+
+    Make the entirety of [class.static.data]/5 a note
+
+    .. and change the index reference of restrictions on local static data members accordingly.
+
diff --git a/papers/n4593.md b/papers/n4593.md new file mode 100644 index 0000000000..8aab563d87 --- /dev/null +++ b/papers/n4593.md @@ -0,0 +1,881 @@ +# N4593 Editor's Report -- Working Draft, Standard for Programming Language C++ + +2016-05-30 +Richard Smith +Google Inc +`` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and those who have provided pull requests with fixes. + +## New papers + + * [N4594](http://wg21.link/n4594) is the current working draft. It replaces [N4582](http://wg21.link/n4582). + * N4593 is this Editor's Report for the current working draft. + +### Motions incorporated into working draft + +This revision contains only editorial changes relative to N4582. + +### Notable editorial changes since N4582 + + * Rearranged subclause hierarchy of [class] to nest topics related to class members under [class.mem]; significant editorial rewording of [class.mem]. + * Added subclauses of [expr.prim] for the different topics covered therein. + * Reordered subclauses of [utilities]: [intseq] moved earlier so it is grouped with the other components of `` + * Systematic cleanup of formatting of *Effects:* paragraphs. + * Reinstated missing fix for CWG908. + * Updated uses of type traits, replacing `foo::type` with `foo_t` and `foo::value` with `foo_v`. + +## Minor editorial fixes + +A log of all editorial fixes made since N4582 is below: + + commit ab81f6044bebb78b10af5adead693ab61f993564 + Author: Marshall Clow + Date: Mon May 30 16:04:10 2016 -0700 + + [allocator.requirements] Fix other incorrect variable names in Table 28 (#732) + + commit 761e32e13be05e5615e103b93ca3744d23348e42 + Author: S. B. Tam + Date: Tue May 31 07:03:00 2016 +0800 + + [util.smartptr.enab] make p6 appear in its own line (#728) + + Currently p6 appears in the same line as p5. + + commit 93bd500d72ca9a2246e9650c8bd4dafa1a3bfd06 + Author: Faisal Vali + Date: Mon May 30 17:59:06 2016 -0500 + + [class.virtual] This seems like it should be a note: it is the only standardese that mentions dynamic binding and object-oriented programming (#725) + + commit e7ed06f377de8a6290e9b5fe372d1ed4018adb2d + Author: Faisal Vali + Date: Mon May 30 17:58:31 2016 -0500 + + [class.abstract] The intro para seems like it should be a note - nothing seems prescriptive about it. (#724) + + commit d0fbc8b31a740a9206e9fa030aff5a7962e15fc3 + Author: Faisal Vali + Date: Mon May 30 17:57:44 2016 -0500 + + [class.member.lookup] 'overloading resolution' sounds odd - every other reference to the process uses 'overload resolution' (#723) + + commit 4e86203d582991750be400a2e64da0ccedd6d08f + Author: timsong-cpp + Date: Mon May 30 18:56:58 2016 -0400 + + [ext.manip] fix typo in put_money description (#717) + + There's no way `os << put_money(...)` could be a formatted *input* function; presumably a formatted *output* function is meant. Also add cross reference to [ostream.formatted.reqmts]. + + commit d4c4a314a3037c2d7b21565ecd0bc96de988ac52 + Author: timsong-cpp + Date: Mon May 30 18:39:13 2016 -0400 + + [algorithms] [numeric.ops] Crossref "writable" (#706) + + Add cross-references to [iterator.requirements.general] for "writable" + for [alg.replace], [alg.fill], [alg.partitions], [partial.sum] and + [adjacent.difference]. + + Fixes #697. + + commit 0560bab1b1fc2eb55fb5fa8f447fc6b1445b6f0c + Author: timsong-cpp + Date: Mon May 30 18:38:19 2016 -0400 + + [alg.random.sample] reword and add cross-reference (#705) + + MeowIterator is not a named requirement, so reworded as "shall satisfy + the requirements of a meow iterator", consistent with the wording in + [algorithms.general]/5. Added cross-references to [meow.iterators], and + to [iterator.requirements.general] for "writable". + + Partially addresses #697 and #696. + + commit 8c1fef8f8f6c190f12f744c568bb1b92de70c579 + Author: Alisdair Meredith + Date: Mon May 30 18:31:53 2016 -0400 + + [meta.unary.prop] Consistent formatting for 'void' (#684) + + * [meta.unary.prop] Consistent formatting for 'void' + + Fixes #544. + + Update all use of 'void' in type traits tables to use the codified + form \tcode{void}. There was one use of the phrase "void types" + that I deliberately chose to not touch. + + A second issue I stumbled over in this edit was inconsistent use + of cv-qualified vs. \cv-qualfied. The latter seemed preferable, + so I applied that formatting consistently through this file for + all uses of cv-qualified that were not otherwise participating + in mark-up. + + * Fix formatting of cv-qualifiers + + commit 89f6b37254b74ac5781d50f092d5163ee5a226fa + Author: Thomas Köppe + Date: Mon May 30 23:28:29 2016 +0100 + + Improve consistency of complexity descriptions (#636) + + * [algorithms] Improve consistency of complexity descriptions + + * [containers] Improve consistency of complexity descriptions + + commit e8acf77a28388f3e4caaad979a1f79d7ac8c78c8 + Author: Kazutoshi SATODA + Date: Tue May 31 07:26:17 2016 +0900 + + [diff.cpp11] Supply a compatibility note for CWG1560 (#530) + + commit b1879656aa540c6249e658af7a33108a63c4f961 + Author: Marshall Clow + Date: Fri May 27 12:01:23 2016 -0700 + + [allocator.requirements] Fix incorrect variable references (#727) + + Two move operations for the allocators refer to `a` or `a1`, though the code uses `u`. Fix the description to match the code. + Also, change the phrase "equals" to "is equal to", which matches other uses in the standard (see [unique.ptr]/4.1 for an example). + + commit 118e6d9510c5030cc7214ae63de7838108bb42e6 + Author: Jonathan Wakely + Date: Wed May 11 18:30:40 2016 +0100 + + [directory_iterator.members] [rec.dir.itr.members] fix "skip_permissions_denied" + + commit f7cbf1b60470ca1fc7d3efa92c0224c707213cf9 + Author: Alisdair Meredith + Date: Sun May 1 14:29:36 2016 -0400 + + deque should not reference vector + + Deque introduces itself in terms of vector, to describe the idea of + random access iterators. This is perhaps more confusing that simply + directing the reader to the clause for random access iterators. For + C++17 we introduce the category of contiguous iterators for vector, + array, and string, and we do not want to confuse the reader into bad + assumptions. Meanwhile, the notion of iterators is much more widely + understood than in 1998, so pointing directly to the appropriate + clause is more likely to help the reader than a potentially misleading analogy. + + commit 6251fa16f6dcf4f95f7eaf0df75793a08db30d6a + Author: S. B. Tam + Date: Thu Apr 28 20:00:25 2016 -0500 + + Remove the semicolon in "Returns: expr;" (#718) + + commit dd19e2ef4964f15b209322e32b792ef2c3429837 + Author: Richard Smith + Date: Thu Apr 28 17:41:35 2016 -0700 + + Revert "[memory.polymorphic.allocator] Coding style fixes (and minor rewording of p8)" + + This reverts commit 2d900093b196229acbda984d254b141bc98f6adc. + + That commit removed fixes for formatting issues that resulted in text + overflowing the right margin of the page (and in some cases overflowing + the page entirely). + + commit 40363dba5923e1b41c06877931362fc3e05e4b96 + Author: Richard Smith + Date: Thu Apr 28 17:28:39 2016 -0700 + + [expr.delete] Clarify how an "otherwise" binds and remove a redundant cross-reference. + + commit 4b1e2e02dd73fec42d5b25fbf274095957133430 + Author: Geoff Romer + Date: Tue Apr 26 15:26:08 2016 -0700 + + [fs.op.permissions] Clean up apparent stray HTML formatting + + commit ebebd8d2dffe5432334aaa4b2cd72930a6e816da + Author: Hubert Tong + Date: Mon Apr 18 22:44:03 2016 -0400 + + Add name "high" to locale::narrow in [category.ctype] + + In [locale.ctype.members], the returns clause for locale::narrow refers + to "high". For correct binding, the corresponding parameter should be + named as such. + + commit 6c3c605365daa66476ff687c840d74b15e49cf03 + Author: Alisdair Meredith + Date: Sun Apr 17 16:27:27 2016 -0400 + + [meta.rel] Fix for for INVOKE in table 54 + + Fix the font for the use of INVOKE in the two new additions + to table 54, is_callable and is_nothrow_callable. Considered + adding a new \invoke command and applying that consistently, + but decided I am not a LaTeX hacker yet, and took the easy + way out. + + commit 3137a4cd43807559136b0c725a72abdd70edf7ff + Author: Dawn Perchik + Date: Fri Apr 15 19:51:27 2016 -0700 + + Fix definition and uses of "value initialize*"/"value-initialize*" (#708) + + Fixes #708. + + commit 3d05daec1068246d2a55812c0c14204d067f2417 + Author: Dawn Perchik + Date: Fri Apr 15 19:39:29 2016 -0700 + + Un-\term "allocation function" and "deallocation function" (#707) + + Fixes #707. + + commit 196a629c1eae78eaaacab483d6cdfe945f9b7962 + Author: Dawn Perchik + Date: Fri Apr 15 18:49:06 2016 -0700 + + Minor edits to library discovered while fixing \effects clauses + + * fix punctuation in \returns + * add missing \tcodes + * break long lines + + commit 4d548679bc5550714c5afb04030627cab9f36968 + Author: Dawn Perchik + Date: Fri Apr 15 18:39:20 2016 -0700 + + Use "As if by" in \effects which lack a code introduction (#694 part 2) + + Fixes #694. + + commit b98ba7337b53392d2bd5561559cc1b0b4d62695d + Author: Dawn Perchik + Date: Fri Apr 15 16:51:08 2016 -0700 + + Fix \effects throughout the library (#694 part 1) + + Fixes include: + * insert ':' before codeblocks (#694) + * fix punctuation and capitalization + * turn long \tcode'd code into codeblocks + * fix inconsistencies + * other minor edits in \effects clauses noticed while scanning thru source + + Fixes #694. + + commit e138cdd1ccdea98e5367e6c43ea7907d432f518a + Author: Dawn Perchik + Date: Fri Apr 15 13:26:08 2016 -0700 + + [input.output] Fix coding style of iostreams to match rest of library + + commit 2400aa57386c7adf2215f5674b51d51a6485f9d7 + Author: Dawn Perchik + Date: Thu Apr 14 18:50:49 2016 -0700 + + [allocator.requirements] Fix missing colon for "u" in Table 27 (#195) + + Fixes #195. + + commit 19f19981e808a9f6fb7c96c35cb8d5c1bf53629f + Author: Dawn Perchik + Date: Thu Apr 14 18:47:04 2016 -0700 + + [re.results] Add missing reference (#201) + + Fixes #201. + + commit 8e98a59012743cd32fcdaf2183e772a0bc223144 + Author: Dawn Perchik + Date: Thu Apr 14 18:38:24 2016 -0700 + + [thread.lock.unique.cons] Fix tense of "own" (#204) + + Fixes #204. + + commit 3d4cd42bac33862b949d0fa68620c5b8fcc00374 + Author: Dawn Perchik + Date: Thu Apr 14 18:34:37 2016 -0700 + + [temp.deduct.type] Add missing "of" (#217) + + Fixes #217. + + commit 7067dbba9d3fed9a357de5590b1aba286b95ee07 + Author: Dawn Perchik + Date: Thu Apr 14 18:28:13 2016 -0700 + + Un-grammarterm "parameter-type-list" (#213) + + Fixes #213. + + commit 150cd4eac8feb0394256e393b7df205078fff15a + Author: Dawn Perchik + Date: Thu Apr 14 18:17:40 2016 -0700 + + [algorithms.general] Fix indenting of shuffle (#233) + + Fixes #233. + + commit 006d596c631212226229c4a326e356b367b1b08a + Author: Dawn Perchik + Date: Thu Apr 14 18:05:28 2016 -0700 + + [temp.deduct.type] Fix template deduction example (#241) + + Fixes #241. + + commit 341a474adb085a9c7a201ad0b628ed80b889bce4 + Author: Dawn Perchik + Date: Thu Apr 14 17:27:09 2016 -0700 + + Hyphenate "default initializ*" (#337) + + Fixes #337. + + commit 4714def6bef384788cff2da555060c4ecd5dfcc6 + Author: Dawn Perchik + Date: Thu Apr 14 17:18:49 2016 -0700 + + [time.duration.nonmember] Fix missing \tcode in \returns (#406) + + Fixes #406. + + commit e76648fba7bb44de8656848cbcf1279e0618729c + Author: Dawn Perchik + Date: Thu Apr 14 17:08:46 2016 -0700 + + [basic.start.dynamic, temp.inst] Don't hyphenate "side-effects" + + Fixes #475. + + commit c2be17ea9b55fc46cef5732375a9218fdd82ee79 + Author: Dawn Perchik + Date: Thu Apr 14 17:03:14 2016 -0700 + + [unique.ptr.single.ctor, tuple.elem] Add "a" before "non-reference type" + + Fixes #460. + + commit 6d0e110ae5b0cf9fcc073091a28850551ecf30d5 + Author: Dawn Perchik + Date: Thu Apr 14 16:24:23 2016 -0700 + + [memory.polymorphic.allocator.class] Fix cross-reference to [memory.polymorphic.allocator.ctor] + + commit a05bcde4a0de9ef92bef94dc13d25efcd9bb4e87 + Author: Dawn Perchik + Date: Thu Apr 14 16:19:29 2016 -0700 + + [memory.polymorphic.allocator.mem] Fix wording "construct an object X at p" + + commit db237d65285f176d794bb0434d42133c708d7f45 + Author: Dawn Perchik + Date: Thu Apr 14 15:19:19 2016 -0700 + + [memory.resource.prot] Clarify that "it" is the dynamic_cast expression in the note in p7 + + Fixes #695. + + commit 71627c6ee935cde503891bdfe4a5d4ccd598ccc2 + Author: Dawn Perchik + Date: Thu Apr 14 14:59:13 2016 -0700 + + [memory] Split up monolithic Latex lines for readability + + commit 2d900093b196229acbda984d254b141bc98f6adc + Author: Dawn Perchik + Date: Thu Apr 14 13:53:23 2016 -0700 + + [memory.polymorphic.allocator] Coding style fixes (and minor rewording of p8) + + commit 84acafc98008c32b9b70a67b9bc8a220a0ac4939 + Author: Dawn Perchik + Date: Thu Apr 14 12:49:07 2016 -0700 + + [memory.polymorphic.allocator] Add references and add/fix comments in synopsis (#699) + + Fixes #699. + + commit 35423415cc532c8053e64696c85bc291962bedd7 + Author: Dawn Perchik + Date: Thu Apr 14 11:10:32 2016 -0700 + + [class.directory_entry] Rename m_path to pathobject for consistency + + commit 5e49026b0383feae8f6e21dd95871eeeea733e41 + Author: Dawn Perchik + Date: Thu Apr 14 11:01:32 2016 -0700 + + [memory] Rename m_resource to memory_rsrc for consistency + + commit 3f72ecddae95fd2a2f485019da16e02c928aef2f + Author: Dawn Perchik + Date: Wed Apr 13 22:09:28 2016 -0700 + + [memory.polymorphic.allocator.mem] Fix wording of "constructing a std::pair object at p" + + commit f88ca1d56ad40e57357cb5b88daf53d2d4ad5e34 + Author: Dawn Perchik + Date: Wed Apr 13 21:47:54 2016 -0700 + + [memory.polymorphic.allocator] Move description in synopsis to function details as a note. + + commit 9b189835ce28223ff18f3d24437a931497f09388 + Author: Dawn Perchik + Date: Wed Apr 13 17:36:23 2016 -0700 + + [sf.cmath] Reference parameters in Returns clauses by adding "where $n$ is |n|". + + commit e5e95300c796f056ba9d9f5284b3b4e2e530cf45 + Author: Dawn Perchik + Date: Wed Apr 13 17:12:50 2016 -0700 + + [sf.cmath] Reformat clauses to be more consistent with the rest of the library. + + commit ad9ada121cff0d82c0f5aa3b764b905952699dbe + Author: Dawn Perchik + Date: Wed Apr 13 17:00:54 2016 -0700 + + [sf.cmath] Replace "Returns: The X functions return" with "Returns:" for consistency. + + commit 08b872a9c9f38ebf172322874765ed499b3df6c2 + Author: Dawn Perchik + Date: Wed Apr 13 15:53:22 2016 -0700 + + [string::find, string::rfind] Change "obtain:" to "hold:" for consistency. + + commit 7f9d7f759df375a916e312cb41f194397c7754c9 + Author: Dawn Perchik + Date: Wed Apr 13 15:49:30 2016 -0700 + + Editorial fixes to 2016-02 LWG Motion 6, P0220R1 (except section 7) + + commit e5723da0ae260544b6800eddb8f9ee151f5754c1 + Author: Dawn Perchik + Date: Wed Apr 13 14:20:01 2016 -0700 + + [temp.deduct.partial, temp.class.spec.match] Italicise "at least as specialized" and add indexes to 'more specialized'. + + Fixes #318. + + commit 1f1e67cc7409d5229d4c2463603a990b85d5e5da + Author: S. B. Tam + Date: Wed Apr 13 18:07:59 2016 +0800 + + [tuple.cnstr] fix the position of \end{itemdescr} + + commit 5e3b57dc2b3b8862b47c61aea114611a178ede90 + Author: Dawn Perchik + Date: Tue Apr 12 20:47:10 2016 -0700 + + [dcl.fct.def.delete] CWG908 Deleted global allocation and deallocation functions + + Reapplied CWG908 which went missing from the spec. Fixes #908. + + commit 65368d8cb23125382e7c32ec5e98ef5bf1959332 + Author: Alisdair Meredith + Date: Tue Apr 12 21:30:59 2016 -0400 + + [tuple.helper] prefer to use tuple_element_t (#686) + + Prefer to use the _t alias to the old trait::type formulation + when specifying the place-holder name for defining + tuple_element of a cv-qualified type. This neatly sidesteps + the question of whether there is a missing typename in the + subsequent usage, or whether that would be implied in the + use of the place-holder. + + commit 882ea1e02ee0331ee4c29ab7d170e40c22f02818 + Author: Alisdair Meredith + Date: Tue Apr 12 21:30:18 2016 -0400 + + [unique.ptr.special] prefer use of common_type_t (#685) + + The preferred style since C++14 is to use the _t alias + rather than the trait::type formulation for transformation + traits. As a second fix, the types in the common_type + instantiation are, in turn, dependant types so require a + leading typename keyword. I double-checked elsewhere and + we are consistent to use typename where requrired inside + other expressions, even though it is frequently omitted + when the named type is used within the surrounding + English text. + + commit ba934a1680408460197f3051e6e8cb90bf4807fa + Author: Alisdair Meredith + Date: Tue Apr 12 21:24:19 2016 -0400 + + [intseq] consolidate docs (#682) + + This change consolidates some of the sprawl occurring in clause 20, + by moving the integer sequence utilities, which are part of the + header, adjacent to the rest of the documentation, between + the main doc and pair, while retaining the pair doc as a + separate subsection adjacent to . + + Considered making the integer sequences a subsection nested in 2.2, + but decided that it must have been pulled out into its own separate + sub-clause for a reason. + + commit 920b2702a8ad5456d86945ed6a8690390bcf4de8 + Author: timsong-cpp + Date: Tue Apr 12 21:21:25 2016 -0400 + + [meta.unary.prop] add missing \ in is_swappable. (#681) + + commit a2e4bc75e7e0ce13d900d81d1ef823bc74788496 + Author: Richard Smith + Date: Tue Apr 12 15:04:51 2016 -0700 + + [dcl.ambig.res] Combine example into the paragraph that it's an example + of, to parallel the other paragraphs in this subclause. + + commit 94d61601737fef05d03b66ed4b07145817948acb + Author: Richard Smith + Date: Tue Apr 12 14:58:12 2016 -0700 + + [dcl.ambig.res] Avoid suggesting "disambiguation" that changes the + meaning of the program. Remove redundant sentence that obscures the + meaning of the type-id versus function-style cast disambiguation rule. + Remove example that actually contains no ambiguity, and merge and + slightly extend remaining examples. + + commit 0586a06705d7ba332771f47cb98ab09ea36988a1 + Author: Dawn Perchik + Date: Thu Apr 7 17:32:50 2016 -0700 + + [string.view] Revert a few editorial changes made to Effects clauses. + + commit a07e7b28e414959208a302851c93070e070b3964 + Author: Richard Smith + Date: Wed Apr 6 17:14:41 2016 -0700 + + [index] Use case-insensitive sorting for index entries __cplusplus and + __has_include relative to other __BLAH__ index entries. + + commit eae7daa089306263adfc8edd127ca34f89d41818 + Author: Richard Smith + Date: Wed Apr 6 16:53:25 2016 -0700 + + [index] Fix some bad collation and confusing index entries. + + Fixes #677, fixes #678. + + commit 6193ae3c50b0bfb0c87248f646a8c89f216fb9b9 + Author: Richard Smith + Date: Wed Apr 6 14:43:23 2016 -0700 + + [expr.prim] Update cross-references after splitting of [expr.prim]. + + commit 6acc681752d7ea1d84809a057293f29e5355f86f + Author: Richard Smith + Date: Mon Apr 4 16:09:21 2016 -0700 + + [expr.prim] Add hierarchical structure to this subclause. + + commit e9f86cb475b8f154deaee4fb6dce7f5860d50333 + Author: Richard Smith + Date: Mon Apr 4 13:44:48 2016 -0700 + + [intro.execution] Add missing paragraph number. + + commit 43470c82ca13a067274a0f592e81f3ffa2fb7f94 + Author: Richard Smith + Date: Tue Mar 29 13:20:32 2016 -0700 + + [namespace.def] Remove content-free introductory sentence. + + commit 04798c768c124dfed38056137e3fc67a9b9a8ba8 + Author: Richard Smith + Date: Tue Mar 29 13:10:35 2016 -0700 + + [class.mem] Move sibling subclauses describing class members into [class.mem]. + + commit 53b83358b9549ab8c9af386fdd5ce33e7a22c0e9 + Author: Richard Smith + Date: Tue Mar 29 12:32:54 2016 -0700 + + [class.mem] Clarify that member templates and their specializations are + in fact class members, that static_assert declarations are valid within + classes despite not introducing member names, and that alias-declarations + can be used to introduce nested types. Give complete definitions for + these terms: + + data member, member function, static member, static member function, + static data member, non-static member, non-static dat amember, + non-static member function + + commit 4d1ede227c6105ea420ea3c72649ab5ce977ff1d + Author: Dawn Perchik + Date: Wed Apr 6 16:22:26 2016 -0700 + + Editorial fixes to 2016-02 LWG Motion 6, P0220R1: string_view (section 7) + + commit bc54ae08d34baf3ae1cff792a7934b9a1a815c75 + Author: Dawn Perchik + Date: Wed Apr 6 16:17:04 2016 -0700 + + [optional.object.swap] Clarify wording in throws clause from "P0220R1: optional (section 5)" + + commit 68024dc30a6167a909e8b3d9715d7ca6ba64373b + Author: Dawn Perchik + Date: Wed Apr 6 15:50:47 2016 -0700 + + [util.smartptr.shared] Fix coding style in example. + + commit a98f587f740832f76492ef4fc4298d2c241c4362 + Author: Dawn Perchik + Date: Wed Apr 6 15:12:27 2016 -0700 + + [fs.op.equivalent, fs.op.is_empty] Add \pnum after \begin{itemdescr}. + + commit b5b160293358fb7d85d5c123b74c004436debd8e + Author: Dawn Perchik + Date: Tue Apr 5 16:25:48 2016 -0700 + + [sf.cmath] Rename section names to be consistent. + + commit bdc58da8212536f8ba7a865f17663a600da690e2 + Author: Dawn Perchik + Date: Tue Apr 5 15:34:22 2016 -0700 + + [sf.cmath] Fix bulleted lists. + + commit a33789a5b77f990d6f1ab419a0f0a7b0cf02c888 + Author: Dawn Perchik + Date: Tue Apr 5 11:33:53 2016 -0700 + + [func.searchers] Use bullets to clarify wording when two iterators are returned. + + commit 3e4a7320116d341199bbc8b6da1b9f062d3663b6 + Author: Jonathan Wakely + Date: Tue Apr 5 13:18:16 2016 +0100 + + [new.delete.array] Add \brk to overlong lines + + commit dcfdd5ccba47bf8b663420c55eadfd3ddc60eebe + Author: Jonathan Wakely + Date: Tue Apr 5 13:16:00 2016 +0100 + + [allocator.requirements] Add \brk in table cell + + commit 4b8a9975a36e13675dd0c2e882d5809dd78fc8ba + Author: Jonathan Wakely + Date: Tue Apr 5 11:06:47 2016 +0100 + + [ifstream.members], [ofstream.members], [fstream.members] Place \ref consistently + + commit 6619d83b8cb4badcf14982f61aa25aa7a3589b19 + Author: Jonathan Wakely + Date: Tue Apr 5 10:47:06 2016 +0100 + + [fs.op.file_size] Add parentheses around reference + + commit 6513551002967d7844c0050ecd39a68339afced2 + Author: Jonathan Wakely + Date: Thu Mar 31 11:14:41 2016 +0100 + + [path.op.absolute] Add cross-reference to [fs.def.absolute.path]. + + commit e3c65c85d858e76a517671a05e102d23fe395bcb + Author: Jonathan Wakely + Date: Thu Mar 31 11:13:51 2016 +0100 + + [path.op.funcs] Add cross-reference to [fs.def.race]. + + commit 4ecda2996fc40c32bdba829b5bccdea19a1d6df8 + Author: Jonathan Wakely + Date: Thu Mar 31 11:03:43 2016 +0100 + + [path.native.obs] Add cross-reference to [fs.def.native]. + + commit 5d086beb992d6ba9fb1537752381295c17d7578a + Author: Jonathan Wakely + Date: Thu Mar 31 10:57:35 2016 +0100 + + [path.construct], [path.assign], [path.append], [path.concat] Change references to [path.cvt]. + + commit afae63cb0536ab2f74dc0f5fb1f78ec8d36ae195 + Author: Jonathan Wakely + Date: Thu Mar 31 10:39:23 2016 +0100 + + [filesystems] Fix references to [fs.err.report]. + + commit 8f8f90bbc0c6607998d80f2ca0951b040ec5e160 + Author: Dawn Perchik + Date: Mon Apr 4 16:14:17 2016 -0700 + + [move.iterator],[unique.ptr.special] Use "Let ... denote" instead of "Let ... be" for consistency. + + Patch from webrown.cpp@gmail.com. + + commit 67dd2ad74b14b78ceca34d44f22dca7ceb4787b2 + Author: Dawn Perchik + Date: Mon Apr 4 16:56:28 2016 -0700 + + [unique.ptr.special] Move ',' outside of \tcode{}. + + commit eb6d427e325f4ddb19280da10ebb387ba8498575 + Author: Dawn Perchik + Date: Mon Apr 4 16:53:07 2016 -0700 + + Use \placeholder{} for some placeholders variables used in library code. + + Patch from webrown.cpp@gmail.com. + + commit 510ccf3d7e6f5d3a4b24391982789d59c18533c5 + Author: Dawn Perchik + Date: Mon Apr 4 16:16:50 2016 -0700 + + [tuple.helper] Add missing pnum before remarks clause. + + Patch from webrown.cpp@gmail.com. + + commit be071c84245573e44ed833eb928e048e4b3a8d67 + Author: Dawn Perchik + Date: Mon Apr 4 15:31:47 2016 -0700 + + Consistently employ _t/_v suffixes when mentioning any type trait's resulting type/value. + + Additional fixes for #221. + Patch from webrown.cpp@gmail.com. + + commit d73bc8590380dc7b9153a6810cafd4ccd1aeae1e + Author: Dawn Perchik + Date: Mon Apr 4 14:16:20 2016 -0700 + + [fs.definitions] Fix capitalization in note. + + commit b2e75616611648378bb2a444371b5eaca0dea324 + Author: Dawn Perchik + Date: Mon Apr 4 13:31:26 2016 -0700 + + Editorial fixes to 2016-02 LWG Motion 7, P0218r1 + + commit b4b1df0a2618e78b4b8682bbdd5c8798564d7595 + Author: Eelis van der Weegen + Date: Sat Apr 2 21:33:04 2016 +0200 + + [string.view, alg.random.sample, numerics] Use \bigoh. + + commit 38dff8d7226f82cd959d3944b8440d4c434cb3cb + Author: Eelis van der Weegen + Date: Wed Mar 30 19:25:43 2016 +0200 + + [sf.cmath] Use \indextext and \indexlibrary instead of \index. + + commit 0b1e789cc76be4fbbad81f41bbc60651908c19ad + Author: Aaron Ballman + Date: Tue Mar 29 12:27:10 2016 -0400 + + [cpp.replace] Remove a bogus grammar term that make object-like and function-like appear to be definitions when they are not. + + commit 57b661f537e5530ad989b5b64a14b91684e81ede + Author: Thomas Köppe + Date: Wed Mar 30 21:30:18 2016 +0100 + + [numerics] Use simpler table for header content + + commit 0212b785871620b4971c4645c8a9539ad789ba33 + Author: JF Bastien + Date: Mon Mar 28 10:59:51 2016 -0700 + + Move index text + + commit d5d0a7ebfd39f5e359b59214de530b1a755897bb + Author: JF Bastien + Date: Mon Mar 28 10:54:48 2016 -0700 + + Index entries for [hardware.interference] + + commit 703d892264af814a64140b17ffe2bf6ae9274dde + Author: Richard Smith + Date: Thu Mar 24 12:26:57 2016 -0700 + + [expr.prim.lambda] Add index entry for example of *this capture. + + commit 53c8e9ad3622645e1b5199d68c400c1768903a31 + Author: Eelis van der Weegen + Date: Thu Mar 24 12:39:34 2016 +0100 + + [intro.object] Refer to 'name' as a term, not a grammar term. + + commit 5c8435cbf3721eefc02eae58543adc73b51d889f + Author: Aaron Ballman + Date: Tue Mar 22 14:03:28 2016 -0400 + + [class.mfct.non-static] Remove bogus grammar term + + commit f7493766fdfbb7ea8b8bc616c75f2397e1ce1cac + Author: Aaron Ballman + Date: Mon Mar 21 15:18:56 2016 -0400 + + [class.mem, class.mfct.non-static] Convert nonstatic to non-static since the hyphenated use is the more common term. + + commit 2ceb76014e572abbb1637313342ad4af94cefcbb + Author: FrankHB + Date: Wed Mar 23 13:15:05 2016 +0800 + + [numarray] Use "compound assignment". Fix missing title in [gslice.array.comp.assign]. + + Signed-off-by: FrankHB + + commit 74a404b60c34585ff9f92ef784e238dbdcc7310f + Author: Richard Smith + Date: Tue Mar 22 14:31:39 2016 -0700 + + Fix makegram script to produce the same output with BSD sed and GNU sed. + + The commands in gramb.sed do nothing in BSD sed, but add undesirable + extra blank lines with GNU sed, so just remove that part of the process. + + commit b8c01f9f267eb931d4fb07cdfc7bd9bb83a67efe + Author: timsong-cpp + Date: Mon Mar 21 19:00:28 2016 -0400 + + [inclusive.scan] Add missing template parameter. + + The `T init` overload for `inclusive_scan` is missing a template parameter `class T`. Also fixed the `` synopsis in [numeric.ops.overview]. + + commit 4d3cc5cc701a7ca3b07cc051d2ac629e10427205 + Author: Thomas Köppe + Date: Mon Mar 21 22:45:13 2016 +0000 + + [algorithms] Use \Cpp macro + + commit 9a7d2ce161de7bf7bf39c6bbfd5ba331ca02edb8 + Author: Mitsuru Kariya + Date: Tue Mar 22 01:42:31 2016 +0900 + + [expr.prim.lambda] Replace EM-SPACE(U+2003) with space(U+0020) + + commit 549a6117a842861ff976139ecc0f97823301fe8c + Author: S. B. Tam + Date: Tue Mar 22 00:38:24 2016 +0800 + + [class.conv.fct] add \tcode{} around `*` + + commit 0d1fb8353c72ce3d139fd743a114e90d4ac05a88 + Author: Kevin M. Godby + Date: Tue Apr 14 10:40:31 2015 -0500 + + Replaced \note with \remark and \notes with \remarks. + + commit 78bcd5a97b39cd4c22a5eae9f62d2f96d5af33ad + Author: Aaron Ballman + Date: Mon Mar 21 10:27:25 2016 -0400 + + [expr.new] Terminate a parenthetical + + commit b75f6aeb2ed18b710484a0a4336b37ec2605cb48 + Author: Frank Columbo + Date: Tue Jan 19 00:22:53 2016 +0000 + + Make the entirety of [class.static.data]/5 a note + + .. and change the index reference of restrictions on local static data members accordingly. diff --git a/papers/n4594.pdf b/papers/n4594.pdf new file mode 100644 index 0000000000..4812268f1b Binary files /dev/null and b/papers/n4594.pdf differ diff --git a/papers/n4603.html b/papers/n4603.html new file mode 100644 index 0000000000..d892737189 --- /dev/null +++ b/papers/n4603.html @@ -0,0 +1,1487 @@ +N4603 +

N4603 Editor's Report -- Committee Draft, Standard for Programming Language C++

+ +

2016-07-12
+Richard Smith
+Google Inc
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Thanks to +Dawn Perchik, +Jonathan Wakely, +Thomas Köppe, and +Alisdair Meredith +for performing the edits for many of the motions applied to this draft, +and to +Kevin Godby and +Thomas Köppe +for modernizing and improving various parts of the standard draft build process.

+ +

Thanks to the editing committee for reviewing the C++17 Committee Draft. +The editing committee for the C++17 CD comprises: +Marshall Clow, +Alisdair Meredith, +Mike Miller, and +Jeffrey Yasskin.

+ +

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

+ +

New papers

+ +
    +
  • N4603 is this Editor's Report.
  • +
  • N4604 is the C++17 Committee Draft.
  • +
  • N4606 is the current working draft. It replaces N4594.
  • +
+ +

Other than their cover sheets, the content of N4604 and N4606 are identical. +Both N4604 and N4606 contain the changes listed below.

+ +

Motions incorporated into committee draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolutions for 7 issues applied:

+ +
    +
  • 1861 Values of a bit-field
  • +
  • 2022 Copy elision in constant expressions (example updated to match P0135R1)
  • +
  • 2076 List-initialization of arguments for constructor parameters
  • +
  • 2091 Deducing reference non-type template arguments
  • +
  • 2137 List-initialization from object of same type
  • +
  • 2145 Parenthesized declarator in function definition
  • +
  • 2171 Triviality of copy constructor with less-qualified parameter
  • +
+ +

CWG motion 2 applies to the Concepts TS

+ +

CWG motion 3: P0028R4 "Using attribute namespaces without repetition"

+ +

CWG motion 4: P0035R4 "Dynamic memory allocation for over-aligned data"

+ +

CWG motion 5: P0091R3 "Template argument deduction for class templates" (clause labels renamed from those in paper)

+ +

CWG motion 6: P0127R2 "Declaring non-type template parameters with auto" (clause labels renamed from those in paper)

+ +

CWG motion 7: P0135R1 "Guaranteed copy elision through simplified value categories"

+ +

CWG motion 8: P0137R1 "Replacement of class objects containing reference members"

+ +

CWG motion 9: P0145R3 "Refining expression evaluation order" and P0400R0 "Order of evaluation of function arguments"

+ +

CWG motion 10 was not approved.

+ +

CWG motion 11: P0283R2 "Standard and non-standard attributes"

+ +

CWG motion 12: P0292R2 "constexpr if"

+ +

CWG motion 13: P0296R2 "Forward progress guarantees: base definitions"

+ +

CWG motion 14: P0299R1 "Forward progress guarantees for the Parallelism TS features"

+ +

CWG motion 15: P0386R2 "inline variables" (see below)

+ +

CWG motion 16: P0391R0 "Introducing the term 'templated entity'"

+ +

CWG motion 17: P0217R3 "Structured bindings"

+ +

CWG motion 18: P0305R1 "Selection statements with initializer"

+ +

CWG motion 19: Core issue resolution from one issue applied:

+ +
    +
  • 1518 Explicit default constructors and copy-list-initialization
  • +
+ +

Core motions added a total of 10 pages to Clause 1-16.

+ +

Library working group motions

+ +

LWG motion 1: Library issue resolutions for 16 issues in "Ready" status applied:

+ +
    +
  • 2181 Exceptions from seed sequence operations
  • +
  • 2309 mutex::lock() should not throw device_or_resource_busy
  • +
  • 2310 Public exposition only member in std::array
  • +
  • 2328 Rvalue stream extraction should use perfect forwarding
  • +
  • 2393 std::function's Callable definition is broken
  • +
  • 2426 Issue about compare_exchange
  • +
  • 2436 Comparators for associative containers should always be CopyConstructible
  • +
  • 2441 Exact-width atomic typedefs should be provided
  • +
  • 2542 Missing const requirements for associative containers
  • +
  • 2549 tuple EXPLICIT constructor templates that take tuple parameters end up taking references to temporaries and will create dangling references
  • +
  • 2550 Wording of unordered container's clear() method complexity
  • +
  • 2667 path::root_directory() description is confusing
  • +
  • 2669 recursive_directory_iterator effects refers to non-existent functions
  • +
  • 2670 system_complete refers to undefined variable base
  • +
  • 2671 Errors in copy
  • +
  • 2673 status() effects cannot be implemented as specified
  • +
+ +

LWG motion 2: Library issue resolutions for 11 issues in "Tentatively Ready" status applied:

+ +
    +
  • 2596 vector::data() should use addressof
  • +
  • 2674 Bidirectional iterator requirement on path::iterator is very expensive
  • +
  • 2683 filesystem::copy() says "no effects" (see below)
  • +
  • 2684 priority_queue lacking comparator typedef
  • +
  • 2685 shared_ptr deleters must not throw on move construction
  • +
  • 2688 clamp misses preconditions and has extraneous condition on result
  • +
  • 2689 Parallel versions of std::copy and std::move shouldn't be in order
  • +
  • 2698 Effect of assign() on iterators/pointers/references
  • +
  • 2706 Error reporting for recursive_directory_iterator::pop() is under-specified
  • +
  • 2707 path construction and assignment should have string_type&& overloads
  • +
  • 2710 "Effects: Equivalent to ..." doesn't count "Synchronization:" as determined semantics
  • +
+ +

LWG motion 3 applies to the Library Fundamentals (v2) TS

+ +

LWG motion 4 applies to the Library Fundamentals (v2) TS

+ +

LWG motion 5: Library issue resolutions for 4 issues in "Immediate" status applied:

+ +
    +
  • 2687 {inclusive,exclusive}_scan misspecified
  • +
  • 2704 recursive_directory_iterator's members should require '*this is dereferenceable'
  • +
  • 2711 path is convertible from approximately everything under the sun
  • +
  • 2725 filesystem::exists(const path&, error_code&) error reporting
  • +
+ +

LWG motion 6: Library issue resolutions for 13 issues in "Immediate" status applied:

+ +
    +
  • 2312 tuple's constructor constraints need to be phrased more precisely
  • +
  • 2422 std::numeric_limits<T>::is_modulo description: "most machines" errata
  • +
  • 2709 offsetof is unnecessarily imprecise
  • +
  • 2716 Specification of shuffle and sample disallows lvalue URNGs
  • +
  • 2718 Parallelism bug in [algorithms.parallel.exec] p2
  • +
  • 2719 permissions function should not be noexcept due to narrow contract
  • +
  • 2720 permissions function incorrectly specified for symlinks
  • +
  • 2721 remove_all has incorrect post conditions
  • +
  • 2723 Do directory_iterator and recursive_directory_iterator become the end iterator upon error?
  • +
  • 2724 The protected virtual member functions of memory_resource should be private
  • +
  • 2726 [recursive_]directory_iterator::increment(error_code&) is underspecified
  • +
  • 2727 Parallel algorithms with constexpr specifier
  • +
  • 2728 status(p).permissions() and symlink_status(p).permissions() are not specified
  • +
+ +

LWG motion 7: P0063R3 "C++17 should refer to C11 instead of C99" (see below)

+ +

LWG motion 8: P0175R1 "Synopses for the C library" (see below)

+ +

LWG motion 9: P0088R3 "variant, a type-safe union for C++17"

+ +

LWG motion 10: P0307R2 "Making optional greater equal again"

+ +

LWG motion 11: P0393R3 "Making variant greater equal"

+ +

LWG motion 12: P0032R3 "Homogeneous interface for variant, any, and optional" (with normative changes, see below)

+ +

LWG motion 13: P0067R3 "Elementary string conversions" not applied, see below

+ +

LWG motion 14: P0254R2 "Integrating string_view and string"

+ +

LWG motion 15 was not approved.

+ +

LWG motion 16: P0258R2 "has_unique_object_representations"

+ +

LWG motion 17: P0040R3 "Extending memory management tools"

+ +

LWG motion 18: P0084R2 "emplace return type"

+ +

LWG motion 19: P0302R1 "Removing allocator support in std::function"

+ +

LWG motion 20: P0083R3 "Splicing sets and maps"

+ +

LWG motion 21: P0181R1 "Ordered by default" (with normative changes, see below)

+ +

LWG motion 22: P0163R0 "shared_ptr::weak_type"

+ +

LWG motion 23: P0209R2 "make_from_tuple: apply for construction"

+ +

LWG motion 24: P0295R0 "Adopt selected Library Fundamentals v2 components"

+ +

LWG motion 25: P0174R2 "Deprecating vestigial library parts"

+ +

LWG motion 26: P0337R0 "Delete operator= for polymorphic_allocator"

+ +

LWG motion 27: P0358R1 "Fixes for not_fn"

+ +

LWG motion 28: P0219R1 "Relative paths for filesystem"

+ +

LWG motion 29: P0392R0 "Adapting string_view by filesystem paths"

+ +

LWG motion 30: P0394R4 "terminate() for parallel algorithms exception handling"

+ +

LWG motion 31: P0336R1 "Better names for parallel execution policies"

+ +

LWG motion 32: P0371R1 "Temporarily discourage memory_order_consume"

+ +

LWG motion 33: P0346R1 "A <random> nomenclature tweak"

+ +

LWG motion 34: P0180R2 "Reserve a new library namespace for future standardization"

+ +

Library motions added a total of 42 pages to Clause 17-30.

+ +

Notable changes to papers as moved

+ +

CWG motion 4

+ +

Wording and paragraph ordering within [new.delete] was modified +to be consistent across all of the largely-duplicated subsections.

+ +

CWG motions 5 and 6

+ +

Some clause labels were renamed from those proposed by these papers, for +consistency with the rest of the standard, as follows:

+ +
    +
  • [dcl.auto.deduct] -> [dcl.type.auto.deduct]
  • +
  • [deduced.class.type] -> [dcl.type.class.deduct]
  • +
  • [class.template.deduction] -> [over.match.class.deduct]
  • +
  • [temp.deduction.guide] -> [temp.deduct.guide]
  • +
+ +

CWG motion 15

+ +

Added missing edit to clause 12 to avoid conflict with wording added to clause +3, which makes a static inline data member declaration a definition. The +clause 12 wording had text left over from constexpr rules that required an +initializer to be provided.

+ +

LWG motion 2, issue 2683

+ +

Proposed wording did not fit surrounding text and has been reworded.

+ +

LWG motion 7

+ +

This paper did not update the definition of "C standard" in +[intro.scope]/2 from C99 to C11. This change has also not been +made editorially, as it is unclear whether this omission is +intentional or an oversight. The paper has been applied as written, +but this issue warrants further investigation.

+ +

LWG motion 8

+ +

The purpose of this paper was to request editorial freedom to restructure the +description of the parts of the C++ standard library that were inherited from +C. To this end, the edits applied are based on those in P0175R1, but in +addition, the descriptions of many C library functions have been moved, +reordered, and reformatted into the standard format used for C++ library +description.

+ +

See the list of editorial fixes below for the full details.

+ +

LWG motion 12

+ +

Added missing updates to definition of class template optional to match +changes in detailed description.

+ +

Removed detailed description of variant's in_place_type and in_place_index +to match changes to synopsis.

+ +

The template parameters to in_place_index_t and the corresponding form of +in_place were specified as template<int> and template<size> respectively +in the wording paper, and have been editorially corrected to the intended +template<size_t>.

+ +

LWG motion 13

+ +

Proposed wording has different signatures for from_chars in the synopsis and +in the detailed wording. The paper was returned to LWG for redrafting, and +a revised wording paper has been provided by the paper author as +P0067R4.

+ +

LWG motion 21

+ +

No explicit editing instructions were provided to merge this motion with +the introduction of std::pmr from 2016-02 LWG Motion 6, +which the base document for this motion predates. +At the request of the paper author, +and based on the clear intent of both motions, +the change was also applied to the containers in namespace std::pmr.

+ +

Notable editorial changes since N4594

+ +
    +
  • As noted in LWG motion 8, descriptions of subclauses related to the portions +of the C standard library incorporated into C++ have been substantially +reorganized.

  • +
  • The index of clause labels (formerly known as Annex F) has been demoted from +an Annex to a regular index and now lists the page number in addition to the +section number for each clause.

  • +
+ +

Minor editorial fixes

+ +

A log of all editorial fixes made since N4594 is below:

+ +
commit 0f682fdcccd2c3a64d478e1e3cdcf3d8f6928bd1
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 11 18:11:57 2016 -0700
+
+    Fix review comments from Jeffrey.
+
+    [any.modifiers] The Requires: clause here was redundant, since the
+    Remarks: clause gives the same condition as a SFINAE condition.
+
+    [path.itr] Align the phrasing of the way in which path::iterator is not
+    a bidirectional iterator with the corresponding phrasing in the
+    description of the bidirectional iterator requirements.
+
+commit 8f0c572eae9b8306e5d78a86dbdebf5c353f5895
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 11 14:38:33 2016 -0700
+
+    [meta.type.synop] Italicize placeholder text "default-alignment" to
+    match formatting in detailed description.
+
+commit bd00cfb2b9f505220b6fc92f0310e56e11209e67
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 11 20:36:22 2016 +0100
+
+    [regex] Remove bogus indexlibrary entry
+
+commit d17944301f1cf53e0b5af2dcda25039bc36c3556
+Author: burblebee <dawn+github@burble.org>
+Date:   Mon Jul 11 12:35:21 2016 -0700
+
+    Make universal-character-name \grammarterm'd (#807)
+
+    Fixes #296
+
+commit 6098c7fa264ac862711616ca933611220e6cc208
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 10 23:55:31 2016 -0700
+
+    [c.math] Change title of this subclause from "C library" to
+    "Mathematical functions for floating point types" to match its contents;
+    the special math functions in <cmath> are not part of the C library.
+
+commit b882709b88e8d8f88b47036f75d99e6949e470fd
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 10 17:46:47 2016 -0700
+
+    [objects.within.classes] Clarify what "exposition only" means for
+    private members that are not data members. This applies the first
+    portion of LWG2516 (voted into Lib Fundamentals) to the working paper.
+
+commit 9c4447539b309db428186ecdfc47809d3ace96fc
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 10 17:15:49 2016 -0700
+
+    Rename [util.smartptr.weakptr] to [util.smartptr.weak.bad]. This section
+    describes the bad_weak_ptr exception class, so the previous name was
+    completely inappropriate.
+
+    Fixes #801.
+
+commit 5f9e2c145d98a7cc605993359d2e2a5437d083a5
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 10 17:03:29 2016 -0700
+
+    [fs.op.relative] Replace "Returns A except B if an error is produced"
+    with "Returns A, or B if an error is produced" to match similar wording
+    elsewhere.
+
+commit 73b8f1ab222076c4b02be47c1b7e1386247695a9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 10 16:59:29 2016 -0700
+
+    [any] Fix template parameter list of make_any to list the
+    parameter that is intended to be explicitly specified first. The
+    wording paper had inconsistent parameter orders between the synopsis and
+    the detailed wording, and this is the obvious intent.
+
+    Fixes #813.
+
+commit 186885a158863e204b45251ecced3c6938dd3c6d
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Sun Jul 10 14:42:39 2016 -0400
+
+    [func.default.traits] Remove inappropriate reference to [unord] (#819)
+
+    The *unordered* associative containers do not use default_*order*.
+
+commit aee45702ed8527b9dc74552a39c32fb6111a01c5
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sun Jul 10 17:58:14 2016 +0100
+
+    [variant.swap] Use math mode for variable "i"
+
+commit 50d074fc6ee918d9658aee57352225cf69aa5d3f
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sun Jul 10 17:50:36 2016 +0800
+
+    [filesystems] Fix unmatched parentheses around references (#814)
+
+commit d3066bfac13e674fa53f1c332f7a4e4779b24fe7
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Sun Jul 10 04:55:40 2016 +0100
+
+    [19-26] Consistent use of _v (#783)
+
+    The library clauses have started to make inconsistent use of the _v
+    variable templates for traits, in preference to directly querying
+    trait::value.  This change set applies that change consistently over
+    all existing wording, where there is a choice of which form might
+    be used.  It does not make any changes where the _v variable is not
+    available, or is being defined in terms of the corresponding ::value.
+
+commit 7e7b6c41caffc276603ba74f72d12f122a7ca098
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sat Jul 9 15:02:55 2016 +0100
+
+    [locale.codecvt.members] Add spaces between function arguments
+
+commit ab44124fa5b55cc4c445926e15f55934f881142a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 9 16:59:35 2016 +0300
+
+    [input.output,strings,utilities] Don't format informative 'see below' as code (#809)
+
+commit 16f3af8a65762aab840e878315a71d17f1dac736
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sat Jul 9 14:37:28 2016 +0100
+
+    Fix index entries for operator!=
+
+commit e50e299cd02da221151413d8332ee6bc20c53912
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sat Jul 9 14:25:23 2016 +0100
+
+    [utility] Fix declarations of in_place_index_t
+
+commit 1ed6ec00c0badef4fbcb0a6fc1d359ad4fae9a22
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jul 7 19:09:49 2016 +0100
+
+    [re.regex.construct] Use tcode instead of textit
+
+commit d51fa51a4d4063a0bd8c6137babe155990f51019
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jul 7 19:06:46 2016 +0100
+
+    [re.traits] Use tcode instead of textit
+
+commit 59a605fb57251183eabb2b1268cb85448c132052
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jul 6 18:03:05 2016 +0100
+
+    [alg.random.sample] Remove stray period.
+
+    Fixes #797
+
+commit 8ae8c1396a30ef880f3b1a5808f5e9dd5c622d21
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jul 6 18:02:42 2016 +0100
+
+    [ios.base.callback] Add missing pnum
+
+commit 7e1143cfa907a405217ba7792a4a46535b815396
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jul 6 01:15:20 2016 +0100
+
+    [re.results.form] use code font
+
+commit 322011bc53f589afdbe4267d1689fa52adf4a58f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Jul 5 15:50:24 2016 +0100
+
+    [tuple.traits] Add missing pnum
+
+commit f78c2de5b51559d89dde5f34f540ca51c1456981
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jun 30 11:12:58 2016 +0100
+
+    [meta.unary.prop.query] fix whitespace in alignment_of row
+
+commit 1329a28df4c2f7b3dbc8e84675b85334cf02e767
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Jul 9 15:07:10 2016 +0200
+
+    [variant.visit] Remove stray colon (#810)
+
+commit 4c8f1a7c4a77986a8838dbc34dc72ca24b67091d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 9 14:31:34 2016 +0300
+
+    [valarray.members] Fix up index entries for named valarray member functions (#808)
+
+    The index currently lists the named member-functions of valarray as
+    if they were free functions - this adds the corresponding entry under
+    the valarray listing in the index, alongside the existing entries for
+    the many operator functions. It also fixes the entry for "size()".
+
+commit cdedc854aa3b73b1a505a58f0c0b3837def1c9e3
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sat Jul 9 18:45:41 2016 +0800
+
+    [ratio.si] Fix typo (#779)
+
+commit 81543ed95ccdc071cf298b3a0b2d98a521e623f0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 9 13:39:37 2016 +0300
+
+    [dcl.spec.auto] Add 'The' to heading 'auto specifier' (#782)
+
+commit f90ba1e46385c97ee30c6e40ce6abcbbae0cb258
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 9 13:26:00 2016 +0300
+
+    [diagnostics] Make system_error synopsis more consistent (#795)
+
+commit 4f46b45b68973e00d732e4995f135ffe17ba0ad3
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Jul 9 05:17:55 2016 +0200
+
+    [stmt.if] Balance brackets and fix indentation in example.
+
+commit b7ee7b2216102257ccad4dea2750e9b945333954
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 9 06:14:48 2016 +0300
+
+    [cpp] Fix index text for STDCPP_DEFAULT_NEW_ALIGNMENT (#784)
+
+commit 0bc04c584447d510d4d9a58553689cd405894fa2
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 9 01:44:04 2016 +0100
+
+    [back] Install proper page marks for post-appendix backmatter
+
+commit 46343660afd101e218aa7ec77a7bc6ba618894b0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 8 23:50:52 2016 +0100
+
+    Generate xrefs as a glossary
+
+commit 48375f4eceabeff09816f9314f02d70b5a084f1f
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Jul 1 16:11:38 2016 -0700
+
+    [filesystems] Add references to fs.def.pathres where "resolve" is used.
+
+commit d91ec5fe94bb69d555940c2b0262aecd002a04be
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Jul 1 16:05:01 2016 -0700
+
+    [fs.def.normal.form] Define terms normalized and normalization.
+
+commit 4e6c8bd3547ac3fa3e5675f9dbac1c62bc8fe868
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Jun 30 16:10:11 2016 -0700
+
+    [fs.op.absolute] Fix inconsistent coding style.
+
+commit babea2e671c49bf8e1d5087fbb6964dca11431e2
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Jun 30 16:05:54 2016 -0700
+
+    [fs.op.proximate][fs.op.weakly_canonical] Rephrase nonsensical wording.
+
+commit 3d6079f4c7a51e8023d18ef599bef301d7f29878
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jun 29 00:19:17 2016 +0100
+
+    [func.default.traits] Add cross-references
+
+commit 3ee9d1f8c7f8d29fb0741e0eecfd259f473324e7
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 8 12:01:38 2016 -0700
+
+    [c.locales], [clocale.syn] Fold child clause into its parent and remove
+    paragraph that is duplicated between the two.
+
+commit 993f8138ab7c07e0d6b3ef4b4f625a0f928d9a6a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 8 12:00:37 2016 -0700
+
+    [c.strings] Point the "see" comments for functions with different
+    signatures in C and C++ to [library.c], which specifies how those
+    functions behave.
+
+commit e53963822cac2fb44d7efe3224c67a748383fbd6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jul 6 17:25:12 2016 -0700
+
+    [string.ops] Move basic_string::operator basic_string_view alongside
+    data() and c_str() rather than putting it in its own section.
+
+commit dd6cf3bf2332b389306311e22a7ad500bf7fd93f
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Fri Jul 8 00:36:09 2016 -0400
+
+    [class.union] Fix typo.
+
+    s/initialiation/initialization/.
+
+commit bbb02446b7ca948f2d84d8d18ff195f942908d9a
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Jul 6 15:50:12 2016 -0700
+
+    [meta.type.synop] Delete extra space before is_nothrow_copy_assignable
+
+commit 2318e73d26f56a058d53a0c4ad65789dcf50cff6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 16:11:20 2016 -0700
+
+    [headers] Update introductory text for the C library now that Clause 17
+    contains a C header synopsis.
+
+commit 73a0fde86eb4506474c25415d4ef2fcf9dd701d6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 16:05:48 2016 -0700
+
+    [cinttypes.syn] Explicitly mark the intmax_t forms of abs and div as
+    optional in the synopsis, to match the normative requirement.
+
+commit c448d933adad9c705c79adfc1cb7f3ea25f7c0ab
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 16:00:51 2016 -0700
+
+    [support.types.layout] Clarify that offsetof is based on the C standard
+    library macro of the same name, now that we no longer explicitly say
+    that all of <cstddef> is based on the corresponding C header.
+
+commit 7b8c69d1fe4eae4785747842fa32127685e9b0c7
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 15:51:06 2016 -0700
+
+    Replace the anachronism 'int f(void)' with 'int f()' throughout the C++
+    standard library description and in a couple of examples.
+
+commit bf0c6f4cd0ff9e10c5e637a751381205c6004b89
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 15:48:19 2016 -0700
+
+    Update declarations of NULL and size_t in C header synopses to refer to
+    the place where C++ gives them different meaning from C.
+
+commit 1a62c222522ad27e189a149f7329cce1c0c651b7
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 15:36:41 2016 -0700
+
+    [library.c] Clarify what we mean by 'restrict', since it doesn't exist
+    in C++.
+
+commit ed3c014c14b1973965567475301587d6240e8f34
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 15:35:11 2016 -0700
+
+    Add index entries for all C standard library entities.
+
+commit 8e4ab9cdee4399b475735b0cb39d70d8e1040969
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 15:16:41 2016 -0700
+
+    [c.strings] Move descriptions of individual headers to the section for
+    the respective header.
+
+commit 1f22f4264428dc65607a419594842fc68c6891ac
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 15:03:36 2016 -0700
+
+    [ctime.syn], [date.time] Delete the latter and move the former into its
+    place. We don't need two descriptions of the contents of <ctime>.
+
+commit 299f1817f14e8a186ecd1b9e12a7c1759f17a17c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 14:58:00 2016 -0700
+
+    Consistency fixes for C library header descriptions.
+
+commit 011c0228045e6cf84fb95e56eec30bda74577c7a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 14:38:43 2016 -0700
+
+    [library.c] Consolidate the rules on the behavior of functions that
+    change signature between the C standard library and the C++ standard
+    library here.
+
+commit d48b1f64507aae655c1c655ea3046083a9bbc2c6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 14:25:34 2016 -0700
+
+    [c.mb.wcs] Reorder after relevant C library synopses.
+
+commit 42d8d347f7dad4116f48a7d6f07260333d30b74c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 14:22:34 2016 -0700
+
+    Move description of <cstdlib> out of [numerics] and into [library]. This
+    is a bad home for it, but it seems to be the best bad home, as the
+    portions of <cstdlib> are described in 5 different library clauses.
+
+commit 46be71ecd68e3731b5d4943ac4c72d86ce37795f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 13:40:22 2016 -0700
+
+    Add cross-references from <cstdlib> synopsis to places where pieces of
+    it are described, and change those places to use the formatting style
+    we normally use for library entity descriptions.
+
+commit 1b56b231f892d3b8aada4fd12f427bbb32f9c22e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 12:30:09 2016 -0700
+
+    [cinttypes.syn] Add missing #include <cstdint> to synopsis.
+
+commit c44e3158fd27aa87d79d7801b4fd538da63a2c0d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 12:27:01 2016 -0700
+
+    [numerics] Integrate the special math functions into the <cmath>
+    synopsis and add proper descriptions for the parts of the C standard
+    library that we modify.
+
+commit f4a9956a3141608ca5b408ed877da26255fcf6c2
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 7 11:07:14 2016 -0700
+
+    [numerics] Remove incorrect suggestion that <tgmath.h> is specified here
+    rather than in Annex D.
+
+commit e6f109e4979ef255068eee5ed6ba99779bf8b50d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jul 6 14:35:06 2016 -0700
+
+    More replacement of "Standard C Library" with the defined term "C
+    standard library", and remove an outdated reference to the C Unicode TR.
+    <uchar.h> is now incorporated directly from C11.
+
+commit e9a9b52de953b0d224316b373423e272cb140cff
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 4 18:53:00 2016 -0700
+
+    Replace uses of the phrase "Standard C library" with the defined term
+    "C standard library" throughout the library clauses.
+
+commit 516d2712c5ab8926583b9249400d502afa8d95bf
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Jul 1 16:31:51 2016 -0700
+
+    [istream::extractors] Fix '.' inside reference.
+
+commit 8c2a29598696e7b3dac5ff2d7f20f1d970649cc4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 3 21:07:27 2016 -0700
+
+    [alg.move] Fix bad linewrapping introduced by LWG2689.
+
+commit 641a469fb9f6bcc5a817f8da3d9443751046110e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 3 20:04:16 2016 -0700
+
+    [tuple.cnstr] Fix bad line wrapping introduced by LWG issue 2549.
+
+commit f40f23d2c9b8de9eeeb781c4e7b90d056750535f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jun 28 22:27:44 2016 +0100
+
+    [stmt] Move grammar and description of 'condition' up
+
+commit b20e63d533990375c9c3b8b0a0c590b7025aca4b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 1 14:55:14 2016 -0700
+
+    [dcl.decomp] Use 'interpreted as' not 'taken as' to specify how a token
+    sequence should be parsed, for consistency with similar wording
+    elsewhere.
+
+commit de2bd84b59f79598f8bb6346c2879fc9e0b741bb
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 1 14:53:15 2016 -0700
+
+    Update cross-references to decomposition declarations to point to
+    [dcl.decomp] not [dcl.spec.auto].
+
+commit 4b95f2e3e1c0dbb19a48302ad249db4de700766d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 1 14:08:06 2016 -0700
+
+    [dcl.type.auto.deduct], [dcl.type.class.deduct] Reverse the order of
+    these two clauses so that [dcl.type.auto.deduct] is properly nested
+    within [dcl.spec.auto].
+
+commit 8daec11f020f6f84dd0e4e40d20ffb176944847a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 1 13:56:39 2016 -0700
+
+    [class.static.data] Fix inconsistency between rules for when a
+    declaration of an inline variable is a definition and remove
+    unintended implication that an inline static data member defined
+    inside a class must also be defined outside.
+
+commit 42f557b123ce1ce3dbd1c1e3c61f0f4cd72e9094
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 1 13:43:26 2016 -0700
+
+    [dcl.inline] Consistently use teletype font when referring to the inline
+    keyword and roman font when referring to the inline property of
+    functions and variables.
+
+commit 77787781dfd56343d9b7007af055a9e3886e1a73
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 1 11:53:28 2016 -0700
+
+    [algorithms.parallel.exec] As instructed by P0299R1, replace all
+    occurrences of 'thread' with 'thread of execution' throughout this
+    subclause.
+
+commit f8fc0629ce634650c176fcd23b8d15fae0a00047
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jun 30 20:08:39 2016 +0100
+
+    [dcl.spec.auto] Disambiguate which return statements are meant
+
+commit 326fc8a501a4f7ed1ddf6bb9b729dda86d95c00f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jun 28 23:46:32 2016 +0100
+
+    [temp] Add cross-reference to "templated entity"
+
+commit cdcabf2ee40c0332d6c16ae89126e4e9bb0e231f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jun 30 18:43:26 2016 -0700
+
+    [expr.call] Move specification of parameter sequencing out of the middle
+    of wording on the conversions performed on parameters and into a
+    separate paragraph. Restore note on the relative ordering of argument
+    side effects and the evaluation of the function body now that it's no
+    longer implied by the sequencing of the argument evaluations.
+    Also fix bad "smart" apostrophe in example.
+
+commit 3dc7b01f3d15aef86be33e935efc1dac10cc5e45
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jun 30 15:59:44 2016 -0700
+
+    [class.temporary] Promote footnote to note to avoid bullets in a
+    footnote, and move it to later in the clause, to a place where it fits
+    the flow of the surrounding text better.
+
+commit 4d277951eac45cdedf88d92d11652d507aba5be9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jun 30 14:52:32 2016 -0700
+
+    [dcl.init] Correct "return object" to defined term "result object".
+
+commit ce323f0b9fbae0434904e31e324d5f7c9589ffb9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jun 30 14:46:53 2016 -0700
+
+    Add missing space in 'cv void'.
+
+commit f454ecbe85381d18b89235c252a1654e8d7357e8
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jun 30 14:46:01 2016 -0700
+
+    [expr.prim.lambda] Fix description of lambda-expressions. The expression
+    itself is a prvalue, not its value.
+
+commit b7c116c427e3a5f37f374cca6c024acd2f3c16c3
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jun 30 14:45:12 2016 -0700
+
+    [expr.comma] Fix description of temporaryness of comma operator. It's
+    not meaningful to talk about a value being a temporary expression.
+
+commit 4ca5a4b5fff957feb1c93920f0f35ff9689af4ff
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jun 30 14:44:34 2016 -0700
+
+    [expr.mptr.oper] The left operand of .*, not the right, should be
+    required to be a glvalue.
+
+commit 86040aee532699152e6dded8f688a57d9662d21c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 27 16:49:28 2016 -0700
+
+    [dcl.type.auto.deduct] Remove unnecessary wording complexity from
+    handling of return type deduction from void.
+
+commit 1a0589b15b5552ea38651b3c877e8d9fcc86d5c3
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 27 15:03:40 2016 -0700
+
+    [expr.type.conv] Remove defined but unused term from class template
+    argument deduction in function-style cast.
+
+commit a4ca89a833d1af4e81d7fd3497d2ee64c2b8dbea
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jun 26 12:22:48 2016 -0700
+
+    Update all wording referring to placement new-expressions to use the
+    defined term rather than some variation of it.
+
+commit e206374d429d33e5f7178df872a73fc5d65bae69
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jun 26 12:18:57 2016 -0700
+
+    Use consistent style and order when listing predeclared, replaceable,
+    and library-supplied overloads of operator new/delete, as suggested
+    in a drafting note in P0035R4.
+
+commit 95321805a3528aa1006bf8187e39e1f4bab00c1e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jun 26 08:13:10 2016 -0700
+
+    [class.copy] Replace example of guaranteed elision in constant
+    expressions with one that is still correct when P0135R1 is applied.
+
+    I note, however, that the requirement here is impossible for an
+    implementation to meet in general; we will need to revise the resolution
+    of this core issue.
+
+commit 77fe85dc22d31d3aa9f5a9ff7ecd3f46cff40b77
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jun 29 20:06:29 2016 +0100
+
+    [associative.reqmts] use code font for q2 in Table 109
+
+commit 707d78c25e8e96133ab40d1720803115eb3592d7
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jun 29 20:00:59 2016 +0100
+
+    [unord.req] use code font for X in Table 11
+
+commit 8bff74f11d38cf8f5b2795269c414e82f5320612
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jun 23 21:13:47 2016 +0300
+
+    [strings] Replace NULL with "null pointer value"
+
+commit a15450c8cb1d13b01ead9acd30db192717848cef
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jun 23 21:13:41 2016 +0300
+
+    [iostreams] Replace NULL with "null pointer value"
+
+commit 44c5364c54f8bcefe980745fcc115410d209eec7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jun 23 22:04:22 2016 +0300
+
+    [macros,intro] Present example/note formatting better (#763)
+
+commit 268f494baf2c666d01bf49159d918c7f7a8c9fa6
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Thu Jun 23 19:05:36 2016 +0100
+
+    [temp.deduct.call] [temp.deduct.conv] Hyphenate top-level
+
+commit 5d8aa54a58b51d5c64d6b43beb6edbb3256d963d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jun 23 20:35:43 2016 +0300
+
+    [overloading] Make operators appear in code font (#764)
+
+commit 896b5132357bd9678cc73b8c29febf25bd31dc75
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Thu Jun 23 14:21:17 2016 +0100
+
+    [diff.cpp11.special] Move to [diff.cpp14.special] (#767)
+
+commit fcdd2f6a714af4812a8b65124b2e6cb28c029df7
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jun 23 12:11:10 2016 +0100
+
+    [diff.cpp03.containers] Use \effect not \effects
+
+commit d25356eced71845d70cc4cb53c515c7b69ab7740
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jun 23 10:03:13 2016 +0100
+
+    [fs.op.absolute] Fix table name
+
+commit bc0e41a4711661efe45b28a0f5bee13c622e417f
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Wed Jun 22 22:50:57 2016 +0300
+
+    [strings,containers] Add iterators to index of implemenetation defined behavior (#754)
+
+    This patch slavishly copies the tag used for array::iterator, without
+    understanding if a better markup might be available.  One consequence
+    is that we get two entries for basic_string_view::const_iterator.
+    Another is that the index around type names appears as two sorted
+    subsequences, rather than one sorted sequence.
+
+    An additional patch will follow for the remaining implementation-defined
+    types that are not present in the index, once the preferred markup is
+    reviewed in this pull request.
+
+commit 1b47dd9975c61c93897f93e8a5ea5bd1480d51a7
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Wed Jun 22 22:30:42 2016 +0300
+
+    [18-20,27] Prefer to use 'override' where appropriate (#753)
+
+    This patch makes consistent use of the 'override' contextual
+    keyword for every member function (other than destructors)
+    that overrides a virtual function in one of its base classes.
+
+    In general, this came down to one of three cases:
+    1) the 'what' function for an exception class
+    2) the allocation functions of a memory resource
+    3) the implementation methods of a stream buffer.
+
+    As far as I can tell, all other virtual function declarations
+    in the standard library are intended as customization points
+    for users, and are not overridden in the standard itself.
+
+    Fixes #751
+
+commit 24ad0836274dbb494f7d391d917aaf1e4f3844fa
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jun 22 19:45:00 2016 +0100
+
+    [iostate.flags] Remove name of exception object thrown
+
+commit 4d67e5d9437373e6bc571db74208f6cd3376d19a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jun 22 19:40:29 2016 +0100
+
+    [filesystems] Hyphenate POSIX-based and Windows-based
+
+commit ad4c80452feea841b8a2e29f5fc1e6aacfdeaa2d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jun 22 19:35:44 2016 +0100
+
+    [fs.norm.ref] Remove redundant reference to MAC OS
+
+commit 535ff921a4c61da91716c9e18d42ffb26cc53c24
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jun 22 19:19:09 2016 +0100
+
+    [meta.rel] Reformat "Type relationship predicates" table
+
+    Adjusted the column widths of the libreqtab3f environment and inserted
+    line breaks.
+
+commit 34fae9749c325302b4e659b775224cb28e3b014d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jun 22 18:50:08 2016 +0100
+
+    [meta.trans.sign] Fix formatting in "Other transformation" table
+
+commit 863cbd1add491eb3cfef66d438f5ca79e3d602f4
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Jun 9 22:40:42 2016 -0400
+
+    [meta.trans.other] Reformat Other Transformations table
+
+    This PR applies the change recommended by https://github.com/cplusplus/draft/issues/629.
+
+    So far, I like the change giving the descriptions more room to
+    breathe, but for come reason the first column has become a
+    little narrower, which is messing with the format a little.
+
+    Generally, I think this looks like a good fix, but may use a
+    little more polish to get the presentation just right.
+
+commit ed0cd287652fbe923373a5628b32f4f8cd90c7f6
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Thu Jun 23 01:17:32 2016 +0800
+
+    [reverse.iter.requirements] Avoid 'global operators' (#442)
+
+    These operator functions are not in the global namespace scope.
+
+commit ddbb859ab54614b710786cf46f569541edd2fdcd
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jun 22 20:15:34 2016 +0300
+
+    [strings] Fix spacing around commas
+
+commit a8ea14bfe285a99f69cbf3b57cd826fb3d03058a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jun 22 10:12:18 2016 -0700
+
+    [global.functions] Replace "global and non-member functions" with less
+    redundant, but no less accurate, term "non-member functions".
+
+commit 571412f6aff170a5aab1f7472526b7e9459f556b
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jun 22 16:06:11 2016 +0100
+
+    [forward.iterators] Capitalize note
+
+commit dc7918e42ddf76a5c9299775128ea9d75f960374
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jun 22 15:58:41 2016 +0100
+
+    [lex.key] Move note after table
+
+commit 28cea19640223d5aa403419813eef0be0371287f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jun 22 15:48:26 2016 +0100
+
+    Fix stray punctuation after notes.
+
+commit c68346dc2e6dcb912f162bafb9f86c12f8bb3713
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jun 17 18:27:30 2016 +0100
+
+    [utilities] Remove std:: from normative wording
+
+commit 4b58cb2262f38475f726aa52724065df537f40ec
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jun 17 18:22:09 2016 +0100
+
+    [iterators] Remove std:: from normative wording
+
+commit 5e827de13e93306778dec7a6933da16acb079e57
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jun 17 18:22:04 2016 +0100
+
+    [strings] Remove std:: from normative wording
+
+commit e0b87fbbe4c2050187ad5b4b1e859a111790fca3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jun 16 20:08:25 2016 +0100
+
+    [Readme] Fix isocpp link for DR submission (#756)
+
+    Fixes #755.
+
+commit d335c89932b3911b5405dd7ad15bf8530d2e884d
+Author: AaronBallman <aaron@aaronballman.com>
+Date:   Thu Jun 16 14:22:21 2016 -0400
+
+    [dcl.enum], [class.mem] Clarify the definitions for layout-compatible and fix their index entries (#700)
+
+commit 820626bf19f2df385d91d0d6c31293f136a9573b
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Mon Jun 13 20:50:08 2016 +0200
+
+    [basic.lookup] Fix typos
+
+commit d7ecb6f7e56001d78747ea6f6a9782b704512d4e
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Mon Jun 13 21:37:11 2016 -0400
+
+    [18,20] Consistent indexing of simple exception types (#750)
+
+    Appply a simple, consistent pattern to the index entries, including
+    th index of implementation defined behaviors, for the library types
+    that derive from std::exception.
+
+    In some cases this means adding entries, in others removing extra
+    nested implementation-defined entries that are redundant since the
+    addition of the index of implementatio defined behaviors.
+
+    A few cross-references were added or corrected as part of this
+    process.
+
+    Further work to make the presentation and specification of these
+    types probably requires LWG issues.  In particular, bad_any_cast
+    is woefully underspecified.
+
+commit f3a3c85b9957f35ddc7b5290cf8367b2cb78bd0e
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Thu Jun 9 21:02:51 2016 -0400
+
+    [valarray.sub] Fix error in example code (#746)
+
+    Fixes #160
+
+commit 6d3936c3f904622757e84df28852373079822d48
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jun 9 14:35:52 2016 -0700
+
+    [libindex] Rename index entries from "bad_X, bad_X::what, implementation
+    defined" to "bad_X, what, implementation defined" for consistency.
+
+    Add some missing index entries for class members that are themselves
+    classes.
+
+commit 28f8551018cb975b18e3ddf95fed50e679b30c79
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Thu Jun 9 22:27:33 2016 +0100
+
+    [bad.cast], [bad.exception] nest index entries consistently (#744)
+
+commit da7277645a807ccbedd12fda104cbd9b78987eca
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jun 9 12:54:00 2016 +0100
+
+    [allocator.adaptor.members] fix index entry for destroy
+
+commit 05521fa5a364ba59a0eeb080cafb8ba95830aa47
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jun 8 19:53:17 2016 -0400
+
+    [18-28] Fix index entry for constructors
+
+    The preferred way to list constructors in the index is under the
+    non-code font term 'constructor', but many classes retain old
+    text that lists the constructor under the class name as the same
+    class name, in a code font.  Worse, there are quite a few classes
+    that have fallen into a hybrid approach, with both listings, which
+    can be confusing. This change-set should catch every constructor
+    indexed in the old style and consistently transform it to the new.
+
+    One additional fix is that allocator_traits mis-indexed the static
+    member functions 'construct' and 'destroy' as the plain-text
+    constructor and destructor.  This patch correctly indexes them as
+    their correct name, in a code-font.
+
+commit e47197014cbef9421b09d2180cab8f37a55658c7
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jun 8 23:27:37 2016 -0400
+
+    [support.runtime] Fix name of stdarg.h in index
+
+    Simple typo where the index (but not the main text) refers
+    to <stdarg.h> as <staarg.h>.
+
+commit 87975172ae653b8bdeb6e582a060cd46b91ab377
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jun 8 21:19:07 2016 -0400
+
+    [18-27] Remove tcode from index entries
+
+    Several old index entries use '\tcode' to force a code
+    font on their sub-entry.  This is no longer necessary,
+    as the LaTeX scripts produce the correct font for an
+    '\idxcode' entry.  However, using '\tcode' inconsistently
+    will produce duplicate entries, and entries that do not
+    sort correctly.  This change set consistently applies
+    '\idxcode' in preference to '\tcode' to eliminate the
+    redundant and mis-sorted entries.
+
+commit a167f5c7a25e54432218847f5109703ef76876fb
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jun 8 19:14:42 2016 +0100
+
+    [compatibility] Add compatibility notices for pp-number (#713)
+
+commit 13b57f74b8b9aac71e4cabe186b16c60670c2c71
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Thu Jun 2 23:03:43 2016 -0400
+
+    [unord.req] p12 should refer to key_eq(), not key_equal()
+
+commit 41340cd5542959085a52449ce5f249534c8314ea
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jun 8 08:46:33 2016 -0400
+
+    [time.duration.comparisons] Fix index entry for duration operator<
+
+    The index entry for 'operator<' of the 'duration' class template is
+    associated with an unknown 'idxl' type, instead of 'durtation'.
+
+commit ee583454f6f9e5e3c320d0a8e6dc18082ffed07d
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jun 8 09:14:16 2016 -0400
+
+    [string.view.comparison] Fix index for basic_string_view operators
+
+    The first issue is that operator<< does not group in the index with
+    other definitions for operator<<, which use an index key of
+    operator\shl.
+
+    The second issue is that operator<< was the only operator indexed
+    under the 'basic_string_view' key, where the precedent fro basic_string
+    and other types is that the free-function operators are still indexed
+    under their respective class entry.
+
+commit 15a68689e8dd9f2ba82f29c37d4fa3e4c9c461ee
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jun 8 08:35:27 2016 -0400
+
+    [allocator.adaptor] consolidate memory utilities]
+
+    This patch simply moves the scoped allocator clause to
+    be adjacent to the other memory and allocator clauses
+    for a more consistent sub-organization of clause 20.
+
+    The patch looks pretty awful thanks to the diff
+    algorithm treating it as a lot of interspersed edits,
+    where in fact is way a single cut/paste for the bulk
+    of the test (plus a second one-liner for the clause 20
+    table of contents).
+
+commit c8f1863b67ce555c7576faddb50bd8707bfe0bee
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Wed Jun 8 01:35:02 2016 -0400
+
+    [18-30] Replace typedefs with alias-declarations (#704)
+
+    This set of changes replace (almost) all use of 'typedef' in the library
+        with a type alias instead:
+            typedef Original NewName;
+         ->
+            using NewName = Original;
+
+        Attention was paid to retaining table-like formatting where present, which
+        is worth reviewing in case I made idiosyncratic choices.
+
+        Clause 29 [atomic] was specifically ignored, as there is a desire for the
+        contained code to look as close to a C compatible header as possible.
+
+commit 2a5d9721aa153e7fcea4ab7ea21333b18dd3d001
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 7 14:46:52 2016 -0700
+
+    [pairs.pair] Fix indentation of Remarks: paragrah.
+
+commit 92c3395bb23f57b9a99d389b3f5aabead337c865
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jun 6 14:00:38 2016 +0100
+
+    [fs.op.permissions] Combine adjacent tcode regions
+
+commit 256d202e61f4317f30ae839125e714e8192690d4
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jun 6 13:55:46 2016 +0100
+
+    [fs.op.permissions] Escape unary complement operator
+
+commit deffb9ed5457d4fa5b0fe44d0fd28c1f8c3ab723
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Thu Jun 2 15:09:08 2016 -0400
+
+    [lex.pptoken] fix term
+
+    "preprocessor token" -> "preprocessing token"
+
+commit a2b62a8c3aa1b334e0506d309b3bfaffd47d0827
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Thu Jun 2 12:16:44 2016 -0400
+
+    [class.path] escape backslash in character literal
+
+    Fixes #731
+
+commit 6be63b64af6c2a6cb40ddf76268dd6d5297f5394
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue May 31 10:24:38 2016 -0700
+
+    [expr] Remove outdated, inaccurate, irrelevant note on the actual
+    behavior of signed integer overflow on "most existing implementations".
+
diff --git a/papers/n4603.md b/papers/n4603.md new file mode 100644 index 0000000000..57cf898fb7 --- /dev/null +++ b/papers/n4603.md @@ -0,0 +1,1346 @@ +# N4603 Editor's Report -- Committee Draft, Standard for Programming Language C++ + +2016-07-12 +Richard Smith +Google Inc +`` + +## Acknowledgements + +Thanks to +Dawn Perchik, +Jonathan Wakely, +Thomas Köppe, and +Alisdair Meredith +for performing the edits for many of the motions applied to this draft, +and to +Kevin Godby and +Thomas Köppe +for modernizing and improving various parts of the standard draft build process. + +Thanks to the editing committee for reviewing the C++17 Committee Draft. +The editing committee for the C++17 CD comprises: +Marshall Clow, +Alisdair Meredith, +Mike Miller, and +Jeffrey Yasskin. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * N4603 is this Editor's Report. + * [N4604](http://wg21.link/n4604) is the C++17 Committee Draft. + * [N4606](http://wg21.link/n4606) is the current working draft. It replaces [N4594](http://wg21.link/n4594). + +Other than their cover sheets, the content of N4604 and N4606 are identical. +Both N4604 and N4606 contain the changes listed below. + +### Motions incorporated into committee draft + +#### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p0384r0) for 7 issues applied: + + * [1861](http://wg21.link/cwg1861) Values of a bit-field + * [2022](http://wg21.link/cwg2022) Copy elision in constant expressions **(example updated to match P0135R1)** + * [2076](http://wg21.link/cwg2076) List-initialization of arguments for constructor parameters + * [2091](http://wg21.link/cwg2091) Deducing reference non-type template arguments + * [2137](http://wg21.link/cwg2137) List-initialization from object of same type + * [2145](http://wg21.link/cwg2145) Parenthesized declarator in function definition + * [2171](http://wg21.link/cwg2171) Triviality of copy constructor with less-qualified parameter + +CWG motion 2 applies to the Concepts TS + +CWG motion 3: [P0028R4 "Using attribute namespaces without repetition"](http://wg21.link/p0028r4) + +CWG motion 4: [P0035R4 "Dynamic memory allocation for over-aligned data"](http://wg21.link/p0035r4) + +CWG motion 5: [P0091R3 "Template argument deduction for class templates"](http://wg21.link/p0091r3) **(clause labels renamed from those in paper)** + +CWG motion 6: [P0127R2 "Declaring non-type template parameters with `auto`"](http://wg21.link/p0127r2) **(clause labels renamed from those in paper)** + +CWG motion 7: [P0135R1 "Guaranteed copy elision through simplified value categories"](http://wg21.link/p0135r1) + +CWG motion 8: [P0137R1 "Replacement of class objects containing reference members"](http://wg21.link/p0137r1) + +CWG motion 9: [P0145R3 "Refining expression evaluation order"](http://wg21.link/p0145r3) and [P0400R0 "Order of evaluation of function arguments"](http://wg21.link/p0400r0) + +CWG motion 10 was not approved. + +CWG motion 11: [P0283R2 "Standard and non-standard attributes"](http://wg21.link/p0283r2) + +CWG motion 12: [P0292R2 "`constexpr if`"](http://wg21.link/p0292r2) + +CWG motion 13: [P0296R2 "Forward progress guarantees: base definitions"](http://wg21.link/p0296r2) + +CWG motion 14: [P0299R1 "Forward progress guarantees for the Parallelism TS features"](http://wg21.link/p0299r1) + +CWG motion 15: [P0386R2 "`inline` variables"](http://wg21.link/p0386r2) **(see below)** + +CWG motion 16: [P0391R0 "Introducing the term 'templated entity'"](http://wg21.link/p0391r0) + +CWG motion 17: [P0217R3 "Structured bindings"](http://wg21.link/p0217r3) + +CWG motion 18: [P0305R1 "Selection statements with initializer"](http://wg21.link/p0305r1) + +CWG motion 19: [Core issue resolution](http://wg21.link/p0398r0) from one issue applied: + + * [1518](http://wg21.link/cwg1518) Explicit default constructors and copy-list-initialization + +Core motions added a total of 10 pages to Clause 1-16. + +#### Library working group motions + +LWG motion 1: [Library issue resolutions](http://wg21.link/p0165r2) for 16 issues in "Ready" status applied: + + * [2181](http://wg21.link/lwg2181) Exceptions from seed sequence operations + * [2309](http://wg21.link/lwg2309) `mutex::lock()` should not throw `device_or_resource_busy` + * [2310](http://wg21.link/lwg2310) Public exposition only member in `std::array` + * [2328](http://wg21.link/lwg2328) Rvalue stream extraction should use perfect forwarding + * [2393](http://wg21.link/lwg2393) `std::function`'s Callable definition is broken + * [2426](http://wg21.link/lwg2426) Issue about `compare_exchange` + * [2436](http://wg21.link/lwg2436) Comparators for associative containers should always be CopyConstructible + * [2441](http://wg21.link/lwg2441) Exact-width atomic `typedef`s should be provided + * [2542](http://wg21.link/lwg2542) Missing `const` requirements for associative containers + * [2549](http://wg21.link/lwg2549) `tuple` *EXPLICIT* constructor templates that take tuple parameters end up taking references to temporaries and will create dangling references + * [2550](http://wg21.link/lwg2550) Wording of unordered container's `clear()` method complexity + * [2667](http://wg21.link/lwg2667) `path::root_directory()` description is confusing + * [2669](http://wg21.link/lwg2669) `recursive_directory_iterator` effects refers to non-existent functions + * [2670](http://wg21.link/lwg2670) `system_complete` refers to undefined variable `base` + * [2671](http://wg21.link/lwg2671) Errors in `copy` + * [2673](http://wg21.link/lwg2673) `status()` effects cannot be implemented as specified + +LWG motion 2: [Library issue resolutions](http://wg21.link/p0165r2) for 11 issues in "Tentatively Ready" status applied: + + * [2596](http://wg21.link/lwg2596) `vector::data()` should use `addressof` + * [2674](http://wg21.link/lwg2674) Bidirectional iterator requirement on `path::iterator` is very expensive + * [2683](http://wg21.link/lwg2683) `filesystem::copy()` says "no effects" **(see below)** + * [2684](http://wg21.link/lwg2684) `priority_queue` lacking comparator `typedef` + * [2685](http://wg21.link/lwg2685) `shared_ptr` deleters must not throw on move construction + * [2688](http://wg21.link/lwg2688) `clamp` misses preconditions and has extraneous condition on result + * [2689](http://wg21.link/lwg2689) Parallel versions of `std::copy` and `std::move` shouldn't be in order + * [2698](http://wg21.link/lwg2698) Effect of `assign()` on iterators/pointers/references + * [2706](http://wg21.link/lwg2706) Error reporting for `recursive_directory_iterator::pop()` is under-specified + * [2707](http://wg21.link/lwg2707) `path` construction and assignment should have `string_type&&` overloads + * [2710](http://wg21.link/lwg2710) "Effects: Equivalent to ..." doesn't count "Synchronization:" as determined semantics + +LWG motion 3 applies to the Library Fundamentals (v2) TS + +LWG motion 4 applies to the Library Fundamentals (v2) TS + +LWG motion 5: [Library issue resolutions](http://wg21.link/p0397r0) for 4 issues in "Immediate" status applied: + + * [2687](http://wg21.link/lwg2687) `{inclusive,exclusive}_scan` misspecified + * [2704](http://wg21.link/lwg2704) `recursive_directory_iterator`'s members should require '`*this` is dereferenceable' + * [2711](http://wg21.link/lwg2711) `path` is convertible from approximately everything under the sun + * [2725](http://wg21.link/lwg2725) `filesystem::exists(const path&, error_code&)` error reporting + +LWG motion 6: [Library issue resolutions](http://wg21.link/p0304r1) for 13 issues in "Immediate" status applied: + + * [2312](http://wg21.link/lwg2312) `tuple`'s constructor constraints need to be phrased more precisely + * [2422](http://wg21.link/lwg2422) `std::numeric_limits::is_modulo` description: "most machines" errata + * [2709](http://wg21.link/lwg2709) `offsetof` is unnecessarily imprecise + * [2716](http://wg21.link/lwg2716) Specification of `shuffle` and `sample` disallows lvalue URNGs + * [2718](http://wg21.link/lwg2718) Parallelism bug in [algorithms.parallel.exec] p2 + * [2719](http://wg21.link/lwg2719) `permissions` function should not be `noexcept` due to narrow contract + * [2720](http://wg21.link/lwg2720) `permissions` function incorrectly specified for symlinks + * [2721](http://wg21.link/lwg2721) `remove_all` has incorrect post conditions + * [2723](http://wg21.link/lwg2723) Do `directory_iterator` and `recursive_directory_iterator` become the end iterator upon error? + * [2724](http://wg21.link/lwg2724) The `protected virtual` member functions of `memory_resource` should be `private` + * [2726](http://wg21.link/lwg2726) `[recursive_]directory_iterator::increment(error_code&)` is underspecified + * [2727](http://wg21.link/lwg2727) Parallel algorithms with `constexpr` specifier + * [2728](http://wg21.link/lwg2728) `status(p).permissions()` and `symlink_status(p).permissions()` are not specified + +LWG motion 7: [P0063R3 "C++17 should refer to C11 instead of C99"](http://wg21.link/p0063r3) **(see below)** + +LWG motion 8: [P0175R1 "Synopses for the C library"](http://wg21.link/p0175r1) **(see below)** + +LWG motion 9: [P0088R3 "`variant`, a type-safe union for C++17"](http://wg21.link/p0088r3) + +LWG motion 10: [P0307R2 "Making `optional` greater equal again"](http://wg21.link/p0307r2) + +LWG motion 11: [P0393R3 "Making `variant` greater equal"](http://wg21.link/p0393r3) + +LWG motion 12: [P0032R3 "Homogeneous interface for `variant`, `any`, and `optional`"](http://wg21.link/p0032r3) **(with normative changes, see below)** + +**LWG motion 13: [P0067R3 "Elementary `string` conversions"](http://wg21.link/p0067r3) not applied, see below** + +LWG motion 14: [P0254R2 "Integrating `string_view` and `string`"](http://wg21.link/p0254r2) + +LWG motion 15 was not approved. + +LWG motion 16: [P0258R2 "`has_unique_object_representations`"](http://wg21.link/p0258r2) + +LWG motion 17: [P0040R3 "Extending memory management tools"](http://wg21.link/p0040r3) + +LWG motion 18: [P0084R2 "`emplace` return type"](http://wg21.link/p0084r2) + +LWG motion 19: [P0302R1 "Removing allocator support in `std::function`"](http://wg21.link/p0302r1) + +LWG motion 20: [P0083R3 "Splicing `set`s and `map`s"](http://wg21.link/p0083r3) + +LWG motion 21: [P0181R1 "Ordered by default"](http://wg21.link/p0181r1) **(with normative changes, see below)** + +LWG motion 22: [P0163R0 "`shared_ptr::weak_type`"](http://wg21.link/p0163r0) + +LWG motion 23: [P0209R2 "`make_from_tuple`: `apply` for construction"](http://wg21.link/p0209r2) + +LWG motion 24: [P0295R0 "Adopt selected Library Fundamentals v2 components"](http://wg21.link/p0295r0) + +LWG motion 25: [P0174R2 "Deprecating vestigial library parts"](http://wg21.link/p0174r2) + +LWG motion 26: [P0337R0 "Delete `operator=` for `polymorphic_allocator`"](http://wg21.link/p0337r0) + +LWG motion 27: [P0358R1 "Fixes for `not_fn`"](http://wg21.link/p0358r1) + +LWG motion 28: [P0219R1 "Relative paths for filesystem"](http://wg21.link/p0219r1) + +LWG motion 29: [P0392R0 "Adapting `string_view` by filesystem paths"](http://wg21.link/p0392r0) + +LWG motion 30: [P0394R4 "`terminate()` for parallel algorithms exception handling"](http://wg21.link/p0394r4) + +LWG motion 31: [P0336R1 "Better names for parallel execution policies"](http://wg21.link/p0336r1) + +LWG motion 32: [P0371R1 "Temporarily discourage `memory_order_consume`"](http://wg21.link/p0371r1) + +LWG motion 33: [P0346R1 "A `` nomenclature tweak"](http://wg21.link/p0346r1) + +LWG motion 34: [P0180R2 "Reserve a new library namespace for future standardization"](http://wg21.link/p0180r2) + +Library motions added a total of 42 pages to Clause 17-30. + +### Notable changes to papers as moved + +#### CWG motion 4 + +Wording and paragraph ordering within [new.delete] was modified +to be consistent across all of the largely-duplicated subsections. + +#### CWG motions 5 and 6 + +Some clause labels were renamed from those proposed by these papers, for +consistency with the rest of the standard, as follows: + + * [dcl.auto.deduct] -> [dcl.type.auto.deduct] + * [deduced.class.type] -> [dcl.type.class.deduct] + * [class.template.deduction] -> [over.match.class.deduct] + * [temp.deduction.guide] -> [temp.deduct.guide] + +#### CWG motion 15 + +Added missing edit to clause 12 to avoid conflict with wording added to clause +3, which makes a `static inline` data member declaration a definition. The +clause 12 wording had text left over from `constexpr` rules that required an +initializer to be provided. + +#### LWG motion 2, issue 2683 + +Proposed wording did not fit surrounding text and has been reworded. + +#### LWG motion 7 + +This paper did not update the definition of "C standard" in +[intro.scope]/2 from C99 to C11. This change has also not been +made editorially, as it is unclear whether this omission is +intentional or an oversight. The paper has been applied as written, +but this issue warrants further investigation. + +#### LWG motion 8 + +The purpose of this paper was to request editorial freedom to restructure the +description of the parts of the C++ standard library that were inherited from +C. To this end, the edits applied are based on those in P0175R1, but in +addition, the descriptions of many C library functions have been moved, +reordered, and reformatted into the standard format used for C++ library +description. + +See the list of editorial fixes below for the full details. + +#### LWG motion 12 + +Added missing updates to definition of class template `optional` to match +changes in detailed description. + +Removed detailed description of variant's `in_place_type` and `in_place_index` +to match changes to synopsis. + +The template parameters to `in_place_index_t` and the corresponding form of +`in_place` were specified as `template` and `template` respectively +in the wording paper, and have been editorially corrected to the intended +`template`. + +#### LWG motion 13 + +Proposed wording has different signatures for `from_chars` in the synopsis and +in the detailed wording. **The paper was returned to LWG for redrafting, and +a revised wording paper has been provided by the paper author as +[P0067R4](http://wg21.link/p0067r4).** + +#### LWG motion 21 + +No explicit editing instructions were provided to merge this motion with +the introduction of `std::pmr` from 2016-02 LWG Motion 6, +which the base document for this motion predates. +At the request of the paper author, +and based on the clear intent of both motions, +the change was also applied to the containers in namespace `std::pmr`. + +### Notable editorial changes since N4594 + + * As noted in LWG motion 8, descriptions of subclauses related to the portions + of the C standard library incorporated into C++ have been substantially + reorganized. + + * The index of clause labels (formerly known as Annex F) has been demoted from + an Annex to a regular index and now lists the page number in addition to the + section number for each clause. + +## Minor editorial fixes + +A log of all editorial fixes made since N4594 is below: + + commit 0f682fdcccd2c3a64d478e1e3cdcf3d8f6928bd1 + Author: Richard Smith + Date: Mon Jul 11 18:11:57 2016 -0700 + + Fix review comments from Jeffrey. + + [any.modifiers] The Requires: clause here was redundant, since the + Remarks: clause gives the same condition as a SFINAE condition. + + [path.itr] Align the phrasing of the way in which path::iterator is not + a bidirectional iterator with the corresponding phrasing in the + description of the bidirectional iterator requirements. + + commit 8f0c572eae9b8306e5d78a86dbdebf5c353f5895 + Author: Richard Smith + Date: Mon Jul 11 14:38:33 2016 -0700 + + [meta.type.synop] Italicize placeholder text "default-alignment" to + match formatting in detailed description. + + commit bd00cfb2b9f505220b6fc92f0310e56e11209e67 + Author: Thomas Köppe + Date: Mon Jul 11 20:36:22 2016 +0100 + + [regex] Remove bogus indexlibrary entry + + commit d17944301f1cf53e0b5af2dcda25039bc36c3556 + Author: burblebee + Date: Mon Jul 11 12:35:21 2016 -0700 + + Make universal-character-name \grammarterm'd (#807) + + Fixes #296 + + commit 6098c7fa264ac862711616ca933611220e6cc208 + Author: Richard Smith + Date: Sun Jul 10 23:55:31 2016 -0700 + + [c.math] Change title of this subclause from "C library" to + "Mathematical functions for floating point types" to match its contents; + the special math functions in are not part of the C library. + + commit b882709b88e8d8f88b47036f75d99e6949e470fd + Author: Richard Smith + Date: Sun Jul 10 17:46:47 2016 -0700 + + [objects.within.classes] Clarify what "exposition only" means for + private members that are not data members. This applies the first + portion of LWG2516 (voted into Lib Fundamentals) to the working paper. + + commit 9c4447539b309db428186ecdfc47809d3ace96fc + Author: Richard Smith + Date: Sun Jul 10 17:15:49 2016 -0700 + + Rename [util.smartptr.weakptr] to [util.smartptr.weak.bad]. This section + describes the bad_weak_ptr exception class, so the previous name was + completely inappropriate. + + Fixes #801. + + commit 5f9e2c145d98a7cc605993359d2e2a5437d083a5 + Author: Richard Smith + Date: Sun Jul 10 17:03:29 2016 -0700 + + [fs.op.relative] Replace "Returns A except B if an error is produced" + with "Returns A, or B if an error is produced" to match similar wording + elsewhere. + + commit 73b8f1ab222076c4b02be47c1b7e1386247695a9 + Author: Richard Smith + Date: Sun Jul 10 16:59:29 2016 -0700 + + [any] Fix template parameter list of make_any to list the + parameter that is intended to be explicitly specified first. The + wording paper had inconsistent parameter orders between the synopsis and + the detailed wording, and this is the obvious intent. + + Fixes #813. + + commit 186885a158863e204b45251ecced3c6938dd3c6d + Author: timsong-cpp + Date: Sun Jul 10 14:42:39 2016 -0400 + + [func.default.traits] Remove inappropriate reference to [unord] (#819) + + The *unordered* associative containers do not use default_*order*. + + commit aee45702ed8527b9dc74552a39c32fb6111a01c5 + Author: Jonathan Wakely + Date: Sun Jul 10 17:58:14 2016 +0100 + + [variant.swap] Use math mode for variable "i" + + commit 50d074fc6ee918d9658aee57352225cf69aa5d3f + Author: S. B. Tam + Date: Sun Jul 10 17:50:36 2016 +0800 + + [filesystems] Fix unmatched parentheses around references (#814) + + commit d3066bfac13e674fa53f1c332f7a4e4779b24fe7 + Author: Alisdair Meredith + Date: Sun Jul 10 04:55:40 2016 +0100 + + [19-26] Consistent use of _v (#783) + + The library clauses have started to make inconsistent use of the _v + variable templates for traits, in preference to directly querying + trait::value. This change set applies that change consistently over + all existing wording, where there is a choice of which form might + be used. It does not make any changes where the _v variable is not + available, or is being defined in terms of the corresponding ::value. + + commit 7e7b6c41caffc276603ba74f72d12f122a7ca098 + Author: Jonathan Wakely + Date: Sat Jul 9 15:02:55 2016 +0100 + + [locale.codecvt.members] Add spaces between function arguments + + commit ab44124fa5b55cc4c445926e15f55934f881142a + Author: Thomas Köppe + Date: Sat Jul 9 16:59:35 2016 +0300 + + [input.output,strings,utilities] Don't format informative 'see below' as code (#809) + + commit 16f3af8a65762aab840e878315a71d17f1dac736 + Author: Jonathan Wakely + Date: Sat Jul 9 14:37:28 2016 +0100 + + Fix index entries for operator!= + + commit e50e299cd02da221151413d8332ee6bc20c53912 + Author: Jonathan Wakely + Date: Sat Jul 9 14:25:23 2016 +0100 + + [utility] Fix declarations of in_place_index_t + + commit 1ed6ec00c0badef4fbcb0a6fc1d359ad4fae9a22 + Author: Jonathan Wakely + Date: Thu Jul 7 19:09:49 2016 +0100 + + [re.regex.construct] Use tcode instead of textit + + commit d51fa51a4d4063a0bd8c6137babe155990f51019 + Author: Jonathan Wakely + Date: Thu Jul 7 19:06:46 2016 +0100 + + [re.traits] Use tcode instead of textit + + commit 59a605fb57251183eabb2b1268cb85448c132052 + Author: Jonathan Wakely + Date: Wed Jul 6 18:03:05 2016 +0100 + + [alg.random.sample] Remove stray period. + + Fixes #797 + + commit 8ae8c1396a30ef880f3b1a5808f5e9dd5c622d21 + Author: Jonathan Wakely + Date: Wed Jul 6 18:02:42 2016 +0100 + + [ios.base.callback] Add missing pnum + + commit 7e1143cfa907a405217ba7792a4a46535b815396 + Author: Jonathan Wakely + Date: Wed Jul 6 01:15:20 2016 +0100 + + [re.results.form] use code font + + commit 322011bc53f589afdbe4267d1689fa52adf4a58f + Author: Jonathan Wakely + Date: Tue Jul 5 15:50:24 2016 +0100 + + [tuple.traits] Add missing pnum + + commit f78c2de5b51559d89dde5f34f540ca51c1456981 + Author: Jonathan Wakely + Date: Thu Jun 30 11:12:58 2016 +0100 + + [meta.unary.prop.query] fix whitespace in alignment_of row + + commit 1329a28df4c2f7b3dbc8e84675b85334cf02e767 + Author: Eelis + Date: Sat Jul 9 15:07:10 2016 +0200 + + [variant.visit] Remove stray colon (#810) + + commit 4c8f1a7c4a77986a8838dbc34dc72ca24b67091d + Author: Thomas Köppe + Date: Sat Jul 9 14:31:34 2016 +0300 + + [valarray.members] Fix up index entries for named valarray member functions (#808) + + The index currently lists the named member-functions of valarray as + if they were free functions - this adds the corresponding entry under + the valarray listing in the index, alongside the existing entries for + the many operator functions. It also fixes the entry for "size()". + + commit cdedc854aa3b73b1a505a58f0c0b3837def1c9e3 + Author: S. B. Tam + Date: Sat Jul 9 18:45:41 2016 +0800 + + [ratio.si] Fix typo (#779) + + commit 81543ed95ccdc071cf298b3a0b2d98a521e623f0 + Author: Thomas Köppe + Date: Sat Jul 9 13:39:37 2016 +0300 + + [dcl.spec.auto] Add 'The' to heading 'auto specifier' (#782) + + commit f90ba1e46385c97ee30c6e40ce6abcbbae0cb258 + Author: Thomas Köppe + Date: Sat Jul 9 13:26:00 2016 +0300 + + [diagnostics] Make system_error synopsis more consistent (#795) + + commit 4f46b45b68973e00d732e4995f135ffe17ba0ad3 + Author: Eelis + Date: Sat Jul 9 05:17:55 2016 +0200 + + [stmt.if] Balance brackets and fix indentation in example. + + commit b7ee7b2216102257ccad4dea2750e9b945333954 + Author: Thomas Köppe + Date: Sat Jul 9 06:14:48 2016 +0300 + + [cpp] Fix index text for STDCPP_DEFAULT_NEW_ALIGNMENT (#784) + + commit 0bc04c584447d510d4d9a58553689cd405894fa2 + Author: Thomas Köppe + Date: Sat Jul 9 01:44:04 2016 +0100 + + [back] Install proper page marks for post-appendix backmatter + + commit 46343660afd101e218aa7ec77a7bc6ba618894b0 + Author: Thomas Köppe + Date: Fri Jul 8 23:50:52 2016 +0100 + + Generate xrefs as a glossary + + commit 48375f4eceabeff09816f9314f02d70b5a084f1f + Author: Dawn Perchik + Date: Fri Jul 1 16:11:38 2016 -0700 + + [filesystems] Add references to fs.def.pathres where "resolve" is used. + + commit d91ec5fe94bb69d555940c2b0262aecd002a04be + Author: Dawn Perchik + Date: Fri Jul 1 16:05:01 2016 -0700 + + [fs.def.normal.form] Define terms normalized and normalization. + + commit 4e6c8bd3547ac3fa3e5675f9dbac1c62bc8fe868 + Author: Dawn Perchik + Date: Thu Jun 30 16:10:11 2016 -0700 + + [fs.op.absolute] Fix inconsistent coding style. + + commit babea2e671c49bf8e1d5087fbb6964dca11431e2 + Author: Dawn Perchik + Date: Thu Jun 30 16:05:54 2016 -0700 + + [fs.op.proximate][fs.op.weakly_canonical] Rephrase nonsensical wording. + + commit 3d6079f4c7a51e8023d18ef599bef301d7f29878 + Author: Thomas Köppe + Date: Wed Jun 29 00:19:17 2016 +0100 + + [func.default.traits] Add cross-references + + commit 3ee9d1f8c7f8d29fb0741e0eecfd259f473324e7 + Author: Richard Smith + Date: Fri Jul 8 12:01:38 2016 -0700 + + [c.locales], [clocale.syn] Fold child clause into its parent and remove + paragraph that is duplicated between the two. + + commit 993f8138ab7c07e0d6b3ef4b4f625a0f928d9a6a + Author: Richard Smith + Date: Fri Jul 8 12:00:37 2016 -0700 + + [c.strings] Point the "see" comments for functions with different + signatures in C and C++ to [library.c], which specifies how those + functions behave. + + commit e53963822cac2fb44d7efe3224c67a748383fbd6 + Author: Richard Smith + Date: Wed Jul 6 17:25:12 2016 -0700 + + [string.ops] Move basic_string::operator basic_string_view alongside + data() and c_str() rather than putting it in its own section. + + commit dd6cf3bf2332b389306311e22a7ad500bf7fd93f + Author: timsong-cpp + Date: Fri Jul 8 00:36:09 2016 -0400 + + [class.union] Fix typo. + + s/initialiation/initialization/. + + commit bbb02446b7ca948f2d84d8d18ff195f942908d9a + Author: Dawn Perchik + Date: Wed Jul 6 15:50:12 2016 -0700 + + [meta.type.synop] Delete extra space before is_nothrow_copy_assignable + + commit 2318e73d26f56a058d53a0c4ad65789dcf50cff6 + Author: Richard Smith + Date: Thu Jul 7 16:11:20 2016 -0700 + + [headers] Update introductory text for the C library now that Clause 17 + contains a C header synopsis. + + commit 73a0fde86eb4506474c25415d4ef2fcf9dd701d6 + Author: Richard Smith + Date: Thu Jul 7 16:05:48 2016 -0700 + + [cinttypes.syn] Explicitly mark the intmax_t forms of abs and div as + optional in the synopsis, to match the normative requirement. + + commit c448d933adad9c705c79adfc1cb7f3ea25f7c0ab + Author: Richard Smith + Date: Thu Jul 7 16:00:51 2016 -0700 + + [support.types.layout] Clarify that offsetof is based on the C standard + library macro of the same name, now that we no longer explicitly say + that all of is based on the corresponding C header. + + commit 7b8c69d1fe4eae4785747842fa32127685e9b0c7 + Author: Richard Smith + Date: Thu Jul 7 15:51:06 2016 -0700 + + Replace the anachronism 'int f(void)' with 'int f()' throughout the C++ + standard library description and in a couple of examples. + + commit bf0c6f4cd0ff9e10c5e637a751381205c6004b89 + Author: Richard Smith + Date: Thu Jul 7 15:48:19 2016 -0700 + + Update declarations of NULL and size_t in C header synopses to refer to + the place where C++ gives them different meaning from C. + + commit 1a62c222522ad27e189a149f7329cce1c0c651b7 + Author: Richard Smith + Date: Thu Jul 7 15:36:41 2016 -0700 + + [library.c] Clarify what we mean by 'restrict', since it doesn't exist + in C++. + + commit ed3c014c14b1973965567475301587d6240e8f34 + Author: Richard Smith + Date: Thu Jul 7 15:35:11 2016 -0700 + + Add index entries for all C standard library entities. + + commit 8e4ab9cdee4399b475735b0cb39d70d8e1040969 + Author: Richard Smith + Date: Thu Jul 7 15:16:41 2016 -0700 + + [c.strings] Move descriptions of individual headers to the section for + the respective header. + + commit 1f22f4264428dc65607a419594842fc68c6891ac + Author: Richard Smith + Date: Thu Jul 7 15:03:36 2016 -0700 + + [ctime.syn], [date.time] Delete the latter and move the former into its + place. We don't need two descriptions of the contents of . + + commit 299f1817f14e8a186ecd1b9e12a7c1759f17a17c + Author: Richard Smith + Date: Thu Jul 7 14:58:00 2016 -0700 + + Consistency fixes for C library header descriptions. + + commit 011c0228045e6cf84fb95e56eec30bda74577c7a + Author: Richard Smith + Date: Thu Jul 7 14:38:43 2016 -0700 + + [library.c] Consolidate the rules on the behavior of functions that + change signature between the C standard library and the C++ standard + library here. + + commit d48b1f64507aae655c1c655ea3046083a9bbc2c6 + Author: Richard Smith + Date: Thu Jul 7 14:25:34 2016 -0700 + + [c.mb.wcs] Reorder after relevant C library synopses. + + commit 42d8d347f7dad4116f48a7d6f07260333d30b74c + Author: Richard Smith + Date: Thu Jul 7 14:22:34 2016 -0700 + + Move description of out of [numerics] and into [library]. This + is a bad home for it, but it seems to be the best bad home, as the + portions of are described in 5 different library clauses. + + commit 46be71ecd68e3731b5d4943ac4c72d86ce37795f + Author: Richard Smith + Date: Thu Jul 7 13:40:22 2016 -0700 + + Add cross-references from synopsis to places where pieces of + it are described, and change those places to use the formatting style + we normally use for library entity descriptions. + + commit 1b56b231f892d3b8aada4fd12f427bbb32f9c22e + Author: Richard Smith + Date: Thu Jul 7 12:30:09 2016 -0700 + + [cinttypes.syn] Add missing #include to synopsis. + + commit c44e3158fd27aa87d79d7801b4fd538da63a2c0d + Author: Richard Smith + Date: Thu Jul 7 12:27:01 2016 -0700 + + [numerics] Integrate the special math functions into the + synopsis and add proper descriptions for the parts of the C standard + library that we modify. + + commit f4a9956a3141608ca5b408ed877da26255fcf6c2 + Author: Richard Smith + Date: Thu Jul 7 11:07:14 2016 -0700 + + [numerics] Remove incorrect suggestion that is specified here + rather than in Annex D. + + commit e6f109e4979ef255068eee5ed6ba99779bf8b50d + Author: Richard Smith + Date: Wed Jul 6 14:35:06 2016 -0700 + + More replacement of "Standard C Library" with the defined term "C + standard library", and remove an outdated reference to the C Unicode TR. + is now incorporated directly from C11. + + commit e9a9b52de953b0d224316b373423e272cb140cff + Author: Richard Smith + Date: Mon Jul 4 18:53:00 2016 -0700 + + Replace uses of the phrase "Standard C library" with the defined term + "C standard library" throughout the library clauses. + + commit 516d2712c5ab8926583b9249400d502afa8d95bf + Author: Dawn Perchik + Date: Fri Jul 1 16:31:51 2016 -0700 + + [istream::extractors] Fix '.' inside reference. + + commit 8c2a29598696e7b3dac5ff2d7f20f1d970649cc4 + Author: Richard Smith + Date: Sun Jul 3 21:07:27 2016 -0700 + + [alg.move] Fix bad linewrapping introduced by LWG2689. + + commit 641a469fb9f6bcc5a817f8da3d9443751046110e + Author: Richard Smith + Date: Sun Jul 3 20:04:16 2016 -0700 + + [tuple.cnstr] Fix bad line wrapping introduced by LWG issue 2549. + + commit f40f23d2c9b8de9eeeb781c4e7b90d056750535f + Author: Thomas Köppe + Date: Tue Jun 28 22:27:44 2016 +0100 + + [stmt] Move grammar and description of 'condition' up + + commit b20e63d533990375c9c3b8b0a0c590b7025aca4b + Author: Richard Smith + Date: Fri Jul 1 14:55:14 2016 -0700 + + [dcl.decomp] Use 'interpreted as' not 'taken as' to specify how a token + sequence should be parsed, for consistency with similar wording + elsewhere. + + commit de2bd84b59f79598f8bb6346c2879fc9e0b741bb + Author: Richard Smith + Date: Fri Jul 1 14:53:15 2016 -0700 + + Update cross-references to decomposition declarations to point to + [dcl.decomp] not [dcl.spec.auto]. + + commit 4b95f2e3e1c0dbb19a48302ad249db4de700766d + Author: Richard Smith + Date: Fri Jul 1 14:08:06 2016 -0700 + + [dcl.type.auto.deduct], [dcl.type.class.deduct] Reverse the order of + these two clauses so that [dcl.type.auto.deduct] is properly nested + within [dcl.spec.auto]. + + commit 8daec11f020f6f84dd0e4e40d20ffb176944847a + Author: Richard Smith + Date: Fri Jul 1 13:56:39 2016 -0700 + + [class.static.data] Fix inconsistency between rules for when a + declaration of an inline variable is a definition and remove + unintended implication that an inline static data member defined + inside a class must also be defined outside. + + commit 42f557b123ce1ce3dbd1c1e3c61f0f4cd72e9094 + Author: Richard Smith + Date: Fri Jul 1 13:43:26 2016 -0700 + + [dcl.inline] Consistently use teletype font when referring to the inline + keyword and roman font when referring to the inline property of + functions and variables. + + commit 77787781dfd56343d9b7007af055a9e3886e1a73 + Author: Richard Smith + Date: Fri Jul 1 11:53:28 2016 -0700 + + [algorithms.parallel.exec] As instructed by P0299R1, replace all + occurrences of 'thread' with 'thread of execution' throughout this + subclause. + + commit f8fc0629ce634650c176fcd23b8d15fae0a00047 + Author: Thomas Köppe + Date: Thu Jun 30 20:08:39 2016 +0100 + + [dcl.spec.auto] Disambiguate which return statements are meant + + commit 326fc8a501a4f7ed1ddf6bb9b729dda86d95c00f + Author: Thomas Köppe + Date: Tue Jun 28 23:46:32 2016 +0100 + + [temp] Add cross-reference to "templated entity" + + commit cdcabf2ee40c0332d6c16ae89126e4e9bb0e231f + Author: Richard Smith + Date: Thu Jun 30 18:43:26 2016 -0700 + + [expr.call] Move specification of parameter sequencing out of the middle + of wording on the conversions performed on parameters and into a + separate paragraph. Restore note on the relative ordering of argument + side effects and the evaluation of the function body now that it's no + longer implied by the sequencing of the argument evaluations. + Also fix bad "smart" apostrophe in example. + + commit 3dc7b01f3d15aef86be33e935efc1dac10cc5e45 + Author: Richard Smith + Date: Thu Jun 30 15:59:44 2016 -0700 + + [class.temporary] Promote footnote to note to avoid bullets in a + footnote, and move it to later in the clause, to a place where it fits + the flow of the surrounding text better. + + commit 4d277951eac45cdedf88d92d11652d507aba5be9 + Author: Richard Smith + Date: Thu Jun 30 14:52:32 2016 -0700 + + [dcl.init] Correct "return object" to defined term "result object". + + commit ce323f0b9fbae0434904e31e324d5f7c9589ffb9 + Author: Richard Smith + Date: Thu Jun 30 14:46:53 2016 -0700 + + Add missing space in 'cv void'. + + commit f454ecbe85381d18b89235c252a1654e8d7357e8 + Author: Richard Smith + Date: Thu Jun 30 14:46:01 2016 -0700 + + [expr.prim.lambda] Fix description of lambda-expressions. The expression + itself is a prvalue, not its value. + + commit b7c116c427e3a5f37f374cca6c024acd2f3c16c3 + Author: Richard Smith + Date: Thu Jun 30 14:45:12 2016 -0700 + + [expr.comma] Fix description of temporaryness of comma operator. It's + not meaningful to talk about a value being a temporary expression. + + commit 4ca5a4b5fff957feb1c93920f0f35ff9689af4ff + Author: Richard Smith + Date: Thu Jun 30 14:44:34 2016 -0700 + + [expr.mptr.oper] The left operand of .*, not the right, should be + required to be a glvalue. + + commit 86040aee532699152e6dded8f688a57d9662d21c + Author: Richard Smith + Date: Mon Jun 27 16:49:28 2016 -0700 + + [dcl.type.auto.deduct] Remove unnecessary wording complexity from + handling of return type deduction from void. + + commit 1a0589b15b5552ea38651b3c877e8d9fcc86d5c3 + Author: Richard Smith + Date: Mon Jun 27 15:03:40 2016 -0700 + + [expr.type.conv] Remove defined but unused term from class template + argument deduction in function-style cast. + + commit a4ca89a833d1af4e81d7fd3497d2ee64c2b8dbea + Author: Richard Smith + Date: Sun Jun 26 12:22:48 2016 -0700 + + Update all wording referring to placement new-expressions to use the + defined term rather than some variation of it. + + commit e206374d429d33e5f7178df872a73fc5d65bae69 + Author: Richard Smith + Date: Sun Jun 26 12:18:57 2016 -0700 + + Use consistent style and order when listing predeclared, replaceable, + and library-supplied overloads of operator new/delete, as suggested + in a drafting note in P0035R4. + + commit 95321805a3528aa1006bf8187e39e1f4bab00c1e + Author: Richard Smith + Date: Sun Jun 26 08:13:10 2016 -0700 + + [class.copy] Replace example of guaranteed elision in constant + expressions with one that is still correct when P0135R1 is applied. + + I note, however, that the requirement here is impossible for an + implementation to meet in general; we will need to revise the resolution + of this core issue. + + commit 77fe85dc22d31d3aa9f5a9ff7ecd3f46cff40b77 + Author: Jonathan Wakely + Date: Wed Jun 29 20:06:29 2016 +0100 + + [associative.reqmts] use code font for q2 in Table 109 + + commit 707d78c25e8e96133ab40d1720803115eb3592d7 + Author: Jonathan Wakely + Date: Wed Jun 29 20:00:59 2016 +0100 + + [unord.req] use code font for X in Table 11 + + commit 8bff74f11d38cf8f5b2795269c414e82f5320612 + Author: Thomas Köppe + Date: Thu Jun 23 21:13:47 2016 +0300 + + [strings] Replace NULL with "null pointer value" + + commit a15450c8cb1d13b01ead9acd30db192717848cef + Author: Thomas Köppe + Date: Thu Jun 23 21:13:41 2016 +0300 + + [iostreams] Replace NULL with "null pointer value" + + commit 44c5364c54f8bcefe980745fcc115410d209eec7 + Author: Thomas Köppe + Date: Thu Jun 23 22:04:22 2016 +0300 + + [macros,intro] Present example/note formatting better (#763) + + commit 268f494baf2c666d01bf49159d918c7f7a8c9fa6 + Author: Jonathan Wakely + Date: Thu Jun 23 19:05:36 2016 +0100 + + [temp.deduct.call] [temp.deduct.conv] Hyphenate top-level + + commit 5d8aa54a58b51d5c64d6b43beb6edbb3256d963d + Author: Thomas Köppe + Date: Thu Jun 23 20:35:43 2016 +0300 + + [overloading] Make operators appear in code font (#764) + + commit 896b5132357bd9678cc73b8c29febf25bd31dc75 + Author: Jonathan Wakely + Date: Thu Jun 23 14:21:17 2016 +0100 + + [diff.cpp11.special] Move to [diff.cpp14.special] (#767) + + commit fcdd2f6a714af4812a8b65124b2e6cb28c029df7 + Author: Jonathan Wakely + Date: Thu Jun 23 12:11:10 2016 +0100 + + [diff.cpp03.containers] Use \effect not \effects + + commit d25356eced71845d70cc4cb53c515c7b69ab7740 + Author: Jonathan Wakely + Date: Thu Jun 23 10:03:13 2016 +0100 + + [fs.op.absolute] Fix table name + + commit bc0e41a4711661efe45b28a0f5bee13c622e417f + Author: Alisdair Meredith + Date: Wed Jun 22 22:50:57 2016 +0300 + + [strings,containers] Add iterators to index of implemenetation defined behavior (#754) + + This patch slavishly copies the tag used for array::iterator, without + understanding if a better markup might be available. One consequence + is that we get two entries for basic_string_view::const_iterator. + Another is that the index around type names appears as two sorted + subsequences, rather than one sorted sequence. + + An additional patch will follow for the remaining implementation-defined + types that are not present in the index, once the preferred markup is + reviewed in this pull request. + + commit 1b47dd9975c61c93897f93e8a5ea5bd1480d51a7 + Author: Alisdair Meredith + Date: Wed Jun 22 22:30:42 2016 +0300 + + [18-20,27] Prefer to use 'override' where appropriate (#753) + + This patch makes consistent use of the 'override' contextual + keyword for every member function (other than destructors) + that overrides a virtual function in one of its base classes. + + In general, this came down to one of three cases: + 1) the 'what' function for an exception class + 2) the allocation functions of a memory resource + 3) the implementation methods of a stream buffer. + + As far as I can tell, all other virtual function declarations + in the standard library are intended as customization points + for users, and are not overridden in the standard itself. + + Fixes #751 + + commit 24ad0836274dbb494f7d391d917aaf1e4f3844fa + Author: Jonathan Wakely + Date: Wed Jun 22 19:45:00 2016 +0100 + + [iostate.flags] Remove name of exception object thrown + + commit 4d67e5d9437373e6bc571db74208f6cd3376d19a + Author: Jonathan Wakely + Date: Wed Jun 22 19:40:29 2016 +0100 + + [filesystems] Hyphenate POSIX-based and Windows-based + + commit ad4c80452feea841b8a2e29f5fc1e6aacfdeaa2d + Author: Jonathan Wakely + Date: Wed Jun 22 19:35:44 2016 +0100 + + [fs.norm.ref] Remove redundant reference to MAC OS + + commit 535ff921a4c61da91716c9e18d42ffb26cc53c24 + Author: Jonathan Wakely + Date: Wed Jun 22 19:19:09 2016 +0100 + + [meta.rel] Reformat "Type relationship predicates" table + + Adjusted the column widths of the libreqtab3f environment and inserted + line breaks. + + commit 34fae9749c325302b4e659b775224cb28e3b014d + Author: Jonathan Wakely + Date: Wed Jun 22 18:50:08 2016 +0100 + + [meta.trans.sign] Fix formatting in "Other transformation" table + + commit 863cbd1add491eb3cfef66d438f5ca79e3d602f4 + Author: Alisdair Meredith + Date: Thu Jun 9 22:40:42 2016 -0400 + + [meta.trans.other] Reformat Other Transformations table + + This PR applies the change recommended by https://github.com/cplusplus/draft/issues/629. + + So far, I like the change giving the descriptions more room to + breathe, but for come reason the first column has become a + little narrower, which is messing with the format a little. + + Generally, I think this looks like a good fix, but may use a + little more polish to get the presentation just right. + + commit ed0cd287652fbe923373a5628b32f4f8cd90c7f6 + Author: S. B. Tam + Date: Thu Jun 23 01:17:32 2016 +0800 + + [reverse.iter.requirements] Avoid 'global operators' (#442) + + These operator functions are not in the global namespace scope. + + commit ddbb859ab54614b710786cf46f569541edd2fdcd + Author: Thomas Köppe + Date: Wed Jun 22 20:15:34 2016 +0300 + + [strings] Fix spacing around commas + + commit a8ea14bfe285a99f69cbf3b57cd826fb3d03058a + Author: Richard Smith + Date: Wed Jun 22 10:12:18 2016 -0700 + + [global.functions] Replace "global and non-member functions" with less + redundant, but no less accurate, term "non-member functions". + + commit 571412f6aff170a5aab1f7472526b7e9459f556b + Author: Jonathan Wakely + Date: Wed Jun 22 16:06:11 2016 +0100 + + [forward.iterators] Capitalize note + + commit dc7918e42ddf76a5c9299775128ea9d75f960374 + Author: Jonathan Wakely + Date: Wed Jun 22 15:58:41 2016 +0100 + + [lex.key] Move note after table + + commit 28cea19640223d5aa403419813eef0be0371287f + Author: Jonathan Wakely + Date: Wed Jun 22 15:48:26 2016 +0100 + + Fix stray punctuation after notes. + + commit c68346dc2e6dcb912f162bafb9f86c12f8bb3713 + Author: Thomas Köppe + Date: Fri Jun 17 18:27:30 2016 +0100 + + [utilities] Remove std:: from normative wording + + commit 4b58cb2262f38475f726aa52724065df537f40ec + Author: Thomas Köppe + Date: Fri Jun 17 18:22:09 2016 +0100 + + [iterators] Remove std:: from normative wording + + commit 5e827de13e93306778dec7a6933da16acb079e57 + Author: Thomas Köppe + Date: Fri Jun 17 18:22:04 2016 +0100 + + [strings] Remove std:: from normative wording + + commit e0b87fbbe4c2050187ad5b4b1e859a111790fca3 + Author: Thomas Köppe + Date: Thu Jun 16 20:08:25 2016 +0100 + + [Readme] Fix isocpp link for DR submission (#756) + + Fixes #755. + + commit d335c89932b3911b5405dd7ad15bf8530d2e884d + Author: AaronBallman + Date: Thu Jun 16 14:22:21 2016 -0400 + + [dcl.enum], [class.mem] Clarify the definitions for layout-compatible and fix their index entries (#700) + + commit 820626bf19f2df385d91d0d6c31293f136a9573b + Author: Johannes Laire + Date: Mon Jun 13 20:50:08 2016 +0200 + + [basic.lookup] Fix typos + + commit d7ecb6f7e56001d78747ea6f6a9782b704512d4e + Author: Alisdair Meredith + Date: Mon Jun 13 21:37:11 2016 -0400 + + [18,20] Consistent indexing of simple exception types (#750) + + Appply a simple, consistent pattern to the index entries, including + th index of implementation defined behaviors, for the library types + that derive from std::exception. + + In some cases this means adding entries, in others removing extra + nested implementation-defined entries that are redundant since the + addition of the index of implementatio defined behaviors. + + A few cross-references were added or corrected as part of this + process. + + Further work to make the presentation and specification of these + types probably requires LWG issues. In particular, bad_any_cast + is woefully underspecified. + + commit f3a3c85b9957f35ddc7b5290cf8367b2cb78bd0e + Author: Alisdair Meredith + Date: Thu Jun 9 21:02:51 2016 -0400 + + [valarray.sub] Fix error in example code (#746) + + Fixes #160 + + commit 6d3936c3f904622757e84df28852373079822d48 + Author: Richard Smith + Date: Thu Jun 9 14:35:52 2016 -0700 + + [libindex] Rename index entries from "bad_X, bad_X::what, implementation + defined" to "bad_X, what, implementation defined" for consistency. + + Add some missing index entries for class members that are themselves + classes. + + commit 28f8551018cb975b18e3ddf95fed50e679b30c79 + Author: Jonathan Wakely + Date: Thu Jun 9 22:27:33 2016 +0100 + + [bad.cast], [bad.exception] nest index entries consistently (#744) + + commit da7277645a807ccbedd12fda104cbd9b78987eca + Author: Jonathan Wakely + Date: Thu Jun 9 12:54:00 2016 +0100 + + [allocator.adaptor.members] fix index entry for destroy + + commit 05521fa5a364ba59a0eeb080cafb8ba95830aa47 + Author: Alisdair Meredith + Date: Wed Jun 8 19:53:17 2016 -0400 + + [18-28] Fix index entry for constructors + + The preferred way to list constructors in the index is under the + non-code font term 'constructor', but many classes retain old + text that lists the constructor under the class name as the same + class name, in a code font. Worse, there are quite a few classes + that have fallen into a hybrid approach, with both listings, which + can be confusing. This change-set should catch every constructor + indexed in the old style and consistently transform it to the new. + + One additional fix is that allocator_traits mis-indexed the static + member functions 'construct' and 'destroy' as the plain-text + constructor and destructor. This patch correctly indexes them as + their correct name, in a code-font. + + commit e47197014cbef9421b09d2180cab8f37a55658c7 + Author: Alisdair Meredith + Date: Wed Jun 8 23:27:37 2016 -0400 + + [support.runtime] Fix name of stdarg.h in index + + Simple typo where the index (but not the main text) refers + to as . + + commit 87975172ae653b8bdeb6e582a060cd46b91ab377 + Author: Alisdair Meredith + Date: Wed Jun 8 21:19:07 2016 -0400 + + [18-27] Remove tcode from index entries + + Several old index entries use '\tcode' to force a code + font on their sub-entry. This is no longer necessary, + as the LaTeX scripts produce the correct font for an + '\idxcode' entry. However, using '\tcode' inconsistently + will produce duplicate entries, and entries that do not + sort correctly. This change set consistently applies + '\idxcode' in preference to '\tcode' to eliminate the + redundant and mis-sorted entries. + + commit a167f5c7a25e54432218847f5109703ef76876fb + Author: Thomas Köppe + Date: Wed Jun 8 19:14:42 2016 +0100 + + [compatibility] Add compatibility notices for pp-number (#713) + + commit 13b57f74b8b9aac71e4cabe186b16c60670c2c71 + Author: Sergey Zubkov + Date: Thu Jun 2 23:03:43 2016 -0400 + + [unord.req] p12 should refer to key_eq(), not key_equal() + + commit 41340cd5542959085a52449ce5f249534c8314ea + Author: Alisdair Meredith + Date: Wed Jun 8 08:46:33 2016 -0400 + + [time.duration.comparisons] Fix index entry for duration operator< + + The index entry for 'operator<' of the 'duration' class template is + associated with an unknown 'idxl' type, instead of 'durtation'. + + commit ee583454f6f9e5e3c320d0a8e6dc18082ffed07d + Author: Alisdair Meredith + Date: Wed Jun 8 09:14:16 2016 -0400 + + [string.view.comparison] Fix index for basic_string_view operators + + The first issue is that operator<< does not group in the index with + other definitions for operator<<, which use an index key of + operator\shl. + + The second issue is that operator<< was the only operator indexed + under the 'basic_string_view' key, where the precedent fro basic_string + and other types is that the free-function operators are still indexed + under their respective class entry. + + commit 15a68689e8dd9f2ba82f29c37d4fa3e4c9c461ee + Author: Alisdair Meredith + Date: Wed Jun 8 08:35:27 2016 -0400 + + [allocator.adaptor] consolidate memory utilities] + + This patch simply moves the scoped allocator clause to + be adjacent to the other memory and allocator clauses + for a more consistent sub-organization of clause 20. + + The patch looks pretty awful thanks to the diff + algorithm treating it as a lot of interspersed edits, + where in fact is way a single cut/paste for the bulk + of the test (plus a second one-liner for the clause 20 + table of contents). + + commit c8f1863b67ce555c7576faddb50bd8707bfe0bee + Author: Alisdair Meredith + Date: Wed Jun 8 01:35:02 2016 -0400 + + [18-30] Replace typedefs with alias-declarations (#704) + + This set of changes replace (almost) all use of 'typedef' in the library + with a type alias instead: + typedef Original NewName; + -> + using NewName = Original; + + Attention was paid to retaining table-like formatting where present, which + is worth reviewing in case I made idiosyncratic choices. + + Clause 29 [atomic] was specifically ignored, as there is a desire for the + contained code to look as close to a C compatible header as possible. + + commit 2a5d9721aa153e7fcea4ab7ea21333b18dd3d001 + Author: Richard Smith + Date: Tue Jun 7 14:46:52 2016 -0700 + + [pairs.pair] Fix indentation of Remarks: paragrah. + + commit 92c3395bb23f57b9a99d389b3f5aabead337c865 + Author: Jonathan Wakely + Date: Mon Jun 6 14:00:38 2016 +0100 + + [fs.op.permissions] Combine adjacent tcode regions + + commit 256d202e61f4317f30ae839125e714e8192690d4 + Author: Jonathan Wakely + Date: Mon Jun 6 13:55:46 2016 +0100 + + [fs.op.permissions] Escape unary complement operator + + commit deffb9ed5457d4fa5b0fe44d0fd28c1f8c3ab723 + Author: timsong-cpp + Date: Thu Jun 2 15:09:08 2016 -0400 + + [lex.pptoken] fix term + + "preprocessor token" -> "preprocessing token" + + commit a2b62a8c3aa1b334e0506d309b3bfaffd47d0827 + Author: timsong-cpp + Date: Thu Jun 2 12:16:44 2016 -0400 + + [class.path] escape backslash in character literal + + Fixes #731 + + commit 6be63b64af6c2a6cb40ddf76268dd6d5297f5394 + Author: Richard Smith + Date: Tue May 31 10:24:38 2016 -0700 + + [expr] Remove outdated, inaccurate, irrelevant note on the actual + behavior of signed integer overflow on "most existing implementations". diff --git a/papers/n4604.pdf b/papers/n4604.pdf new file mode 100644 index 0000000000..6232872fd6 Binary files /dev/null and b/papers/n4604.pdf differ diff --git a/papers/n4606.pdf b/papers/n4606.pdf new file mode 100644 index 0000000000..10ddb217f8 Binary files /dev/null and b/papers/n4606.pdf differ diff --git a/papers/n4618.pdf b/papers/n4618.pdf new file mode 100644 index 0000000000..935e2d9047 Binary files /dev/null and b/papers/n4618.pdf differ diff --git a/papers/n4619.html b/papers/n4619.html new file mode 100644 index 0000000000..573a677304 --- /dev/null +++ b/papers/n4619.html @@ -0,0 +1,3679 @@ +N4619 +

N4619 Editors' Report -- Working Draft, Standard for Programming Language C++

+ +

2016-11-28
+Richard Smith (editor) (Google Inc)
+Dawn Perchik (co-editor) (Embarcadero Technologies Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to +Jens Maurer and Alisdair Meredith +for performing many large-scale editorial cleanups across the standard.

+ +

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

+ +

New papers

+ +
    +
  • N4619 is this Editors' Report.
  • +
  • N4618 is the current working draft. It replaces N4606.
  • +
+ +

Motions incorporated into committee draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolutions for 5 issues in "Ready" status applied, resolving 6 issues:

+ +
    +
  • 1395 Partial ordering of variadic templates reconsidered
  • +
  • 1825 Partial ordering between variadic and non-variadic function templates (no changes, resolved by 1395)
  • +
  • 1961 Potentially-concurrent actions within a signal handler
  • +
  • 2143 Value-dependency via injected-class-name
  • +
  • 2155 Defining classes and enumerations via using-declarations
  • +
  • 2271 Aliasing this
  • +
+ +

CWG motion 2: Core issue resolutions for 2 issues in "Tentatively Ready" status applied:

+ +
    +
  • 2100 Value-dependent address of static data member of class template
  • +
  • 2094 Trivial copy/move constructor for class with volatile member
  • +
+ +

CWG motion 3: Core issue resolutions for 1 issue applied:

+ +
    +
  • 1343 Sequencing of non-class initialization
  • +
+ +

CWG motion 4: P0522R0 "Matching of template template-arguments excludes compatible templates", resolving 1 issue:

+ +
    +
  • 150 Template template parameters and default arguments
  • +
+ +

CWG motion 5: P0003R5 "Removing deprecated exception specifications", resolving 3 NB comments:

+ +
    +
  • See also LWG motion 20, which applies the same paper
  • +
  • US 18, US 70, GB 43: Adopt P0003R5 to remove dynamic exception specifications
  • +
+ +

CWG motion 6: P0490R0 "Core language changes addressing National Body comments for C++17 CD", resolving 1 issue and 19 NB comments:

+ +
    +
  • US 28: Incorrect definition for principal constructor
  • +
  • US 93: Argument evaluation order when calling an operator function
  • +
  • US 94, GB 13, FI 21: Class template deduction in explicit type conversion using a braced-init-list
  • +
  • US 103: Explicit deduction guides consider default template arguments
  • +
  • GB 5: Definition of template parameter
  • +
  • GB 6: Definition of undefined behavior vs constexpr
  • +
  • GB 19: Missing cv-qualification when materializing a temporary object
  • +
  • GB 20: Decomposition declaration should commit to tuple interpretation early
  • +
  • GB 23: Handlers taking a reference to array or function
  • +
  • GB 25: Imprecise description when terminate is called
  • +
  • GB 26: 'Last' active handler and multithreading
  • +
  • GB 27: Multiple activations of the same exception object
  • +
  • GB 63: Add limit for number of lambda captures
  • +
  • GB 64: Add limit for length of initializer-list
  • +
  • GB 65: Add limit for number of identifiers in decomposition declaration
  • +
  • FI 20: Decomposition declarations with parentheses
  • +
  • RU 1, 253: Why must empty or fully-initialized const objects be initialized?
  • +
+ +

CWG motion 7: P0195R2 "Pack expansions in using-declarations"

+ +

CWG motion 8: P0512R0 "Class template argument deduction NB comments"

+ +
    +
  • US 19: Give explicit deduction guides priority over implicit deduction guides
  • +
  • US 20: T&& in an implicit deduction guide is not always a forwarding reference
  • +
+ +

CWG motion 9 was not approved.

+ +

CWG motion 10 applies to the Modules TS

+ +

CWG motion 11 applies to the Concepts TS

+ +

Core motions added a total of 1 page to Clause 1-16.

+ +

Library working group motions

+ +

LWG motions 1-3 apply to the Library Fundamentals (v2) TS

+ +

LWG motions 4-5 apply to the Ranges TS

+ +

LWG motions 6-7 apply to the Networking TS

+ +

LWG motions 8-9 apply to the Coroutines TS

+ +

LWG motion 10: Library issue resolutions for 1 issues in "Immediate" status applied:

+ +
    +
  • 2770 tuple_size<const T> specialization breaks decomposition declarations
  • +
+ +

LWG motion 11: Library issue resolutions for 64 issues in "Tentatively Ready" status applied:

+ +
    +
  • 2062 Effect contradictions w/o no-throw guarantee of std::function swaps
  • +
  • 2166 Heap property underspecified?
  • +
  • 2221 No formatted output operator for nullptr
  • +
  • 2223 shrink_to_fit effect on iterator validity
  • +
  • 2261 Are containers required to use their pointer type internally?
  • +
  • 2394 locale::name specification unclear — what is implementation-defined?
  • +
  • 2460 LWG issue 2408 and value categories
  • +
  • 2468 Self-move-assignment of library types
  • +
  • 2475 Allow overwriting of std::basic_string terminator with charT() to allow cleaner interoperation with legacy APIs
  • +
  • 2503 multiline option should be added to syntax_option_type
  • +
  • 2510 Tag types should not be DefaultConstructible
  • +
  • 2514 Type traits must not be final
  • +
  • 2519 Iterator operator-= has gratuitous undefined behaviour
  • +
  • 2531 future::get should explicitly state that the shared state is released
  • +
  • 2534 Constrain rvalue stream operators (with normative changes, see below)
  • +
  • 2536 What should <complex.h> do?
  • +
  • 2540 unordered_multimap::insert hint iterator
  • +
  • 2543 not applied, see below
  • +
  • 2544 istreambuf_iterator(basic_streambuf<charT, traits>* s) effects unclear when s is 0
  • +
  • 2556 Wide contract for future::share()
  • +
  • 2562 Consistent total ordering of pointers by comparison functors
  • +
  • 2567 Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits
  • +
  • 2569 conjunction and disjunction requirements are too strict
  • +
  • 2578 Iterator requirements should reference iterator traits
  • +
  • 2584 <regex> ECMAScript IdentityEscape is ambiguous
  • +
  • 2589 match_results can't satisfy the requirements of a container
  • +
  • 2591 std::function's member template target() should not lead to undefined behaviour
  • +
  • 2598 addressof works on temporaries
  • +
  • 2664 operator/ (and other append) semantics not useful if argument has root
  • +
  • 2672 Should is_empty use error_code in its specification?
  • +
  • 2678 std::filesystem enum classes overspecified
  • +
  • 2679 Inconsistent use of "Effects: Equivalent to"
  • +
  • 2680 Add "Equivalent to" to filesystem
  • +
  • 2681 filesystem::copy() cannot copy symlinks
  • +
  • 2686 Why is std::hash specialized for error_code, but not error_condition?
  • +
  • 2694 Application of LWG 436 accidentally deleted definition of "facet"
  • +
  • 2696 Interaction between make_shared and enable_shared_from_this is underspecified
  • +
  • 2699 Missing restriction in [numeric.requirements]
  • +
  • 2712 copy_file(from, to, ...) has a number of unspecified error conditions
  • +
  • 2722 equivalent incorrectly specifies throws clause
  • +
  • 2729 Missing SFINAE on std::pair::operator=
  • +
  • 2732 Questionable specification of path::operator/= and path::append
  • +
  • 2735 std::abs(short), std::abs(signed char) and others should return int instead of double in order to be compatible with C++98 and C
  • +
  • 2736 nullopt_t insufficiently constrained
  • +
  • 2738 is_constructible with void types
  • +
  • 2739 Issue with time_point non-member subtraction with an unsigned duration
  • +
  • 2740 constexpr optional<T>::operator->
  • +
  • 2742 Inconsistent string interface taking string_view
  • +
  • 2744 any's in_place constructors
  • +
  • 2747 Possibly redundant std::move in [alg.foreach]
  • +
  • 2748 swappable traits for optionals
  • +
  • 2749 swappable traits for variants
  • +
  • 2752 Throws: clauses of async and packaged_task are unimplementable
  • +
  • 2753 not applied, see below
  • +
  • 2754 The in_place constructors and emplace functions added by P0032R3 don't require CopyConstructible
  • +
  • 2755 [string.view.io] uses non-existent basic_string_view::to_string function
  • +
  • 2756 optional<T> should 'forward' T's implicit conversions
  • +
  • 2758 std::string{}.assign("ABCDE", 0, 1) is ambiguous
  • +
  • 2759 gcd / lcm and bool
  • +
  • 2760 non-const basic_string::data should not invalidate iterators
  • +
  • 2765 Did LWG 1123 go too far?
  • +
  • 2767 not_fn call_wrapper can form invalid types
  • +
  • 2771 Broken Effects: of some basic_string::compare functions in terms of basic_string_view
  • +
  • 2773 Making std::ignore constexpr
  • +
  • 2777 basic_string_view::copy should use char_traits::copy
  • +
  • 2778 basic_string_view is missing constexpr
  • +
+ +

LWG motion 12: P0426R1 "constexpr for std::char_traits", resolving 2 NB comments:

+ +
    +
  • US 81, RU 4: char_traits operations should be constexpr
  • +
+ +

LWG motion 13: P0403R1 "Literal suffix for basic_string_view", resolving 2 NB comments:

+ +
    +
  • US 80, FI 6: Add user-defined literal suffix for basic_string_view
  • +
+ +

LWG motion 14: P0505R0 "constexpr for <chrono>", resolving 1 NB comment:

+ +
    +
  • GB 50: Make member functions of duration and time_point constexpr
  • +
+ +

LWG motion 15: P0418R2 "Fail or succeed: there is no atomic lattice", resolving 1 issue and 1 NB comment:

+ +
    +
  • CA 16: Merge P0418R1 or similar to resolve LWG 2445
  • +
  • 2445 "Stronger" memory ordering
  • +
+ +

LWG motion 16: P0508R0 "Structured bindings for node_handles", resolving 1 NB comment:

+ +
    +
  • GB 58: Allow decomposition of insert_return_type
  • +
+ +

LWG motion 17: P0503R0 "Correcting library usage of 'literal type'", resolving 3 NB comments:

+ +
    +
  • GB 68: Verify term "literal type" is used appropriately
  • +
  • US 154: Copy constructor of istream_iterator and literal types
  • +
  • US 155: Destructor of istream_iterator and literal types
  • +
+ +

LWG motion 18: Two papers applied, resolving 1 NB comment:

+ + + +

LWG motion 19: P0504R0 "Revisiting in-place tag types for any/optional/variant", resolving 1 NB comment:

+ +
    +
  • CH 3(a): in_place tags prevent perfect forwarding after decay to function
  • +
+ +

LWG motion 20: P0003R5 "Removing deprecated exception specifications", resolving 3 NB comments:

+ +
    +
  • See also CWG motion 5, which applies the same paper
  • +
  • US 18, US 70, GB 43: Adopt P0003R5 to remove dynamic exception specifications
  • +
+ +

LWG motion 21: P0510R0 "Disallowing references, incomplete types, arrays, and empty variants", resolving 12 NB comments:

+ +
    +
  • US 112: Explicitly disallow variant<>
  • +
  • US 115, US 181, FI 22: Remove support for variant<void, ...>
  • +
  • US 116: Remove support for variant<T[N], ...>
  • +
  • US 117: Remove support for variant<T(&)(), ...>
  • +
  • US 120: Remove redundant wording for void elements in variant
  • +
  • CH 3(b): Remove support for variant<T&, ...>
  • +
  • CH 4: Improve support for variant<void, ...>
  • +
  • CH 5: Repair variant<>
  • +
  • CH 6: Clarify behavior for variant<T&, ...>
  • +
  • CH 8: Clarify construction behavior for variant<>
  • +
+ +

LWG motion 22: P0516R0 "Clarify that shared_future's copy operations have wide contracts", resolving 1 NB comment:

+ +
    +
  • GB 62: Give shared_future copy operations a wide contract and noexcept
  • +
+ +

LWG motion 23: P0509R1 "Restrictions on exception handling", resolving 2 NB comments: see below

+ +
    +
  • GB 41: Unclear restrictions on strengthening exception specifications
  • +
  • GB 42: Use of 'should' suggests unintended normative encouragement
  • +
+ +

LWG motion 24: P0502R0 "Throwing out of a parallel algorithm terminates -- but how?", resolving 7 NB comments:

+ +
    +
  • US 15, US 167: Revisit calling terminate in response to an exception from a parallel algorithm
  • +
  • US 16, US 168: Clarify (nondeterministic?) behavior when rethrowing exception from element access function
  • +
  • US 169: Use an exception_list to propagate multiple exceptions from parallel algorithm execution
  • +
  • US 170: Allow for future addition of alternative exception handling mechanisms to parallel algorithms
  • +
  • CA 17: Preserve parallel algorithm exception behavior in CD
  • +
+ +

LWG motion 25: P0517R0 "Make future_error constructible", resolving 1 NB comment:

+ +
    +
  • US 163: Document constructor for future_error
  • +
+ +

LWG motion 26: P0521R0 "shared_ptr use_count/unique", resolving 1 NB comment:

+ +
    +
  • CA 14: use_count needs either synchronization or weaker guarantees
  • +
+ +

LWG motion 27: P0513R0 "Poisoning the hash", resolving 2 issues and 2 NB comment:

+ +
    +
  • FI 15: "Poison" hash<optional<T>> if T is not hashable
  • +
  • GB 69: Reword requirements and remarks for hash<variant<T...>> specialization
  • +
  • 2791 string_views and strings should yield same hash values
  • +
  • 2543 hash support for enums underspecified
  • +
+ +

LWG motion 28: P0067R5 "Elementary string conversions", resolving 1 NB comment:

+ +
    +
  • FI 5: Merge fixed version of P0067
  • +
+ +

LWG motion 29: P0435R1 "LWG issue resolutions for common_type"

+ +

Library motions added a total of 9 pages to Clause 17-30.

+ +

Notable changes to papers as moved

+ +

LWG motion 11

+ +

LWG2534

+ +

The wording change applied here needed to be rebased onto the wording change +applied by LWG2328 as part of 2016-06 LWG Motion 1.

+ +

LWG2328 changes the rvalue ostream extractor to use perfect forwarding, changing from:

+ +
+

+template <class charT, class traits, class T>
+ basic_istream<charT, traits>&
+ operator>>(basic_istream<charT, traits>&& is, T& x); +

+ +

-1- Effects: is >> x

+
+ +

to:

+ +
+

+template <class charT, class traits, class T>
+ basic_istream<charT, traits>&
+ operator>>(basic_istream<charT, traits>&& is, T&& x); +

+ +

-1- Effects: Equivalent to: + +is >> std::forward<T>(x);
+return is; +

+
+ +

LWG2534 adds a matching SFINAE condition, and proposes this wording based on +the standard prior to the application of LWG2328:

+ +
+

-?- Remarks: This function shall not participate in overload resolution unless the expression is >> x is well-formed.

+
+ +

The two LWG issue resolutions have been editorially merged, resulting instead +in the addition of this SFINAE condition:

+ +
+

-?- Remarks: This function shall not participate in overload resolution unless the expression is >> std::forward<T>(x) is well-formed.

+
+ +

LWG2543

+ +

The resolution of +LWG issue 2543 +is made redundant and unnecessary by +LWG motion 27 in +P0513R0, +which applies a more general fix to the same wording. +As a result, LWG2543's resolution has not been applied, +and instead LWG2543 should be marked as resolved by P0513R0.

+ +

LWG2753

+ +

The resolution of +LWG issue 2753 +conflicts with the resolution of +LWG issue 2756 +and has not been applied. +In particular, +LWG 2753 changes the draft to say that the +optional(const optional<T>&) constructor +should not participate in overload resolution +if !is_copy_constructible_v<T>, whereas +LWG 2756 changes the draft to say that the +constructor should be deleted in the same case.

+ +

LWG motion 23

+ +

The wording of this paper intended to apply on top of the wording changes applied by +P0003 (applied by CWG motion 5 and LWG motion 20), +but was not updated to match the latest wording changes from P0003R5, and as a +result, many of its proposed changes are redundant with those applied by P0003R5. +There is no conflict between the intent of the two papers, and both have +been applied.

+ +

Disposition of editorial NB comments on C++ 2017 CD1

+ +

Listed below are draft disposition for all comments that were +filed as editorial in the ISO 14882 CD (2016) NB comments, +p0488r0, +and the late editorial comments in p0489r0. +Except where otherwise noted, these dispositions only represent the current +viewpoint of the Project Editor.

+ +

ES Comments

+ +

ES 3: Accepted, fixed in f6482016.

+ +
    +
  • Example is correct with or without proposed change.
  • +
+ +

US Comments

+ +

US 4: No consensus for change.

+ +
    +
  • While _v forms are generally preferred in library clauses, defining the core +language semantics in terms of a variable template seems to introduce undue +complexity.
  • +
  • CWG concurs with this direction.
  • +
+ +

US 9: Accepted, fixed in 97058f9c.

+ +
    +
  • LWG concurs with this direction.
  • +
+ +

US 11: Accepted with modifications, fixed in 663f1324.

+ +
    +
  • In the reference in paragraph 9, the ::value was removed to match similar specifications.
  • +
+ +

US 12: Accepted, fixed in 0fdcc1ab.

+ +

US 13: Accepted with modifications, fixed by 79974877.

+ +
    +
  • Specifying the value of is_destructible_v<T> within the specification for +is_destructible would be considerably less clear than specifying the value +of is_destructible<T>::value.

  • +
  • Modified resolution: Instead of proposed fix, change Condition for +is_destructible to:

  • +
+ +
+

Condition: Either T is a reference type, or T is a complete object type +for which the expression declval<U&>().~U() is well-formed when treated +as an unevaluated operand (Clause [expr]), where U is +remove_all_extents_t<T>.

+
+ +
    +
  • LWG concurs with this direction.
  • +
+ +

US 26: Accepted, fixed by 85aac089.

+ +

US 27: Accepted, fixed by fb925656.

+ +

US 38: Accepted, fixed by adb0da05.

+ +
    +
  • LWG concurs with this direction.
  • +
+ +

US 39: Accepted, fixed by d47d5ca4.

+ +
    +
  • LWG concurs with this direction.
  • +
+ +

US 41: LWG to handle issue

+ +
    +
  • LWG has deferred a decision on this to Kona.
  • +
+ +

US 42: LWG to handle issue

+ +
    +
  • The suggested resolution contradicts [fs.op.status]/7, which indicates that +pathname resolution does always resolve a symlink. There is no other +specification of how pathname resolution behaves, so the proposed note would +not be justified by normative text.
  • +
  • LWG has deferred a decision on this to Kona.

    + +

    US 47: LWG to handle issue

  • +
  • LWG has deferred a decision on this to Kona.

  • +
+ +

US 50: LWG to handle issue

+ +
    +
  • The proposed change seems valuable, but would be a normative change if the type +is an input iterator type for which decay_t would produce a different type. +The Project Editor would like LWG to consider whether that change is acceptable.
  • +
  • LWG has deferred a decision on this to Kona.
  • +
+ +

US 87: SG1 to handle issue

+ +
    +
  • CWG considers the revised term to be less clear. A compromise term "block with +progress guarantee delegation" (removing the "forward" but retaining the +"guarantee") has been proposed.
  • +
+ +

US 88: Accepted, fixed in 554514cc.

+ +

US 89: Accepted with modifications, fixed in 7e920239, d580a0dd.

+ +
    +
  • "+" in section heading replaced by "and"
  • +
+ +

US 90: Accepted, fixed in 131716c4.

+ +

US 91: Accepted, fixed in 0a344234.

+ +
    +
  • LWG and SG1 concur with the direction of this issue.
  • +
+ +

US 96: Accepted, fixed in e6d9dfff.

+ +

US 97: Duplicate of US 4.

+ +

US 120: Accepted, fixed in a8f966f5.

+ +
    +
  • LWG concurs with this direction.
  • +
+ +

US 133: Accepted, fixed in 71c347ed.

+ +

US 136: Accepted, fixed in 27b46764.

+ +

US 138: No consensus for change.

+ +
    +
  • [func.requires] are requirements on the library, [requirements] are +requirements on the program. [func.requires] does not fit within +[requirements], nor within Clause 17 at all.
  • +
  • The call wrapper terms are not used outside the specified clause (except within +Annex D), so moving them to [definitions] does not seem useful.
  • +
+ +

US 149: No consensus for change.

+ +
    +
  • It is unclear what this comment is referencing. There is no note in 23.3.7.3 +[array.special]/3, and 23.2.1 [container.requirements.general]/9 already +excludes array from its general requirements.
  • +
  • Perhaps the objection is that the semantics of array::swap are never actually +defined anywhere -- do we use swap(a[i], b[i]) to swap elements, or some other +mechanism such as move-assigning via a temporary? -- in which case this omission +does not seem editorial.
  • +
  • LWG concurs with this direction.
  • +
+ +

US 152: LWG to handle issue

+ +
    +
  • This comment is not editorial.
  • +
+ +

US 157: Duplicate of US 91.

+ +

US 158: No consensus for change.

+ +
    +
  • The Project Editor believes that including the description of the <numerics> +header in the "Algorithms" clause instead of the "Numerics" clause would harm +the organization of the standard. +One possible approach would be to rename the "Numerics" subclause to a name +that fits its remaining content, but LWG did not support that approach.
  • +
  • The last sentence of the proposed change for US 166 appears to be intended to +be part of this NB comment instead.
  • +
  • LWG concurs with this direction.
  • +
+ +

US 173: Accepted, fixed in 4fde500c.

+ +

US 179: Accepted with modifications, fixed in 662ddc79.

+ +
    +
  • Renamed section label to +[optional.optional] since optional is not a class, matching [pairs.pair], +[tuple.tuple], [variant.variant].
  • +
  • LWG concurs with this direction.
  • +
+ +

US 180: Accepted with modifications, fixed in e62da07d.

+ +
    +
  • Section label not changed (see US 179).
  • +
  • LWG concurs with this direction.
  • +
+ +

US 182: Accepted, fixed by e229a482.

+ +

GB Comments

+ +

GB 7: Accepted, fixed in fd1204ed.

+ +
    +
  • CWG concurs with the direction of this issue.
  • +
+ +

GB 8: Accepted, fixed in d0e5d065.

+ +
    +
  • CWG concurs with the direction of this issue.
  • +
+ +

GB 11: Accepted, fixed by 4fa3ef43.

+ +

GB 14: Accepted, fixed by 142c82e4.

+ +
    +
  • Not filed as editorial, but will be handled editorially per CWG request.
  • +
  • CWG concurs with the direction of this issue.
  • +
+ +

GB 22: Accepted, fixed by e11da84f.

+ +
    +
  • No type listed for comment, but considered editorial
  • +
  • CWG concurs with the direction of this issue.
  • +
+ +

GB 24: Accepted, fixed by 84cb6529.

+ +
    +
  • CWG concurs with the direction of this issue.
  • +
+ +

GB 29: Accepted, fixed in 6621ef71.

+ +

GB 31: Accepted with modifications, fixed in 32b2de88.

+ +
    +
  • The definition of "character traits" is in 21.2/1. The relevant traits classes +are actually only defined in Clause 21, and the headers in Clause 22 don't even +declare these traits classes (although they do use them). The note is +sufficiently wrong that the best solution appears to be to remove it entirely.
  • +
  • Removed note.
  • +
+ +

GB 32: Accepted, fixed in 94244ddf.

+ +

GB 33: Accepted, fixed in a8d89234.

+ +

GB 34: Accepted, fixed in ddc64ff8.

+ +

GB 37: Accepted, fixed in a5e70c64.

+ +
    +
  • LWG concurs with this direction.
  • +
+ +

GB 43: LWG to handle issue

+ +
    +
  • Resolved by CWG motion 5 / LWG motion 20
  • +
+ +

GB 47: LWG to handle issue

+ +
    +
  • Resolved by LWG motion 18
  • +
+ +

GB 48: Accepted, fixed in 2a96241e.

+ +

GB 52: Accepted, fixed in 65859b3b.

+ +

GB 66: CWG to handle issue

+ +

GB 67: Accepted, fixed in 464156d1.

+ +

RU Comments

+ +

No editorial comments.

+ +

JP Comments

+ +

JP 1: Accepted with modifications, fixed by 942b3fbc.

+ +
    +
  • Additional changes: +
      +
    1. [iostream.objects.overview]/4: add cross-reference to C11 7.21.2, and replace +"C standard" with "C standard library" for consistency
    2. +
    3. [alg.c.library]/2: replace "C standard" with "C standard library" for +consistency
    4. +
  • +
+ +

JP 2: Accepted, fixed by c6552f06.

+ +

JP 3: CWG to handle issue

+ +
    +
  • CWG wishes to investigate alternative wording changes.
  • +
+ +

JP 4: Accepted, fixed by 76308413.

+ +

JP 5: Accepted, fixed by 3e0038a3.

+ +

JP 6, JP 7, JP 14, JP 16, JP 17: No consensus for change.

+ +
    +
  • The proposed change is not correct. The double-quote notation is used for the +canonical type names defined by the algorithm in [dcl.meaning]. In this context,

    + +
    +

    function type T

    +
    + +

    means T, where T is a function type. The suggested alternative of

    + +
    +

    ''function type T''

    +
    + +

    would be meaningless. We could change the wording to

    + +
    +

    ''array of T'' or function type ''T''

    +
    + +

    but the convention is to omit the ''...'' when surrounding a single type name.

  • +
+ +

JP 8: No consensus for change.

+ +
    +
  • The comment is not correct. declarator ; is a valid function declaration when +the declarator declares a constructor, destructor, or conversion function. The +wording is therefore correct as written.
  • +
  • The proposed alternative wording would fail to capture the intent that the +declartor shall be well-formed as a declarator for a complete +function-declaration (not merely a valid function declarator).
  • +
+ +

JP 9: Accepted, fixed by aa74ca01.

+ +

JP 10, JP 11: No consensus for change.

+ +
    +
  • The core language portion of the standard intentionally does not have a +consistent "house style" used in examples, in order to emphasize that the +language itself takes no position on questions of style.
  • +
+ +

JP 12: Accepted with modifications, fixed in b598c94e.

+ +
    +
  • Figure is referenced by number instead of as "below".
  • +
+ +

JP 13: Accepted, fixed in ee809590.

+ +

JP 15: No consensus for change.

+ +
    +
  • 12.5 does not appear to be relevant here. The cross-reference to 5.3.4 fully +describes how the matching deallocation function is determined. The +cross-reference to 3.7.4.2 is just for the term "deallocation function", and +covers both the class-specific and global cases.
  • +
+ +

JP 18: Accepted with modifications, fixed in a8654e86.

+ +
    +
  • Solved by promoting the footnote into a note and splitting the surrounding +paragraph into multiple paragraphs.
  • +
+ +

JP 21: Accepted, fixed in cf099ae6.

+ +

JP 22: Accepted with modifications, fixed in 472a7176.

+ +
    +
  • The wording has been simplified in a different way from that proposed.
  • +
+ +

JP 23: Accepted with modifications.

+ +
    +
  • Each algorithm with a parallel form is now explicitly called out.
  • +
  • Duplicate of US 91.
  • +
+ +

JP 24: Accepted, fixed in 984ef4a1.

+ +

JP 25: LWG to handle issue

+ +
    +
  • This comment is not editorial.
  • +
+ +

JP 26: Accepted, fixed by e229a482.

+ +
    +
  • Duplicate of US 182.
  • +
+ +

CA Comments

+ +

No editorial comments.

+ +

FI Comments

+ +

No editorial comments.

+ +

CH Comments

+ +

No editorial comments.

+ +

Late Comments

+ +

Late 15: Accepted, fixed in 066aba68.

+ +

Late 30: LWG to handle issue

+ +
    +
  • The change appears correct but LWG feedback is requested to ensure that the +s1 == s2 check wasn't trying to check something else beyond the fact that +the paths resolve to the same file system entity.
  • +
+ +

Late 42: Accepted, fixed in 3b22c874.

+ +
    +
  • Of note: the Postcondition is impossible to guarantee, due to the possibility +of a file system race.
  • +
+ +

Notable editorial changes

+ +

The incorrect application of two papers, moved by prior meetings, have been fixed:

+ +
    +
  • In the application of P0035R4, the __STDCPP_DEFAULT_NEW_ALIGNMENT__ macro +was accidentally added to the wrong paragraph of [cpp.predefined], making it +optional instead of mandatory. It has been moved to the correct paragraph.
  • +
  • In the application of P0135R1, wording allowing an rvalue reference to a +function to bind to the result of converting a class object to a function +lvalue via a conversion function was accidentally removed, and has been +restored.
  • +
+ +

C.5 [diff.library] has received an overhaul in this revision of the +working draft. Consistent with the intent of Annex C, it has been updated to +comprehensively list all the known differences between the C standard library +and the corresponding C++ <X.h> stanard library headers. Thanks to Thomas +Köppe for this!

+ +

The index of implementation-defined behavior and index of library names have +also received an overhaul, thanks to a mammoth effort by Alisdair Meredith, and +should now both be complete.

+ +

A number of issues in our LaTeX setup have been resolved by Thomas Köppe, the +result of which is that vertical spacing, particularly between bullets in +bulleted lists and after codeblocks, should now be much more consistent.

+ +

Minor editorial fixes

+ +

A log of all editorial fixes made since N4606 is below:

+ +
commit cb12b08d5bd16ae70119b79c64fbec35437f64ff
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 29 00:44:29 2016 +0000
+
+    [map.modifiers, unord.map.modifiers] Add std:: qualifiers to move and forward, and tidy up overlong lines.
+
+    Also harmonize the itemdecls between ordered and unordered map.
+
+commit 902bf771e78c58037c9571e1b1220f79ee0bb47d
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon Nov 28 18:55:23 2016 -0500
+
+    [unord.req.except] Add missing \tcode for Hash and Pred. (#1141)
+
+commit 2a67c388f84a5ffe788f643d87631b1a76550a4c
+Author: alfmin <a.minarik.1@aon.at>
+Date:   Mon Nov 28 23:49:38 2016 +0100
+
+    [except.spec] missing linebreak (#1140)
+
+    It seems "noecept throw()" is ment to be split as different possibilities
+
+commit 6a7684281253a7c6d2eb7a32ac796eeb4122d4bf
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon Nov 28 15:43:29 2016 -0500
+
+    [cpp.replace] Adjust footnote to clarify that conditionally-supported-directives are directives whether supported or not (#1045)
+
+commit 8d089846de4f60ed939d79c162c5e782fa9a1675
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 20:34:57 2016 +0000
+
+    [tuple.special] Use maths operators
+
+commit 8bdc1417c5dabb5acd4d37ffd0d7b7ce642ee58c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 20:22:33 2016 +0000
+
+    [macros] Reduce whitespace at the end of code blocks (#1135)
+
+commit 41ae590ddd1c5d7d6245d6216eb514d5d84414e3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 20:21:50 2016 +0000
+
+    [tuple.apply] Improve line fit of apply_impl
+
+commit b391f4ab79722708500ebb96edcb1d7c0ef49fa1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 19:54:38 2016 +0000
+
+    [expr.const] Reflow comments to be slightly more economical
+
+commit a31b2df303c7aaa383fdebf21fcf8d6f95159e9a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 19:40:38 2016 +0000
+
+    [complex.ops] Replace inappropriate codeblock with itemdecl; remove some unneeded linebreaks.
+
+commit 26a2e15669bc96dfbad16e4fb5fe915955b83991
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 28 20:33:49 2016 +0100
+
+    [class.union] Clarify in the note that a default member (#1113)
+
+    initializer may prevent a defaulted special member function
+    from being implicitly deleted.
+
+    Fixes #1073.
+
+commit fd2ff5bdafb161b97e4a84cb2a7dffa31a198e3e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 28 20:33:21 2016 +0100
+
+    [basic.lookup.unqual] Rephrase unqualified lookup in a function definition. (#1106)
+
+    Fixes #451.
+
+commit bbf03b48143ea3c2792a22ccda49bff1c53ee094
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 19:26:03 2016 +0000
+
+    [string.classes] Remove unneeded padding newlines around namespace content
+
+commit 089afdbe21788549b458b632c6c39613a28fedff
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 28 19:56:40 2016 +0100
+
+    [class.copy] Introduce three subsections. (#1077)
+
+    Fixes #490.
+
+commit 1864404cabbd5530eca0d9c951eb2f68d21c523d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 18:43:32 2016 +0000
+
+    [basic.life] Fix nesting of example; tidy up list.
+
+commit 53202da4ed4a19a40210091354a2d42d779ebdd3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 18:12:15 2016 +0000
+
+    [lex.charset] Remove unneeded newlines
+
+commit a03fe3f68adb5fd57e5273700f3c0f7a5770e67e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 28 19:09:18 2016 +0100
+
+    [class] Rephrase definition of M(X) used to define a standard-layout class. (#1076)
+
+    Fixes #496.
+
+commit 7ce7c1759414ccf718c5308c17dfeb483f60ad94
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Nov 28 19:01:27 2016 +0100
+
+    [dcl.decl] Turn very large footnote into ordinary note. (#1121)
+
+commit 0e26279b88c3b8b0a09babdeec8418d383f07419
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 17:58:15 2016 +0000
+
+    [basic.scope.class] Break up enumerated list into ordinary paragraphs (#1137)
+
+commit cd3deb891cee5436a64ff9a8f7bb304a4fcc6c00
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 23:02:25 2016 +0100
+
+    'floating-point something', not 'floating point something'
+
+commit a07f03f1f80c4fe8c0702faa9dbbeba409ffc7fc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 21:00:44 2016 +0100
+
+    'nondeterministic', not 'non-deterministic'
+
+commit 850f15f5b97d5e34caa340dd37f4902d035e353f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 20:59:09 2016 +0100
+
+    'non-graphic', not 'nongraphic'
+
+commit 5cf1bc0e8456c28416ed95673523edfde4672f25
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 20:58:08 2016 +0100
+
+    'non-portable', not 'nonportable'
+
+commit 3febb8b9dfe0a9e83a912c6f5fb56687b528261d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 20:57:19 2016 +0100
+
+    'non-member', not 'nonmember' (when referring to a class or namespace member)
+
+commit 61f3c9a294704541f8efe170a80d74873d8210cc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 20:53:04 2016 +0100
+
+    'non-constant', not 'nonconstant'
+
+commit 49111b4c998cf975342d4b96c85a419f531c92b4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 20:51:59 2016 +0100
+
+    'non-const', not 'nonconst'
+
+commit b90068ae889c88b8a14ed126f4323de747f3aa6f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 20:51:17 2016 +0100
+
+    'non-class', not 'nonclass'
+
+commit e53393820b5208457ffef5d08a3b00b59e623345
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 20:49:37 2016 +0100
+
+    'non-abstract', not 'nonabstract' (for classes)
+
+commit 520ebd836da8379e85c43600759b2cde1ca5c58b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 20:48:47 2016 +0100
+
+    'nonzero', not 'non-zero'
+
+commit ab27bb454fb6303fdd44da80b6eba3df2b1feae9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 20:47:23 2016 +0100
+
+    'subobject', not 'sub-object'
+
+commit afb46ec4c8a7435955b748855c112635efebced1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 20:47:09 2016 +0100
+
+    'subexpression', not 'sub-expression'
+
+commit 1f1a2392349f126adec4ea6f3b3fd4cf7632e311
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Mon Nov 28 09:07:48 2016 +0000
+
+    [fpos.operations] Use code font for a type (#1138)
+
+commit 5255e81297bb3aaca6eb2ab1c48a4d224a7fb5b1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 02:25:55 2016 +0000
+
+    [dcl.constexpr] Fix missing full stop
+
+commit ab13956de2d579e16dff696e5146d86f6f459458
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 02:21:07 2016 +0000
+
+    [re.grammar] Change ordered list to unordered list
+
+commit 791e71b1627c8ba4b60e4f7c33553010e435d0f9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 00:04:39 2016 +0000
+
+    [basic] Remove unnecessary and awkward whitespace in and around lists from LaTeX source
+
+commit 49ed4ada682162900a0a9adc02a1a3bbb87d2fa3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 28 00:04:21 2016 +0000
+
+    [intro, lex] Remove unnecessary and awkward whitespace in and around lists from LaTeX source
+
+commit 4d9c28c18416750b0e9bfd44fcfdb0827637b984
+Author: JF Bastien <github@jfbastien.com>
+Date:   Sun Nov 27 18:24:11 2016 -0500
+
+    [pairs.pair, tuple.cnstr] Change 'behaviour' to 'behavior' (#1136)
+
+    Fixes #1128.
+
+commit f3c809c29877f301e3cc8e25c4c184651ab68758
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 27 23:32:47 2016 +0100
+
+    [thread.lock] Extract error conditions from 'Throws' element. (#1122)
+
+    Fixes #458.
+
+commit 87fb2d8482f2fbdcb7b474991094df267fd7cf66
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 27 21:44:20 2016 +0000
+
+    [std, macros, styles] Use 'enumerate' package to make vertical spacing of lists uniform. (#1134)
+
+    This change makes it so that lists are now spaced the same regardless of whether they are preceded by a paragraph break.
+
+commit 866c1451ab2f1f2bef0052abd849b07115d4672c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 27 20:41:11 2016 +0100
+
+    [variant] Use \tcode for type designators, not math mode. (#1125)
+
+    Fixes #1115.
+
+commit 22c396b3ccb46e9224433eb1c7ff761a28b83121
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 27 18:19:49 2016 +0000
+
+    [meta.logical] Fix application of LWG 2567 and add further explicit boolean conversions editorially. (#1133)
+
+    Fixes #1132.
+
+commit d8aab1fbd28d97a467993c2f9c4cb669e025c561
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 27 00:12:11 2016 +0000
+
+    [utilities] Harmonize spacing and placement of qualifiers
+
+    Fixes #127.
+
+commit e864521c22fe29b5a0141114ee57e8c63cb24149
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Nov 26 23:56:25 2016 +0000
+
+    [re, thread] Move 'const' qualifier to the right place.
+
+    Cf. Issue #127.
+
+commit 59c2abecdbc40473221763caef77944ea351d0ca
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Nov 26 23:31:49 2016 +0000
+
+    [depr.default.allocator] Simplify specification of allocator<T>::address.
+
+    Fixes #257.
+
+commit 0b640ed8161937d31f31e251c297b658c559a978
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Nov 26 22:39:15 2016 +0000
+
+    [streambuf.virtuals] Simplify the logic of exposition; remove several unneeded lists (#1111)
+
+commit 44e46e63aaeef375a8521fd93b5db2a40692dbe7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 26 23:37:10 2016 +0100
+
+    [lib] Remove 'std::' prefix from library names. (#1085)
+
+    The standard library specifies that references to its names are assumed to be prefixed by '::std::'. Therefore, we can remove any explicit 'std::' prefixes.
+
+    [iterator.range] was not touched, because it is unclear whether argument-dependent lookup was intended to be disabled here.
+
+    Fixes #431.
+
+commit aff2b2ad7752f1175e455cdc44f23e9d0d9539ed
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 26 23:34:44 2016 +0100
+
+    [filesystems] Do not repeat section title in cross-references to [fs.err.report]. (#1123)
+
+    Fixes #1116.
+
+commit 71aa637c9cd8cea15e9ebc6160ef9208247d5601
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 21 14:20:17 2016 +0100
+
+    [lib] Remove trailing colon in sectioning comments of synopses.
+
+    Fixes #802.
+
+commit 6af539d47d5a122627845c47f31d2e700a2ca3cc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 21 14:17:17 2016 +0100
+
+    [lib] Add missing comma in sectioning comments of synposes.
+
+commit ce32af9de74e953245d920a82f7caf1d8a395988
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 21 13:53:51 2016 +0100
+
+    [meta.type.synop] Remove 'see' in sectioning comments of synopses.
+
+commit 64978c8dfc17b3f89083f861f08cd06b13dc10d9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 26 23:33:06 2016 +0100
+
+    [diff] Miscellaneous fixes. (#1114)
+
+    Consistently end the 'Changes' phrase with a period.
+    Add missing newlines.
+    Remove spurious 'Rationale' item.
+    Fix typos.
+
+    Fixes #214.
+
+commit 2b36c558eeb660bf664b4b5b9f06ae15e19f23e7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 26 20:55:58 2016 +0100
+
+    [temp.deduct.call] Add example involving cv-qualifiers and references. (#1108)
+
+    Fixes #517.
+
+commit 6bca6072e5a605e25ef3f49fb7fb2c2171d07c4c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 26 20:38:41 2016 +0100
+
+    Adjust italics and index entries for 'underlying type'. (#1127)
+
+    Fixes #330.
+
+commit 37073d63e58f74b52fb3b5061c126e18a603d3d2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 26 20:31:54 2016 +0100
+
+    [basic.def.odr] Avoid counting the number of bullets in normative text (#1109)
+
+    Fixes #944.
+
+commit 2e8a867fa6fc9a98fd0044b303ae4567351644fd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 26 20:31:03 2016 +0100
+
+    [sequence.reqmts] Remove redundant 'forward iterator' requirement for sequence containers (#1107)
+
+    Any container is nowadays required to have forward iterators;
+    see the table entries for X::iterator and X::const_iterator in
+    [container.requirements.general].
+
+    Fixes #461.
+
+commit 62956c9b1afd2ce6ddc81378feee28e964eb1b33
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 26 20:29:45 2016 +0100
+
+    [re.matchflag] Remove namespace qualification when mentioning match_flag_type. (#1124)
+
+    Fixes #443.
+
+commit f5c8386fa7ae8e944645e2328b823dc60f1c3499
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 26 20:28:53 2016 +0100
+
+    [thread.lock.shared] Add sectioning comments to synopsis. (#1126)
+
+    Fixes #459.
+
+commit 3930000f039bf64dc451fa5e8ca7376df59a900f
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sun Nov 27 03:28:35 2016 +0800
+
+    [expr.xor, macros] Replace \exor command with \caret; remove \exor definition. (#1131)
+
+commit a23cd78bf34f3dd75820ac4d3985d693a9fedf80
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Nov 24 02:36:01 2016 +0100
+
+    [locale.facet] Don't bother itemizing a single item. (#1118)
+
+commit 345084aa3c8acfb02f21594055ec4211766959ce
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 24 01:01:30 2016 +0000
+
+    [ostream.cons] Fix misnested environments
+
+commit 42cf4c9e926052930bee439b8f3752d60562df06
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 20:49:11 2016 +0100
+
+    [thread.mutex.requirements] Make references to mutex requirements consistent. (#1110)
+
+    Fixes #202.
+
+commit f3d1ffb3eabf2a352564890ea31c3ad996a194b8
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Nov 23 20:07:11 2016 +0100
+
+    [macros, basic, streambuf] Retire 'enumeraten' environment in favour of 'enumerate'. (#1105)
+
+commit c8cef8d7b9b2c9f1aa5c222fe5edfcb44d358420
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 15:57:59 2016 +0100
+
+    [class.conv.fct] Add examples for 'auto' as a conversion-function-id (#1104)
+
+    A trailing return type is ill-formed, a conversion function with a
+    deduced return type is fine, but a conversion function template with a
+    deduced return type is ill-formed.
+
+    Fixes #424.
+
+commit bb03cceade6485044b1ce820f4a4088597dc6f91
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 23 15:20:59 2016 +0100
+
+    [iterator.requirements.general] Use singular when defining 'value type' and 'writeable to' for iterators. (#1101)
+
+    Fixes #698.
+
+commit 19ec46ecfd460bd5c08db7bb9c2252ceaf1f26a2
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Nov 23 11:49:21 2016 +0100
+
+    [basic.scope.class] Add missing whitespace before example. (#1103)
+
+commit da6c19b7adeefe444c01b3045c887068c9c8d122
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 22 22:32:57 2016 +0100
+
+    [quoted.manip] operator>> is not a member of basic_istream. (#1100)
+
+    Fixes #729.
+
+commit eb4f045e6e46d5db001c4344f0667c739ccf3e7e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 22 12:41:16 2016 +0100
+
+    [istream], [ostream] Remove paragraph numbers in cross-references. (#1099)
+
+    Also replace cross-references referring to their own section with 'above'.
+
+    Fixes #702.
+
+commit f8013a4a70859bc3ff6716343c1351e9a0e35490
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 22 10:50:18 2016 +0100
+
+    [reverse.iter.ops] Simplify reverse_iterator operator function declarations by using non-dependent difference_type. (#1098)
+
+    Fixes #831.
+
+commit 02480305fcbb76733a73749aadc31451b0595b75
+Author: hubert-reinterpretcast <hubert-reinterpretcast@users.noreply.github.com>
+Date:   Mon Nov 21 18:12:49 2016 -0500
+
+    [intro.execution] Remove unnecessary function from example (#1084)
+
+commit a5c38698b7a5ecb93af8d6d58e681f997bf0461f
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Mon Nov 21 22:09:51 2016 +0000
+
+    [library] Use \effects etc. when referring to itemdescr elements in introductory text (#1093)
+
+commit 5bb341be09ed6a2cb78be29148597b87388fe9d7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 21 23:05:26 2016 +0100
+
+    [futures.overview], [futures.async] Use 'bitmask type' terminology. (#1095)
+
+    Fixes #826.
+
+commit 1f4bff0667fe6608e6e9cf016e74930cb7650589
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Nov 21 18:32:48 2016 +0100
+
+    [basic.lookup.argdep] Mark definitions of 'associated class/namespace'. (#1092)
+
+commit 93651a2a49cba7c07f99c4e0836572eb84ba6ded
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Mon Nov 21 10:30:40 2016 -0500
+
+    [algorithms, containers, future] Add \tcode
+
+commit e5136d1d0a3495cc1365d141f7d5a42a7c5ed7cb
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Mon Nov 21 10:29:33 2016 -0500
+
+    [dcl.enum, path.modifiers] Fix typos
+
+commit f1afd40ef0e8929391bc39100d0332742cdb5184
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 20 22:23:02 2016 +0100
+
+    Replace \textit{cv} with \cv{} or \cvqual{...} as appopriate. (#1081)
+
+commit 0a22a24110b8a239e283e46959b955ada170fee1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 20 22:21:58 2016 +0100
+
+    [temp.variadic] Move example so that it attaches to the correct paragraph. (#1082)
+
+    Fixes #964.
+
+commit e028d7033c17ddc0fab7467761edf127797ade1d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 20 22:21:33 2016 +0100
+
+    [dcl.ref] Introduce the phrase 'reference collapsing' in a note. (#1083)
+
+    Fixes #546.
+
+commit 5e506593bd5a0ba684bfe387c2b841710133f2fb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 20 21:44:26 2016 +0100
+
+    [associative.reqmts], [unord.req] Fix typo in precondition for the 'merge' member function. (#1080)
+
+    Fixes #919.
+
+commit 24fb65b27efa04ca018e5fa7b4b026fe3c089216
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 20 18:33:38 2016 +0000
+
+    [basic.lookup.classref] Replace unnecessary use of 'indented' with 'codeblock'
+
+commit 580dbaf49aef78c01b7986465432d0167efd5344
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 20 18:20:46 2016 +0000
+
+    [conv.qual, temp.deduct.conv] Improve presentation of conversion sequences
+
+commit a863d2d479b3f643074d6a2bdaf0fc6253d2b7ca
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 20 17:13:24 2016 +0000
+
+    Remove unneeded whitespace in synopses
+
+commit dc3b7515e4c36298301325e5a87bfdd0d9ae43ba
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 20 00:44:57 2016 +0100
+
+    [lib] Spell 'value-initialization' with a hyphen. (#1075)
+
+    Fixes #510.
+
+commit ef536ae539c8feb8ba2e8e4609f6a41188340a66
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 18 19:05:31 2016 +0000
+
+    Remove rogue namespace closing comments
+
+commit 5310973c4b99913f64d2bc11cea8337ea82f521a
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Fri Nov 18 13:59:02 2016 -0500
+
+    [atomics] Clean up indexing (#1038)
+
+    Reverse class/member names in indexlibrarymember macros to be
+    consistent with the prefered style in other clauses.
+
+    Expand in the index several functions that are documented as a
+    pattern-match, such as fetch_add and fetch_sub.
+
+    Replace 'atomic type' for index references with either just 'atomic',
+    'atomic<integral>', or 'atomic<T*>' to follow existing conventions
+    for documenting templates, and to more clearly call out the larger
+    interfaces of the defined specializations.
+
+    Added further indexing for a few items that had missed index entries
+    in the first pass.
+
+commit c2ae996d2f4f5438dcfc0ccffe2420d3954f2f50
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Fri Nov 18 13:24:45 2016 -0500
+
+    [container.requirements.general] Remove redundant Requires (#1044)
+
+    The allocator requirements already require move construction to not throw, so there's no need to repeat it here.
+
+commit 82705c48a465b2e41ab77d59feaf5bc01fc98716
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Fri Nov 18 13:13:38 2016 -0500
+
+    [facet.num.put.virtuals] Provide definition of 'showpoint' and don't apply '&' twice (#1065)
+
+    Fixes #605.
+
+commit 1ed585c3a461cd19fdb0e124e3b96bffe30b846a
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Fri Nov 18 18:12:33 2016 +0000
+
+    [system_error.syn, syserr.compare] Declare all nonmembers in the synopsis (#881)
+
+    Move definitions of less-than operators to [syserr.compare]
+
+    Fixes #880.
+
+commit a15786d31a8a6f8773ed27531b30ad5cd60c906f
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Fri Nov 18 12:44:25 2016 -0500
+
+    [numeric] Order elements correctly (#1070)
+
+    This is the analog to ballot comment JP-21, ordering the
+    Requires/Effects/Returns clauses correctly through clause
+    26.  A couple of re-orderings are deliberately skipped,
+    due to a dependency in the wording, introducing terms in
+    the out-of-order elements.
+
+commit b8e0e09f33d8ac6a1420dc7142c9335351002a48
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Nov 18 18:42:25 2016 +0100
+
+    [lex] Replace \term with \placeholder or \defn as appropriate (#1067)
+
+    Partially addresses #329.
+
+commit 78101400763e9890085d2744a9cc352bf50892a7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Nov 18 18:41:41 2016 +0100
+
+    [variant.assign] Introduce bullets for 'If an exception is thrown...' phrases. (#1069)
+
+    Fixes #822.
+
+commit 2e87ec7fd5bb8b8fa739c0f70435f2992b1972ea
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Nov 18 18:41:16 2016 +0100
+
+    Improve line breaking (resolves some 'Overfull \hbox' warnings) (#1068)
+
+    Partially addresses #693.
+
+commit 7bcebfc762c07fa0e92be4f359afa4110a117720
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Fri Nov 18 00:26:30 2016 +0000
+
+    [container.requirements] Improve punctuation (#1037)
+
+commit 464156d15fc72ba0d908a84a45aa67a57800d940
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Nov 17 16:05:14 2016 -0800
+
+    NB GB-67 (C++17 CD): [charname] [lex.name]: Integrate Annex E contents
+    into description of identifiers.
+
+commit 32df76cdac626ee9b1ef2dc6f07368152f1b536f
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Fri Nov 18 00:04:20 2016 +0000
+
+    [container.requirements] Consistent semicolons in tables (#1034)
+
+commit 6233e94a9bd4b2df3f8e92509dd62b88ed5af9da
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 17 22:32:12 2016 +0000
+
+    [diff.mods.to.definitions] Add entry for 'nullptr_t in stddef.h' (#1056)
+
+commit 4dcde4a386a1db07c6e0730b89ab640c971debfa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 17 23:30:50 2016 +0100
+
+    [expr.rel] Complete the definition of 'compares greater than' (#1015)
+
+    Fixes #435.
+
+commit 752303398df5762fa6b4836c62ec5b0c12d02030
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 17 23:27:51 2016 +0100
+
+    [over.match] 'underlying type' for a reference is undefined (#1013)
+
+    Fixes #391.
+
+commit 5ee7f40a75c39b23cab87ae520a593a5229e6b02
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 17 23:25:48 2016 +0100
+
+    [intro.multithread] add 'std' to standard library names (#1003)
+
+    remove redundant description of same-thread signal handler execution
+    Fixes #285.
+
+commit c9189b97256ae75be317e579ed3eaace3491470d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 17 22:34:29 2016 +0100
+
+    [utilities], [futures.task] Use 'not defined', not 'undefined', to present library declarations of primary templates that are not supposed to have a definition. (#1063)
+
+    Fixes #528.
+
+commit 710d2f87b5437173bdaebb5b374e3ec27becdac0
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Thu Nov 17 20:53:28 2016 +0000
+
+    Use \tcode{true} and \tcode{false} consistently (#977)
+
+commit 0838cf97543b9f8f82cc9efedae960dccb177010
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 17 19:14:52 2016 +0100
+
+    [intro] Replace \term with \placeholder or \defn as appropriate (#1062)
+
+    Partially addresses #329.
+
+commit 6e498da00b2b1a5a448b93f6ad7d5921556cd815
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 17 19:06:35 2016 +0100
+
+    [basic] Replace \term with \defnx as appropriate (#1061)
+
+    Partially addresses #329.
+
+commit 7d68bf4083a94358baf57fa73d43a99446f5f352
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 17 19:01:59 2016 +0100
+
+    [macros.tex et al.] Define a new macro \caret and apply it. (#1050)
+
+    Fixes #205.
+
+commit c3c8081c3487d2a6c653ac06720c78afc6e91a79
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 17 15:59:19 2016 +0000
+
+    [atomics] Further whitespace/italic correction improvements, reflow introductory comments
+
+commit ba75a0e4cc9459dce9da038d77f9d4836aa896e7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 17 15:15:05 2016 +0000
+
+    [atomics] Better use of \placeholders, cleanup.
+
+    Also improves whitespace, italic correction and alignment. I also included a few drive-by fixes where placeholders should have been used but weren't.
+
+    See also #1060.
+
+commit 96b4cd28a2bc75b6f70139c0296be382f180cf8d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 17 15:14:24 2016 +0100
+
+    [diff.cpp03.input.output] Use code font for 'explicit' (#1059)
+
+    Fixes #1019.
+
+commit 2d748554921139b61c1091d3c0184490e364695a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 17 04:06:12 2016 +0000
+
+    [localization] Make punctuation more uniform
+
+commit ac0727870d2e8f0379dedd8ff59b193964294eda
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 17 03:53:42 2016 +0000
+
+    [strings] Make punctuation more uniform
+
+commit 3bcc5f2aaabb423c3c1046f9a7ed9183d2413b22
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 17 03:10:09 2016 +0000
+
+    [utilities] Make punctuation more uniform
+
+commit 0289b1bb4c5d73c67931cae74136b87e9331555a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 17 03:19:11 2016 +0000
+
+    [dcl.type.cv] Remove paragraph break inside intra-paragraph example
+
+commit 73bff4c27ce2125dc8720b5d24fe658a2018a4df
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 17 03:23:46 2016 +0100
+
+    Change 'result is undefined' to 'has undefined behavior' (#1042)
+
+    Fixes #557.
+
+commit e4e0cc63fd63b7dbdd5d8341dc3763f5c2a7f37a
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Thu Nov 17 02:21:59 2016 +0000
+
+    [intro.scope, namespace.udecl, temp.deduct.type] Avoid "and so" (#1030)
+
+    * [intro.scope] Change "and so" to "so"
+
+    * [namespace.udecl] Rephrase a sentence
+
+    * [temp.deduct.type] Change "and so" to "so"
+
+commit a5e70c64564bd9e1924388972465e0ef71513a06
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 16 17:52:41 2016 -0800
+
+    NB GB-37 (C++17 CD): [cstdlib.syn] Move into Clause 18. It doesn't
+    really fit well anywhere, but this is better than including it in Clause
+    17 at least.
+
+commit 65859b3bc7924c78e5a2e8cbcd71106ff23eeb5d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 17 03:13:01 2016 +0100
+
+    NB GB-52 (C++17 CD): [utility] shorten stable names (#1048)
+
+    memory.resource -> mem.res
+    optional.bad_optional_access -> optional.badaccess
+    memory.polymorphic -> mem.poly
+    func.searchers -> func.search
+    ... boyer_moore -> ... bm
+    ... boyer_moore_horspool -> ... bmh
+
+commit 23b1faa028cfb58d0c0df9cf70c044514d931aa7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 17 02:00:21 2016 +0000
+
+    [diff.library] Remove listings of content shared between C and C++. Resolves LWG 2201. (#1052)
+
+    Annex C should only list the *differences* from C. Listing common content is not so useful, and hard to maintain.
+
+    Fixes #1006.
+
+commit aaf284bf6b9b7ebaf4d90ef79a41bbf71b098c5d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 17 00:02:50 2016 +0000
+
+    [pairs.pair] Minor line breaking improvements; avoid overlong lines.
+
+    See #693.
+
+commit ddc64ff8409b855d4989139807ca8c5f41732986
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 16 15:49:25 2016 -0800
+
+    NB GB-34 (C++17 CD): [contents] A macro is not an entity, don't claim it
+    is.
+
+commit 32b2de88091568a0d76f4d94f62af325c69c7485
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 16 15:38:09 2016 -0800
+
+    NB GB-31 (C++17 CD): [defns.traits] Remove apparent definition of term
+    "character traits" in non-normative text. This "definition" was both
+    redundant and incorrect.
+
+commit fd1204eda92479a17463869c6688ae75caf7e67c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 16 15:35:42 2016 -0800
+
+    NB GB-7 (C++17 CD): [intro.object] Add example where multiple array
+    objects could provide storage for the same object.
+
+commit e62da07ddda54b9441f7bd82ba60d196efedbcb9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 16 15:27:49 2016 -0800
+
+    NB US-180 (C++17 CD): [variant.variant] Rename section to "Class
+    template variant".
+
+commit 662ddc7975dafdef16560e6568db506d39c9d6b6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 16 15:23:10 2016 -0800
+
+    NB US-179 (C++17 CD): [optional] Replace "optional for object type" with
+    just "optional object", and likewise rename stable name from
+    [optional.object] to [optional.optional].
+
+commit 4fde500ca5d1c006aa7f24de57573af73f654718
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 16 15:01:52 2016 -0800
+
+    NB US-173 (C++17 CD): [cstdlib.syn] Add 'noexcept' to synopsis to match
+    detailed description of abort, atexit, at_quick_exit, _Exit, quick_exit.
+
+commit b9330baf6b5d3be147e9dd5d3d79b6d601bd04d1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 16 23:58:51 2016 +0100
+
+    [exception] Rephrase to avoid overfull hbox (#1057)
+
+    See #693.
+
+commit 71c347edcd2fc76a1591fff88249ec37985a3770
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 16 14:55:58 2016 -0800
+
+    NB US-133 (C++17 CD): [util.smartptr.shared.const] Remove redundant
+    restatement that this constructor enables shared_from_this. That is
+    already implied by the "equivalent to" wording earlier in the paragraph.
+
+commit e4d752459ed6708d62cbc2646e38ad02ceaa1182
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 16 14:53:29 2016 -0800
+
+    Revert "NB JP-3 (C++17 CD) [basic.stc] Use 'new-expression' instead of 'operator new'"
+
+    CWG have requested that this NB comment be reassigned to them for
+    further rewording, so we're leaving the baseline text alone.
+
+    This reverts commit c455680e44f1dc4a3fa499820eb0a9658700ce45.
+
+commit 35aa4ad6361cdb14e28a50a7452d7a1c98a7ffe8
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 16 19:11:50 2016 +0000
+
+    [cstring.syn] Remove erroneous space
+
+commit 5688dd45fe3c86eddfd7faf9e718417635b94549
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 16 15:48:10 2016 +0000
+
+    [headers] Reflow 'Annex-K' table to fit on the page
+
+commit abbd013dd258df1c50fb4c852105f7ec892b21fd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 16 16:21:09 2016 +0100
+
+    Replace 'run-time' by 'runtime' for consistency. (#1053)
+
+    Fixes #167.
+
+commit 10b453d8c2087823df2cc407d4bfafca0b9b7f6b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 16 15:08:16 2016 +0000
+
+    [headers] Remove erroneous whitespace
+
+commit 0310ba0b7ff38e58041c25466b20ce777d0a8b22
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 16 04:12:18 2016 +0000
+
+    [diff.mods.to.definitions] Harmonize presentation of wchar_t vs char{16,32}_t
+
+    Part of Issue #1006.
+
+commit 9c076ebcb70a80526e6d7675b487738158726707
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 16 03:47:19 2016 +0000
+
+    [diff.mods.to.headers] Explain what happened to meaningless C headers (#1051)
+
+commit 9df9501ad3fa4f91f79e1963382cfa84fc6b251e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 16 02:08:17 2016 +0000
+
+    [cstdlib.syn, csignal.syn] Introduce exposition-only function types with C and C++ language linkage to improve the presentation of C library functions that take callbacks. (#1049)
+
+    This change improves correctness, since we never meant to specify the language linkage of the function names, but only of the callback parameter type.
+
+    Fixes #1002.
+
+commit 74ccbfc749da14a12a2a84e5a94ec17a886349fe
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 16 01:01:13 2016 +0000
+
+    [diff.library] Add entries for stdalign.h, stdbool.h and wchar.h
+
+commit 066aba68cacb2188eee7d8e728ce556e852c822e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 16 00:09:03 2016 +0000
+
+    Late 15 (C++17 CD): [path.gen] Simplify and clarify specification of lexically_relative (#1036)
+
+commit baba3a117601c2a8838572c2358ac8846fc6c937
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 15 22:39:53 2016 +0000
+
+    [depr.str.strstreams] Update cross-references to C synopses
+
+commit 383eb251f0256a0ce766f868d3512b5f4bada18c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 15 22:19:51 2016 +0000
+
+    [cfenv.syn] Fix 'see below' styling
+
+commit 9d81196d42f0fc9b0c3855f95f21140e870b567c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 15 22:02:12 2016 +0000
+
+    [diff.mods.to.definitions] Add new entry for 'static_assert'
+
+commit f2fa62f00922a41a70b1f078d49ea48ad842c288
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 15 18:41:22 2016 +0000
+
+    [diff.library] Update references to the main text.
+
+    The references should have been updated part of P0175.
+
+    Also add "aligned_alloc", which was added in P0063.
+
+    See also Issue #1006.
+
+commit 8b205506a5008596bdbebf0e489c587b03c49e5d
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Nov 14 18:40:08 2016 -0800
+
+    [algorithms.general] Fix typo (add missing "s") (#1047)
+
+commit a5b59b1deaeb9ff88aab1638e05536b8d771d72c
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Nov 14 18:28:59 2016 -0500
+
+    [strings] Index cstd header synopses
+
+    Adds entries to the library index for every cstd... header
+    in the strings clause, pointing to their synopsis.
+
+commit 8868c58632d8da1cc84f676d2659504fee7db31d
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 15 00:12:53 2016 +0100
+
+    [dcl.align] Avoid 'shall' for a requirement on the implementation (#1043)
+
+    Fixes #493.
+
+commit 7fe7d133ec25afcaccf35894928a1572d828f067
+Merge: 72cc920 b95372b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 14 23:11:55 2016 +0000
+
+    [meta] Add cross-references to 'referenceable type' (#1041)
+
+    Fixes #297.
+
+commit 72cc920eed189894cdcb0d0bffb7bd65a177b8c3
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 15 00:11:01 2016 +0100
+
+    Replace 'sub-clause' by 'subclause' (#1040)
+
+    Fixes #497.
+
+commit e0f0311b6cd909da4d1e306d8786636312cac11c
+Merge: 3b22c87 c909c62
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 14 14:41:37 2016 +0000
+
+    [lex.ext] Add hyphen in index entry for 'user-defined literals' (#1039)
+
+    Fixes #628.
+
+commit 3b22c8749c9ac4de17c5554657b7a2209c9a6ca9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 13 19:05:57 2016 -0800
+
+    Late 42 (C++17 CD): [fs.op.file_size] Add missing argument for file_size
+
+commit ff616485ff9a6ddb3d5ec395b3b4aa566a14eb30
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Mon Nov 14 01:59:16 2016 +0000
+
+    Add missing whitespace (#1035)
+
+commit 27b46764e5a7db52bd1d6f21e6c73b26c494918e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 13 14:50:09 2016 -0800
+
+    US NB-136 (C++17 CD): [util.smartptr.shared.cast] Remove repeated
+    specification of the return value of shared pointer casts.
+
+commit a8f966f5fac9517d383eade7af49cff56d25de67
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 13 14:44:54 2016 -0800
+
+    NB US-120 (C++17 CD): [variant.get] Remove redundant requirement that
+    get<cv void> is not used.
+
+commit e6d9dfffc2bd9d9fcf67a273fb3574e3f77ab92b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 13 14:36:14 2016 -0800
+
+    NB US-96 (C++17 CD): [dcl.decomp] Rearrange to number elements from 0
+    instead of from 1.
+
+commit 219538a7be4f3e71f05070d1a52aa7150505e732
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Nov 12 13:45:14 2016 -0800
+
+    [diff.special] Remove incorrect suggestion that volatile-qualified
+    special member may be defaulted.
+
+    Editorially fixes CWG2221.
+
+commit 1a277130f140afc793d7d5a22c93a8a0ea5d10c5
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 23:26:44 2016 +0100
+
+    [string.require] Add note that traits::char_type is the same as charT for basic_string specializations. (#1029)
+
+    Fixes #198.
+
+commit c5b7a6ba233f8bdd434db436a7de3807aebc5fef
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 23:23:57 2016 +0100
+
+    [expr.const] Avoid 'value' of a glvalue in definition of constant expressions. (#1028)
+
+    Fixes #594.
+
+commit b7b273f3d58ee5101ccc5c5a08115c7c1b3413f8
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 16:18:19 2016 +0100
+
+    Harmonize formatting of 'cv' in 'cv-qualified'
+    Fixes #798.
+
+commit a389fa642edf19af885e01740fe20ad0622bc032
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 15:42:50 2016 +0100
+
+    [class.this], [temp.param] 'cv-qualified' should never be \grammarterm'd
+    Fixes #798.
+
+commit cf099ae6b4fccd8a98bf03c46cdd3110d9cd9d69
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 13 16:25:35 2016 +0000
+
+    NB JP-21 (C++17 CD): [algorithms] Order elements consistently
+
+commit d0ea7cf85301da153f7a3288a46647698bfc8d44
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 17:08:36 2016 +0100
+
+    [vector.bool] Excise use of undefined term 'conversion operator' (#1018)
+
+    Fixes #444.
+
+commit 407ecd72a77d73b12a3039aa6bb664b539a7d2a8
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 17:05:09 2016 +0100
+
+    [namespace.udecl] Remove stray newline in grammar production (#1026)
+
+    Fixes #482.
+
+commit fda0b03c9bfb3f75aed513d463205b93f6aa65cc
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 17:01:52 2016 +0100
+
+    [expr.dynamic.cast] Remove redundant specification of value category for a dynamic_cast to reference type. (#1024)
+
+    Fixes #450.
+
+commit 16e5d80b3a53b1581dee8ceeb7f8b01e63926bda
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 16:59:39 2016 +0100
+
+    [type.descriptions.general] Remove reference to undefined library concepts. (#1023)
+
+    Fixes #455.
+
+commit 39f748eaee65d0f71c921c3eb4197117a2f5a5f5
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 16:55:48 2016 +0100
+
+    [atomics] Fix standard-layout requirement for atomic types (#1021)
+
+    Fixes #506.
+
+commit b7de198005c93c493afb6863e22b4b0b74b25185
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 16:49:50 2016 +0100
+
+    [intro.execution] Adjust example to new rules for sequencing of expressions. (#1020)
+
+    Fixes #953.
+
+commit 6d379965896494e80c52930ff3ed15c7733d8c6b
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 07:44:16 2016 +0100
+
+    [containers] 'const iterator' should be 'constant iterator' (#1012)
+
+    Fixes #386.
+
+commit df9f0c83eb865778955700065d722de9fd4966d5
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 06:30:30 2016 +0100
+
+    [dcl.type.simple] Add decltype(auto) to the table giving meaning to simple-type-specifiers. (#1016)
+
+    Fixes #436.
+
+commit 679b0edf34ffb7c849458ce83b9e6159d43ecd10
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 06:25:20 2016 +0100
+
+    [any,thread] Whitespace for template parameter packs (#1014)
+
+    Fixes #430.
+
+commit c1998d328b69d9833869a6f3639d5ebef88972a0
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 06:22:40 2016 +0100
+
+    [class.ctor] Split into numbered paragraphs (#1011)
+
+    Fixes #379.
+
+commit 6ac49c9f39966eae2b268995c11e4032171b2653
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 06:21:44 2016 +0100
+
+    [facet.num.get.virtuals] Clarify 'fails to convert' for empty sequence (#1010)
+
+    Fixes #378.
+
+commit c3d32741fd36b7c821d283b8e0d331d9775bce85
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 06:21:05 2016 +0100
+
+    [numeric.limits.members] Replace 'IEC 559' with 'ISO/IEC/IEEE 60559' (#1009)
+
+    Fixes #343.
+
+commit f7320cd536bc9c124d475001a1e64dbf5bd490fc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Nov 12 21:13:13 2016 -0800
+
+    Capitalize notes that consist of complete sentences.
+
+    Fixes #293.
+
+commit d645b2595590b8b28f1392a3bfcf21d084e4b8bd
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 06:16:36 2016 +0100
+
+    [lib] Modernize closing template brackets (#1008)
+
+    Fixes #342.
+
+commit d6bda0d828241f231c490036103a350a0f4b002d
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 13 06:15:38 2016 +0100
+
+    [dcl.init] Clarify invocation of list-initialization for '= braced-init-list' (#1007)
+
+    Fixes #332.
+
+commit 0a344234c266a90af1644be3e188b71d2f00c84a
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Sat Nov 12 13:09:45 2016 -0800
+
+    NB US-91 (C++17 CD): [algorithm][numeric] Specify all parallel algorithms (#937)
+
+    Also addresses US-157, US-183, JP-23
+
+    Add a copy of the parallel algorithm signature below each corresponding
+    non-parallel signature in the specification for each algorithm in the
+    <algorithm> and <numeric> headers.  This is *mostly* an exercise in
+    copy/paste - however a small subset of algorithms have wording that
+    either refers to the signatures obliquely, requiring a minor wording
+    tweak, or uses the 'Effects: as if ...' formulation, which requires a
+    separate specification for the parallel form to perfectly forward the
+    execution policy.
+
+    A further tweak disambiguates the indexing of the various 'move'
+    functions.
+
+commit 411f35a2aa57681f11018a2914efb19bd9920a6b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Nov 12 11:47:39 2016 -0800
+
+    [expr.call], [expr.static.cast]: Convert one copy of rule on calling a
+    function through a wrong-typed function pointer to a note. Fix
+    incompleteness of the other copy of the rule.
+
+    Editorially fixes CWG2215.
+
+commit 6953b24c045895770f089a1c04da8e46007348af
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Nov 12 09:39:49 2016 -0800
+
+    [special] Clarify that we are using overload resolution to determine the
+    corresponding constructor, not performing overload resolution "on" it
+    (whatever that might mean).
+
+    Editorially fixes CWG 2197.
+
+commit 829560f0630a9f553ee722c50b12ccb7b3f6fa47
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 17:41:09 2016 +0100
+
+    [func.bind.bind] Fix intro sentence for local definitions (#1005)
+
+    Fixes #301.
+
+commit 364c9624cf656a608bf6399f2ffaeec3d98a9dbf
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Sat Nov 12 08:38:50 2016 -0800
+
+    [lex.literal] Consistent indexing of 'prefix' and 'suffix' (#932)
+
+    Provide a consistent indexing of integer, character, and string
+    literals - particularly regarding prefix and suffix entries that
+    were not completely indexed before.
+
+commit e974f194a43ed93f96adfaa1f63b43a42631c248
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 17:36:26 2016 +0100
+
+    [diff.cpp11.lex] Fix example for digit separators (#1004)
+
+    Fixes #306.
+
+commit 337fd045eb3699afb62f17e32c69668f45193b56
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Sat Nov 12 08:34:22 2016 -0800
+
+    [basic.link] Consistent indexing of 'translation unit' (#931)
+
+    [basic.link] consistent indexing of 'translation unit']
+
+    Ensure all definitions of 'translation unit' sort together in the index, with a common spelling of the white-space. Always use the singular form of "translation unit" in the index. Use \defnx when appropriate.
+
+commit 9b37e81ddb0c0fcb5a11b12b1e88d4d70e8da5c0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Nov 12 03:18:40 2016 -0800
+
+    [cpp.cond] Remove stray brace (introduced in a8654e86734a3ca1348c7e4d3de0af703f049af0)
+
+commit 8615adbf8bf8439d3b5eacd62589e2f236c0e18a
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Nov 12 12:15:43 2016 +0100
+
+    Use the "standard library" terms defined in [intro.refs]/2 and [library.general]/1 consistently. (#934)
+
+commit 7c6153d34d067068ec133e04520483ac023346bb
+Author: hubert-reinterpretcast <hubert-reinterpretcast@users.noreply.github.com>
+Date:   Sat Nov 12 02:19:50 2016 -0800
+
+    [expr.reinterpret.cast]: requirement redundant with static_cast: a note it is (#996)
+
+commit 3cc48b76b974a76f09c57d60b2d9ca76b57cfd29
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 08:54:05 2016 +0100
+
+    [lib] Replace 'Postcondition:' by 'Postconditions:'
+
+    Fixes #282.
+
+commit 179eb7045f74e17fe96a464156d0363043fd08c9
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 08:50:53 2016 +0100
+
+    [lib] Replace 'Remark:' by 'Remarks:'
+
+    Fixes #282.
+
+commit fcf5d663cc51306c08bee76f4a1ce5b9d4cf3933
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Sat Nov 12 10:11:20 2016 +0000
+
+    [iostreams] Refer to int values as `nonzero` instead of `true` (#978)
+
+commit 0b5bcd518ac2d64c0a342e79841dec1e8655c93e
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 11:00:53 2016 +0100
+
+    [string.classes] Rename stable names 'string::*' (#999)
+
+commit 7cc8e898486d017babde19b0495f58dd719d104b
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 10:59:30 2016 +0100
+
+    [istream.extractors] Rename stable name 'istream::extractors' (#1001)
+
+    Fixes #271.
+
+commit 947e6a689f859a3e7f16b78d716efbe6a3de402c
+Author: JF Bastien <github@jfbastien.com>
+Date:   Sat Nov 12 01:50:58 2016 -0800
+
+    Index entries for signed integer representations
+
+    * Add index entries for ones' and two's complements
+
+    * Editorial: add 'signed integer representation' index entry
+
+    * Update location of index entry
+
+commit e3774214e4513ab7becad2d78cafde859db913b2
+Author: Gilbert Röhrbein <gilbert@ifsr.de>
+Date:   Sat Nov 12 10:49:11 2016 +0100
+
+    Format references more consistently
+
+    * [re.synopt, string.view.cons, string.view.comparison] table~/ref -> Table~/ref
+    * [expr.new] annex~/ref -> Annex~/ref
+    * [utility.arg.requirements] tables~/ref -> Tables~/ref
+
+commit 6238924fdf1bcbba8b5223df5e35463e83e469b3
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Nov 12 10:47:41 2016 +0100
+
+    Fix lots of see/seealso references, especially regarding operators. (#943)
+
+commit 36a454ac039fc638178f0d1175dc47f3037014b5
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Nov 12 10:30:04 2016 +0100
+
+    [expr.prim.paren] Clarify that parentheses preserve all value categories, not just lvalueness. (#915)
+
+commit 0f15558dd76901fadd53c65774f78296761e45fa
+Author: AaronBallman <aaron@aaronballman.com>
+Date:   Sat Nov 12 04:28:44 2016 -0500
+
+    [expr.call] Use a more idiomatic way to specify the expression has undefined behavior (#898)
+
+commit 112f0da88f7112ba706d76f35b7ca85f0c5e0477
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Sat Nov 12 08:59:37 2016 +0000
+
+    [atomics.order] Remove redundant typedef-name for memory_order (#851)
+
+    * [atomics.order] Remove redundant typedef-name for memory_order
+
+    * [atomics.flag] Remove redundant typedef-name for atomic_flag
+
+commit 67d476ce3c9d47f8f6f5e157fc0340cdf6825a13
+Author: AaronBallman <aaron@aaronballman.com>
+Date:   Sat Nov 12 03:57:58 2016 -0500
+
+    [future.async]p3 Use neither/nor and capitalize sentences properly (#827)
+
+commit fa639c445f70e6f5c065954bfcb182442ad53620
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Sat Nov 12 16:56:35 2016 +0800
+
+    [gram] Change "syntax" to "grammar". (#790)
+
+    Annex A is a summary of grammar, but not only syntactic grammar. Even in contexts without need of grammatical disambiguation, pure syntactically handling (reduction merely based on parsing of the token stream without semantic information) of several context-sensitive constructs (e.g. constant-expression and several kinds of type-id) has already been insufficient. Since the remained difference is acknowledged in the same paragraph, I think my change is also editorial. (On the contrary, ISO C may have more problems because it uses "syntax" everywhere.)
+
+commit 984ef4a18b5892d304d111f3853e12b2ab1670b4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Nov 12 00:20:33 2016 -0800
+
+    NB JP-24 (C++17 CD): [alg.permutations.generators] Separate 'returns' from 'effects'
+
+commit 472a71760200dba263be043d222c83ae53551423
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Nov 12 00:04:51 2016 -0800
+
+    NB JP-22 (C++17 CD): [mismatch] Simplify specification of std::mismatch
+
+commit 25becfcbfba170c8de030a80c81bb1740dbcfecd
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Fri Nov 11 23:24:59 2016 -0800
+
+    [defns.referenceable] Clean up definition text
+
+    Definitions should start with a lower-case letter.  The paragraph
+    defining referenceable erroneously starts with a leading space.
+
+commit 56bfdac1f93b8a877ff24c5d61248623e81fbaad
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 08:21:15 2016 +0100
+
+    [string::compare] Replace 'smallest' by 'smaller' (#998)
+
+    Fixes #270.
+
+commit b6d93f8a67c8d3b1178dba2b551e2529e0d0cc4a
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 08:20:40 2016 +0100
+
+    [string.capacity] Improve max_size() description by copying from string_view (#994)
+
+    Fixes #255.
+
+commit 131716c43342b2f9b7c789289a77ed9126bedfa4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 11 23:14:00 2016 -0800
+
+    NB US-90 (C++17 CD): [algorithms.parallel.exec] Add cross-reference to
+    section describing execution policies.
+
+commit d0e5d065629048c1b279e5f30d111d7fb7a6aedd
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Fri Nov 11 22:50:09 2016 -0800
+
+    NB GB-8 (C++17 CD): [intro.object] Clearer definition for 'complete object' (#991)
+
+commit 5c0f40cae5424a1fe5cb4c720e2ce51e54c67dec
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 07:43:59 2016 +0100
+
+    [alg.reverse] Use ValueSwappable instead of swappable requirement (#993)
+
+    Fixes #210.
+
+commit a8654e86734a3ca1348c7e4d3de0af703f049af0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 22:29:46 2016 -0800
+
+    NB JP-18 (C++17 CD): [cpp.cond] Split up long paragraph and incorporate footnotes as notes
+
+commit 4bcaad233a6bd87c67a905112af48850ab5907a6
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 07:25:16 2016 +0100
+
+    [intro.races] remove redundant constraint on modification order (#990)
+
+    Fixes #159
+
+commit 6621ef71a7de1e5e6b1be26fc7bd8348d0fb6656
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Fri Nov 11 22:13:47 2016 -0800
+
+    NB GB-29 (C++17 CD): [intro.defs] Move definitions of 'block' and 'unblock' to Clause 1
+
+    Move the definitions of block and unblock to the clause 1
+    definitions subclause, rather than the library definitions
+    subclause, as the memory model relies on these terms.
+
+commit 93fd82d142809d0896981851746a281d561412a4
+Author: Bekenn <bekenn@gmail.com>
+Date:   Fri Nov 11 22:05:29 2016 -0800
+
+    Updated required package list. (#986)
+
+commit d0e9ca76ef04eb05e284435e5c6a7bd4b18d6544
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 07:03:37 2016 +0100
+
+    [class.dtor] Add paragraph number (#987)
+
+    Fixes #144.
+
+commit 2a96241e384fa628da8f66013d3aa460a5eb353e
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Fri Nov 11 22:00:29 2016 -0800
+
+    NB GB-48 (C++17 CD): [parallel.execpol.objects] Simplify stable tag (#988)
+
+commit ee809590378c2252b5c4a2b734ccb121211c7e63
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 21:58:47 2016 -0800
+
+    NB JP-13 (C++17 CD): [class.friend] Fix reference to 'inline'
+
+commit 554514cc9508d660cacc7f559c584fdd459b2fb5
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 11 21:57:30 2016 -0800
+
+    NB US-88 (C++17 CD): [execpol.seq] Rename "Sequential" -> "Sequenced"
+
+commit d47d5ca45cdf5ff9a4018f264e917b908511e9e0
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 11 21:45:43 2016 -0800
+
+    NB US-39 (C++17 CD): [fs.def.parent] Remove meaningless note.
+
+commit b598c94e0d1ad9ea17872244315425abceb0702d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 21:45:18 2016 -0800
+
+    NB JP-12 (C++17 CD): [class.mi] Refer to figures by number
+
+commit adb0da05b5b94ce699d232ae68a82d64bea01f02
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 11 21:42:32 2016 -0800
+
+    NB US-38 (C++17 CD): [fs.def.ntcts] Remove redundant definition.
+
+commit fb925656add6108e0f32b049ae4e907d8a6b9e5e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 11 21:36:17 2016 -0800
+
+    NB US-27 (C++17 CD): [class.base.init] Fix overly-wide space between
+    "side" and "effect" in comment in example.
+
+commit 27de65a2a57ac52ad3a3b96dc87cdbe9a56a6d00
+Author: jensmaurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 12 06:33:23 2016 +0100
+
+    [dcl.init] Don't mention expression where braced-init-list may appear (#985)
+
+    fixes #150
+
+commit a8d8923438bbf02bd9295c741d61caccd94861f2
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Fri Nov 11 21:27:07 2016 -0800
+
+    NB GB-33 (C++17 CD): [objects.within.classes] Change 'external behavior' to 'observable' (#983)
+
+commit 94244ddf94a7e18f06f15d723ca5f07fc24a20c4
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Fri Nov 11 21:25:52 2016 -0800
+
+    NB GB-32 (C++17 CD): [defns.additional] Make this clause a note in [definitions] (#982)
+
+commit 85aac089757a373d9a675442de93dbad5babce8f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 11 21:14:35 2016 -0800
+
+    NB US-26 (C++17 CD): [class.ctor] Demote redundant "either no parameters
+    or [all parameters have a property]" to a parenthetical.
+
+commit 799748771a59b234812d5f02144de8716a640458
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 11 21:04:27 2016 -0800
+
+    NB US-13 (C++17 CD): [meta.unary.prop] Rephrase Condition for
+    `is_destructible` to avoid use of `is_destructible<T>::value`.
+
+commit aa74ca01a5f6fd9a720e91a49da505f031778144
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 21:02:42 2016 -0800
+
+    NB JP-9 (C++17 CD): [dcl.fct.def.delete] Fix reference to 'inline'
+
+commit 3e0038a38c202ae4929c2e49128a35587c4620f7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 20:58:30 2016 -0800
+
+    NB JP-5 (C++17 CD): [conv.rval] Add missing semicolon
+
+commit 76308413b7c7937afd0009cf3ecc7de36ec10781
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 20:55:37 2016 -0800
+
+    NB JP-4 (C++17): [basic.life] Fix example to say '*pb', not '&pb'
+
+commit 4fa3ef43e2f4d9562d75b1c5ec28d2037719cb97
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Fri Nov 11 20:51:57 2016 -0800
+
+    NB GB-11 (C++17 CD): [intro.memory] Add a footnote referencing CHAR_BIT
+
+commit c455680e44f1dc4a3fa499820eb0a9658700ce45
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 20:49:36 2016 -0800
+
+    NB JP-3 (C++17 CD) [basic.stc] Use 'new-expression' instead of 'operator new'
+
+commit 0fdcc1abfb5ef6e055979d5b84f14fded6f40f6c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 11 20:37:58 2016 -0800
+
+    NB US-12 (C++17 CD): [meta.unary.prop] Remove (subtly) redundant uses of
+    bool_constant from definition of is_signed and is_unsigned.
+
+commit 942b3fbcc808f867f55efda94b0f2d88d35d3d6d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 20:36:03 2016 -0800
+
+    NB JP-1 (C++17 CD): Update reference to C11
+
+commit c663f13244de12123744d9da5ae0dc0cd8cc480c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 11 20:30:37 2016 -0800
+
+    NB US-11 (C++17 CD): [meta.unary.prop] Replace
+    has_unique_object_representations<T>::value with _v form in one place
+    and remove ::value in another, for consistency with similar
+    specifications.
+
+commit 97058f9cc925cd9a9e818545cad4e1c198d714cb
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 11 20:24:17 2016 -0800
+
+    NB US-9 (C++17 CD): [meta.type.synop] Add missing definition of
+    has_unique_object_representations_v.
+
+commit f6482016438b7d64a6eaf1c8b250d6911143e06f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 20:24:20 2016 -0800
+
+    NB ES-3 (C++17 CD): [depr.static_constexpr] Change redeclaration to use 'constexpr' instead of 'const'
+
+commit 1beaf17ee237b344aba87966ef7d4f31eea72cb8
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 11 19:38:00 2016 -0800
+
+    [meta.rel] Massage Comments for is_base_of to avoid unclear phrasing.
+
+commit f8f56a38f6636aa159acb91ab3c3bf2896482179
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Nov 10 15:14:29 2016 -0800
+
+    [diff.expr] Document that C++ does not support decrement on bool, unlike C.
+
+    Fixes CWG2184
+
+commit 84cb65298006c22747d31aeb983fd3d93b6ae43b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 7 16:48:19 2016 -0800
+
+    NB GB-24 (C++17 CD): [except.handle] Fix incorrect example.
+
+commit e11da84f160df97ab05f84ee5920d3f26b501ea8
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 7 16:45:14 2016 -0800
+
+    NB GB-22 (C++17 CD): Replace references to "raise" with "throw" when
+    describing exceptions.
+
+commit 142c82e43359be3e707f84e078386424ddedc41d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 7 16:30:46 2016 -0800
+
+    NB GB-14 (C++17 CD): [expr.pre.inc] Remove vestigial references to increment of bool.
+
+commit 79e9ee94150a4db7297cc2017ceb9604dd2e2fce
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 11:32:47 2016 -0800
+
+    [basic.start.static] Add missing full stop.
+
+commit 46aff72f86855f4daf6f3b3c588133160aec6de1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 08:19:41 2016 -0800
+
+    [cpp.replace] Style 'replacement-list' as a grammar term
+
+commit bb4ed4cd557735f4077a4fca13aa56db44da5bbf
+Author: W-E-Brown <webrown.cpp@gmail.com>
+Date:   Thu Nov 10 21:13:41 2016 -0800
+
+    Use decay_t<> rather than typename decay<>::type. (#979)
+
+commit d580a0dd6ecee0d727432a7d12cf933ede89cfee
+Author: JF Bastien <github@jfbastien.com>
+Date:   Thu Nov 10 10:11:17 2016 -0800
+
+    [execpol] Remove '+' from policy name (#976)
+
+commit b3e942c6be2fc8742e6d394af8d5588a44f90d2a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 10 09:38:02 2016 -0800
+
+    [stringstream] Fix section reference
+
+commit 2fc3bc0fefc2584da857ca758af0bea006652fab
+Author: Antony Polukhin <antoshkka@gmail.com>
+Date:   Thu Nov 10 21:29:40 2016 +0400
+
+    [sf.cmath] Make headings and stable names more accurate
+
+    Editorial issues found by Matwey V. Kornilov from Sternberg Astronomical Institute, Lomonosov Moscow State University, Russia:
+
+    * Clause "Associated Legendre polynomials" is wrongly entitled. "Associated Legendre functions" would be more appropriate here. Though "Associated Legendre polynomials" term is sometimes used it is formally wrong term. A polynomial (by definition) is a particular kind of function which can be represented using only finite number of additions, multiplications and exponentiations to a non-negative power, i.e. in canonical form of `SUM(AiX^i)`. Obviously, some of P^m_l are not polynomials. For instance, for m=l=1, `P11(x) == sqrt(1 − x*x)` is not representable as `SUM(AiX^i)`. See for reference: Abramowitz and Stegun, Chapter 8 "Legendre Functions".
+
+    * "[sf.cmath.cyl_bessel]" is a bad name for the tag. "[sf.cmath.cyl_bessel]" sounds like "Bessel functions" and when people say "Bessel functions" they usually mean Jν from [sf.cmath.cyl_bessel_j]. Replaced "[sf.cmath.cyl_bessel]" with "[sf.cmath.cyl_bessel_i]".
+
+    * "[sf.cmath.cyl_bessel_k]" misses references to "[sf.cmath.cyl_bessel_j]" and "[sf.cmath.cyl_neumann]" in the "See also" section. In [sf.cmath.cyl_bessel_j] Jv(x) is defined, in [sf.cmath.cyl_neumann] Nν(x) is defined - both of them are used in the "Returns:" section of the [sf.cmath.cyl_bessel_k].
+
+commit 68f0e28c14c6ba36a31eeeb1e9fb4517a46dec87
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 9 14:11:12 2016 -0800
+
+    [re] Whitespace fixes
+
+commit 7f692bf13dbedef3885103e6dd9030f6445d3960
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Nov 9 22:48:15 2016 +0100
+
+    [re.syn] Synchronize regex_constants synopsis with [re.const]. (#866)
+
+commit 7e920239a94d21b5790ca2255ee932401db7c67a
+Author: JF Bastien <github@jfbastien.com>
+Date:   Wed Nov 9 12:05:17 2016 -0800
+
+    [execpol] rename "vec" to "unsequenced" (#972)
+
+    Update missed updates.
+
+commit 24d17974f117806dc9c1b23755c56e618c913ad4
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Wed Nov 9 15:03:12 2016 -0500
+
+    Improve comment formatting; includes replacing "file" with "translation unit"
+
+commit 4b774369b64f99f7285834f80e12bb9ddaee3e01
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 9 10:49:22 2016 -0800
+
+    [expr] Remove accidental whitespace
+
+commit 2b7778ced56508aacf61cacefd0db1fb1372b6d4
+Author: Daniel James <daniel@calamity.org.uk>
+Date:   Mon Nov 7 12:33:53 2016 +0000
+
+    [associative.reqmts] Add missing qualification to 'mapped_type' (#968)
+
+commit 0824b215fdec5adba25b10203aaf0d3e4b2ccb7b
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Wed Nov 2 09:35:05 2016 +0800
+
+    [syntax] Use a different example (#959)
+
+commit 37239df14fccaea1a2350533b86b669efbe9530c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 2 01:34:41 2016 +0000
+
+    [stmt.iter] Remove superfluous and incorrect note (#960)
+
+    The original note has become obsolete with commit f40f23d2c9b8de9eeeb781c4e7b90d056750535f.
+
+commit 430c40d56ee4a5756f441304512d2d04757ccbec
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Nov 1 21:33:13 2016 -0400
+
+    [iterator.synopsis] Add specialization specified in [iterator.traits]/3 (#961)
+
+commit d5df57b34cd9bd8a72062e0d5d9627cfb772d670
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Nov 1 21:31:32 2016 -0400
+
+    [iterator.range]/1 List <string_view>, specified in [string.view.synop]/1 (#962)
+
+commit ab40db0ba572e4ccb7007dab026791654d31832b
+Author: Koichi Murase <myoga.murase@gmail.com>
+Date:   Sat Oct 22 23:20:20 2016 +0900
+
+    [temp.alias, rand.dist.pois.exp] Fix typos (#956)
+
+    * [temp.alias]/1 Fix typo
+
+    a alias template -> an alias template
+
+    * [rand.dist.pois.exp]/3 Fix typo
+
+     a exponential_distribution object -> an exponential_distribution object
+
+commit 21e3a325074aede246c1ace0a64bec0945627355
+Author: Koichi Murase <myoga.murase@gmail.com>
+Date:   Sat Oct 22 20:09:16 2016 +0900
+
+    [streambuf.virt.put] Fix typo (#955)
+
+    Is is unspecified ... -> It is unspecified ...
+
+commit 77c0632d1514b00d04d076880df57879cde3dd5a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Oct 20 16:10:34 2016 -0700
+
+    [dcl.init.aggr] Replace incorrect "anonymous bit-fields" with "unnamed
+    bit-fields". Move restriction that only non-static data members are
+    aggregate elements into the definition of aggregate elements, and demote
+    the other occurrence of this rule to a note.
+
+    Due to an obviously-accidental wording oversight, the previous
+    formulation technically included member functions and member classes as
+    aggregate elements. This reformulation avoids that problem.
+
+commit 9fe6aa53d88c77da9d64d152b8f577e153a15d3a
+Author: Zhihao Yuan <lichray@gmail.com>
+Date:   Tue Oct 18 12:52:21 2016 -0500
+
+    [stmt.stmt] use grammar term "brace-or-equal-initializer" in condition rather than expanding it into two productions
+
+commit 0b1495bb47d86d81724bc7d2627da15ed9db9c49
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Oct 17 02:28:19 2016 +0200
+
+    [basic, class.this, algorithms] Remove parentheses around references. (#949)
+
+commit b30a619cc000039c40f24b3f73a40813d10c9919
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Oct 13 15:36:07 2016 +0200
+
+    [class.conv.fct] Add missing 'the'. (#950)
+
+commit cae0f6d14a666dc983129f7f6c6b7597a932d7c0
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Oct 13 13:38:20 2016 +0200
+
+    [basic, stmt, dcl.dcl] Move surrounding punctuation out of \grammarterm arguments. (#948)
+
+commit 0b92ee326552cab2d0274573183da9acd3dc0832
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Oct 13 12:14:45 2016 +0200
+
+    [expr.reinterpret.cast] Remove unwanted whitespace after \indextext. (#947)
+
+commit 7cd154a00385fa398f528e0c04737f60b040f73d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Oct 10 11:10:36 2016 -0700
+
+    [dcl.type] Fix poor phrasing -- it's not appropriate to restrict the
+    defining-type-specifiers that can appear in a type-specifier-seq, since
+    type-specifier-seqs contain type-specifiers, not defining-type-specifiers.
+
+commit e1e874d361e9bd2f54b79fae61888e573cae898c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Oct 7 17:11:13 2016 +0100
+
+    [algorithms.parallel.exec] Add hyphenation hints to impldef index entry
+
+commit 763eb317a94d1e801157b02fc60750338d4d15dd
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Oct 7 17:01:04 2016 +0100
+
+    [rand.device] Rephrase index entry for impldef behaviour to be easier to compose
+
+commit e69f16e7f6c418109ee36c12bf5b5b1b1086ac37
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Oct 7 16:49:34 2016 +0100
+
+    [string::copy] Remove duplicate \pnum
+
+commit c6552f06c8e35020718d5bd211f7cbeef96ea1f3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Oct 6 01:53:39 2016 +0100
+
+    [basic.def.odr] Update references to [dcl.inline]
+
+commit 3d807a2cf2b617804c7042b9594d0b6cc9d6fbbf
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Oct 5 23:10:06 2016 +0100
+
+    Fix comment typo in .travis.yml
+
+commit b071e45d1f53b7c4d363ea96b8493e2155262886
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Mon Oct 3 15:37:01 2016 +0100
+
+    [input.iterators] Fix formatting of parentheses and p. (#912)
+
+    Fixes #457
+
+commit 865ed277b20341bcc6073d3cb3ba59e4fcabd95c
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Oct 3 16:32:32 2016 +0200
+
+    [class, class.derived, special] Write space in 'access control' consistently in index keys. (#942)
+
+commit 5625f78108fea82e6e0348f9455e1267b6f6a40d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Sep 29 19:13:40 2016 -0700
+
+    [cpp.predefined] Fix misapplication of P0035R4: the macro
+    __STDCPP_DEFAULT_NEW_ALIGNMENT__ should be listed in the first paragraph
+    of [cpp.predefined] (macros that the implementation is required to
+    provide), not in the second paragraph (macros that the implementation
+    conditionally defines).
+
+commit 4b2a5e599e82edb5b077e7a664e61eb54dc00b37
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Sep 28 06:28:19 2016 +0200
+
+    [extern.names] Use \tcode when referring to namespace std. (#941)
+
+commit 15a0972b4cb1b0bb21e1ef1dd6a292bdfd799be4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Sep 27 18:26:33 2016 +0100
+
+    [deque] Fix index entries
+
+commit 1b5edf959ef6b2a66fada4e381a3e1c652f329a9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Sep 27 16:07:19 2016 +0100
+
+    [generalindex] Fix misnested multipage index ranges
+
+commit b7bf4fa94b934049cb4ad53de8ea40744539b742
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Sep 27 15:18:25 2016 +0100
+
+    [thread.decaycopy] Format index entry for DECAY_COPY correctly and add a library index entry
+
+commit cb197a9ab4aeac754e483a07766f37cd8655aeaa
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Sep 27 15:01:54 2016 +0100
+
+    [expr, except] Clean up index entry for terminate, unexpected
+
+commit 00b162ba76a5623439b8fee2dba465684483717b
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Sep 27 00:24:28 2016 +0200
+
+    [cpp.predefined] Make description for __cplusplus non-redundant and consistent with rest. (#868)
+
+commit 9a27ccdbe8b15ce278b5bfbbccb118b00fd9ae34
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Sep 26 20:14:00 2016 +0100
+
+    [time.duration.nonmember] Add missing \tcode (#936)
+
+commit 92bf827cd2f4d4e58c68c434856b568776bc810f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Sep 26 19:52:27 2016 +0100
+
+    [time.syn] Format whitespace more consistently with the rest of the WD (#935)
+
+commit b3f00ef6a963bbbcfc18d56e96f0c59a806b3fdf
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Sep 26 14:36:19 2016 +0200
+
+    [depr.istrstream.cons] Add missing constructor. (#878)
+
+commit 61c3a7507d8558e14987d820a4198df846d61b29
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Sep 26 01:32:45 2016 +0100
+
+    [rand] Format "i.e." and "e.g." consistently
+
+commit 5b1d1cb4649e35e351fa897fcae02f6830b972f1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 25 21:06:43 2016 +0100
+
+    [any] Add parameter name for initializer_list<U>
+
+commit 8ff7ef110391d56327434ab7aebf9a2622eb7941
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 25 20:24:12 2016 +0100
+
+    [tables] Remove extraneous braces that make code in tables index and space differently
+
+commit 38b972645ff94a48f2e96367ae75d31ce57770a8
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 25 19:44:21 2016 +0100
+
+    [re] Fix typo in index ("transform_primary")
+
+commit 70c56d53378082d2e7d41a866c25c697921cd9ee
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Sep 25 20:49:54 2016 +0200
+
+    [futures.promise] Add missing 'noexcept' for swap itemdecl. (#889)
+
+commit 6ced9532d2d93409a5278335ede966ef095d7c45
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Sep 25 20:37:26 2016 +0200
+
+    [class.local, facet.num.{get,put}.virtuals, temp.expl.spec] Remove stray whitespace. (#907)
+
+commit 11ba3a041b1aad927fba1e717cfd1a3e95eb5d23
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Sep 25 20:36:26 2016 +0200
+
+    [facet.num.put.virtuals] Fix grammar: determining -> determine. (#908)
+
+commit 0c671278864c492782f057b2c39e7f51c43b5c77
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Sun Sep 25 11:34:23 2016 -0700
+
+    [dcl.type.simple] Consistent indexing of "type specifier" (#929)
+
+    The main index for type specifiers was split in two, due to
+    alternate spellings as 'type specifier' and 'type~specifier'.
+    Consistently use the latter, as it was the dominant form.
+
+commit 05c8373f19741a1d19942b95e8e4bd1a3ae34246
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Sun Sep 25 11:29:09 2016 -0700
+
+    [index] Consistent indexing of "name hiding" (#933)
+
+    Ensure all index references to name hiding use the same whitespace character.
+
+commit 24af7d897bd168f08cfc4ae48ae743e61357a401
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sat Sep 24 12:10:41 2016 +0100
+
+    [associative.reqmts] [unord.req] Fix "pointed to by to" typos
+
+commit d5a02cebd5b393f52896b362e436d3c42c4af310
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Sep 8 20:52:34 2016 -0400
+
+    [meta] Add index entries for each type trait
+
+    Create an index entry for each row in the type traits tables,
+    indexing the corresping trait.  Where a trait is defined outside
+    the table, add a second index reference to the latter.  This
+    causes an annoying duplication, as the current software sees the
+    index entry inside the table as in some way NOT the same as the
+    entry outside the table.
+
+    Disambiguate the is_empty function from the filesystem library,
+    and the is_empty trait.  The issue for is_signed being a trait
+    and a member of numberic_limits resolves itself.
+
+commit 8fabb00d310c879b4912d983bb4e4198242814ce
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Fri Sep 23 15:59:39 2016 -0700
+
+    [function.objects] Use formal Returns: clause for std functors (#909)
+
+    Revise presentation of all functors in clauses 20.14.(5-8) to use a
+    formal Returns: clause, consistent with the conventions laid out in
+    clause 17, rather than ad-hoc presentation lacking any of the
+    recognised markers.
+
+    This turned into a substantial re-render.  In order to break up a
+    wall of code with occasional normative text, I have introduced a
+    subsection for each class.  Under each new subsection, I collect
+    the primary class template and the 'diamond' specialization, which
+    were previously separated by the intervening classes.
+
+commit f797a8c32980beb1c29144f53e6a6f332c32aeef
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Fri Sep 23 15:52:47 2016 -0700
+
+    [whole standard] Audit index of implementation-defined behavior (#899)
+
+    * Audit index of implementation-defined behavior
+
+    Review all uses of the terms 'implementation-defined' and
+    'implementation defined' in the standard, and replace with
+    \impldef entries in the index of implementation defined
+    behavior where appropriate.
+
+    Clean up some older index entries that did not have a clear
+    reference, and appear to predate the index of implementation
+    defined behavior being added by Pete Becker for C++11.
+
+    Changes may appear more disruptive than in practice, due to
+    word-wrapping reflowing a paragraph or two in the doc source,
+    but not on the rendered pdf.
+
+commit c1f3535f90a7d545ec1cbf1884ba5da6738023d3
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Thu Sep 22 20:43:54 2016 +0100
+
+    [container.node] Move sub-clause to after [sequence.reqmts] (#850)
+
+commit f295171dc9860ca3a4df9fdb2e8ea32932c2782a
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Thu Sep 22 12:27:46 2016 -0700
+
+    [thread.once] Move struct once_flag defintion into corresponding subclause (#920)
+
+    By convention, unless the whole specification of the class is in the
+    header synopsis (typically a tag type) the class should be forward
+    declared in the synopsis.  The class definition for once_flag is moved
+    to 30.4.4 [thread.once].
+
+commit fcf439e935e445b2f185e7aa51925e859640b4e7
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Thu Sep 22 12:24:22 2016 -0700
+
+    [thread] Index review clause 30 (#901)
+
+    * turn around indexlibraryname uses
+
+    * [thread] Review of library index
+
+    This review handles several topic related to the index of library names:
+        apply indexlibrarymember for all member functions other than constructors/destructors
+        consistent ordering of indexlibrarymember{identifier}{class-name}
+        every index macro has a trailing % to avoid accidental whitespace
+        ensure headers are indexed with synopsis
+        ensure every itemdecl has a library index entry
+        index every class definition
+
+commit 7067fd1ff9a50a0f98a132c1c1b409a94649ec09
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Thu Sep 22 12:19:52 2016 -0700
+
+    [depr, exception.syn] Consistently move deprecated declarations to Annex D (#900)
+
+    This change moves the deprecated declarations in the <exception>
+    header to Annex D, in a manner consistent with the library pattern
+    of fully specifying deprecated components and names in the deprecation
+    annex.
+
+    Then apply consistent wording across the library parts of the annex
+    describing how non-deprecated headers introduce the deprecated extensions.
+
+    Finally, ensure that the deprecated extensions to standard headers are
+    indexed as part of that standard header.
+
+commit 5126c2b681f7508e306b1b2469da9c76c9a7fc52
+Author: Jason Merrill <jason.merrill@gmail.com>
+Date:   Wed Sep 21 12:01:27 2016 -0400
+
+    [new.delete.array] Add missing []. (#924)
+
+commit f43f6966e63ba0dffb7dbf0809f481834ae51370
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Wed Sep 21 16:59:12 2016 +0100
+
+    [iterator.iterators] Remove unmatched parenthesis, formatting (#926)
+
+    * [iterator.iterators] Remove unmatched parenthesis
+
+    * [iterators] Add missing \tcode{}
+
+commit e229a482fd89f62e629893283eccb258c518a7c7
+Author: Agustín Bergé <k@fusionfenix.com>
+Date:   Thu Sep 15 23:40:59 2016 +0200
+
+    [inner.product] Fix typo (#925)
+
+commit 0f1335487001f480b79e2ca156bbef9bbf6ae1ba
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Sep 12 20:11:02 2016 +0200
+
+    [class.base.init] Remove stray indentation in codeblock. (#923)
+
+commit 4df5774eb1e26246fa09684e74ca0a56ba35b385
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Thu Sep 8 18:45:06 2016 -0400
+
+    [thread.lock.shared] Apply conventional indent to shared_lock class definition (#921)
+
+    The convention appears to be no blank lines between the opening
+    of the enclosing namespace, and the class defintion; a two-space
+    indent for everything inside the namespace; and no comment on
+    closing brace of the namespace.
+
+commit 6f16e580b9ab1ca6abcaa525f15881e9d40f761c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Sep 8 11:14:40 2016 +0100
+
+    [cstdio.syn] Add missing 'std'
+
+commit 3c01650257905276393ad520ea6afb1d77de2b87
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Thu Sep 8 06:10:30 2016 -0400
+
+    [lex.phases] Index and xref raw string literals (#902)
+
+    Add a cross-reference on the reversion of universal characters in raw string
+    literals, as it is far from clear that [lex.pptoken] is the place to look
+    for this rule, which is not spelled out clearly in the phase1/phase2 rules.
+    Remove a confusing pair of parentheses as it was not clear if the intent
+    was to make the parenthetical a note, which we have a better way to render,
+    or normative.  Given the requirement that universal characters behave
+    consistently, this seems normative, rather than a note.
+
+    Index raw string literals, which appear to be entirely lacking from the
+    main index.
+
+commit edadb9b1ebece68c75602bc8e61db6e34f41f0a1
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Sep 6 13:59:56 2016 -0700
+
+    [dcl.type.auto.deduct] Correct ill-formed expression 'void{}' to the
+    intended 'void()'.
+
+commit feca861da4becdddbcc86d3704cbde9bb139a108
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Tue Aug 30 16:12:02 2016 -0700
+
+    [class.path][path.member][path.itr] Rename expos member 'pathname' to 'pathstring' to reduce confusion
+
+commit 1a9d0120502097c64660da7c20e40c9d5ee392c5
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Aug 30 15:37:36 2016 +0100
+
+    [fs.op.exists] Move after [fs.op.equivalent]
+
+commit 258642f6bb3a39416ffcdc880fe662ab7a28dea2
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Tue Aug 30 10:12:26 2016 -0400
+
+    [optional.object.ctor] Use injected class names (#910)
+
+    Remove redundant template parameters and use injected names instead.
+
+commit ff52ca99722eea9b5510ae174d8d00470c1ae7a2
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Wed Aug 24 11:06:08 2016 -0400
+
+    [intro.progress] fix typo: guaranteees -> guarantees (#906)
+
+commit e90dfda4d1cc70a098c4e2cc8da701557df5438d
+Merge: 2d706e1 91393aa
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Mon Aug 15 14:37:13 2016 +0100
+
+    Merge pull request #884 from timsong-cpp/this_fixes
+
+    Remove redundant `this->` in library specification
+
+commit 2d706e100d9fa081b12c206998d700d293a9ecd5
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Aug 14 11:44:50 2016 +0100
+
+    [declval] Move example outside the \itemdescr and into its own, numbered paragraph.
+
+commit 68f8ea755f2b69df03bcb6f39280c521380ac5c8
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Thu Aug 11 17:59:28 2016 -0400
+
+    [depr] Review of library index (#883)
+
+    This review handles several topic related to the index of library names:
+        apply indexlibrarymember for all member functions other than constructors/destructors
+        consistent ordering of indexlibrarymember{identifier}{class-name}
+        every index macro has a trailing % to avoid accidental whitespace
+        ensure headers are indexed with synopsis
+        ensure every itemdecl has a library index entry
+        index all of the adaptable function typedef-names
+
+commit 4f2a90541f5692ca80741064ba3eacbbb80416fa
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Aug 10 23:14:54 2016 +0100
+
+    [cstdlib.syn] Add missing extern-C/C++ overloads for at_exit, at_quick_exit (#890)
+
+commit 0acba3bc62de2811b88a5d0f83d8fb24b2a73d69
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Aug 10 12:50:46 2016 -0700
+
+    [intro.execution] Delete now-incorrect example: arguments to a function
+    call are now indeterminately-sequenced, not unsequenced.
+
+commit a9031702d79c69130b23a5d85f923119449f988e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Aug 9 15:56:28 2016 -0700
+
+    [basic.def.odr] Add missing "potential results of" in one case in the
+    recursive definition of the set of potential results.
+
+    This definition is intended to be a recursive formulation that produces
+    a set of id-expressions, as explained in the introductory sentence, so
+    it's clear that we were just missing the recursion in one bullet rather
+    than trying to terminate the recursion early in this case.
+
+commit fa624a64b11fb8fd5ea9e7a7905c570f912cb79f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Aug 9 11:49:09 2016 -0700
+
+    [class.copy] Fix example to take into account guaranteed copy elision,
+    and add an example where we need both stages of overload resolution when
+    handling "return local_variable;".
+
+commit 361aa966ea5b92640245479c8221032ae408960f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Aug 8 16:40:13 2016 -0700
+
+    [diff.decl] Replace undefined term "compilation unit" with the intended
+    "translation unit". In passing, fix awkward grammar.
+
+commit 2ab1a393049185df9e33c87992a4f012f03483da
+Merge: 0a08f81 7d5762b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 8 11:29:51 2016 +0100
+
+    Merge pull request #891 from tkoeppe/alisdair27
+
+    Editorial review of Clause 27 [input.output]
+
+commit 0a08f8141a376c7468162f5aee40683a36c32129
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Aug 7 01:34:54 2016 +0200
+
+    [set.cons, multiset.cons] Specify correct constructed type and add missing \tcode. (#896)
+
+commit 29aac16a1dbb03c87c4c10a7e68115083abe6cd8
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Aug 6 21:07:50 2016 +0200
+
+    [util.smartptr.getdeleter] Remove broken 'std:' qualification on addressof. (#895)
+
+commit a96b6ef50687115b686d9f92d1eefa3ea97e0836
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Aug 6 11:46:46 2016 +0200
+
+    [thread.thread.id] Consistently use an lvalue reference for operator<<'s first parameter. (#885)
+
+commit a31763b4c335ef4236c997aa7e4e4eb319ea29ea
+Author: W-E-Brown <webrown.cpp@gmail.com>
+Date:   Sat Aug 6 04:45:27 2016 -0500
+
+    g/special math functions/s//mathematical special functions/ (#886)
+
+    There's nothing special about the math; mathematicians have long termed these functions as "special functions".  Because C++ also uses "special functions" as a different term of art (referring to copy c'tors, d'tors, etc.), we disambiguate by prefixing "mathematical".
+
+commit dabf1c4f5798a2f9ea1a01ce8913ceaefbc9f643
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Aug 6 11:42:00 2016 +0200
+
+    [container.requirements.general] Use proper environment for note. (#887)
+
+commit 643e755e90038354e02ea4ae345d125f2d2dbd09
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Aug 6 00:51:16 2016 +0200
+
+    [associative.reqmts] Add missing line break. (#888)
+
+commit 912f5f2b73417eab6626faa4a0f7658b99199c29
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Aug 5 11:10:19 2016 +0200
+
+    [temp.deduct.call] Don't nest paragraphs inside itemizations. (#882)
+
+commit ef0ec0f79c5627795d344c766342d1e94837ee8a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Aug 4 17:04:37 2016 +0100
+
+    [memory.resource.private] Resolve LWG 2701 editorially
+
+commit 28781eab2d228df9e03128e39ee279342608685f
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Aug 3 20:13:53 2016 +0200
+
+    [depr.strstreambuf.cons] Remove stray period in footnote. (#875)
+
+commit 7eafafe82f7e4574c1c688473d308662da8f042c
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Aug 3 19:58:21 2016 +0200
+
+    [depr.strstreambuf.cons] Don't use an itemdecl and index entry for a mere use of setg. (#876)
+
+commit 91836d9b51db2203d711cca71592532fb0aa82c5
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Aug 3 19:55:50 2016 +0200
+
+    [depr.strstreambuf.virtuals] Fix typo: (unsigned char*)gnext -> (unsigned char)*gnext. (#877)
+
+commit cc06e4902f30df049020173e2e9ad21857b73722
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Wed Aug 3 01:50:52 2016 +0800
+
+    Fix incorrect use of \idxhdr (#874)
+
+commit 010a27bcd4d27a34d5e1efe9994b9373a29186cb
+Author: Zhihao Yuan <lichray@gmail.com>
+Date:   Tue Aug 2 09:54:49 2016 -0500
+
+    [meta.unary.cat] Use core term non-union class type (#873)
+
+commit e790562a1a709af2314bcbfb03a0b299ac19e7d3
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Aug 1 11:44:44 2016 +0200
+
+    [dcl.attr.deprecated, depr.ostream.members] Fix trailing whitespace in \tcode. (#870)
+
+commit 7bf13851fdd815170f22757b2f35ac9e331b6330
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Aug 1 10:03:49 2016 +0200
+
+    [depr.strstream.dest] Move rdbuf() to [depr.strstream.oper]. (#871)
+
+commit 52b41647a32908bda1d9b3d39d1973621895b822
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Jul 30 23:14:30 2016 +0200
+
+    [depr.{i,o}strstream.cons] Remove stray parentheses. (#869)
+
+commit 2738a070e85770ced228b4dda67efddc3b1d8598
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Jul 28 19:48:10 2016 +0200
+
+    [re.traits] Remove excessive newlines from codeblocks. (#867)
+
+commit 64eb87ec2e0ace621c9dfb08d4da381ed4ec0c2e
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Jul 28 15:33:16 2016 +0200
+
+    [re.traits] Remove excessive parentheses in "Returns:" element. (#865)
+
+commit 5b99768ea828ffddbee490d20140f423f9bc8bcf
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Jul 28 15:21:12 2016 +0200
+
+    [special, strings, localization, numerics] Add missing trailing periods in footnotes. (#863)
+
+commit 15b80e2756635b1a0aa45e476d2f321fe160da3b
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Jul 28 14:41:46 2016 +0200
+
+    [re.tokiter.incr] Add missing \pnum for "Returns:" element. (#864)
+
+commit 277eb59b0b92a4431f1217f50e96b196a0c967f1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jul 28 13:17:24 2016 +0100
+
+    [memory.general] Update outdated references
+
+commit 418c0e380ec04e25f0000ea5216dccde311bddaa
+Merge: cd3e040 63e697f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jul 27 19:03:46 2016 +0300
+
+    Merge pull request #861 from tkoeppe/index_review
+
+    Review of library index entries. Thanks to @AlisdairM for all the work!
+
+commit cd3e040699bc46b2d68de2c2977cf3656baf2bee
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Jul 23 12:39:18 2016 +0200
+
+    [basic, memory, time] Use \impldef consistently. (#852)
+
+commit c65dd97b6d030ffbaa3208c98ded4acb4eb805ed
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 23 02:28:15 2016 +0100
+
+    [impldef] Improve hyphenation in index
+
+commit af8b1fdd633161a26d193311369da5ecfa1e7a59
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 23 02:20:09 2016 +0100
+
+    [macros,impldef] Collate \tcode in- and outside listings
+
+commit 298a9ceb62275d37964ca99e4e6224ba6d78da46
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jul 22 12:33:55 2016 +0100
+
+    [diff.cpp11.basic] Fix return type of operator new
+
+commit fbb0e94a7722b57631bedbe19332696bc121f889
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Jul 22 04:48:18 2016 +0200
+
+    [numeric.ops.gcd] Don't format "that" as code in note. (#848)
+
+commit 6dc0d72393c44542c6b859c49f4cc3a158ad1fa0
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Jul 22 00:40:47 2016 +0200
+
+    [path.generic.obs] Escape backslash in string literal in example. (#846) (#846)
+
+commit e4748e244fa3d58f232e086c7ad14a6f8550573e
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Jul 22 00:01:52 2016 +0200
+
+    [file_status.obs] Remove stray \begin{itemdecl}. (#847)
+
+commit 29b3ff36affa37f62e15d73b4838453f0b079ea4
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Jul 21 21:18:45 2016 +0200
+
+    [temp.deduct.call] Avoid line wrap in long comment. (#845)
+
+commit 6b82a23fc4433c704e0837d34ebe880c6408a09c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jul 21 17:44:57 2016 +0100
+
+    [util.smartptr.getdeleter] Add missing \tcode
+
+commit 65289796ef503fd291ae5eed8d45a2aac0c25032
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jul 21 13:52:27 2016 +0300
+
+    [support,utilities] More uses of \indexlibrarymember (#841)
+
+commit acd3ef208f35c4289a029887e39da9f1dd507378
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Jul 20 17:45:58 2016 -0700
+
+    [optional.object.observe] Add missing constexpr to detailed description of optional::value_or(U&&) &&
+
+    This constexpr specifier was present in the `<optional>` synopsis, but omitted from the detailed specification in [optional.object.observe].
+
+commit 6145c73c3706618a383c093274d3ed3d0564b134
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jul 21 01:05:38 2016 +0300
+
+    [impldef] Collate index correctly (#834)
+
+commit 153f8118833920df2e99e7356b434c8c3b0b27f7
+Author: bogdan <bogdan_iordanescu@yahoo.com>
+Date:   Wed Jul 20 22:23:32 2016 +0300
+
+    [dcl.init.ref] Add missing \tcode (#838)
+
+commit acbb19a62d8f8ddbef118572b748e9fc587b0450
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Wed Jul 20 16:38:37 2016 +0100
+
+    [hardware.interference] Use itemdecl instead of codeblock (#836)
+
+commit 6927a933fd5c777f19f33498a6a43608f4ce5555
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Jul 18 14:07:51 2016 -0700
+
+    [headers] Fix typo in "<memory_resource>" (#833)
+
+commit b8894ed3d6362868f326cacb5c46b9f691e5446b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 18 23:07:51 2016 +0300
+
+    [gram] Use 'extract' package for grammar summary (#816)
+
+commit a10b517ae0384ca21a7b3178d71a55c5315f66e1
+Author: bogdan <bogdan_iordanescu@yahoo.com>
+Date:   Mon Jul 18 21:32:25 2016 +0300
+
+    [dcl.init.ref] Add back function lvalues to [dcl.init.ref]/5.2.1.2 (#832)
+
+    Restore some words accidentally removed in the application of P0135R1 to the working draft.
+
+commit 9d9e41779db2661ae54e10c06303a3b62fc3d3eb
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Mon Jul 18 10:16:24 2016 +0100
+
+    [diagnostics] Consistently escape newlines in index entries in Clause 19 (#829)
+
+    This change has no visual effect and is not strictly necessary, but it makes our use of index commands more consistent and uniform.
+
+commit 7be4a057201f03eb7199f3ddca81a737bd1558ec
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 15 10:42:05 2016 -0700
+
+    [reduce] Fix invasion of the right margin.
+
+commit f8580e91438915e33dc421a671984b97045d199e
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Fri Jul 15 21:16:24 2016 +0800
+
+    [diff.basic] Improve clarity of "const implies inline" compatibility note (#789)
+
+    Though Annex C is informative, it's better to keep the terminology similar to normative text, which is easier to refer.
+
+commit c040e66e61322b3962c92cff9595c6affdd3a736
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Jul 15 06:46:05 2016 +0800
+
+    [path.type.cvt] remove redundant word (#828)
+
+    Remove the second "method" in "The method of conversion method is unspecified."
+
+commit d0fa6a619a194a152b3689a0cce1b1ff6ebcb75e
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Wed Jul 13 16:12:52 2016 +0100
+
+    [support] Improve index entries for clause 18 (#823)
+
+    Fix a couple of mis-indexed operators, and add index entries
+    for a few missing functions, most notably the new launder
+    function.
+
+commit 2b6ef6b8b7576fcf56970ca4df4575522ee88a57
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jul 13 12:14:05 2016 +0100
+
+    [strings] Break line in table caption better
+
+commit 4973a225a8969cee8f7752074b194bde1d1abf90
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Tue Jul 12 23:11:47 2016 +0100
+
+    [input.output] Index all member functions in clause 27 (#820)
+
+    Index member functions in Clause 27
+
diff --git a/papers/n4619.md b/papers/n4619.md new file mode 100644 index 0000000000..2c79b5b4f4 --- /dev/null +++ b/papers/n4619.md @@ -0,0 +1,3396 @@ +# N4619 Editors' Report -- Working Draft, Standard for Programming Language C++ + +2016-11-28 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Embarcadero Technologies Inc) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Special thanks to +Jens Maurer and Alisdair Meredith +for performing many large-scale editorial cleanups across the standard. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * N4619 is this Editors' Report. + * [N4618](http://wg21.link/n4618) is the current working draft. It replaces [N4606](http://wg21.link/n4606). + +## Motions incorporated into committee draft + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p0519r0) for 5 issues in "Ready" status applied, resolving 6 issues: + + * [1395](http://wg21.link/cwg1395) Partial ordering of variadic templates reconsidered + * [1825](http://wg21.link/cwg1825) Partial ordering between variadic and non-variadic function templates (no changes, resolved by 1395) + * [1961](http://wg21.link/cwg1961) Potentially-concurrent actions within a signal handler + * [2143](http://wg21.link/cwg2143) Value-dependency via injected-class-name + * [2155](http://wg21.link/cwg2155) Defining classes and enumerations via *using-declaration*s + * [2271](http://wg21.link/cwg2271) Aliasing `this` + +CWG motion 2: [Core issue resolutions](http://wg21.link/p0520r0) for 2 issues in "Tentatively Ready" status applied: + + * [2100](http://wg21.link/cwg2100) Value-dependent address of static data member of class template + * [2094](http://wg21.link/cwg2094) Trivial copy/move constructor for class with volatile member + +CWG motion 3: [Core issue resolutions](http://wg21.link/p0507r0) for 1 issue applied: + + * [1343](http://wg21.link/cwg1343) Sequencing of non-class initialization + +CWG motion 4: [P0522R0 "Matching of template template-arguments excludes compatible templates"](http://wg21.link/p0283r2), resolving 1 issue: + + * [150](http://wg21.link/cwg150) Template template parameters and default arguments + +CWG motion 5: [P0003R5 "Removing deprecated exception specifications"](http://wg21.link/p0003r5), resolving 3 NB comments: + + * See also LWG motion 20, which applies the same paper + * US 18, US 70, GB 43: Adopt P0003R5 to remove dynamic exception specifications + +CWG motion 6: [P0490R0 "Core language changes addressing National Body comments for C++17 CD"](http://wg21.link/p0490r0), resolving 1 issue and 19 NB comments: + + * US 28: Incorrect definition for principal constructor + * US 93: Argument evaluation order when calling an operator function + * US 94, GB 13, FI 21: Class template deduction in explicit type conversion using a *braced-init-list* + * US 103: Explicit deduction guides consider default template arguments + * GB 5: Definition of template parameter + * GB 6: Definition of undefined behavior vs constexpr + * GB 19: Missing cv-qualification when materializing a temporary object + * GB 20: Decomposition declaration should commit to tuple interpretation early + * GB 23: Handlers taking a reference to array or function + * GB 25: Imprecise description when `terminate` is called + * GB 26: 'Last' active handler and multithreading + * GB 27: Multiple activations of the same exception object + * GB 63: Add limit for number of lambda captures + * GB 64: Add limit for length of *initializer-list* + * GB 65: Add limit for number of *identifier*s in decomposition declaration + * FI 20: Decomposition declarations with parentheses + * RU 1, [253](http://wg21.link/cwg253): Why must empty or fully-initialized const objects be initialized? + +CWG motion 7: [P0195R2 "Pack expansions in *using-declaration*s"](http://wg21.link/p0195r2) + +CWG motion 8: [P0512R0 "Class template argument deduction NB comments"](http://wg21.link/p0512r0) + + * US 19: Give explicit deduction guides priority over implicit deduction guides + * US 20: `T&&` in an implicit deduction guide is not always a forwarding reference + +CWG motion 9 was not approved. + +CWG motion 10 applies to the Modules TS + +CWG motion 11 applies to the Concepts TS + +Core motions added a total of 1 page to Clause 1-16. + +### Library working group motions + +LWG motions 1-3 apply to the Library Fundamentals (v2) TS + +LWG motions 4-5 apply to the Ranges TS + +LWG motions 6-7 apply to the Networking TS + +LWG motions 8-9 apply to the Coroutines TS + +LWG motion 10: [Library issue resolutions](http://wg21.link/p0304r1) for 1 issues in "Immediate" status applied: + + * [2770](http://wg21.link/lwg2770) `tuple_size` specialization breaks decomposition declarations + +LWG motion 11: [Library issue resolutions](http://wg21.link/p0165r3) for 64 issues in "Tentatively Ready" status applied: + + * [2062](http://wg21.link/lwg2062) Effect contradictions w/o no-throw guarantee of `std::function` swaps + * [2166](http://wg21.link/lwg2166) Heap property underspecified? + * [2221](http://wg21.link/lwg2221) No formatted output operator for `nullptr` + * [2223](http://wg21.link/lwg2223) `shrink_to_fit` effect on iterator validity + * [2261](http://wg21.link/lwg2261) Are containers required to use their `pointer` type internally? + * [2394](http://wg21.link/lwg2394) `locale::name` specification unclear — what is implementation-defined? + * [2460](http://wg21.link/lwg2460) LWG issue 2408 and value categories + * [2468](http://wg21.link/lwg2468) Self-move-assignment of library types + * [2475](http://wg21.link/lwg2475) Allow overwriting of `std::basic_string` terminator with `charT()` to allow cleaner interoperation with legacy APIs + * [2503](http://wg21.link/lwg2503) `multiline` option should be added to `syntax_option_type` + * [2510](http://wg21.link/lwg2510) Tag types should not be `DefaultConstructible` + * [2514](http://wg21.link/lwg2514) Type traits must not be `final` + * [2519](http://wg21.link/lwg2519) Iterator `operator-=` has gratuitous undefined behaviour + * [2531](http://wg21.link/lwg2531) `future::get` should explicitly state that the shared state is released + * [2534](http://wg21.link/lwg2534) Constrain rvalue stream operators **(with normative changes, see below)** + * [2536](http://wg21.link/lwg2536) What should `` do? + * [2540](http://wg21.link/lwg2540) `unordered_multimap::insert` hint iterator + * **[2543](http://wg21.link/lwg2543) not applied, see below** + * [2544](http://wg21.link/lwg2544) `istreambuf_iterator(basic_streambuf* s)` effects unclear when `s` is `0` + * [2556](http://wg21.link/lwg2556) Wide contract for `future::share()` + * [2562](http://wg21.link/lwg2562) Consistent total ordering of pointers by comparison functors + * [2567](http://wg21.link/lwg2567) Specification of logical operator traits uses `BaseCharacteristic`, which is defined only for `UnaryTypeTraits` and `BinaryTypeTraits` + * [2569](http://wg21.link/lwg2569) `conjunction` and `disjunction` requirements are too strict + * [2578](http://wg21.link/lwg2578) Iterator requirements should reference iterator traits + * [2584](http://wg21.link/lwg2584) `` ECMAScript `IdentityEscape` is ambiguous + * [2589](http://wg21.link/lwg2589) `match_results` can't satisfy the requirements of a container + * [2591](http://wg21.link/lwg2591) `std::function`'s member template `target()` should not lead to undefined behaviour + * [2598](http://wg21.link/lwg2598) `addressof` works on temporaries + * [2664](http://wg21.link/lwg2664) `operator/` (and other append) semantics not useful if argument has root + * [2672](http://wg21.link/lwg2672) Should `is_empty` use `error_code` in its specification? + * [2678](http://wg21.link/lwg2678) `std::filesystem` `enum class`es overspecified + * [2679](http://wg21.link/lwg2679) Inconsistent use of "*Effects:* Equivalent to" + * [2680](http://wg21.link/lwg2680) Add "Equivalent to" to filesystem + * [2681](http://wg21.link/lwg2681) `filesystem::copy()` cannot copy symlinks + * [2686](http://wg21.link/lwg2686) Why is `std::hash` specialized for `error_code`, but not `error_condition`? + * [2694](http://wg21.link/lwg2694) Application of LWG 436 accidentally deleted definition of "facet" + * [2696](http://wg21.link/lwg2696) Interaction between `make_shared` and `enable_shared_from_this` is underspecified + * [2699](http://wg21.link/lwg2699) Missing restriction in [numeric.requirements] + * [2712](http://wg21.link/lwg2712) `copy_file(from, to, ...)` has a number of unspecified error conditions + * [2722](http://wg21.link/lwg2722) `equivalent` incorrectly specifies throws clause + * [2729](http://wg21.link/lwg2729) Missing SFINAE on `std::pair::operator=` + * [2732](http://wg21.link/lwg2732) Questionable specification of `path::operator/=` and `path::append` + * [2735](http://wg21.link/lwg2735) `std::abs(short)`, `std::abs(signed char)` and others should return `int` instead of `double` in order to be compatible with C++98 and C + * [2736](http://wg21.link/lwg2736) `nullopt_t` insufficiently constrained + * [2738](http://wg21.link/lwg2738) `is_constructible` with `void` types + * [2739](http://wg21.link/lwg2739) Issue with `time_point` non-member subtraction with an `unsigned` duration + * [2740](http://wg21.link/lwg2740) `constexpr optional::operator->` + * [2742](http://wg21.link/lwg2742) Inconsistent `string` interface taking `string_view` + * [2744](http://wg21.link/lwg2744) `any`'s `in_place` constructors + * [2747](http://wg21.link/lwg2747) Possibly redundant `std::move` in [alg.foreach] + * [2748](http://wg21.link/lwg2748) swappable traits for `optional`s + * [2749](http://wg21.link/lwg2749) swappable traits for `variant`s + * [2752](http://wg21.link/lwg2752) *Throws:* clauses of `async` and `packaged_task` are unimplementable + * **[2753](http://wg21.link/lwg2753) not applied, see below** + * [2754](http://wg21.link/lwg2754) The `in_place` constructors and `emplace` functions added by P0032R3 don't require `CopyConstructible` + * [2755](http://wg21.link/lwg2755) [string.view.io] uses non-existent `basic_string_view::to_string` function + * [2756](http://wg21.link/lwg2756) `optional` should 'forward' `T`'s implicit conversions + * [2758](http://wg21.link/lwg2758) `std::string{}.assign("ABCDE", 0, 1)` is ambiguous + * [2759](http://wg21.link/lwg2759) `gcd` / `lcm` and `bool` + * [2760](http://wg21.link/lwg2760) non-`const` `basic_string::data` should not invalidate iterators + * [2765](http://wg21.link/lwg2765) Did LWG 1123 go too far? + * [2767](http://wg21.link/lwg2767) `not_fn` `call_wrapper` can form invalid types + * [2771](http://wg21.link/lwg2771) Broken *Effects:* of some `basic_string::compare` functions in terms of `basic_string_view` + * [2773](http://wg21.link/lwg2773) Making `std::ignore` `constexpr` + * [2777](http://wg21.link/lwg2777) `basic_string_view::copy` should use `char_traits::copy` + * [2778](http://wg21.link/lwg2778) `basic_string_view` is missing `constexpr` + +LWG motion 12: [P0426R1 "`constexpr` for `std::char_traits`"](http://wg21.link/p0426r1), resolving 2 NB comments: + + * US 81, RU 4: `char_traits` operations should be `constexpr` + +LWG motion 13: [P0403R1 "Literal suffix for `basic_string_view`"](http://wg21.link/p0403r1), resolving 2 NB comments: + + * US 80, FI 6: Add user-defined literal suffix for `basic_string_view` + +LWG motion 14: [P0505R0 "`constexpr` for ``"](http://wg21.link/p0505r0), resolving 1 NB comment: + + * GB 50: Make member functions of `duration` and `time_point` `constexpr` + +LWG motion 15: [P0418R2 "Fail or succeed: there is no atomic lattice"](http://wg21.link/p0418r2), resolving 1 issue and 1 NB comment: + + * CA 16: Merge P0418R1 or similar to resolve LWG 2445 + * [2445](http://wg21.link/lwg2445) "Stronger" memory ordering + +LWG motion 16: [P0508R0 "Structured bindings for *node_handle*s"](http://wg21.link/p0508r0), resolving 1 NB comment: + + * GB 58: Allow decomposition of `insert_return_type` + +LWG motion 17: [P0503R0 "Correcting library usage of 'literal type'"](http://wg21.link/p0503r0), resolving 3 NB comments: + + * GB 68: Verify term "literal type" is used appropriately + * US 154: Copy constructor of `istream_iterator` and literal types + * US 155: Destructor of `istream_iterator` and literal types + +LWG motion 18: Two papers applied, resolving 1 NB comment: + + * [P0414R2 "Merging `shared_ptr` changes from Library Fundamentals (v2) TS"](http://wg21.link/p0414r2) + * [P0497R0 "Fixes to `shared_ptr` support for arrays"](http://wg21.link/p0497r0) + * FI 19: Adopt P0414 + +LWG motion 19: [P0504R0 "Revisiting in-place tag types for `any`/`optional`/`variant`"](http://wg21.link/p0504r0), resolving 1 NB comment: + + * CH 3(a): `in_place` tags prevent perfect forwarding after decay to function + +LWG motion 20: [P0003R5 "Removing deprecated exception specifications"](http://wg21.link/p0003r5), resolving 3 NB comments: + + * See also CWG motion 5, which applies the same paper + * US 18, US 70, GB 43: Adopt P0003R5 to remove dynamic exception specifications + +LWG motion 21: [P0510R0 "Disallowing references, incomplete types, arrays, and empty `variant`s"](http://wg21.link/p0510r0), resolving 12 NB comments: + + * US 112: Explicitly disallow `variant<>` + * US 115, US 181, FI 22: Remove support for `variant` + * US 116: Remove support for `variant` + * US 117: Remove support for `variant` + * US 120: Remove redundant wording for `void` elements in `variant` + * CH 3(b): Remove support for `variant` + * CH 4: Improve support for `variant` + * CH 5: Repair `variant<>` + * CH 6: Clarify behavior for `variant` + * CH 8: Clarify construction behavior for `variant<>` + +LWG motion 22: [P0516R0 "Clarify that `shared_future`'s copy operations have wide contracts"](http://wg21.link/p0516r0), resolving 1 NB comment: + + * GB 62: Give `shared_future` copy operations a wide contract and `noexcept` + +LWG motion 23: [P0509R1 "Restrictions on exception handling"](http://wg21.link/p0509r1), resolving 2 NB comments: **see below** + + * GB 41: Unclear restrictions on strengthening exception specifications + * GB 42: Use of 'should' suggests unintended normative encouragement + +LWG motion 24: [P0502R0 "Throwing out of a parallel algorithm terminates -- but how?"](http://wg21.link/p0502r0), resolving 7 NB comments: + + * US 15, US 167: Revisit calling `terminate` in response to an exception from a parallel algorithm + * US 16, US 168: Clarify (nondeterministic?) behavior when rethrowing exception from element access function + * US 169: Use an `exception_list` to propagate multiple exceptions from parallel algorithm execution + * US 170: Allow for future addition of alternative exception handling mechanisms to parallel algorithms + * CA 17: Preserve parallel algorithm exception behavior in CD + +LWG motion 25: [P0517R0 "Make `future_error` constructible"](http://wg21.link/p0517r0), resolving 1 NB comment: + + * US 163: Document constructor for `future_error` + +LWG motion 26: [P0521R0 "`shared_ptr` `use_count`/`unique`"](http://wg21.link/p0521r0), resolving 1 NB comment: + + * CA 14: `use_count` needs either synchronization or weaker guarantees + +LWG motion 27: [P0513R0 "Poisoning the hash"](http://wg21.link/p0513r0), resolving 2 issues and 2 NB comment: + + * FI 15: "Poison" `hash>` if `T` is not hashable + * GB 69: Reword requirements and remarks for `hash>` specialization + * [2791](http://wg21.link/lwg2791) `string_view`s and `string`s should yield same hash values + * [2543](http://wg21.link/lwg2543) `hash` support for `enum`s underspecified + +LWG motion 28: [P0067R5 "Elementary string conversions"](http://wg21.link/p0067r5), resolving 1 NB comment: + + * FI 5: Merge fixed version of P0067 + +LWG motion 29: [P0435R1 "LWG issue resolutions for `common_type`"](http://wg21.link/p0435r1) + +Library motions added a total of 9 pages to Clause 17-30. + +## Notable changes to papers as moved + +### LWG motion 11 + +#### LWG2534 + +The wording change applied here needed to be rebased onto the wording change +applied by LWG2328 as part of 2016-06 LWG Motion 1. + +LWG2328 changes the rvalue ostream extractor to use perfect forwarding, changing from: + +> ``` +> template +> basic_istream& +> operator>>(basic_istream&& is, T& x); +> ``` +> +> -1- *Effects:* `is >> x` + +to: + +> ``` +> template +> basic_istream& +> operator>>(basic_istream&& is, T&& x); +> ``` +> +> -1- *Effects:* Equivalent to: +> ``` +> is >> std::forward(x); +> return is; +> ``` + +LWG2534 adds a matching SFINAE condition, and proposes this wording based on +the standard prior to the application of LWG2328: + +> -?- Remarks: This function shall not participate in overload resolution unless the expression `is >> x` is well-formed. + +The two LWG issue resolutions have been editorially merged, resulting instead +in the addition of this SFINAE condition: + +> -?- Remarks: This function shall not participate in overload resolution unless the expression `is >> std::forward(x)` is well-formed. + +#### LWG2543 + +The resolution of +[LWG issue 2543](http://wg21.link/lwg2543) +is made redundant and unnecessary by +LWG motion 27 in +[P0513R0](http://wg21.link/p0513r0), +which applies a more general fix to the same wording. +As a result, LWG2543's resolution has not been applied, +and instead LWG2543 should be marked as resolved by P0513R0. + +#### LWG2753 + +The resolution of +[LWG issue 2753](http://wg21.link/lwg2753) +conflicts with the resolution of +[LWG issue 2756](http://wg21.link/lwg2756) +and has not been applied. +In particular, +LWG 2753 changes the draft to say that the +`optional(const optional&)` constructor +should not participate in overload resolution +if `!is_copy_constructible_v`, whereas +LWG 2756 changes the draft to say that the +constructor should be deleted in the same case. + +### LWG motion 23 + +The wording of this paper intended to apply on top of the wording changes applied by +[P0003](http://wg21.link/p0003r5) (applied by CWG motion 5 and LWG motion 20), +but was not updated to match the latest wording changes from P0003R5, and as a +result, many of its proposed changes are redundant with those applied by P0003R5. +There is no conflict between the intent of the two papers, and both have +been applied. + +## Disposition of editorial NB comments on C++ 2017 CD1 + +Listed below are draft disposition for all comments that were +filed as editorial in the ISO 14882 CD (2016) NB comments, +[p0488r0](http://wg21.link/p0488r0), +and the late editorial comments in [p0489r0](http://wg21.link/p0489r0). +Except where otherwise noted, these dispositions only represent the current +viewpoint of the Project Editor. + +### ES Comments + +ES 3: Accepted, fixed in f6482016. + + * Example is correct with or without proposed change. + +### US Comments + +US 4: No consensus for change. + + * While `_v` forms are generally preferred in library clauses, defining the core +language semantics in terms of a variable template seems to introduce undue +complexity. + * CWG concurs with this direction. + +US 9: Accepted, fixed in 97058f9c. + + * LWG concurs with this direction. + +US 11: Accepted with modifications, fixed in 663f1324. + + * In the reference in paragraph 9, the `::value` was removed to match similar specifications. + +US 12: Accepted, fixed in 0fdcc1ab. + +US 13: Accepted with modifications, fixed by 79974877. + + * Specifying the value of `is_destructible_v` within the specification for +`is_destructible` would be considerably less clear than specifying the value +of `is_destructible::value`. + + * **Modified resolution:** Instead of proposed fix, change Condition for +`is_destructible` to: + +> Condition: Either `T` is a reference type, or `T` is a complete object type +for which the expression `declval().~U()` is well-formed when treated +as an unevaluated operand (Clause [expr]), where `U` is +`remove_all_extents_t`. + + * LWG concurs with this direction. + +US 26: Accepted, fixed by 85aac089. + +US 27: Accepted, fixed by fb925656. + +US 38: Accepted, fixed by adb0da05. + + * LWG concurs with this direction. + +US 39: Accepted, fixed by d47d5ca4. + + * LWG concurs with this direction. + +US 41: **LWG to handle issue** + + * LWG has deferred a decision on this to Kona. + +US 42: **LWG to handle issue** + + * The suggested resolution contradicts [fs.op.status]/7, which indicates that +pathname resolution does always resolve a symlink. There is no other +specification of how pathname resolution behaves, so the proposed note would +not be justified by normative text. + * LWG has deferred a decision on this to Kona. + + US 47: **LWG to handle issue** + + * LWG has deferred a decision on this to Kona. + +US 50: **LWG to handle issue** + + * The proposed change seems valuable, but would be a normative change if the type +is an input iterator type for which `decay_t` would produce a different type. +The Project Editor would like LWG to consider whether that change is acceptable. + * LWG has deferred a decision on this to Kona. + +US 87: **SG1 to handle issue** + + * CWG considers the revised term to be less clear. A compromise term "block with +progress guarantee delegation" (removing the "forward" but retaining the +"guarantee") has been proposed. + +US 88: Accepted, fixed in 554514cc. + +US 89: Accepted with modifications, fixed in 7e920239, d580a0dd. + + * "+" in section heading replaced by "and" + +US 90: Accepted, fixed in 131716c4. + +US 91: Accepted, fixed in 0a344234. + + * LWG and SG1 concur with the direction of this issue. + +US 96: Accepted, fixed in e6d9dfff. + +US 97: Duplicate of US 4. + +US 120: Accepted, fixed in a8f966f5. + + * LWG concurs with this direction. + +US 133: Accepted, fixed in 71c347ed. + +US 136: Accepted, fixed in 27b46764. + +US 138: No consensus for change. + + * [func.requires] are requirements on the library, [requirements] are +requirements on the program. [func.requires] does not fit within +[requirements], nor within Clause 17 at all. + * The call wrapper terms are not used outside the specified clause (except within +Annex D), so moving them to [definitions] does not seem useful. + +US 149: No consensus for change. + + * It is unclear what this comment is referencing. There is no note in 23.3.7.3 +[array.special]/3, and 23.2.1 [container.requirements.general]/9 already +excludes `array` from its general requirements. + * Perhaps the objection is that the semantics of `array::swap` are never actually +defined anywhere -- do we use `swap(a[i], b[i])` to swap elements, or some other +mechanism such as move-assigning via a temporary? -- in which case this omission +does not seem editorial. + * LWG concurs with this direction. + +US 152: **LWG to handle issue** + + * This comment is not editorial. + +US 157: Duplicate of US 91. + +US 158: No consensus for change. + + * The Project Editor believes that including the description of the `` +header in the "Algorithms" clause instead of the "Numerics" clause would harm +the organization of the standard. +One possible approach would be to rename the "Numerics" subclause to a name +that fits its remaining content, but LWG did not support that approach. + * The last sentence of the proposed change for US 166 appears to be intended to +be part of this NB comment instead. + * LWG concurs with this direction. + +US 173: Accepted, fixed in 4fde500c. + +US 179: Accepted with modifications, fixed in 662ddc79. + + * Renamed section label to +[optional.optional] since optional is not a class, matching [pairs.pair], +[tuple.tuple], [variant.variant]. + * LWG concurs with this direction. + +US 180: Accepted with modifications, fixed in e62da07d. + + * Section label not changed (see US 179). + * LWG concurs with this direction. + +US 182: Accepted, fixed by e229a482. + +### GB Comments + +GB 7: Accepted, fixed in fd1204ed. + + * CWG concurs with the direction of this issue. + +GB 8: Accepted, fixed in d0e5d065. + + * CWG concurs with the direction of this issue. + +GB 11: Accepted, fixed by 4fa3ef43. + +GB 14: Accepted, fixed by 142c82e4. + + * Not filed as editorial, but will be handled editorially per CWG request. + * CWG concurs with the direction of this issue. + +GB 22: Accepted, fixed by e11da84f. + + * No type listed for comment, but considered editorial + * CWG concurs with the direction of this issue. + +GB 24: Accepted, fixed by 84cb6529. + + * CWG concurs with the direction of this issue. + +GB 29: Accepted, fixed in 6621ef71. + +GB 31: Accepted with modifications, fixed in 32b2de88. + + * The definition of "character traits" is in 21.2/1. The relevant traits classes +are actually only defined in Clause 21, and the headers in Clause 22 don't even +declare these traits classes (although they do use them). The note is +sufficiently wrong that the best solution appears to be to remove it entirely. + * Removed note. + +GB 32: Accepted, fixed in 94244ddf. + +GB 33: Accepted, fixed in a8d89234. + +GB 34: Accepted, fixed in ddc64ff8. + +GB 37: Accepted, fixed in a5e70c64. + + * LWG concurs with this direction. + +GB 43: **LWG to handle issue** + + * Resolved by CWG motion 5 / LWG motion 20 + +GB 47: **LWG to handle issue** + + * Resolved by LWG motion 18 + +GB 48: Accepted, fixed in 2a96241e. + +GB 52: Accepted, fixed in 65859b3b. + +GB 66: **CWG to handle issue** + +GB 67: Accepted, fixed in 464156d1. + +### RU Comments + +No editorial comments. + +### JP Comments + +JP 1: Accepted with modifications, fixed by 942b3fbc. + + * Additional changes: + 1. [iostream.objects.overview]/4: add cross-reference to C11 7.21.2, and replace + "C standard" with "C standard library" for consistency + 2. [alg.c.library]/2: replace "C standard" with "C standard library" for + consistency + + +JP 2: Accepted, fixed by c6552f06. + +JP 3: **CWG to handle issue** + + * CWG wishes to investigate alternative wording changes. + +JP 4: Accepted, fixed by 76308413. + +JP 5: Accepted, fixed by 3e0038a3. + +JP 6, JP 7, JP 14, JP 16, JP 17: No consensus for change. + + * The proposed change is not correct. The double-quote notation is used for the + canonical type names defined by the algorithm in [dcl.meaning]. In this context, + + > function type `T` + + means `T`, where `T` is a function type. The suggested alternative of + + > ''function type `T`'' + + would be meaningless. We could change the wording to + + > ''array of `T`'' or function type ''`T`'' + + but the convention is to omit the ''...'' when surrounding a single type name. + +JP 8: No consensus for change. + + * The comment is not correct. `declarator ;` is a valid function declaration when +the declarator declares a constructor, destructor, or conversion function. The +wording is therefore correct as written. + * The proposed alternative wording would fail to capture the intent that the +declartor shall be well-formed as a declarator for a complete +function-declaration (not merely a valid function declarator). + +JP 9: Accepted, fixed by aa74ca01. + +JP 10, JP 11: No consensus for change. + + * The core language portion of the standard intentionally does not have a +consistent "house style" used in examples, in order to emphasize that the +language itself takes no position on questions of style. + +JP 12: Accepted with modifications, fixed in b598c94e. + + * Figure is referenced by number instead of as "below". + +JP 13: Accepted, fixed in ee809590. + +JP 15: No consensus for change. + + * 12.5 does not appear to be relevant here. The cross-reference to 5.3.4 fully +describes how the matching deallocation function is determined. The +cross-reference to 3.7.4.2 is just for the term "deallocation function", and +covers both the class-specific and global cases. + +JP 18: Accepted with modifications, fixed in a8654e86. + + * Solved by promoting the footnote into a note and splitting the surrounding +paragraph into multiple paragraphs. + +JP 21: Accepted, fixed in cf099ae6. + +JP 22: Accepted with modifications, fixed in 472a7176. + + * The wording has been simplified in a different way from that proposed. + +JP 23: Accepted with modifications. + + * Each algorithm *with* a parallel form is now explicitly called out. + * Duplicate of US 91. + +JP 24: Accepted, fixed in 984ef4a1. + +JP 25: **LWG to handle issue** + + * This comment is not editorial. + +JP 26: Accepted, fixed by e229a482. + + * Duplicate of US 182. + +### CA Comments + +No editorial comments. + +### FI Comments + +No editorial comments. + +### CH Comments + +No editorial comments. + +### Late Comments + +Late 15: Accepted, fixed in 066aba68. + +Late 30: **LWG to handle issue** + + * The change appears correct but LWG feedback is requested to ensure that the +`s1 == s2` check wasn't trying to check something else beyond the fact that +the paths resolve to the same file system entity. + +Late 42: Accepted, fixed in 3b22c874. + + * Of note: the Postcondition is impossible to guarantee, due to the possibility +of a file system race. + +## Notable editorial changes + +The incorrect application of two papers, moved by prior meetings, have been fixed: + + * In the application of P0035R4, the `__STDCPP_DEFAULT_NEW_ALIGNMENT__` macro + was accidentally added to the wrong paragraph of [cpp.predefined], making it + optional instead of mandatory. It has been moved to the correct paragraph. + * In the application of P0135R1, wording allowing an rvalue reference to a + function to bind to the result of converting a class object to a function + lvalue via a conversion function was accidentally removed, and has been + restored. + +C.5 [diff.library] has received an overhaul in this revision of the +working draft. Consistent with the intent of Annex C, it has been updated to +comprehensively list all the known differences between the C standard library +and the corresponding C++ `` stanard library headers. Thanks to Thomas +Köppe for this! + +The index of implementation-defined behavior and index of library names have +also received an overhaul, thanks to a mammoth effort by Alisdair Meredith, and +should now both be complete. + +A number of issues in our LaTeX setup have been resolved by Thomas Köppe, the +result of which is that vertical spacing, particularly between bullets in +bulleted lists and after codeblocks, should now be much more consistent. + +## Minor editorial fixes + +A log of all editorial fixes made since N4606 is below: + + commit cb12b08d5bd16ae70119b79c64fbec35437f64ff + Author: Thomas Köppe + Date: Tue Nov 29 00:44:29 2016 +0000 + + [map.modifiers, unord.map.modifiers] Add std:: qualifiers to move and forward, and tidy up overlong lines. + + Also harmonize the itemdecls between ordered and unordered map. + + commit 902bf771e78c58037c9571e1b1220f79ee0bb47d + Author: timsong-cpp + Date: Mon Nov 28 18:55:23 2016 -0500 + + [unord.req.except] Add missing \tcode for Hash and Pred. (#1141) + + commit 2a67c388f84a5ffe788f643d87631b1a76550a4c + Author: alfmin + Date: Mon Nov 28 23:49:38 2016 +0100 + + [except.spec] missing linebreak (#1140) + + It seems "noecept throw()" is ment to be split as different possibilities + + commit 6a7684281253a7c6d2eb7a32ac796eeb4122d4bf + Author: timsong-cpp + Date: Mon Nov 28 15:43:29 2016 -0500 + + [cpp.replace] Adjust footnote to clarify that conditionally-supported-directives are directives whether supported or not (#1045) + + commit 8d089846de4f60ed939d79c162c5e782fa9a1675 + Author: Thomas Köppe + Date: Mon Nov 28 20:34:57 2016 +0000 + + [tuple.special] Use maths operators + + commit 8bdc1417c5dabb5acd4d37ffd0d7b7ce642ee58c + Author: Thomas Köppe + Date: Mon Nov 28 20:22:33 2016 +0000 + + [macros] Reduce whitespace at the end of code blocks (#1135) + + commit 41ae590ddd1c5d7d6245d6216eb514d5d84414e3 + Author: Thomas Köppe + Date: Mon Nov 28 20:21:50 2016 +0000 + + [tuple.apply] Improve line fit of apply_impl + + commit b391f4ab79722708500ebb96edcb1d7c0ef49fa1 + Author: Thomas Köppe + Date: Mon Nov 28 19:54:38 2016 +0000 + + [expr.const] Reflow comments to be slightly more economical + + commit a31b2df303c7aaa383fdebf21fcf8d6f95159e9a + Author: Thomas Köppe + Date: Mon Nov 28 19:40:38 2016 +0000 + + [complex.ops] Replace inappropriate codeblock with itemdecl; remove some unneeded linebreaks. + + commit 26a2e15669bc96dfbad16e4fb5fe915955b83991 + Author: Jens Maurer + Date: Mon Nov 28 20:33:49 2016 +0100 + + [class.union] Clarify in the note that a default member (#1113) + + initializer may prevent a defaulted special member function + from being implicitly deleted. + + Fixes #1073. + + commit fd2ff5bdafb161b97e4a84cb2a7dffa31a198e3e + Author: Jens Maurer + Date: Mon Nov 28 20:33:21 2016 +0100 + + [basic.lookup.unqual] Rephrase unqualified lookup in a function definition. (#1106) + + Fixes #451. + + commit bbf03b48143ea3c2792a22ccda49bff1c53ee094 + Author: Thomas Köppe + Date: Mon Nov 28 19:26:03 2016 +0000 + + [string.classes] Remove unneeded padding newlines around namespace content + + commit 089afdbe21788549b458b632c6c39613a28fedff + Author: Jens Maurer + Date: Mon Nov 28 19:56:40 2016 +0100 + + [class.copy] Introduce three subsections. (#1077) + + Fixes #490. + + commit 1864404cabbd5530eca0d9c951eb2f68d21c523d + Author: Thomas Köppe + Date: Mon Nov 28 18:43:32 2016 +0000 + + [basic.life] Fix nesting of example; tidy up list. + + commit 53202da4ed4a19a40210091354a2d42d779ebdd3 + Author: Thomas Köppe + Date: Mon Nov 28 18:12:15 2016 +0000 + + [lex.charset] Remove unneeded newlines + + commit a03fe3f68adb5fd57e5273700f3c0f7a5770e67e + Author: Jens Maurer + Date: Mon Nov 28 19:09:18 2016 +0100 + + [class] Rephrase definition of M(X) used to define a standard-layout class. (#1076) + + Fixes #496. + + commit 7ce7c1759414ccf718c5308c17dfeb483f60ad94 + Author: Eelis + Date: Mon Nov 28 19:01:27 2016 +0100 + + [dcl.decl] Turn very large footnote into ordinary note. (#1121) + + commit 0e26279b88c3b8b0a09babdeec8418d383f07419 + Author: Thomas Köppe + Date: Mon Nov 28 17:58:15 2016 +0000 + + [basic.scope.class] Break up enumerated list into ordinary paragraphs (#1137) + + commit cd3deb891cee5436a64ff9a8f7bb304a4fcc6c00 + Author: Jens Maurer + Date: Wed Nov 23 23:02:25 2016 +0100 + + 'floating-point something', not 'floating point something' + + commit a07f03f1f80c4fe8c0702faa9dbbeba409ffc7fc + Author: Jens Maurer + Date: Wed Nov 23 21:00:44 2016 +0100 + + 'nondeterministic', not 'non-deterministic' + + commit 850f15f5b97d5e34caa340dd37f4902d035e353f + Author: Jens Maurer + Date: Wed Nov 23 20:59:09 2016 +0100 + + 'non-graphic', not 'nongraphic' + + commit 5cf1bc0e8456c28416ed95673523edfde4672f25 + Author: Jens Maurer + Date: Wed Nov 23 20:58:08 2016 +0100 + + 'non-portable', not 'nonportable' + + commit 3febb8b9dfe0a9e83a912c6f5fb56687b528261d + Author: Jens Maurer + Date: Wed Nov 23 20:57:19 2016 +0100 + + 'non-member', not 'nonmember' (when referring to a class or namespace member) + + commit 61f3c9a294704541f8efe170a80d74873d8210cc + Author: Jens Maurer + Date: Wed Nov 23 20:53:04 2016 +0100 + + 'non-constant', not 'nonconstant' + + commit 49111b4c998cf975342d4b96c85a419f531c92b4 + Author: Jens Maurer + Date: Wed Nov 23 20:51:59 2016 +0100 + + 'non-const', not 'nonconst' + + commit b90068ae889c88b8a14ed126f4323de747f3aa6f + Author: Jens Maurer + Date: Wed Nov 23 20:51:17 2016 +0100 + + 'non-class', not 'nonclass' + + commit e53393820b5208457ffef5d08a3b00b59e623345 + Author: Jens Maurer + Date: Wed Nov 23 20:49:37 2016 +0100 + + 'non-abstract', not 'nonabstract' (for classes) + + commit 520ebd836da8379e85c43600759b2cde1ca5c58b + Author: Jens Maurer + Date: Wed Nov 23 20:48:47 2016 +0100 + + 'nonzero', not 'non-zero' + + commit ab27bb454fb6303fdd44da80b6eba3df2b1feae9 + Author: Jens Maurer + Date: Wed Nov 23 20:47:23 2016 +0100 + + 'subobject', not 'sub-object' + + commit afb46ec4c8a7435955b748855c112635efebced1 + Author: Jens Maurer + Date: Wed Nov 23 20:47:09 2016 +0100 + + 'subexpression', not 'sub-expression' + + commit 1f1a2392349f126adec4ea6f3b3fd4cf7632e311 + Author: Johannes Laire + Date: Mon Nov 28 09:07:48 2016 +0000 + + [fpos.operations] Use code font for a type (#1138) + + commit 5255e81297bb3aaca6eb2ab1c48a4d224a7fb5b1 + Author: Thomas Köppe + Date: Mon Nov 28 02:25:55 2016 +0000 + + [dcl.constexpr] Fix missing full stop + + commit ab13956de2d579e16dff696e5146d86f6f459458 + Author: Thomas Köppe + Date: Mon Nov 28 02:21:07 2016 +0000 + + [re.grammar] Change ordered list to unordered list + + commit 791e71b1627c8ba4b60e4f7c33553010e435d0f9 + Author: Thomas Köppe + Date: Mon Nov 28 00:04:39 2016 +0000 + + [basic] Remove unnecessary and awkward whitespace in and around lists from LaTeX source + + commit 49ed4ada682162900a0a9adc02a1a3bbb87d2fa3 + Author: Thomas Köppe + Date: Mon Nov 28 00:04:21 2016 +0000 + + [intro, lex] Remove unnecessary and awkward whitespace in and around lists from LaTeX source + + commit 4d9c28c18416750b0e9bfd44fcfdb0827637b984 + Author: JF Bastien + Date: Sun Nov 27 18:24:11 2016 -0500 + + [pairs.pair, tuple.cnstr] Change 'behaviour' to 'behavior' (#1136) + + Fixes #1128. + + commit f3c809c29877f301e3cc8e25c4c184651ab68758 + Author: Jens Maurer + Date: Sun Nov 27 23:32:47 2016 +0100 + + [thread.lock] Extract error conditions from 'Throws' element. (#1122) + + Fixes #458. + + commit 87fb2d8482f2fbdcb7b474991094df267fd7cf66 + Author: Thomas Köppe + Date: Sun Nov 27 21:44:20 2016 +0000 + + [std, macros, styles] Use 'enumerate' package to make vertical spacing of lists uniform. (#1134) + + This change makes it so that lists are now spaced the same regardless of whether they are preceded by a paragraph break. + + commit 866c1451ab2f1f2bef0052abd849b07115d4672c + Author: Jens Maurer + Date: Sun Nov 27 20:41:11 2016 +0100 + + [variant] Use \tcode for type designators, not math mode. (#1125) + + Fixes #1115. + + commit 22c396b3ccb46e9224433eb1c7ff761a28b83121 + Author: Thomas Köppe + Date: Sun Nov 27 18:19:49 2016 +0000 + + [meta.logical] Fix application of LWG 2567 and add further explicit boolean conversions editorially. (#1133) + + Fixes #1132. + + commit d8aab1fbd28d97a467993c2f9c4cb669e025c561 + Author: Thomas Köppe + Date: Sun Nov 27 00:12:11 2016 +0000 + + [utilities] Harmonize spacing and placement of qualifiers + + Fixes #127. + + commit e864521c22fe29b5a0141114ee57e8c63cb24149 + Author: Thomas Köppe + Date: Sat Nov 26 23:56:25 2016 +0000 + + [re, thread] Move 'const' qualifier to the right place. + + Cf. Issue #127. + + commit 59c2abecdbc40473221763caef77944ea351d0ca + Author: Thomas Köppe + Date: Sat Nov 26 23:31:49 2016 +0000 + + [depr.default.allocator] Simplify specification of allocator::address. + + Fixes #257. + + commit 0b640ed8161937d31f31e251c297b658c559a978 + Author: Thomas Köppe + Date: Sat Nov 26 22:39:15 2016 +0000 + + [streambuf.virtuals] Simplify the logic of exposition; remove several unneeded lists (#1111) + + commit 44e46e63aaeef375a8521fd93b5db2a40692dbe7 + Author: Jens Maurer + Date: Sat Nov 26 23:37:10 2016 +0100 + + [lib] Remove 'std::' prefix from library names. (#1085) + + The standard library specifies that references to its names are assumed to be prefixed by '::std::'. Therefore, we can remove any explicit 'std::' prefixes. + + [iterator.range] was not touched, because it is unclear whether argument-dependent lookup was intended to be disabled here. + + Fixes #431. + + commit aff2b2ad7752f1175e455cdc44f23e9d0d9539ed + Author: Jens Maurer + Date: Sat Nov 26 23:34:44 2016 +0100 + + [filesystems] Do not repeat section title in cross-references to [fs.err.report]. (#1123) + + Fixes #1116. + + commit 71aa637c9cd8cea15e9ebc6160ef9208247d5601 + Author: Jens Maurer + Date: Mon Nov 21 14:20:17 2016 +0100 + + [lib] Remove trailing colon in sectioning comments of synopses. + + Fixes #802. + + commit 6af539d47d5a122627845c47f31d2e700a2ca3cc + Author: Jens Maurer + Date: Mon Nov 21 14:17:17 2016 +0100 + + [lib] Add missing comma in sectioning comments of synposes. + + commit ce32af9de74e953245d920a82f7caf1d8a395988 + Author: Jens Maurer + Date: Mon Nov 21 13:53:51 2016 +0100 + + [meta.type.synop] Remove 'see' in sectioning comments of synopses. + + commit 64978c8dfc17b3f89083f861f08cd06b13dc10d9 + Author: Jens Maurer + Date: Sat Nov 26 23:33:06 2016 +0100 + + [diff] Miscellaneous fixes. (#1114) + + Consistently end the 'Changes' phrase with a period. + Add missing newlines. + Remove spurious 'Rationale' item. + Fix typos. + + Fixes #214. + + commit 2b36c558eeb660bf664b4b5b9f06ae15e19f23e7 + Author: Jens Maurer + Date: Sat Nov 26 20:55:58 2016 +0100 + + [temp.deduct.call] Add example involving cv-qualifiers and references. (#1108) + + Fixes #517. + + commit 6bca6072e5a605e25ef3f49fb7fb2c2171d07c4c + Author: Jens Maurer + Date: Sat Nov 26 20:38:41 2016 +0100 + + Adjust italics and index entries for 'underlying type'. (#1127) + + Fixes #330. + + commit 37073d63e58f74b52fb3b5061c126e18a603d3d2 + Author: Jens Maurer + Date: Sat Nov 26 20:31:54 2016 +0100 + + [basic.def.odr] Avoid counting the number of bullets in normative text (#1109) + + Fixes #944. + + commit 2e8a867fa6fc9a98fd0044b303ae4567351644fd + Author: Jens Maurer + Date: Sat Nov 26 20:31:03 2016 +0100 + + [sequence.reqmts] Remove redundant 'forward iterator' requirement for sequence containers (#1107) + + Any container is nowadays required to have forward iterators; + see the table entries for X::iterator and X::const_iterator in + [container.requirements.general]. + + Fixes #461. + + commit 62956c9b1afd2ce6ddc81378feee28e964eb1b33 + Author: Jens Maurer + Date: Sat Nov 26 20:29:45 2016 +0100 + + [re.matchflag] Remove namespace qualification when mentioning match_flag_type. (#1124) + + Fixes #443. + + commit f5c8386fa7ae8e944645e2328b823dc60f1c3499 + Author: Jens Maurer + Date: Sat Nov 26 20:28:53 2016 +0100 + + [thread.lock.shared] Add sectioning comments to synopsis. (#1126) + + Fixes #459. + + commit 3930000f039bf64dc451fa5e8ca7376df59a900f + Author: S. B. Tam + Date: Sun Nov 27 03:28:35 2016 +0800 + + [expr.xor, macros] Replace \exor command with \caret; remove \exor definition. (#1131) + + commit a23cd78bf34f3dd75820ac4d3985d693a9fedf80 + Author: Eelis + Date: Thu Nov 24 02:36:01 2016 +0100 + + [locale.facet] Don't bother itemizing a single item. (#1118) + + commit 345084aa3c8acfb02f21594055ec4211766959ce + Author: Thomas Köppe + Date: Thu Nov 24 01:01:30 2016 +0000 + + [ostream.cons] Fix misnested environments + + commit 42cf4c9e926052930bee439b8f3752d60562df06 + Author: Jens Maurer + Date: Wed Nov 23 20:49:11 2016 +0100 + + [thread.mutex.requirements] Make references to mutex requirements consistent. (#1110) + + Fixes #202. + + commit f3d1ffb3eabf2a352564890ea31c3ad996a194b8 + Author: Eelis + Date: Wed Nov 23 20:07:11 2016 +0100 + + [macros, basic, streambuf] Retire 'enumeraten' environment in favour of 'enumerate'. (#1105) + + commit c8cef8d7b9b2c9f1aa5c222fe5edfcb44d358420 + Author: Jens Maurer + Date: Wed Nov 23 15:57:59 2016 +0100 + + [class.conv.fct] Add examples for 'auto' as a conversion-function-id (#1104) + + A trailing return type is ill-formed, a conversion function with a + deduced return type is fine, but a conversion function template with a + deduced return type is ill-formed. + + Fixes #424. + + commit bb03cceade6485044b1ce820f4a4088597dc6f91 + Author: Jens Maurer + Date: Wed Nov 23 15:20:59 2016 +0100 + + [iterator.requirements.general] Use singular when defining 'value type' and 'writeable to' for iterators. (#1101) + + Fixes #698. + + commit 19ec46ecfd460bd5c08db7bb9c2252ceaf1f26a2 + Author: Eelis + Date: Wed Nov 23 11:49:21 2016 +0100 + + [basic.scope.class] Add missing whitespace before example. (#1103) + + commit da6c19b7adeefe444c01b3045c887068c9c8d122 + Author: Jens Maurer + Date: Tue Nov 22 22:32:57 2016 +0100 + + [quoted.manip] operator>> is not a member of basic_istream. (#1100) + + Fixes #729. + + commit eb4f045e6e46d5db001c4344f0667c739ccf3e7e + Author: Jens Maurer + Date: Tue Nov 22 12:41:16 2016 +0100 + + [istream], [ostream] Remove paragraph numbers in cross-references. (#1099) + + Also replace cross-references referring to their own section with 'above'. + + Fixes #702. + + commit f8013a4a70859bc3ff6716343c1351e9a0e35490 + Author: Jens Maurer + Date: Tue Nov 22 10:50:18 2016 +0100 + + [reverse.iter.ops] Simplify reverse_iterator operator function declarations by using non-dependent difference_type. (#1098) + + Fixes #831. + + commit 02480305fcbb76733a73749aadc31451b0595b75 + Author: hubert-reinterpretcast + Date: Mon Nov 21 18:12:49 2016 -0500 + + [intro.execution] Remove unnecessary function from example (#1084) + + commit a5c38698b7a5ecb93af8d6d58e681f997bf0461f + Author: Johannes Laire + Date: Mon Nov 21 22:09:51 2016 +0000 + + [library] Use \effects etc. when referring to itemdescr elements in introductory text (#1093) + + commit 5bb341be09ed6a2cb78be29148597b87388fe9d7 + Author: Jens Maurer + Date: Mon Nov 21 23:05:26 2016 +0100 + + [futures.overview], [futures.async] Use 'bitmask type' terminology. (#1095) + + Fixes #826. + + commit 1f4bff0667fe6608e6e9cf016e74930cb7650589 + Author: Eelis + Date: Mon Nov 21 18:32:48 2016 +0100 + + [basic.lookup.argdep] Mark definitions of 'associated class/namespace'. (#1092) + + commit 93651a2a49cba7c07f99c4e0836572eb84ba6ded + Author: Johannes Laire + Date: Mon Nov 21 10:30:40 2016 -0500 + + [algorithms, containers, future] Add \tcode + + commit e5136d1d0a3495cc1365d141f7d5a42a7c5ed7cb + Author: Johannes Laire + Date: Mon Nov 21 10:29:33 2016 -0500 + + [dcl.enum, path.modifiers] Fix typos + + commit f1afd40ef0e8929391bc39100d0332742cdb5184 + Author: Jens Maurer + Date: Sun Nov 20 22:23:02 2016 +0100 + + Replace \textit{cv} with \cv{} or \cvqual{...} as appopriate. (#1081) + + commit 0a22a24110b8a239e283e46959b955ada170fee1 + Author: Jens Maurer + Date: Sun Nov 20 22:21:58 2016 +0100 + + [temp.variadic] Move example so that it attaches to the correct paragraph. (#1082) + + Fixes #964. + + commit e028d7033c17ddc0fab7467761edf127797ade1d + Author: Jens Maurer + Date: Sun Nov 20 22:21:33 2016 +0100 + + [dcl.ref] Introduce the phrase 'reference collapsing' in a note. (#1083) + + Fixes #546. + + commit 5e506593bd5a0ba684bfe387c2b841710133f2fb + Author: Jens Maurer + Date: Sun Nov 20 21:44:26 2016 +0100 + + [associative.reqmts], [unord.req] Fix typo in precondition for the 'merge' member function. (#1080) + + Fixes #919. + + commit 24fb65b27efa04ca018e5fa7b4b026fe3c089216 + Author: Thomas Köppe + Date: Sun Nov 20 18:33:38 2016 +0000 + + [basic.lookup.classref] Replace unnecessary use of 'indented' with 'codeblock' + + commit 580dbaf49aef78c01b7986465432d0167efd5344 + Author: Thomas Köppe + Date: Sun Nov 20 18:20:46 2016 +0000 + + [conv.qual, temp.deduct.conv] Improve presentation of conversion sequences + + commit a863d2d479b3f643074d6a2bdaf0fc6253d2b7ca + Author: Thomas Köppe + Date: Sun Nov 20 17:13:24 2016 +0000 + + Remove unneeded whitespace in synopses + + commit dc3b7515e4c36298301325e5a87bfdd0d9ae43ba + Author: Jens Maurer + Date: Sun Nov 20 00:44:57 2016 +0100 + + [lib] Spell 'value-initialization' with a hyphen. (#1075) + + Fixes #510. + + commit ef536ae539c8feb8ba2e8e4609f6a41188340a66 + Author: Thomas Köppe + Date: Fri Nov 18 19:05:31 2016 +0000 + + Remove rogue namespace closing comments + + commit 5310973c4b99913f64d2bc11cea8337ea82f521a + Author: Alisdair Meredith + Date: Fri Nov 18 13:59:02 2016 -0500 + + [atomics] Clean up indexing (#1038) + + Reverse class/member names in indexlibrarymember macros to be + consistent with the prefered style in other clauses. + + Expand in the index several functions that are documented as a + pattern-match, such as fetch_add and fetch_sub. + + Replace 'atomic type' for index references with either just 'atomic', + 'atomic', or 'atomic' to follow existing conventions + for documenting templates, and to more clearly call out the larger + interfaces of the defined specializations. + + Added further indexing for a few items that had missed index entries + in the first pass. + + commit c2ae996d2f4f5438dcfc0ccffe2420d3954f2f50 + Author: timsong-cpp + Date: Fri Nov 18 13:24:45 2016 -0500 + + [container.requirements.general] Remove redundant Requires (#1044) + + The allocator requirements already require move construction to not throw, so there's no need to repeat it here. + + commit 82705c48a465b2e41ab77d59feaf5bc01fc98716 + Author: Sergey Zubkov + Date: Fri Nov 18 13:13:38 2016 -0500 + + [facet.num.put.virtuals] Provide definition of 'showpoint' and don't apply '&' twice (#1065) + + Fixes #605. + + commit 1ed585c3a461cd19fdb0e124e3b96bffe30b846a + Author: Jonathan Wakely + Date: Fri Nov 18 18:12:33 2016 +0000 + + [system_error.syn, syserr.compare] Declare all nonmembers in the synopsis (#881) + + Move definitions of less-than operators to [syserr.compare] + + Fixes #880. + + commit a15786d31a8a6f8773ed27531b30ad5cd60c906f + Author: Alisdair Meredith + Date: Fri Nov 18 12:44:25 2016 -0500 + + [numeric] Order elements correctly (#1070) + + This is the analog to ballot comment JP-21, ordering the + Requires/Effects/Returns clauses correctly through clause + 26. A couple of re-orderings are deliberately skipped, + due to a dependency in the wording, introducing terms in + the out-of-order elements. + + commit b8e0e09f33d8ac6a1420dc7142c9335351002a48 + Author: Jens Maurer + Date: Fri Nov 18 18:42:25 2016 +0100 + + [lex] Replace \term with \placeholder or \defn as appropriate (#1067) + + Partially addresses #329. + + commit 78101400763e9890085d2744a9cc352bf50892a7 + Author: Jens Maurer + Date: Fri Nov 18 18:41:41 2016 +0100 + + [variant.assign] Introduce bullets for 'If an exception is thrown...' phrases. (#1069) + + Fixes #822. + + commit 2e87ec7fd5bb8b8fa739c0f70435f2992b1972ea + Author: Jens Maurer + Date: Fri Nov 18 18:41:16 2016 +0100 + + Improve line breaking (resolves some 'Overfull \hbox' warnings) (#1068) + + Partially addresses #693. + + commit 7bcebfc762c07fa0e92be4f359afa4110a117720 + Author: Johannes Laire + Date: Fri Nov 18 00:26:30 2016 +0000 + + [container.requirements] Improve punctuation (#1037) + + commit 464156d15fc72ba0d908a84a45aa67a57800d940 + Author: Richard Smith + Date: Thu Nov 17 16:05:14 2016 -0800 + + NB GB-67 (C++17 CD): [charname] [lex.name]: Integrate Annex E contents + into description of identifiers. + + commit 32df76cdac626ee9b1ef2dc6f07368152f1b536f + Author: Johannes Laire + Date: Fri Nov 18 00:04:20 2016 +0000 + + [container.requirements] Consistent semicolons in tables (#1034) + + commit 6233e94a9bd4b2df3f8e92509dd62b88ed5af9da + Author: Thomas Köppe + Date: Thu Nov 17 22:32:12 2016 +0000 + + [diff.mods.to.definitions] Add entry for 'nullptr_t in stddef.h' (#1056) + + commit 4dcde4a386a1db07c6e0730b89ab640c971debfa + Author: Jens Maurer + Date: Thu Nov 17 23:30:50 2016 +0100 + + [expr.rel] Complete the definition of 'compares greater than' (#1015) + + Fixes #435. + + commit 752303398df5762fa6b4836c62ec5b0c12d02030 + Author: Jens Maurer + Date: Thu Nov 17 23:27:51 2016 +0100 + + [over.match] 'underlying type' for a reference is undefined (#1013) + + Fixes #391. + + commit 5ee7f40a75c39b23cab87ae520a593a5229e6b02 + Author: Jens Maurer + Date: Thu Nov 17 23:25:48 2016 +0100 + + [intro.multithread] add 'std' to standard library names (#1003) + + remove redundant description of same-thread signal handler execution + Fixes #285. + + commit c9189b97256ae75be317e579ed3eaace3491470d + Author: Jens Maurer + Date: Thu Nov 17 22:34:29 2016 +0100 + + [utilities], [futures.task] Use 'not defined', not 'undefined', to present library declarations of primary templates that are not supposed to have a definition. (#1063) + + Fixes #528. + + commit 710d2f87b5437173bdaebb5b374e3ec27becdac0 + Author: Johannes Laire + Date: Thu Nov 17 20:53:28 2016 +0000 + + Use \tcode{true} and \tcode{false} consistently (#977) + + commit 0838cf97543b9f8f82cc9efedae960dccb177010 + Author: Jens Maurer + Date: Thu Nov 17 19:14:52 2016 +0100 + + [intro] Replace \term with \placeholder or \defn as appropriate (#1062) + + Partially addresses #329. + + commit 6e498da00b2b1a5a448b93f6ad7d5921556cd815 + Author: Jens Maurer + Date: Thu Nov 17 19:06:35 2016 +0100 + + [basic] Replace \term with \defnx as appropriate (#1061) + + Partially addresses #329. + + commit 7d68bf4083a94358baf57fa73d43a99446f5f352 + Author: Jens Maurer + Date: Thu Nov 17 19:01:59 2016 +0100 + + [macros.tex et al.] Define a new macro \caret and apply it. (#1050) + + Fixes #205. + + commit c3c8081c3487d2a6c653ac06720c78afc6e91a79 + Author: Thomas Köppe + Date: Thu Nov 17 15:59:19 2016 +0000 + + [atomics] Further whitespace/italic correction improvements, reflow introductory comments + + commit ba75a0e4cc9459dce9da038d77f9d4836aa896e7 + Author: Thomas Köppe + Date: Thu Nov 17 15:15:05 2016 +0000 + + [atomics] Better use of \placeholders, cleanup. + + Also improves whitespace, italic correction and alignment. I also included a few drive-by fixes where placeholders should have been used but weren't. + + See also #1060. + + commit 96b4cd28a2bc75b6f70139c0296be382f180cf8d + Author: Jens Maurer + Date: Thu Nov 17 15:14:24 2016 +0100 + + [diff.cpp03.input.output] Use code font for 'explicit' (#1059) + + Fixes #1019. + + commit 2d748554921139b61c1091d3c0184490e364695a + Author: Thomas Köppe + Date: Thu Nov 17 04:06:12 2016 +0000 + + [localization] Make punctuation more uniform + + commit ac0727870d2e8f0379dedd8ff59b193964294eda + Author: Thomas Köppe + Date: Thu Nov 17 03:53:42 2016 +0000 + + [strings] Make punctuation more uniform + + commit 3bcc5f2aaabb423c3c1046f9a7ed9183d2413b22 + Author: Thomas Köppe + Date: Thu Nov 17 03:10:09 2016 +0000 + + [utilities] Make punctuation more uniform + + commit 0289b1bb4c5d73c67931cae74136b87e9331555a + Author: Thomas Köppe + Date: Thu Nov 17 03:19:11 2016 +0000 + + [dcl.type.cv] Remove paragraph break inside intra-paragraph example + + commit 73bff4c27ce2125dc8720b5d24fe658a2018a4df + Author: Jens Maurer + Date: Thu Nov 17 03:23:46 2016 +0100 + + Change 'result is undefined' to 'has undefined behavior' (#1042) + + Fixes #557. + + commit e4e0cc63fd63b7dbdd5d8341dc3763f5c2a7f37a + Author: Johannes Laire + Date: Thu Nov 17 02:21:59 2016 +0000 + + [intro.scope, namespace.udecl, temp.deduct.type] Avoid "and so" (#1030) + + * [intro.scope] Change "and so" to "so" + + * [namespace.udecl] Rephrase a sentence + + * [temp.deduct.type] Change "and so" to "so" + + commit a5e70c64564bd9e1924388972465e0ef71513a06 + Author: Richard Smith + Date: Wed Nov 16 17:52:41 2016 -0800 + + NB GB-37 (C++17 CD): [cstdlib.syn] Move into Clause 18. It doesn't + really fit well anywhere, but this is better than including it in Clause + 17 at least. + + commit 65859b3bc7924c78e5a2e8cbcd71106ff23eeb5d + Author: Jens Maurer + Date: Thu Nov 17 03:13:01 2016 +0100 + + NB GB-52 (C++17 CD): [utility] shorten stable names (#1048) + + memory.resource -> mem.res + optional.bad_optional_access -> optional.badaccess + memory.polymorphic -> mem.poly + func.searchers -> func.search + ... boyer_moore -> ... bm + ... boyer_moore_horspool -> ... bmh + + commit 23b1faa028cfb58d0c0df9cf70c044514d931aa7 + Author: Thomas Köppe + Date: Thu Nov 17 02:00:21 2016 +0000 + + [diff.library] Remove listings of content shared between C and C++. Resolves LWG 2201. (#1052) + + Annex C should only list the *differences* from C. Listing common content is not so useful, and hard to maintain. + + Fixes #1006. + + commit aaf284bf6b9b7ebaf4d90ef79a41bbf71b098c5d + Author: Thomas Köppe + Date: Thu Nov 17 00:02:50 2016 +0000 + + [pairs.pair] Minor line breaking improvements; avoid overlong lines. + + See #693. + + commit ddc64ff8409b855d4989139807ca8c5f41732986 + Author: Richard Smith + Date: Wed Nov 16 15:49:25 2016 -0800 + + NB GB-34 (C++17 CD): [contents] A macro is not an entity, don't claim it + is. + + commit 32b2de88091568a0d76f4d94f62af325c69c7485 + Author: Richard Smith + Date: Wed Nov 16 15:38:09 2016 -0800 + + NB GB-31 (C++17 CD): [defns.traits] Remove apparent definition of term + "character traits" in non-normative text. This "definition" was both + redundant and incorrect. + + commit fd1204eda92479a17463869c6688ae75caf7e67c + Author: Richard Smith + Date: Wed Nov 16 15:35:42 2016 -0800 + + NB GB-7 (C++17 CD): [intro.object] Add example where multiple array + objects could provide storage for the same object. + + commit e62da07ddda54b9441f7bd82ba60d196efedbcb9 + Author: Richard Smith + Date: Wed Nov 16 15:27:49 2016 -0800 + + NB US-180 (C++17 CD): [variant.variant] Rename section to "Class + template variant". + + commit 662ddc7975dafdef16560e6568db506d39c9d6b6 + Author: Richard Smith + Date: Wed Nov 16 15:23:10 2016 -0800 + + NB US-179 (C++17 CD): [optional] Replace "optional for object type" with + just "optional object", and likewise rename stable name from + [optional.object] to [optional.optional]. + + commit 4fde500ca5d1c006aa7f24de57573af73f654718 + Author: Richard Smith + Date: Wed Nov 16 15:01:52 2016 -0800 + + NB US-173 (C++17 CD): [cstdlib.syn] Add 'noexcept' to synopsis to match + detailed description of abort, atexit, at_quick_exit, _Exit, quick_exit. + + commit b9330baf6b5d3be147e9dd5d3d79b6d601bd04d1 + Author: Jens Maurer + Date: Wed Nov 16 23:58:51 2016 +0100 + + [exception] Rephrase to avoid overfull hbox (#1057) + + See #693. + + commit 71c347edcd2fc76a1591fff88249ec37985a3770 + Author: Richard Smith + Date: Wed Nov 16 14:55:58 2016 -0800 + + NB US-133 (C++17 CD): [util.smartptr.shared.const] Remove redundant + restatement that this constructor enables shared_from_this. That is + already implied by the "equivalent to" wording earlier in the paragraph. + + commit e4d752459ed6708d62cbc2646e38ad02ceaa1182 + Author: Richard Smith + Date: Wed Nov 16 14:53:29 2016 -0800 + + Revert "NB JP-3 (C++17 CD) [basic.stc] Use 'new-expression' instead of 'operator new'" + + CWG have requested that this NB comment be reassigned to them for + further rewording, so we're leaving the baseline text alone. + + This reverts commit c455680e44f1dc4a3fa499820eb0a9658700ce45. + + commit 35aa4ad6361cdb14e28a50a7452d7a1c98a7ffe8 + Author: Thomas Köppe + Date: Wed Nov 16 19:11:50 2016 +0000 + + [cstring.syn] Remove erroneous space + + commit 5688dd45fe3c86eddfd7faf9e718417635b94549 + Author: Thomas Köppe + Date: Wed Nov 16 15:48:10 2016 +0000 + + [headers] Reflow 'Annex-K' table to fit on the page + + commit abbd013dd258df1c50fb4c852105f7ec892b21fd + Author: Jens Maurer + Date: Wed Nov 16 16:21:09 2016 +0100 + + Replace 'run-time' by 'runtime' for consistency. (#1053) + + Fixes #167. + + commit 10b453d8c2087823df2cc407d4bfafca0b9b7f6b + Author: Thomas Köppe + Date: Wed Nov 16 15:08:16 2016 +0000 + + [headers] Remove erroneous whitespace + + commit 0310ba0b7ff38e58041c25466b20ce777d0a8b22 + Author: Thomas Köppe + Date: Wed Nov 16 04:12:18 2016 +0000 + + [diff.mods.to.definitions] Harmonize presentation of wchar_t vs char{16,32}_t + + Part of Issue #1006. + + commit 9c076ebcb70a80526e6d7675b487738158726707 + Author: Thomas Köppe + Date: Wed Nov 16 03:47:19 2016 +0000 + + [diff.mods.to.headers] Explain what happened to meaningless C headers (#1051) + + commit 9df9501ad3fa4f91f79e1963382cfa84fc6b251e + Author: Thomas Köppe + Date: Wed Nov 16 02:08:17 2016 +0000 + + [cstdlib.syn, csignal.syn] Introduce exposition-only function types with C and C++ language linkage to improve the presentation of C library functions that take callbacks. (#1049) + + This change improves correctness, since we never meant to specify the language linkage of the function names, but only of the callback parameter type. + + Fixes #1002. + + commit 74ccbfc749da14a12a2a84e5a94ec17a886349fe + Author: Thomas Köppe + Date: Wed Nov 16 01:01:13 2016 +0000 + + [diff.library] Add entries for stdalign.h, stdbool.h and wchar.h + + commit 066aba68cacb2188eee7d8e728ce556e852c822e + Author: Thomas Köppe + Date: Wed Nov 16 00:09:03 2016 +0000 + + Late 15 (C++17 CD): [path.gen] Simplify and clarify specification of lexically_relative (#1036) + + commit baba3a117601c2a8838572c2358ac8846fc6c937 + Author: Thomas Köppe + Date: Tue Nov 15 22:39:53 2016 +0000 + + [depr.str.strstreams] Update cross-references to C synopses + + commit 383eb251f0256a0ce766f868d3512b5f4bada18c + Author: Thomas Köppe + Date: Tue Nov 15 22:19:51 2016 +0000 + + [cfenv.syn] Fix 'see below' styling + + commit 9d81196d42f0fc9b0c3855f95f21140e870b567c + Author: Thomas Köppe + Date: Tue Nov 15 22:02:12 2016 +0000 + + [diff.mods.to.definitions] Add new entry for 'static_assert' + + commit f2fa62f00922a41a70b1f078d49ea48ad842c288 + Author: Thomas Köppe + Date: Tue Nov 15 18:41:22 2016 +0000 + + [diff.library] Update references to the main text. + + The references should have been updated part of P0175. + + Also add "aligned_alloc", which was added in P0063. + + See also Issue #1006. + + commit 8b205506a5008596bdbebf0e489c587b03c49e5d + Author: Casey Carter + Date: Mon Nov 14 18:40:08 2016 -0800 + + [algorithms.general] Fix typo (add missing "s") (#1047) + + commit a5b59b1deaeb9ff88aab1638e05536b8d771d72c + Author: Alisdair Meredith + Date: Mon Nov 14 18:28:59 2016 -0500 + + [strings] Index cstd header synopses + + Adds entries to the library index for every cstd... header + in the strings clause, pointing to their synopsis. + + commit 8868c58632d8da1cc84f676d2659504fee7db31d + Author: jensmaurer + Date: Tue Nov 15 00:12:53 2016 +0100 + + [dcl.align] Avoid 'shall' for a requirement on the implementation (#1043) + + Fixes #493. + + commit 7fe7d133ec25afcaccf35894928a1572d828f067 + Merge: 72cc920 b95372b + Author: Thomas Köppe + Date: Mon Nov 14 23:11:55 2016 +0000 + + [meta] Add cross-references to 'referenceable type' (#1041) + + Fixes #297. + + commit 72cc920eed189894cdcb0d0bffb7bd65a177b8c3 + Author: jensmaurer + Date: Tue Nov 15 00:11:01 2016 +0100 + + Replace 'sub-clause' by 'subclause' (#1040) + + Fixes #497. + + commit e0f0311b6cd909da4d1e306d8786636312cac11c + Merge: 3b22c87 c909c62 + Author: Thomas Köppe + Date: Mon Nov 14 14:41:37 2016 +0000 + + [lex.ext] Add hyphen in index entry for 'user-defined literals' (#1039) + + Fixes #628. + + commit 3b22c8749c9ac4de17c5554657b7a2209c9a6ca9 + Author: Thomas Köppe + Date: Sun Nov 13 19:05:57 2016 -0800 + + Late 42 (C++17 CD): [fs.op.file_size] Add missing argument for file_size + + commit ff616485ff9a6ddb3d5ec395b3b4aa566a14eb30 + Author: Johannes Laire + Date: Mon Nov 14 01:59:16 2016 +0000 + + Add missing whitespace (#1035) + + commit 27b46764e5a7db52bd1d6f21e6c73b26c494918e + Author: Richard Smith + Date: Sun Nov 13 14:50:09 2016 -0800 + + US NB-136 (C++17 CD): [util.smartptr.shared.cast] Remove repeated + specification of the return value of shared pointer casts. + + commit a8f966f5fac9517d383eade7af49cff56d25de67 + Author: Richard Smith + Date: Sun Nov 13 14:44:54 2016 -0800 + + NB US-120 (C++17 CD): [variant.get] Remove redundant requirement that + get is not used. + + commit e6d9dfffc2bd9d9fcf67a273fb3574e3f77ab92b + Author: Richard Smith + Date: Sun Nov 13 14:36:14 2016 -0800 + + NB US-96 (C++17 CD): [dcl.decomp] Rearrange to number elements from 0 + instead of from 1. + + commit 219538a7be4f3e71f05070d1a52aa7150505e732 + Author: Richard Smith + Date: Sat Nov 12 13:45:14 2016 -0800 + + [diff.special] Remove incorrect suggestion that volatile-qualified + special member may be defaulted. + + Editorially fixes CWG2221. + + commit 1a277130f140afc793d7d5a22c93a8a0ea5d10c5 + Author: jensmaurer + Date: Sun Nov 13 23:26:44 2016 +0100 + + [string.require] Add note that traits::char_type is the same as charT for basic_string specializations. (#1029) + + Fixes #198. + + commit c5b7a6ba233f8bdd434db436a7de3807aebc5fef + Author: jensmaurer + Date: Sun Nov 13 23:23:57 2016 +0100 + + [expr.const] Avoid 'value' of a glvalue in definition of constant expressions. (#1028) + + Fixes #594. + + commit b7b273f3d58ee5101ccc5c5a08115c7c1b3413f8 + Author: jensmaurer + Date: Sun Nov 13 16:18:19 2016 +0100 + + Harmonize formatting of 'cv' in 'cv-qualified' + Fixes #798. + + commit a389fa642edf19af885e01740fe20ad0622bc032 + Author: jensmaurer + Date: Sun Nov 13 15:42:50 2016 +0100 + + [class.this], [temp.param] 'cv-qualified' should never be \grammarterm'd + Fixes #798. + + commit cf099ae6b4fccd8a98bf03c46cdd3110d9cd9d69 + Author: Thomas Köppe + Date: Sun Nov 13 16:25:35 2016 +0000 + + NB JP-21 (C++17 CD): [algorithms] Order elements consistently + + commit d0ea7cf85301da153f7a3288a46647698bfc8d44 + Author: jensmaurer + Date: Sun Nov 13 17:08:36 2016 +0100 + + [vector.bool] Excise use of undefined term 'conversion operator' (#1018) + + Fixes #444. + + commit 407ecd72a77d73b12a3039aa6bb664b539a7d2a8 + Author: jensmaurer + Date: Sun Nov 13 17:05:09 2016 +0100 + + [namespace.udecl] Remove stray newline in grammar production (#1026) + + Fixes #482. + + commit fda0b03c9bfb3f75aed513d463205b93f6aa65cc + Author: jensmaurer + Date: Sun Nov 13 17:01:52 2016 +0100 + + [expr.dynamic.cast] Remove redundant specification of value category for a dynamic_cast to reference type. (#1024) + + Fixes #450. + + commit 16e5d80b3a53b1581dee8ceeb7f8b01e63926bda + Author: jensmaurer + Date: Sun Nov 13 16:59:39 2016 +0100 + + [type.descriptions.general] Remove reference to undefined library concepts. (#1023) + + Fixes #455. + + commit 39f748eaee65d0f71c921c3eb4197117a2f5a5f5 + Author: jensmaurer + Date: Sun Nov 13 16:55:48 2016 +0100 + + [atomics] Fix standard-layout requirement for atomic types (#1021) + + Fixes #506. + + commit b7de198005c93c493afb6863e22b4b0b74b25185 + Author: jensmaurer + Date: Sun Nov 13 16:49:50 2016 +0100 + + [intro.execution] Adjust example to new rules for sequencing of expressions. (#1020) + + Fixes #953. + + commit 6d379965896494e80c52930ff3ed15c7733d8c6b + Author: jensmaurer + Date: Sun Nov 13 07:44:16 2016 +0100 + + [containers] 'const iterator' should be 'constant iterator' (#1012) + + Fixes #386. + + commit df9f0c83eb865778955700065d722de9fd4966d5 + Author: jensmaurer + Date: Sun Nov 13 06:30:30 2016 +0100 + + [dcl.type.simple] Add decltype(auto) to the table giving meaning to simple-type-specifiers. (#1016) + + Fixes #436. + + commit 679b0edf34ffb7c849458ce83b9e6159d43ecd10 + Author: jensmaurer + Date: Sun Nov 13 06:25:20 2016 +0100 + + [any,thread] Whitespace for template parameter packs (#1014) + + Fixes #430. + + commit c1998d328b69d9833869a6f3639d5ebef88972a0 + Author: jensmaurer + Date: Sun Nov 13 06:22:40 2016 +0100 + + [class.ctor] Split into numbered paragraphs (#1011) + + Fixes #379. + + commit 6ac49c9f39966eae2b268995c11e4032171b2653 + Author: jensmaurer + Date: Sun Nov 13 06:21:44 2016 +0100 + + [facet.num.get.virtuals] Clarify 'fails to convert' for empty sequence (#1010) + + Fixes #378. + + commit c3d32741fd36b7c821d283b8e0d331d9775bce85 + Author: jensmaurer + Date: Sun Nov 13 06:21:05 2016 +0100 + + [numeric.limits.members] Replace 'IEC 559' with 'ISO/IEC/IEEE 60559' (#1009) + + Fixes #343. + + commit f7320cd536bc9c124d475001a1e64dbf5bd490fc + Author: Thomas Köppe + Date: Sat Nov 12 21:13:13 2016 -0800 + + Capitalize notes that consist of complete sentences. + + Fixes #293. + + commit d645b2595590b8b28f1392a3bfcf21d084e4b8bd + Author: jensmaurer + Date: Sun Nov 13 06:16:36 2016 +0100 + + [lib] Modernize closing template brackets (#1008) + + Fixes #342. + + commit d6bda0d828241f231c490036103a350a0f4b002d + Author: jensmaurer + Date: Sun Nov 13 06:15:38 2016 +0100 + + [dcl.init] Clarify invocation of list-initialization for '= braced-init-list' (#1007) + + Fixes #332. + + commit 0a344234c266a90af1644be3e188b71d2f00c84a + Author: Alisdair Meredith + Date: Sat Nov 12 13:09:45 2016 -0800 + + NB US-91 (C++17 CD): [algorithm][numeric] Specify all parallel algorithms (#937) + + Also addresses US-157, US-183, JP-23 + + Add a copy of the parallel algorithm signature below each corresponding + non-parallel signature in the specification for each algorithm in the + and headers. This is *mostly* an exercise in + copy/paste - however a small subset of algorithms have wording that + either refers to the signatures obliquely, requiring a minor wording + tweak, or uses the 'Effects: as if ...' formulation, which requires a + separate specification for the parallel form to perfectly forward the + execution policy. + + A further tweak disambiguates the indexing of the various 'move' + functions. + + commit 411f35a2aa57681f11018a2914efb19bd9920a6b + Author: Richard Smith + Date: Sat Nov 12 11:47:39 2016 -0800 + + [expr.call], [expr.static.cast]: Convert one copy of rule on calling a + function through a wrong-typed function pointer to a note. Fix + incompleteness of the other copy of the rule. + + Editorially fixes CWG2215. + + commit 6953b24c045895770f089a1c04da8e46007348af + Author: Richard Smith + Date: Sat Nov 12 09:39:49 2016 -0800 + + [special] Clarify that we are using overload resolution to determine the + corresponding constructor, not performing overload resolution "on" it + (whatever that might mean). + + Editorially fixes CWG 2197. + + commit 829560f0630a9f553ee722c50b12ccb7b3f6fa47 + Author: jensmaurer + Date: Sat Nov 12 17:41:09 2016 +0100 + + [func.bind.bind] Fix intro sentence for local definitions (#1005) + + Fixes #301. + + commit 364c9624cf656a608bf6399f2ffaeec3d98a9dbf + Author: Alisdair Meredith + Date: Sat Nov 12 08:38:50 2016 -0800 + + [lex.literal] Consistent indexing of 'prefix' and 'suffix' (#932) + + Provide a consistent indexing of integer, character, and string + literals - particularly regarding prefix and suffix entries that + were not completely indexed before. + + commit e974f194a43ed93f96adfaa1f63b43a42631c248 + Author: jensmaurer + Date: Sat Nov 12 17:36:26 2016 +0100 + + [diff.cpp11.lex] Fix example for digit separators (#1004) + + Fixes #306. + + commit 337fd045eb3699afb62f17e32c69668f45193b56 + Author: Alisdair Meredith + Date: Sat Nov 12 08:34:22 2016 -0800 + + [basic.link] Consistent indexing of 'translation unit' (#931) + + [basic.link] consistent indexing of 'translation unit'] + + Ensure all definitions of 'translation unit' sort together in the index, with a common spelling of the white-space. Always use the singular form of "translation unit" in the index. Use \defnx when appropriate. + + commit 9b37e81ddb0c0fcb5a11b12b1e88d4d70e8da5c0 + Author: Thomas Köppe + Date: Sat Nov 12 03:18:40 2016 -0800 + + [cpp.cond] Remove stray brace (introduced in a8654e86734a3ca1348c7e4d3de0af703f049af0) + + commit 8615adbf8bf8439d3b5eacd62589e2f236c0e18a + Author: Eelis + Date: Sat Nov 12 12:15:43 2016 +0100 + + Use the "standard library" terms defined in [intro.refs]/2 and [library.general]/1 consistently. (#934) + + commit 7c6153d34d067068ec133e04520483ac023346bb + Author: hubert-reinterpretcast + Date: Sat Nov 12 02:19:50 2016 -0800 + + [expr.reinterpret.cast]: requirement redundant with static_cast: a note it is (#996) + + commit 3cc48b76b974a76f09c57d60b2d9ca76b57cfd29 + Author: jensmaurer + Date: Sat Nov 12 08:54:05 2016 +0100 + + [lib] Replace 'Postcondition:' by 'Postconditions:' + + Fixes #282. + + commit 179eb7045f74e17fe96a464156d0363043fd08c9 + Author: jensmaurer + Date: Sat Nov 12 08:50:53 2016 +0100 + + [lib] Replace 'Remark:' by 'Remarks:' + + Fixes #282. + + commit fcf5d663cc51306c08bee76f4a1ce5b9d4cf3933 + Author: Johannes Laire + Date: Sat Nov 12 10:11:20 2016 +0000 + + [iostreams] Refer to int values as `nonzero` instead of `true` (#978) + + commit 0b5bcd518ac2d64c0a342e79841dec1e8655c93e + Author: jensmaurer + Date: Sat Nov 12 11:00:53 2016 +0100 + + [string.classes] Rename stable names 'string::*' (#999) + + commit 7cc8e898486d017babde19b0495f58dd719d104b + Author: jensmaurer + Date: Sat Nov 12 10:59:30 2016 +0100 + + [istream.extractors] Rename stable name 'istream::extractors' (#1001) + + Fixes #271. + + commit 947e6a689f859a3e7f16b78d716efbe6a3de402c + Author: JF Bastien + Date: Sat Nov 12 01:50:58 2016 -0800 + + Index entries for signed integer representations + + * Add index entries for ones' and two's complements + + * Editorial: add 'signed integer representation' index entry + + * Update location of index entry + + commit e3774214e4513ab7becad2d78cafde859db913b2 + Author: Gilbert Röhrbein + Date: Sat Nov 12 10:49:11 2016 +0100 + + Format references more consistently + + * [re.synopt, string.view.cons, string.view.comparison] table~/ref -> Table~/ref + * [expr.new] annex~/ref -> Annex~/ref + * [utility.arg.requirements] tables~/ref -> Tables~/ref + + commit 6238924fdf1bcbba8b5223df5e35463e83e469b3 + Author: Eelis + Date: Sat Nov 12 10:47:41 2016 +0100 + + Fix lots of see/seealso references, especially regarding operators. (#943) + + commit 36a454ac039fc638178f0d1175dc47f3037014b5 + Author: Eelis + Date: Sat Nov 12 10:30:04 2016 +0100 + + [expr.prim.paren] Clarify that parentheses preserve all value categories, not just lvalueness. (#915) + + commit 0f15558dd76901fadd53c65774f78296761e45fa + Author: AaronBallman + Date: Sat Nov 12 04:28:44 2016 -0500 + + [expr.call] Use a more idiomatic way to specify the expression has undefined behavior (#898) + + commit 112f0da88f7112ba706d76f35b7ca85f0c5e0477 + Author: Jonathan Wakely + Date: Sat Nov 12 08:59:37 2016 +0000 + + [atomics.order] Remove redundant typedef-name for memory_order (#851) + + * [atomics.order] Remove redundant typedef-name for memory_order + + * [atomics.flag] Remove redundant typedef-name for atomic_flag + + commit 67d476ce3c9d47f8f6f5e157fc0340cdf6825a13 + Author: AaronBallman + Date: Sat Nov 12 03:57:58 2016 -0500 + + [future.async]p3 Use neither/nor and capitalize sentences properly (#827) + + commit fa639c445f70e6f5c065954bfcb182442ad53620 + Author: FrankHB + Date: Sat Nov 12 16:56:35 2016 +0800 + + [gram] Change "syntax" to "grammar". (#790) + + Annex A is a summary of grammar, but not only syntactic grammar. Even in contexts without need of grammatical disambiguation, pure syntactically handling (reduction merely based on parsing of the token stream without semantic information) of several context-sensitive constructs (e.g. constant-expression and several kinds of type-id) has already been insufficient. Since the remained difference is acknowledged in the same paragraph, I think my change is also editorial. (On the contrary, ISO C may have more problems because it uses "syntax" everywhere.) + + commit 984ef4a18b5892d304d111f3853e12b2ab1670b4 + Author: Thomas Köppe + Date: Sat Nov 12 00:20:33 2016 -0800 + + NB JP-24 (C++17 CD): [alg.permutations.generators] Separate 'returns' from 'effects' + + commit 472a71760200dba263be043d222c83ae53551423 + Author: Thomas Köppe + Date: Sat Nov 12 00:04:51 2016 -0800 + + NB JP-22 (C++17 CD): [mismatch] Simplify specification of std::mismatch + + commit 25becfcbfba170c8de030a80c81bb1740dbcfecd + Author: Alisdair Meredith + Date: Fri Nov 11 23:24:59 2016 -0800 + + [defns.referenceable] Clean up definition text + + Definitions should start with a lower-case letter. The paragraph + defining referenceable erroneously starts with a leading space. + + commit 56bfdac1f93b8a877ff24c5d61248623e81fbaad + Author: jensmaurer + Date: Sat Nov 12 08:21:15 2016 +0100 + + [string::compare] Replace 'smallest' by 'smaller' (#998) + + Fixes #270. + + commit b6d93f8a67c8d3b1178dba2b551e2529e0d0cc4a + Author: jensmaurer + Date: Sat Nov 12 08:20:40 2016 +0100 + + [string.capacity] Improve max_size() description by copying from string_view (#994) + + Fixes #255. + + commit 131716c43342b2f9b7c789289a77ed9126bedfa4 + Author: Richard Smith + Date: Fri Nov 11 23:14:00 2016 -0800 + + NB US-90 (C++17 CD): [algorithms.parallel.exec] Add cross-reference to + section describing execution policies. + + commit d0e5d065629048c1b279e5f30d111d7fb7a6aedd + Author: Alisdair Meredith + Date: Fri Nov 11 22:50:09 2016 -0800 + + NB GB-8 (C++17 CD): [intro.object] Clearer definition for 'complete object' (#991) + + commit 5c0f40cae5424a1fe5cb4c720e2ce51e54c67dec + Author: jensmaurer + Date: Sat Nov 12 07:43:59 2016 +0100 + + [alg.reverse] Use ValueSwappable instead of swappable requirement (#993) + + Fixes #210. + + commit a8654e86734a3ca1348c7e4d3de0af703f049af0 + Author: Thomas Köppe + Date: Fri Nov 11 22:29:46 2016 -0800 + + NB JP-18 (C++17 CD): [cpp.cond] Split up long paragraph and incorporate footnotes as notes + + commit 4bcaad233a6bd87c67a905112af48850ab5907a6 + Author: jensmaurer + Date: Sat Nov 12 07:25:16 2016 +0100 + + [intro.races] remove redundant constraint on modification order (#990) + + Fixes #159 + + commit 6621ef71a7de1e5e6b1be26fc7bd8348d0fb6656 + Author: Alisdair Meredith + Date: Fri Nov 11 22:13:47 2016 -0800 + + NB GB-29 (C++17 CD): [intro.defs] Move definitions of 'block' and 'unblock' to Clause 1 + + Move the definitions of block and unblock to the clause 1 + definitions subclause, rather than the library definitions + subclause, as the memory model relies on these terms. + + commit 93fd82d142809d0896981851746a281d561412a4 + Author: Bekenn + Date: Fri Nov 11 22:05:29 2016 -0800 + + Updated required package list. (#986) + + commit d0e9ca76ef04eb05e284435e5c6a7bd4b18d6544 + Author: jensmaurer + Date: Sat Nov 12 07:03:37 2016 +0100 + + [class.dtor] Add paragraph number (#987) + + Fixes #144. + + commit 2a96241e384fa628da8f66013d3aa460a5eb353e + Author: Alisdair Meredith + Date: Fri Nov 11 22:00:29 2016 -0800 + + NB GB-48 (C++17 CD): [parallel.execpol.objects] Simplify stable tag (#988) + + commit ee809590378c2252b5c4a2b734ccb121211c7e63 + Author: Thomas Köppe + Date: Fri Nov 11 21:58:47 2016 -0800 + + NB JP-13 (C++17 CD): [class.friend] Fix reference to 'inline' + + commit 554514cc9508d660cacc7f559c584fdd459b2fb5 + Author: Richard Smith + Date: Fri Nov 11 21:57:30 2016 -0800 + + NB US-88 (C++17 CD): [execpol.seq] Rename "Sequential" -> "Sequenced" + + commit d47d5ca45cdf5ff9a4018f264e917b908511e9e0 + Author: Richard Smith + Date: Fri Nov 11 21:45:43 2016 -0800 + + NB US-39 (C++17 CD): [fs.def.parent] Remove meaningless note. + + commit b598c94e0d1ad9ea17872244315425abceb0702d + Author: Thomas Köppe + Date: Fri Nov 11 21:45:18 2016 -0800 + + NB JP-12 (C++17 CD): [class.mi] Refer to figures by number + + commit adb0da05b5b94ce699d232ae68a82d64bea01f02 + Author: Richard Smith + Date: Fri Nov 11 21:42:32 2016 -0800 + + NB US-38 (C++17 CD): [fs.def.ntcts] Remove redundant definition. + + commit fb925656add6108e0f32b049ae4e907d8a6b9e5e + Author: Richard Smith + Date: Fri Nov 11 21:36:17 2016 -0800 + + NB US-27 (C++17 CD): [class.base.init] Fix overly-wide space between + "side" and "effect" in comment in example. + + commit 27de65a2a57ac52ad3a3b96dc87cdbe9a56a6d00 + Author: jensmaurer + Date: Sat Nov 12 06:33:23 2016 +0100 + + [dcl.init] Don't mention expression where braced-init-list may appear (#985) + + fixes #150 + + commit a8d8923438bbf02bd9295c741d61caccd94861f2 + Author: Alisdair Meredith + Date: Fri Nov 11 21:27:07 2016 -0800 + + NB GB-33 (C++17 CD): [objects.within.classes] Change 'external behavior' to 'observable' (#983) + + commit 94244ddf94a7e18f06f15d723ca5f07fc24a20c4 + Author: Alisdair Meredith + Date: Fri Nov 11 21:25:52 2016 -0800 + + NB GB-32 (C++17 CD): [defns.additional] Make this clause a note in [definitions] (#982) + + commit 85aac089757a373d9a675442de93dbad5babce8f + Author: Richard Smith + Date: Fri Nov 11 21:14:35 2016 -0800 + + NB US-26 (C++17 CD): [class.ctor] Demote redundant "either no parameters + or [all parameters have a property]" to a parenthetical. + + commit 799748771a59b234812d5f02144de8716a640458 + Author: Richard Smith + Date: Fri Nov 11 21:04:27 2016 -0800 + + NB US-13 (C++17 CD): [meta.unary.prop] Rephrase Condition for + `is_destructible` to avoid use of `is_destructible::value`. + + commit aa74ca01a5f6fd9a720e91a49da505f031778144 + Author: Thomas Köppe + Date: Fri Nov 11 21:02:42 2016 -0800 + + NB JP-9 (C++17 CD): [dcl.fct.def.delete] Fix reference to 'inline' + + commit 3e0038a38c202ae4929c2e49128a35587c4620f7 + Author: Thomas Köppe + Date: Fri Nov 11 20:58:30 2016 -0800 + + NB JP-5 (C++17 CD): [conv.rval] Add missing semicolon + + commit 76308413b7c7937afd0009cf3ecc7de36ec10781 + Author: Thomas Köppe + Date: Fri Nov 11 20:55:37 2016 -0800 + + NB JP-4 (C++17): [basic.life] Fix example to say '*pb', not '&pb' + + commit 4fa3ef43e2f4d9562d75b1c5ec28d2037719cb97 + Author: Alisdair Meredith + Date: Fri Nov 11 20:51:57 2016 -0800 + + NB GB-11 (C++17 CD): [intro.memory] Add a footnote referencing CHAR_BIT + + commit c455680e44f1dc4a3fa499820eb0a9658700ce45 + Author: Thomas Köppe + Date: Fri Nov 11 20:49:36 2016 -0800 + + NB JP-3 (C++17 CD) [basic.stc] Use 'new-expression' instead of 'operator new' + + commit 0fdcc1abfb5ef6e055979d5b84f14fded6f40f6c + Author: Richard Smith + Date: Fri Nov 11 20:37:58 2016 -0800 + + NB US-12 (C++17 CD): [meta.unary.prop] Remove (subtly) redundant uses of + bool_constant from definition of is_signed and is_unsigned. + + commit 942b3fbcc808f867f55efda94b0f2d88d35d3d6d + Author: Thomas Köppe + Date: Fri Nov 11 20:36:03 2016 -0800 + + NB JP-1 (C++17 CD): Update reference to C11 + + commit c663f13244de12123744d9da5ae0dc0cd8cc480c + Author: Richard Smith + Date: Fri Nov 11 20:30:37 2016 -0800 + + NB US-11 (C++17 CD): [meta.unary.prop] Replace + has_unique_object_representations::value with _v form in one place + and remove ::value in another, for consistency with similar + specifications. + + commit 97058f9cc925cd9a9e818545cad4e1c198d714cb + Author: Richard Smith + Date: Fri Nov 11 20:24:17 2016 -0800 + + NB US-9 (C++17 CD): [meta.type.synop] Add missing definition of + has_unique_object_representations_v. + + commit f6482016438b7d64a6eaf1c8b250d6911143e06f + Author: Thomas Köppe + Date: Fri Nov 11 20:24:20 2016 -0800 + + NB ES-3 (C++17 CD): [depr.static_constexpr] Change redeclaration to use 'constexpr' instead of 'const' + + commit 1beaf17ee237b344aba87966ef7d4f31eea72cb8 + Author: Richard Smith + Date: Fri Nov 11 19:38:00 2016 -0800 + + [meta.rel] Massage Comments for is_base_of to avoid unclear phrasing. + + commit f8f56a38f6636aa159acb91ab3c3bf2896482179 + Author: Richard Smith + Date: Thu Nov 10 15:14:29 2016 -0800 + + [diff.expr] Document that C++ does not support decrement on bool, unlike C. + + Fixes CWG2184 + + commit 84cb65298006c22747d31aeb983fd3d93b6ae43b + Author: Richard Smith + Date: Mon Nov 7 16:48:19 2016 -0800 + + NB GB-24 (C++17 CD): [except.handle] Fix incorrect example. + + commit e11da84f160df97ab05f84ee5920d3f26b501ea8 + Author: Richard Smith + Date: Mon Nov 7 16:45:14 2016 -0800 + + NB GB-22 (C++17 CD): Replace references to "raise" with "throw" when + describing exceptions. + + commit 142c82e43359be3e707f84e078386424ddedc41d + Author: Richard Smith + Date: Mon Nov 7 16:30:46 2016 -0800 + + NB GB-14 (C++17 CD): [expr.pre.inc] Remove vestigial references to increment of bool. + + commit 79e9ee94150a4db7297cc2017ceb9604dd2e2fce + Author: Thomas Köppe + Date: Fri Nov 11 11:32:47 2016 -0800 + + [basic.start.static] Add missing full stop. + + commit 46aff72f86855f4daf6f3b3c588133160aec6de1 + Author: Thomas Köppe + Date: Fri Nov 11 08:19:41 2016 -0800 + + [cpp.replace] Style 'replacement-list' as a grammar term + + commit bb4ed4cd557735f4077a4fca13aa56db44da5bbf + Author: W-E-Brown + Date: Thu Nov 10 21:13:41 2016 -0800 + + Use decay_t<> rather than typename decay<>::type. (#979) + + commit d580a0dd6ecee0d727432a7d12cf933ede89cfee + Author: JF Bastien + Date: Thu Nov 10 10:11:17 2016 -0800 + + [execpol] Remove '+' from policy name (#976) + + commit b3e942c6be2fc8742e6d394af8d5588a44f90d2a + Author: Thomas Köppe + Date: Thu Nov 10 09:38:02 2016 -0800 + + [stringstream] Fix section reference + + commit 2fc3bc0fefc2584da857ca758af0bea006652fab + Author: Antony Polukhin + Date: Thu Nov 10 21:29:40 2016 +0400 + + [sf.cmath] Make headings and stable names more accurate + + Editorial issues found by Matwey V. Kornilov from Sternberg Astronomical Institute, Lomonosov Moscow State University, Russia: + + * Clause "Associated Legendre polynomials" is wrongly entitled. "Associated Legendre functions" would be more appropriate here. Though "Associated Legendre polynomials" term is sometimes used it is formally wrong term. A polynomial (by definition) is a particular kind of function which can be represented using only finite number of additions, multiplications and exponentiations to a non-negative power, i.e. in canonical form of `SUM(AiX^i)`. Obviously, some of P^m_l are not polynomials. For instance, for m=l=1, `P11(x) == sqrt(1 − x*x)` is not representable as `SUM(AiX^i)`. See for reference: Abramowitz and Stegun, Chapter 8 "Legendre Functions". + + * "[sf.cmath.cyl_bessel]" is a bad name for the tag. "[sf.cmath.cyl_bessel]" sounds like "Bessel functions" and when people say "Bessel functions" they usually mean Jν from [sf.cmath.cyl_bessel_j]. Replaced "[sf.cmath.cyl_bessel]" with "[sf.cmath.cyl_bessel_i]". + + * "[sf.cmath.cyl_bessel_k]" misses references to "[sf.cmath.cyl_bessel_j]" and "[sf.cmath.cyl_neumann]" in the "See also" section. In [sf.cmath.cyl_bessel_j] Jv(x) is defined, in [sf.cmath.cyl_neumann] Nν(x) is defined - both of them are used in the "Returns:" section of the [sf.cmath.cyl_bessel_k]. + + commit 68f0e28c14c6ba36a31eeeb1e9fb4517a46dec87 + Author: Thomas Köppe + Date: Wed Nov 9 14:11:12 2016 -0800 + + [re] Whitespace fixes + + commit 7f692bf13dbedef3885103e6dd9030f6445d3960 + Author: Eelis + Date: Wed Nov 9 22:48:15 2016 +0100 + + [re.syn] Synchronize regex_constants synopsis with [re.const]. (#866) + + commit 7e920239a94d21b5790ca2255ee932401db7c67a + Author: JF Bastien + Date: Wed Nov 9 12:05:17 2016 -0800 + + [execpol] rename "vec" to "unsequenced" (#972) + + Update missed updates. + + commit 24d17974f117806dc9c1b23755c56e618c913ad4 + Author: Sergey Zubkov + Date: Wed Nov 9 15:03:12 2016 -0500 + + Improve comment formatting; includes replacing "file" with "translation unit" + + commit 4b774369b64f99f7285834f80e12bb9ddaee3e01 + Author: Thomas Köppe + Date: Wed Nov 9 10:49:22 2016 -0800 + + [expr] Remove accidental whitespace + + commit 2b7778ced56508aacf61cacefd0db1fb1372b6d4 + Author: Daniel James + Date: Mon Nov 7 12:33:53 2016 +0000 + + [associative.reqmts] Add missing qualification to 'mapped_type' (#968) + + commit 0824b215fdec5adba25b10203aaf0d3e4b2ccb7b + Author: S. B. Tam + Date: Wed Nov 2 09:35:05 2016 +0800 + + [syntax] Use a different example (#959) + + commit 37239df14fccaea1a2350533b86b669efbe9530c + Author: Thomas Köppe + Date: Wed Nov 2 01:34:41 2016 +0000 + + [stmt.iter] Remove superfluous and incorrect note (#960) + + The original note has become obsolete with commit f40f23d2c9b8de9eeeb781c4e7b90d056750535f. + + commit 430c40d56ee4a5756f441304512d2d04757ccbec + Author: Johel Ernesto Guerrero Peña + Date: Tue Nov 1 21:33:13 2016 -0400 + + [iterator.synopsis] Add specialization specified in [iterator.traits]/3 (#961) + + commit d5df57b34cd9bd8a72062e0d5d9627cfb772d670 + Author: Johel Ernesto Guerrero Peña + Date: Tue Nov 1 21:31:32 2016 -0400 + + [iterator.range]/1 List , specified in [string.view.synop]/1 (#962) + + commit ab40db0ba572e4ccb7007dab026791654d31832b + Author: Koichi Murase + Date: Sat Oct 22 23:20:20 2016 +0900 + + [temp.alias, rand.dist.pois.exp] Fix typos (#956) + + * [temp.alias]/1 Fix typo + + a alias template -> an alias template + + * [rand.dist.pois.exp]/3 Fix typo + + a exponential_distribution object -> an exponential_distribution object + + commit 21e3a325074aede246c1ace0a64bec0945627355 + Author: Koichi Murase + Date: Sat Oct 22 20:09:16 2016 +0900 + + [streambuf.virt.put] Fix typo (#955) + + Is is unspecified ... -> It is unspecified ... + + commit 77c0632d1514b00d04d076880df57879cde3dd5a + Author: Richard Smith + Date: Thu Oct 20 16:10:34 2016 -0700 + + [dcl.init.aggr] Replace incorrect "anonymous bit-fields" with "unnamed + bit-fields". Move restriction that only non-static data members are + aggregate elements into the definition of aggregate elements, and demote + the other occurrence of this rule to a note. + + Due to an obviously-accidental wording oversight, the previous + formulation technically included member functions and member classes as + aggregate elements. This reformulation avoids that problem. + + commit 9fe6aa53d88c77da9d64d152b8f577e153a15d3a + Author: Zhihao Yuan + Date: Tue Oct 18 12:52:21 2016 -0500 + + [stmt.stmt] use grammar term "brace-or-equal-initializer" in condition rather than expanding it into two productions + + commit 0b1495bb47d86d81724bc7d2627da15ed9db9c49 + Author: Eelis + Date: Mon Oct 17 02:28:19 2016 +0200 + + [basic, class.this, algorithms] Remove parentheses around references. (#949) + + commit b30a619cc000039c40f24b3f73a40813d10c9919 + Author: Eelis + Date: Thu Oct 13 15:36:07 2016 +0200 + + [class.conv.fct] Add missing 'the'. (#950) + + commit cae0f6d14a666dc983129f7f6c6b7597a932d7c0 + Author: Eelis + Date: Thu Oct 13 13:38:20 2016 +0200 + + [basic, stmt, dcl.dcl] Move surrounding punctuation out of \grammarterm arguments. (#948) + + commit 0b92ee326552cab2d0274573183da9acd3dc0832 + Author: Eelis + Date: Thu Oct 13 12:14:45 2016 +0200 + + [expr.reinterpret.cast] Remove unwanted whitespace after \indextext. (#947) + + commit 7cd154a00385fa398f528e0c04737f60b040f73d + Author: Richard Smith + Date: Mon Oct 10 11:10:36 2016 -0700 + + [dcl.type] Fix poor phrasing -- it's not appropriate to restrict the + defining-type-specifiers that can appear in a type-specifier-seq, since + type-specifier-seqs contain type-specifiers, not defining-type-specifiers. + + commit e1e874d361e9bd2f54b79fae61888e573cae898c + Author: Thomas Köppe + Date: Fri Oct 7 17:11:13 2016 +0100 + + [algorithms.parallel.exec] Add hyphenation hints to impldef index entry + + commit 763eb317a94d1e801157b02fc60750338d4d15dd + Author: Thomas Köppe + Date: Fri Oct 7 17:01:04 2016 +0100 + + [rand.device] Rephrase index entry for impldef behaviour to be easier to compose + + commit e69f16e7f6c418109ee36c12bf5b5b1b1086ac37 + Author: Jonathan Wakely + Date: Fri Oct 7 16:49:34 2016 +0100 + + [string::copy] Remove duplicate \pnum + + commit c6552f06c8e35020718d5bd211f7cbeef96ea1f3 + Author: Thomas Köppe + Date: Thu Oct 6 01:53:39 2016 +0100 + + [basic.def.odr] Update references to [dcl.inline] + + commit 3d807a2cf2b617804c7042b9594d0b6cc9d6fbbf + Author: Jonathan Wakely + Date: Wed Oct 5 23:10:06 2016 +0100 + + Fix comment typo in .travis.yml + + commit b071e45d1f53b7c4d363ea96b8493e2155262886 + Author: Jonathan Wakely + Date: Mon Oct 3 15:37:01 2016 +0100 + + [input.iterators] Fix formatting of parentheses and p. (#912) + + Fixes #457 + + commit 865ed277b20341bcc6073d3cb3ba59e4fcabd95c + Author: Eelis + Date: Mon Oct 3 16:32:32 2016 +0200 + + [class, class.derived, special] Write space in 'access control' consistently in index keys. (#942) + + commit 5625f78108fea82e6e0348f9455e1267b6f6a40d + Author: Richard Smith + Date: Thu Sep 29 19:13:40 2016 -0700 + + [cpp.predefined] Fix misapplication of P0035R4: the macro + __STDCPP_DEFAULT_NEW_ALIGNMENT__ should be listed in the first paragraph + of [cpp.predefined] (macros that the implementation is required to + provide), not in the second paragraph (macros that the implementation + conditionally defines). + + commit 4b2a5e599e82edb5b077e7a664e61eb54dc00b37 + Author: Eelis + Date: Wed Sep 28 06:28:19 2016 +0200 + + [extern.names] Use \tcode when referring to namespace std. (#941) + + commit 15a0972b4cb1b0bb21e1ef1dd6a292bdfd799be4 + Author: Thomas Köppe + Date: Tue Sep 27 18:26:33 2016 +0100 + + [deque] Fix index entries + + commit 1b5edf959ef6b2a66fada4e381a3e1c652f329a9 + Author: Thomas Köppe + Date: Tue Sep 27 16:07:19 2016 +0100 + + [generalindex] Fix misnested multipage index ranges + + commit b7bf4fa94b934049cb4ad53de8ea40744539b742 + Author: Thomas Köppe + Date: Tue Sep 27 15:18:25 2016 +0100 + + [thread.decaycopy] Format index entry for DECAY_COPY correctly and add a library index entry + + commit cb197a9ab4aeac754e483a07766f37cd8655aeaa + Author: Thomas Köppe + Date: Tue Sep 27 15:01:54 2016 +0100 + + [expr, except] Clean up index entry for terminate, unexpected + + commit 00b162ba76a5623439b8fee2dba465684483717b + Author: Eelis + Date: Tue Sep 27 00:24:28 2016 +0200 + + [cpp.predefined] Make description for __cplusplus non-redundant and consistent with rest. (#868) + + commit 9a27ccdbe8b15ce278b5bfbbccb118b00fd9ae34 + Author: Thomas Köppe + Date: Mon Sep 26 20:14:00 2016 +0100 + + [time.duration.nonmember] Add missing \tcode (#936) + + commit 92bf827cd2f4d4e58c68c434856b568776bc810f + Author: Thomas Köppe + Date: Mon Sep 26 19:52:27 2016 +0100 + + [time.syn] Format whitespace more consistently with the rest of the WD (#935) + + commit b3f00ef6a963bbbcfc18d56e96f0c59a806b3fdf + Author: Eelis + Date: Mon Sep 26 14:36:19 2016 +0200 + + [depr.istrstream.cons] Add missing constructor. (#878) + + commit 61c3a7507d8558e14987d820a4198df846d61b29 + Author: Thomas Köppe + Date: Mon Sep 26 01:32:45 2016 +0100 + + [rand] Format "i.e." and "e.g." consistently + + commit 5b1d1cb4649e35e351fa897fcae02f6830b972f1 + Author: Thomas Köppe + Date: Sun Sep 25 21:06:43 2016 +0100 + + [any] Add parameter name for initializer_list + + commit 8ff7ef110391d56327434ab7aebf9a2622eb7941 + Author: Thomas Köppe + Date: Sun Sep 25 20:24:12 2016 +0100 + + [tables] Remove extraneous braces that make code in tables index and space differently + + commit 38b972645ff94a48f2e96367ae75d31ce57770a8 + Author: Thomas Köppe + Date: Sun Sep 25 19:44:21 2016 +0100 + + [re] Fix typo in index ("transform_primary") + + commit 70c56d53378082d2e7d41a866c25c697921cd9ee + Author: Eelis + Date: Sun Sep 25 20:49:54 2016 +0200 + + [futures.promise] Add missing 'noexcept' for swap itemdecl. (#889) + + commit 6ced9532d2d93409a5278335ede966ef095d7c45 + Author: Eelis + Date: Sun Sep 25 20:37:26 2016 +0200 + + [class.local, facet.num.{get,put}.virtuals, temp.expl.spec] Remove stray whitespace. (#907) + + commit 11ba3a041b1aad927fba1e717cfd1a3e95eb5d23 + Author: Eelis + Date: Sun Sep 25 20:36:26 2016 +0200 + + [facet.num.put.virtuals] Fix grammar: determining -> determine. (#908) + + commit 0c671278864c492782f057b2c39e7f51c43b5c77 + Author: Alisdair Meredith + Date: Sun Sep 25 11:34:23 2016 -0700 + + [dcl.type.simple] Consistent indexing of "type specifier" (#929) + + The main index for type specifiers was split in two, due to + alternate spellings as 'type specifier' and 'type~specifier'. + Consistently use the latter, as it was the dominant form. + + commit 05c8373f19741a1d19942b95e8e4bd1a3ae34246 + Author: Alisdair Meredith + Date: Sun Sep 25 11:29:09 2016 -0700 + + [index] Consistent indexing of "name hiding" (#933) + + Ensure all index references to name hiding use the same whitespace character. + + commit 24af7d897bd168f08cfc4ae48ae743e61357a401 + Author: Jonathan Wakely + Date: Sat Sep 24 12:10:41 2016 +0100 + + [associative.reqmts] [unord.req] Fix "pointed to by to" typos + + commit d5a02cebd5b393f52896b362e436d3c42c4af310 + Author: Alisdair Meredith + Date: Thu Sep 8 20:52:34 2016 -0400 + + [meta] Add index entries for each type trait + + Create an index entry for each row in the type traits tables, + indexing the corresping trait. Where a trait is defined outside + the table, add a second index reference to the latter. This + causes an annoying duplication, as the current software sees the + index entry inside the table as in some way NOT the same as the + entry outside the table. + + Disambiguate the is_empty function from the filesystem library, + and the is_empty trait. The issue for is_signed being a trait + and a member of numberic_limits resolves itself. + + commit 8fabb00d310c879b4912d983bb4e4198242814ce + Author: Alisdair Meredith + Date: Fri Sep 23 15:59:39 2016 -0700 + + [function.objects] Use formal Returns: clause for std functors (#909) + + Revise presentation of all functors in clauses 20.14.(5-8) to use a + formal Returns: clause, consistent with the conventions laid out in + clause 17, rather than ad-hoc presentation lacking any of the + recognised markers. + + This turned into a substantial re-render. In order to break up a + wall of code with occasional normative text, I have introduced a + subsection for each class. Under each new subsection, I collect + the primary class template and the 'diamond' specialization, which + were previously separated by the intervening classes. + + commit f797a8c32980beb1c29144f53e6a6f332c32aeef + Author: Alisdair Meredith + Date: Fri Sep 23 15:52:47 2016 -0700 + + [whole standard] Audit index of implementation-defined behavior (#899) + + * Audit index of implementation-defined behavior + + Review all uses of the terms 'implementation-defined' and + 'implementation defined' in the standard, and replace with + \impldef entries in the index of implementation defined + behavior where appropriate. + + Clean up some older index entries that did not have a clear + reference, and appear to predate the index of implementation + defined behavior being added by Pete Becker for C++11. + + Changes may appear more disruptive than in practice, due to + word-wrapping reflowing a paragraph or two in the doc source, + but not on the rendered pdf. + + commit c1f3535f90a7d545ec1cbf1884ba5da6738023d3 + Author: Jonathan Wakely + Date: Thu Sep 22 20:43:54 2016 +0100 + + [container.node] Move sub-clause to after [sequence.reqmts] (#850) + + commit f295171dc9860ca3a4df9fdb2e8ea32932c2782a + Author: Alisdair Meredith + Date: Thu Sep 22 12:27:46 2016 -0700 + + [thread.once] Move struct once_flag defintion into corresponding subclause (#920) + + By convention, unless the whole specification of the class is in the + header synopsis (typically a tag type) the class should be forward + declared in the synopsis. The class definition for once_flag is moved + to 30.4.4 [thread.once]. + + commit fcf439e935e445b2f185e7aa51925e859640b4e7 + Author: Alisdair Meredith + Date: Thu Sep 22 12:24:22 2016 -0700 + + [thread] Index review clause 30 (#901) + + * turn around indexlibraryname uses + + * [thread] Review of library index + + This review handles several topic related to the index of library names: + apply indexlibrarymember for all member functions other than constructors/destructors + consistent ordering of indexlibrarymember{identifier}{class-name} + every index macro has a trailing % to avoid accidental whitespace + ensure headers are indexed with synopsis + ensure every itemdecl has a library index entry + index every class definition + + commit 7067fd1ff9a50a0f98a132c1c1b409a94649ec09 + Author: Alisdair Meredith + Date: Thu Sep 22 12:19:52 2016 -0700 + + [depr, exception.syn] Consistently move deprecated declarations to Annex D (#900) + + This change moves the deprecated declarations in the + header to Annex D, in a manner consistent with the library pattern + of fully specifying deprecated components and names in the deprecation + annex. + + Then apply consistent wording across the library parts of the annex + describing how non-deprecated headers introduce the deprecated extensions. + + Finally, ensure that the deprecated extensions to standard headers are + indexed as part of that standard header. + + commit 5126c2b681f7508e306b1b2469da9c76c9a7fc52 + Author: Jason Merrill + Date: Wed Sep 21 12:01:27 2016 -0400 + + [new.delete.array] Add missing []. (#924) + + commit f43f6966e63ba0dffb7dbf0809f481834ae51370 + Author: Johannes Laire + Date: Wed Sep 21 16:59:12 2016 +0100 + + [iterator.iterators] Remove unmatched parenthesis, formatting (#926) + + * [iterator.iterators] Remove unmatched parenthesis + + * [iterators] Add missing \tcode{} + + commit e229a482fd89f62e629893283eccb258c518a7c7 + Author: Agustín Bergé + Date: Thu Sep 15 23:40:59 2016 +0200 + + [inner.product] Fix typo (#925) + + commit 0f1335487001f480b79e2ca156bbef9bbf6ae1ba + Author: Eelis + Date: Mon Sep 12 20:11:02 2016 +0200 + + [class.base.init] Remove stray indentation in codeblock. (#923) + + commit 4df5774eb1e26246fa09684e74ca0a56ba35b385 + Author: Alisdair Meredith + Date: Thu Sep 8 18:45:06 2016 -0400 + + [thread.lock.shared] Apply conventional indent to shared_lock class definition (#921) + + The convention appears to be no blank lines between the opening + of the enclosing namespace, and the class defintion; a two-space + indent for everything inside the namespace; and no comment on + closing brace of the namespace. + + commit 6f16e580b9ab1ca6abcaa525f15881e9d40f761c + Author: Thomas Köppe + Date: Thu Sep 8 11:14:40 2016 +0100 + + [cstdio.syn] Add missing 'std' + + commit 3c01650257905276393ad520ea6afb1d77de2b87 + Author: Alisdair Meredith + Date: Thu Sep 8 06:10:30 2016 -0400 + + [lex.phases] Index and xref raw string literals (#902) + + Add a cross-reference on the reversion of universal characters in raw string + literals, as it is far from clear that [lex.pptoken] is the place to look + for this rule, which is not spelled out clearly in the phase1/phase2 rules. + Remove a confusing pair of parentheses as it was not clear if the intent + was to make the parenthetical a note, which we have a better way to render, + or normative. Given the requirement that universal characters behave + consistently, this seems normative, rather than a note. + + Index raw string literals, which appear to be entirely lacking from the + main index. + + commit edadb9b1ebece68c75602bc8e61db6e34f41f0a1 + Author: Richard Smith + Date: Tue Sep 6 13:59:56 2016 -0700 + + [dcl.type.auto.deduct] Correct ill-formed expression 'void{}' to the + intended 'void()'. + + commit feca861da4becdddbcc86d3704cbde9bb139a108 + Author: Dawn Perchik + Date: Tue Aug 30 16:12:02 2016 -0700 + + [class.path][path.member][path.itr] Rename expos member 'pathname' to 'pathstring' to reduce confusion + + commit 1a9d0120502097c64660da7c20e40c9d5ee392c5 + Author: Jonathan Wakely + Date: Tue Aug 30 15:37:36 2016 +0100 + + [fs.op.exists] Move after [fs.op.equivalent] + + commit 258642f6bb3a39416ffcdc880fe662ab7a28dea2 + Author: Alisdair Meredith + Date: Tue Aug 30 10:12:26 2016 -0400 + + [optional.object.ctor] Use injected class names (#910) + + Remove redundant template parameters and use injected names instead. + + commit ff52ca99722eea9b5510ae174d8d00470c1ae7a2 + Author: Sergey Zubkov + Date: Wed Aug 24 11:06:08 2016 -0400 + + [intro.progress] fix typo: guaranteees -> guarantees (#906) + + commit e90dfda4d1cc70a098c4e2cc8da701557df5438d + Merge: 2d706e1 91393aa + Author: Jonathan Wakely + Date: Mon Aug 15 14:37:13 2016 +0100 + + Merge pull request #884 from timsong-cpp/this_fixes + + Remove redundant `this->` in library specification + + commit 2d706e100d9fa081b12c206998d700d293a9ecd5 + Author: Thomas Köppe + Date: Sun Aug 14 11:44:50 2016 +0100 + + [declval] Move example outside the \itemdescr and into its own, numbered paragraph. + + commit 68f8ea755f2b69df03bcb6f39280c521380ac5c8 + Author: Alisdair Meredith + Date: Thu Aug 11 17:59:28 2016 -0400 + + [depr] Review of library index (#883) + + This review handles several topic related to the index of library names: + apply indexlibrarymember for all member functions other than constructors/destructors + consistent ordering of indexlibrarymember{identifier}{class-name} + every index macro has a trailing % to avoid accidental whitespace + ensure headers are indexed with synopsis + ensure every itemdecl has a library index entry + index all of the adaptable function typedef-names + + commit 4f2a90541f5692ca80741064ba3eacbbb80416fa + Author: Thomas Köppe + Date: Wed Aug 10 23:14:54 2016 +0100 + + [cstdlib.syn] Add missing extern-C/C++ overloads for at_exit, at_quick_exit (#890) + + commit 0acba3bc62de2811b88a5d0f83d8fb24b2a73d69 + Author: Richard Smith + Date: Wed Aug 10 12:50:46 2016 -0700 + + [intro.execution] Delete now-incorrect example: arguments to a function + call are now indeterminately-sequenced, not unsequenced. + + commit a9031702d79c69130b23a5d85f923119449f988e + Author: Richard Smith + Date: Tue Aug 9 15:56:28 2016 -0700 + + [basic.def.odr] Add missing "potential results of" in one case in the + recursive definition of the set of potential results. + + This definition is intended to be a recursive formulation that produces + a set of id-expressions, as explained in the introductory sentence, so + it's clear that we were just missing the recursion in one bullet rather + than trying to terminate the recursion early in this case. + + commit fa624a64b11fb8fd5ea9e7a7905c570f912cb79f + Author: Richard Smith + Date: Tue Aug 9 11:49:09 2016 -0700 + + [class.copy] Fix example to take into account guaranteed copy elision, + and add an example where we need both stages of overload resolution when + handling "return local_variable;". + + commit 361aa966ea5b92640245479c8221032ae408960f + Author: Richard Smith + Date: Mon Aug 8 16:40:13 2016 -0700 + + [diff.decl] Replace undefined term "compilation unit" with the intended + "translation unit". In passing, fix awkward grammar. + + commit 2ab1a393049185df9e33c87992a4f012f03483da + Merge: 0a08f81 7d5762b + Author: Thomas Köppe + Date: Mon Aug 8 11:29:51 2016 +0100 + + Merge pull request #891 from tkoeppe/alisdair27 + + Editorial review of Clause 27 [input.output] + + commit 0a08f8141a376c7468162f5aee40683a36c32129 + Author: Eelis + Date: Sun Aug 7 01:34:54 2016 +0200 + + [set.cons, multiset.cons] Specify correct constructed type and add missing \tcode. (#896) + + commit 29aac16a1dbb03c87c4c10a7e68115083abe6cd8 + Author: Eelis + Date: Sat Aug 6 21:07:50 2016 +0200 + + [util.smartptr.getdeleter] Remove broken 'std:' qualification on addressof. (#895) + + commit a96b6ef50687115b686d9f92d1eefa3ea97e0836 + Author: Eelis + Date: Sat Aug 6 11:46:46 2016 +0200 + + [thread.thread.id] Consistently use an lvalue reference for operator<<'s first parameter. (#885) + + commit a31763b4c335ef4236c997aa7e4e4eb319ea29ea + Author: W-E-Brown + Date: Sat Aug 6 04:45:27 2016 -0500 + + g/special math functions/s//mathematical special functions/ (#886) + + There's nothing special about the math; mathematicians have long termed these functions as "special functions". Because C++ also uses "special functions" as a different term of art (referring to copy c'tors, d'tors, etc.), we disambiguate by prefixing "mathematical". + + commit dabf1c4f5798a2f9ea1a01ce8913ceaefbc9f643 + Author: Eelis + Date: Sat Aug 6 11:42:00 2016 +0200 + + [container.requirements.general] Use proper environment for note. (#887) + + commit 643e755e90038354e02ea4ae345d125f2d2dbd09 + Author: Eelis + Date: Sat Aug 6 00:51:16 2016 +0200 + + [associative.reqmts] Add missing line break. (#888) + + commit 912f5f2b73417eab6626faa4a0f7658b99199c29 + Author: Eelis + Date: Fri Aug 5 11:10:19 2016 +0200 + + [temp.deduct.call] Don't nest paragraphs inside itemizations. (#882) + + commit ef0ec0f79c5627795d344c766342d1e94837ee8a + Author: Jonathan Wakely + Date: Thu Aug 4 17:04:37 2016 +0100 + + [memory.resource.private] Resolve LWG 2701 editorially + + commit 28781eab2d228df9e03128e39ee279342608685f + Author: Eelis + Date: Wed Aug 3 20:13:53 2016 +0200 + + [depr.strstreambuf.cons] Remove stray period in footnote. (#875) + + commit 7eafafe82f7e4574c1c688473d308662da8f042c + Author: Eelis + Date: Wed Aug 3 19:58:21 2016 +0200 + + [depr.strstreambuf.cons] Don't use an itemdecl and index entry for a mere use of setg. (#876) + + commit 91836d9b51db2203d711cca71592532fb0aa82c5 + Author: Eelis + Date: Wed Aug 3 19:55:50 2016 +0200 + + [depr.strstreambuf.virtuals] Fix typo: (unsigned char*)gnext -> (unsigned char)*gnext. (#877) + + commit cc06e4902f30df049020173e2e9ad21857b73722 + Author: S. B. Tam + Date: Wed Aug 3 01:50:52 2016 +0800 + + Fix incorrect use of \idxhdr (#874) + + commit 010a27bcd4d27a34d5e1efe9994b9373a29186cb + Author: Zhihao Yuan + Date: Tue Aug 2 09:54:49 2016 -0500 + + [meta.unary.cat] Use core term non-union class type (#873) + + commit e790562a1a709af2314bcbfb03a0b299ac19e7d3 + Author: Eelis + Date: Mon Aug 1 11:44:44 2016 +0200 + + [dcl.attr.deprecated, depr.ostream.members] Fix trailing whitespace in \tcode. (#870) + + commit 7bf13851fdd815170f22757b2f35ac9e331b6330 + Author: Eelis + Date: Mon Aug 1 10:03:49 2016 +0200 + + [depr.strstream.dest] Move rdbuf() to [depr.strstream.oper]. (#871) + + commit 52b41647a32908bda1d9b3d39d1973621895b822 + Author: Eelis + Date: Sat Jul 30 23:14:30 2016 +0200 + + [depr.{i,o}strstream.cons] Remove stray parentheses. (#869) + + commit 2738a070e85770ced228b4dda67efddc3b1d8598 + Author: Eelis + Date: Thu Jul 28 19:48:10 2016 +0200 + + [re.traits] Remove excessive newlines from codeblocks. (#867) + + commit 64eb87ec2e0ace621c9dfb08d4da381ed4ec0c2e + Author: Eelis + Date: Thu Jul 28 15:33:16 2016 +0200 + + [re.traits] Remove excessive parentheses in "Returns:" element. (#865) + + commit 5b99768ea828ffddbee490d20140f423f9bc8bcf + Author: Eelis + Date: Thu Jul 28 15:21:12 2016 +0200 + + [special, strings, localization, numerics] Add missing trailing periods in footnotes. (#863) + + commit 15b80e2756635b1a0aa45e476d2f321fe160da3b + Author: Eelis + Date: Thu Jul 28 14:41:46 2016 +0200 + + [re.tokiter.incr] Add missing \pnum for "Returns:" element. (#864) + + commit 277eb59b0b92a4431f1217f50e96b196a0c967f1 + Author: Thomas Köppe + Date: Thu Jul 28 13:17:24 2016 +0100 + + [memory.general] Update outdated references + + commit 418c0e380ec04e25f0000ea5216dccde311bddaa + Merge: cd3e040 63e697f + Author: Thomas Köppe + Date: Wed Jul 27 19:03:46 2016 +0300 + + Merge pull request #861 from tkoeppe/index_review + + Review of library index entries. Thanks to @AlisdairM for all the work! + + commit cd3e040699bc46b2d68de2c2977cf3656baf2bee + Author: Eelis + Date: Sat Jul 23 12:39:18 2016 +0200 + + [basic, memory, time] Use \impldef consistently. (#852) + + commit c65dd97b6d030ffbaa3208c98ded4acb4eb805ed + Author: Thomas Köppe + Date: Sat Jul 23 02:28:15 2016 +0100 + + [impldef] Improve hyphenation in index + + commit af8b1fdd633161a26d193311369da5ecfa1e7a59 + Author: Thomas Köppe + Date: Sat Jul 23 02:20:09 2016 +0100 + + [macros,impldef] Collate \tcode in- and outside listings + + commit 298a9ceb62275d37964ca99e4e6224ba6d78da46 + Author: Jonathan Wakely + Date: Fri Jul 22 12:33:55 2016 +0100 + + [diff.cpp11.basic] Fix return type of operator new + + commit fbb0e94a7722b57631bedbe19332696bc121f889 + Author: Eelis + Date: Fri Jul 22 04:48:18 2016 +0200 + + [numeric.ops.gcd] Don't format "that" as code in note. (#848) + + commit 6dc0d72393c44542c6b859c49f4cc3a158ad1fa0 + Author: Eelis + Date: Fri Jul 22 00:40:47 2016 +0200 + + [path.generic.obs] Escape backslash in string literal in example. (#846) (#846) + + commit e4748e244fa3d58f232e086c7ad14a6f8550573e + Author: Eelis + Date: Fri Jul 22 00:01:52 2016 +0200 + + [file_status.obs] Remove stray \begin{itemdecl}. (#847) + + commit 29b3ff36affa37f62e15d73b4838453f0b079ea4 + Author: Eelis + Date: Thu Jul 21 21:18:45 2016 +0200 + + [temp.deduct.call] Avoid line wrap in long comment. (#845) + + commit 6b82a23fc4433c704e0837d34ebe880c6408a09c + Author: Thomas Köppe + Date: Thu Jul 21 17:44:57 2016 +0100 + + [util.smartptr.getdeleter] Add missing \tcode + + commit 65289796ef503fd291ae5eed8d45a2aac0c25032 + Author: Thomas Köppe + Date: Thu Jul 21 13:52:27 2016 +0300 + + [support,utilities] More uses of \indexlibrarymember (#841) + + commit acd3ef208f35c4289a029887e39da9f1dd507378 + Author: Casey Carter + Date: Wed Jul 20 17:45:58 2016 -0700 + + [optional.object.observe] Add missing constexpr to detailed description of optional::value_or(U&&) && + + This constexpr specifier was present in the `` synopsis, but omitted from the detailed specification in [optional.object.observe]. + + commit 6145c73c3706618a383c093274d3ed3d0564b134 + Author: Thomas Köppe + Date: Thu Jul 21 01:05:38 2016 +0300 + + [impldef] Collate index correctly (#834) + + commit 153f8118833920df2e99e7356b434c8c3b0b27f7 + Author: bogdan + Date: Wed Jul 20 22:23:32 2016 +0300 + + [dcl.init.ref] Add missing \tcode (#838) + + commit acbb19a62d8f8ddbef118572b748e9fc587b0450 + Author: Alisdair Meredith + Date: Wed Jul 20 16:38:37 2016 +0100 + + [hardware.interference] Use itemdecl instead of codeblock (#836) + + commit 6927a933fd5c777f19f33498a6a43608f4ce5555 + Author: Casey Carter + Date: Mon Jul 18 14:07:51 2016 -0700 + + [headers] Fix typo in "" (#833) + + commit b8894ed3d6362868f326cacb5c46b9f691e5446b + Author: Thomas Köppe + Date: Mon Jul 18 23:07:51 2016 +0300 + + [gram] Use 'extract' package for grammar summary (#816) + + commit a10b517ae0384ca21a7b3178d71a55c5315f66e1 + Author: bogdan + Date: Mon Jul 18 21:32:25 2016 +0300 + + [dcl.init.ref] Add back function lvalues to [dcl.init.ref]/5.2.1.2 (#832) + + Restore some words accidentally removed in the application of P0135R1 to the working draft. + + commit 9d9e41779db2661ae54e10c06303a3b62fc3d3eb + Author: Alisdair Meredith + Date: Mon Jul 18 10:16:24 2016 +0100 + + [diagnostics] Consistently escape newlines in index entries in Clause 19 (#829) + + This change has no visual effect and is not strictly necessary, but it makes our use of index commands more consistent and uniform. + + commit 7be4a057201f03eb7199f3ddca81a737bd1558ec + Author: Richard Smith + Date: Fri Jul 15 10:42:05 2016 -0700 + + [reduce] Fix invasion of the right margin. + + commit f8580e91438915e33dc421a671984b97045d199e + Author: FrankHB + Date: Fri Jul 15 21:16:24 2016 +0800 + + [diff.basic] Improve clarity of "const implies inline" compatibility note (#789) + + Though Annex C is informative, it's better to keep the terminology similar to normative text, which is easier to refer. + + commit c040e66e61322b3962c92cff9595c6affdd3a736 + Author: S. B. Tam + Date: Fri Jul 15 06:46:05 2016 +0800 + + [path.type.cvt] remove redundant word (#828) + + Remove the second "method" in "The method of conversion method is unspecified." + + commit d0fa6a619a194a152b3689a0cce1b1ff6ebcb75e + Author: Alisdair Meredith + Date: Wed Jul 13 16:12:52 2016 +0100 + + [support] Improve index entries for clause 18 (#823) + + Fix a couple of mis-indexed operators, and add index entries + for a few missing functions, most notably the new launder + function. + + commit 2b6ef6b8b7576fcf56970ca4df4575522ee88a57 + Author: Thomas Köppe + Date: Wed Jul 13 12:14:05 2016 +0100 + + [strings] Break line in table caption better + + commit 4973a225a8969cee8f7752074b194bde1d1abf90 + Author: Alisdair Meredith + Date: Tue Jul 12 23:11:47 2016 +0100 + + [input.output] Index all member functions in clause 27 (#820) + + Index member functions in Clause 27 diff --git a/papers/n4639.html b/papers/n4639.html new file mode 100644 index 0000000000..6fb30b381b --- /dev/null +++ b/papers/n4639.html @@ -0,0 +1,1370 @@ +N4639 +

N4639 Editors' Report -- Working Draft, Standard for Programming Language C++

+ +

2016-02-06
+Richard Smith (editor) (Google Inc)
+Dawn Perchik (co-editor) (Embarcadero Technologies Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to +Jens Maurer +for performing many of the editorial fixes since N4618.

+ +

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

+ +

New papers

+ +
    +
  • N4639 is this Editors' Report.
  • +
  • N4640 is the current working draft. It replaces N4618.
  • +
+ +

Motions incorporated into working draft

+ +

This revision contains only editorial changes relative to N4618.

+ +

Notable editorial changes

+ +
    +
  • Jens Maurer performed a cleanup of the valarray wording, converting it +to use the standard formatting style and descriptive elements for library +wording. Thanks also to Jonathan Wakely and Marshall Clow for verifying +that this change preserves the normative meaning.

  • +
  • [alg.partitions] is now nested under [alg.sorting] rather than +[alg.modifying.operations]. This is a better fit because partition is a +partial sort (just like nth_element is), and is_partitioned is not a +mutating sequecne operation.

  • +
+ +

Minor editorial fixes

+ +

A log of editorial fixes made since N4618 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 f77a2b27e9e68eacedb23d675d2d257125f3a7e7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Feb 6 19:54:31 2017 +0100
+
+    Define 'object type' only once. (#1268)
+
+    There were only a few references to the definition in
+    1.8 [intro.object], so drop that definition and refer
+    to 'type of an object' instead.
+
+    Fixes #511.
+
+commit fec48d5db12705f1fcec4be6a9ceb3a067c305cd
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Feb 6 03:09:41 2017 +0100
+
+    [valarray.access] 'evaluates as' -> 'evaluates to'. (#1337)
+
+commit b79c41937b0150569e1428d1093d9504762f15dd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Feb 6 02:02:39 2017 +0100
+
+    [numarray] Add standard description elements. (#1215)
+
+    Partially addresses #1071.
+
+commit 1f8ab13005ff2820d4044c6707a1dabfebce2c1b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Feb 6 02:01:59 2017 +0100
+
+    [dcl.init.aggr] Add example for array of unknown bound (#1270)
+
+    * Consistently refer to 'array of unknown bound'
+    not 'array of unknown size'; see [dcl.array].
+
+    * [dcl.init.aggr] Add example for array of unknown bound
+    as non-static data member.
+
+    Addresses core issue 1985.
+
+    Fixes #396.
+
+commit ec9f102dec2e4624750f01cdebc6f7132361edaa
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Feb 5 17:39:12 2017 +0000
+
+    [cinttypes.syn] Add missing 'the', capitalize sentence
+
+commit e23a5df2f8819c88b87e3392d6522b747481e381
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Feb 5 17:13:46 2017 +0000
+
+    [iostream.format] Minor rewording to be more accurate and fit the lines better
+
+commit 1a0dd180eb3ea3af05cdf1f573eb6f69b0f1b152
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Feb 5 14:51:08 2017 +0000
+
+    Format "i^th" consistently.
+
+    Fixes #653, see also #974.
+
+commit 24900a40ed833ccebb1f3760efe366e4ba73109a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Feb 5 14:26:33 2017 +0000
+
+    [cpp] Swap "control-line" and "if-section".
+
+    With the increased vertical grammar spacing, it is expedient to put the presentation of "control-line" onto the first page so as not to require a huge gap.
+
+commit 4935ed404aa4819e63c560aa2104dbfa70d18f40
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Feb 5 13:09:48 2017 +0000
+
+    [ratio.{syn,comparison}] Mild reformatting for consistency.
+
+    Fixes #1402.
+
+commit 50353bd3bb69d770d00e2fb9236bc913994b96c7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Feb 5 13:03:56 2017 +0000
+
+    [associative.set.syn] Fix cross-reference link for 'multiset'
+
+    Fixes #1424.
+
+commit 766792134b9edb507c569ead9745d12c56735115
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Feb 5 12:20:50 2017 +0000
+
+    [algorithms.parallel] Add missing \pnum
+
+    Fixes #1432.
+
+commit e88d2343b441b399673aa934de766323c68353f5
+Author: Marshall Clow <marshall@idio.com>
+Date:   Sat Feb 4 20:48:13 2017 -0800
+
+    [string.view.template] Change the `reference`, `pointer` etc typedefs in `string_view` to use `value_type` rather than `charT` (#1416)
+
+    This is a cut down version of https://github.com/cplusplus/draft/pull/141, to ensure that it is editorial
+
+commit 04fa63d98ac28457ea038b75fa05f49d14d8ab5b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 5 05:12:58 2017 +0100
+
+    Use 'base class subobject', not 'base subobject' (#1382)
+
+    Fixes #1379.
+
+commit 2de42d5a857886ee1200990ce40f7d8e61eb2293
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Feb 5 04:07:38 2017 +0000
+
+    [func.bind.is{bind,place}] Don't begin sentences with code.
+
+commit 7b704e1759cb09b65c0443c9f63b4773b153d000
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Feb 5 04:46:40 2017 +0100
+
+    Capitalize examples where appropriate. (#1356)
+
+commit 1e00bc3e8addc7b263ecbc7b2f5a510c904b876c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 5 04:45:13 2017 +0100
+
+    [class.temporary] Use 'Clause~\ref{class.access}' (#1348)
+
+    Fixes #1347.
+
+commit 73b2294ca033dee878d678d5c79adc62e352559e
+Author: Billy O'Neal <billy.oneal@gmail.com>
+Date:   Sat Feb 4 19:44:16 2017 -0800
+
+    [atomics.syn] Don't describe function template overloads as "partial specializations"
+
+commit 41c6bac2314892f1b51b0ef4d22fd7aedb9562a5
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Feb 5 04:43:14 2017 +0100
+
+    [string.io] Don't refer to sentry by name it was not given. (#1333)
+
+commit 4408f4667327fffa4e527995a1b73f674e459927
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 5 04:42:14 2017 +0100
+
+    [lib] Replace pre: and post: in requirements tables (#1284)
+
+    with \requires and \postcondition, respectively.
+
+    Also replace yields: with \returns and effect: with \effects.
+
+    Fixes #1281.
+
+commit cf2241bd976a3759a1a036e239471ceda48fb06c
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Feb 5 04:38:27 2017 +0100
+
+    [conv.lval] Split off description of conversion result into dedicated paragraph. (#1318)
+
+commit a665fddad337ac8316695c06730a59e2051eaa5d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 5 04:36:14 2017 +0100
+
+    Harmonize formatting of 'main' function. (#1308)
+
+    Consistently use \tcode{main}.
+    Add cross-references to [basic.start.main].
+
+    Fixes #1304.
+
+commit 6841997d7c36b2a4c14d638de00c1804d018c844
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Feb 5 04:34:59 2017 +0100
+
+    [expr] Split off definition of 'composite pointer type' into dedicated paragraph. (#1300)
+
+commit 7fcb601a9ee72dd45f7df8001c23b9f7cb8b0aca
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Feb 5 04:33:04 2017 +0100
+
+    [strings] Remove remarks that repeat what was stated a few lines before. (#1289)
+
+commit bc106e5f01563337b4069998c6e149b795b65111
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Feb 5 03:31:13 2017 +0000
+
+    [tuple.creation] Simplify the introductory notation, and then use notation that matches the introduction. (#1251)
+
+commit e5674e1d47bbd87ecd4caefb3f37c4c3cb3551df
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 5 04:30:31 2017 +0100
+
+    [func.bind.bind] Reformat to use math-style indexing. (#1285)
+
+    Partially addresses #1139.
+
+commit 9a5c34e6a8c86a93167724aa5061415f1df8a069
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 5 03:30:12 2017 +0100
+
+    [stmt.dcl] Clarify footnote about deadlock avoidance. (#1266)
+
+    Fixes #849.
+
+commit 4b0d533134e61f713a877dadbe6df92f64291d6a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 16 16:25:04 2016 +0100
+
+    [lib] Harmonize casing for 'shall meet the requirements of ... iterator'.
+
+    Also cross-reference the sections, not the tables, for
+    iterator requirements.
+
+    Fixes #696.
+
+commit 03c356f9d764a8230323bf2fdc77495b98032780
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 16 16:17:02 2016 +0100
+
+    [time.point] Fix cross-reference to clock requirements.
+
+commit 55a498202fb5b558cd93635a63ed111931634b0a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 5 02:01:30 2017 +0100
+
+    [lex.literal] Avoid references to plain 'literal' (#1277)
+
+    unless the \grammarterm is intended.
+
+    Fixes #322.
+
+commit 469e9f021fe65774b5845350be3cff4a12d40680
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Feb 4 21:12:04 2017 +0100
+
+    [namespace.udecl] Clarify error in example. (#1254)
+
+commit 26e92b499f7a41c7b65c7e2828a1608021adf695
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Feb 4 21:02:59 2017 +0100
+
+    [temp.deduct] Avoid talking about 'side effect' and 'evaluation' (#1252)
+
+    when discussing template instantiations.
+
+commit 43c20dbebf207d985f8d051d2994ce22108049e4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Feb 4 20:52:06 2017 +0100
+
+    [alg.partitions] Move entire subclause to [alg.sorting]. (#1245)
+
+    The non-modifying operation is_partitioned doesn't fit into
+    'mutating sequence operations', and partitioning can be
+    considered a weak sort.
+
+    Fixes #289.
+
+commit 42578d91450b0b563e076151427b6deff4647f6d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Feb 4 19:44:57 2017 +0000
+
+    [macros, styles] Remove minipages from BNF environments and use a custom enumitem list for spacing. (#1170)
+
+    BNF entries are now spaced like normal paragraphs. Individual paragraphs are kept on a single page by setting a high widow penalty.
+
+    It is now immaterial whether multiple nontermdefs are contained in a single bnf environment, or whether each def is in its own environment. Pages can break between elements, not within.
+
+commit 23d739974007c3f827ad2e55da60cb4358681773
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Feb 4 20:19:51 2017 +0100
+
+    [lib] Replace 'Notes:' elements with regular [ Note: ... -- end note] (#1160)
+
+    Remove the \realnotes and \realnote macros.
+    No longer mention 'Notes:' in [structure.specifications].
+
+    Fixes #492.
+
+commit 5a1d430e6c09099ba7e420db733bcf116e8ca868
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Sat Feb 4 19:08:19 2017 +0000
+
+    [streambuf.virt.get] use half-open ranges in underflow effects (#1157)
+
+commit a50661aa098dca6cb7b34061e2d30fd541999cd4
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Sat Feb 4 19:00:02 2017 +0000
+
+    [locale.time.get] change undefined term "record" to "object" (#1412)
+
+commit 3f0133279c6852aa7e7c20c2b5e97f32d80847a8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Feb 4 19:59:31 2017 +0100
+
+    [support.types] Properly describe <cstddef> header (#1415)
+
+    After the synopsis for <cstddef>, add a sentence (cloned from cstdlib.syn)
+    that the contents are the same as <stddef.h> except for wchar_t,
+    [support.types.nullptr], and [support.types.layout].
+
+    Fixes #1404.
+
+commit 06c788de055ef33fa8aae1d479b01600c399a86b
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Feb 4 19:51:51 2017 +0100
+
+    Don't parenthesize \refs after 'in'/'of'/'notwithstanding'. (#1420)
+
+commit 0f8ca3d7da39bd290062408ca2b2572c40994e9a
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Feb 4 19:50:25 2017 +0100
+
+    [lex.phases] Remove stray period. (#1421)
+
+commit 25fb80b3521531d71bb45c677ed9eace5b39f7ae
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 3 18:49:37 2017 +0000
+
+    [forwardlist.ops] Add comma
+
+commit 019585eb4da447ff6a41fa766056b4febff08c25
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Wed Feb 1 08:17:03 2017 +0800
+
+    [locale.facet] add missing backslash in \defn (#1418)
+
+commit ed8dbf4c0bce4adf96307c1d427dde0685f7dbdf
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Jan 30 13:43:20 2017 +0100
+
+    [dcl.enum] Italicize 'unscoped enumeration' in its definition. (#1410)
+
+commit c7f6a9139872aad48a944d018ce5e4b3de15ce81
+Author: Axel Naumann <github@axel-naumann.de>
+Date:   Thu Jan 26 17:04:41 2017 +0100
+
+    [thread.lock.algorithm] Change '0-based' to 'zero-based'.
+
+    Conforming with other occurrences in the standard.
+
+commit b63d68ab7bc08f5e969a5b44b000941e6e82eb2e
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Jan 22 21:26:37 2017 +0100
+
+    [basic.ios.cons] Remove stray semicolon. (#1397)
+
+commit 701df7eac2474300d2b602700a3c32a51ef439a7
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Jan 22 18:35:35 2017 +0100
+
+    Add missing \pnums. (#1396)
+
+commit 5ce8ed130a43ffc17b1d05d349e9568831016891
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jan 20 17:54:09 2017 +0000
+
+    [special] Add comma.
+
+commit 03c99a1b516a85000456841b061d5b1f17b32e48
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jan 20 17:52:52 2017 +0000
+
+    [optional.ctor] add missing \pnum
+
+commit 4bbb3ba2e4e7065900c12b97710db3e398c6ee2d
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Jan 20 18:48:20 2017 +0100
+
+    [cpp.pragma.op] Add missing \pnums and remove unwanted paragraph breaks. (#1387)
+
+commit d2263429a07205edf8d2ffcd6d41cfe5d61544f8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jan 19 00:17:04 2017 +0100
+
+    [dcl.link] Index implementation-defined behavior. (#1330)
+
+    Fixes #1326.
+
+commit 61c4f655ac96e2eba807f8e13f9adae1405bdf49
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Jan 18 23:24:39 2017 +0100
+
+    [dcl.ambig.res] Describe example ambiguous case more clearly. (#1371)
+
+commit 94c7fdf49d51898a10c846bb0409bf07ba66256c
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Jan 18 23:23:57 2017 +0100
+
+    Consistently use 'this International Standard'. (#1380)
+
+commit 95977f18c0594a12a90ca050ec5f8006b4b7bf53
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Jan 18 22:59:08 2017 +0100
+
+    Add missing hyphen in 'floating-point'. (#1319)
+
+commit 2001a03014df142f5f9a5974c64fc2ff96d4f2cd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jan 18 22:47:23 2017 +0100
+
+    'floating-point something', not 'floating point something' (#1384)
+
+    Adjust occurrences that spanned a line break in the LaTeX
+    source and were therefore missed in commit
+    cd3deb891cee5436a64ff9a8f7bb304a4fcc6c00.
+
+commit c8295e3a928f93cff021d88b7b1532b5a58d5114
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jan 18 22:45:41 2017 +0100
+
+    [stmt.stmt], [dcl.attr.deprecated] Remove hyphen in 're-declared' (#1381)
+
+    Fixes #1378.
+
+commit 2b0db35833f8ccce30744b46465e609e4b109366
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jan 18 14:57:38 2017 +0000
+
+    [utilities.general] Update reference to bitset section and add missing \rowsep
+
+commit 417d713d341911e3e366610c85761d246785f02f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jan 18 00:33:11 2017 +0000
+
+    [over.match.best, over.ics.rank] Remove premature ends of sentences.
+
+    This addresses a major part of #90.
+
+commit d76a411d35b1ed933cb5d11dc492ab4489cb239e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jan 17 23:48:02 2017 +0000
+
+    [over.ics.rank] Replace self-referential reference with 'this subclause'
+
+commit ee154f9dd08d93124455f408f69030862acca9eb
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Mon Jan 16 07:25:43 2017 -0500
+
+    Fix remaining uses of \Cpp macro (#1366)
+
+    I believe this patch catches the last two places in the current
+    draft that should be using a variant of the \Cpp macros to
+    better render the 'C++' string.
+
+commit 4e6dc965fc2a2f562d8bd62cafe5a1d51745a79d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jan 13 14:32:39 2017 +0000
+
+    [re] Move long pieces of code into codeblocks and remove redundant "the result of" from return statements
+
+    This fixes overfull hboxes, see #693.
+
+commit ab8f2c7c0331efbb9713a46d4c940df94a0e48f7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jan 10 11:04:16 2017 +0100
+
+    [mem.res.pool], [mem.res.monotonic.buffer] Do not define the otherwise unused term 'owns'. (#1260)
+
+    Fixes #1257.
+
+commit 3acb49d296ba7efdc7542e943262138dc0eb9b74
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jan 6 19:21:45 2017 +0000
+
+    [string.insert] Change "pos1" to "pos" for overloads taking one position
+
+    Also make argument names in synopsis consistent.
+
+    Fixes #1338
+
+commit 732fd444a33043bce3caf6d6d939f6e81fb56ddd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jan 5 13:04:01 2017 +0100
+
+    [rand.adapt.shuf] Show exposition-only members in the order in which initialization is described. (#1332)
+
+    Fixes #1331.
+
+commit b9081cc3d7a314ac336695166e0123cdb1da6623
+Author: Kazutoshi SATODA <k_satoda@f2.dion.ne.jp>
+Date:   Wed Jan 4 23:31:49 2017 +0900
+
+    [dcl.init] Fix a typo in definition of const-default-constructible (#1327)
+
+commit 10452d174140fbcf0bfc1fab37dbdbd63913be79
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Jan 4 11:45:00 2017 +0100
+
+    [complex.ops] Don't repeat declaration in "Effects:" element. (#1324)
+
+commit 94c2fbabdc1057d7bc7cdb83d1585d24de3fd146
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Jan 3 18:05:03 2017 +0100
+
+    [re.submatch.op] Remove excessive parentheses in "Returns:" element. (#1323)
+
+commit 3b81b0b9cafacee9d23b47d1a8862a9d0eee6ab7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jan 3 16:58:58 2017 +0100
+
+    [sf.cmath] Fix 'where' associations of Greek variable names. (#1317)
+
+    Fixes #1291.
+
+commit 2416d453c28a821076a1046bec1b13d6dd8ee7d7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jan 3 16:05:27 2017 +0100
+
+    [util.smartptr.enab] Remove leftover postcondition after P0033R1. (#1314)
+
+    Fixes #1299.
+
+commit 0effa034c24cc78f5128d36327f0d30047531b89
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jan 3 16:02:08 2017 +0100
+
+    [class.derived] Avoid \pnum inside examples. (#1265)
+
+    Fixes #781.
+
+commit 2163ad27876b6e0423650c71b01646a8daca6cdc
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Tue Jan 3 07:36:29 2017 -0500
+
+    [meta.trans.other] add missing cv for common_type (#1292)
+
+    P0435R1 says 'cv void', but the cv part was dropped.
+
+commit 09e6e6de2e92c33daa53ee1013847df68c99ad52
+Author: alexanderkscott <k878208@mvrht.com>
+Date:   Sat Dec 31 14:06:51 2016 +0000
+
+    [iterators, numerics] Replace 'sub-clause' by 'subclause' (#1302)
+
+commit 2168e10fb3608d4ab84190d3d0c8cd5101dc52b9
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Dec 30 16:46:18 2016 +0100
+
+    Capitalize notes that consist of complete sentences. (#1297)
+
+commit 3681e72ce5b8d0f09e15bfb4fef11bd230951cc6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 21 18:58:54 2016 +0000
+
+    [conv.qual] Consistent notation for indexed types T_1, T_2
+
+commit 3e2b77aed27438f6751ad59ca75fc90bde79993b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 21 19:55:02 2016 +0100
+
+    Mechanically harmonize indexed types to $\tcode{T}_i$. (#1283)
+
+    Replace \tcode{T}$_i$  and $T_i$ with $\tcode{T}_i$.
+
+commit 0b9f60c4c373e57cda055b7aba64afb674db1fff
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Dec 21 18:14:54 2016 +0100
+
+    [string.view.find] Add missing 'be' (#1282)
+
+commit d49359badc2115b010dcf978d86067f1a2cfb331
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 20 16:47:32 2016 +0100
+
+    [containers] Replace pre: and post: in requirements tables with \requires and \postcondition, respectively. (#1273)
+
+    Fixes #792.
+
+commit 9fe30c8353b264318a1c90d2ce817347e1f6738c
+Author: Casey Carter <Casey@Carter.net>
+Date:   Sun Dec 18 15:34:21 2016 -0800
+
+    Fix typos in [mem.poly.allocator.mem]/9.1 and /9.5 (#1269)
+
+    (There is no "T" in scope.)
+
+commit 666886e51092f447e9ecb6f26a2965a8c03da667
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 19 00:31:51 2016 +0100
+
+    [associative.reqmts] Harmonize capitalization. (#1271)
+
+    Older entries seem to start with a lowercase letter and only
+    have a full stop if a second sentence follows.  For newer
+    entries (initializer lists, node_handle functions), apply
+    that style, too.
+
+    Fixes #328.
+
+commit a3afbc8daaa557cc0cd1f76e40158032ca6f097f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 16 15:47:47 2016 +0100
+
+    Avoid \pnum inside examples. (#1262)
+
+    With the exception of [facets.examples].
+
+    Fixes #781.
+
+commit 5d129b232ac55abeb508a8f890d478a45eab5554
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 16 12:43:55 2016 +0100
+
+    [dcl.array], [temp.deduct.type] Split notes spanning numbered paragraphs. (#1261)
+
+    Partially addresses #781.
+
+commit 3750b234c1699d2c7b0f83e2c52fbd65d74c4299
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 15 17:43:32 2016 +0100
+
+    [unique.ptr.single.modifiers] Use 'if and only if' when calling deleter. (#1255)
+
+    Fixes #248.
+
+commit 8e64a085cdcd7c41b3f4d4298933cb52b6572420
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 15 17:42:24 2016 +0100
+
+    [sf.math] Promote parenthesized parts of function names to un-parenthesized. (#1256)
+
+    Fixes #1250.
+
+commit f8904bd946650f240a6af76193f406377e2fb1b7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 30 19:50:31 2016 +0100
+
+    [support.limits] Rearrange section 'Implementation properties'
+
+     - Change order of subsections.
+     - Remove [limits] and [c.limits] subsection headings.
+     - Move descriptions of numeric_limits members and specializations as
+       subsections under the description of the primary class template.
+     - Add sectioning comments to the <limits> synopsis.
+
+    Fixes #785.
+
+commit 9a6d4c3a14d77eaea17044e3b52942582d65eac8
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Dec 15 00:29:13 2016 +0000
+
+    [forward] Remove mid-example paragraph breaks
+
+commit 7f7e757693b3173d9490e63e28f384fbba7dcd91
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 14 23:49:59 2016 +0000
+
+    Change a few stray headings to sentence case
+
+    Fixes #1200 and #1201.
+
+commit 32026a5b490a8f0b310530425108247694968def
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 21 22:45:55 2016 +0100
+
+    [class.copy] Rephrase rule preferring a move constructor
+    in a throw-expression or a return statement.
+
+    Fixes #712.
+
+commit 19a0c06093e39f5b0a85316f2564312c9e52b129
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 7 20:02:50 2016 +0000
+
+    [temp.class] Reorganize examples into a separate paragraph
+
+commit 64e5cffbef31b7a00175d969fae2cf5f70c27f48
+Author: W-E-Brown <webrown.cpp@gmail.com>
+Date:   Wed Dec 14 17:03:23 2016 -0600
+
+    s/(possibly cv-qualified)/\\cv{}~/ and allied changes (#1142)
+
+    Applied across the entire standard.
+
+commit 571a258bd4d59725e1bbbb69febaffb3d3a513ed
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 14 22:55:05 2016 +0000
+
+    [input.output] Add references to inclusions in a synopsis
+
+commit eacf4129776df8481599ec44e0c256590aed1ccb
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 10 17:56:41 2016 +0000
+
+    [{ex,in}clusive.scan, transform.{ex,in}clusive.scan]: Rephase 'for each *j' in terms of indexes
+
+    Addresses #693 for this part, but is also clearer.
+
+commit c39761a36fed573e369ccccd81f54ee2c9f69930
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 14 21:13:57 2016 +0100
+
+    [iostream.forward.overview] Promote introductory
+    sentences to normative text.
+
+    Fixes #494.
+
+commit 5f0f4df6ab6dfa566d394da9c4321c1015f63747
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Dec 14 12:21:10 2016 -0800
+
+    [basic.def.odr] Clarify that the "not an odr use" requirement for using
+    an internal linkage constant within an inline function (etc) only
+    applies to odr-uses within that inline function, and not uses elsewhere
+    in the program.
+
+commit 2f3c3b8c3a401fd6d8f081b608db6572be01b7e0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 14 18:46:51 2016 +0100
+
+    [temp] Add variable templates to the definition of 'template'. (#1225)
+
+    Fixes #593.
+
+commit f32e068898a371b94a27f895f3863a810186e70e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 14 18:38:09 2016 +0100
+
+    [unord] Use 'key equality predicate' consistently. (#1241)
+
+    Replaces occasional uses of 'key equality function'.
+
+    Fixes #630.
+
+commit b54f2507ffc23c0e573f4637217003b4074c33aa
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Dec 14 18:37:20 2016 +0100
+
+    [strings, algorithms, diff] Replace 'routine' with 'function'. (#1217)
+
+commit 7b087da9cd6867fd6b8b499c6ec766499db48772
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Dec 14 17:58:47 2016 +0100
+
+    [class.derived] Don't bother splitting last remark in note off into separate paragraph. (#1240)
+
+commit c6d00d91a0c464c528c6cd38c442ad6a11036aa7
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Dec 14 17:22:14 2016 +0100
+
+    [dcl.init, class.directory_iterator, fs.op.current_path] Split multiparagraph notes into multiple note paragraphs.
+
+    The paragraphs are unrelated and don't belong into a single note.
+
+commit f66fb79c44dc6051aa83d6489fee707a584ebe82
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Wed Dec 14 15:46:57 2016 +0000
+
+    [lib] Fix capitalization and punctuation in itemdescrs. (#1238)
+
+commit 6407d69c8e98e5d94e623c4cf84b1419ae12de62
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Dec 14 15:56:12 2016 +0100
+
+    [path.non-member] Structure multi-paragraph note using an itemization instead. (#1236)
+
+commit edd2c5fb29b2feb6a6acc23f843d351a8f06b2ec
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 14 14:35:44 2016 +0000
+
+    [cstdint.syn] Add cross reference to C
+
+commit 122b2d896fe4049e30afb498b0e59be399dc0e45
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 14 02:53:47 2016 +0000
+
+    [temp] Misc tweaks: tcode, ellipses, capitalization, comment spacing
+
+commit 4da0a38a1982e4cb65a06848051ca4c5a43b04bd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 14 14:52:36 2016 +0100
+
+    [string.view.hash] Add a note about equality to string hashes. (#1235)
+
+    From http://lists.isocpp.org/lib/2016/12/1531.php.
+
+commit 776fd05bf781b265cfc96711d2abfd49a781ea20
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 14 02:15:49 2016 +0000
+
+    Use \commentellip macro in a few more places
+
+commit 81eea5e1b5a477404b39176f71699f7b87a2dc01
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 14 01:22:29 2016 +0000
+
+    [over.match.best] Convert footnote into ordinary note and remove overly tutorialisque explanations
+
+    Fixes #1232.
+
+commit 93631694be2ac0cd0aade763e50a49bef8f9c4b4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 14 00:54:29 2016 +0100
+
+    [localization] Add numbered headings for synopses. (#1229)
+
+    Also remove use of \synopsis for class template definitions.
+
+    Partially addresses #566.
+
+commit 93ccb079c2a809aded1d71a21e783560be019492
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 14 00:49:33 2016 +0100
+
+    [algorithms] Add numbered heading for synopsis. (#1230)
+
+    Partially addresses #566.
+
+commit e6b9e3124c58f91f8d624f3d512f1f786e1f5adb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 14 00:22:55 2016 +0100
+
+    [input.output] Add numbered headings for synopses. (#1228)
+
+    Remove now-empty 'Overview' sections.
+
+    Partially addresses #566.
+
+commit c9688d7dc5e4471868d84f92d98c43a01e7465e2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 13 23:31:04 2016 +0100
+
+    [mem.res.monotonic.buffer.ctor] Spell reference to a parameter correctly. (#1226)
+
+    Fixes #1055.
+
+commit a3f3773d4ca287c252a485c343348c729f60c82d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 13 23:06:39 2016 +0100
+
+    [lib] Use 'comparison function', not 'comparison operator'. (#1224)
+
+    When talking about an operator function, use the term defined in
+    [defns.comparison].
+
+    Fixes #612.
+
+commit 8b1f6cc8d73eec0306db1dec66f2da52a03ea274
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 13 22:28:40 2016 +0100
+
+    [any] Rename the ValueType template parameter to T. (#1220)
+
+    The parameter has a confusing name: It is not actually the value type
+    contained in the 'any'.
+    Where the new T clashes with an existing use of T, rename the latter to VT,
+    since this is actually the value type of the 'any'.
+
+    Fixes #1202.
+
+commit e4bc84c405ac09ff7a5aa5b8df39d5e1f5b7bd39
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 13 21:56:10 2016 +0100
+
+    [dcl.init.ref] Replace 'type qualifier' with 'cv-qualifier' in example. (#1222)
+
+    Fixes #1219.
+
+commit 1894a77ec88dd28d87985e162ef57c45580a9ad2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 13 21:53:28 2016 +0100
+
+    [list.ops] Move effects to 'Effects' element. (#1221)
+
+    Also reorder the elements so that 'Requires' is before 'Effects'.
+
+    Fixes #796.
+
+commit aefc83c6c66013c5053f4c184c4fd7bf400e96fe
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 13 18:20:02 2016 +0100
+
+    [utility], [bitset] Introduce a separate heading for the synopsis. (#1213)
+
+    Partially addresses #566.
+
+commit 0a3f38c33d4fb7459fb507faf88591bc1828b31c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 13 18:19:08 2016 +0100
+
+    [bitset.members] Adjust confusing index entries for 'set' and 'any'. (#1218)
+
+    Fixes #743.
+
+commit bc42416f97adb35907af7af8fe407d3a445a1824
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 12 23:56:13 2016 +0100
+
+    [thread] Add numbered headings for synopses. (#1214)
+
+    Partially addresses #566.
+
+commit 546a162c06881491f8394babb4147941f2af53ee
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 12 16:45:28 2016 +0100
+
+    [pairs.spec], [tuple.creation] Avoid 'equality' of types phrasing. (#1212)
+
+    Fixes #491.
+
+commit 5ec123d3e037fc3b85542ea2f31b86c6375d7c06
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 12 16:25:47 2016 +0100
+
+    [class.temporary] Add paragraph number and split off example into its own paragraph. (#1211)
+
+commit a8a89d9144a9050b85b8bfe780340a763193a1f4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Dec 12 14:46:31 2016 +0000
+
+    [pairs.pair, tuple.cnstr] Replace 'The constructor initializes' with just 'Initializes', which is how we say it in many other places. (#1206)
+
+commit 3c6ba0621a8e23c474f77fbee24b06d76b125dd3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Dec 12 01:50:27 2016 +0000
+
+    [special] Capitalize notes and examples that are complete sentences.
+
+commit 3a0d1be2ccd055f6bef1e91ebc2ca7ee19f3638e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Dec 12 01:33:44 2016 +0000
+
+    [class.cdtor] Clarify presentation of example
+
+    Seperate the hypothetical alternative case from the real code with newlines and describe in irrealis mood.
+
+commit 33375c726c64c4e602b52269708441f5cdccfa77
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Sun Dec 11 07:20:28 2016 -0500
+
+    [mem.res.syn] Call polymorphic_allocator a 'class template' (#1209)
+
+commit fdb5d1a7ed71add105ee5eca4307d9a6a042ba75
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Sun Dec 11 07:11:28 2016 -0500
+
+    [variant.bad.access] Use 'override' instead of 'virtual' in synopsis (#1208)
+
+commit edba6d4a097e9de2caa79461341b3c3476941790
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 10 19:50:28 2016 +0000
+
+    [diff.cpp03.special] Use the more correct "call function f" rather than "call function f()" to resolve overfull line and fulfil compulsion for pedantry.
+
+commit 3c6d91088e58e56e295419efdd47ddc8a4628196
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 10 17:10:54 2016 +0000
+
+    [func.not_fn] Clean-up not_fun
+
+    Use placeholder macros. Reformat class synopsis in our usual style. Reorder private members. Use codeblocks for long descriptions.
+
+    Addresses #693.
+
+commit 2b17f472d2c1fcfb96f5f9d4f5f7d799c6d336ae
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 10 17:09:25 2016 +0000
+
+    [mem.res.pool.mem] Reorder and reflow do_is_equal descriptions.
+
+    Addresses #693 for that section.
+
+commit f9ce3d269eb5bd2ffd3bb74f79ba1298da1d83bc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 10 16:34:41 2016 +0000
+
+    [tuple.helper, variant.helper] Change "specialization of *class*" to "specialization of *template*".
+
+    The containing lines were too long (cf. #693), and the change is a mild increase in pedantic correctness.
+
+commit faaf054bd237780b3999c4efdbbcc2b6bf88721b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 9 23:32:42 2016 +0100
+
+    [limits] Use 'subnormal number' as defined by IEEE 754-2008 = ISO 60559. (#1203)
+
+    Also add index entries for 'denormalized value' and 'value,
+    denormalized', pointing to 'number, subnormal'.
+
+    Fixes #1017.
+
+commit 4f182cba568b3f753d2bdeb61c349bd65b8bf241
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 8 23:02:33 2016 +0100
+
+    [util.smartptr.shared.atomic] Merge duplicate description items.
+
+    Partially addresses #288.
+
+commit b22cda3a831508a362930f6eb25d1f839f0f8ea8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 8 22:57:32 2016 +0100
+
+    [alg.lex.comparison] Remove duplicate 'Remarks:' item and comfort lone codeblock
+
+    Partially addresses #288.
+
+commit faecbe8a6f3db2bd411b64428c1f3345b1677550
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Thu Dec 8 15:19:45 2016 +0000
+
+    [rand.req.adapt] Fix syntax error (#1194)
+
+commit a9159bdbf9b6baa096f2c51d9129cd03431d03bd
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Dec 8 16:08:58 2016 +0100
+
+    [numeric.special] Remove redundant 'inline' specifiers in example. (#1192)
+
+commit ff36dc5f586abb837a3963b1b8815a245bdbc741
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Thu Dec 8 10:47:07 2016 +0000
+
+    [depr] Add missing parentheses around bitwise expressions (#1191)
+
+commit b6d625f215dbac299982094cf54e4fed0999e873
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Dec 8 10:06:47 2016 +0000
+
+    Hyphenate 'implementation-defined' in a few residual cases
+
+commit 77f36805a4adc0a5d145264fc5e5e6ab11b5e8f2
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 2 02:58:22 2016 +0000
+
+    [dcl.align] Touch up error comments
+
+commit 6d082aa3bed44e5342e55d19453d9669671063fa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 7 23:07:21 2016 +0100
+
+    [intseq.general] Remove example not quite mirroring a standard function. (#1187)
+
+    Fixes #1176.
+
+commit 426dd1880198d5aaa51ae189d3e1d3780d3da1ce
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 7 22:28:33 2016 +0100
+
+    [containers, alg.transform] Minor presentation fixes. (#1184)
+
+    Harmonize the punctuation in complexity requirements where a definition
+    for N is introduced.
+    Add a missing closing parenthesis.
+    Add a full stop.
+
+    Fixes #191.
+
+commit ff91738d4f67123fa944a76506826f7a3c14b3e2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 7 21:25:39 2016 +0100
+
+    [class.virtual] Remove awkward 'but'. (#1182)
+
+    Fixes #170.
+
+commit 4975167baaed59b6b3aab9d93ea14682c45a6217
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 7 20:44:25 2016 +0100
+
+    [function.objects] Introduce a new subsection for the <functional> synopsis. (#1179)
+
+    Also add a cross-reference from [unord.hash] to the synopsis, which
+    is the only place where the primary template is declared.
+
+    Fixes #192.
+
+commit d4c17ce01bf7b1419b330e798119b838ab8f1380
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 7 20:07:18 2016 +0100
+
+    [pairs.pair] Further harmonize spelling of template parameters for pair<U1, U2>. (#1178)
+
+    Fixes #125.
+
+commit 10ae5c39b0d4065486974c1c80d338b904a9f013
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Dec 7 12:13:32 2016 +0100
+
+    Capitalize examples outside sentences. (#1174)
+
+commit 5301db44da7db8839114f9c032e7fe293da31879
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Dec 7 11:25:11 2016 +0100
+
+    Capitalize notes. (#1173)
+
+commit d2a69983b30ba4a3dec9bece774cb11fe50353c1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 7 01:37:27 2016 +0000
+
+    [stmt.stmt] Align comments to customary columns and reflow some very narrow comments
+
+commit 1fe866912ad07ea76353bb08723aad8552620f7c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 7 01:55:54 2016 +0100
+
+    [utility] Harmonize spelling of template parameters for std::pair<T1,T2>. (#1172)
+
+    Addresses #125.
+
+commit 99c6b4c6d08b99b36a10a50127b43ab461fd2f57
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Dec 3 00:43:13 2016 +0000
+
+    [expr] Use same notation for collections of cv-qualification signatures as in [conv.qual]
+
+commit 2df5c6df7ee8cd884da607897b229cc8e1913ecb
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 29 02:47:55 2016 +0000
+
+    [basic] Reflow comments to be more compact; use math set notation for sets
+
+commit 28b0897221d9b641ef8439cfd29ef81b7d1f81b6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 2 00:40:17 2016 +0100
+
+    [headers, depr.c.headers] Avoid brittle counts of headers. (#1167)
+
+    Fixes #766.
+
+commit cf522b9177c01511a8c0b7197d9e48aa2224512d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 1 23:58:40 2016 +0100
+
+    [utilities] Do not use CamelCase for 'BaseCharacteristic'. (#1164)
+
+    This is a regular English phrase used as a technical term.
+
+    Fixes #1154.
+
+commit 69d8903278277e96779c8435fedad0018fe10ee4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 1 23:52:01 2016 +0100
+
+    [re.regex] Add missing 'multiline' constant. (#1162)
+
+    Fixes #1129.
+
+commit 19dc0aa5c8b8b53f0bfe17724fb26795c187c10a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Oct 21 11:39:17 2016 -0700
+
+    [dcl.init.aggr] Wording simplification. Aggregate elements are only
+    defined for purposes of aggregate initialization; we don't need to
+    repeat that every time we use the term.
+
+commit cca5257d60abcf9a62f545e9c146fe2c367f843a
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Wed Nov 30 00:03:04 2016 +0000
+
+    Move punctuation outside quotation marks according to logical nesting (#1148)
+
+commit a69d5beeaf1041c064cbad97db9b05a7e6ce079c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 29 23:57:44 2016 +0000
+
+    [expr.prim.lambda] Move first paragraph below grammar.
+
+    Text before the main grammar needs to be very short; this first paragraph was getting out of hand.
+
+commit c58e854d79a71d7494c6c1bcf496c6795f10821b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 29 21:47:05 2016 +0000
+
+    [string.classes] Turn <string> synopsis into numbered subclause
+
+    In pursuit of issue #566.
+
+commit 30e55475c622cdda9274f5d3af79eae416b650ef
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 29 21:38:41 2016 +0000
+
+    [tuple, variant] Turn synopses into numbered subclauses
+
+    In pursuit of issue #566.
+
+commit 48efdfe014549e6d116ce12ca427f7df0e0f8c70
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 29 19:58:48 2016 +0000
+
+    [pairs.pair], [tuple.tuple] Tidy up presentation of member functions (order elements consistently; use better index notation)
+
+    Also fixes issue #1117 and partially addresses issue #653.
+
+commit 807e6f951e19e418cbc379797d1c32e4b8a49dca
+Author: Johannes Laire <johannes@laire.fi>
+Date:   Tue Nov 29 12:37:17 2016 -0500
+
+    [library] Capitalize headings
+
+commit bcd2eb6e3cfd68d90b4b761df8dd0728e4e0629b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 29 02:52:44 2016 +0000
+
+    [basic.def.odf] Clarify example by adding a variable that actually odr-uses D()
+
diff --git a/papers/n4639.md b/papers/n4639.md new file mode 100644 index 0000000000..291425caff --- /dev/null +++ b/papers/n4639.md @@ -0,0 +1,1243 @@ +# N4639 Editors' Report -- Working Draft, Standard for Programming Language C++ + +2016-02-06 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Embarcadero Technologies Inc) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Special thanks to +Jens Maurer +for performing many of the editorial fixes since N4618. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * N4639 is this Editors' Report. + * [N4640](http://wg21.link/n4640) is the current working draft. It replaces [N4618](http://wg21.link/n4618). + +### Motions incorporated into working draft + +This revision contains only editorial changes relative to N4618. + +## Notable editorial changes + + * Jens Maurer performed a cleanup of the `valarray` wording, converting it + to use the standard formatting style and descriptive elements for library + wording. Thanks also to Jonathan Wakely and Marshall Clow for verifying + that this change preserves the normative meaning. + + * [alg.partitions] is now nested under [alg.sorting] rather than + [alg.modifying.operations]. This is a better fit because `partition` is a + partial sort (just like `nth_element` is), and `is_partitioned` is not a + mutating sequecne operation. + +## Minor editorial fixes + +A log of editorial fixes made since N4618 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/n4618...n4640). + + commit f77a2b27e9e68eacedb23d675d2d257125f3a7e7 + Author: Jens Maurer + Date: Mon Feb 6 19:54:31 2017 +0100 + + Define 'object type' only once. (#1268) + + There were only a few references to the definition in + 1.8 [intro.object], so drop that definition and refer + to 'type of an object' instead. + + Fixes #511. + + commit fec48d5db12705f1fcec4be6a9ceb3a067c305cd + Author: Eelis + Date: Mon Feb 6 03:09:41 2017 +0100 + + [valarray.access] 'evaluates as' -> 'evaluates to'. (#1337) + + commit b79c41937b0150569e1428d1093d9504762f15dd + Author: Jens Maurer + Date: Mon Feb 6 02:02:39 2017 +0100 + + [numarray] Add standard description elements. (#1215) + + Partially addresses #1071. + + commit 1f8ab13005ff2820d4044c6707a1dabfebce2c1b + Author: Jens Maurer + Date: Mon Feb 6 02:01:59 2017 +0100 + + [dcl.init.aggr] Add example for array of unknown bound (#1270) + + * Consistently refer to 'array of unknown bound' + not 'array of unknown size'; see [dcl.array]. + + * [dcl.init.aggr] Add example for array of unknown bound + as non-static data member. + + Addresses core issue 1985. + + Fixes #396. + + commit ec9f102dec2e4624750f01cdebc6f7132361edaa + Author: Thomas Köppe + Date: Sun Feb 5 17:39:12 2017 +0000 + + [cinttypes.syn] Add missing 'the', capitalize sentence + + commit e23a5df2f8819c88b87e3392d6522b747481e381 + Author: Thomas Köppe + Date: Sun Feb 5 17:13:46 2017 +0000 + + [iostream.format] Minor rewording to be more accurate and fit the lines better + + commit 1a0dd180eb3ea3af05cdf1f573eb6f69b0f1b152 + Author: Thomas Köppe + Date: Sun Feb 5 14:51:08 2017 +0000 + + Format "i^th" consistently. + + Fixes #653, see also #974. + + commit 24900a40ed833ccebb1f3760efe366e4ba73109a + Author: Thomas Köppe + Date: Sun Feb 5 14:26:33 2017 +0000 + + [cpp] Swap "control-line" and "if-section". + + With the increased vertical grammar spacing, it is expedient to put the presentation of "control-line" onto the first page so as not to require a huge gap. + + commit 4935ed404aa4819e63c560aa2104dbfa70d18f40 + Author: Thomas Köppe + Date: Sun Feb 5 13:09:48 2017 +0000 + + [ratio.{syn,comparison}] Mild reformatting for consistency. + + Fixes #1402. + + commit 50353bd3bb69d770d00e2fb9236bc913994b96c7 + Author: Thomas Köppe + Date: Sun Feb 5 13:03:56 2017 +0000 + + [associative.set.syn] Fix cross-reference link for 'multiset' + + Fixes #1424. + + commit 766792134b9edb507c569ead9745d12c56735115 + Author: Thomas Köppe + Date: Sun Feb 5 12:20:50 2017 +0000 + + [algorithms.parallel] Add missing \pnum + + Fixes #1432. + + commit e88d2343b441b399673aa934de766323c68353f5 + Author: Marshall Clow + Date: Sat Feb 4 20:48:13 2017 -0800 + + [string.view.template] Change the `reference`, `pointer` etc typedefs in `string_view` to use `value_type` rather than `charT` (#1416) + + This is a cut down version of https://github.com/cplusplus/draft/pull/141, to ensure that it is editorial + + commit 04fa63d98ac28457ea038b75fa05f49d14d8ab5b + Author: Jens Maurer + Date: Sun Feb 5 05:12:58 2017 +0100 + + Use 'base class subobject', not 'base subobject' (#1382) + + Fixes #1379. + + commit 2de42d5a857886ee1200990ce40f7d8e61eb2293 + Author: Thomas Köppe + Date: Sun Feb 5 04:07:38 2017 +0000 + + [func.bind.is{bind,place}] Don't begin sentences with code. + + commit 7b704e1759cb09b65c0443c9f63b4773b153d000 + Author: Eelis + Date: Sun Feb 5 04:46:40 2017 +0100 + + Capitalize examples where appropriate. (#1356) + + commit 1e00bc3e8addc7b263ecbc7b2f5a510c904b876c + Author: Jens Maurer + Date: Sun Feb 5 04:45:13 2017 +0100 + + [class.temporary] Use 'Clause~\ref{class.access}' (#1348) + + Fixes #1347. + + commit 73b2294ca033dee878d678d5c79adc62e352559e + Author: Billy O'Neal + Date: Sat Feb 4 19:44:16 2017 -0800 + + [atomics.syn] Don't describe function template overloads as "partial specializations" + + commit 41c6bac2314892f1b51b0ef4d22fd7aedb9562a5 + Author: Eelis + Date: Sun Feb 5 04:43:14 2017 +0100 + + [string.io] Don't refer to sentry by name it was not given. (#1333) + + commit 4408f4667327fffa4e527995a1b73f674e459927 + Author: Jens Maurer + Date: Sun Feb 5 04:42:14 2017 +0100 + + [lib] Replace pre: and post: in requirements tables (#1284) + + with \requires and \postcondition, respectively. + + Also replace yields: with \returns and effect: with \effects. + + Fixes #1281. + + commit cf2241bd976a3759a1a036e239471ceda48fb06c + Author: Eelis + Date: Sun Feb 5 04:38:27 2017 +0100 + + [conv.lval] Split off description of conversion result into dedicated paragraph. (#1318) + + commit a665fddad337ac8316695c06730a59e2051eaa5d + Author: Jens Maurer + Date: Sun Feb 5 04:36:14 2017 +0100 + + Harmonize formatting of 'main' function. (#1308) + + Consistently use \tcode{main}. + Add cross-references to [basic.start.main]. + + Fixes #1304. + + commit 6841997d7c36b2a4c14d638de00c1804d018c844 + Author: Eelis + Date: Sun Feb 5 04:34:59 2017 +0100 + + [expr] Split off definition of 'composite pointer type' into dedicated paragraph. (#1300) + + commit 7fcb601a9ee72dd45f7df8001c23b9f7cb8b0aca + Author: Eelis + Date: Sun Feb 5 04:33:04 2017 +0100 + + [strings] Remove remarks that repeat what was stated a few lines before. (#1289) + + commit bc106e5f01563337b4069998c6e149b795b65111 + Author: Thomas Köppe + Date: Sun Feb 5 03:31:13 2017 +0000 + + [tuple.creation] Simplify the introductory notation, and then use notation that matches the introduction. (#1251) + + commit e5674e1d47bbd87ecd4caefb3f37c4c3cb3551df + Author: Jens Maurer + Date: Sun Feb 5 04:30:31 2017 +0100 + + [func.bind.bind] Reformat to use math-style indexing. (#1285) + + Partially addresses #1139. + + commit 9a5c34e6a8c86a93167724aa5061415f1df8a069 + Author: Jens Maurer + Date: Sun Feb 5 03:30:12 2017 +0100 + + [stmt.dcl] Clarify footnote about deadlock avoidance. (#1266) + + Fixes #849. + + commit 4b0d533134e61f713a877dadbe6df92f64291d6a + Author: Jens Maurer + Date: Fri Dec 16 16:25:04 2016 +0100 + + [lib] Harmonize casing for 'shall meet the requirements of ... iterator'. + + Also cross-reference the sections, not the tables, for + iterator requirements. + + Fixes #696. + + commit 03c356f9d764a8230323bf2fdc77495b98032780 + Author: Jens Maurer + Date: Fri Dec 16 16:17:02 2016 +0100 + + [time.point] Fix cross-reference to clock requirements. + + commit 55a498202fb5b558cd93635a63ed111931634b0a + Author: Jens Maurer + Date: Sun Feb 5 02:01:30 2017 +0100 + + [lex.literal] Avoid references to plain 'literal' (#1277) + + unless the \grammarterm is intended. + + Fixes #322. + + commit 469e9f021fe65774b5845350be3cff4a12d40680 + Author: Jens Maurer + Date: Sat Feb 4 21:12:04 2017 +0100 + + [namespace.udecl] Clarify error in example. (#1254) + + commit 26e92b499f7a41c7b65c7e2828a1608021adf695 + Author: Jens Maurer + Date: Sat Feb 4 21:02:59 2017 +0100 + + [temp.deduct] Avoid talking about 'side effect' and 'evaluation' (#1252) + + when discussing template instantiations. + + commit 43c20dbebf207d985f8d051d2994ce22108049e4 + Author: Jens Maurer + Date: Sat Feb 4 20:52:06 2017 +0100 + + [alg.partitions] Move entire subclause to [alg.sorting]. (#1245) + + The non-modifying operation is_partitioned doesn't fit into + 'mutating sequence operations', and partitioning can be + considered a weak sort. + + Fixes #289. + + commit 42578d91450b0b563e076151427b6deff4647f6d + Author: Thomas Köppe + Date: Sat Feb 4 19:44:57 2017 +0000 + + [macros, styles] Remove minipages from BNF environments and use a custom enumitem list for spacing. (#1170) + + BNF entries are now spaced like normal paragraphs. Individual paragraphs are kept on a single page by setting a high widow penalty. + + It is now immaterial whether multiple nontermdefs are contained in a single bnf environment, or whether each def is in its own environment. Pages can break between elements, not within. + + commit 23d739974007c3f827ad2e55da60cb4358681773 + Author: Jens Maurer + Date: Sat Feb 4 20:19:51 2017 +0100 + + [lib] Replace 'Notes:' elements with regular [ Note: ... -- end note] (#1160) + + Remove the \realnotes and \realnote macros. + No longer mention 'Notes:' in [structure.specifications]. + + Fixes #492. + + commit 5a1d430e6c09099ba7e420db733bcf116e8ca868 + Author: Jonathan Wakely + Date: Sat Feb 4 19:08:19 2017 +0000 + + [streambuf.virt.get] use half-open ranges in underflow effects (#1157) + + commit a50661aa098dca6cb7b34061e2d30fd541999cd4 + Author: Jonathan Wakely + Date: Sat Feb 4 19:00:02 2017 +0000 + + [locale.time.get] change undefined term "record" to "object" (#1412) + + commit 3f0133279c6852aa7e7c20c2b5e97f32d80847a8 + Author: Jens Maurer + Date: Sat Feb 4 19:59:31 2017 +0100 + + [support.types] Properly describe header (#1415) + + After the synopsis for , add a sentence (cloned from cstdlib.syn) + that the contents are the same as except for wchar_t, + [support.types.nullptr], and [support.types.layout]. + + Fixes #1404. + + commit 06c788de055ef33fa8aae1d479b01600c399a86b + Author: Eelis + Date: Sat Feb 4 19:51:51 2017 +0100 + + Don't parenthesize \refs after 'in'/'of'/'notwithstanding'. (#1420) + + commit 0f8ca3d7da39bd290062408ca2b2572c40994e9a + Author: Eelis + Date: Sat Feb 4 19:50:25 2017 +0100 + + [lex.phases] Remove stray period. (#1421) + + commit 25fb80b3521531d71bb45c677ed9eace5b39f7ae + Author: Jonathan Wakely + Date: Fri Feb 3 18:49:37 2017 +0000 + + [forwardlist.ops] Add comma + + commit 019585eb4da447ff6a41fa766056b4febff08c25 + Author: timsong-cpp + Date: Wed Feb 1 08:17:03 2017 +0800 + + [locale.facet] add missing backslash in \defn (#1418) + + commit ed8dbf4c0bce4adf96307c1d427dde0685f7dbdf + Author: Eelis + Date: Mon Jan 30 13:43:20 2017 +0100 + + [dcl.enum] Italicize 'unscoped enumeration' in its definition. (#1410) + + commit c7f6a9139872aad48a944d018ce5e4b3de15ce81 + Author: Axel Naumann + Date: Thu Jan 26 17:04:41 2017 +0100 + + [thread.lock.algorithm] Change '0-based' to 'zero-based'. + + Conforming with other occurrences in the standard. + + commit b63d68ab7bc08f5e969a5b44b000941e6e82eb2e + Author: Eelis + Date: Sun Jan 22 21:26:37 2017 +0100 + + [basic.ios.cons] Remove stray semicolon. (#1397) + + commit 701df7eac2474300d2b602700a3c32a51ef439a7 + Author: Eelis + Date: Sun Jan 22 18:35:35 2017 +0100 + + Add missing \pnums. (#1396) + + commit 5ce8ed130a43ffc17b1d05d349e9568831016891 + Author: Jonathan Wakely + Date: Fri Jan 20 17:54:09 2017 +0000 + + [special] Add comma. + + commit 03c99a1b516a85000456841b061d5b1f17b32e48 + Author: Jonathan Wakely + Date: Fri Jan 20 17:52:52 2017 +0000 + + [optional.ctor] add missing \pnum + + commit 4bbb3ba2e4e7065900c12b97710db3e398c6ee2d + Author: Eelis + Date: Fri Jan 20 18:48:20 2017 +0100 + + [cpp.pragma.op] Add missing \pnums and remove unwanted paragraph breaks. (#1387) + + commit d2263429a07205edf8d2ffcd6d41cfe5d61544f8 + Author: Jens Maurer + Date: Thu Jan 19 00:17:04 2017 +0100 + + [dcl.link] Index implementation-defined behavior. (#1330) + + Fixes #1326. + + commit 61c4f655ac96e2eba807f8e13f9adae1405bdf49 + Author: Eelis + Date: Wed Jan 18 23:24:39 2017 +0100 + + [dcl.ambig.res] Describe example ambiguous case more clearly. (#1371) + + commit 94c7fdf49d51898a10c846bb0409bf07ba66256c + Author: Eelis + Date: Wed Jan 18 23:23:57 2017 +0100 + + Consistently use 'this International Standard'. (#1380) + + commit 95977f18c0594a12a90ca050ec5f8006b4b7bf53 + Author: Eelis + Date: Wed Jan 18 22:59:08 2017 +0100 + + Add missing hyphen in 'floating-point'. (#1319) + + commit 2001a03014df142f5f9a5974c64fc2ff96d4f2cd + Author: Jens Maurer + Date: Wed Jan 18 22:47:23 2017 +0100 + + 'floating-point something', not 'floating point something' (#1384) + + Adjust occurrences that spanned a line break in the LaTeX + source and were therefore missed in commit + cd3deb891cee5436a64ff9a8f7bb304a4fcc6c00. + + commit c8295e3a928f93cff021d88b7b1532b5a58d5114 + Author: Jens Maurer + Date: Wed Jan 18 22:45:41 2017 +0100 + + [stmt.stmt], [dcl.attr.deprecated] Remove hyphen in 're-declared' (#1381) + + Fixes #1378. + + commit 2b0db35833f8ccce30744b46465e609e4b109366 + Author: Thomas Köppe + Date: Wed Jan 18 14:57:38 2017 +0000 + + [utilities.general] Update reference to bitset section and add missing \rowsep + + commit 417d713d341911e3e366610c85761d246785f02f + Author: Thomas Köppe + Date: Wed Jan 18 00:33:11 2017 +0000 + + [over.match.best, over.ics.rank] Remove premature ends of sentences. + + This addresses a major part of #90. + + commit d76a411d35b1ed933cb5d11dc492ab4489cb239e + Author: Thomas Köppe + Date: Tue Jan 17 23:48:02 2017 +0000 + + [over.ics.rank] Replace self-referential reference with 'this subclause' + + commit ee154f9dd08d93124455f408f69030862acca9eb + Author: Alisdair Meredith + Date: Mon Jan 16 07:25:43 2017 -0500 + + Fix remaining uses of \Cpp macro (#1366) + + I believe this patch catches the last two places in the current + draft that should be using a variant of the \Cpp macros to + better render the 'C++' string. + + commit 4e6dc965fc2a2f562d8bd62cafe5a1d51745a79d + Author: Thomas Köppe + Date: Fri Jan 13 14:32:39 2017 +0000 + + [re] Move long pieces of code into codeblocks and remove redundant "the result of" from return statements + + This fixes overfull hboxes, see #693. + + commit ab8f2c7c0331efbb9713a46d4c940df94a0e48f7 + Author: Jens Maurer + Date: Tue Jan 10 11:04:16 2017 +0100 + + [mem.res.pool], [mem.res.monotonic.buffer] Do not define the otherwise unused term 'owns'. (#1260) + + Fixes #1257. + + commit 3acb49d296ba7efdc7542e943262138dc0eb9b74 + Author: Jonathan Wakely + Date: Fri Jan 6 19:21:45 2017 +0000 + + [string.insert] Change "pos1" to "pos" for overloads taking one position + + Also make argument names in synopsis consistent. + + Fixes #1338 + + commit 732fd444a33043bce3caf6d6d939f6e81fb56ddd + Author: Jens Maurer + Date: Thu Jan 5 13:04:01 2017 +0100 + + [rand.adapt.shuf] Show exposition-only members in the order in which initialization is described. (#1332) + + Fixes #1331. + + commit b9081cc3d7a314ac336695166e0123cdb1da6623 + Author: Kazutoshi SATODA + Date: Wed Jan 4 23:31:49 2017 +0900 + + [dcl.init] Fix a typo in definition of const-default-constructible (#1327) + + commit 10452d174140fbcf0bfc1fab37dbdbd63913be79 + Author: Eelis + Date: Wed Jan 4 11:45:00 2017 +0100 + + [complex.ops] Don't repeat declaration in "Effects:" element. (#1324) + + commit 94c2fbabdc1057d7bc7cdb83d1585d24de3fd146 + Author: Eelis + Date: Tue Jan 3 18:05:03 2017 +0100 + + [re.submatch.op] Remove excessive parentheses in "Returns:" element. (#1323) + + commit 3b81b0b9cafacee9d23b47d1a8862a9d0eee6ab7 + Author: Jens Maurer + Date: Tue Jan 3 16:58:58 2017 +0100 + + [sf.cmath] Fix 'where' associations of Greek variable names. (#1317) + + Fixes #1291. + + commit 2416d453c28a821076a1046bec1b13d6dd8ee7d7 + Author: Jens Maurer + Date: Tue Jan 3 16:05:27 2017 +0100 + + [util.smartptr.enab] Remove leftover postcondition after P0033R1. (#1314) + + Fixes #1299. + + commit 0effa034c24cc78f5128d36327f0d30047531b89 + Author: Jens Maurer + Date: Tue Jan 3 16:02:08 2017 +0100 + + [class.derived] Avoid \pnum inside examples. (#1265) + + Fixes #781. + + commit 2163ad27876b6e0423650c71b01646a8daca6cdc + Author: timsong-cpp + Date: Tue Jan 3 07:36:29 2017 -0500 + + [meta.trans.other] add missing cv for common_type (#1292) + + P0435R1 says 'cv void', but the cv part was dropped. + + commit 09e6e6de2e92c33daa53ee1013847df68c99ad52 + Author: alexanderkscott + Date: Sat Dec 31 14:06:51 2016 +0000 + + [iterators, numerics] Replace 'sub-clause' by 'subclause' (#1302) + + commit 2168e10fb3608d4ab84190d3d0c8cd5101dc52b9 + Author: Eelis + Date: Fri Dec 30 16:46:18 2016 +0100 + + Capitalize notes that consist of complete sentences. (#1297) + + commit 3681e72ce5b8d0f09e15bfb4fef11bd230951cc6 + Author: Thomas Köppe + Date: Wed Dec 21 18:58:54 2016 +0000 + + [conv.qual] Consistent notation for indexed types T_1, T_2 + + commit 3e2b77aed27438f6751ad59ca75fc90bde79993b + Author: Jens Maurer + Date: Wed Dec 21 19:55:02 2016 +0100 + + Mechanically harmonize indexed types to $\tcode{T}_i$. (#1283) + + Replace \tcode{T}$_i$ and $T_i$ with $\tcode{T}_i$. + + commit 0b9f60c4c373e57cda055b7aba64afb674db1fff + Author: Eelis + Date: Wed Dec 21 18:14:54 2016 +0100 + + [string.view.find] Add missing 'be' (#1282) + + commit d49359badc2115b010dcf978d86067f1a2cfb331 + Author: Jens Maurer + Date: Tue Dec 20 16:47:32 2016 +0100 + + [containers] Replace pre: and post: in requirements tables with \requires and \postcondition, respectively. (#1273) + + Fixes #792. + + commit 9fe30c8353b264318a1c90d2ce817347e1f6738c + Author: Casey Carter + Date: Sun Dec 18 15:34:21 2016 -0800 + + Fix typos in [mem.poly.allocator.mem]/9.1 and /9.5 (#1269) + + (There is no "T" in scope.) + + commit 666886e51092f447e9ecb6f26a2965a8c03da667 + Author: Jens Maurer + Date: Mon Dec 19 00:31:51 2016 +0100 + + [associative.reqmts] Harmonize capitalization. (#1271) + + Older entries seem to start with a lowercase letter and only + have a full stop if a second sentence follows. For newer + entries (initializer lists, node_handle functions), apply + that style, too. + + Fixes #328. + + commit a3afbc8daaa557cc0cd1f76e40158032ca6f097f + Author: Jens Maurer + Date: Fri Dec 16 15:47:47 2016 +0100 + + Avoid \pnum inside examples. (#1262) + + With the exception of [facets.examples]. + + Fixes #781. + + commit 5d129b232ac55abeb508a8f890d478a45eab5554 + Author: Jens Maurer + Date: Fri Dec 16 12:43:55 2016 +0100 + + [dcl.array], [temp.deduct.type] Split notes spanning numbered paragraphs. (#1261) + + Partially addresses #781. + + commit 3750b234c1699d2c7b0f83e2c52fbd65d74c4299 + Author: Jens Maurer + Date: Thu Dec 15 17:43:32 2016 +0100 + + [unique.ptr.single.modifiers] Use 'if and only if' when calling deleter. (#1255) + + Fixes #248. + + commit 8e64a085cdcd7c41b3f4d4298933cb52b6572420 + Author: Jens Maurer + Date: Thu Dec 15 17:42:24 2016 +0100 + + [sf.math] Promote parenthesized parts of function names to un-parenthesized. (#1256) + + Fixes #1250. + + commit f8904bd946650f240a6af76193f406377e2fb1b7 + Author: Jens Maurer + Date: Wed Nov 30 19:50:31 2016 +0100 + + [support.limits] Rearrange section 'Implementation properties' + + - Change order of subsections. + - Remove [limits] and [c.limits] subsection headings. + - Move descriptions of numeric_limits members and specializations as + subsections under the description of the primary class template. + - Add sectioning comments to the synopsis. + + Fixes #785. + + commit 9a6d4c3a14d77eaea17044e3b52942582d65eac8 + Author: Thomas Köppe + Date: Thu Dec 15 00:29:13 2016 +0000 + + [forward] Remove mid-example paragraph breaks + + commit 7f7e757693b3173d9490e63e28f384fbba7dcd91 + Author: Thomas Köppe + Date: Wed Dec 14 23:49:59 2016 +0000 + + Change a few stray headings to sentence case + + Fixes #1200 and #1201. + + commit 32026a5b490a8f0b310530425108247694968def + Author: Jens Maurer + Date: Mon Nov 21 22:45:55 2016 +0100 + + [class.copy] Rephrase rule preferring a move constructor + in a throw-expression or a return statement. + + Fixes #712. + + commit 19a0c06093e39f5b0a85316f2564312c9e52b129 + Author: Thomas Köppe + Date: Wed Dec 7 20:02:50 2016 +0000 + + [temp.class] Reorganize examples into a separate paragraph + + commit 64e5cffbef31b7a00175d969fae2cf5f70c27f48 + Author: W-E-Brown + Date: Wed Dec 14 17:03:23 2016 -0600 + + s/(possibly cv-qualified)/\\cv{}~/ and allied changes (#1142) + + Applied across the entire standard. + + commit 571a258bd4d59725e1bbbb69febaffb3d3a513ed + Author: Thomas Köppe + Date: Wed Dec 14 22:55:05 2016 +0000 + + [input.output] Add references to inclusions in a synopsis + + commit eacf4129776df8481599ec44e0c256590aed1ccb + Author: Thomas Köppe + Date: Sat Dec 10 17:56:41 2016 +0000 + + [{ex,in}clusive.scan, transform.{ex,in}clusive.scan]: Rephase 'for each *j' in terms of indexes + + Addresses #693 for this part, but is also clearer. + + commit c39761a36fed573e369ccccd81f54ee2c9f69930 + Author: Jens Maurer + Date: Wed Dec 14 21:13:57 2016 +0100 + + [iostream.forward.overview] Promote introductory + sentences to normative text. + + Fixes #494. + + commit 5f0f4df6ab6dfa566d394da9c4321c1015f63747 + Author: Richard Smith + Date: Wed Dec 14 12:21:10 2016 -0800 + + [basic.def.odr] Clarify that the "not an odr use" requirement for using + an internal linkage constant within an inline function (etc) only + applies to odr-uses within that inline function, and not uses elsewhere + in the program. + + commit 2f3c3b8c3a401fd6d8f081b608db6572be01b7e0 + Author: Jens Maurer + Date: Wed Dec 14 18:46:51 2016 +0100 + + [temp] Add variable templates to the definition of 'template'. (#1225) + + Fixes #593. + + commit f32e068898a371b94a27f895f3863a810186e70e + Author: Jens Maurer + Date: Wed Dec 14 18:38:09 2016 +0100 + + [unord] Use 'key equality predicate' consistently. (#1241) + + Replaces occasional uses of 'key equality function'. + + Fixes #630. + + commit b54f2507ffc23c0e573f4637217003b4074c33aa + Author: Eelis + Date: Wed Dec 14 18:37:20 2016 +0100 + + [strings, algorithms, diff] Replace 'routine' with 'function'. (#1217) + + commit 7b087da9cd6867fd6b8b499c6ec766499db48772 + Author: Eelis + Date: Wed Dec 14 17:58:47 2016 +0100 + + [class.derived] Don't bother splitting last remark in note off into separate paragraph. (#1240) + + commit c6d00d91a0c464c528c6cd38c442ad6a11036aa7 + Author: Eelis + Date: Wed Dec 14 17:22:14 2016 +0100 + + [dcl.init, class.directory_iterator, fs.op.current_path] Split multiparagraph notes into multiple note paragraphs. + + The paragraphs are unrelated and don't belong into a single note. + + commit f66fb79c44dc6051aa83d6489fee707a584ebe82 + Author: Johannes Laire + Date: Wed Dec 14 15:46:57 2016 +0000 + + [lib] Fix capitalization and punctuation in itemdescrs. (#1238) + + commit 6407d69c8e98e5d94e623c4cf84b1419ae12de62 + Author: Eelis + Date: Wed Dec 14 15:56:12 2016 +0100 + + [path.non-member] Structure multi-paragraph note using an itemization instead. (#1236) + + commit edd2c5fb29b2feb6a6acc23f843d351a8f06b2ec + Author: Thomas Köppe + Date: Wed Dec 14 14:35:44 2016 +0000 + + [cstdint.syn] Add cross reference to C + + commit 122b2d896fe4049e30afb498b0e59be399dc0e45 + Author: Thomas Köppe + Date: Wed Dec 14 02:53:47 2016 +0000 + + [temp] Misc tweaks: tcode, ellipses, capitalization, comment spacing + + commit 4da0a38a1982e4cb65a06848051ca4c5a43b04bd + Author: Jens Maurer + Date: Wed Dec 14 14:52:36 2016 +0100 + + [string.view.hash] Add a note about equality to string hashes. (#1235) + + From http://lists.isocpp.org/lib/2016/12/1531.php. + + commit 776fd05bf781b265cfc96711d2abfd49a781ea20 + Author: Thomas Köppe + Date: Wed Dec 14 02:15:49 2016 +0000 + + Use \commentellip macro in a few more places + + commit 81eea5e1b5a477404b39176f71699f7b87a2dc01 + Author: Thomas Köppe + Date: Wed Dec 14 01:22:29 2016 +0000 + + [over.match.best] Convert footnote into ordinary note and remove overly tutorialisque explanations + + Fixes #1232. + + commit 93631694be2ac0cd0aade763e50a49bef8f9c4b4 + Author: Jens Maurer + Date: Wed Dec 14 00:54:29 2016 +0100 + + [localization] Add numbered headings for synopses. (#1229) + + Also remove use of \synopsis for class template definitions. + + Partially addresses #566. + + commit 93ccb079c2a809aded1d71a21e783560be019492 + Author: Jens Maurer + Date: Wed Dec 14 00:49:33 2016 +0100 + + [algorithms] Add numbered heading for synopsis. (#1230) + + Partially addresses #566. + + commit e6b9e3124c58f91f8d624f3d512f1f786e1f5adb + Author: Jens Maurer + Date: Wed Dec 14 00:22:55 2016 +0100 + + [input.output] Add numbered headings for synopses. (#1228) + + Remove now-empty 'Overview' sections. + + Partially addresses #566. + + commit c9688d7dc5e4471868d84f92d98c43a01e7465e2 + Author: Jens Maurer + Date: Tue Dec 13 23:31:04 2016 +0100 + + [mem.res.monotonic.buffer.ctor] Spell reference to a parameter correctly. (#1226) + + Fixes #1055. + + commit a3f3773d4ca287c252a485c343348c729f60c82d + Author: Jens Maurer + Date: Tue Dec 13 23:06:39 2016 +0100 + + [lib] Use 'comparison function', not 'comparison operator'. (#1224) + + When talking about an operator function, use the term defined in + [defns.comparison]. + + Fixes #612. + + commit 8b1f6cc8d73eec0306db1dec66f2da52a03ea274 + Author: Jens Maurer + Date: Tue Dec 13 22:28:40 2016 +0100 + + [any] Rename the ValueType template parameter to T. (#1220) + + The parameter has a confusing name: It is not actually the value type + contained in the 'any'. + Where the new T clashes with an existing use of T, rename the latter to VT, + since this is actually the value type of the 'any'. + + Fixes #1202. + + commit e4bc84c405ac09ff7a5aa5b8df39d5e1f5b7bd39 + Author: Jens Maurer + Date: Tue Dec 13 21:56:10 2016 +0100 + + [dcl.init.ref] Replace 'type qualifier' with 'cv-qualifier' in example. (#1222) + + Fixes #1219. + + commit 1894a77ec88dd28d87985e162ef57c45580a9ad2 + Author: Jens Maurer + Date: Tue Dec 13 21:53:28 2016 +0100 + + [list.ops] Move effects to 'Effects' element. (#1221) + + Also reorder the elements so that 'Requires' is before 'Effects'. + + Fixes #796. + + commit aefc83c6c66013c5053f4c184c4fd7bf400e96fe + Author: Jens Maurer + Date: Tue Dec 13 18:20:02 2016 +0100 + + [utility], [bitset] Introduce a separate heading for the synopsis. (#1213) + + Partially addresses #566. + + commit 0a3f38c33d4fb7459fb507faf88591bc1828b31c + Author: Jens Maurer + Date: Tue Dec 13 18:19:08 2016 +0100 + + [bitset.members] Adjust confusing index entries for 'set' and 'any'. (#1218) + + Fixes #743. + + commit bc42416f97adb35907af7af8fe407d3a445a1824 + Author: Jens Maurer + Date: Mon Dec 12 23:56:13 2016 +0100 + + [thread] Add numbered headings for synopses. (#1214) + + Partially addresses #566. + + commit 546a162c06881491f8394babb4147941f2af53ee + Author: Jens Maurer + Date: Mon Dec 12 16:45:28 2016 +0100 + + [pairs.spec], [tuple.creation] Avoid 'equality' of types phrasing. (#1212) + + Fixes #491. + + commit 5ec123d3e037fc3b85542ea2f31b86c6375d7c06 + Author: Jens Maurer + Date: Mon Dec 12 16:25:47 2016 +0100 + + [class.temporary] Add paragraph number and split off example into its own paragraph. (#1211) + + commit a8a89d9144a9050b85b8bfe780340a763193a1f4 + Author: Thomas Köppe + Date: Mon Dec 12 14:46:31 2016 +0000 + + [pairs.pair, tuple.cnstr] Replace 'The constructor initializes' with just 'Initializes', which is how we say it in many other places. (#1206) + + commit 3c6ba0621a8e23c474f77fbee24b06d76b125dd3 + Author: Thomas Köppe + Date: Mon Dec 12 01:50:27 2016 +0000 + + [special] Capitalize notes and examples that are complete sentences. + + commit 3a0d1be2ccd055f6bef1e91ebc2ca7ee19f3638e + Author: Thomas Köppe + Date: Mon Dec 12 01:33:44 2016 +0000 + + [class.cdtor] Clarify presentation of example + + Seperate the hypothetical alternative case from the real code with newlines and describe in irrealis mood. + + commit 33375c726c64c4e602b52269708441f5cdccfa77 + Author: Sergey Zubkov + Date: Sun Dec 11 07:20:28 2016 -0500 + + [mem.res.syn] Call polymorphic_allocator a 'class template' (#1209) + + commit fdb5d1a7ed71add105ee5eca4307d9a6a042ba75 + Author: Sergey Zubkov + Date: Sun Dec 11 07:11:28 2016 -0500 + + [variant.bad.access] Use 'override' instead of 'virtual' in synopsis (#1208) + + commit edba6d4a097e9de2caa79461341b3c3476941790 + Author: Thomas Köppe + Date: Sat Dec 10 19:50:28 2016 +0000 + + [diff.cpp03.special] Use the more correct "call function f" rather than "call function f()" to resolve overfull line and fulfil compulsion for pedantry. + + commit 3c6d91088e58e56e295419efdd47ddc8a4628196 + Author: Thomas Köppe + Date: Sat Dec 10 17:10:54 2016 +0000 + + [func.not_fn] Clean-up not_fun + + Use placeholder macros. Reformat class synopsis in our usual style. Reorder private members. Use codeblocks for long descriptions. + + Addresses #693. + + commit 2b17f472d2c1fcfb96f5f9d4f5f7d799c6d336ae + Author: Thomas Köppe + Date: Sat Dec 10 17:09:25 2016 +0000 + + [mem.res.pool.mem] Reorder and reflow do_is_equal descriptions. + + Addresses #693 for that section. + + commit f9ce3d269eb5bd2ffd3bb74f79ba1298da1d83bc + Author: Thomas Köppe + Date: Sat Dec 10 16:34:41 2016 +0000 + + [tuple.helper, variant.helper] Change "specialization of *class*" to "specialization of *template*". + + The containing lines were too long (cf. #693), and the change is a mild increase in pedantic correctness. + + commit faaf054bd237780b3999c4efdbbcc2b6bf88721b + Author: Jens Maurer + Date: Fri Dec 9 23:32:42 2016 +0100 + + [limits] Use 'subnormal number' as defined by IEEE 754-2008 = ISO 60559. (#1203) + + Also add index entries for 'denormalized value' and 'value, + denormalized', pointing to 'number, subnormal'. + + Fixes #1017. + + commit 4f182cba568b3f753d2bdeb61c349bd65b8bf241 + Author: Jens Maurer + Date: Thu Dec 8 23:02:33 2016 +0100 + + [util.smartptr.shared.atomic] Merge duplicate description items. + + Partially addresses #288. + + commit b22cda3a831508a362930f6eb25d1f839f0f8ea8 + Author: Jens Maurer + Date: Thu Dec 8 22:57:32 2016 +0100 + + [alg.lex.comparison] Remove duplicate 'Remarks:' item and comfort lone codeblock + + Partially addresses #288. + + commit faecbe8a6f3db2bd411b64428c1f3345b1677550 + Author: Johannes Laire + Date: Thu Dec 8 15:19:45 2016 +0000 + + [rand.req.adapt] Fix syntax error (#1194) + + commit a9159bdbf9b6baa096f2c51d9129cd03431d03bd + Author: Eelis + Date: Thu Dec 8 16:08:58 2016 +0100 + + [numeric.special] Remove redundant 'inline' specifiers in example. (#1192) + + commit ff36dc5f586abb837a3963b1b8815a245bdbc741 + Author: Johannes Laire + Date: Thu Dec 8 10:47:07 2016 +0000 + + [depr] Add missing parentheses around bitwise expressions (#1191) + + commit b6d625f215dbac299982094cf54e4fed0999e873 + Author: Thomas Köppe + Date: Thu Dec 8 10:06:47 2016 +0000 + + Hyphenate 'implementation-defined' in a few residual cases + + commit 77f36805a4adc0a5d145264fc5e5e6ab11b5e8f2 + Author: Thomas Köppe + Date: Fri Dec 2 02:58:22 2016 +0000 + + [dcl.align] Touch up error comments + + commit 6d082aa3bed44e5342e55d19453d9669671063fa + Author: Jens Maurer + Date: Wed Dec 7 23:07:21 2016 +0100 + + [intseq.general] Remove example not quite mirroring a standard function. (#1187) + + Fixes #1176. + + commit 426dd1880198d5aaa51ae189d3e1d3780d3da1ce + Author: Jens Maurer + Date: Wed Dec 7 22:28:33 2016 +0100 + + [containers, alg.transform] Minor presentation fixes. (#1184) + + Harmonize the punctuation in complexity requirements where a definition + for N is introduced. + Add a missing closing parenthesis. + Add a full stop. + + Fixes #191. + + commit ff91738d4f67123fa944a76506826f7a3c14b3e2 + Author: Jens Maurer + Date: Wed Dec 7 21:25:39 2016 +0100 + + [class.virtual] Remove awkward 'but'. (#1182) + + Fixes #170. + + commit 4975167baaed59b6b3aab9d93ea14682c45a6217 + Author: Jens Maurer + Date: Wed Dec 7 20:44:25 2016 +0100 + + [function.objects] Introduce a new subsection for the synopsis. (#1179) + + Also add a cross-reference from [unord.hash] to the synopsis, which + is the only place where the primary template is declared. + + Fixes #192. + + commit d4c17ce01bf7b1419b330e798119b838ab8f1380 + Author: Jens Maurer + Date: Wed Dec 7 20:07:18 2016 +0100 + + [pairs.pair] Further harmonize spelling of template parameters for pair. (#1178) + + Fixes #125. + + commit 10ae5c39b0d4065486974c1c80d338b904a9f013 + Author: Eelis + Date: Wed Dec 7 12:13:32 2016 +0100 + + Capitalize examples outside sentences. (#1174) + + commit 5301db44da7db8839114f9c032e7fe293da31879 + Author: Eelis + Date: Wed Dec 7 11:25:11 2016 +0100 + + Capitalize notes. (#1173) + + commit d2a69983b30ba4a3dec9bece774cb11fe50353c1 + Author: Thomas Köppe + Date: Wed Dec 7 01:37:27 2016 +0000 + + [stmt.stmt] Align comments to customary columns and reflow some very narrow comments + + commit 1fe866912ad07ea76353bb08723aad8552620f7c + Author: Jens Maurer + Date: Wed Dec 7 01:55:54 2016 +0100 + + [utility] Harmonize spelling of template parameters for std::pair. (#1172) + + Addresses #125. + + commit 99c6b4c6d08b99b36a10a50127b43ab461fd2f57 + Author: Thomas Köppe + Date: Sat Dec 3 00:43:13 2016 +0000 + + [expr] Use same notation for collections of cv-qualification signatures as in [conv.qual] + + commit 2df5c6df7ee8cd884da607897b229cc8e1913ecb + Author: Thomas Köppe + Date: Tue Nov 29 02:47:55 2016 +0000 + + [basic] Reflow comments to be more compact; use math set notation for sets + + commit 28b0897221d9b641ef8439cfd29ef81b7d1f81b6 + Author: Jens Maurer + Date: Fri Dec 2 00:40:17 2016 +0100 + + [headers, depr.c.headers] Avoid brittle counts of headers. (#1167) + + Fixes #766. + + commit cf522b9177c01511a8c0b7197d9e48aa2224512d + Author: Jens Maurer + Date: Thu Dec 1 23:58:40 2016 +0100 + + [utilities] Do not use CamelCase for 'BaseCharacteristic'. (#1164) + + This is a regular English phrase used as a technical term. + + Fixes #1154. + + commit 69d8903278277e96779c8435fedad0018fe10ee4 + Author: Jens Maurer + Date: Thu Dec 1 23:52:01 2016 +0100 + + [re.regex] Add missing 'multiline' constant. (#1162) + + Fixes #1129. + + commit 19dc0aa5c8b8b53f0bfe17724fb26795c187c10a + Author: Richard Smith + Date: Fri Oct 21 11:39:17 2016 -0700 + + [dcl.init.aggr] Wording simplification. Aggregate elements are only + defined for purposes of aggregate initialization; we don't need to + repeat that every time we use the term. + + commit cca5257d60abcf9a62f545e9c146fe2c367f843a + Author: Johannes Laire + Date: Wed Nov 30 00:03:04 2016 +0000 + + Move punctuation outside quotation marks according to logical nesting (#1148) + + commit a69d5beeaf1041c064cbad97db9b05a7e6ce079c + Author: Thomas Köppe + Date: Tue Nov 29 23:57:44 2016 +0000 + + [expr.prim.lambda] Move first paragraph below grammar. + + Text before the main grammar needs to be very short; this first paragraph was getting out of hand. + + commit c58e854d79a71d7494c6c1bcf496c6795f10821b + Author: Thomas Köppe + Date: Tue Nov 29 21:47:05 2016 +0000 + + [string.classes] Turn synopsis into numbered subclause + + In pursuit of issue #566. + + commit 30e55475c622cdda9274f5d3af79eae416b650ef + Author: Thomas Köppe + Date: Tue Nov 29 21:38:41 2016 +0000 + + [tuple, variant] Turn synopses into numbered subclauses + + In pursuit of issue #566. + + commit 48efdfe014549e6d116ce12ca427f7df0e0f8c70 + Author: Thomas Köppe + Date: Tue Nov 29 19:58:48 2016 +0000 + + [pairs.pair], [tuple.tuple] Tidy up presentation of member functions (order elements consistently; use better index notation) + + Also fixes issue #1117 and partially addresses issue #653. + + commit 807e6f951e19e418cbc379797d1c32e4b8a49dca + Author: Johannes Laire + Date: Tue Nov 29 12:37:17 2016 -0500 + + [library] Capitalize headings + + commit bcd2eb6e3cfd68d90b4b761df8dd0728e4e0629b + Author: Thomas Köppe + Date: Tue Nov 29 02:52:44 2016 +0000 + + [basic.def.odf] Clarify example by adding a variable that actually odr-uses D() diff --git a/papers/n4640.pdf b/papers/n4640.pdf new file mode 100644 index 0000000000..e28b707bff Binary files /dev/null and b/papers/n4640.pdf differ diff --git a/papers/n4659.pdf b/papers/n4659.pdf new file mode 100644 index 0000000000..fedd1b8e50 Binary files /dev/null and b/papers/n4659.pdf differ diff --git a/papers/n4661.html b/papers/n4661.html new file mode 100644 index 0000000000..a29605270a --- /dev/null +++ b/papers/n4661.html @@ -0,0 +1,1005 @@ +N4661 +

N4661 Editors' Report -- Programming Languages -- C++

+ +

2017-03-20
+Richard Smith (editor) (Google Inc)
+Dawn Perchik (co-editor) (Embarcadero Technologies Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to +the members of the editing committee for the C++17 DIS, namely +Marshall Clow, +Mike Miller, +Ville Voutilainen, +and +Jeffrey Yasskin +for their review of the correctness of the working paper +as modified by the motions from the Kona 2017 meeting.

+ +

Special thanks also to +Jonathan Wakely +and +Alisdair Meredith +for performing edits and editorial review for several of the motions applied since N4640, +and to +Jens Maurer +for performing many of the editorial fixes since N4640.

+ +

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

+ +

New papers

+ +
    +
  • N4659 is the current working draft. It replaces N4640.
  • +
  • N4660 is the C++17 DIS.
  • +
  • N4661 is this Editors' Report.
  • +
+ +

The contents of N4659 and N4660 are identical except for the cover sheet and +page headings.

+ +

Motions incorporated into working draft and C++17 DIS

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolutions for 5 issues in "ready" status applied:

+ +
    +
  • 1677 Constant initialization via aggregate initialization
  • +
  • 1860 What is a "direct member?"
  • +
  • 2174 Unclear rules for friend definitions in templates
  • +
  • 2205 Restrictions on use of alignas
  • +
  • 2218 Ambiguity and namespace aliases
  • +
+ +

The other 7 issues in "ready" status from P0575R1 were applied by CWG Motion 3

+ +

CWG motion 2: Core issue resolutions for 5 issues in "tentatively ready" status applied:

+ +
    +
  • 2201 Cv-qualification of array types
  • +
  • 2206 Composite type of object and function pointers
  • +
  • 2214 Missing requirement on representation of integer values
  • +
  • 2220 Hiding index variable in range-based for
  • +
  • 2224 Member subobjects and base-class casts
  • +
  • 2259 Unclear context describing ambiguity
  • +
  • 2262 Attributes for asm-definition
  • +
+ +

CWG motion 3: Core issue resolutions for 12 issues in "ready" and "tentatively ready" status applied, resolving 13 issues:

+ +
    +
  • 426 Identically-named variables, one internally and one externally linked, allowed?
  • +
  • 727 In-class explicit specializations
  • +
  • 1622 Empty aggregate initializer for union (no changes, resolved by 2272)
  • +
  • 1710 Missing template keyword in class-or-decltype
  • +
  • 2196 Zero-initialization with virtual base classes
  • +
  • 2198 Linkage of enumerators
  • +
  • 2211 Hiding by lambda captures and parameters
  • +
  • 2247 Lambda capture and variable argument list
  • +
  • 2248 Problems with sized delete
  • +
  • 2251 Unreachable enumeration list-initialization
  • +
  • 2268 Unions with mutable members in constant expressions revisited
  • +
  • 2272 Implicit initialization of aggregate members of reference type
  • +
  • 2276 Dependent noexcept and function type-dependence
  • +
+ +

CWG motion 4: P0612R0 "NB comment CH 2: volatile", resolving 1 NB comment:

+ +
    +
  • CH 2: Clarify whether volatile semantics require volatile objects or merely volatile-qualified glvalues
  • +
+ +

CWG motion 5: P0613R0 "NB comment GB15: Resolution of Core Issue 2011", resolving 1 NB comment and 1 issue:

+ +
    +
  • GB 15, 2011 Unclear effect of reference capture of reference
  • +
+ +

CWG motion 6: P0298R3 "A byte type definition", resolving 3 NB comments:

+ + + +

CWG motion 7: P0615R0 "Renaming for structured bindings"

+ +

CWG motion 8: P0620R0 "Drafting for class template argument deduction issues", resolving 3 NB comments:

+ +
    +
  • US 94, GB 13, FI 21: Support class template argument deduction in T{x1, x2, ...} syntax
  • +
+ +

CWG motion 9: P0270R3 "Removing C dependencies from signal handler wording" with changes, see below, resolving 1 NB comment:

+ + + +

CWG motion 10: P0250R3 "Wording improvements for initialization and thread ids", resolving 2 issues in "concurrency" status:

+ +
    +
  • 1784 Concurrent execution during static local initialization
  • +
  • 2046 Incomplete thread specifications
  • +
+ +

CWG motion 11a applies to the Modules TS.

+ +

CWG motion 11b was not approved.

+ +

Library working group motions

+ +

Issue resolutions

+ +

LWG motion 1 applies to the Coroutines TS.

+ +

LWG motion 2: Library issue resolutions for 22 issues in "Ready" and "Tentatively Ready" status applied, resolving 23 issues:

+ +
    +
  • 2260 Missing requirement for Allocator::pointer
  • +
  • 2768 any_cast and move semantics (no changes, resolved by 2769)
  • +
  • 2769 Redundant const in the return type of any_cast(const any&)
  • +
  • 2781 Contradictory requirements for std::function and std::reference_wrapper
  • +
  • 2782 scoped_allocator_adaptor constructors must be constrained
  • +
  • 2784 Resolution to LWG 2484 is missing "otherwise, no effects" and is hard to parse
  • +
  • 2785 quoted should work with basic_string_view
  • +
  • 2786 Annex C should mention shared_ptr changes for array support
  • +
  • 2787 [file_status.cons] doesn't match class definition
  • +
  • 2789 Equivalence of contained objects
  • +
  • 2794 Missing requirements for allocator pointers
  • +
  • 2795 [global.functions] provides incorrect example of ADL use
  • +
  • 2804 Unconditional constexpr default constructor for istream_iterator
  • +
  • 2824 list::sort should say that the order of elements is unspecified if an exception is thrown
  • +
  • 2826 string_view iterators use old wording
  • +
  • 2834 Resolution to LWG 2223 is missing wording about end iterators
  • +
  • 2835 Resolution to LWG 2536 seems to misspecify <tgmath.h>
  • +
  • 2837 gcd and lcm should support a wider range of input values
  • +
  • 2838 is_literal_type specification needs a little cleanup
  • +
  • 2842 in_place_t check for optional::optional(U&&) should decay U
  • +
  • 2850 std::function move constructor does unnecessary work
  • +
  • 2853 Possible inconsistency in specification of erase in [vector.modifiers]
  • +
  • 2855 std::throw_with_nested("string_literal")
  • +
+ +

Resolution of 2812 "Range access is available with <string_view>" not applied, as this issue had already been resolved editorially

+ +

LWG motion 3: Library issue resolutions for 3 issues in "Review" status applied:

+ +
    +
  • 2676 Provide filesystem::path overloads for "File-based streams"
  • +
  • 2790 Missing specification of istreambuf_iterator::operator->
  • +
  • 2796 tuple should be a literal type
  • +
+ +

Filesystem

+ +

LWG motion 4: P0317R1 "Directory entry caching for filesystem" with changes, see below

+ +

LWG motion 5: P0492R2 "Proposed resolution of C++17 National Body comments for filesystems", resolving 31 NB comments and 2 issues:

+ +
    +
  • US 32: Meaning of [fs.conform.9945] unclear
  • +
  • US 33: Definition of "canonical path" problematic
  • +
  • US 34: Are there attributes of a file that are not an aspect of the file system?
  • +
  • US 36: Symbolic links themselves are attached to a directory via (hard) links
  • +
  • US 37: The term "redundant current directory (dot) elements" is not defined
  • +
  • US 43: Concerns about encoded character types
  • +
  • US 44, 2798: Definition of path in terms of a string requires leaky abstraction
  • +
  • US 45: Generic format portability compromised by unspecified root-name (no changes, resolved by US 73, CA 2)
  • +
  • US 46: filename can be empty so productions for relative-path are redundant
  • +
  • US 47: . and .. already match the name production
  • +
  • US 48: Multiple separators are often meaningful in a root-name
  • +
  • US 51: Failing to add / when appending empty string prevents useful applications (no changes, resolved by US 74, CA 3)
  • +
  • US 52, 2665: remove_filename postcondition is not by itself a definition
  • +
  • US 53: remove_filename's name does not correspond to its behavior (no changes, resolved by US 52, US 60)
  • +
  • US 54: remove_filename is broken
  • +
  • US 55: replace_extension's use of path as parameter is inappropriate
  • +
  • US 58: parent_path behavior for root paths is useless (no changes, resolved by US 77, CA 6)
  • +
  • US 60: path("/foo/").filename() == path(".") is surprising
  • +
  • US 61: Leading dots in filename should not begin an extension (no changes, resolved by US 74, CA 3)
  • +
  • US 62: It is important that stem() + extension() == filename() (no changes, resolved by US 74, CA 3)
  • +
  • US 63: lexically_normal inconsistently treats trailing / but not /.. as directory (no changes, resolved by US 37, US 74, CA 3)
  • +
  • US 73, CA 2: root-name is effectively implementation defined
  • +
  • US 74, CA 3: The term "pathname" is ambiguous in some contexts
  • +
  • US 77, CA 6: operator/ and other appends not useful if arg has root-name
  • +
  • US 78, CA 7: Member absolute in [fs.op.absolute] is overspecified for non-POSIX-like O/S
  • +
  • Late 36: permissions error_code overload should be noexcept (no changes, resolved by Late 37)
  • +
  • Late 37: permissions actions should be separate parameter
  • +
+ +

LWG motion 6: P0430R2 "File system library on non-POSIX-like operating systems", resolving 6 NB comments:

+ +
    +
  • US 75, CA 4: Extra flag in path constructors is needed
  • +
  • US 76, CA 5: root-name definition is over-specified.
  • +
  • US 79, CA 8: Some operation functions are overspecified for implementation-defined file types
  • +
+ +

Parallel algorithms

+ +

LWG motion 7: P0452R1 "Unifying <numeric> parallel algorithms", partially resolving 2 NB comments:

+ +
    +
  • US 161: inner_product should use GENERALIZED_SUM
  • +
  • US 184: inner_product should not have ExecutionPolicy overload
  • +
+ +

LWG motion 8: P0518R1 "Allowing copies as arguments to function objects given to parallel algorithms", resolving 1 NB comment:

+ +
    +
  • CH 11: Allow parallel algorithms to make copies of their arguments
  • +
+ +

LWG motion 9: P0523R1 "Complexity of parallel algorithms", partially resolving 1 NB comment:

+ +
    +
  • CH 10: Relax complexity specifications for parallel algorithms
  • +
+ +

LWG motion 10: P0574R1 "Algorithm complexity constraints and parallel overloads", partially resolving 1 NB comment:

+ +
    +
  • CH 10: Relax complexity specifications for parallel algorithms
  • +
+ +

LWG motion 11: P0467R2 "Iterator concerns for parallel algorithms", partially resolving 2 NB comments:

+ +
    +
  • US 156: Relax iterator requirements for parallel algorithms
  • +
  • US 162: Relax parallel adjacent_difference specification to permit parallelization
  • +
+ +

LWG motion 12: P0623R0 "Final C++17 parallel algorithms fixes", partially resolving 3 NB comments:

+ +
    +
  • US 161: inner_product should use GENERALIZED_SUM
  • +
  • US 162: Relax parallel adjacent_difference specification to permit parallelization
  • +
  • US 184: inner_product should not have ExecutionPolicy overload
  • +
+ +

NB response papers

+ +

LWG motion 13: P0604R0 "Resolving GB 55, US 84, US 85, US 86", resolving 4 NB comments:

+ +
    +
  • GB 55, US 85: Fix is_callable and result_of to not use a function type as their interface
  • +
  • US 84: More clearly distinguish *INVOKE(f, t1, t2, ..., tN)* and *INVOKE(f, t1, t2, ..., tN, R)*
  • +
  • US 86: Rename is_callable to is_invocable
  • +
+ +

LWG motion 14: P0607R0 "inline variables for the standard library", resolving 2 NB comments:

+ +
    +
  • FI 9, GB28: Use inline variables for library tag types
  • +
+ +

LWG motion 15: P0618R0 "Deprecating <codecvt>", resolving 3 NB comments:

+ +
    +
  • GB 57: Deprecate <codecvt>
  • +
  • US 64, CA 9: Preserve references to UCS2
  • +
+ +

LWG motion 16: Revert P0181R1 "Ordered By Default", applied by 2016-06 LWG Motion 21, resolving 1 NB comment:

+ +
    +
  • FI 18: Revert addition of default_order
  • +
+ +

LWG motion 17: P0156R2 "Variadic lock guard", resolving 2 NB comments:

+ +
    +
  • FI 8, GB 61: Revert making lock_guard variadic
  • +
+ +

LWG motion 18: P0599R1 "noexcept for hash functions", resolving 1 NB comment:

+ +
    +
  • US 140: Some or all hash<T> specializations should be noexcept
  • +
+ +

LWG motion 19: P0433R2 "Integrating template deduction for class templates into the standard library", resolving 2 NB comments and 3 issues:

+ +
    +
  • US 7, US 19 (remaining parts after P0512R0), US 147, US 148, US 150: Provide suitable deduction guides for the standard library
  • +
+ +

Despite the claims of this paper and the wording of Motion 19, +this paper is unrelated to US 14

+ +

NB issue resolutions

+ +

LWG motion 20: Library issue resolutions for 23 issues in "Immediate" status applied, resolving 20 NB comments:

+ +
    +
  • CH 7, 2904: Make variant move-assignment more exception safe
  • +
  • GB 36, 2866: Incorrect derived classes constraints
  • +
  • GB 49, 2806: Base class of bad_optional_access
  • +
  • GB 53, 2807: std::invoke should use std::is_nothrow_callable
  • +
  • GB 54, 2868: Missing specification of bad_any_cast::what()
  • +
  • US 107, 2872: Add definition for "direct-non-list-initialization"
  • +
  • US 111, 2890: The definition of "object state" applies only to class types
  • +
  • US 111, 2900: The copy and move constructors of optional are not constexpr
  • +
  • US 118, 2903: The form of initialization for the emplace-constructors is not specified
  • +
  • US 122, 2801: Default-constructibility of unique_ptr
  • +
  • US 123, 2905: is_constructible_v<unique_ptr<P | D> | P | D const &> should be false when D is not copy constructible
  • +
  • US 124, 2873: Add noexcept to several shared_ptr related functions
  • +
  • US 125, 2874: Constructor shared_ptr::shared_ptr(Y*) should be constrained
  • +
  • US 126, 2875: shared_ptr::shared_ptr(Y* | D | […]) constructors should be constrained
  • +
  • US 127, 2802: shared_ptr constructor requirements for a deleter
  • +
  • US 129, 2876: shared_ptr::shared_ptr(const weak_ptr<Y>&) constructor should be constrained
  • +
  • US 135, 2908: The less-than operator for shared pointers could do more
  • +
  • US 145, 2861: basic_string should require that charT match traits::char_type
  • +
  • US 153, 2878: Missing DefaultConstructible requirement for istream_iterator default constructor
  • +
  • US 165, 2921: packaged_task and type-erased allocators
  • +
  • 2788: basic_string range mutators unintentionally require a default constructible allocator
  • +
  • 2857: {variant,optional,any}::emplace should return the constructed value
  • +
  • 2934: optional<const T> doesn't compare with T
  • +
+ +

Note: the resolutions of issues 2894 and 2911 in P0625R0 are not included in this motion

+ +

LWG motion 20a was not approved.

+ +

LWG motion 20b: Library issue resolution for 1 issue in "Immediate" status applied, resolving 1 NB comment:

+ +
    +
  • US 143, 2911: An is_aggregate_type trait is needed
  • +
+ +

Non-NB-comment papers

+ +

LWG motion 21: P0558R1 "Resolving atomic<T> named base class inconsistencies"

+ +

LWG motion 22: P0548R1 "common_type and duration"

+ +

LWG motion 23 applies to the Ranges TS.

+ +

Notable editorial changes

+ +

Motions

+ +
    +
  • CWG 6: In application of P0298R3, updated introductory sentence of [cstddef.syn] +to avoid claiming that std::byte is part of ISO C's <stddef.h> header.

  • +
  • CWG 9: Change to [csignal.syn] was not applied, because the desired normative +effect had already been accomplished by P0175R1, +which was applied at the previous meeting and removed the baseline text for +this change. The effect of the merge is that std::signal is not required +to itself have C language linkage (but its parameter and returned function +pointer types are). Also added subclause to house description of signal +handlers, rather than including it in the <csignal> header synopsis.

  • +
  • LWG 4: The normative description of directory_entry::is_directory is +specified in terms of a non-existent file_status member, and either the +status or symlink_status members could have been intended. After +consulting with LWG, +this usage of file_status has been replaced by status.

  • +
+ +

NB comments

+ +
    +
  • __cplusplus macro value updated from 201402L to 201703L, resolving +NB comments CA 15 and US 83.

  • +
  • Added acknowledgement of ECMAScript trademark, resolving NB comment GB 10.

  • +
  • Added normative references to LIA-1 and IEEE 754.

  • +
  • Added note to definition of literal type, resolving NB comment GB 68.

  • +
  • Made introductory sentence of [basic.stc] consistent with later normative +wording, resolving NB comment JP 3, as directed by CWG.

  • +
+ +

ISO Directives

+ +
    +
  • Promoted "Scope", "Normative references", and "Terms and definitions" to +top-level Clauses as required by ISO Directives.

  • +
  • Updated introductory text of "Normative references" and "Terms and definitions" +to match those specified by ISO Directives.

  • +
+ +

Content rearrangement

+ +
    +
  • [fs.path.generic]: rearranged pathname grammar to avoid long paragraphs of +text in descriptive elements and refactored to fix ambiguities in the +grammar, after consultation with LWG.

  • +
  • [expr.prim.lambda]: split out subclauses for the closure type and captures; +reviewed by CWG at Kona 2017.

  • +
  • Move specification of deprecated standard library headers into Annex D, +after consultation with LWG.

  • +
+ +

Stable name changes

+ +
    +
  • A "Cross references from ISO C++ 2014" section has been added, listing all +stable names from C++ 2014 that do not appear within the C++ 2017 standard, +and where the corresponding text can be found (if it still exists).

  • +
  • Systematic review and cleanup of filesystem stable names:
    + [class.path] -> [fs.class.path]
    + [path.generic] -> [fs.path.generic]
    + [path.cvt] -> [fs.path.cvt]
    + [path.fmt.cvt] -> [fs.path.fmt.cvt]
    + [path.type.cvt] -> [fs.path.type.cvt]
    + [path.req] -> [fs.path.req]
    + [path.member] -> [fs.path.member]
    + [path.construct] -> [fs.path.construct]
    + [path.assign] -> [fs.path.assign]
    + [path.append] -> [fs.path.append]
    + [path.concat] -> [fs.path.concat]
    + [path.modifiers] -> [fs.path.modifiers]
    + [path.native.obs] -> [fs.path.native.obs]
    + [path.generic.obs] -> [fs.path.generic.obs]
    + [path.compare] -> [fs.path.compare]
    + [path.decompose] -> [fs.path.decompose]
    + [path.query] -> [fs.path.query]
    + [path.gen] -> [fs.path.gen]
    + [path.itr] -> [fs.path.itr]
    + [path.non-member] -> [fs.path.nonmember]
    + [path.io] -> [fs.path.io]
    + [path.factory] -> [fs.path.factory]
    + [class.filesystem_error] -> [fs.class.filesystem_error]
    + [enum.path.format] -> [fs.enum.path.format]
    + [enum.file_type] -> [fs.enum.file_type]
    + [enum.copy_options] -> [fs.enum.copy.opts]
    + [enum.perms] -> [fs.enum.perms]
    + [enum.perm_options] -> [fs.enum.perm.opts]
    + [enum.directory_options] -> [fs.enum.dir.opts]
    + [class.file_status] -> [fs.class.file_status]
    + [file_status.cons] -> [fs.file_status.cons]
    + [file_status.obs] -> [fs.file_status.obs]
    + [file_status.mods] -> [fs.file_status.mods]
    + [class.directory_entry] -> [fs.class.directory_entry]
    + [directory_entry.cons] -> [fs.dir.entry.cons]
    + [directory_entry.mods] -> [fs.dir.entry.mods]
    + [directory_entry.obs] -> [fs.dir.entry.obs]
    + [class.directory_iterator] -> [fs.class.directory_iterator]
    + [directory_iterator.members] -> [fs.dir.itr.members]
    + [directory_iterator.nonmembers] -> [fs.dir.itr.nonmembers]
    + [class.rec.dir.itr] -> [fs.class.rec.dir.itr]
    + [rec.dir.itr.members] -> [fs.rec.dir.itr.members]
    + [rec.dir.itr.nonmembers] -> [fs.rec.dir.itr.nonmembers]

  • +
  • [istreambuf.iterator] 5 subclauses +[istreambuf.iterator::equal], +[istreambuf.iterator::op!=], +[istreambuf.iterator::op*], +[istreambuf.iterator::op++], +[istreambuf.iterator::op==] +merged into a single [istreambuf.iterator.ops] comprising half a page of text;

  • +
  • Several subclauses with stable names containing :: have been renamed to +instead use . as the component separator.

  • +
+ +

Minor editorial fixes

+ +

A log of editorial fixes made since N4640 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 dbf3efe18813054c95abae388c53bf30e96e7e83
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 20 15:19:47 2017 -0700
+
+    [intro.refs], [intro.defs] Update introductory text to match latest ISO
+    Directives.
+
+commit 32825151765e214d79103a137aa29a9a4357687f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 20 15:00:51 2017 -0700
+
+    Replace "this International Standard" with "this document" in some
+    places where it is a clear improvement.
+
+    The 7th Edition of the ISO Directives no longer require us to use
+    "this International Standard" when the document refers to itself. We
+    retain that phrasing when the reference is to the abstract notion of
+    the specification as opposed to the text embodying it.
+
+    This is a step towards addressing #1389.
+
+commit 1798a9b6795d6ee92bf093e2a6256c34212552b1
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 20 14:14:22 2017 -0700
+
+    [fs.path.generic] Refactor generic pathname grammar to remove redundancy and ambiguity.
+
+commit 660d97e40353337b0b6b533903ab16e330855a77
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sat Aug 6 18:02:50 2016 +0200
+
+    [depr.func.adaptor.typedefs] Clarify that reference_wrapper does not define argument_type for non-nullary member function pointer types.
+
+commit 95cbc03c20f20d98a53a3e696df6003ec27abc42
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 8 16:35:25 2017 +0100
+
+    [istreambuf.iterator] Join subsections for operations descriptions.
+
+    There was one subsection for every operator, yet everything
+    fits on half a page.
+
+    Fixes #1429, #1449.
+
+commit d2b6fb6eefc3c28eb448352cd6d8b0d08e860a66
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 16 21:27:11 2017 +0000
+
+    [containers] Rephrase deduction guide constraints
+
+    Replace "is called with" wording that doesn't apply to deduction guides.
+
+    Move rules about qualifying as input iterators or allocators to
+    [container.requirements.general].
+
+commit a7f52d1904e5a6d2d407eb4145ba54552d0b3e69
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 20 00:07:04 2017 -0700
+
+    [fs.path.generic] Move descriptions of grammar elements out of the
+    grammar and into separate paragraphs, and format path grammar as we
+    format the language grammar.
+
+    Also rephrase description of root-name to use the defined term
+    "implementation-defined" directly rather than separating it into
+    "implementations [...] define".
+
+commit 04a9e5d759b4fea810ed029dd6b6a0d5ebfd224a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Feb 10 22:46:20 2017 +0100
+
+    [fs.op.copy], [fs.op.copy_file] Rephrase requirements on copy_options.
+
+    Use bitmask 'element' phrasing for restrictions on copy_options.
+
+    Fixes #1445.
+
+commit df9a809a36c34acc0870c5d7869e7549574e1437
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 18 23:08:32 2017 +0100
+
+    [partial.sort] Remove 'It takes' from complexity specification.
+
+    Partially addresses #1088.
+
+commit 5cf60394dbe171ec16bfbba1459772e40b9cf6e1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Mar 18 21:21:14 2017 +0000
+
+    [temp.class.spec.mfunc] Add missing comment to example
+
+commit cdd6dda21e3273ea63b733c3cfb3b630bb1847eb
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 16 15:37:17 2017 -0700
+
+    [xref] Add glossary of cross-references between C++14 section labels and
+    C++17 section labels.
+
+    Fixes #1547.
+
+commit 88c20950fac6915844143bb73129e2eb1b41d17d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 16 02:51:38 2017 +0000
+
+    [filesystem] Shorten stable names and add "fs." prefixes
+
+    [class.path] -> [fs.class.path]
+    [path.generic] -> [fs.path.generic]
+    [path.cvt] -> [fs.path.cvt]
+    [path.fmt.cvt] -> [fs.path.fmt.cvt]
+    [path.type.cvt] -> [fs.path.type.cvt]
+    [path.req] -> [fs.path.req]
+    [path.member] -> [fs.path.member]
+    [path.construct] -> [fs.path.construct]
+    [path.assign] -> [fs.path.assign]
+    [path.append] -> [fs.path.append]
+    [path.concat] -> [fs.path.concat]
+    [path.modifiers] -> [fs.path.modifiers]
+    [path.native.obs] -> [fs.path.native.obs]
+    [path.generic.obs] -> [fs.path.generic.obs]
+    [path.compare] -> [fs.path.compare]
+    [path.decompose] -> [fs.path.decompose]
+    [path.query] -> [fs.path.query]
+    [path.gen] -> [fs.path.gen]
+    [path.itr] -> [fs.path.itr]
+    [path.non-member] -> [fs.path.nonmember]
+    [path.io] -> [fs.path.io]
+    [path.factory] -> [fs.path.factory]
+    [class.filesystem_error] -> [fs.class.filesystem_error]
+    [enum.path.format] -> [fs.enum.path.format]
+    [enum.file_type] -> [fs.enum.file_type]
+    [enum.copy_options] -> [fs.enum.copy.opts]
+    [enum.perms] -> [fs.enum.perms]
+    [enum.perm_options] -> [fs.enum.perm.opts]
+    [enum.directory_options] -> [fs.enum.dir.opts]
+    [class.file_status] -> [fs.class.file_status]
+    [file_status.cons] -> [fs.file_status.cons]
+    [file_status.obs] -> [fs.file_status.obs]
+    [file_status.mods] -> [fs.file_status.mods]
+    [class.directory_entry] -> [fs.class.directory_entry]
+    [directory_entry.cons] -> [fs.dir.entry.cons]
+    [directory_entry.mods] -> [fs.dir.entry.mods]
+    [directory_entry.obs] -> [fs.dir.entry.obs]
+    [class.directory_iterator] -> [fs.class.directory_iterator]
+    [directory_iterator.members] -> [fs.dir.itr.members]
+    [directory_iterator.nonmembers] -> [fs.dir.itr.nonmembers]
+    [class.rec.dir.itr] -> [fs.class.rec.dir.itr]
+    [rec.dir.itr.members] -> [fs.rec.dir.itr.members]
+    [rec.dir.itr.nonmembers] -> [fs.rec.dir.itr.nonmembers]
+
+commit ad33212fded427f1e0b4e57c53c9e9215318b223
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Thu Mar 16 11:21:05 2017 -0400
+
+    [any.modifiers] fix emplace return type for 'any' (#1545)
+
+    LWG issue 2857 was applied verbatim, without noticing
+    that 'ValueType' had been previously changed to 'T'.
+    This makes things consistent by choosing 'T' as the
+    simpler form, more consistent with 'optional' and
+    'variant'.
+
+commit 09e4674b0b6ab2f74bfe5a14120edea874115779
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Feb 28 07:27:01 2017 +0100
+
+    [expr.prim.lambda] Move syntactic restriction on decl-specifier-seq to the front.
+
+    Per CWG guidance.
+
+commit 763a3fda5cec74d17371ddf4957f1f522331ebb0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 30 19:17:52 2016 +0100
+
+    [expr.prim.lambda] Split specification of lambda expressions into subsections.
+
+    Fixes #1155.
+
+commit 8139f2f9ec81cf4b8c24640f968880241dd23231
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 17 19:51:44 2016 +0000
+
+    Move specification of deprecated headers to Annex D
+
+commit c9354b33e1de8e0cf6dc42a73c733e1d8a34e7e0
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 15 18:29:49 2017 -0700
+
+    Update value of __cplusplus to 201703L.
+
+    Fixes #1513 and NB CA 15 and US 83 (C++17 CD).
+
+commit 8baa18cbbf33a9b73711638b13a4960e15179c6d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 15 18:29:13 2017 -0700
+
+    Add acknowledgement of ECMAScript trademark.
+
+    Fixes NB GB 10 (C++17 CD).
+
+commit 4d53b8b250751aae7768955f75eb7f27db08d83e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 15 12:55:55 2017 -0700
+
+    Editorial fixes for P0317R1.
+
+    [directory_entry.mods] Improve singular/plural, add commas.
+
+    [class.directory_iterator] Reorder words to more closely align xref with
+    the term for which it is a reference, add comma.
+
+commit dd42ed5d6e04e623992e0464e49323a2b6a1f518
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Mar 12 14:34:57 2017 -0700
+
+    [atomics.flag] Replace "shall be" with "is" when describing properties
+    of the implementation, for consistency with changes made by P0558R1.
+
+commit 49caa2b829256f8198ed649ca3f5057bde96a2c7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Mar 5 09:19:33 2017 -1000
+
+    [func.search] Add missing period
+
+commit 4f0891849e4799367174cc8783a3d88b6ff6b95a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Mar 3 02:36:27 2017 +0000
+
+    [meta.trans] replace "shall name" with "names" in traits tables
+
+commit 42c6d5cc8ed83ba4b48b8b94d51b7a317d577a46
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 20 21:45:21 2016 +0100
+
+    [lib] For showing complexity, use $N \log N$
+    and not $N \log(N)$ or other variants.
+
+    Partially addresses #1088.
+
+commit 42c5a2ce36d7403ca37cb8b038aa37065c353ba4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 20 23:45:26 2016 +0100
+
+    [intro.refs] Add normative references to LIA-1 and IEEE 754.
+
+    Fixes #237.
+
+commit bdff8687ccb470564400597403d484ad02890f24
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Feb 10 21:25:42 2017 +0100
+
+    [any] Use 'contained value' consistently.
+
+    This harmonizes the use of 'constained value' across
+    optional, variant, and any, with appropriate index
+    entries.
+
+    Fixes #1401.
+
+commit 6a5edb752b88c448dce4cba528de307d79966b9e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 9 21:42:49 2017 +0100
+
+    Harmonize punctuation for 'ill-formed, no diagnostic required'
+
+    Fixes #1450.
+
+commit 40f3fb37986ecff07567cc4601fac334fee8aff9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 8 15:35:43 2017 +0100
+
+    [basic.types] Remove excessive references to [basic.type.qualifier].
+
+    Fixes #1419.
+
+commit ee930ef3ee97f244d278ac3f762ec5f167dc005a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 2 02:20:48 2017 +0000
+
+    [rand.dist.bern.negbin] Fix index for k member
+
+commit bbcf0ea60c63d741bc51818633c70df2690e99b4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 1 13:34:52 2017 -1000
+
+    Add a note to the definition of literal type to indicate that it is not
+    a guarantee that such an object can be created in a constant expression.
+
+    Wording from John Spicer / CWG.
+
+    Addresses NB GB 68 (C++17 CD).
+
+commit be54f2e8e12c54071692ef3ebd6e49f6e3255a27
+Author: Jakub Wilk <jwilk@jwilk.net>
+Date:   Tue Feb 28 19:17:32 2017 +0100
+
+    [diff.decl] Fix typo (#1494)
+
+commit 2f6aff7e71cc33243671d1e501911d331af61fa3
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Feb 27 16:23:46 2017 -1000
+
+    [basic.stc] Fix introductory sentence on dynamic storage duration to
+    match later more-normative rule: it applies to objects, not storage.
+
+    Fixes NB JP 3 (C++17 CD).
+
+commit ec4ca6fc07907ea817152970c45d4c04c86d3c5c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Feb 27 11:30:27 2017 -0800
+
+    [intro] Promote "Scope", "Normative references", "Terms and definitions"
+    to top-level clauses per ISO directives.
+
+    Modify \definition macro so we can more easily have definitions at
+    different depths in different lists.
+
+commit fe6c8bda60fbca2cd3a488650988ce0a7df20d03
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Feb 24 12:09:31 2017 +0100
+
+    [localization, diff] Remove superfluous 'return 0;' from 'main' in examples. (#1482)
+
+commit 17e28024d81e366a6d1044fa29a0cd1bdf10f77f
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Feb 23 12:32:58 2017 +0100
+
+    [meta.unary.prop, meta.trans.other] Omit unhelpful second argument in static_asserts. (#1479)
+
+commit 33f16cb3417ad21949769d82cae36c1b653e4519
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 23 01:47:09 2017 +0100
+
+    [dcl.attr.nodiscard] Clarify example with reference return type. (#1471)
+
+    Add rationale why a warning is not encouraged for this case.
+
+    Fixes #1470.
+
+commit 7cd42666e143e19bdaf9e62211066cab255fb99f
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Feb 23 01:25:26 2017 +0100
+
+    [expr.mptr.oper] Use defined term 'null member pointer value'. (#1434)
+
+commit 5bc5cbae28d9e741ebc7df996f1f0d230ac4087e
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Feb 21 00:16:14 2017 +0100
+
+    [rand.req.{eng,dist}] Replace square brackets around reference with regular parentheses. (#1481)
+
+commit 44f489bba7c7595077043c7360cf7ff329eeb090
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sun Feb 19 15:41:48 2017 +0100
+
+    [except.spec] Add missing 'an'. (#1478)
+
+commit 16938d84892051f5c9e2fe4afca578fc57b1c4f3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Feb 18 19:21:13 2017 +0000
+
+    [support.runtime] Remove extraneous and misleading parentheses from names of functions and macros
+
+commit d2fe52eaaf53b6843ab6fe152a2a05e5a7da06fc
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Thu Feb 16 20:54:49 2017 +0100
+
+    [alg.min.max] Enlarge lfloor/rfloor delimiters. (#1455)
+
+commit 7e5537d1e9c7a6d63c9877cf5babde4ddf14807c
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Wed Feb 15 15:38:19 2017 +0100
+
+    Parenthesize some \refs. (#1436)
+
+commit 473966e60653e8e2bc8ed154d8b18a3736f97088
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 9 12:14:12 2017 +0100
+
+    [unord.req] Insert hint is 'p', not 'q' (#1440)
+
+    LWG 2540 changed the hint for insert from 'q'
+    (a valid and dereferenceable iterator) to 'p'
+    (a valid, but not necessarily dereferenceable iterator),
+    but neglected to adjust the description text.
+
+    Fixes #1423.
+
+commit 90c486f80612c3a7fd26ee408631991814f7b81c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 8 17:21:31 2017 +0100
+
+    [any.assign] Rename T to VT. (#1448)
+
+    These renames were overlooked in commit 8b1f6cc8d73eec0306db1dec66f2da52a03ea274.
+
+    Fixes #1443.
+
diff --git a/papers/n4661.md b/papers/n4661.md new file mode 100644 index 0000000000..a8331e1952 --- /dev/null +++ b/papers/n4661.md @@ -0,0 +1,825 @@ +# N4661 Editors' Report -- Programming Languages -- C++ + +2017-03-20 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Embarcadero Technologies Inc) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Special thanks to +the members of the editing committee for the C++17 DIS, namely +Marshall Clow, +Mike Miller, +Ville Voutilainen, +and +Jeffrey Yasskin +for their review of the correctness of the working paper +as modified by the motions from the Kona 2017 meeting. + +Special thanks also to +Jonathan Wakely +and +Alisdair Meredith +for performing edits and editorial review for several of the motions applied since N4640, +and to +Jens Maurer +for performing many of the editorial fixes since N4640. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4659](http://wg21.link/n4659) is the current working draft. It replaces [N4640](http://wg21.link/n4640). + * [N4660](http://wg21.link/n4660) is the C++17 DIS. + * N4661 is this Editors' Report. + +The contents of N4659 and N4660 are identical except for the cover sheet and +page headings. + +## Motions incorporated into working draft and C++17 DIS + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p0575r1) for 5 issues in "ready" status applied: + + * [1677](http://wg21.link/cwg1677) Constant initialization via aggregate initialization + * [1860](http://wg21.link/cwg1860) What is a "direct member?" + * [2174](http://wg21.link/cwg2174) Unclear rules for friend definitions in templates + * [2205](http://wg21.link/cwg2205) Restrictions on use of alignas + * [2218](http://wg21.link/cwg2218) Ambiguity and namespace aliases + +**The other 7 issues in "ready" status from P0575R1 were applied by CWG Motion 3** + +CWG motion 2: [Core issue resolutions](http://wg21.link/p0576r1) for 5 issues in "tentatively ready" status applied: + + * [2201](http://wg21.link/cwg2201) Cv-qualification of array types + * [2206](http://wg21.link/cwg2206) Composite type of object and function pointers + * [2214](http://wg21.link/cwg2214) Missing requirement on representation of integer values + * [2220](http://wg21.link/cwg2220) Hiding index variable in range-based `for` + * [2224](http://wg21.link/cwg2224) Member subobjects and base-class casts + * [2259](http://wg21.link/cwg2259) Unclear context describing ambiguity + * [2262](http://wg21.link/cwg2262) Attributes for *asm-definition* + +CWG motion 3: [Core issue resolutions](http://wg21.link/p0622r0) for 12 issues in "ready" and "tentatively ready" status applied, resolving 13 issues: + + * [426](http://wg21.link/cwg426) Identically-named variables, one internally and one externally linked, allowed? + * [727](http://wg21.link/cwg727) In-class explicit specializations + * [1622](http://wg21.link/cwg1622) Empty aggregate initializer for union (no changes, resolved by 2272) + * [1710](http://wg21.link/cwg1710) Missing `template` keyword in *class-or-decltype* + * [2196](http://wg21.link/cwg2196) Zero-initialization with virtual base classes + * [2198](http://wg21.link/cwg2198) Linkage of enumerators + * [2211](http://wg21.link/cwg2211) Hiding by lambda captures and parameters + * [2247](http://wg21.link/cwg2247) Lambda capture and variable argument list + * [2248](http://wg21.link/cwg2248) Problems with sized delete + * [2251](http://wg21.link/cwg2251) Unreachable enumeration list-initialization + * [2268](http://wg21.link/cwg2268) Unions with mutable members in constant expressions revisited + * [2272](http://wg21.link/cwg2272) Implicit initialization of aggregate members of reference type + * [2276](http://wg21.link/cwg2276) Dependent `noexcept` and function type-dependence + +CWG motion 4: [P0612R0 "NB comment CH 2: volatile"](http://wg21.link/p0612r0), resolving 1 NB comment: + + * CH 2: Clarify whether volatile semantics require volatile objects or merely volatile-qualified glvalues + +CWG motion 5: [P0613R0 "NB comment GB15: Resolution of Core Issue 2011"](http://wg21.link/p0613r0), resolving 1 NB comment and 1 issue: + + * GB 15, [2011](http://wg21.link/cwg2011) Unclear effect of reference capture of reference + +CWG motion 6: [P0298R3 "A `byte` type definition"](http://wg21.link/p0298r3), resolving 3 NB comments: + + * CA 11, US 72: Adopt [P0257R1 "A `byte` type for increased type safety"](http://wg21.link/p0257r1) with modifications + * US 22: Adopt [P0298R1 "A `byte` type definition"](http://wg21.link/p0298r1) + +CWG motion 7: [P0615R0 "Renaming for structured bindings"](http://wg21.link/p0615r0) + +CWG motion 8: [P0620R0 "Drafting for class template argument deduction issues"](http://wg21.link/p0620r0), resolving 3 NB comments: + + * US 94, GB 13, FI 21: Support class template argument deduction in `T{x1, x2, ...}` syntax + +CWG motion 9: [P0270R3 "Removing C dependencies from signal handler wording"](http://wg21.link/p0270r3) **with changes, see below**, resolving 1 NB comment: + + * CA 1: Adopt [P0270R1 "Removing C dependencies from signal handler wording"](http://wg21.link/p0270r1) + +CWG motion 10: [P0250R3 "Wording improvements for initialization and thread ids"](http://wg21.link/p0250r3), resolving 2 issues in "concurrency" status: + + * [1784](http://wg21.link/cwg1784) Concurrent execution during static local initialization + * [2046](http://wg21.link/cwg2046) Incomplete thread specifications + +CWG motion 11a applies to the Modules TS. + +CWG motion 11b was not approved. + +### Library working group motions + +#### Issue resolutions + +LWG motion 1 applies to the Coroutines TS. + +LWG motion 2: [Library issue resolutions](http://wg21.link/p0165r4) for 22 issues in "Ready" and "Tentatively Ready" status applied, resolving 23 issues: + + * [2260](http://wg21.link/lwg2260) Missing requirement for `Allocator::pointer` + * [2768](http://wg21.link/lwg2768) `any_cast` and move semantics (no changes, resolved by 2769) + * [2769](http://wg21.link/lwg2769) Redundant `const` in the return type of `any_cast(const any&)` + * [2781](http://wg21.link/lwg2781) Contradictory requirements for `std::function` and `std::reference_wrapper` + * [2782](http://wg21.link/lwg2782) `scoped_allocator_adaptor` constructors must be constrained + * [2784](http://wg21.link/lwg2784) Resolution to [LWG 2484](http://wg21.link/lwg2484) is missing "otherwise, no effects" and is hard to parse + * [2785](http://wg21.link/lwg2785) `quoted` should work with `basic_string_view` + * [2786](http://wg21.link/lwg2786) Annex C should mention `shared_ptr` changes for array support + * [2787](http://wg21.link/lwg2787) [file_status.cons] doesn't match class definition + * [2789](http://wg21.link/lwg2789) Equivalence of contained objects + * [2794](http://wg21.link/lwg2794) Missing requirements for allocator pointers + * [2795](http://wg21.link/lwg2795) [global.functions] provides incorrect example of ADL use + * [2804](http://wg21.link/lwg2804) Unconditional `constexpr` default constructor for `istream_iterator` + * [2824](http://wg21.link/lwg2824) `list::sort` should say that the order of elements is unspecified if an exception is thrown + * [2826](http://wg21.link/lwg2826) `string_view` iterators use old wording + * [2834](http://wg21.link/lwg2834) Resolution to [LWG 2223](http://wg21.link/lwg2223) is missing wording about end iterators + * [2835](http://wg21.link/lwg2835) Resolution to [LWG 2536](http://wg21.link/lwg2536) seems to misspecify `` + * [2837](http://wg21.link/lwg2837) `gcd` and `lcm` should support a wider range of input values + * [2838](http://wg21.link/lwg2838) `is_literal_type` specification needs a little cleanup + * [2842](http://wg21.link/lwg2842) `in_place_t` check for `optional::optional(U&&)` should decay `U` + * [2850](http://wg21.link/lwg2850) `std::function` move constructor does unnecessary work + * [2853](http://wg21.link/lwg2853) Possible inconsistency in specification of `erase` in [vector.modifiers] + * [2855](http://wg21.link/lwg2855) `std::throw_with_nested("string_literal")` + +**Resolution of [2812](http://wg21.link/lwg2812) "Range access is available with ``" not applied, as this issue had already been resolved editorially** + +LWG motion 3: [Library issue resolutions](http://wg21.link/p0610r0) for 3 issues in "Review" status applied: + + * [2676](http://wg21.link/lwg2676) Provide `filesystem::path` overloads for "File-based streams" + * [2790](http://wg21.link/lwg2790) Missing specification of `istreambuf_iterator::operator->` + * [2796](http://wg21.link/lwg2796) `tuple` should be a literal type + +#### Filesystem + +LWG motion 4: [P0317R1 "Directory entry caching for filesystem"](http://wg21.link/p0317r1) **with changes, see below** + +LWG motion 5: [P0492R2 "Proposed resolution of C++17 National Body comments for filesystems"](http://wg21.link/p0492r2), resolving 31 NB comments and 2 issues: + + * US 32: Meaning of [fs.conform.9945] unclear + * US 33: Definition of "canonical path" problematic + * US 34: Are there attributes of a file that are not an aspect of the file system? + * US 36: Symbolic links themselves are attached to a directory via (hard) links + * US 37: The term "redundant current directory (*dot*) elements" is not defined + * US 43: Concerns about encoded character types + * US 44, [2798](http://wg21.link/lwg2798): Definition of `path` in terms of a string requires leaky abstraction + * US 45: Generic format portability compromised by unspecified *root-name* (no changes, resolved by US 73, CA 2) + * US 46: *filename* can be empty so productions for *relative-path* are redundant + * US 47: `.` and `..` already match the *name* production + * US 48: Multiple separators are often meaningful in a *root-name* + * US 51: Failing to add `/` when appending empty string prevents useful applications (no changes, resolved by US 74, CA 3) + * US 52, [2665](http://wg21.link/lwg2665): `remove_filename` postcondition is not by itself a definition + * US 53: `remove_filename`'s name does not correspond to its behavior (no changes, resolved by US 52, US 60) + * US 54: `remove_filename` is broken + * US 55: `replace_extension`'s use of `path` as parameter is inappropriate + * US 58: `parent_path` behavior for root paths is useless (no changes, resolved by US 77, CA 6) + * US 60: `path("/foo/").filename() == path(".")` is surprising + * US 61: Leading dots in `filename` should not begin an extension (no changes, resolved by US 74, CA 3) + * US 62: It is important that `stem() + extension() == filename()` (no changes, resolved by US 74, CA 3) + * US 63: `lexically_normal` inconsistently treats trailing `/` but not `/..` as directory (no changes, resolved by US 37, US 74, CA 3) + * US 73, CA 2: *root-name* is effectively implementation defined + * US 74, CA 3: The term "pathname" is ambiguous in some contexts + * US 77, CA 6: `operator/` and other `append`s not useful if arg has *root-name* + * US 78, CA 7: Member `absolute` in [fs.op.absolute] is overspecified for non-POSIX-like O/S + * Late 36: `permissions` `error_code` overload should be `noexcept` (no changes, resolved by Late 37) + * Late 37: `permissions` actions should be separate parameter + +LWG motion 6: [P0430R2 "File system library on non-POSIX-like operating systems"](http://wg21.link/p0430r2), resolving 6 NB comments: + + * US 75, CA 4: Extra flag in `path` constructors is needed + * US 76, CA 5: *root-name* definition is over-specified. + * US 79, CA 8: Some operation functions are overspecified for implementation-defined file types + +#### Parallel algorithms + +LWG motion 7: [P0452R1 "Unifying `` parallel algorithms"](http://wg21.link/p0452r1), partially resolving 2 NB comments: + + * US 161: `inner_product` should use *`GENERALIZED_SUM`* + * US 184: `inner_product` should not have `ExecutionPolicy` overload + +LWG motion 8: [P0518R1 "Allowing copies as arguments to function objects given to parallel algorithms"](http://wg21.link/p0518r1), resolving 1 NB comment: + + * CH 11: Allow parallel algorithms to make copies of their arguments + +LWG motion 9: [P0523R1 "Complexity of parallel algorithms"](http://wg21.link/p0523r1), partially resolving 1 NB comment: + + * CH 10: Relax complexity specifications for parallel algorithms + +LWG motion 10: [P0574R1 "Algorithm complexity constraints and parallel overloads"](http://wg21.link/p0574r1), partially resolving 1 NB comment: + + * CH 10: Relax complexity specifications for parallel algorithms + +LWG motion 11: [P0467R2 "Iterator concerns for parallel algorithms"](http://wg21.link/p0467r2), partially resolving 2 NB comments: + + * US 156: Relax iterator requirements for parallel algorithms + * US 162: Relax parallel `adjacent_difference` specification to permit parallelization + +LWG motion 12: [P0623R0 "Final C++17 parallel algorithms fixes"](http://wg21.link/p0623r0), partially resolving 3 NB comments: + + * US 161: `inner_product` should use *`GENERALIZED_SUM`* + * US 162: Relax parallel `adjacent_difference` specification to permit parallelization + * US 184: `inner_product` should not have `ExecutionPolicy` overload + +#### NB response papers + +LWG motion 13: [P0604R0 "Resolving GB 55, US 84, US 85, US 86"](http://wg21.link/p0604r0), resolving 4 NB comments: + + * GB 55, US 85: Fix `is_callable` and `result_of` to not use a function type as their interface + * US 84: More clearly distinguish `*INVOKE(f, t1, t2, ..., tN)*` and `*INVOKE(f, t1, t2, ..., tN, R)*` + * US 86: Rename `is_callable` to `is_invocable` + +LWG motion 14: [P0607R0 "`inline` variables for the standard library"](http://wg21.link/p0607r0), resolving 2 NB comments: + + * FI 9, GB28: Use `inline` variables for library tag types + +LWG motion 15: [P0618R0 "Deprecating ``"](http://wg21.link/p0618r0), resolving 3 NB comments: + + * GB 57: Deprecate `` + * US 64, CA 9: Preserve references to UCS2 + +LWG motion 16: **Revert [P0181R1 "Ordered By Default"](http://wg21.link/p0181r1)**, applied by 2016-06 LWG Motion 21, resolving 1 NB comment: + + * FI 18: Revert addition of `default_order` + +LWG motion 17: [P0156R2 "Variadic lock guard"](http://wg21.link/p0156r2), resolving 2 NB comments: + + * FI 8, GB 61: Revert making `lock_guard` variadic + +LWG motion 18: [P0599R1 "`noexcept` for `hash` functions"](http://wg21.link/p0599r1), resolving 1 NB comment: + + * US 140: Some or all `hash` specializations should be `noexcept` + +LWG motion 19: [P0433R2 "Integrating template deduction for class templates into the standard library"](http://wg21.link/p0433r2), resolving 2 NB comments and 3 issues: + + * US 7, US 19 (remaining parts after P0512R0), US 147, US 148, US 150: Provide suitable deduction guides for the standard library + +**Despite the claims of this paper and the wording of Motion 19, +this paper is unrelated to US 14** + +#### NB issue resolutions + +LWG motion 20: [Library issue resolutions](http://wg21.link/p0625r0) for 23 issues in "Immediate" status applied, resolving 20 NB comments: + + * CH 7, [2904](http://wg21.link/lwg2904): Make `variant` move-assignment more exception safe + * GB 36, [2866](http://wg21.link/lwg2866): Incorrect derived classes constraints + * GB 49, [2806](http://wg21.link/lwg2806): Base class of `bad_optional_access` + * GB 53, [2807](http://wg21.link/lwg2807): `std::invoke` should use `std::is_nothrow_callable` + * GB 54, [2868](http://wg21.link/lwg2868): Missing specification of `bad_any_cast::what()` + * US 107, [2872](http://wg21.link/lwg2872): Add definition for "direct-non-list-initialization" + * US 111, [2890](http://wg21.link/lwg2890): The definition of "object state" applies only to class types + * US 111, [2900](http://wg21.link/lwg2900): The copy and move constructors of `optional` are not `constexpr` + * US 118, [2903](http://wg21.link/lwg2903): The form of initialization for the emplace-constructors is not specified + * US 122, [2801](http://wg21.link/lwg2801): Default-constructibility of `unique_ptr` + * US 123, [2905](http://wg21.link/lwg2905): `is_constructible_v | P | D const &>` should be `false` when `D` is not copy constructible + * US 124, [2873](http://wg21.link/lwg2873): Add `noexcept` to several `shared_ptr` related functions + * US 125, [2874](http://wg21.link/lwg2874): Constructor `shared_ptr::shared_ptr(Y*)` should be constrained + * US 126, [2875](http://wg21.link/lwg2875): `shared_ptr::shared_ptr(Y* | D | […])` constructors should be constrained + * US 127, [2802](http://wg21.link/lwg2802): `shared_ptr` constructor requirements for a deleter + * US 129, [2876](http://wg21.link/lwg2876): `shared_ptr::shared_ptr(const weak_ptr&)` constructor should be constrained + * US 135, [2908](http://wg21.link/lwg2908): The less-than operator for shared pointers could do more + * US 145, [2861](http://wg21.link/lwg2861): `basic_string` should require that `charT` match `traits::char_type` + * US 153, [2878](http://wg21.link/lwg2878): Missing DefaultConstructible requirement for `istream_iterator` default constructor + * US 165, [2921](http://wg21.link/lwg2921): `packaged_task` and type-erased allocators + * [2788](http://wg21.link/lwg2788): `basic_string` range mutators unintentionally require a default constructible allocator + * [2857](http://wg21.link/lwg2857): `{variant,optional,any}::emplace` should return the constructed value + * [2934](http://wg21.link/lwg2934): `optional` doesn't compare with `T` + +**Note: the resolutions of issues 2894 and 2911 in P0625R0 are not included in this motion** + +LWG motion 20a was not approved. + +LWG motion 20b: [Library issue resolution](http://wg21.link/p0625r0) for 1 issue in "Immediate" status applied, resolving 1 NB comment: + + * US 143, [2911](http://wg21.link/lwg2911): An `is_aggregate_type` trait is needed + +#### Non-NB-comment papers + +LWG motion 21: [P0558R1 "Resolving `atomic` named base class inconsistencies"](http://wg21.link/p0558r1) + +LWG motion 22: [P0548R1 "`common_type` and `duration`"](http://wg21.link/p0548r1) + +LWG motion 23 applies to the Ranges TS. + +## Notable editorial changes + +### Motions + + * CWG 6: In application of P0298R3, updated introductory sentence of [cstddef.syn] + to avoid claiming that `std::byte` is part of ISO C's `` header. + + * CWG 9: Change to [csignal.syn] was not applied, because the desired normative + effect had already been accomplished by [P0175R1](http://wg21.link/p0175r1), + which was applied at the previous meeting and removed the baseline text for + this change. The effect of the merge is that `std::signal` is *not* required + to itself have C language linkage (but its parameter and returned function + pointer types are). Also added subclause to house description of signal + handlers, rather than including it in the `` header synopsis. + + * LWG 4: The normative description of `directory_entry::is_directory` is + specified in terms of a non-existent `file_status` member, and either the + `status` or `symlink_status` members could have been intended. After + [consulting with LWG](http://lists.isocpp.org/lib/2017/03/2262.php), + this usage of `file_status` has been replaced by `status`. + +### NB comments + + * `__cplusplus` macro value updated from `201402L` to `201703L`, resolving + NB comments CA 15 and US 83. + + * Added acknowledgement of ECMAScript trademark, resolving NB comment GB 10. + + * Added normative references to LIA-1 and IEEE 754. + + * Added note to definition of literal type, resolving NB comment GB 68. + + * Made introductory sentence of [basic.stc] consistent with later normative + wording, resolving NB comment JP 3, as directed by CWG. + +### ISO Directives + + * Promoted "Scope", "Normative references", and "Terms and definitions" to + top-level Clauses as required by ISO Directives. + + * Updated introductory text of "Normative references" and "Terms and definitions" + to match those specified by ISO Directives. + +### Content rearrangement + + * [fs.path.generic]: rearranged *pathname* grammar to avoid long paragraphs of + text in descriptive elements and refactored to fix ambiguities in the + grammar, after consultation with LWG. + + * [expr.prim.lambda]: split out subclauses for the closure type and captures; + reviewed by CWG at Kona 2017. + + * Move specification of deprecated standard library headers into Annex D, + after consultation with LWG. + +### Stable name changes + + * A "Cross references from ISO C++ 2014" section has been added, listing all + stable names from C++ 2014 that do not appear within the C++ 2017 standard, + and where the corresponding text can be found (if it still exists). + + * Systematic review and cleanup of filesystem stable names: + [class.path] -> [fs.class.path] + [path.generic] -> [fs.path.generic] + [path.cvt] -> [fs.path.cvt] + [path.fmt.cvt] -> [fs.path.fmt.cvt] + [path.type.cvt] -> [fs.path.type.cvt] + [path.req] -> [fs.path.req] + [path.member] -> [fs.path.member] + [path.construct] -> [fs.path.construct] + [path.assign] -> [fs.path.assign] + [path.append] -> [fs.path.append] + [path.concat] -> [fs.path.concat] + [path.modifiers] -> [fs.path.modifiers] + [path.native.obs] -> [fs.path.native.obs] + [path.generic.obs] -> [fs.path.generic.obs] + [path.compare] -> [fs.path.compare] + [path.decompose] -> [fs.path.decompose] + [path.query] -> [fs.path.query] + [path.gen] -> [fs.path.gen] + [path.itr] -> [fs.path.itr] + [path.non-member] -> [fs.path.nonmember] + [path.io] -> [fs.path.io] + [path.factory] -> [fs.path.factory] + [class.filesystem\_error] -> [fs.class.filesystem\_error] + [enum.path.format] -> [fs.enum.path.format] + [enum.file\_type] -> [fs.enum.file\_type] + [enum.copy\_options] -> [fs.enum.copy.opts] + [enum.perms] -> [fs.enum.perms] + [enum.perm\_options] -> [fs.enum.perm.opts] + [enum.directory\_options] -> [fs.enum.dir.opts] + [class.file\_status] -> [fs.class.file\_status] + [file\_status.cons] -> [fs.file\_status.cons] + [file\_status.obs] -> [fs.file\_status.obs] + [file\_status.mods] -> [fs.file\_status.mods] + [class.directory\_entry] -> [fs.class.directory\_entry] + [directory\_entry.cons] -> [fs.dir.entry.cons] + [directory\_entry.mods] -> [fs.dir.entry.mods] + [directory\_entry.obs] -> [fs.dir.entry.obs] + [class.directory\_iterator] -> [fs.class.directory\_iterator] + [directory\_iterator.members] -> [fs.dir.itr.members] + [directory\_iterator.nonmembers] -> [fs.dir.itr.nonmembers] + [class.rec.dir.itr] -> [fs.class.rec.dir.itr] + [rec.dir.itr.members] -> [fs.rec.dir.itr.members] + [rec.dir.itr.nonmembers] -> [fs.rec.dir.itr.nonmembers] + + * [istreambuf.iterator] 5 subclauses + [istreambuf.iterator::equal], + [istreambuf.iterator::op!=], + [istreambuf.iterator::op\*], + [istreambuf.iterator::op++], + [istreambuf.iterator::op==] + merged into a single [istreambuf.iterator.ops] comprising half a page of text; + + * Several subclauses with stable names containing `::` have been renamed to + instead use `.` as the component separator. + +## Minor editorial fixes + +A log of editorial fixes made since N4640 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/n4640...n4659). + + commit dbf3efe18813054c95abae388c53bf30e96e7e83 + Author: Richard Smith + Date: Mon Mar 20 15:19:47 2017 -0700 + + [intro.refs], [intro.defs] Update introductory text to match latest ISO + Directives. + + commit 32825151765e214d79103a137aa29a9a4357687f + Author: Richard Smith + Date: Mon Mar 20 15:00:51 2017 -0700 + + Replace "this International Standard" with "this document" in some + places where it is a clear improvement. + + The 7th Edition of the ISO Directives no longer require us to use + "this International Standard" when the document refers to itself. We + retain that phrasing when the reference is to the abstract notion of + the specification as opposed to the text embodying it. + + This is a step towards addressing #1389. + + commit 1798a9b6795d6ee92bf093e2a6256c34212552b1 + Author: Richard Smith + Date: Mon Mar 20 14:14:22 2017 -0700 + + [fs.path.generic] Refactor generic pathname grammar to remove redundancy and ambiguity. + + commit 660d97e40353337b0b6b533903ab16e330855a77 + Author: Eelis van der Weegen + Date: Sat Aug 6 18:02:50 2016 +0200 + + [depr.func.adaptor.typedefs] Clarify that reference_wrapper does not define argument_type for non-nullary member function pointer types. + + commit 95cbc03c20f20d98a53a3e696df6003ec27abc42 + Author: Jens Maurer + Date: Wed Feb 8 16:35:25 2017 +0100 + + [istreambuf.iterator] Join subsections for operations descriptions. + + There was one subsection for every operator, yet everything + fits on half a page. + + Fixes #1429, #1449. + + commit d2b6fb6eefc3c28eb448352cd6d8b0d08e860a66 + Author: Jonathan Wakely + Date: Thu Mar 16 21:27:11 2017 +0000 + + [containers] Rephrase deduction guide constraints + + Replace "is called with" wording that doesn't apply to deduction guides. + + Move rules about qualifying as input iterators or allocators to + [container.requirements.general]. + + commit a7f52d1904e5a6d2d407eb4145ba54552d0b3e69 + Author: Richard Smith + Date: Mon Mar 20 00:07:04 2017 -0700 + + [fs.path.generic] Move descriptions of grammar elements out of the + grammar and into separate paragraphs, and format path grammar as we + format the language grammar. + + Also rephrase description of root-name to use the defined term + "implementation-defined" directly rather than separating it into + "implementations [...] define". + + commit 04a9e5d759b4fea810ed029dd6b6a0d5ebfd224a + Author: Jens Maurer + Date: Fri Feb 10 22:46:20 2017 +0100 + + [fs.op.copy], [fs.op.copy_file] Rephrase requirements on copy_options. + + Use bitmask 'element' phrasing for restrictions on copy_options. + + Fixes #1445. + + commit df9a809a36c34acc0870c5d7869e7549574e1437 + Author: Jens Maurer + Date: Sat Mar 18 23:08:32 2017 +0100 + + [partial.sort] Remove 'It takes' from complexity specification. + + Partially addresses #1088. + + commit 5cf60394dbe171ec16bfbba1459772e40b9cf6e1 + Author: Thomas Köppe + Date: Sat Mar 18 21:21:14 2017 +0000 + + [temp.class.spec.mfunc] Add missing comment to example + + commit cdd6dda21e3273ea63b733c3cfb3b630bb1847eb + Author: Richard Smith + Date: Thu Mar 16 15:37:17 2017 -0700 + + [xref] Add glossary of cross-references between C++14 section labels and + C++17 section labels. + + Fixes #1547. + + commit 88c20950fac6915844143bb73129e2eb1b41d17d + Author: Jonathan Wakely + Date: Thu Mar 16 02:51:38 2017 +0000 + + [filesystem] Shorten stable names and add "fs." prefixes + + [class.path] -> [fs.class.path] + [path.generic] -> [fs.path.generic] + [path.cvt] -> [fs.path.cvt] + [path.fmt.cvt] -> [fs.path.fmt.cvt] + [path.type.cvt] -> [fs.path.type.cvt] + [path.req] -> [fs.path.req] + [path.member] -> [fs.path.member] + [path.construct] -> [fs.path.construct] + [path.assign] -> [fs.path.assign] + [path.append] -> [fs.path.append] + [path.concat] -> [fs.path.concat] + [path.modifiers] -> [fs.path.modifiers] + [path.native.obs] -> [fs.path.native.obs] + [path.generic.obs] -> [fs.path.generic.obs] + [path.compare] -> [fs.path.compare] + [path.decompose] -> [fs.path.decompose] + [path.query] -> [fs.path.query] + [path.gen] -> [fs.path.gen] + [path.itr] -> [fs.path.itr] + [path.non-member] -> [fs.path.nonmember] + [path.io] -> [fs.path.io] + [path.factory] -> [fs.path.factory] + [class.filesystem_error] -> [fs.class.filesystem_error] + [enum.path.format] -> [fs.enum.path.format] + [enum.file_type] -> [fs.enum.file_type] + [enum.copy_options] -> [fs.enum.copy.opts] + [enum.perms] -> [fs.enum.perms] + [enum.perm_options] -> [fs.enum.perm.opts] + [enum.directory_options] -> [fs.enum.dir.opts] + [class.file_status] -> [fs.class.file_status] + [file_status.cons] -> [fs.file_status.cons] + [file_status.obs] -> [fs.file_status.obs] + [file_status.mods] -> [fs.file_status.mods] + [class.directory_entry] -> [fs.class.directory_entry] + [directory_entry.cons] -> [fs.dir.entry.cons] + [directory_entry.mods] -> [fs.dir.entry.mods] + [directory_entry.obs] -> [fs.dir.entry.obs] + [class.directory_iterator] -> [fs.class.directory_iterator] + [directory_iterator.members] -> [fs.dir.itr.members] + [directory_iterator.nonmembers] -> [fs.dir.itr.nonmembers] + [class.rec.dir.itr] -> [fs.class.rec.dir.itr] + [rec.dir.itr.members] -> [fs.rec.dir.itr.members] + [rec.dir.itr.nonmembers] -> [fs.rec.dir.itr.nonmembers] + + commit ad33212fded427f1e0b4e57c53c9e9215318b223 + Author: Alisdair Meredith + Date: Thu Mar 16 11:21:05 2017 -0400 + + [any.modifiers] fix emplace return type for 'any' (#1545) + + LWG issue 2857 was applied verbatim, without noticing + that 'ValueType' had been previously changed to 'T'. + This makes things consistent by choosing 'T' as the + simpler form, more consistent with 'optional' and + 'variant'. + + commit 09e4674b0b6ab2f74bfe5a14120edea874115779 + Author: Jens Maurer + Date: Tue Feb 28 07:27:01 2017 +0100 + + [expr.prim.lambda] Move syntactic restriction on decl-specifier-seq to the front. + + Per CWG guidance. + + commit 763a3fda5cec74d17371ddf4957f1f522331ebb0 + Author: Jens Maurer + Date: Wed Nov 30 19:17:52 2016 +0100 + + [expr.prim.lambda] Split specification of lambda expressions into subsections. + + Fixes #1155. + + commit 8139f2f9ec81cf4b8c24640f968880241dd23231 + Author: Thomas Köppe + Date: Thu Nov 17 19:51:44 2016 +0000 + + Move specification of deprecated headers to Annex D + + commit c9354b33e1de8e0cf6dc42a73c733e1d8a34e7e0 + Author: Richard Smith + Date: Wed Mar 15 18:29:49 2017 -0700 + + Update value of __cplusplus to 201703L. + + Fixes #1513 and NB CA 15 and US 83 (C++17 CD). + + commit 8baa18cbbf33a9b73711638b13a4960e15179c6d + Author: Richard Smith + Date: Wed Mar 15 18:29:13 2017 -0700 + + Add acknowledgement of ECMAScript trademark. + + Fixes NB GB 10 (C++17 CD). + + commit 4d53b8b250751aae7768955f75eb7f27db08d83e + Author: Richard Smith + Date: Wed Mar 15 12:55:55 2017 -0700 + + Editorial fixes for P0317R1. + + [directory_entry.mods] Improve singular/plural, add commas. + + [class.directory_iterator] Reorder words to more closely align xref with + the term for which it is a reference, add comma. + + commit dd42ed5d6e04e623992e0464e49323a2b6a1f518 + Author: Richard Smith + Date: Sun Mar 12 14:34:57 2017 -0700 + + [atomics.flag] Replace "shall be" with "is" when describing properties + of the implementation, for consistency with changes made by P0558R1. + + commit 49caa2b829256f8198ed649ca3f5057bde96a2c7 + Author: Thomas Köppe + Date: Sun Mar 5 09:19:33 2017 -1000 + + [func.search] Add missing period + + commit 4f0891849e4799367174cc8783a3d88b6ff6b95a + Author: Jonathan Wakely + Date: Fri Mar 3 02:36:27 2017 +0000 + + [meta.trans] replace "shall name" with "names" in traits tables + + commit 42c6d5cc8ed83ba4b48b8b94d51b7a317d577a46 + Author: Jens Maurer + Date: Tue Dec 20 21:45:21 2016 +0100 + + [lib] For showing complexity, use $N \log N$ + and not $N \log(N)$ or other variants. + + Partially addresses #1088. + + commit 42c5a2ce36d7403ca37cb8b038aa37065c353ba4 + Author: Jens Maurer + Date: Tue Dec 20 23:45:26 2016 +0100 + + [intro.refs] Add normative references to LIA-1 and IEEE 754. + + Fixes #237. + + commit bdff8687ccb470564400597403d484ad02890f24 + Author: Jens Maurer + Date: Fri Feb 10 21:25:42 2017 +0100 + + [any] Use 'contained value' consistently. + + This harmonizes the use of 'constained value' across + optional, variant, and any, with appropriate index + entries. + + Fixes #1401. + + commit 6a5edb752b88c448dce4cba528de307d79966b9e + Author: Jens Maurer + Date: Thu Feb 9 21:42:49 2017 +0100 + + Harmonize punctuation for 'ill-formed, no diagnostic required' + + Fixes #1450. + + commit 40f3fb37986ecff07567cc4601fac334fee8aff9 + Author: Jens Maurer + Date: Wed Feb 8 15:35:43 2017 +0100 + + [basic.types] Remove excessive references to [basic.type.qualifier]. + + Fixes #1419. + + commit ee930ef3ee97f244d278ac3f762ec5f167dc005a + Author: Jonathan Wakely + Date: Thu Mar 2 02:20:48 2017 +0000 + + [rand.dist.bern.negbin] Fix index for k member + + commit bbcf0ea60c63d741bc51818633c70df2690e99b4 + Author: Richard Smith + Date: Wed Mar 1 13:34:52 2017 -1000 + + Add a note to the definition of literal type to indicate that it is not + a guarantee that such an object can be created in a constant expression. + + Wording from John Spicer / CWG. + + Addresses NB GB 68 (C++17 CD). + + commit be54f2e8e12c54071692ef3ebd6e49f6e3255a27 + Author: Jakub Wilk + Date: Tue Feb 28 19:17:32 2017 +0100 + + [diff.decl] Fix typo (#1494) + + commit 2f6aff7e71cc33243671d1e501911d331af61fa3 + Author: Richard Smith + Date: Mon Feb 27 16:23:46 2017 -1000 + + [basic.stc] Fix introductory sentence on dynamic storage duration to + match later more-normative rule: it applies to objects, not storage. + + Fixes NB JP 3 (C++17 CD). + + commit ec4ca6fc07907ea817152970c45d4c04c86d3c5c + Author: Richard Smith + Date: Mon Feb 27 11:30:27 2017 -0800 + + [intro] Promote "Scope", "Normative references", "Terms and definitions" + to top-level clauses per ISO directives. + + Modify \definition macro so we can more easily have definitions at + different depths in different lists. + + commit fe6c8bda60fbca2cd3a488650988ce0a7df20d03 + Author: Eelis + Date: Fri Feb 24 12:09:31 2017 +0100 + + [localization, diff] Remove superfluous 'return 0;' from 'main' in examples. (#1482) + + commit 17e28024d81e366a6d1044fa29a0cd1bdf10f77f + Author: Eelis + Date: Thu Feb 23 12:32:58 2017 +0100 + + [meta.unary.prop, meta.trans.other] Omit unhelpful second argument in static_asserts. (#1479) + + commit 33f16cb3417ad21949769d82cae36c1b653e4519 + Author: Jens Maurer + Date: Thu Feb 23 01:47:09 2017 +0100 + + [dcl.attr.nodiscard] Clarify example with reference return type. (#1471) + + Add rationale why a warning is not encouraged for this case. + + Fixes #1470. + + commit 7cd42666e143e19bdaf9e62211066cab255fb99f + Author: Eelis + Date: Thu Feb 23 01:25:26 2017 +0100 + + [expr.mptr.oper] Use defined term 'null member pointer value'. (#1434) + + commit 5bc5cbae28d9e741ebc7df996f1f0d230ac4087e + Author: Eelis + Date: Tue Feb 21 00:16:14 2017 +0100 + + [rand.req.{eng,dist}] Replace square brackets around reference with regular parentheses. (#1481) + + commit 44f489bba7c7595077043c7360cf7ff329eeb090 + Author: Eelis + Date: Sun Feb 19 15:41:48 2017 +0100 + + [except.spec] Add missing 'an'. (#1478) + + commit 16938d84892051f5c9e2fe4afca578fc57b1c4f3 + Author: Thomas Köppe + Date: Sat Feb 18 19:21:13 2017 +0000 + + [support.runtime] Remove extraneous and misleading parentheses from names of functions and macros + + commit d2fe52eaaf53b6843ab6fe152a2a05e5a7da06fc + Author: Eelis + Date: Thu Feb 16 20:54:49 2017 +0100 + + [alg.min.max] Enlarge lfloor/rfloor delimiters. (#1455) + + commit 7e5537d1e9c7a6d63c9877cf5babde4ddf14807c + Author: Eelis + Date: Wed Feb 15 15:38:19 2017 +0100 + + Parenthesize some \refs. (#1436) + + commit 473966e60653e8e2bc8ed154d8b18a3736f97088 + Author: Jens Maurer + Date: Thu Feb 9 12:14:12 2017 +0100 + + [unord.req] Insert hint is 'p', not 'q' (#1440) + + LWG 2540 changed the hint for insert from 'q' + (a valid and dereferenceable iterator) to 'p' + (a valid, but not necessarily dereferenceable iterator), + but neglected to adjust the description text. + + Fixes #1423. + + commit 90c486f80612c3a7fd26ee408631991814f7b81c + Author: Jens Maurer + Date: Wed Feb 8 17:21:31 2017 +0100 + + [any.assign] Rename T to VT. (#1448) + + These renames were overlooked in commit 8b1f6cc8d73eec0306db1dec66f2da52a03ea274. + + Fixes #1443. diff --git a/papers/n4687.pdf b/papers/n4687.pdf new file mode 100644 index 0000000000..434402ba51 Binary files /dev/null and b/papers/n4687.pdf differ diff --git a/papers/n4688.html b/papers/n4688.html new file mode 100644 index 0000000000..38466dadb7 --- /dev/null +++ b/papers/n4688.html @@ -0,0 +1,823 @@ +N4688 +

N4688 Editors' Report -- Programming Languages -- C++

+ +

2017-07-30
+Richard Smith (editor) (Google Inc)
+Dawn Perchik (co-editor) (Embarcadero Technologies Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to +Jens Maurer, +Jonathan Wakely, +and Eelis van der Weegen +for performing many of the editorial fixes since N4659.

+ +

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

+ +

New papers

+ +
    +
  • N4687 is the current working draft for C++20. It replaces N4659.
  • +
  • N4688 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolution for 1 issue in "ready" status applied:

+ +
    +
  • 2253 Unnamed bit-fields and zero-initialization
  • +
+ +

CWG motion 2: Core issue resolutions for 6 issues in "tentatively ready" status applied, resolving 8 issues:

+ +
    +
  • 1523 Point of declaration in range-based for
  • +
  • 1704 Type checking in explicit instantiation of variable templates
  • +
  • 1728 Type of an explicit instantiation of a variable template (no changes, resolved by 1704)
  • +
  • 1836 Use of class type being defined in trailing-return-type
  • +
  • 2273 Inheriting constructors vs implicit default constructor
  • +
  • 2277 Ambiguity inheriting constructors with default arguments (no changes, resolved by 2273)
  • +
  • 2287 Pointer-interconvertibility in non-standard-layout unions
  • +
  • 2290 Unclear specification for overload resolution and deleted special member functions
  • +
+ +

CWG motion 3: P0727R0 "Temporary objects vs temporary expressions", resolving 3 core issue:

+ +
    +
  • 943 Is T() a temporary?
  • +
  • 1076 Value categories and lvalue temporaries
  • +
  • 1299 "Temporary objects" vs "temporary expressions"
  • +
+ +

CWG motion 4: P0683R1 "Default member initializers for bit-fields"

+ +

CWG motion 5: P0704R1 "Fixing const-qualified pointers to members"

+ +

CWG motion 6: P0409R2 "Allow lambda capture [=, this]"

+ +

CWG motion 7: P0306R4 "Comma omission and comma deletion"

+ +

CWG motion 8: P0329R4 "Designated initialization"

+ +

CWG motion 9: P0428R2 "Familiar template syntax for generic lambdas"

+ +

CWG motion 10: P0702R1 "Language support for constructor template argument deduction"

+ +

CWG motion 11: P0734R0 "Concepts" with changes, see below

+ +

CWG motion 12 applies to the Modules TS.

+ +

Library working group motions

+ +

LWG motion 13-14 apply to the Coroutines TS.

+ +

LWG motion 15-22 apply to the Ranges TS.

+ +

LWG motion 23-29 apply to the Networking TS.

+ +

LWG motion 30 applies to the Parallelism TS.

+ +

LWG motion 31: Library issue resolutions for 12 issues in "Ready" and "Tentatively Ready" status applied:

+ +
    +
  • 2444 Inconsistent complexity for std::sort_heap
  • +
  • 2593 Moved-from state of Allocators
  • +
  • 2597 std::log misspecified for complex numbers
  • +
  • 2783 stack::emplace() and queue::emplace() should return decltype(auto)
  • +
  • 2932 Constraints on parallel algorithm implementations are underspecified
  • +
  • 2937 Is equivalent("existing_thing", "not_existing_thing") an error?
  • +
  • 2940 result_of specification also needs a little cleanup
  • +
  • 2942 LWG 2873's resolution missed weak_ptr::owner_before
  • +
  • 2954 Specialization of the convenience variable templates should be prohibited
  • +
  • 2961 Bad postcondition for set_default_resource
  • +
  • 2966 Incomplete resolution of US 74
  • +
  • 2974 Diagnose out of bounds tuple_element / variant_alternative
  • +
+ +

LWG motion 32: Library issue resolutions for 2 issues in "Immediate" status applied:

+ +
    +
  • 2901 variants cannot properly support allocators
  • +
  • 2956 filesystem::canonical() still defined in terms of absolute(p, base)
  • +
+ +

LWG motion 33: P0463R1 "Endian, just endian"

+ +

LWG motion 34: P0682R1: "Repairing elementary string conversions", resolving 1 library issue:

+ +
    +
  • 2955 to_chars / from_chars depend on std::string
  • +
+ +

LWG motion 35: P0739R0 "Some improvements to class template argument deduction integration into the standard library", resolving 2 as-yet-unnumbered library issues

+ +

LWG motion 36: P0674R1 "Extending make_shared to support arrays", resolving 1 library issue:

+ +
    +
  • 2070 allocate_shared should use allocator_traits<A>::construct
  • +
+ +

Notable editorial changes

+ +

Motions

+ +
    +
  • CWG 11: The grammar production for a concept definition missed the trailing ;. +This has been rectified editorially, reflecting the obvious intent of the committee. +Two changes adding "concepts" to lists of entities have not been changed, because +a concept is a template and "templates" in general were already in the relevant list. +Several other changes were made rephrasing the wording to match the prevailing style of +the working draft.
  • +
+ +

Stable name changes

+ +

The "Cross references from ISO C++ 2014" section has been replaced by a +"Cross references from ISO C++ 2017" section.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made since N4659 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 9b13e3785ef95f3c7ac159177a03bccd610b774b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 30 16:13:25 2017 -0700
+
+    [dcl.array] Consolidate redundant, repetitive, and somewhat incorrect
+    examples and notes on multidimensional arrays.
+
+    Fixes #1645
+
+commit 19c63142301038e843bfd23676e036768ab35c96
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sun Jul 30 23:50:06 2017 +0800
+
+    [expr.const] Move p7 next to p3.
+
+commit bbca26c5e79d52a1622ff0cedeb92897a1350bf9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Apr 5 20:23:15 2017 +0200
+
+    [expr.type.conv] Clarify if ... otherwise ladder.
+
+    Fixes #1591.
+
+commit 9f16f5ae4a54f2478d268c408100c5a005d3f278
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jul 22 00:57:55 2017 +0200
+
+    [expr] Use 'possibly converted' for discarded-value expression.
+
+    Fixes #1597.
+
+commit 8d7a1a767f933e917b6bb20eea3e1c5fabf1cc0c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 29 20:42:39 2017 +0200
+
+    [class.mfct.non-static], [class.this] Define and use cv member function.
+
+    Fixes #447.
+
+commit 1314cc49a106fac2acba29e0e301343f857ba252
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed May 10 13:24:59 2017 -0700
+
+    Change the return type of monotonic_buffer_resource's deleted assignment
+
+    ... to monotonic_buffer_resource& for consistency with the default definition of the builtin assignment operator. This change has no normative effect, it only eliminates the inconsistency as a potential source of confusion.
+
+    Since the return type of deleted functions is not observable, this change is editorial.
+
+commit c85f24dee9feb613c9454db572cd674234f3159f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Mar 25 16:20:40 2017 +0000
+
+    [string.cons] Consolidate two functions into one description
+
+commit f897604bd8cab510a843153db0133c3d5e13912f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jul 22 00:31:23 2017 +0200
+
+    [class.temporary] Remove note giving questionable implementation advice.
+
+    And move the surviving part of the note to before the
+    corresponding example.
+
+    Fixes #1674.
+
+commit 10e4c7437ba63c2975a160e84aecffdbfafd990b
+Author: Hubert Tong <hstong@ca.ibm.com>
+Date:   Mon Jul 24 17:45:16 2017 -0400
+
+    [over.call.object] Reference postfix-expression in call syntax correctly
+
+    The grammar production corresponding to the call syntax has
+    _postfix-expression_ as the callee operand. [over.call.object] appears
+    to refer to this operand as the _primary-expression_ in the syntax.
+
+commit ad966418d82b4e5480ad390a5f75ffbf37385f37
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 28 17:16:07 2017 -0700
+
+    [temp] Add missing ';' to grammar for concept-definition.
+
+    Despite being a normative change, this matches the overwhelmingly
+    obvious intent of the committee.
+
+    Fixes #1686
+
+commit afd6d4f065219067f372dafd1bb590a912775b41
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 28 17:13:28 2017 -0700
+
+    [temp.constr.normal] Give a proper definition for "normalization".
+
+commit 38408888321282f9c0788ec9c40e2bd2f464617b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 28 16:47:17 2017 -0700
+
+    [temp.constr.order] Fix spacing in example.
+
+commit aa4b1ae864fb85377570ba9775b5d34d79772922
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 28 16:42:40 2017 -0700
+
+    [temp.constr.order] Clarify description of subsumption and ordering by constraints.
+
+commit 508cd59e6c9b23441ce5ed46e5012ccd1a8aed51
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 28 11:24:51 2017 -0700
+
+    [dcl.fct.def] Reword = default ; and = delete ; introductory text for clarity.
+
+commit 182937c038dec15efaf5521d53d06960d6f1d661
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 28 11:20:18 2017 -0700
+
+    [dcl.fct] Move use of "parameter-type-list" to after its definition.
+
+    Split rules on function redeclarations out of rules for determining the
+    type of an individual function.
+
+commit ac6360546cb1eb982cf8d2123ceb2c99a0156b95
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jul 26 14:22:49 2017 -0700
+
+    [expr.prim.req] Use grammar terms rather than undefined phrases when
+    referring to kinds of *requirement*.
+
+commit ff1242c4aa50958fa0380208eb0f2c45e3a8fea2
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 25 13:49:18 2017 +0100
+
+    [meta.endian] Simplify wording, avoid "shall"
+
+commit 17820beb537c1576fe906228d741b64b9b2e8fc1
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 24 11:22:34 2017 -0700
+
+    [temp] Fix example to use valid expression in requires-clause.
+
+commit 02574b8575c200095aa281d0886a73fe58c00580
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 24 00:37:34 2017 -0700
+
+    [temp.inst] Tweak explanation in example.
+
+commit de236bab92922adc3c38f6fc0eb1fb4ec2a17c16
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 24 00:36:24 2017 -0700
+
+    [temp.inst] Fix typo 'the the'.
+
+commit a76a3886035f484866add3a12af43c3b21143aa1
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 24 00:34:07 2017 -0700
+
+    [temp.concept] Remove redundancy: the global scope is a namespace scope.
+
+commit 9a94a384336cb37974b3a8803dcf2424812ec854
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 24 00:27:55 2017 -0700
+
+    [temp.class.spec] Fix typo "the primary" -> "the primary template".
+
+commit 7240fc98453bad27eb6112ae98b0f8e8fad8e39a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 24 00:25:43 2017 -0700
+
+    [temp.mem.func] Add introductory text to new example to separate it from the prior example.
+
+commit 99013e76613ec877b912b18b3ffeb9d2b1cf8f1c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 24 00:20:39 2017 -0700
+
+    [expr.prim.req.compound] Switch to passive voice.
+
+commit 1f1b944f2d849974ae01a5f2c45883d8213c3653
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 24 00:04:15 2017 -0700
+
+    [temp.param] Switch to passive voice.
+
+commit 6568af0b4270bfc1497882a108741fa01ebeaa70
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 23 23:54:34 2017 -0700
+
+    [temp] Add note around example to explain what it's an example of, and
+    add missing paragraph numbers.
+
+commit d37aa67b1bf795d4d98e79a9cc7ca8278608dc4f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 23 23:48:17 2017 -0700
+
+    [temp] Fix confusion between two different forms of template-declaration.
+
+    When the template-head is followed by a concept-definition, it is not
+    technically followed by a declaration, so avoid claiming that it is.
+
+commit 4d88f30cdbb3d49019935f15340b88b79382c202
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 23 23:38:15 2017 -0700
+
+    [over.over] Switch to passive voice.
+
+commit 78a8901592907f8904ec824b2966414900586869
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 23 23:25:18 2017 -0700
+
+    [expr.prim.req.nested] Remove incorrect (out of date) note.
+
+commit ca3cb945e042dc5bf63edfeeaf6d2e42ce2a3669
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 23 15:01:59 2017 -0700
+
+    [expr.prim.req] Remove redundant note that repeats what the prior example just said.
+
+commit 763a125ca686aae8aaed3fd8f779bf5ad7ca1a5c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 23 14:58:25 2017 -0700
+
+    [expr.prim.req] Repair meaningless "A requirement is one that [..]" phrasing.
+
+commit fcbeb9e63ad175128a1d7a9f5dc70536f5e2be81
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Jul 23 14:44:30 2017 -0700
+
+    [temp.constr.atomic] Split long paragraph into three.
+
+commit 119b98d70d24612e425fb2ae1b6caffb93689b89
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jul 20 22:30:39 2017 +0100
+
+    [filebuf.virtuals] Refer to return values specified in Effects
+
+    Fixes #1552
+
+commit ecad20efeaf0c244ea6a64d79484a0145a51242b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 20 09:03:27 2017 -0700
+
+    [expr.mptr.oper] Rephrase wording for symmetry with P0704R1.
+
+commit 32fffbe4796ab0852f7bdf66b6d48d2e2b5e61ea
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Jul 18 21:02:33 2017 +0200
+
+    [iterator.synopsis, template.bitset] Add missing whitespace. (#1673)
+
+commit b7ac9558b63434daa2217b35512225bc3213ebb4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Jul 15 15:04:54 2017 -0700
+
+    [expr.const] Fix example of integral constant expression conversion to
+    involve integral constant expressions.
+
+    Fixes #1627.
+
+commit cd2cc5c4709f4b8295d71d9fed92f3f2b2393f77
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Jul 15 14:49:27 2017 -0700
+
+    [alg.equal] Fix misapplication of P0467R2: change "no" to "an" in bullet
+    3.2.
+
+    Fixes #1578.
+
+commit b226afc6dcddc427668a47710d13064de23b0167
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Jul 15 14:39:03 2017 -0700
+
+    [stringbuf.virtuals] Note in Returns: element that the return value for
+    non-error cases is specified in the Effects: element.
+
+    Fixes #1552
+
+commit b63b10a9aeb8a7ef0b3f2cbbb9a20be88f0b56b7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jul 15 23:21:32 2017 +0200
+
+    [variant.visit], [tuple.apply], [futures.task.members] add cross-references for INVOKE to [func.require]
+
+    Fixes #1480.
+
+commit 8d45c56ea7224266462c6c807987676bcf35e93e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Jul 15 14:13:14 2017 -0700
+
+    Add missing index entries for 'alignas', alignof', 'noexcept'.
+
+commit 6114f86c1479a9ebf3b27fae694e9157a1a12423
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jul 15 15:51:17 2017 -0400
+
+    Move reference to LIA-1 into a new section 'Bibliography'
+
+commit 488ef200887417bfa6124896549c09447a8c2fa9
+Author: JF Bastien <github@jfbastien.com>
+Date:   Mon Jul 10 22:39:29 2017 -0400
+
+    Clarify a note on cmpxchg
+
+    The "thus" part absolutely does not follow from the preceding note text, and isn't even correct on its own. Since this is a note I assume this is an editorial change and doesn't need an issue.
+
+commit f268d45e51ddadcb21036185900a602c9a502413
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jul 10 17:43:08 2017 +0100
+
+    [filesystem_error.members] Rename to [fs.filesystem_error.members]
+
+    Fixes #1633
+
+commit 331b6a67d4fa55d1f8d4c9eb300c4aa7ce63d27e
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jul 10 17:41:18 2017 +0100
+
+    [stringbuf.virtuals] balance parentheses in seekoff table
+
+commit 48c0e75206dc98cfcb5ea88ebe29fa8858f6448a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jun 28 11:42:56 2017 +0100
+
+    [memory.syn] Add reinterpret_pointer_cast to synopsis
+
+commit 921ef046dc2daab44f6c7638aef3a03f85a06909
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Apr 7 21:14:43 2017 +0200
+
+    Replace 'encouraged' with 'should'.
+
+    Consistent with ISO Directives, Part 2, encouragement for
+    implementations is supposed to use 'should', not 'encouraged'.
+
+    Fixes #1601.
+
+commit 89fccb39352b0c30b07272e38487dbf9fb67ed76
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sat Apr 8 12:45:21 2017 +0200
+
+    [temp.deduct.type] Use \cv instead of \grammarterm{cv-list}.
+
+commit 0740877e0dd13b15c411f4b8f1fc489ecffec52f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Apr 5 23:10:33 2017 +0200
+
+    [string.streams], [file.streams] Use simple-template-id when naming base classes.
+
+    Fixes #1551.
+
+commit 0207b6c6c40a884292a2a7ff1ea8c8a7d08b9d9f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Apr 5 21:14:24 2017 +0200
+
+    Spell 'well-defined' with a hyphen when it is an adjective.
+
+    Fixes #1587.
+
+commit 2044cbd25d588150bb0a19cc8df2992a88a29e1e
+Author: Richard Smith <richard-github@metafoo.co.uk>
+Date:   Sat Jul 15 11:41:57 2017 -0700
+
+    [basic.def.odr] Replace mid-sentence period with "; and"
+
+commit 95ac3d662c788cdabc382509be4c273e5c80b334
+Author: lewissbaker <lewissbaker@users.noreply.github.com>
+Date:   Thu Jul 6 21:42:46 2017 +0930
+
+    [stmt.if] Fix spelling mistake in 'if constexpr' wording. (#1653)
+
+commit 48da313836eb57fd8282649c6c17b50a9cb97c3a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 20 14:59:57 2017 -0700
+
+    [lex.string] Remove mention of trigraphs from raw string literal example.
+
+    Fixes #1635.
+
+commit 1268aa09067159b94a6f83267d0a539b81dbbdc6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 20 14:45:07 2017 -0700
+
+    [meta.unary.prop] Fix typo 'remove_all_extents<T>' which should say
+    'remove_all_extents_t<T>', introduced editorially in commit 79974877.
+
+    Fixes #1644.
+
+commit c92319d1caf3462e1a3a745ea3947d56c974383a
+Author: Evan Wallace <onlyone@senet.com.au>
+Date:   Mon Jun 19 01:56:28 2017 +1000
+
+    [basic.stc.dynamic.safety] Update cross-reference to effects of using invalid pointer values. (#1636)
+
+    Updated the Note describing "invalid pointer values" to refer to [basic.stc] rather than [basic.stc.dynamic.deallocation].
+
+    The relevant description of "invalid pointer values" reads:
+    "Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior."
+
+    Previously the reference was correct, as this text was in [basic.stc.dynamic.deallocation]/4, but the text was moved to [basic.stc]/4 by P0137R1; without updating the reference.
+
+    The Note also incorrectly claims that using an invalid pointer value is always undefined, when it can be implementation defined in certain cases, but I did not fix this in this commit; as updating the reference makes this nuance sufficiently clear.
+
+    This is an editorial issue as it only changes non-normative text.
+
+commit 5eeec28487dd99e9e2441fc3e64e33b7a957a8fe
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Jun 17 15:45:17 2017 +0200
+
+    For 'signal-safe', refer to [support.signal], not [csignal.syn]. (#1640)
+
+commit 8c005473ba69d52314d5c399c9c9adb6429cc7ed
+Author: Zhihao Yuan <lichray@gmail.com>
+Date:   Thu May 18 11:36:43 2017 -0500
+
+    [any.nonmembers] fix LWG2769 resolution
+
+    Restores the changes made by #1220
+
+commit e8c2b45b618ef13843dd9fbc3e26f1520c8522a8
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 17 23:06:18 2017 +0100
+
+    [fs.dir.entry.obs] Fix position of error_code arguments
+
+    Fixes #1630
+
+commit ae6271c88727c3fabe7dd8258f8687b369d83d6d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Apr 20 23:06:37 2017 +0100
+
+    [fs.filesystem.syn] Update synopsis for filesystem::absolute
+
+commit c42d836d952219eba62edf1ef47ad763b5e57a54
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Apr 18 11:59:59 2017 +0200
+
+    [streambuf.virt.put] Fix logic error in the specification of the overflow() effects, introduced by 0b640ed8161937d31f31e251c297b658c559a978. (#1613)
+
+commit d5c0fd378f01b1aa9710ac8f2b61a6bc79b27aa5
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Apr 18 11:57:08 2017 +0200
+
+    [class.protected] Add missing full stop at end of sentence. (#1614)
+
+commit 70a0afc6dfbd5699ab562ebb93b269abde2834ba
+Author: Daniel Grunwald <grunwald@axivion.com>
+Date:   Wed Apr 12 19:19:45 2017 +0200
+
+    [fs.class.path] Add missing semicolon
+
+commit 6debd6037c34befdb156e805912917d154ea658f
+Author: Daniel Grunwald <grunwald@axivion.com>
+Date:   Thu Apr 6 20:47:58 2017 +0200
+
+    [iomanip.syn] Fix std::setfill() template declaration
+
+commit c17b1771be3f51dcea4d7670392ba9052a33c0b1
+Author: Daniel Grunwald <grunwald@axivion.com>
+Date:   Thu Apr 6 20:37:21 2017 +0200
+
+    [cmath.syn] Fix hypot(long double,long double) overload
+
+commit 578c39a0d74543a49da66483059debd7fb1316bc
+Author: Daniel Grunwald <grunwald@axivion.com>
+Date:   Thu Apr 6 20:19:21 2017 +0200
+
+    [cstring.syn], [cwchar.syn] Add a bunch of missing semicolons
+
+commit 07e4d9ceea888564765a2821a0a7d883dd315acb
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Apr 11 14:19:51 2017 -0700
+
+    [except.spec] Add missing '~' in comment in example.
+
+    Thanks to Sergey P. Derevyago for reporting this!
+
+commit 98b39118c529e4ed72d707ba325412a61d734f16
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Mar 28 21:55:42 2017 +0200
+
+    [filesystems] Change '!predicate' phrasing to 'predicate is false'.
+
+    Fixes #1535.
+
+commit dff391e0df8e4c8f4bb0eb74ecc6bf2578c18fd0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 31 21:58:25 2017 +0200
+
+    [lib] Use nullptr, not 0, for null pointer values. (#1586)
+
+    Fixes #208.
+
+commit e030dc8c97ac3da75817ac4867e7c403e55de252
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Mar 28 21:38:48 2017 +0200
+
+    [any.cons] Use 'contained value', not 'contained object'. (#1582)
+
+    Fixes #1580.
+
+commit 389cc2d957a5e9f133c631fa1c23e14bc3dc97fe
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Mar 28 16:20:44 2017 +0100
+
+    [any.bad_any_cast] fix incorrect references to bad_any_access
+
+commit a0f6514c5e51714da31a6d0a7aa9a218908a3c86
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Mar 26 18:07:52 2017 +0100
+
+    [locale.money.get.members] Fix missing parameter type
+
+commit 5f7e2c6f5711ba3818519ec3b3f2c84d23a8fe93
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Mar 26 17:41:45 2017 +0100
+
+    [facet.ctype.char.virtuals] Add missing \pnum
+
+commit b12acc0d4aa1095ed0306e31155c1662205c2437
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Mar 26 16:44:14 2017 +0100
+
+    [category.ctype] Replace unnecessary placeholder type by the usual 'see below'
+
+commit fc9599aea58a7ea7e671f9b304cc1fe3f89c2a8b
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sat Mar 25 20:37:39 2017 +0800
+
+    [utility] Change 'nonzero' to more appropriate words. (#1575)
+
+commit 5d438d2569decb770062966bb347cc4b1eb075b0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Mar 23 22:14:14 2017 +0100
+
+    [mem.poly.allocator.mem], [string.view.iterators] Replace 'method' with 'member function'.
+
+    Fixes #1573.
+
+commit 6d5ac829064fb264cac2805b0e8fdf193b32b62c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 22 00:25:58 2017 +0100
+
+    [intro.memory] Replace undefined 'field' with 'member' in note.
+
+    Fixes #1569.
+
+commit f04c1dcee22cc5f1dd6d99448f8de4da8ba31ed3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Mar 24 23:54:54 2017 +0000
+
+    [except.handle, except.spec, fs.op.temp_dir_path] Fix typos
+
diff --git a/papers/n4688.md b/papers/n4688.md new file mode 100644 index 0000000000..8ce5443f5a --- /dev/null +++ b/papers/n4688.md @@ -0,0 +1,682 @@ +# N4688 Editors' Report -- Programming Languages -- C++ + +2017-07-30 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Embarcadero Technologies Inc) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Special thanks to +Jens Maurer, +Jonathan Wakely, +and Eelis van der Weegen +for performing many of the editorial fixes since N4659. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4687](http://wg21.link/n4687) is the current working draft for C++20. It replaces [N4659](http://wg21.link/n4659). + * N4688 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolution](http://wg21.link/p0710r1) for 1 issue in "ready" status applied: + + * [2253](http://wg21.link/cwg2253) Unnamed bit-fields and zero-initialization + +CWG motion 2: [Core issue resolutions](http://wg21.link/p0711r0) for 6 issues in "tentatively ready" status applied, resolving 8 issues: + + * [1523](http://wg21.link/cwg1523) Point of declaration in range-based for + * [1704](http://wg21.link/cwg1704) Type checking in explicit instantiation of variable templates + * [1728](http://wg21.link/cwg1728) Type of an explicit instantiation of a variable template (no changes, resolved by 1704) + * [1836](http://wg21.link/cwg1836) Use of class type being defined in trailing-return-type + * [2273](http://wg21.link/cwg2273) Inheriting constructors vs implicit default constructor + * [2277](http://wg21.link/cwg2277) Ambiguity inheriting constructors with default arguments (no changes, resolved by 2273) + * [2287](http://wg21.link/cwg2287) Pointer-interconvertibility in non-standard-layout unions + * [2290](http://wg21.link/cwg2290) Unclear specification for overload resolution and deleted special member functions + +CWG motion 3: [P0727R0 "Temporary objects vs temporary expressions"](http://wg21.link/p0727r0), resolving 3 core issue: + + * [943](http://wg21.link/cwg943) Is `T()` a temporary? + * [1076](http://wg21.link/cwg1076) Value categories and lvalue temporaries + * [1299](http://wg21.link/cwg1299) "Temporary objects" vs "temporary expressions" + +CWG motion 4: [P0683R1 "Default member initializers for bit-fields"](http://wg21.link/p0683r1) + +CWG motion 5: [P0704R1 "Fixing `const`-qualified pointers to members"](http://wg21.link/p0704r1) + +CWG motion 6: [P0409R2 "Allow lambda capture `[=, this]`"](http://wg21.link/p0409r2) + +CWG motion 7: [P0306R4 "Comma omission and comma deletion"](http://wg21.link/p0306r4) + +CWG motion 8: [P0329R4 "Designated initialization"](http://wg21.link/p0329r4) + +CWG motion 9: [P0428R2 "Familiar template syntax for generic lambdas"](http://wg21.link/p0428r2) + +CWG motion 10: [P0702R1 "Language support for constructor template argument deduction"](http://wg21.link/p0702r1) + +CWG motion 11: [P0734R0 "Concepts"](http://wg21.link/p0734r0) **with changes, see below** + +CWG motion 12 applies to the Modules TS. + +### Library working group motions + +LWG motion 13-14 apply to the Coroutines TS. + +LWG motion 15-22 apply to the Ranges TS. + +LWG motion 23-29 apply to the Networking TS. + +LWG motion 30 applies to the Parallelism TS. + +LWG motion 31: [Library issue resolutions](http://wg21.link/p0698r0) for 12 issues in "Ready" and "Tentatively Ready" status applied: + + * [2444](http://wg21.link/lwg2444) Inconsistent complexity for `std::sort_heap` + * [2593](http://wg21.link/lwg2593) Moved-from state of `Allocator`s + * [2597](http://wg21.link/lwg2597) `std::log` misspecified for complex numbers + * [2783](http://wg21.link/lwg2783) `stack::emplace()` and `queue::emplace()` should return `decltype(auto)` + * [2932](http://wg21.link/lwg2932) Constraints on parallel algorithm implementations are underspecified + * [2937](http://wg21.link/lwg2937) Is `equivalent("existing_thing", "not_existing_thing")` an error? + * [2940](http://wg21.link/lwg2940) `result_of` specification also needs a little cleanup + * [2942](http://wg21.link/lwg2942) [LWG 2873](http://wg21.link/lwg2873)'s resolution missed `weak_ptr::owner_before` + * [2954](http://wg21.link/lwg2954) Specialization of the convenience variable templates should be prohibited + * [2961](http://wg21.link/lwg2961) Bad postcondition for `set_default_resource` + * [2966](http://wg21.link/lwg2966) Incomplete resolution of US 74 + * [2974](http://wg21.link/lwg2974) Diagnose out of bounds `tuple_element` / `variant_alternative` + +LWG motion 32: [Library issue resolutions](http://wg21.link/p0699r0) for 2 issues in "Immediate" status applied: + + * [2901](http://wg21.link/lwg2901) `variant`s cannot properly support allocators + * [2956](http://wg21.link/lwg2956) `filesystem::canonical()` still defined in terms of `absolute(p, base)` + +LWG motion 33: [P0463R1 "Endian, just endian"](http://wg21.link/p0463r1) + +LWG motion 34: [P0682R1: "Repairing elementary string conversions"](http://wg21.link/p0682r1), resolving 1 library issue: + + * [2955](http://wg21.link/lwg2955) `to_chars` / `from_chars` depend on `std::string` + +LWG motion 35: [P0739R0 "Some improvements to class template argument deduction integration into the standard library"](http://wg21.link/p0739r0), resolving 2 as-yet-unnumbered library issues + +LWG motion 36: [P0674R1 "Extending `make_shared` to support arrays"](http://wg21.link/p0674r1), resolving 1 library issue: + + * [2070](http://wg21.link/lwg2070) `allocate_shared` should use `allocator_traits::construct` + +## Notable editorial changes + +### Motions + + * CWG 11: The grammar production for a `concept` definition missed the trailing `;`. + This has been rectified editorially, reflecting the obvious intent of the committee. + Two changes adding "concepts" to lists of entities have not been changed, because + a concept is a template and "templates" in general were already in the relevant list. + Several other changes were made rephrasing the wording to match the prevailing style of + the working draft. + +### Stable name changes + +The "Cross references from ISO C++ 2014" section has been replaced by a +"Cross references from ISO C++ 2017" section. + +## Minor editorial fixes + +A log of editorial fixes made since N4659 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/n4659...n4687). + + commit 9b13e3785ef95f3c7ac159177a03bccd610b774b + Author: Richard Smith + Date: Sun Jul 30 16:13:25 2017 -0700 + + [dcl.array] Consolidate redundant, repetitive, and somewhat incorrect + examples and notes on multidimensional arrays. + + Fixes #1645 + + commit 19c63142301038e843bfd23676e036768ab35c96 + Author: S. B. Tam + Date: Sun Jul 30 23:50:06 2017 +0800 + + [expr.const] Move p7 next to p3. + + commit bbca26c5e79d52a1622ff0cedeb92897a1350bf9 + Author: Jens Maurer + Date: Wed Apr 5 20:23:15 2017 +0200 + + [expr.type.conv] Clarify if ... otherwise ladder. + + Fixes #1591. + + commit 9f16f5ae4a54f2478d268c408100c5a005d3f278 + Author: Jens Maurer + Date: Sat Jul 22 00:57:55 2017 +0200 + + [expr] Use 'possibly converted' for discarded-value expression. + + Fixes #1597. + + commit 8d7a1a767f933e917b6bb20eea3e1c5fabf1cc0c + Author: Jens Maurer + Date: Wed Mar 29 20:42:39 2017 +0200 + + [class.mfct.non-static], [class.this] Define and use cv member function. + + Fixes #447. + + commit 1314cc49a106fac2acba29e0e301343f857ba252 + Author: Casey Carter + Date: Wed May 10 13:24:59 2017 -0700 + + Change the return type of monotonic_buffer_resource's deleted assignment + + ... to monotonic_buffer_resource& for consistency with the default definition of the builtin assignment operator. This change has no normative effect, it only eliminates the inconsistency as a potential source of confusion. + + Since the return type of deleted functions is not observable, this change is editorial. + + commit c85f24dee9feb613c9454db572cd674234f3159f + Author: Thomas Köppe + Date: Sat Mar 25 16:20:40 2017 +0000 + + [string.cons] Consolidate two functions into one description + + commit f897604bd8cab510a843153db0133c3d5e13912f + Author: Jens Maurer + Date: Sat Jul 22 00:31:23 2017 +0200 + + [class.temporary] Remove note giving questionable implementation advice. + + And move the surviving part of the note to before the + corresponding example. + + Fixes #1674. + + commit 10e4c7437ba63c2975a160e84aecffdbfafd990b + Author: Hubert Tong + Date: Mon Jul 24 17:45:16 2017 -0400 + + [over.call.object] Reference postfix-expression in call syntax correctly + + The grammar production corresponding to the call syntax has + _postfix-expression_ as the callee operand. [over.call.object] appears + to refer to this operand as the _primary-expression_ in the syntax. + + commit ad966418d82b4e5480ad390a5f75ffbf37385f37 + Author: Richard Smith + Date: Fri Jul 28 17:16:07 2017 -0700 + + [temp] Add missing ';' to grammar for concept-definition. + + Despite being a normative change, this matches the overwhelmingly + obvious intent of the committee. + + Fixes #1686 + + commit afd6d4f065219067f372dafd1bb590a912775b41 + Author: Richard Smith + Date: Fri Jul 28 17:13:28 2017 -0700 + + [temp.constr.normal] Give a proper definition for "normalization". + + commit 38408888321282f9c0788ec9c40e2bd2f464617b + Author: Richard Smith + Date: Fri Jul 28 16:47:17 2017 -0700 + + [temp.constr.order] Fix spacing in example. + + commit aa4b1ae864fb85377570ba9775b5d34d79772922 + Author: Richard Smith + Date: Fri Jul 28 16:42:40 2017 -0700 + + [temp.constr.order] Clarify description of subsumption and ordering by constraints. + + commit 508cd59e6c9b23441ce5ed46e5012ccd1a8aed51 + Author: Richard Smith + Date: Fri Jul 28 11:24:51 2017 -0700 + + [dcl.fct.def] Reword = default ; and = delete ; introductory text for clarity. + + commit 182937c038dec15efaf5521d53d06960d6f1d661 + Author: Richard Smith + Date: Fri Jul 28 11:20:18 2017 -0700 + + [dcl.fct] Move use of "parameter-type-list" to after its definition. + + Split rules on function redeclarations out of rules for determining the + type of an individual function. + + commit ac6360546cb1eb982cf8d2123ceb2c99a0156b95 + Author: Richard Smith + Date: Wed Jul 26 14:22:49 2017 -0700 + + [expr.prim.req] Use grammar terms rather than undefined phrases when + referring to kinds of *requirement*. + + commit ff1242c4aa50958fa0380208eb0f2c45e3a8fea2 + Author: Thomas Köppe + Date: Tue Jul 25 13:49:18 2017 +0100 + + [meta.endian] Simplify wording, avoid "shall" + + commit 17820beb537c1576fe906228d741b64b9b2e8fc1 + Author: Richard Smith + Date: Mon Jul 24 11:22:34 2017 -0700 + + [temp] Fix example to use valid expression in requires-clause. + + commit 02574b8575c200095aa281d0886a73fe58c00580 + Author: Richard Smith + Date: Mon Jul 24 00:37:34 2017 -0700 + + [temp.inst] Tweak explanation in example. + + commit de236bab92922adc3c38f6fc0eb1fb4ec2a17c16 + Author: Richard Smith + Date: Mon Jul 24 00:36:24 2017 -0700 + + [temp.inst] Fix typo 'the the'. + + commit a76a3886035f484866add3a12af43c3b21143aa1 + Author: Richard Smith + Date: Mon Jul 24 00:34:07 2017 -0700 + + [temp.concept] Remove redundancy: the global scope is a namespace scope. + + commit 9a94a384336cb37974b3a8803dcf2424812ec854 + Author: Richard Smith + Date: Mon Jul 24 00:27:55 2017 -0700 + + [temp.class.spec] Fix typo "the primary" -> "the primary template". + + commit 7240fc98453bad27eb6112ae98b0f8e8fad8e39a + Author: Richard Smith + Date: Mon Jul 24 00:25:43 2017 -0700 + + [temp.mem.func] Add introductory text to new example to separate it from the prior example. + + commit 99013e76613ec877b912b18b3ffeb9d2b1cf8f1c + Author: Richard Smith + Date: Mon Jul 24 00:20:39 2017 -0700 + + [expr.prim.req.compound] Switch to passive voice. + + commit 1f1b944f2d849974ae01a5f2c45883d8213c3653 + Author: Richard Smith + Date: Mon Jul 24 00:04:15 2017 -0700 + + [temp.param] Switch to passive voice. + + commit 6568af0b4270bfc1497882a108741fa01ebeaa70 + Author: Richard Smith + Date: Sun Jul 23 23:54:34 2017 -0700 + + [temp] Add note around example to explain what it's an example of, and + add missing paragraph numbers. + + commit d37aa67b1bf795d4d98e79a9cc7ca8278608dc4f + Author: Richard Smith + Date: Sun Jul 23 23:48:17 2017 -0700 + + [temp] Fix confusion between two different forms of template-declaration. + + When the template-head is followed by a concept-definition, it is not + technically followed by a declaration, so avoid claiming that it is. + + commit 4d88f30cdbb3d49019935f15340b88b79382c202 + Author: Richard Smith + Date: Sun Jul 23 23:38:15 2017 -0700 + + [over.over] Switch to passive voice. + + commit 78a8901592907f8904ec824b2966414900586869 + Author: Richard Smith + Date: Sun Jul 23 23:25:18 2017 -0700 + + [expr.prim.req.nested] Remove incorrect (out of date) note. + + commit ca3cb945e042dc5bf63edfeeaf6d2e42ce2a3669 + Author: Richard Smith + Date: Sun Jul 23 15:01:59 2017 -0700 + + [expr.prim.req] Remove redundant note that repeats what the prior example just said. + + commit 763a125ca686aae8aaed3fd8f779bf5ad7ca1a5c + Author: Richard Smith + Date: Sun Jul 23 14:58:25 2017 -0700 + + [expr.prim.req] Repair meaningless "A requirement is one that [..]" phrasing. + + commit fcbeb9e63ad175128a1d7a9f5dc70536f5e2be81 + Author: Richard Smith + Date: Sun Jul 23 14:44:30 2017 -0700 + + [temp.constr.atomic] Split long paragraph into three. + + commit 119b98d70d24612e425fb2ae1b6caffb93689b89 + Author: Jonathan Wakely + Date: Thu Jul 20 22:30:39 2017 +0100 + + [filebuf.virtuals] Refer to return values specified in Effects + + Fixes #1552 + + commit ecad20efeaf0c244ea6a64d79484a0145a51242b + Author: Richard Smith + Date: Thu Jul 20 09:03:27 2017 -0700 + + [expr.mptr.oper] Rephrase wording for symmetry with P0704R1. + + commit 32fffbe4796ab0852f7bdf66b6d48d2e2b5e61ea + Author: Eelis + Date: Tue Jul 18 21:02:33 2017 +0200 + + [iterator.synopsis, template.bitset] Add missing whitespace. (#1673) + + commit b7ac9558b63434daa2217b35512225bc3213ebb4 + Author: Richard Smith + Date: Sat Jul 15 15:04:54 2017 -0700 + + [expr.const] Fix example of integral constant expression conversion to + involve integral constant expressions. + + Fixes #1627. + + commit cd2cc5c4709f4b8295d71d9fed92f3f2b2393f77 + Author: Richard Smith + Date: Sat Jul 15 14:49:27 2017 -0700 + + [alg.equal] Fix misapplication of P0467R2: change "no" to "an" in bullet + 3.2. + + Fixes #1578. + + commit b226afc6dcddc427668a47710d13064de23b0167 + Author: Richard Smith + Date: Sat Jul 15 14:39:03 2017 -0700 + + [stringbuf.virtuals] Note in Returns: element that the return value for + non-error cases is specified in the Effects: element. + + Fixes #1552 + + commit b63b10a9aeb8a7ef0b3f2cbbb9a20be88f0b56b7 + Author: Jens Maurer + Date: Sat Jul 15 23:21:32 2017 +0200 + + [variant.visit], [tuple.apply], [futures.task.members] add cross-references for INVOKE to [func.require] + + Fixes #1480. + + commit 8d45c56ea7224266462c6c807987676bcf35e93e + Author: Richard Smith + Date: Sat Jul 15 14:13:14 2017 -0700 + + Add missing index entries for 'alignas', alignof', 'noexcept'. + + commit 6114f86c1479a9ebf3b27fae694e9157a1a12423 + Author: Thomas Köppe + Date: Sat Jul 15 15:51:17 2017 -0400 + + Move reference to LIA-1 into a new section 'Bibliography' + + commit 488ef200887417bfa6124896549c09447a8c2fa9 + Author: JF Bastien + Date: Mon Jul 10 22:39:29 2017 -0400 + + Clarify a note on cmpxchg + + The "thus" part absolutely does not follow from the preceding note text, and isn't even correct on its own. Since this is a note I assume this is an editorial change and doesn't need an issue. + + commit f268d45e51ddadcb21036185900a602c9a502413 + Author: Jonathan Wakely + Date: Mon Jul 10 17:43:08 2017 +0100 + + [filesystem_error.members] Rename to [fs.filesystem_error.members] + + Fixes #1633 + + commit 331b6a67d4fa55d1f8d4c9eb300c4aa7ce63d27e + Author: Jonathan Wakely + Date: Mon Jul 10 17:41:18 2017 +0100 + + [stringbuf.virtuals] balance parentheses in seekoff table + + commit 48c0e75206dc98cfcb5ea88ebe29fa8858f6448a + Author: Jonathan Wakely + Date: Wed Jun 28 11:42:56 2017 +0100 + + [memory.syn] Add reinterpret_pointer_cast to synopsis + + commit 921ef046dc2daab44f6c7638aef3a03f85a06909 + Author: Jens Maurer + Date: Fri Apr 7 21:14:43 2017 +0200 + + Replace 'encouraged' with 'should'. + + Consistent with ISO Directives, Part 2, encouragement for + implementations is supposed to use 'should', not 'encouraged'. + + Fixes #1601. + + commit 89fccb39352b0c30b07272e38487dbf9fb67ed76 + Author: Eelis van der Weegen + Date: Sat Apr 8 12:45:21 2017 +0200 + + [temp.deduct.type] Use \cv instead of \grammarterm{cv-list}. + + commit 0740877e0dd13b15c411f4b8f1fc489ecffec52f + Author: Jens Maurer + Date: Wed Apr 5 23:10:33 2017 +0200 + + [string.streams], [file.streams] Use simple-template-id when naming base classes. + + Fixes #1551. + + commit 0207b6c6c40a884292a2a7ff1ea8c8a7d08b9d9f + Author: Jens Maurer + Date: Wed Apr 5 21:14:24 2017 +0200 + + Spell 'well-defined' with a hyphen when it is an adjective. + + Fixes #1587. + + commit 2044cbd25d588150bb0a19cc8df2992a88a29e1e + Author: Richard Smith + Date: Sat Jul 15 11:41:57 2017 -0700 + + [basic.def.odr] Replace mid-sentence period with "; and" + + commit 95ac3d662c788cdabc382509be4c273e5c80b334 + Author: lewissbaker + Date: Thu Jul 6 21:42:46 2017 +0930 + + [stmt.if] Fix spelling mistake in 'if constexpr' wording. (#1653) + + commit 48da313836eb57fd8282649c6c17b50a9cb97c3a + Author: Richard Smith + Date: Tue Jun 20 14:59:57 2017 -0700 + + [lex.string] Remove mention of trigraphs from raw string literal example. + + Fixes #1635. + + commit 1268aa09067159b94a6f83267d0a539b81dbbdc6 + Author: Richard Smith + Date: Tue Jun 20 14:45:07 2017 -0700 + + [meta.unary.prop] Fix typo 'remove_all_extents' which should say + 'remove_all_extents_t', introduced editorially in commit 79974877. + + Fixes #1644. + + commit c92319d1caf3462e1a3a745ea3947d56c974383a + Author: Evan Wallace + Date: Mon Jun 19 01:56:28 2017 +1000 + + [basic.stc.dynamic.safety] Update cross-reference to effects of using invalid pointer values. (#1636) + + Updated the Note describing "invalid pointer values" to refer to [basic.stc] rather than [basic.stc.dynamic.deallocation]. + + The relevant description of "invalid pointer values" reads: + "Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior." + + Previously the reference was correct, as this text was in [basic.stc.dynamic.deallocation]/4, but the text was moved to [basic.stc]/4 by P0137R1; without updating the reference. + + The Note also incorrectly claims that using an invalid pointer value is always undefined, when it can be implementation defined in certain cases, but I did not fix this in this commit; as updating the reference makes this nuance sufficiently clear. + + This is an editorial issue as it only changes non-normative text. + + commit 5eeec28487dd99e9e2441fc3e64e33b7a957a8fe + Author: Eelis + Date: Sat Jun 17 15:45:17 2017 +0200 + + For 'signal-safe', refer to [support.signal], not [csignal.syn]. (#1640) + + commit 8c005473ba69d52314d5c399c9c9adb6429cc7ed + Author: Zhihao Yuan + Date: Thu May 18 11:36:43 2017 -0500 + + [any.nonmembers] fix LWG2769 resolution + + Restores the changes made by #1220 + + commit e8c2b45b618ef13843dd9fbc3e26f1520c8522a8 + Author: Jonathan Wakely + Date: Wed May 17 23:06:18 2017 +0100 + + [fs.dir.entry.obs] Fix position of error_code arguments + + Fixes #1630 + + commit ae6271c88727c3fabe7dd8258f8687b369d83d6d + Author: Jonathan Wakely + Date: Thu Apr 20 23:06:37 2017 +0100 + + [fs.filesystem.syn] Update synopsis for filesystem::absolute + + commit c42d836d952219eba62edf1ef47ad763b5e57a54 + Author: Eelis + Date: Tue Apr 18 11:59:59 2017 +0200 + + [streambuf.virt.put] Fix logic error in the specification of the overflow() effects, introduced by 0b640ed8161937d31f31e251c297b658c559a978. (#1613) + + commit d5c0fd378f01b1aa9710ac8f2b61a6bc79b27aa5 + Author: Eelis + Date: Tue Apr 18 11:57:08 2017 +0200 + + [class.protected] Add missing full stop at end of sentence. (#1614) + + commit 70a0afc6dfbd5699ab562ebb93b269abde2834ba + Author: Daniel Grunwald + Date: Wed Apr 12 19:19:45 2017 +0200 + + [fs.class.path] Add missing semicolon + + commit 6debd6037c34befdb156e805912917d154ea658f + Author: Daniel Grunwald + Date: Thu Apr 6 20:47:58 2017 +0200 + + [iomanip.syn] Fix std::setfill() template declaration + + commit c17b1771be3f51dcea4d7670392ba9052a33c0b1 + Author: Daniel Grunwald + Date: Thu Apr 6 20:37:21 2017 +0200 + + [cmath.syn] Fix hypot(long double,long double) overload + + commit 578c39a0d74543a49da66483059debd7fb1316bc + Author: Daniel Grunwald + Date: Thu Apr 6 20:19:21 2017 +0200 + + [cstring.syn], [cwchar.syn] Add a bunch of missing semicolons + + commit 07e4d9ceea888564765a2821a0a7d883dd315acb + Author: Richard Smith + Date: Tue Apr 11 14:19:51 2017 -0700 + + [except.spec] Add missing '~' in comment in example. + + Thanks to Sergey P. Derevyago for reporting this! + + commit 98b39118c529e4ed72d707ba325412a61d734f16 + Author: Jens Maurer + Date: Tue Mar 28 21:55:42 2017 +0200 + + [filesystems] Change '!predicate' phrasing to 'predicate is false'. + + Fixes #1535. + + commit dff391e0df8e4c8f4bb0eb74ecc6bf2578c18fd0 + Author: Jens Maurer + Date: Fri Mar 31 21:58:25 2017 +0200 + + [lib] Use nullptr, not 0, for null pointer values. (#1586) + + Fixes #208. + + commit e030dc8c97ac3da75817ac4867e7c403e55de252 + Author: Jens Maurer + Date: Tue Mar 28 21:38:48 2017 +0200 + + [any.cons] Use 'contained value', not 'contained object'. (#1582) + + Fixes #1580. + + commit 389cc2d957a5e9f133c631fa1c23e14bc3dc97fe + Author: Jonathan Wakely + Date: Tue Mar 28 16:20:44 2017 +0100 + + [any.bad_any_cast] fix incorrect references to bad_any_access + + commit a0f6514c5e51714da31a6d0a7aa9a218908a3c86 + Author: Thomas Köppe + Date: Sun Mar 26 18:07:52 2017 +0100 + + [locale.money.get.members] Fix missing parameter type + + commit 5f7e2c6f5711ba3818519ec3b3f2c84d23a8fe93 + Author: Thomas Köppe + Date: Sun Mar 26 17:41:45 2017 +0100 + + [facet.ctype.char.virtuals] Add missing \pnum + + commit b12acc0d4aa1095ed0306e31155c1662205c2437 + Author: Thomas Köppe + Date: Sun Mar 26 16:44:14 2017 +0100 + + [category.ctype] Replace unnecessary placeholder type by the usual 'see below' + + commit fc9599aea58a7ea7e671f9b304cc1fe3f89c2a8b + Author: S. B. Tam + Date: Sat Mar 25 20:37:39 2017 +0800 + + [utility] Change 'nonzero' to more appropriate words. (#1575) + + commit 5d438d2569decb770062966bb347cc4b1eb075b0 + Author: Jens Maurer + Date: Thu Mar 23 22:14:14 2017 +0100 + + [mem.poly.allocator.mem], [string.view.iterators] Replace 'method' with 'member function'. + + Fixes #1573. + + commit 6d5ac829064fb264cac2805b0e8fdf193b32b62c + Author: Jens Maurer + Date: Wed Mar 22 00:25:58 2017 +0100 + + [intro.memory] Replace undefined 'field' with 'member' in note. + + Fixes #1569. + + commit f04c1dcee22cc5f1dd6d99448f8de4da8ba31ed3 + Author: Thomas Köppe + Date: Fri Mar 24 23:54:54 2017 +0000 + + [except.handle, except.spec, fs.op.temp_dir_path] Fix typos + diff --git a/papers/n4700.pdf b/papers/n4700.pdf new file mode 100644 index 0000000000..9062905f62 Binary files /dev/null and b/papers/n4700.pdf differ diff --git a/papers/n4701.html b/papers/n4701.html new file mode 100644 index 0000000000..543315a383 --- /dev/null +++ b/papers/n4701.html @@ -0,0 +1,552 @@ +N4701 +

N4701 Editors' Report -- Programming Languages -- C++

+ +

2017-10-16
+Richard Smith (editor) (Google Inc)
+Dawn Perchik (co-editor) (Embarcadero Technologies Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to +Jens Maurer, +Jonathan Wakely, +and Eelis van der Weegen +for performing many of the editorial fixes since N4687.

+ +

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

+ +

New papers

+ +
    +
  • N4700 is the current working draft for C++20. It replaces N4659.
  • +
  • N4701 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

This revision contains only editorial changes relative to N4687.

+ +

Notable editorial changes

+ +

Changes in the style of specification

+ +
    +
  • Entries in Terms and Definitions have been reworded to serve as a replacement +for the term they define.
  • +
  • Care has been taken to replace any use of "must" with "shall" when it states +a requirement rather than a logical necessity.
  • +
  • The standard now generally refers to itself as "this document", and only in +rare cases as "this International Standard".
  • +
+ +

Drafting for future standard changes should take the above into account.

+ +

Lists of figures and tables

+ +

At the request of ISO, the lists of figures and tables have been removed from +the document.

+ +

Pagination

+ +

At the request of ISO, the paper size used for the working draft has been +switched to A4.

+ +

Courtesy of Jens Maurer, we now automatically attempt to avoid page breaks +in undesirable places: immediately after section headings, and between the +declaration and description of standard library elements. We also provide +page break hints at the end of declarations and on blank lines in code blocks. +Many thanks to Jens; this will substantially reduce the effort required to +finalize the C++20 IS. Please file an file an editorial +issues +if you find any bad page breaks in the working draft.

+ +

Filesystem Terms and Definitions

+ +

Per the ISO Directives, the filesystem wording is not entitled to its own +Terms and Definitions section. The corresponding terms have been converted +to use our normal style of an italicized definition, the definitions have +been incorporated into the relevant portion of the running text, and the +[fs.definitions] subclause has been removed.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4687 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 e3a5f29e3dbd60089a6371e5f16d5d507c429ea3
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Oct 16 16:19:56 2017 -0700
+
+    [util.smartptr.shared.cmp] Fix overfull hbox.
+    [unique.ptr.special] Adjust to match changes to [util.smartptr.shared.cmp]
+    [tuple.cnstr] Adjust wording to avoid awkward linebreak within code
+    fragment.
+
+commit d1ba29b57990161cbbcdbb3faf60aa9b67cc3274
+Author: Akira Takahashi <faithandbrave@gmail.com>
+Date:   Tue Oct 17 01:29:14 2017 +0900
+
+    [util.smartptr.shared.cmp] Add "typename" for dependent name (#1770)
+
+commit dbb1ea97f1cb57cab275ba4eec9def4b3daab97e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 16 16:20:06 2017 +0200
+
+    [unord.map.overview], [unord.multimap.overview] Use iter_val_t instead of iter_value_t (#1772)
+
+commit b07fd6c53e0d5841b513192ebe08c047f3d05df4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Apr 20 21:41:52 2017 +0200
+
+    Use 'well-formed' (with hyphen) consistently.
+
+    Fixes #1618.
+
+commit af40423574aa8e3a495b382840a258f94cb6349d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jul 10 18:23:47 2017 +0100
+
+    [stringbuf.virtuals] Rephrase DR 453 resolution for seekoff
+
+    This avoids the requirement to compare newoff to zero when the value of
+    newoff hasn't been determined.
+
+commit d6a3234838da05d460366c83d8ec524f42ea37a4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 6 22:29:52 2017 +0200
+
+    [thread.condition.condvarany] Remove note made incorrect by LWG 2135.
+
+    Fixes #1755.
+
+commit dead61f32a2ed040745b668640924520d7b64c71
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Oct 13 20:28:20 2017 +0100
+
+    [fs.filesystem.syn] fix ordering of exists and equivalent
+
+commit ac3ed314239fccf81cece3cf7aeabdced03e5032
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 13 23:30:00 2017 +0200
+
+    [class.virtual] Correct function names in example comments.
+
+    Fixes #1740.
+
+commit 0059794f5370697d647bf31cc434cf306ba08554
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Oct 10 12:23:17 2017 -0700
+
+    Front matter: remove "Contents" entry from itself. Remove list of tables
+    and list of figures. Reorder cross-reference bullets in "Terms and
+    definitions".
+
+    As requested by ISO Central Secretariat.
+
+commit 8b767974c25346ea4d8990ebe315ab8dfa45a3b9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 6 21:52:12 2017 +0200
+
+    [mem.res.private] Remove misleading 'typical' in note.
+
+    Fixes #1698.
+
+commit 4a5ff4e7f947da6130a25900443317c18e879acf
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Oct 3 13:41:04 2017 +0100
+
+    [time] Fix namespace for definitions in std::chrono
+
+    The previous commit ad767d39f1a0667470ded0e5eb3155fcdd55f465 accidentally added the wrong namespace "std" instead of "std::chrono".
+
+commit 72647e7b03472315794872a10dfe2f2b74a2fa74
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Oct 3 10:22:55 2017 +0100
+
+    [mem.res] Fix namespace for definitions in std::pmr
+
+    The previous commit ad767d39f1a0667470ded0e5eb3155fcdd55f465 accidentally added the wrong namespace "std" instead of "std::pmr".
+
+commit eb035cf60c50ef8ad7d74ffdd5c2140f4179769a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Oct 3 01:01:53 2017 +0100
+
+    [memory.syn, unique.ptr] Add explanatory comments to make_unique overloads similar to the ones for make_shared, and mild presentational cleanup
+
+commit ad767d39f1a0667470ded0e5eb3155fcdd55f465
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Oct 3 00:18:23 2017 +0100
+
+    [utilities] Add missing "namespace std" to some class definitions
+
+commit b888c3d0cbe078475562f2b4d5f45e1528e61c6e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Oct 3 00:08:23 2017 +0100
+
+    [containers] Remove repeated statement of relational operator declarations (#1759)
+
+commit 1c43bc8685335048cd30042a712c0b40ff7f890a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Oct 2 22:55:20 2017 +0100
+
+    [unique.ptr, util.smartptr.shared] Remove redundant repetitions of declarations that already appear in the synopsis (#1758)
+
+commit 6d9e8c6237230c1c09d7f265751caf8cd5a1e2dc
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Sep 25 15:58:53 2017 -0700
+
+    [dcl.type.simple] Improve naming of template specialization in example.
+
+commit 97f21603bd6a9a547b98394a85c1cc0f342f7273
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Sep 25 15:45:43 2017 -0700
+
+    Fix '// Error' in examples to use '// error' instead.
+
+commit fa958265bed2a99d6d9787705297dc34c749017a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Sep 25 23:45:52 2017 +0100
+
+    [thread.req.timing] Use mathematical symbols
+
+commit 10c90ef815f10a800a3119476dc637c288c7c312
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Sep 25 23:31:58 2017 +0100
+
+    [thread] Harmonize presentation of synopses and declarations
+
+commit 9680eb724be8802b9823b234f0f5cad88a2efde9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Sep 25 11:49:13 2017 -0700
+
+    [ios.members.static] Fix case of first letter in footnotes.
+
+commit 6a7b14ae0b0f74f3ee27f0ad1354920acc830558
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Sep 25 09:32:47 2017 -0700
+
+    [string.assign] Add missing "Returns:".
+
+commit 9177b4b733b7fe8d121647d5638040c1d059370e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Sep 18 13:44:55 2017 +0100
+
+    [allocator.requirements] Fix footnote within Table 31 and table placement
+
+commit b6268620ee5cf87e4416f58e8f37995618b6495c
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Aug 15 13:34:46 2017 +0100
+
+    [futures.async] remove parens from DECAY_COPY()
+
+commit 64c8b273fb401b845a851fc0361766943959d6d7
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Sat Aug 12 01:03:02 2017 -0400
+
+    [diff.cpp14.library] Add Annex C entry for new headers in C++17
+
+    Fixes #1700.
+
+commit 1a9b8ebecd1c4e2da29329be5d7bda696c8cfbed
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Sep 12 11:53:46 2017 -0700
+
+    Convert "must"s in normative wording that do not indicate logical
+    necessity to a different form.
+
+    Normative requirements use "shall". Advice to users uses "should".
+    Description of the behavior of the implementation that does not of
+    itself constitute a requirement uses the imperative mood.
+
+    Fixes ISO 21 (C++17 DIS)
+
+commit 6218c216178655ece30733a0ec8043af9a65bf2e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Sep 14 14:45:56 2017 -0700
+
+    Replace "this International Standard" with "this document" when
+    referring to the document as a body of text.
+
+    Cases where that phrasing is used to compare this standard to other
+    revisions of the C++ standard retain this phrasing for clarity.
+
+    Fixes ISO 20 (C++17 DIS)
+
+commit 132326619d234a2b62819fd3a2cba6d9c654be23
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Sep 14 14:00:40 2017 -0700
+
+    [support.start.term] Remove note that is not justified by normative
+    wording.
+
+    Fixes NB JP 7 (C++17 DIS)
+
+commit 577968dc4de4674333510aea1d0e7da38c9e3bb6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Sep 11 16:51:59 2017 -0700
+
+    [temp.over.link] Change leading letter in comments in example to lowercase.
+
+    Fixes NB JP 6 (C++17 DIS)
+
+commit 081894151eb9b8f628168af9fffc38b0cbd0f6cf
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Sep 11 16:45:15 2017 -0700
+
+    [over.match.funcs] Remove the number of overload resolution contexts
+    from the introductory text.
+
+    It has become out of date relative to the actual number, and listing a
+    number here is not useful.
+
+    Fixes NB JP 5 (C++17 DIS)
+
+commit 6b0c8352738bce937d5aa633aacb4cd3c3285acc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Sep 7 21:58:28 2017 +0100
+
+    [intro.defs, definitions, fs.definitions] change notes in Terms and Definitions to say "Note X to entry"
+
+    Fixes ISO 3 (C++17 DIS)
+
+commit fa49082e030985ebdf3ecc91ece5cbdf72421338
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Sep 11 16:30:12 2017 -0700
+
+    [fs] Integrate file system terms and definitions into the text at appropriate places.
+
+    Update xrefs to point to the relevant definitions.
+
+    Update index entries for constraint normalization to harmonize with
+    those for path normalization.
+
+commit 60453da3081d8fa5753f48d2c78e1e78b1a3b079
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Sep 11 11:40:41 2017 -0700
+
+    [fs.definitions] Replace "Terms and definitions" formatting with inline definitions.
+
+    These definitions do not satisfy ISO rules for a "Terms and definitions"
+    section, and in any case it does not make sense for FS to have its own
+    "Terms and definitions". Following our usual convention, we use inline
+    definitions for locally-scoped terms.
+
+commit 5619b65614eae10510f337a1eacd05fc4308fe5c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Sep 7 14:40:23 2017 -0700
+
+    Update [intro.defs] and [definitions] to use (roughly) substitutable
+    phrases as definitions.
+
+    In particular, such phrases should not begin with an article. However,
+    for definitions of adjectives, a noun phrase is still used, because the
+    English language is not compatible with ISO's requirements.
+
+commit a31fa795274e9fbb676b3ef2a8e60df12eb516b0
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Sep 11 16:36:49 2017 -0700
+
+    [intro.refs] Remove redundant reference to C11 Technical Corrigendum 1.
+
+    When making a normative reference to another document, all relevant
+    Technical Corrigenda are assumed and need not be listed explicitly.
+
+    Fixes ISO 1 (C++17 DIS)
+
+commit 1a4e554f910cdd1df3d2d8a62c2270dd1219eddc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Sep 7 20:02:06 2017 +0100
+
+    [any.cons] fix tag typename; "in_place<T>" should be "in_place_type<T>"
+
+    Fixes NB JP 10 (C++17 DIS)
+
+commit 788b07ba87458c35228ecbdccb2e9dfac37eebf8
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Sep 7 19:18:13 2017 +0100
+
+    [algorithms.parallel.user] remove stray full stop
+
+    Fixes NB JP 12 (C++17 DIS)
+
+commit d0b014a78818c0c1cc4c7b2e96f1264990d06478
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Sep 7 19:09:32 2017 +0100
+
+    [support.general, depr.cpp.headers] remove index entries for now-deprecated headers and symbols, and add missing index entries for deprecated headers.
+
+    Fixes NB JP 23 (C++17 DIS)
+
+commit d9075c89a2539d5b3038c1a15b02673fe18589c3
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Sep 7 11:55:36 2017 +0100
+
+    [alg.reverse] remove duplicated Requires: element
+
+    Fixes NB JP 14 (C++17 DIS)
+
+commit 27331fd3a2c8b3b78223712d56bbd51be1c9159b
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sat Aug 12 18:14:44 2017 +0200
+
+    Consistently place footnote mark after sentence full stop, not before it.
+
+commit be5c14cf44a6e6ea7348e65dbf99e3a8152c28ac
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Aug 9 15:59:11 2017 -0700
+
+    [expr.prim.req.compound] Adjust description in example to be easier to understand.
+
+commit c57ffb959dc939979111a4d1bcc31b71da643511
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 4 18:33:41 2017 +0100
+
+    [temp.deduct] Split long paragraph 8
+
+commit e3b4927ea0f4e8c8bf1f7461226c729b4e2c00be
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Aug 1 22:06:30 2017 +0100
+
+    [memory.syn, util.smartptr.shared] Add missing {make,allocate}_shared declarations to synopsis
+
+    We list those functions in two places: the main synopsis in [memory.syn], and also a smaller subset in [util.smartptr.shared] just for shared_ptr.
+
+    Also contains some minor presentational improvements for both instances.
+
+    Fixes #1697.
+
+commit 355a20beb12ba9c26cb09d41159f7f68238dab7d
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Tue Aug 1 04:14:14 2017 -0400
+
+    [defns.well.formed] remove full stop
+
diff --git a/papers/n4701.md b/papers/n4701.md new file mode 100644 index 0000000000..327bf41ef6 --- /dev/null +++ b/papers/n4701.md @@ -0,0 +1,424 @@ +# N4701 Editors' Report -- Programming Languages -- C++ + +2017-10-16 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Embarcadero Technologies Inc) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Special thanks to +Jens Maurer, +Jonathan Wakely, +and Eelis van der Weegen +for performing many of the editorial fixes since N4687. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4700](http://wg21.link/n4700) is the current working draft for C++20. It replaces [N4659](http://wg21.link/n4687). + * N4701 is this Editors' Report. + +## Motions incorporated into working draft + +This revision contains only editorial changes relative to N4687. + +## Notable editorial changes + +### Changes in the style of specification + +* Entries in Terms and Definitions have been reworded to serve as a replacement + for the term they define. +* Care has been taken to replace any use of "must" with "shall" when it states + a requirement rather than a logical necessity. +* The standard now generally refers to itself as "this document", and only in + rare cases as "this International Standard". + +Drafting for future standard changes should take the above into account. + +### Lists of figures and tables + +At the request of ISO, the lists of figures and tables have been removed from +the document. + +### Pagination + +At the request of ISO, the paper size used for the working draft has been +switched to A4. + +Courtesy of Jens Maurer, we now automatically attempt to avoid page breaks +in undesirable places: immediately after section headings, and between the +declaration and description of standard library elements. We also provide +page break hints at the end of declarations and on blank lines in code blocks. +Many thanks to Jens; this will substantially reduce the effort required to +finalize the C++20 IS. Please file an [file an editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +if you find any bad page breaks in the working draft. + +### Filesystem Terms and Definitions + +Per the ISO Directives, the filesystem wording is not entitled to its own +Terms and Definitions section. The corresponding terms have been converted +to use our normal style of an italicized definition, the definitions have +been incorporated into the relevant portion of the running text, and the +[fs.definitions] subclause has been removed. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4687 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/n4687...n4700). + + commit e3a5f29e3dbd60089a6371e5f16d5d507c429ea3 + Author: Richard Smith + Date: Mon Oct 16 16:19:56 2017 -0700 + + [util.smartptr.shared.cmp] Fix overfull hbox. + [unique.ptr.special] Adjust to match changes to [util.smartptr.shared.cmp] + [tuple.cnstr] Adjust wording to avoid awkward linebreak within code + fragment. + + commit d1ba29b57990161cbbcdbb3faf60aa9b67cc3274 + Author: Akira Takahashi + Date: Tue Oct 17 01:29:14 2017 +0900 + + [util.smartptr.shared.cmp] Add "typename" for dependent name (#1770) + + commit dbb1ea97f1cb57cab275ba4eec9def4b3daab97e + Author: Jens Maurer + Date: Mon Oct 16 16:20:06 2017 +0200 + + [unord.map.overview], [unord.multimap.overview] Use iter_val_t instead of iter_value_t (#1772) + + commit b07fd6c53e0d5841b513192ebe08c047f3d05df4 + Author: Jens Maurer + Date: Thu Apr 20 21:41:52 2017 +0200 + + Use 'well-formed' (with hyphen) consistently. + + Fixes #1618. + + commit af40423574aa8e3a495b382840a258f94cb6349d + Author: Jonathan Wakely + Date: Mon Jul 10 18:23:47 2017 +0100 + + [stringbuf.virtuals] Rephrase DR 453 resolution for seekoff + + This avoids the requirement to compare newoff to zero when the value of + newoff hasn't been determined. + + commit d6a3234838da05d460366c83d8ec524f42ea37a4 + Author: Jens Maurer + Date: Fri Oct 6 22:29:52 2017 +0200 + + [thread.condition.condvarany] Remove note made incorrect by LWG 2135. + + Fixes #1755. + + commit dead61f32a2ed040745b668640924520d7b64c71 + Author: Jonathan Wakely + Date: Fri Oct 13 20:28:20 2017 +0100 + + [fs.filesystem.syn] fix ordering of exists and equivalent + + commit ac3ed314239fccf81cece3cf7aeabdced03e5032 + Author: Jens Maurer + Date: Fri Oct 13 23:30:00 2017 +0200 + + [class.virtual] Correct function names in example comments. + + Fixes #1740. + + commit 0059794f5370697d647bf31cc434cf306ba08554 + Author: Richard Smith + Date: Tue Oct 10 12:23:17 2017 -0700 + + Front matter: remove "Contents" entry from itself. Remove list of tables + and list of figures. Reorder cross-reference bullets in "Terms and + definitions". + + As requested by ISO Central Secretariat. + + commit 8b767974c25346ea4d8990ebe315ab8dfa45a3b9 + Author: Jens Maurer + Date: Fri Oct 6 21:52:12 2017 +0200 + + [mem.res.private] Remove misleading 'typical' in note. + + Fixes #1698. + + commit 4a5ff4e7f947da6130a25900443317c18e879acf + Author: Thomas Köppe + Date: Tue Oct 3 13:41:04 2017 +0100 + + [time] Fix namespace for definitions in std::chrono + + The previous commit ad767d39f1a0667470ded0e5eb3155fcdd55f465 accidentally added the wrong namespace "std" instead of "std::chrono". + + commit 72647e7b03472315794872a10dfe2f2b74a2fa74 + Author: Thomas Köppe + Date: Tue Oct 3 10:22:55 2017 +0100 + + [mem.res] Fix namespace for definitions in std::pmr + + The previous commit ad767d39f1a0667470ded0e5eb3155fcdd55f465 accidentally added the wrong namespace "std" instead of "std::pmr". + + commit eb035cf60c50ef8ad7d74ffdd5c2140f4179769a + Author: Thomas Köppe + Date: Tue Oct 3 01:01:53 2017 +0100 + + [memory.syn, unique.ptr] Add explanatory comments to make_unique overloads similar to the ones for make_shared, and mild presentational cleanup + + commit ad767d39f1a0667470ded0e5eb3155fcdd55f465 + Author: Thomas Köppe + Date: Tue Oct 3 00:18:23 2017 +0100 + + [utilities] Add missing "namespace std" to some class definitions + + commit b888c3d0cbe078475562f2b4d5f45e1528e61c6e + Author: Thomas Köppe + Date: Tue Oct 3 00:08:23 2017 +0100 + + [containers] Remove repeated statement of relational operator declarations (#1759) + + commit 1c43bc8685335048cd30042a712c0b40ff7f890a + Author: Thomas Köppe + Date: Mon Oct 2 22:55:20 2017 +0100 + + [unique.ptr, util.smartptr.shared] Remove redundant repetitions of declarations that already appear in the synopsis (#1758) + + commit 6d9e8c6237230c1c09d7f265751caf8cd5a1e2dc + Author: Richard Smith + Date: Mon Sep 25 15:58:53 2017 -0700 + + [dcl.type.simple] Improve naming of template specialization in example. + + commit 97f21603bd6a9a547b98394a85c1cc0f342f7273 + Author: Richard Smith + Date: Mon Sep 25 15:45:43 2017 -0700 + + Fix '// Error' in examples to use '// error' instead. + + commit fa958265bed2a99d6d9787705297dc34c749017a + Author: Thomas Köppe + Date: Mon Sep 25 23:45:52 2017 +0100 + + [thread.req.timing] Use mathematical symbols + + commit 10c90ef815f10a800a3119476dc637c288c7c312 + Author: Thomas Köppe + Date: Mon Sep 25 23:31:58 2017 +0100 + + [thread] Harmonize presentation of synopses and declarations + + commit 9680eb724be8802b9823b234f0f5cad88a2efde9 + Author: Richard Smith + Date: Mon Sep 25 11:49:13 2017 -0700 + + [ios.members.static] Fix case of first letter in footnotes. + + commit 6a7b14ae0b0f74f3ee27f0ad1354920acc830558 + Author: Richard Smith + Date: Mon Sep 25 09:32:47 2017 -0700 + + [string.assign] Add missing "Returns:". + + commit 9177b4b733b7fe8d121647d5638040c1d059370e + Author: Thomas Köppe + Date: Mon Sep 18 13:44:55 2017 +0100 + + [allocator.requirements] Fix footnote within Table 31 and table placement + + commit b6268620ee5cf87e4416f58e8f37995618b6495c + Author: Jonathan Wakely + Date: Tue Aug 15 13:34:46 2017 +0100 + + [futures.async] remove parens from DECAY_COPY() + + commit 64c8b273fb401b845a851fc0361766943959d6d7 + Author: timsong-cpp + Date: Sat Aug 12 01:03:02 2017 -0400 + + [diff.cpp14.library] Add Annex C entry for new headers in C++17 + + Fixes #1700. + + commit 1a9b8ebecd1c4e2da29329be5d7bda696c8cfbed + Author: Richard Smith + Date: Tue Sep 12 11:53:46 2017 -0700 + + Convert "must"s in normative wording that do not indicate logical + necessity to a different form. + + Normative requirements use "shall". Advice to users uses "should". + Description of the behavior of the implementation that does not of + itself constitute a requirement uses the imperative mood. + + Fixes ISO 21 (C++17 DIS) + + commit 6218c216178655ece30733a0ec8043af9a65bf2e + Author: Richard Smith + Date: Thu Sep 14 14:45:56 2017 -0700 + + Replace "this International Standard" with "this document" when + referring to the document as a body of text. + + Cases where that phrasing is used to compare this standard to other + revisions of the C++ standard retain this phrasing for clarity. + + Fixes ISO 20 (C++17 DIS) + + commit 132326619d234a2b62819fd3a2cba6d9c654be23 + Author: Richard Smith + Date: Thu Sep 14 14:00:40 2017 -0700 + + [support.start.term] Remove note that is not justified by normative + wording. + + Fixes NB JP 7 (C++17 DIS) + + commit 577968dc4de4674333510aea1d0e7da38c9e3bb6 + Author: Richard Smith + Date: Mon Sep 11 16:51:59 2017 -0700 + + [temp.over.link] Change leading letter in comments in example to lowercase. + + Fixes NB JP 6 (C++17 DIS) + + commit 081894151eb9b8f628168af9fffc38b0cbd0f6cf + Author: Richard Smith + Date: Mon Sep 11 16:45:15 2017 -0700 + + [over.match.funcs] Remove the number of overload resolution contexts + from the introductory text. + + It has become out of date relative to the actual number, and listing a + number here is not useful. + + Fixes NB JP 5 (C++17 DIS) + + commit 6b0c8352738bce937d5aa633aacb4cd3c3285acc + Author: Thomas Köppe + Date: Thu Sep 7 21:58:28 2017 +0100 + + [intro.defs, definitions, fs.definitions] change notes in Terms and Definitions to say "Note X to entry" + + Fixes ISO 3 (C++17 DIS) + + commit fa49082e030985ebdf3ecc91ece5cbdf72421338 + Author: Richard Smith + Date: Mon Sep 11 16:30:12 2017 -0700 + + [fs] Integrate file system terms and definitions into the text at appropriate places. + + Update xrefs to point to the relevant definitions. + + Update index entries for constraint normalization to harmonize with + those for path normalization. + + commit 60453da3081d8fa5753f48d2c78e1e78b1a3b079 + Author: Richard Smith + Date: Mon Sep 11 11:40:41 2017 -0700 + + [fs.definitions] Replace "Terms and definitions" formatting with inline definitions. + + These definitions do not satisfy ISO rules for a "Terms and definitions" + section, and in any case it does not make sense for FS to have its own + "Terms and definitions". Following our usual convention, we use inline + definitions for locally-scoped terms. + + commit 5619b65614eae10510f337a1eacd05fc4308fe5c + Author: Richard Smith + Date: Thu Sep 7 14:40:23 2017 -0700 + + Update [intro.defs] and [definitions] to use (roughly) substitutable + phrases as definitions. + + In particular, such phrases should not begin with an article. However, + for definitions of adjectives, a noun phrase is still used, because the + English language is not compatible with ISO's requirements. + + commit a31fa795274e9fbb676b3ef2a8e60df12eb516b0 + Author: Richard Smith + Date: Mon Sep 11 16:36:49 2017 -0700 + + [intro.refs] Remove redundant reference to C11 Technical Corrigendum 1. + + When making a normative reference to another document, all relevant + Technical Corrigenda are assumed and need not be listed explicitly. + + Fixes ISO 1 (C++17 DIS) + + commit 1a4e554f910cdd1df3d2d8a62c2270dd1219eddc + Author: Thomas Köppe + Date: Thu Sep 7 20:02:06 2017 +0100 + + [any.cons] fix tag typename; "in_place" should be "in_place_type" + + Fixes NB JP 10 (C++17 DIS) + + commit 788b07ba87458c35228ecbdccb2e9dfac37eebf8 + Author: Thomas Köppe + Date: Thu Sep 7 19:18:13 2017 +0100 + + [algorithms.parallel.user] remove stray full stop + + Fixes NB JP 12 (C++17 DIS) + + commit d0b014a78818c0c1cc4c7b2e96f1264990d06478 + Author: Thomas Köppe + Date: Thu Sep 7 19:09:32 2017 +0100 + + [support.general, depr.cpp.headers] remove index entries for now-deprecated headers and symbols, and add missing index entries for deprecated headers. + + Fixes NB JP 23 (C++17 DIS) + + commit d9075c89a2539d5b3038c1a15b02673fe18589c3 + Author: Jonathan Wakely + Date: Thu Sep 7 11:55:36 2017 +0100 + + [alg.reverse] remove duplicated Requires: element + + Fixes NB JP 14 (C++17 DIS) + + commit 27331fd3a2c8b3b78223712d56bbd51be1c9159b + Author: Eelis van der Weegen + Date: Sat Aug 12 18:14:44 2017 +0200 + + Consistently place footnote mark after sentence full stop, not before it. + + commit be5c14cf44a6e6ea7348e65dbf99e3a8152c28ac + Author: Richard Smith + Date: Wed Aug 9 15:59:11 2017 -0700 + + [expr.prim.req.compound] Adjust description in example to be easier to understand. + + commit c57ffb959dc939979111a4d1bcc31b71da643511 + Author: Thomas Köppe + Date: Fri Aug 4 18:33:41 2017 +0100 + + [temp.deduct] Split long paragraph 8 + + commit e3b4927ea0f4e8c8bf1f7461226c729b4e2c00be + Author: Thomas Köppe + Date: Tue Aug 1 22:06:30 2017 +0100 + + [memory.syn, util.smartptr.shared] Add missing {make,allocate}_shared declarations to synopsis + + We list those functions in two places: the main synopsis in [memory.syn], and also a smaller subset in [util.smartptr.shared] just for shared_ptr. + + Also contains some minor presentational improvements for both instances. + + Fixes #1697. + + commit 355a20beb12ba9c26cb09d41159f7f68238dab7d + Author: timsong-cpp + Date: Tue Aug 1 04:14:14 2017 -0400 + + [defns.well.formed] remove full stop diff --git a/papers/n4713.pdf b/papers/n4713.pdf new file mode 100644 index 0000000000..254570829e Binary files /dev/null and b/papers/n4713.pdf differ diff --git a/papers/n4714.html b/papers/n4714.html new file mode 100644 index 0000000000..c3a2d132d1 --- /dev/null +++ b/papers/n4714.html @@ -0,0 +1,732 @@ +N4714 +

N4714 Editors' Report -- Programming Languages -- C++

+ +

2017-11-27
+Richard Smith (editor) (Google Inc)
+Dawn Perchik (co-editor) (Embarcadero Technologies Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to +Jens Maurer +for performing many of the editorial fixes since N4700.

+ +

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

+ +

New papers

+ +
    +
  • N4713 is the current working draft for C++20. It replaces N4700.
  • +
  • N4714 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolution for 1 issue in "ready" status applied:

+ +
    +
  • 2342 Reference reinterpret_cast and pointer-interconvertibility
  • +
+ +

CWG motion 2: Core issue resolutions for 7 issues in "tentatively ready" status applied:

+ +
    +
  • 1862 Determining "corresponding members" for friendship
  • +
  • 2177 Placement operator delete and parameter copies
  • +
  • 2305 Explicit instantiation of constexpr or inline variable template
  • +
  • 2307 Unclear definition of "equivalent to a nontype template parameter"
  • +
  • 2313 Redeclaration of structured binding reference variables
  • +
  • 2315 What is the "corresponding special member" of a variant member?
  • +
  • 2338 Undefined behavior converting to short enums with fixed underlying types
  • +
+ +

CWG motion 3: P0614R1 "Range-based for statements with initializer"

+ +

CWG motion 4: P0588R1 "Simplifying implicit lambda capture"

+ +

CWG motion 5: P0846R0 "ADL and function templates that are not visible"

+ +

CWG motion 6: P0641R2 "Resolving core issue #1331", resolving 1 core issue:

+ +
    +
  • 1331 const mismatch with defaulted copy constructor
  • +
+ +

CWG motion 7: P0859R0 "Core issue 1581", resolving 1 core issue:

+ +
    +
  • 1581 When are constexpr member functions defined?
  • +
+ +

CWG motion 8: P0515R3 "Consistent comparison" and P0768R1 "Library support for the spaceship (comparison) operator"

+ +

CWG motion 9: P0857R0 "Functionality gaps in constraints"

+ +

CWG motion 10: P0692R1 "Access checking on specializations"

+ +

CWG motion 11: P0624R2 "Default constructible and assignable stateless lambdas"

+ +

CWG motion 12: P0767R1 "Deprecate POD"

+ +

CWG motion 13: P0315R4 "Lambdas in unevaluated contexts"

+ +

Library working group motions

+ +

LWG motion 1 and 2 apply to the Parallelism TS.

+ +

LWG motion 3 applies to the Networking TS.

+ +

LWG motion 4: Library issue resolutions for 24 issues in "Ready" or "Tentatively Ready" status applied:

+ +
    +
  • 2870 Default value of parameter theta of polar should be dependent
  • +
  • 2935 What should create_directories do when p already exists but is not a directory?
  • +
  • 2941 [thread.req.timing] wording should apply to both member and namespace-level functions
  • +
  • 2944 LWG 2905 accidentally removed requirement that construction of the deleter doesn't throw an exception
  • +
  • 2945 Order of template parameters in optional comparisons
  • +
  • 2948 unique_ptr does not define operator<< for stream output
  • +
  • 2950 std::byte operations are misspecified
  • +
  • 2952 iterator_traits should work for pointers to cv T
  • +
  • 2953 LWG 2853 should apply to deque::erase too
  • +
  • 2964 Apparently redundant requirement for dynamic_pointer_cast
  • +
  • 2965 Non-existing path::native_string() in filesystem_error::what() specification
  • +
  • 2972 What is is_trivially_destructible_v<int>?
  • +
  • 2976 Dangling uses_allocator specialization for packaged_task
  • +
  • 2977 unordered_meow::merge() has incorrect Throws: clause
  • +
  • 2978 Hash support for pmr::string and friends
  • +
  • 2979 aligned_union should require complete object types
  • +
  • 2980 Cannot compare_exchange empty pointers
  • +
  • 2981 Remove redundant deduction guides from standard library
  • +
  • 2982 Making size_type consistent in associative container deduction guides
  • +
  • 2988 Clause 32 cleanup missed one typename
  • +
  • 2993 reference_wrapper<T> conversion from T&&
  • +
  • 2998 Requirements on function objects passed to {forward_,}list-specific algorithms
  • +
  • 3001 weak_ptr::element_type needs remove_extent_t
  • +
  • 3024 variant's copies must be deleted instead of disabled via SFINAE
  • +
+ +

LWG motion 5: Library issue resolution for 1 issue in "Immediate" status applied:

+ +
    +
  • 2958 Moves improperly defined as deleted
  • +
+ +

LWG motion 6: P0550R2 "Transformation trait remove_cvref"

+ +

LWG motion 7: P0777R1 "Treating unnecessary decay"

+ +

LWG motion 8: P0600R1 "[[nodiscard]] in the Library"

+ +

Do not try and apply LWG motion 9 to the working draft. That's impossible. +Instead, only realize the truth. There is no LWG motion 9.

+ +

LWG motion 10: P0439R0 "Make std::memory_order a scoped enumeration"

+ +

LWG motion 11: P0053R7 "Synchronized buffered ostream"

+ +

LWG motion 12: P0653R2 "Utility to convert a pointer to a raw pointer"

+ +

LWG motion 13: P0202R3 "Add constexpr modifiers to functions in <algorithm> and <utility> Headers"

+ +

LWG motion 14: P0415R1 "constexpr for std::complex"

+ +

LWG motion 15: P0718R2 "Atomic shared_ptr"

+ +

LWG motion 16: P0020R6 "Floating point atomic"

+ +

LWG motion 17: P0616R0 "De-pessimize legacy <numeric> algorithms with std::move"

+ +

LWG motion 18: P0457R2 "String prefix and suffix checking"

+ +

Notable editorial changes

+ +

CWG motion 8

+ +

Instead of removing [operators] and adding a new section to [requirements], the +existing stable name for this section is preserved. This section was moved to +[description] rather than to [requirements], as it describes a notational +device used for standard exposition.

+ +

[alg.3way] added to [alg.sorting] rather than [alg.nonmodifying] to +match existing lexicographical_compare functions.

+ +

LWG motion 8

+ +

[[nodiscard]] was inadvertantly omitted from deque::empty() in the detailed +wording changes (but was covered by the general description of the change). +After consultation with LWG, this oversight has been corrected in the wording.

+ +

LWG motion 10

+ +

All references to the existing memory_order_* enumerators throughout the +working draft were updated to use the new scoped enumerator nmaes.

+ +

LWG motion 11

+ +

Changes were made to the organization and presentation of the wording +to fit better into the existing document.

+ +

LWG motion 12

+ +

The requested addition to [pointer.traits.function] has been moved into a new +subclause "Pointer traits optional members" and modified slightly to fit this +new presentation, as it does not describe a member of the pointer_traits +primary template.

+ +

Text reorganization

+ +

In an effort to conform to ISO drafting directives to avoid hanging paragraphs +(text in subclauses that also contain further nested subclauses) and to remove +excessive subclause structure, the following changes have been made:

+ +
    +
  • [intro] and [basic] have been reorganized so that [intro] acts as an +introduction to the standard document and [basic] introduces the basic +concepts of the standard in an order closer to dependency order
  • +
  • [conv.rank] moved from [conv] to [basic.types], as it does not describe a conversion.
  • +
  • [expr] has additional subclause structure to partially resolve hanging +paragraphs and generally improve its organization
  • +
  • [expr] has a new subclause describing properties of expressions, containing +some of the prior hanging paragraphs from [expr], as well as [basic.lval]
  • +
  • [array], [util.sharedptr] Per-function subclauses have been merged into parent subclause.
  • +
+ +

Changes in the style of specification

+ +
    +
  • Code font is no longer used when referring to non-syntax properties of entities +(even when those properties are derived from syntax). This applies to the terms +"inline", "friend", "public", "protected", "private", "const object". +We generally intend to use code font only when referring specifically +to program syntax.

  • +
  • In library wording, template headers are formatted consistently with no +space between the template keyword and the < token.

  • +
+ +

Drafting for future standard changes should take the above into account.

+ +

Index of library headers

+ +

In order to keep the "Index of library names" focused on listing library names, +index entries for library headers have been moved to a separate, new "Index of +library headers".

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4700 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 903df06f3e67c9a52539892cb6844b55392c5331
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 27 22:00:03 2017 +0000
+
+    [allocator.adaptor.syn] Delete duplicate declarations of relational operators
+
+commit cebfe0a09fb56ec33726559c8b6d006dc19e4ab7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 15 23:18:22 2017 +0100
+
+    [temp.constr.order] In definition of 'subsumes', remove
+    confusing introductory paragraph.
+
+commit 74df95e9e3fad1aa5844c281614bbfffb1cc6189
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 22 23:45:18 2017 +0100
+
+    [diff] Introduce numbered paragraphs
+
+commit e543af304e195ad301da272caa7ef12107077ac0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 25 00:01:36 2017 +0100
+
+    [lib] Harmonize spacing for template headers.
+
+    Use 'template<class T>'.
+    Also remove space between two closing template brackets.
+
+commit b73e56f7a2b92449d9ec4938b01fa7014edad33a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 15 23:26:11 2017 +0100
+
+    [basic.link] Entities declared in an unnamed namespace
+    never have external linkage.
+
+commit fc16d3133817701a780092cf6456722a40e27d28
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 19 23:11:51 2017 +0100
+
+    [temp.arg.explicit] Remove note obsoleted by P0846R0
+
+commit d29bd8c6591fe74b095e5bd277f986462ba40b24
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 26 18:36:42 2017 +0100
+
+    [fs.op.funcs] Separate effects from returns. (#1848)
+
+commit e2457df32a6ee70417681de10be78eb815a0b22f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 20 10:23:18 2017 +0100
+
+    [complex.numbers] Use \xref for references to the C standard.
+
+commit bd2ce5c2d4ec26a5c412160ce5983149c510a131
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 21 23:35:02 2017 +0100
+
+    Create a new index for library headers
+
+    and remove them from the index of library names.
+
+commit d1125303456c2305a72baebbb51d80151722f8ab
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Nov 23 14:33:32 2017 +0000
+
+    [basic.life],[mem.res.private],[mem.res.pool.mem],[mem.res.monotonic.buffer] fix cross-references
+
+commit 1d467a8a06cabd314e250a04ca9a4c81591d035a
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Thu Nov 23 15:31:45 2017 -0400
+
+    [func.require] Clarify which assignment operators
+
+commit 9dbbf9cbbe6994f7d4ad19098029e995eb34e1c3
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Nov 25 19:04:08 2017 -0400
+
+    [unord.req, fs.path.io] Fix "Effects: Equivalent to" styles (#1806)
+
+commit efdda2b9ca7f0ed78d7f134d8b1ca2e405610190
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 25 22:57:08 2017 +0100
+
+    [lib] Harmonize punctuation of 'Effects: Equivalent to' (#1815)
+
+commit 63ccd0513f6d9ac3555ca8becfcd7d15ed503522
+Author: stbergmann <sbergman@redhat.com>
+Date:   Sat Nov 25 03:33:31 2017 +0100
+
+    [basic.types] Add missing "be" in note (#1839)
+
+commit 9a8f4fde487200bcf4433facb0274f67d540617c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 25 03:29:09 2017 +0100
+
+    [lex.ccon] Align char16_t phrasing to UTF-8 one (#1847)
+
+commit 784f8c9980a74393ceaf201b343aa232a82113a4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 24 01:03:52 2017 +0000
+
+    [complex{,.special,.members}] Use injected-class-name in class definitions and itemdecls
+
+commit 877918fdc3e5223006b782d3c5959470bd7c02a8
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Fri Nov 24 00:57:49 2017 +0000
+
+    [allocator.requirements] Fix pointer_to expression and reinstate descriptive variable 'r' (#1656)
+
+commit 2ca4340d93ec4cd63c330303e5beef20db8604df
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Thu Nov 23 22:48:22 2017 +0000
+
+    [vector.bool] Use injected-class-name in synopsis (#1844)
+
+commit 4eedcb0d29f7c3b143dc3492caecb9c608590e12
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Nov 22 19:26:28 2017 -0800
+
+    [diff.cpp17.library] Add Annex C entry for new headers <compare> and
+    <syncstream> added since C++17.
+
+commit 9112c6aecc48e1a0deea1f9493de224a43689a87
+Author: Aaron Ballman <aballman@grammatech.com>
+Date:   Mon Mar 13 09:51:35 2017 -0400
+
+    Use the terms "single-object delete expression" and
+    "array delete expression" as definitions, removing
+    the italics when not appropriate.
+
+commit b3b8a19812829ab521958eed6b2f1a3411180cdb
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 19 22:17:17 2017 +0000
+
+    [structure.summary] Remove obsolete paragraph about Note(s): and Example(s): elements that we no longer provide
+
+    Also restyle a manual Note: in [unord.req] to use the standard note environment.
+
+commit 8958e953fd2cd60bd02ed4fcd2c055eded6e0f4d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 21 23:28:52 2017 +0000
+
+    [unord.req] Spell out the behaviour of cbegin/cend, remove ambiguous note
+
+commit b64354a7503c1cdc358d7f5dd1405ed903e170ef
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 22 12:10:00 2017 +0000
+
+    [depr.meta.types] Merge POD deprecation into existing type traits deprecation section and reorganize the section a bit
+
+commit 374252a76008ac0316320d2dd4e8652910539a97
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 22 01:01:39 2017 +0100
+
+    [util.sharedptr] Dissolve subclause and integrate contents into parent. (#1814)
+
+commit 75c0adccb38301f66979cc3c3ab5cd15a0a75a17
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 21 23:29:05 2017 +0100
+
+    [expr, over] Add cross-references for 'usual arithmetic conversions'. (#1804)
+
+commit 7670c1a8e025aa464fe5bebff7ae2626fb01b07f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Feb 7 11:10:48 2017 +0100
+
+    [structure.specifications] Do not use library description macros in running text
+
+    This avoids colons in running text and some bad spacing.
+
+commit deb9fb19a039dbcd943a5955064d8c0e3d55a45c
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Mar 4 06:46:30 2017 -1000
+
+    Consistent comma after e.g. and i.e.
+
+    After grepping to determine the preferred idiom, it seems clear that
+    the standard prefers to follow both e.g. and i.e. with a comma, rather
+    than omit it.  This patch applies that rule to the few places that
+    were missing the comma.
+
+commit e1b92d6c125ef43e19915ba0b031baa2c6611c62
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 21 18:01:18 2017 +0000
+
+    [over.match.best] Remove meaningless "i.e."
+
+commit 72b80b32c7ab185cc08eb72cf24ce6d839f7e6f3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 21 16:19:36 2017 +0000
+
+    [alg.partition] Use established terminology 'partitioned with respect to'
+
+commit b4a1e3c1c73531f3a61ae6e44abecab766e9c537
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 21 15:52:31 2017 +0000
+
+    [binary.search] Formulate partitioning requirements in the same style as all the other related algorithms do
+
+commit b1fd50580cf389c61635a5767bf46b1b8823ce0c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 21 13:04:27 2017 +0100
+
+    [expr.compound] Expression operators do not 'return' results. (#1818)
+
+commit 68e53321ed7bf8505748e0f69947e21f9374d3a2
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Nov 21 08:02:52 2017 -0400
+
+    [strings.general] Use plural "string classes" (#1823)
+
+    The summary even says "string classes", and now we also have the "string_view classes".
+
+commit a5c25539b2605d8e6817b43d48e359d24642d1b7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 21 11:46:26 2017 +0100
+
+    [variant] Move 'Otherwise' to start of following bullet. (#1813)
+
+commit e13e3097e6c92f67b86458af9a3d4793b0aeb544
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 21 01:49:37 2017 +0000
+
+    [utilities] Add missing charconv entry to summary table
+
+commit cbd25c4b3e6f83aaf2fa9fe894ff52b1f428a8c5
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Nov 12 00:37:09 2017 -0700
+
+    Hyphenate 'pointer-to-member' when it is an adjective and define the adjective.
+
+    Fixes #1369.
+
+commit 801fb0ba013362cede5a9eaeae0da688e554d3ad
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 12 06:51:19 2017 +0100
+
+    [conv.rank] Move from [conv] to [basic.types] (#1802)
+
+commit ff65cec7b977db1a6900b0321f10c91e152ab8d2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 1 23:39:21 2017 +0100
+
+    Use 'trailing requires-clause'
+
+    where the requires-clause in a template-head is not meant.
+
+    Fixes #1672.
+
+commit 672bb6075cb0512a234b4f6bdd41f00cc01e6642
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Apr 19 23:03:42 2017 +0200
+
+    [dcl.init] Clarify introduction
+
+    Fixes #1615.
+
+commit 7c6f936298543387f2f17563f01e95fce904783d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 2 22:18:04 2017 +0100
+
+    [array] Dissolve single-item subclauses.
+
+    Partially addresses #1242.
+
+commit 04c4e8338eadb18deb63354a95c2624ef5b3fbed
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 11 19:34:18 2017 +0100
+
+    [intro.execution] Clarify full-expression in example.
+
+    Fixes #1706.
+
+commit 2e25955ecf6a576c98590097ec76aa616495c466
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 11 07:29:23 2017 +0100
+
+    [expr] Add subclauses and adjust cross-references to [expr].
+
+    Also move [basic.lval] into [expr].
+
+commit 87c88e99620ecbc3958dc0e06d86aa72806206c4
+Author: Casey Carter <Casey@Carter.net>
+Date:   Sat Nov 11 21:48:25 2017 -0700
+
+    [algorithms.general] & [algorithm.syn] name "mutating sequence operations" consistently (#1801)
+
+    Despite the stable name "alg.modifying.operations," the section is titled "Mutating sequence operations."
+
+commit 0963b3d26dcce7dff2b924e4d9d3daff0e1f50d6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 12 05:32:46 2017 +0100
+
+    [lib] Harmonize introductory comments in synopses (#1775)
+
+    Even if no section reference is given, make them lowercase
+    and remove trailing colons.
+
+commit 6b6578cc415bf17b237a0889ef2dc53f4b392d02
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 12 05:30:40 2017 +0100
+
+    [locale.moneypunct.virtuals] Add reference to ISO 4217. (#1779)
+
+commit 49870469d0a3347b91e42faa9c931859e924e83e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 12 04:21:40 2017 +0100
+
+    [lib] Add hyphen to 'well-defined' (#1776)
+
+commit 982a456f176ca00409c6e514af932051dce2485f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 11 05:06:58 2017 +0100
+
+    [intro], [basic] Rearrange subclauses
+
+    Fixes #1539.
+
+commit 301a71e35c49fafe2188736aff2631f36c81dd47
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 10 23:55:37 2017 -0800
+
+    [basic.lookup.argdep] Correct xref to point to the normative invisible
+    friend rule.
+
+commit 4f77c89e7635c8a9f361a0757c7765bcefeacd5e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 9 17:33:33 2017 -0700
+
+    [over.built] Improve placeholder phrasing
+
+commit 24bfe67b857bc6634ffc796324999373352d6d72
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 8 23:50:33 2017 -0700
+
+    [meta.endian] Clarify wording regarding size of scalar types
+
+commit 7a7d123584613a90cc64dbfb4b848807c3f085c8
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Wed Nov 8 01:50:47 2017 -0400
+
+    [any.class] Revert dot to comma typo from bdff8687c (#1795)
+
+commit ee8aa525e65ada1f1949ebc9eb006af8b29f7e85
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Nov 8 00:13:27 2017 +0000
+
+    [basic.ios.members], [streambuf.virt.put], [cmplx.over] replace enumerated lists with itemized
+
+commit 6ca5523589f8eb8d2843fe34386382a34064f41d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Nov 7 23:24:36 2017 +0000
+
+    [fstream], [fs.class.directory_entry] qualify filesystem::path consistently
+
+commit b4acb0ca022f5b4e8a535a164c845ab87e312a1f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Nov 7 08:56:03 2017 -0800
+
+    [basic.def] Fix typo "braced-enclosed".
+
+commit b174bd63680803b18f1ebce4d743b13c257cd3bf
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 2 18:54:45 2017 +0000
+
+    [defns.referenceable] Remove duplicate 'an'
+
+commit f0b892320c609974270ccd415ecef081529e664f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 2 03:19:54 2017 +0100
+
+    [array.size] Remove full member declaration from itemdecl. (#1790)
+
+commit ea4b17a448b46671488b96812629d92c0c9c61be
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 27 00:53:45 2017 +0200
+
+    [expr.prim.lambda.capture] Move discusssion of capture-by-reference of references
+
+    to after the introduction of 'capture by reference'.
+
+    Fixes #1785.
+
diff --git a/papers/n4714.md b/papers/n4714.md new file mode 100644 index 0000000000..3d220ec6e4 --- /dev/null +++ b/papers/n4714.md @@ -0,0 +1,591 @@ +# N4714 Editors' Report -- Programming Languages -- C++ + +2017-11-27 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Embarcadero Technologies Inc) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Special thanks to +Jens Maurer +for performing many of the editorial fixes since N4700. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4713](http://wg21.link/n4713) is the current working draft for C++20. It replaces [N4700](http://wg21.link/n4700). + * N4714 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolution](http://wg21.link/p0817r0) for 1 issue in "ready" status applied: + + * [2342](http://wg21.link/cwg2342) Reference `reinterpret_cast` and pointer-interconvertibility + +CWG motion 2: [Core issue resolutions](http://wg21.link/p0818r1) for 7 issues in "tentatively ready" status applied: + + * [1862](http://wg21.link/cwg1862) Determining "corresponding members" for friendship + * [2177](http://wg21.link/cwg2177) Placement `operator delete` and parameter copies + * [2305](http://wg21.link/cwg2305) Explicit instantiation of `constexpr` or `inline` variable template + * [2307](http://wg21.link/cwg2307) Unclear definition of "equivalent to a nontype template parameter" + * [2313](http://wg21.link/cwg2313) Redeclaration of structured binding reference variables + * [2315](http://wg21.link/cwg2315) What is the "corresponding special member" of a variant member? + * [2338](http://wg21.link/cwg2338) Undefined behavior converting to short enums with fixed underlying types + +CWG motion 3: [P0614R1 "Range-based `for` statements with initializer"](http://wg21.link/p0614r1) + +CWG motion 4: [P0588R1 "Simplifying implicit lambda capture"](http://wg21.link/p0588r1) + +CWG motion 5: [P0846R0 "ADL and function templates that are not visible"](http://wg21.link/p0846r0) + +CWG motion 6: [P0641R2 "Resolving core issue #1331"](http://wg21.link/p0641r2), resolving 1 core issue: + + * [1331](http://wg21.link/cwg1331) `const` mismatch with defaulted copy constructor + +CWG motion 7: [P0859R0 "Core issue 1581"](http://wg21.link/p0859r0), resolving 1 core issue: + + * [1581](http://wg21.link/cwg1581) When are `constexpr` member functions defined? + +CWG motion 8: [P0515R3 "Consistent comparison"](http://wg21.link/p0515r3) and [P0768R1 "Library support for the spaceship (comparison) operator"](http://wg21.link/p0768r1) + +CWG motion 9: [P0857R0 "Functionality gaps in constraints"](http://wg21.link/p0857r0) + +CWG motion 10: [P0692R1 "Access checking on specializations"](http://wg21.link/p0692r1) + +CWG motion 11: [P0624R2 "Default constructible and assignable stateless lambdas"](http://wg21.link/p0624r2) + +CWG motion 12: [P0767R1 "Deprecate POD"](http://wg21.link/p0767r1) + +CWG motion 13: [P0315R4 "Lambdas in unevaluated contexts"](http://wg21.link/p0315r4) + +### Library working group motions + +LWG motion 1 and 2 apply to the Parallelism TS. + +LWG motion 3 applies to the Networking TS. + +LWG motion 4: [Library issue resolutions](http://wg21.link/p0815r0) for 24 issues in "Ready" or "Tentatively Ready" status applied: + + * [2870](http://wg21.link/lwg2870) Default value of parameter `theta` of `polar` should be dependent + * [2935](http://wg21.link/lwg2935) What should `create_directories` do when `p` already exists but is not a directory? + * [2941](http://wg21.link/lwg2941) [thread.req.timing] wording should apply to both member and namespace-level functions + * [2944](http://wg21.link/lwg2944) [LWG 2905](http://wg21.link/lwg2905) accidentally removed requirement that construction of the deleter doesn't throw an exception + * [2945](http://wg21.link/lwg2945) Order of template parameters in `optional` comparisons + * [2948](http://wg21.link/lwg2948) `unique_ptr` does not define `operator<<` for stream output + * [2950](http://wg21.link/lwg2950) `std::byte` operations are misspecified + * [2952](http://wg21.link/lwg2952) `iterator_traits` should work for pointers to *cv* `T` + * [2953](http://wg21.link/lwg2953) [LWG 2853](http://wg21.link/lwg2853) should apply to `deque::erase` too + * [2964](http://wg21.link/lwg2964) Apparently redundant requirement for `dynamic_pointer_cast` + * [2965](http://wg21.link/lwg2965) Non-existing `path::native_string()` in `filesystem_error::what()` specification + * [2972](http://wg21.link/lwg2972) What is `is_trivially_destructible_v`? + * [2976](http://wg21.link/lwg2976) Dangling `uses_allocator` specialization for `packaged_task` + * [2977](http://wg21.link/lwg2977) `unordered_`*meow*`::merge()` has incorrect **Throws:** clause + * [2978](http://wg21.link/lwg2978) Hash support for `pmr::string` and friends + * [2979](http://wg21.link/lwg2979) `aligned_union` should require complete object types + * [2980](http://wg21.link/lwg2980) Cannot `compare_exchange` empty pointers + * [2981](http://wg21.link/lwg2981) Remove redundant deduction guides from standard library + * [2982](http://wg21.link/lwg2982) Making `size_type` consistent in associative container deduction guides + * [2988](http://wg21.link/lwg2988) Clause 32 cleanup missed one `typename` + * [2993](http://wg21.link/lwg2993) `reference_wrapper` conversion from `T&&` + * [2998](http://wg21.link/lwg2998) Requirements on function objects passed to {`forward_`,}`list`-specific algorithms + * [3001](http://wg21.link/lwg3001) `weak_ptr::element_type` needs `remove_extent_t` + * [3024](http://wg21.link/lwg3024) `variant`'s copies must be deleted instead of disabled via SFINAE + +LWG motion 5: [Library issue resolution](http://wg21.link/p0864r0) for 1 issue in "Immediate" status applied: + + * [2958](http://wg21.link/2958) Moves improperly defined as deleted + +LWG motion 6: [P0550R2 "Transformation trait `remove_cvref`"](http://wg21.link/p0550r2) + +LWG motion 7: [P0777R1 "Treating unnecessary `decay`"](http://wg21.link/p0777r1) + +LWG motion 8: [P0600R1 "`[[nodiscard]]` in the Library"](http://wg21.link/p0600r1) + +Do not try and apply LWG motion 9 to the working draft. That's impossible. +Instead, only realize the truth. There is no LWG motion 9. + +LWG motion 10: [P0439R0 "Make `std::memory_order` a scoped enumeration"](http://wg21.link/p0439r0) + +LWG motion 11: [P0053R7 "Synchronized buffered `ostream`"](http://wg21.link/p0053r7) + +LWG motion 12: [P0653R2 "Utility to convert a pointer to a raw pointer"](http://wg21.link/p0653r2) + +LWG motion 13: [P0202R3 "Add `constexpr` modifiers to functions in `` and `` Headers"](http://wg21.link/p0202r3) + +LWG motion 14: [P0415R1 "`constexpr` for `std::complex`"](http://wg21.link/p0415r1) + +LWG motion 15: [P0718R2 "Atomic `shared_ptr`"](http://wg21.link/p0718r2) + +LWG motion 16: [P0020R6 "Floating point atomic"](http://wg21.link/p0020r6) + +LWG motion 17: [P0616R0 "De-pessimize legacy `` algorithms with `std::move`"](http://wg21.link/p0616r0) + +LWG motion 18: [P0457R2 "String prefix and suffix checking"](http://wg21.link/p0457r2) + +## Notable editorial changes + +### CWG motion 8 + +Instead of removing [operators] and adding a new section to [requirements], the +existing stable name for this section is preserved. This section was moved to +[description] rather than to [requirements], as it describes a notational +device used for standard exposition. + +[alg.3way] added to [alg.sorting] rather than [alg.nonmodifying] to +match existing `lexicographical_compare` functions. + +### LWG motion 8 + +`[[nodiscard]]` was inadvertantly omitted from `deque::empty()` in the detailed +wording changes (but was covered by the general description of the change). +After consultation with LWG, this oversight has been corrected in the wording. + +### LWG motion 10 + +All references to the existing `memory_order_*` enumerators throughout the +working draft were updated to use the new scoped enumerator nmaes. + +### LWG motion 11 + +Changes were made to the organization and presentation of the wording +to fit better into the existing document. + +### LWG motion 12 + +The requested addition to [pointer.traits.function] has been moved into a new +subclause "Pointer traits optional members" and modified slightly to fit this +new presentation, as it does not describe a member of the `pointer_traits` +primary template. + +### Text reorganization + +In an effort to conform to ISO drafting directives to avoid hanging paragraphs +(text in subclauses that also contain further nested subclauses) and to remove +excessive subclause structure, the following changes have been made: + +* [intro] and [basic] have been reorganized so that [intro] acts as an + introduction to the standard document and [basic] introduces the basic + concepts of the standard in an order closer to dependency order +* [conv.rank] moved from [conv] to [basic.types], as it does not describe a conversion. +* [expr] has additional subclause structure to partially resolve hanging + paragraphs and generally improve its organization +* [expr] has a new subclause describing properties of expressions, containing + some of the prior hanging paragraphs from [expr], as well as [basic.lval] +* [array], [util.sharedptr] Per-function subclauses have been merged into parent subclause. + +### Changes in the style of specification + +* Code font is no longer used when referring to non-syntax properties of entities + (even when those properties are derived from syntax). This applies to the terms + "inline", "friend", "public", "protected", "private", "const object". + We generally intend to use code font only when referring specifically + to program syntax. + +* In library wording, template headers are formatted consistently with no + space between the `template` keyword and the `<` token. + +Drafting for future standard changes should take the above into account. + +### Index of library headers + +In order to keep the "Index of library names" focused on listing library names, +index entries for library headers have been moved to a separate, new "Index of +library headers". + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4700 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/n4700...n4713). + + commit 903df06f3e67c9a52539892cb6844b55392c5331 + Author: Thomas Köppe + Date: Mon Nov 27 22:00:03 2017 +0000 + + [allocator.adaptor.syn] Delete duplicate declarations of relational operators + + commit cebfe0a09fb56ec33726559c8b6d006dc19e4ab7 + Author: Jens Maurer + Date: Wed Nov 15 23:18:22 2017 +0100 + + [temp.constr.order] In definition of 'subsumes', remove + confusing introductory paragraph. + + commit 74df95e9e3fad1aa5844c281614bbfffb1cc6189 + Author: Jens Maurer + Date: Wed Nov 22 23:45:18 2017 +0100 + + [diff] Introduce numbered paragraphs + + commit e543af304e195ad301da272caa7ef12107077ac0 + Author: Jens Maurer + Date: Sat Nov 25 00:01:36 2017 +0100 + + [lib] Harmonize spacing for template headers. + + Use 'template'. + Also remove space between two closing template brackets. + + commit b73e56f7a2b92449d9ec4938b01fa7014edad33a + Author: Jens Maurer + Date: Wed Nov 15 23:26:11 2017 +0100 + + [basic.link] Entities declared in an unnamed namespace + never have external linkage. + + commit fc16d3133817701a780092cf6456722a40e27d28 + Author: Jens Maurer + Date: Sun Nov 19 23:11:51 2017 +0100 + + [temp.arg.explicit] Remove note obsoleted by P0846R0 + + commit d29bd8c6591fe74b095e5bd277f986462ba40b24 + Author: Jens Maurer + Date: Sun Nov 26 18:36:42 2017 +0100 + + [fs.op.funcs] Separate effects from returns. (#1848) + + commit e2457df32a6ee70417681de10be78eb815a0b22f + Author: Jens Maurer + Date: Mon Nov 20 10:23:18 2017 +0100 + + [complex.numbers] Use \xref for references to the C standard. + + commit bd2ce5c2d4ec26a5c412160ce5983149c510a131 + Author: Jens Maurer + Date: Tue Nov 21 23:35:02 2017 +0100 + + Create a new index for library headers + + and remove them from the index of library names. + + commit d1125303456c2305a72baebbb51d80151722f8ab + Author: Jonathan Wakely + Date: Thu Nov 23 14:33:32 2017 +0000 + + [basic.life],[mem.res.private],[mem.res.pool.mem],[mem.res.monotonic.buffer] fix cross-references + + commit 1d467a8a06cabd314e250a04ca9a4c81591d035a + Author: Johel Ernesto Guerrero Peña + Date: Thu Nov 23 15:31:45 2017 -0400 + + [func.require] Clarify which assignment operators + + commit 9dbbf9cbbe6994f7d4ad19098029e995eb34e1c3 + Author: Johel Ernesto Guerrero Peña + Date: Sat Nov 25 19:04:08 2017 -0400 + + [unord.req, fs.path.io] Fix "Effects: Equivalent to" styles (#1806) + + commit efdda2b9ca7f0ed78d7f134d8b1ca2e405610190 + Author: Jens Maurer + Date: Sat Nov 25 22:57:08 2017 +0100 + + [lib] Harmonize punctuation of 'Effects: Equivalent to' (#1815) + + commit 63ccd0513f6d9ac3555ca8becfcd7d15ed503522 + Author: stbergmann + Date: Sat Nov 25 03:33:31 2017 +0100 + + [basic.types] Add missing "be" in note (#1839) + + commit 9a8f4fde487200bcf4433facb0274f67d540617c + Author: Jens Maurer + Date: Sat Nov 25 03:29:09 2017 +0100 + + [lex.ccon] Align char16_t phrasing to UTF-8 one (#1847) + + commit 784f8c9980a74393ceaf201b343aa232a82113a4 + Author: Thomas Köppe + Date: Fri Nov 24 01:03:52 2017 +0000 + + [complex{,.special,.members}] Use injected-class-name in class definitions and itemdecls + + commit 877918fdc3e5223006b782d3c5959470bd7c02a8 + Author: Jonathan Wakely + Date: Fri Nov 24 00:57:49 2017 +0000 + + [allocator.requirements] Fix pointer_to expression and reinstate descriptive variable 'r' (#1656) + + commit 2ca4340d93ec4cd63c330303e5beef20db8604df + Author: Jonathan Wakely + Date: Thu Nov 23 22:48:22 2017 +0000 + + [vector.bool] Use injected-class-name in synopsis (#1844) + + commit 4eedcb0d29f7c3b143dc3492caecb9c608590e12 + Author: Richard Smith + Date: Wed Nov 22 19:26:28 2017 -0800 + + [diff.cpp17.library] Add Annex C entry for new headers and + added since C++17. + + commit 9112c6aecc48e1a0deea1f9493de224a43689a87 + Author: Aaron Ballman + Date: Mon Mar 13 09:51:35 2017 -0400 + + Use the terms "single-object delete expression" and + "array delete expression" as definitions, removing + the italics when not appropriate. + + commit b3b8a19812829ab521958eed6b2f1a3411180cdb + Author: Thomas Köppe + Date: Sun Nov 19 22:17:17 2017 +0000 + + [structure.summary] Remove obsolete paragraph about Note(s): and Example(s): elements that we no longer provide + + Also restyle a manual Note: in [unord.req] to use the standard note environment. + + commit 8958e953fd2cd60bd02ed4fcd2c055eded6e0f4d + Author: Thomas Köppe + Date: Tue Nov 21 23:28:52 2017 +0000 + + [unord.req] Spell out the behaviour of cbegin/cend, remove ambiguous note + + commit b64354a7503c1cdc358d7f5dd1405ed903e170ef + Author: Thomas Köppe + Date: Wed Nov 22 12:10:00 2017 +0000 + + [depr.meta.types] Merge POD deprecation into existing type traits deprecation section and reorganize the section a bit + + commit 374252a76008ac0316320d2dd4e8652910539a97 + Author: Jens Maurer + Date: Wed Nov 22 01:01:39 2017 +0100 + + [util.sharedptr] Dissolve subclause and integrate contents into parent. (#1814) + + commit 75c0adccb38301f66979cc3c3ab5cd15a0a75a17 + Author: Jens Maurer + Date: Tue Nov 21 23:29:05 2017 +0100 + + [expr, over] Add cross-references for 'usual arithmetic conversions'. (#1804) + + commit 7670c1a8e025aa464fe5bebff7ae2626fb01b07f + Author: Jens Maurer + Date: Tue Feb 7 11:10:48 2017 +0100 + + [structure.specifications] Do not use library description macros in running text + + This avoids colons in running text and some bad spacing. + + commit deb9fb19a039dbcd943a5955064d8c0e3d55a45c + Author: Alisdair Meredith + Date: Sat Mar 4 06:46:30 2017 -1000 + + Consistent comma after e.g. and i.e. + + After grepping to determine the preferred idiom, it seems clear that + the standard prefers to follow both e.g. and i.e. with a comma, rather + than omit it. This patch applies that rule to the few places that + were missing the comma. + + commit e1b92d6c125ef43e19915ba0b031baa2c6611c62 + Author: Thomas Köppe + Date: Tue Nov 21 18:01:18 2017 +0000 + + [over.match.best] Remove meaningless "i.e." + + commit 72b80b32c7ab185cc08eb72cf24ce6d839f7e6f3 + Author: Thomas Köppe + Date: Tue Nov 21 16:19:36 2017 +0000 + + [alg.partition] Use established terminology 'partitioned with respect to' + + commit b4a1e3c1c73531f3a61ae6e44abecab766e9c537 + Author: Thomas Köppe + Date: Tue Nov 21 15:52:31 2017 +0000 + + [binary.search] Formulate partitioning requirements in the same style as all the other related algorithms do + + commit b1fd50580cf389c61635a5767bf46b1b8823ce0c + Author: Jens Maurer + Date: Tue Nov 21 13:04:27 2017 +0100 + + [expr.compound] Expression operators do not 'return' results. (#1818) + + commit 68e53321ed7bf8505748e0f69947e21f9374d3a2 + Author: Johel Ernesto Guerrero Peña + Date: Tue Nov 21 08:02:52 2017 -0400 + + [strings.general] Use plural "string classes" (#1823) + + The summary even says "string classes", and now we also have the "string_view classes". + + commit a5c25539b2605d8e6817b43d48e359d24642d1b7 + Author: Jens Maurer + Date: Tue Nov 21 11:46:26 2017 +0100 + + [variant] Move 'Otherwise' to start of following bullet. (#1813) + + commit e13e3097e6c92f67b86458af9a3d4793b0aeb544 + Author: Thomas Köppe + Date: Tue Nov 21 01:49:37 2017 +0000 + + [utilities] Add missing charconv entry to summary table + + commit cbd25c4b3e6f83aaf2fa9fe894ff52b1f428a8c5 + Author: Thomas Köppe + Date: Sun Nov 12 00:37:09 2017 -0700 + + Hyphenate 'pointer-to-member' when it is an adjective and define the adjective. + + Fixes #1369. + + commit 801fb0ba013362cede5a9eaeae0da688e554d3ad + Author: Jens Maurer + Date: Sun Nov 12 06:51:19 2017 +0100 + + [conv.rank] Move from [conv] to [basic.types] (#1802) + + commit ff65cec7b977db1a6900b0321f10c91e152ab8d2 + Author: Jens Maurer + Date: Wed Nov 1 23:39:21 2017 +0100 + + Use 'trailing requires-clause' + + where the requires-clause in a template-head is not meant. + + Fixes #1672. + + commit 672bb6075cb0512a234b4f6bdd41f00cc01e6642 + Author: Jens Maurer + Date: Wed Apr 19 23:03:42 2017 +0200 + + [dcl.init] Clarify introduction + + Fixes #1615. + + commit 7c6f936298543387f2f17563f01e95fce904783d + Author: Jens Maurer + Date: Thu Nov 2 22:18:04 2017 +0100 + + [array] Dissolve single-item subclauses. + + Partially addresses #1242. + + commit 04c4e8338eadb18deb63354a95c2624ef5b3fbed + Author: Jens Maurer + Date: Sat Nov 11 19:34:18 2017 +0100 + + [intro.execution] Clarify full-expression in example. + + Fixes #1706. + + commit 2e25955ecf6a576c98590097ec76aa616495c466 + Author: Jens Maurer + Date: Sat Nov 11 07:29:23 2017 +0100 + + [expr] Add subclauses and adjust cross-references to [expr]. + + Also move [basic.lval] into [expr]. + + commit 87c88e99620ecbc3958dc0e06d86aa72806206c4 + Author: Casey Carter + Date: Sat Nov 11 21:48:25 2017 -0700 + + [algorithms.general] & [algorithm.syn] name "mutating sequence operations" consistently (#1801) + + Despite the stable name "alg.modifying.operations," the section is titled "Mutating sequence operations." + + commit 0963b3d26dcce7dff2b924e4d9d3daff0e1f50d6 + Author: Jens Maurer + Date: Sun Nov 12 05:32:46 2017 +0100 + + [lib] Harmonize introductory comments in synopses (#1775) + + Even if no section reference is given, make them lowercase + and remove trailing colons. + + commit 6b6578cc415bf17b237a0889ef2dc53f4b392d02 + Author: Jens Maurer + Date: Sun Nov 12 05:30:40 2017 +0100 + + [locale.moneypunct.virtuals] Add reference to ISO 4217. (#1779) + + commit 49870469d0a3347b91e42faa9c931859e924e83e + Author: Jens Maurer + Date: Sun Nov 12 04:21:40 2017 +0100 + + [lib] Add hyphen to 'well-defined' (#1776) + + commit 982a456f176ca00409c6e514af932051dce2485f + Author: Jens Maurer + Date: Sat Nov 11 05:06:58 2017 +0100 + + [intro], [basic] Rearrange subclauses + + Fixes #1539. + + commit 301a71e35c49fafe2188736aff2631f36c81dd47 + Author: Richard Smith + Date: Fri Nov 10 23:55:37 2017 -0800 + + [basic.lookup.argdep] Correct xref to point to the normative invisible + friend rule. + + commit 4f77c89e7635c8a9f361a0757c7765bcefeacd5e + Author: Thomas Köppe + Date: Thu Nov 9 17:33:33 2017 -0700 + + [over.built] Improve placeholder phrasing + + commit 24bfe67b857bc6634ffc796324999373352d6d72 + Author: Thomas Köppe + Date: Wed Nov 8 23:50:33 2017 -0700 + + [meta.endian] Clarify wording regarding size of scalar types + + commit 7a7d123584613a90cc64dbfb4b848807c3f085c8 + Author: Johel Ernesto Guerrero Peña + Date: Wed Nov 8 01:50:47 2017 -0400 + + [any.class] Revert dot to comma typo from bdff8687c (#1795) + + commit ee8aa525e65ada1f1949ebc9eb006af8b29f7e85 + Author: Jonathan Wakely + Date: Wed Nov 8 00:13:27 2017 +0000 + + [basic.ios.members], [streambuf.virt.put], [cmplx.over] replace enumerated lists with itemized + + commit 6ca5523589f8eb8d2843fe34386382a34064f41d + Author: Jonathan Wakely + Date: Tue Nov 7 23:24:36 2017 +0000 + + [fstream], [fs.class.directory_entry] qualify filesystem::path consistently + + commit b4acb0ca022f5b4e8a535a164c845ab87e312a1f + Author: Richard Smith + Date: Tue Nov 7 08:56:03 2017 -0800 + + [basic.def] Fix typo "braced-enclosed". + + commit b174bd63680803b18f1ebce4d743b13c257cd3bf + Author: Thomas Köppe + Date: Thu Nov 2 18:54:45 2017 +0000 + + [defns.referenceable] Remove duplicate 'an' + + commit f0b892320c609974270ccd415ecef081529e664f + Author: Jens Maurer + Date: Thu Nov 2 03:19:54 2017 +0100 + + [array.size] Remove full member declaration from itemdecl. (#1790) + + commit ea4b17a448b46671488b96812629d92c0c9c61be + Author: Jens Maurer + Date: Fri Oct 27 00:53:45 2017 +0200 + + [expr.prim.lambda.capture] Move discusssion of capture-by-reference of references + + to after the introduction of 'capture by reference'. + + Fixes #1785. diff --git a/papers/n4727.pdf b/papers/n4727.pdf new file mode 100644 index 0000000000..db4ec455e7 Binary files /dev/null and b/papers/n4727.pdf differ diff --git a/papers/n4728.html b/papers/n4728.html new file mode 100644 index 0000000000..d99e4c3ad7 --- /dev/null +++ b/papers/n4728.html @@ -0,0 +1,427 @@ +N4728 +

N4728 Editors' Report -- Programming Languages -- C++

+ +

2018-02-12
+Richard Smith (editor) (Google Inc)
+Dawn Perchik (co-editor) (Embarcadero Technologies Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to +Jens Maurer +for performing many of the editorial fixes since N4713.

+ +

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

+ +

New papers

+ +
    +
  • N4727 is the current working draft for C++20. It replaces N4713.
  • +
  • N4728 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

This revision contains only editorial changes relative to N4727.

+ +

Notable editorial changes

+ +

Fixed misapplication of LWG issue 704

+ +

The application of LWG issue 704 introduced a +reference to the "Allocator-aware container requirements" table in normative +wording. Due to an editorial oversight after the insertion of earlier tables +caused the table numbering to change, this reference was instead pointed at the +"Container requirements" table, altering the normative interpretation of the +words.

+ +

The intended normative impact of LWG issue 704 has been restored by repointing +the reference to the correct table. However, we believe the wording still does +not have the intended effect, and LWG issue 3059 +has been opened to rectify this wording.

+ +

Index of grammar productions

+ +

The index of grammar productions now indexes both the point at which each +grammar production is defined (in bold) and all references to the grammar +production in the main text.

+ +

Thanks to Jens Maurer for providing the necessary edits and cleanups for this +change.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4727 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 858b48f15b2a05e7332634efbe7effc1aace407a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 16 19:13:15 2017 +0100
+
+    [basic.def] 'class name declaration' is undefined.
+
+commit 12f2ee068f9a7933c0b916ecdba6d90adc4c6708
+Author: JF Bastien <github@jfbastien.com>
+Date:   Wed Feb 7 14:50:37 2018 -0800
+
+    [atomics.types.operations] Clarify compare_exchange note
+
+    We now have explicit floating-point specializations for atomic. We had cmpxchg for them before, but people are now looking at increased usage and are confused about what the behavior is for `-0.` with `0.`, as well as NaNs. I propose clarifying the note to make this extra clear. This is a note and is therefore purely editorial, and would be a waste of SG1's time.
+
+commit f39be10b4419ea86711b7de4e9fe67ad340dc489
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 29 21:25:35 2017 +0100
+
+    [filesystems] 'dot' and 'dot-dot' are not \grammarterms
+
+commit 2ce8d327638e02de1009a687eb59825efed96438
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 30 22:36:27 2017 +0100
+
+    [over.best.ics] Adjust example for [over.match.list] case
+
+commit 58e1d43a0971d0c9bf8d33c2feaf546e33a10f7d
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Wed Dec 6 01:03:21 2017 -0400
+
+    [string.view.template] Add missing stable reference
+
+commit c4b8bd47dd6d20ec653e388febaff44f510c5446
+Author: Geoff Romer <gromer@google.com>
+Date:   Fri Dec 8 11:02:50 2017 -0800
+
+    Constant expressions can have "library UB"
+
+commit e2db0305802e4974426741693e28a232d0bc22ef
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 12 21:31:00 2017 +0100
+
+    [temp.dep.type] Clarify that a simple-template-id denotes a type
+
+commit 3431c062a2c76261f0fbb44b710a0775a568928b
+Author: Agustin K-ballo Berge <k@fusionfenix.com>
+Date:   Thu Dec 14 17:14:26 2017 -0300
+
+    [refwrap] Fix wrong use of "shall"
+
+commit 2cbbe1c63ff17ff6e566c4dfa11211a6b3455e6d
+Author: Agustin K-ballo Berge <k@fusionfenix.com>
+Date:   Thu Dec 14 17:17:32 2017 -0300
+
+    [thread.thread.id] Fix wrong uses of "shall"
+
+commit afa8c506f108c383826bf9962721d37d76ac4efb
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Tue Feb 13 03:02:28 2018 +0800
+
+    [basic.scope.class,basic.lookup.unqual] Use the term "default member initializer" (#1892)
+
+commit 08c9d619ab28c79b51ef9ca4b6349436d4cf28c5
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sun Dec 31 04:08:11 2017 +0800
+
+    [expr.const] Fix no longer correct comment
+
+commit a1243f679098d3dd1e4e566873ae53c18a974e8c
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jan 3 10:26:16 2018 +0000
+
+    [dcl.enum] use indefinite article before "fixed underlying type"
+
+commit cde94b80a4f229f564a51b20ed4e133ba15ee481
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jan 9 22:52:49 2018 +0100
+
+    [namespace.udir] Ambiguous lookup results are covered in [basic.lookup]
+
+    Relegate a duplicate normative statement in [namespace.udir]
+    to a note and add a cross-reference to [basic.lookup].
+
+commit 0ce8ae35424bc010661a33e3dcabde31faf603d1
+Author: James Dennett <jdennett@google.com>
+Date:   Tue Jan 30 10:50:05 2018 -0800
+
+    Fix references to container requirements tables.
+
+    LWG issue 704 ("MoveAssignable requirement for container value type
+    overly strict") added a reference from [associative.reqmts] to what was
+    at the time table 93 ("Allocator-aware container requirements").
+
+    That table is now table 86, but the cross reference is now
+    (incorrectly) to table 83 ("Container requirements").  It should still
+    refer to the Allocator-ware container requirements table.  This patch
+    changes it to do so, matching what the committee voted in (many years
+    ago).
+
+commit efbeb9ed7471b550df9da7a305e745a21a2d9569
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sat Dec 9 02:47:23 2017 +0800
+
+    [dcl.struct.bind] Clarify that structured bindings are entities (as contrast to names)
+
+commit c90e151f98a97423df50d438d075544545132989
+Author: Marshall Clow <marshall@idio.com>
+Date:   Mon Jan 29 12:01:30 2018 -0800
+
+    [array.members] Update the description for array::data to match that of vector::data (#1904)
+
+commit 4dec2aca3412c8c7d674f07409f44584ab225173
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Jan 29 11:54:35 2018 -0800
+
+    [fs.rec.dir.itr.members] Grammar fixes. (#1903)
+
+commit 616405fb021f33841280407e95a7a44e1183a719
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sat Jan 20 04:19:32 2018 +0100
+
+    [class.temporary, temp.inst, temp.dep, temp.res] Capitalize some sentences.
+
+commit 560e5f5d5797de2d376eaae96bb586c833e9dda2
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jan 11 15:44:26 2018 -0800
+
+    [dcl.init.ref] Remove an unnecessary level of bullet nesting.
+
+commit b4d7e7406dfa7c59591743dca9b79f30fa8f15bd
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jan 11 21:56:03 2018 +0000
+
+    [variant.visit] Rephrase specification of 'visit' to be more technically correct and precise
+
+commit 487e870347a4c76c9b6dd664c4e5671e709c81d8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jan 5 22:08:55 2018 +0100
+
+    [basic.lookup] Clarify name lookup consistency
+
+commit 66a540e5b586bf85befc9ed14e6e98e708d0b305
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jan 5 14:53:02 2018 +0000
+
+    [algorithms] Uniformize spelling of "in the initializer list"
+
+commit 8e93464548bfabaa4dd501e4031f7afb7a70da3e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jan 5 14:49:07 2018 +0000
+
+    [algorithms] Add missing full stops to inline Returns elements
+
+commit 2da91dac56d2be7bed2c09cb7804d0fcc2d649ae
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jan 2 12:38:09 2018 -0800
+
+    [variant.visit] qualify std::forward for consistency
+
+commit 70bd5d816825351d5b4abd376847814e9c1a9d4d
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Fri Dec 22 06:24:47 2017 -0500
+
+    Use 'one of' formulation for binary-digit
+
+    The grammar for literals consistently prefers using the 'one of' a set
+    formulation for character sets, rather than listing each character as
+    an option.  This holds for other parts of this grammar, even when the
+    set of options is just two items, such as hexadecimal-prefix,
+    unsigned-suffix, or long-suffix.
+
+    As binary-digit is the odd one out, this simple update makes it
+    consistent with the rest of the grammar specifications in this
+    clause.
+
+commit 9c4f6823e057da4112563254bc766b465b55d06f
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Tue Jan 2 17:40:32 2018 +0000
+
+    [re.regex.construct] Add missing default argument to itemdecl (#1893)
+
+commit f7bfd1766672c272509718f48eef2f5cf80725e9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jan 2 17:32:45 2018 +0000
+
+    [basic.string] State class invariants about [data(), data() + size()] in the introduction. (#1879)
+
+commit 0c0e0c3a740c133e1d25bfdbe141a3128d77a381
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Fri Dec 15 15:50:01 2017 -0500
+
+    [atomics.types.memop] Add missing `\pnum`s (#1890)
+
+commit bfcc4d844ac3758060c277e881b3aab7cf24743a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 6 22:01:32 2017 +0000
+
+    [re.def] Clarify index entry for "sub-expression"
+
+commit 3e715907193e3f5d47ff15470ef7a0496010e834
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Wed Dec 6 06:42:55 2017 -0500
+
+    [diff.mods.to.headers] Remove non-existent headers from the indexes (#1878)
+
+    Three C11 headers are called out as not being part of C++.
+    They should not be listed in the index of headers, which
+    currently points to the two places that explicitly state
+    these headers do not exist.
+
+commit 83e302d3bb6a5f88554b1ec75e8aa51760458c5f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Dec 3 20:45:03 2017 +0000
+
+    [string.cons] Replace postcondition tables by ordinary Postcondition elements
+
+commit 2da6e6a2c191ee03785f4eea34380b49274ffd52
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 30 13:57:14 2017 +0100
+
+    [facet.num.put.virtuals] Fix definition and use of 'loc' (#1861)
+
+commit 7945291d0b619765caf56ed746f173762c4824ee
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 30 13:55:41 2017 +0100
+
+    [charconv.to.chars, charconv.from.chars] Replace 'minus sign' with '-' (#1862)
+
+commit 6c89881ad5ba8008a83d05232e316b9b5acbd08f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 30 13:55:15 2017 +0100
+
+    [fs.path.decompose] 'root-path' is not a grammar non-terminal (#1864)
+
+    Use the function call root_path() instead.
+
+commit ce1a9d0b60b3375d7e2f59cfdcd82ffb127f0eb9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 29 00:57:43 2017 +0100
+
+    [intro.scope] C++ is not a strict superset of C
+
diff --git a/papers/n4728.md b/papers/n4728.md new file mode 100644 index 0000000000..1526c0be1e --- /dev/null +++ b/papers/n4728.md @@ -0,0 +1,301 @@ +# N4728 Editors' Report -- Programming Languages -- C++ + +2018-02-12 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Embarcadero Technologies Inc) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Special thanks to +Jens Maurer +for performing many of the editorial fixes since N4713. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4727](http://wg21.link/n4727) is the current working draft for C++20. It replaces [N4713](http://wg21.link/n4713). + * N4728 is this Editors' Report. + +## Motions incorporated into working draft + +This revision contains only editorial changes relative to N4727. + +## Notable editorial changes + +### Fixed misapplication of LWG issue 704 + +The application of [LWG issue 704](http://wg21.link/lwg704) introduced a +reference to the "Allocator-aware container requirements" table in normative +wording. Due to an editorial oversight after the insertion of earlier tables +caused the table numbering to change, this reference was instead pointed at the +"Container requirements" table, altering the normative interpretation of the +words. + +The intended normative impact of LWG issue 704 has been restored by repointing +the reference to the correct table. However, we believe the wording still does +not have the intended effect, and [LWG issue 3059](http://wg21.link/lwg3059) +has been opened to rectify this wording. + +### Index of grammar productions + +The index of grammar productions now indexes both the point at which each +grammar production is defined (in bold) and all references to the grammar +production in the main text. + +Thanks to Jens Maurer for providing the necessary edits and cleanups for this +change. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4727 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/n4713...n4727). + + commit 858b48f15b2a05e7332634efbe7effc1aace407a + Author: Jens Maurer + Date: Thu Nov 16 19:13:15 2017 +0100 + + [basic.def] 'class name declaration' is undefined. + + commit 12f2ee068f9a7933c0b916ecdba6d90adc4c6708 + Author: JF Bastien + Date: Wed Feb 7 14:50:37 2018 -0800 + + [atomics.types.operations] Clarify compare_exchange note + + We now have explicit floating-point specializations for atomic. We had cmpxchg for them before, but people are now looking at increased usage and are confused about what the behavior is for `-0.` with `0.`, as well as NaNs. I propose clarifying the note to make this extra clear. This is a note and is therefore purely editorial, and would be a waste of SG1's time. + + commit f39be10b4419ea86711b7de4e9fe67ad340dc489 + Author: Jens Maurer + Date: Wed Nov 29 21:25:35 2017 +0100 + + [filesystems] 'dot' and 'dot-dot' are not \grammarterms + + commit 2ce8d327638e02de1009a687eb59825efed96438 + Author: Jens Maurer + Date: Thu Nov 30 22:36:27 2017 +0100 + + [over.best.ics] Adjust example for [over.match.list] case + + commit 58e1d43a0971d0c9bf8d33c2feaf546e33a10f7d + Author: Johel Ernesto Guerrero Peña + Date: Wed Dec 6 01:03:21 2017 -0400 + + [string.view.template] Add missing stable reference + + commit c4b8bd47dd6d20ec653e388febaff44f510c5446 + Author: Geoff Romer + Date: Fri Dec 8 11:02:50 2017 -0800 + + Constant expressions can have "library UB" + + commit e2db0305802e4974426741693e28a232d0bc22ef + Author: Jens Maurer + Date: Tue Dec 12 21:31:00 2017 +0100 + + [temp.dep.type] Clarify that a simple-template-id denotes a type + + commit 3431c062a2c76261f0fbb44b710a0775a568928b + Author: Agustin K-ballo Berge + Date: Thu Dec 14 17:14:26 2017 -0300 + + [refwrap] Fix wrong use of "shall" + + commit 2cbbe1c63ff17ff6e566c4dfa11211a6b3455e6d + Author: Agustin K-ballo Berge + Date: Thu Dec 14 17:17:32 2017 -0300 + + [thread.thread.id] Fix wrong uses of "shall" + + commit afa8c506f108c383826bf9962721d37d76ac4efb + Author: S. B. Tam + Date: Tue Feb 13 03:02:28 2018 +0800 + + [basic.scope.class,basic.lookup.unqual] Use the term "default member initializer" (#1892) + + commit 08c9d619ab28c79b51ef9ca4b6349436d4cf28c5 + Author: S. B. Tam + Date: Sun Dec 31 04:08:11 2017 +0800 + + [expr.const] Fix no longer correct comment + + commit a1243f679098d3dd1e4e566873ae53c18a974e8c + Author: Jonathan Wakely + Date: Wed Jan 3 10:26:16 2018 +0000 + + [dcl.enum] use indefinite article before "fixed underlying type" + + commit cde94b80a4f229f564a51b20ed4e133ba15ee481 + Author: Jens Maurer + Date: Tue Jan 9 22:52:49 2018 +0100 + + [namespace.udir] Ambiguous lookup results are covered in [basic.lookup] + + Relegate a duplicate normative statement in [namespace.udir] + to a note and add a cross-reference to [basic.lookup]. + + commit 0ce8ae35424bc010661a33e3dcabde31faf603d1 + Author: James Dennett + Date: Tue Jan 30 10:50:05 2018 -0800 + + Fix references to container requirements tables. + + LWG issue 704 ("MoveAssignable requirement for container value type + overly strict") added a reference from [associative.reqmts] to what was + at the time table 93 ("Allocator-aware container requirements"). + + That table is now table 86, but the cross reference is now + (incorrectly) to table 83 ("Container requirements"). It should still + refer to the Allocator-ware container requirements table. This patch + changes it to do so, matching what the committee voted in (many years + ago). + + commit efbeb9ed7471b550df9da7a305e745a21a2d9569 + Author: S. B. Tam + Date: Sat Dec 9 02:47:23 2017 +0800 + + [dcl.struct.bind] Clarify that structured bindings are entities (as contrast to names) + + commit c90e151f98a97423df50d438d075544545132989 + Author: Marshall Clow + Date: Mon Jan 29 12:01:30 2018 -0800 + + [array.members] Update the description for array::data to match that of vector::data (#1904) + + commit 4dec2aca3412c8c7d674f07409f44584ab225173 + Author: Casey Carter + Date: Mon Jan 29 11:54:35 2018 -0800 + + [fs.rec.dir.itr.members] Grammar fixes. (#1903) + + commit 616405fb021f33841280407e95a7a44e1183a719 + Author: Eelis van der Weegen + Date: Sat Jan 20 04:19:32 2018 +0100 + + [class.temporary, temp.inst, temp.dep, temp.res] Capitalize some sentences. + + commit 560e5f5d5797de2d376eaae96bb586c833e9dda2 + Author: Richard Smith + Date: Thu Jan 11 15:44:26 2018 -0800 + + [dcl.init.ref] Remove an unnecessary level of bullet nesting. + + commit b4d7e7406dfa7c59591743dca9b79f30fa8f15bd + Author: Thomas Köppe + Date: Thu Jan 11 21:56:03 2018 +0000 + + [variant.visit] Rephrase specification of 'visit' to be more technically correct and precise + + commit 487e870347a4c76c9b6dd664c4e5671e709c81d8 + Author: Jens Maurer + Date: Fri Jan 5 22:08:55 2018 +0100 + + [basic.lookup] Clarify name lookup consistency + + commit 66a540e5b586bf85befc9ed14e6e98e708d0b305 + Author: Thomas Köppe + Date: Fri Jan 5 14:53:02 2018 +0000 + + [algorithms] Uniformize spelling of "in the initializer list" + + commit 8e93464548bfabaa4dd501e4031f7afb7a70da3e + Author: Thomas Köppe + Date: Fri Jan 5 14:49:07 2018 +0000 + + [algorithms] Add missing full stops to inline Returns elements + + commit 2da91dac56d2be7bed2c09cb7804d0fcc2d649ae + Author: Casey Carter + Date: Tue Jan 2 12:38:09 2018 -0800 + + [variant.visit] qualify std::forward for consistency + + commit 70bd5d816825351d5b4abd376847814e9c1a9d4d + Author: Alisdair Meredith + Date: Fri Dec 22 06:24:47 2017 -0500 + + Use 'one of' formulation for binary-digit + + The grammar for literals consistently prefers using the 'one of' a set + formulation for character sets, rather than listing each character as + an option. This holds for other parts of this grammar, even when the + set of options is just two items, such as hexadecimal-prefix, + unsigned-suffix, or long-suffix. + + As binary-digit is the odd one out, this simple update makes it + consistent with the rest of the grammar specifications in this + clause. + + commit 9c4f6823e057da4112563254bc766b465b55d06f + Author: Jonathan Wakely + Date: Tue Jan 2 17:40:32 2018 +0000 + + [re.regex.construct] Add missing default argument to itemdecl (#1893) + + commit f7bfd1766672c272509718f48eef2f5cf80725e9 + Author: Thomas Köppe + Date: Tue Jan 2 17:32:45 2018 +0000 + + [basic.string] State class invariants about [data(), data() + size()] in the introduction. (#1879) + + commit 0c0e0c3a740c133e1d25bfdbe141a3128d77a381 + Author: timsong-cpp + Date: Fri Dec 15 15:50:01 2017 -0500 + + [atomics.types.memop] Add missing `\pnum`s (#1890) + + commit bfcc4d844ac3758060c277e881b3aab7cf24743a + Author: Thomas Köppe + Date: Wed Dec 6 22:01:32 2017 +0000 + + [re.def] Clarify index entry for "sub-expression" + + commit 3e715907193e3f5d47ff15470ef7a0496010e834 + Author: Alisdair Meredith + Date: Wed Dec 6 06:42:55 2017 -0500 + + [diff.mods.to.headers] Remove non-existent headers from the indexes (#1878) + + Three C11 headers are called out as not being part of C++. + They should not be listed in the index of headers, which + currently points to the two places that explicitly state + these headers do not exist. + + commit 83e302d3bb6a5f88554b1ec75e8aa51760458c5f + Author: Thomas Köppe + Date: Sun Dec 3 20:45:03 2017 +0000 + + [string.cons] Replace postcondition tables by ordinary Postcondition elements + + commit 2da6e6a2c191ee03785f4eea34380b49274ffd52 + Author: Jens Maurer + Date: Thu Nov 30 13:57:14 2017 +0100 + + [facet.num.put.virtuals] Fix definition and use of 'loc' (#1861) + + commit 7945291d0b619765caf56ed746f173762c4824ee + Author: Jens Maurer + Date: Thu Nov 30 13:55:41 2017 +0100 + + [charconv.to.chars, charconv.from.chars] Replace 'minus sign' with '-' (#1862) + + commit 6c89881ad5ba8008a83d05232e316b9b5acbd08f + Author: Jens Maurer + Date: Thu Nov 30 13:55:15 2017 +0100 + + [fs.path.decompose] 'root-path' is not a grammar non-terminal (#1864) + + Use the function call root_path() instead. + + commit ce1a9d0b60b3375d7e2f59cfdcd82ffb127f0eb9 + Author: Jens Maurer + Date: Wed Nov 29 00:57:43 2017 +0100 + + [intro.scope] C++ is not a strict superset of C diff --git a/papers/n4740.html b/papers/n4740.html new file mode 100644 index 0000000000..72f7586c42 --- /dev/null +++ b/papers/n4740.html @@ -0,0 +1,850 @@ +N4740 +

N4740 Editors' Report -- Programming Languages -- C++

+ +

2018-04-02
+Richard Smith (editor) (Google Inc)
+Dawn Perchik (co-editor) (Bright Side Computing, LLC)
+Thomas Köppe (co-editor) (Google DeepMind)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to +Jens Maurer +for performing many of the editorial fixes since N4727.

+ +

Thanks to Walter E Brown and Peter Sommerlad for +supplying LaTeX sources for their papers +P0551R3 (LWG motion 13) +and +P0753R2 (LWG motion 14).

+ +

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

+ +

New papers

+ +
    +
  • N4741 is the current working draft for C++20. It replaces N4727.
  • +
  • N4740 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolutions for 17 issue in "tentatively ready" status applied:

+ +
    +
  • 1893 Function-style cast with braced-init-lists and empty pack expansions
  • +
  • 1910 "Shall" requirement applied to runtime behavior
  • +
  • 1983 Inappropriate use of virt-specifier
  • +
  • 2059 Linkage and deduced return types
  • +
  • 2081 Deduced return type in redeclaration or specialization of function template
  • +
  • 2088 Late tiebreakers in partial ordering
  • +
  • 2092 Deduction failure and overload resolution
  • +
  • 2164 Name hiding and using-directives
  • +
  • 2226 Xvalues vs lvalues in conditional expressions
  • +
  • 2227 Destructor access and default member initializers
  • +
  • 2229 Volatile unnamed bit-fields
  • +
  • 2234 Missing rules for simple-template-id as class-name
  • +
  • 2235 Partial ordering and non-dependent types
  • +
  • 2237 Can a template-id name a constructor?
  • +
  • 2255 Instantiated static data member templates
  • +
  • 2260 Explicit specializations of deleted member functions
  • +
  • 2299 constexpr vararg functions
  • +
+ +

CWG motion 2: P0840R2 "Language support for empty objects"

+ +

CWG motion 3: P0962R1 "Relaxing the range-for customization point finding rules"

+ +

CWG motion 4: P0969R0 "Allow structured bindings to accessible members"

+ +

CWG motion 5: P0961R1 "Relaxing the structured bindings customization point finding rules"

+ +

CWG motion 6: P0634R3 "Down with typename!"

+ +

CWG motion 7: P0780R2 "Allow pack expansion in lambda init-capture"

+ +

CWG motion 8: P0479R5 "likely and unlikely attributes"

+ +

CWG motion 9: P0905R1 "Symmetry for spaceship" with wording changes, see below

+ +

CWG motions 10 and 11 apply to the Coroutines TS.

+ +

Library working group motions

+ +

LWG motions 1 and 2 apply to the Parallelism TS.

+ +

LWG motion 3 applies to the Reflection TS.

+ +

LWG motion 4 applies to the Coroutines TS.

+ +

LWG motion 5 applies to the Networking TS.

+ +

LWG motion 6 applies to the Library Fundamentals TS.

+ +

LWG motion 7: Library issue resolutions for 29 issues in "Ready" or "Tentatively Ready" status applied:

+ +
    +
  • 2164 What are the semantics of vector.emplace(vector.begin(), vector.back())?
  • +
  • 2243 istream::putback problem
  • +
  • 2816 resize_file has impossible postcondition
  • +
  • 2843 Unclear behavior of std::pmr::memory_resource::do_allocate()
  • +
  • 2849 Why does !is_regular_file(from) cause copy_file to report a "file already exists" error?
  • +
  • 2851 std::filesystem enum classes are now underspecified
  • +
  • 2969 polymorphic_allocator::construct() shouldn't pass resource()
  • +
  • 2975 Missing case for pair construction in scoped and polymorphic allocators
  • +
  • 2989 path's stream insertion operator lets you insert everything under the sun
  • +
  • 3000 monotonic_memory_resource::do_is_equal uses dynamic_cast unnecessarily
  • +
  • 3004 [string.capacity] and [vector.capacity] should specify time complexity for capacity()
  • +
  • 3005 Destruction order of arrays by make_shared/allocate_shared only recommended?
  • +
  • 3007 allocate_shared should rebind allocator to cv-unqualified value_type for construction
  • +
  • 3009 Including <string_view> doesn't provide std::size/empty/data
  • +
  • 3013 (recursive_)directory_iterator construction and traversal should not be noexcept
  • +
  • 3014 More noexcept issues with filesystem operations
  • +
  • 3015 copy_options::unspecified underspecified
  • +
  • 3017 list splice functions should use addressof
  • +
  • 3026 filesystem::weakly_canonical still defined in terms of canonical(p, base)
  • +
  • 3030 Who shall meet the requirements of try_lock?
  • +
  • 3034 P0767R1 breaks previously-standard-layout types
  • +
  • 3035 std::allocator's constructors should be constexpr
  • +
  • 3039 Unnecessary decay in thread and packaged_task
  • +
  • 3041 Unnecessary decay in reference_wrapper
  • +
  • 3042 is_literal_type_v should be inline
  • +
  • 3043 Bogus postcondition for filesystem_error constructor
  • +
  • 3045 atomic<floating-point> doesn't have value_type or difference_type
  • +
  • 3048 transform_reduce(exec, first1, last1, first2, init) discards execution policy
  • +
  • 3051 Floating point classifications were inadvertently changed in P0175
  • +
+ +

LWG motion 8: Library issue resolutions for 2 issues in "Immediate" status applied:

+ +
    +
  • 2946 LWG 2758's resolution missed further corrections
  • +
  • 3075 basic_string needs deduction guides from basic_string_view
  • +
+ +

LWG motion 9: P0754R2 "<version>"

+ +

LWG motion 10: P0809R0 "Comparing unordered containers", resolving 1 library issue:

+ +
    +
  • 2831 Equality can be defined when Hash function objects have different behaviour
  • +
+ +

LWG motion 11: P0355R7 "Extending chrono to calendars and time zones" with wording changes, see below

+ +

LWG motion 12: P0966R1 "string::reserve should not shrink"

+ +

LWG motion 13: P0551R3 "Thou shalt not specialize std function templates!"

+ +

LWG motion 14: P0753R2 "Manipulators for C++ synchronized buffered ostream"

+ +

LWG motion 15: P0122R7 "<span>" with wording changes, see below

+ +

LWG motion 16: P0858R0 "Constexpr iterator requirements"

+ +

Notable editorial changes

+ +

CWG motion 9

+ +

After consultation with CWG, the wording for injecting additional operator<=> +candidates has been editorially reworked, introducing a named set of "rewritten +candidates" in the place of the ad-hoc additional lookups previously specified. +That change allows the wording of this motion to be expressed more directly, +but, as a consequence, the wording changes applied for this paper differ +substantially from those moved.

+ +

LWG motion 11

+ +

This paper introduces a large amount of new text (~78 pages), and as such a +substantial quantity of editorial changes were necessary to align the moved +wording with the Working Draft's style guidelines:

+ +
    +
  • Reordered synopsis to match detailed description.
  • +
  • Significant changes to stable names, per style guide.
  • +
  • Added missing zoned_traits to <chrono> synopsis.
  • +
  • Removed redundant chrono:: qualification in synopsis.
  • +
  • [time.duration.io] Significant wording changes for comprehensibility.
  • +
  • Adjusted return type of clock_cast in synopsis to match that in detailed description.
  • +
  • Added subheadings to clock cast description, replacing line comments in the middle of the wording.
  • +
  • Adjusted specification of clock_cast to avoid awkward "at least one of [...] exactly one of" +construction and to avoid references to bullet numbers in the body text.
  • +
  • Reordered parsing and formatting sections to the end.
  • +
  • Removed descriptions for operator!=, operator>, operator<=, operator>= overloads +that are covered by [operators]
  • +
  • Removed some tutorial front-matter and design discussion from day, month, year, weekday, etc.
  • +
  • operator-(month, month), operator-(weekday, weekday): +specify returned value in Returns: element rather than +splitting the specification across Returns: and Remarks:.
  • +
  • Added subheadings for the new classes to separate member and non-member function descriptions
  • +
  • Modified time_of_day examples to include sample code producing the given output
  • +
  • Removed exposition-only members tzdb::next and tzdb_list::head_ +that are not actually used in the exposition, after consultation with LWG.
  • +
  • Modified leap-second example to not require updates each time a leap-second is added.
  • +
+ +

LWG motion 15

+ +
    +
  • Rearranged sectioning to match our normal style.
  • +
  • Removed std:: from type names in class definition.
  • +
  • Reordered member descriptions to match the style we use elsewhere.
  • +
  • Rewrote the subspan() wording to avoid deeply-nested expression and to +clarify what type is denoted by the see below in the synopsis.
  • +
+ +

Simplification of non-member swap presentation

+ +

The specification for the non-member swap function for container types has +been consolidated in the container requirements table, replacing the former +presentation which repeated the description once for each container.

+ +

This removes the subclauses +[deque.special], +[forwardlist.special], +[list.special], +[vector.special], +[map.special], +[multimap.special], +[set.special], +[multiset.special], +[unord.map.swap], +[unord.multimap.swap], +[unord.set.swap], +and +[unord.multiset.swap].

+ +

reverse_iterator subclause consolidation

+ +

reverse_iterator previously had one subclause for each member function, +in violation of our normal presentation style. These subclauses have been +merged into groups of related functionality as follows:

+ +
    +
  • [reverse.iter.op=] has been merged into [reverse.iter.cons]
  • +
  • [reverse.iter.{op==, op<, op!=, op>, op>=, op<=}] have been merged into [reverse.iter.cmp]
  • +
  • [reverse.iter.{op.star, opref, opindex}] have been merged into [reverse.iter.elem]
  • +
  • [reverse.iter.{op+, op-, op++, op+=, op--, op-=}] have been merged into [reverse.iter.nav]
  • +
  • [reverse.iter.{opdiff, opsum, make}] have been merged into [reverse.iter.nonmember]
  • +
  • [reverse.iter.ops] became empty after the above changes and has been removed.
  • +
+ +

Simplification of basic_regex constant presentation

+ +

The presentation style used for the synopsis of the basic_regex synonyms +for the std::regex_constants has been shortened by use of a typedef, and +the subclause [re.regex.const] containing redundant out-of-line descriptions +of those flags has been removed.

+ +

Cleanup of uses of the word "concept"

+ +

In the Working Draft, the word "concept" is used both in the technical sense, +denoting a C++ concept, and informally, denoting an idea or notion. We have +editorially cleaned up a few of the more confusing and ambiguous instances of +the term; most notably, Clause 6, formerly named "Basic concepts", is now +named "Basics".

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4727 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 17191eca85eebcacbc3ef37e61ee51103d892268
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 28 21:05:41 2018 +0200
+
+    [any.class] Rephrase small-object optimization
+
+commit 05675f74017966048a4db1a5c5419be357082622
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Apr 2 22:44:03 2018 +0100
+
+    [any.class, optional.optional] Add missing "namespace std" around class definitions.
+
+commit 2fcacf3f23a5fbf9cd95611342803ba536904d01
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Apr 2 13:45:41 2018 -0700
+
+    [container.node] Remove placeholder class name from subheadings.
+
+    Partially addresses #1242.
+
+commit 87ae756d027d7e611d6e89f7d3232a95b6c72203
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Apr 2 21:56:40 2018 +0200
+
+    [xrefdelta] Fixes for reverse_iterator cleanup (#2015)
+
+commit 4aa55de012f85e9f250f2c608e00a351fc9db9f1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Apr 2 13:40:32 2018 +0100
+
+    [layout] Place footnotes at the bottom of the page. (#1830)
+
+    This uses a feature introduced by memoir 3.7e, '\feetatbottom',
+    which makes footnotes appear at the bottom of the page, rather
+    than immediately following the main text.
+
+commit 5b5d225156372b717d84e0137ab759626a8886f4
+Author: Hubert Tong <hstong@ca.ibm.com>
+Date:   Mon Apr 2 00:29:33 2018 -0400
+
+    [temp.concept]: Use note; no syntax for explicit specialization, etc.
+
+    Explicit specialization, etc. of a concept cannot be formed
+    syntactically. As such, a further rule to prevent such constructs is
+    redundant as normative text.
+
+    Implements the proposed direction from core/2017/07/2719.
+
+commit bec67956e817d7edd02bdbffe5b1254113102928
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Apr 1 20:11:03 2018 -0700
+
+    [over.match.best] Use new "rewritten candidates" terminology to simplify
+    wording.
+
+commit 51684d21aa98c6cf20a44274f38ffd07b191e2f2
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 26 18:53:28 2018 -0700
+
+    [over.match.oper] Refactor the <=> rewrite candidate rules for clarity.
+
+commit e0a88df11e5cf0988b40dd65218d7ce9f456c763
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 11:15:42 2018 +0200
+
+    [ostream.manip,time] Replace "can not" with "cannot"
+
+commit 6c9e27dab526298771cdbf1a8dacf165f6547ead
+Author: Tony Van Eerd <tvaneerd@gmail.com>
+Date:   Sun Apr 1 22:14:59 2018 -0400
+
+    [sequence.reqmts] Convert advice on container selection into a note.
+
+    Also separate out the advice for std::array from that for std::vector and emphasize the main message.
+
+commit 7e4b556f44c47c70c4d1e93c5b3c82b01a949326
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 24 19:42:20 2018 +0100
+
+    [implimits] Clarify meaning of implementation limits
+
+commit b1c4c87a7ca880e4d2e46cb9b62517e940ef0339
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Feb 20 22:55:17 2018 +0100
+
+    [lib] Replace 'requirements of FrobMunchable'
+
+    with 'FrobMunchable requirements'.
+
+commit 2a1d53b1820a460066ae374a95529c7def2dda16
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Feb 20 22:27:27 2018 +0100
+
+    [lib] Use table references for CamelCase requirements.
+
+commit dbeb68f0dd7bb8fd950f33a94409b9d5ba778729
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Feb 19 22:44:54 2018 +0100
+
+    [lib] Use "shall satisfy", not "shall meet", for requirements.
+
+commit 8738c6b38db45d06724e4a75afd2134d3f6e6f3f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 23 21:27:11 2018 +0100
+
+    [containers] Removed redundant specifications of non-member swap
+
+commit 4d3434c2c9ed41c31925172948ff81166f623f64
+Author: eus <eus@member.fsf.org>
+Date:   Mon Apr 2 03:41:11 2018 +0200
+
+    [expr.ass] Clarify description of simple assignment
+
+    Replace vague "value of the expression" wording with more-precise "result of the right operand".
+
+commit 1b4da01c47fcf7522fa3df0d8c0b96ed840f4103
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Mar 18 17:56:14 2018 +0100
+
+    [associative.reqmts] Turn emphasis into a note.
+
+commit 1a9fd49cdf58d6dfe8da51dcad93ce8f73f144e0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Feb 19 18:37:49 2018 +0100
+
+    [expr.dynamic.cast] Remove redundant statements on casting away constness
+
+commit 73bfbf2d8a40822779dfdd544f5112fd2096a7d9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Feb 17 11:26:07 2018 +0100
+
+    [stmt.while] Generalize the equivalence for a declaration as the condition.
+
+commit 1d50d2d2d2b39dda529bbfe26d5f144a8ec3eee0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 15 22:02:06 2018 +0100
+
+    [over.match.oper] Add a note for conversions on synthesized candidates.
+
+commit 63dd5c67b22fb48d79e86028ea0564a3d02ffd7f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Apr 1 17:31:39 2018 -0700
+
+    [utility] Convert hanging paragraph into [utility.syn] introduction.
+
+    For #1771.
+
+commit eb4d1fec2fc26285b9586e2ace2c289167934811
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Feb 13 22:36:16 2018 +0100
+
+    'floating type' is not a defined term in C++
+
+commit 4b5d9adaaff8b2bf09f1a5a88e8875347adb6714
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 16 00:48:48 2017 +0100
+
+    [unique.ptr] Remove definition of 'transfers ownership'.
+
+    It is mostly subsumed by the detailed descriptions of the move
+    constructors and assignment operators.
+
+commit a257a072efe2b6f2fe2dbdc5529b14315b08fbd8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 28 10:08:02 2018 +0100
+
+    [dcl.spec.auto] Use of undeduced placeholder types
+
+    As discussed for CWG 2285, variables declared with a
+    placeholder type should never reference itself in the
+    initializer.  Similarly, clarify the treatment of
+    deduced function return types.
+
+commit 27d7912784f9a092b1c5263aeb6d80838d04eac6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 28 23:49:26 2018 +0100
+
+    [std] Review cross-references to [expr.prim]
+
+    Cross-references to [expr.prim] should instead point to one
+    of its subclauses.
+
+commit a7fc1b661981367e3976053420488e99e22f79af
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Mar 25 16:31:20 2018 +0200
+
+    [lib] Avoid 'shall' and 'should' in footnotes.
+
+commit 340eac6a322c3f70734f506c627237fe58ef9e22
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Sat Mar 31 15:55:36 2018 -0400
+
+    [ostream.manip] Fix typo where "basic_osyncbuf" should be "basic_syncbuf" (#2004)
+
+commit ff08270c5411ac37c32b7c1161c1ff906b7d324e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 31 21:13:57 2018 +0200
+
+    [span.elem] Fix misplaced colon (#2007)
+
+commit e7479664be7bacd829a31b8302c5a9f38efb6313
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 31 18:12:01 2018 +0200
+
+    [reverse.iterators] Dissolve single-item subclauses. (#1832)
+
+commit 6209ca1f73c66cf19c50e558546d1c9e537ba253
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 31 16:39:28 2018 +0200
+
+    [locale] Remove class name repeated in subheadings (#1932)
+
+commit 296a41539c6e2b8b16f6c706d7d2185f7ef7f255
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 31 16:39:02 2018 +0200
+
+    [containers] Remove class name repeated in subheadings (#1933)
+
+commit 31d6168980ef064112d1ad5498635fa9ca07bc65
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 31 01:35:57 2018 +0200
+
+    [expr.rel] Clarify auxiliary partial ordering (#1977)
+
+commit 720b0695962cf4b37d9e0c204131d8d38a4b04de
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 31 01:32:28 2018 +0200
+
+    Remove uses of 'concept' with ordinary English meaning. (#1918)
+
+commit 10bcbb745f0783dfefddab24755c36022c3df798
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Mar 21 14:17:30 2018 +0000
+
+    [sequences] Add exposition-only alias template for deduction guides.
+
+commit 3fca4f451709b90435d3f84ffe5d7b13763cf58d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Mar 21 14:01:31 2018 +0000
+
+    [associative], [unord] Use \placeholder for deduction guide alias templates.
+
+    Also rename iter_val_t to iter-mapped-type and then add iter-value-type for value_type.
+
+    Fixes #1523
+
+commit 174bec6cf075f5234bebdba8361ebb477bb7a84a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 31 00:35:05 2018 +0200
+
+    [utilities] Move chars_format bitmask statement to [charconv.syn] (#1992)
+
+commit 22ad3d732bb6f1692693f778bf75d06e5cf8a545
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 24 18:46:59 2018 +0100
+
+    [lib] \xref may refer to standards other than C
+
+commit 013c6e02583ab0ca723b21be4e4832ec450b4ba3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 31 00:14:20 2018 +0200
+
+    Index all mentions of 'implementation-dependent' (#1967)
+
+commit d17c6071d4f1db70b6335b3636150c8266e7d25d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 31 00:11:54 2018 +0200
+
+    Typeset ordinals as "i^\text{th}" instead of "i-th" (#2003)
+
+commit 3b582e7e19277a8b5a8bb94eab848704a734ef29
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 23:38:52 2018 +0200
+
+    [ios.base] Disambiguate names to distinguish parameters from static data members (#1969)
+
+commit cba9d3374881202621385e70323940780cb1f39b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 23:35:41 2018 +0200
+
+    [support.types.byteops] Move 'Remarks' to after 'Effects' (#1973)
+
+commit ea4048f5899f9136820240aed2703a4762547552
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 23:32:59 2018 +0200
+
+    [time.duration.nonmember] Replace type designator "CR" with its definition (#1985)
+
+commit 131dfa601c0ad1d53124079ee8142ffcbd825490
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 23:30:46 2018 +0200
+
+    [conv.fctptr, special] Pointers to members designate their target (#1968)
+
+commit 47a27a8432016c86d3a20b0600524f0331531761
+Author: FrankHB <frankhb1989@gmail.com>
+Date:   Sat Mar 31 05:09:20 2018 +0800
+
+    [over.best.ics] Fix capitalization of "conversion" in p6 (#1987)
+
+    To avoid confusion, occurrence of "derived-to-base conversion" should not be with capital letter "C", which implies the name of a conversion category. The rank is already specified at the end of the paragraph.
+
+commit 4143715f45af009dd98ffef02e8e1c695048e324
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 23:04:05 2018 +0200
+
+    CWG2345 [stmt.stmt, stmt.dcl] Jumping across initializers in init-statements and conditions (#1949)
+
+commit 42e35cf1d7a0b8084c310a4ca8ee02a3aeb127df
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 22:59:29 2018 +0200
+
+    [dcl.fct.def.delete] Adjust 'onlydouble' example. (#1950)
+
+commit cc5becb7e47b6f7bc53d3ad68bcfd3f0b8087025
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 22:57:35 2018 +0200
+
+    [temp.spec] Fix cross-reference to one-definition rule. (#1980)
+
+commit 174c44e85b419eaedf3f1d97409be889c5d72b17
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 17:15:42 2018 +0200
+
+    [temp.local] Fix example not to name the constructor. (#1981)
+
+commit 9355f5dd3ecf1186f139d16629f180f327ca9e59
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 17:13:19 2018 +0200
+
+    [re.regex] Avoid duplicate list of constants (#1984)
+
+    Shorten the synopsis and remove [re.regex.const].
+
+commit 9c74ada42d85359d1ef83e78de359fc07de7c0db
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 17:05:55 2018 +0200
+
+    [class.temporary] Repair example (#1944)
+
+commit 035bd47dcb5e72b7471892a0fe005ea4daa5ece8
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Mar 30 17:03:42 2018 +0200
+
+    Remove [facets.examples]. (#1957)
+
+commit dcf7f0514bf02092910788911a52e287d23594ef
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Fri Mar 30 16:01:50 2018 +0100
+
+    [error.reporting] Change \rSec3 to \rSec2 (#1954)
+
+    Fixes #1953
+
+commit 1fe02a2c9ff79d1eb0bbe8c3732ef4a5814751c8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 16:59:48 2018 +0200
+
+    [access] Remove inappropriate uses of \term (#1940)
+
+commit 031d2bd4729b39be85822cecd7ca340985a8963e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 16:57:50 2018 +0200
+
+    [intro.abstract] Change example for unspecified behavior. (#1930)
+
+commit feb53073b17f9b14787f7aa0d92fa4dde2b5c62e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 30 16:54:26 2018 +0200
+
+    [insert.iterators] Dissolve single-item subclauses. (#1924)
+
+commit 69ce701c5b37508fcc21b2396476b7f53252dfde
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Mar 29 01:48:06 2018 +0100
+
+    [views.span] Editorial review fixes:
+
+      * [span.sub] Refactor the specification of subspan() slightly to define the return type precisely. Note that when Extent is not dynamic, then Extent and size() are the same, so we can say "size()" in both cases unconditionally.
+
+      * Introduce new heading "Overview [span.overview]" to remove hanging paragraphs in [views.span].
+
+      * Rephrase "Extent < dynamic_extent" to "Extent is negative and not equal to dynamic_extent" to avoid unnecessary dependency on details of dynamic_extent.
+
+commit 88d223ccf2aa7d822fc1db6c14719c215816acf6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 29 17:47:29 2018 -0700
+
+    [ostream.manip] Rephrase references to exposition-only variable "buf",
+    and add "Calls" to Effects: clause to match our style guide.
+
+commit e1e43280e84f438edd331a8e5142c1a0760d8cf4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 26 15:21:35 2018 -0700
+
+    Add normative references to ISO 8601 and RFC 6557, referenced
+    normatively by P0355R7.
+
+    Fixes #1971.
+
+commit 35b73d1ce73e0dae89adae4966eea3197dfc6123
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 26 18:10:25 2018 -0700
+
+    [temp.variadic] Clarify what the elements of pack expansions are.
+
+    Also some minor wording cleanups: strike a stray "identifier" and
+    make paragraph 3 properly parallel to paragraphs 1 and 2.
+
+commit 13f4e960592e662a275ddcc7be1bc7bc6e00bfa8
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 26 17:39:24 2018 -0700
+
+    [temp.res] Convert note to footnote to avoid breaking up flow,
+    add back introductory sentence for the template validity rule,
+    and fix formatting of example.
+
+commit dec138c4f884ff6bc348da80bc7983da0a95455c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Mar 17 18:06:07 2018 -0400
+
+    [temp.res] Clarify that we're talking about the declarator-id of
+    the function or function template, not that of the
+    parameter-declaration.
+
+commit 9192d658321ebf900a1c3c52931cbf04a15b5b2f
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Mon Mar 26 18:57:26 2018 -0700
+
+    [diff] Replace "as the following example illustrates" with "For example" for consistency.
+
+commit 0ad3281f3deb677f939311d3464f1155d6fc3fcc
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Mon Mar 26 18:50:58 2018 -0700
+
+    [diff] Be consistent in formatting and add introductions to examples.
+
+commit 7066a903c55cffe1ca8ba8318b83b1376ed1c2b8
+Author: Richard Smith <richard-github@metafoo.co.uk>
+Date:   Fri Mar 16 22:00:59 2018 -0400
+
+    [expr.reinterpret.cast] Clarify that pointer->int type restriction looks at the type not the pointer value.
+
+    We were imprecise in what we meant by "large enough to hold it", but the intent is clear.
+
+commit 359cc0cbece331e02787b5efd6eee4b3f0906920
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Feb 19 18:44:11 2018 +0100
+
+    [dcl.dcl] Change example for static_assert (#1923)
+
+commit 5a98cbfbf989151425261cb4a982c4b0b26f1a7d
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri Feb 16 09:29:00 2018 -0800
+
+    [fs.path.nonmember] Fix pluralization/possessive (#1929)
+
+commit a82582e97b4e4abaed32ea8fbe383b61562fc913
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 15 23:59:05 2018 +0100
+
+    [string.classes] Remove class name repeated in subheadings (#1928)
+
+commit 4f11b39e4a9b55b5cc74ae8ced01122796aa0b6a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 14 22:58:16 2018 +0100
+
+    [depr.str.strstreams] Add synopsis for <strstream> header (#1922)
+
diff --git a/papers/n4740.md b/papers/n4740.md new file mode 100644 index 0000000000..3b0c2a834f --- /dev/null +++ b/papers/n4740.md @@ -0,0 +1,710 @@ +# N4740 Editors' Report -- Programming Languages -- C++ + +2018-04-02 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Special thanks to +Jens Maurer +for performing many of the editorial fixes since N4727. + +Thanks to Walter E Brown and Peter Sommerlad for +supplying LaTeX sources for their papers +[P0551R3](http://wg21.link/p0551r3) (LWG motion 13) +and +[P0753R2](http://wg21.link/p0753r2) (LWG motion 14). + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4741](http://wg21.link/n4741) is the current working draft for C++20. It replaces [N4727](http://wg21.link/n4727). + * N4740 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p0968r0) for 17 issue in "tentatively ready" status applied: + + * [1893](http://wg21.link/cwg1893) Function-style cast with *braced-init-list*s and empty pack expansions + * [1910](http://wg21.link/cwg1910) "Shall" requirement applied to runtime behavior + * [1983](http://wg21.link/cwg1983) Inappropriate use of *virt-specifier* + * [2059](http://wg21.link/cwg2059) Linkage and deduced return types + * [2081](http://wg21.link/cwg2081) Deduced return type in redeclaration or specialization of function template + * [2088](http://wg21.link/cwg2088) Late tiebreakers in partial ordering + * [2092](http://wg21.link/cwg2092) Deduction failure and overload resolution + * [2164](http://wg21.link/cwg2164) Name hiding and *using-directives* + * [2226](http://wg21.link/cwg2226) Xvalues vs lvalues in conditional expressions + * [2227](http://wg21.link/cwg2227) Destructor access and default member initializers + * [2229](http://wg21.link/cwg2229) Volatile unnamed bit-fields + * [2234](http://wg21.link/cwg2234) Missing rules for *simple-template-id* as *class-name* + * [2235](http://wg21.link/cwg2235) Partial ordering and non-dependent types + * [2237](http://wg21.link/cwg2237) Can a *template-id* name a constructor? + * [2255](http://wg21.link/cwg2255) Instantiated static data member templates + * [2260](http://wg21.link/cwg2260) Explicit specializations of deleted member functions + * [2299](http://wg21.link/cwg2299) `constexpr` vararg functions + +CWG motion 2: [P0840R2 "Language support for empty objects"](http://wg21.link/p0840r2) + +CWG motion 3: [P0962R1 "Relaxing the range-for customization point finding rules"](http://wg21.link/p0962r1) + +CWG motion 4: [P0969R0 "Allow structured bindings to accessible members"](http://wg21.link/p0969r0) + +CWG motion 5: [P0961R1 "Relaxing the structured bindings customization point finding rules"](http://wg21.link/p0961r1) + +CWG motion 6: [P0634R3 "Down with `typename`!"](http://wg21.link/p0634r3) + +CWG motion 7: [P0780R2 "Allow pack expansion in lambda *init-capture*"](http://wg21.link/p0780r2) + +CWG motion 8: [P0479R5 "`likely` and `unlikely` attributes"](http://wg21.link/p0479r5) + +CWG motion 9: [P0905R1 "Symmetry for spaceship"](http://wg21.link/p0905r1) **with wording changes, see below** + +CWG motions 10 and 11 apply to the Coroutines TS. + +### Library working group motions + +LWG motions 1 and 2 apply to the Parallelism TS. + +LWG motion 3 applies to the Reflection TS. + +LWG motion 4 applies to the Coroutines TS. + +LWG motion 5 applies to the Networking TS. + +LWG motion 6 applies to the Library Fundamentals TS. + +LWG motion 7: [Library issue resolutions](http://wg21.link/p0888r0) for 29 issues in "Ready" or "Tentatively Ready" status applied: + + * [2164](http://wg21.link/lwg2164) What are the semantics of `vector.emplace(vector.begin(), vector.back())`? + * [2243](http://wg21.link/lwg2243) `istream::putback` problem + * [2816](http://wg21.link/lwg2816) `resize_file` has impossible postcondition + * [2843](http://wg21.link/lwg2843) Unclear behavior of `std::pmr::memory_resource::do_allocate()` + * [2849](http://wg21.link/lwg2849) Why does `!is_regular_file(from)` cause `copy_file` to report a "file already exists" error? + * [2851](http://wg21.link/lwg2851) `std::filesystem` enum classes are now underspecified + * [2969](http://wg21.link/lwg2969) `polymorphic_allocator::construct()` shouldn't pass `resource()` + * [2975](http://wg21.link/lwg2975) Missing case for `pair` construction in scoped and polymorphic allocators + * [2989](http://wg21.link/lwg2989) `path`'s stream insertion operator lets you insert everything under the sun + * [3000](http://wg21.link/lwg3000) `monotonic_memory_resource::do_is_equal` uses `dynamic_cast` unnecessarily + * [3004](http://wg21.link/lwg3004) [string.capacity] and [vector.capacity] should specify time complexity for `capacity()` + * [3005](http://wg21.link/lwg3005) Destruction order of arrays by `make_shared`/`allocate_shared` only recommended? + * [3007](http://wg21.link/lwg3007) `allocate_shared` should rebind allocator to cv-unqualified `value_type` for construction + * [3009](http://wg21.link/lwg3009) Including `` doesn't provide `std::size/empty/data` + * [3013](http://wg21.link/lwg3013) (`recursive_`)`directory_iterator` construction and traversal should not be `noexcept` + * [3014](http://wg21.link/lwg3014) More `noexcept` issues with filesystem operations + * [3015](http://wg21.link/lwg3015) `copy_options::unspecified` underspecified + * [3017](http://wg21.link/lwg3017) `list` `splice` functions should use `addressof` + * [3026](http://wg21.link/lwg3026) `filesystem::weakly_canonical` still defined in terms of `canonical(p, base)` + * [3030](http://wg21.link/lwg3030) Who shall meet the requirements of `try_lock`? + * [3034](http://wg21.link/lwg3034) [P0767R1](http://wg21.link/p0767r1) breaks previously-standard-layout types + * [3035](http://wg21.link/lwg3035) `std::allocator`'s constructors should be `constexpr` + * [3039](http://wg21.link/lwg3039) Unnecessary `decay` in `thread` and `packaged_task` + * [3041](http://wg21.link/lwg3041) Unnecessary `decay` in `reference_wrapper` + * [3042](http://wg21.link/lwg3042) `is_literal_type_v` should be `inline` + * [3043](http://wg21.link/lwg3043) Bogus postcondition for `filesystem_error` constructor + * [3045](http://wg21.link/lwg3045) `atomic<`*`floating-point`*`>` doesn't have `value_type` or `difference_type` + * [3048](http://wg21.link/lwg3048) `transform_reduce(exec, first1, last1, first2, init)` discards execution policy + * [3051](http://wg21.link/lwg3051) Floating point classifications were inadvertently changed in [P0175](http://wg21.link/p0175) + +LWG motion 8: [Library issue resolutions](http://wg21.link/p1003r0) for 2 issues in "Immediate" status applied: + + * [2946](http://wg21.link/lwg2946) [LWG 2758](http://wg21.link/lwg2758)'s resolution missed further corrections + * [3075](http://wg21.link/lwg3075) `basic_string` needs deduction guides from `basic_string_view` + +LWG motion 9: [P0754R2 "``"](http://wg21.link/p0754r2) + +LWG motion 10: [P0809R0 "Comparing unordered containers"](http://wg21.link/p0809r0), resolving 1 library issue: + + * [2831](http://wg21.link/lwg2831) Equality can be defined when `Hash` function objects have different behaviour + +LWG motion 11: [P0355R7 "Extending `chrono` to calendars and time zones"](http://wg21.link/p0355r7) **with wording changes, see below** + +LWG motion 12: [P0966R1 "`string::reserve` should not shrink"](http://wg21.link/p0966r1) + +LWG motion 13: [P0551R3 "Thou shalt not specialize `std` function templates!"](http://wg21.link/p0551r3) + +LWG motion 14: [P0753R2 "Manipulators for C++ synchronized buffered ostream"](http://wg21.link/p0753r2) + +LWG motion 15: [P0122R7 "``"](http://wg21.link/p0122r7) **with wording changes, see below** + +LWG motion 16: [P0858R0 "Constexpr iterator requirements"](http://wg21.link/p0858r0) + +## Notable editorial changes + +### CWG motion 9 + +After consultation with CWG, the wording for injecting additional `operator<=>` +candidates has been editorially reworked, introducing a named set of "rewritten +candidates" in the place of the ad-hoc additional lookups previously specified. +That change allows the wording of this motion to be expressed more directly, +but, as a consequence, the wording changes applied for this paper differ +substantially from those moved. + +### LWG motion 11 + +This paper introduces a large amount of new text (~78 pages), and as such a +substantial quantity of editorial changes were necessary to align the moved +wording with the Working Draft's style guidelines: + + * Reordered synopsis to match detailed description. + * Significant changes to stable names, per style guide. + * Added missing `zoned_traits` to `` synopsis. + * Removed redundant `chrono::` qualification in synopsis. + * [time.duration.io] Significant wording changes for comprehensibility. + * Adjusted return type of `clock_cast` in synopsis to match that in detailed description. + * Added subheadings to clock cast description, replacing line comments in the middle of the wording. + * Adjusted specification of `clock_cast` to avoid awkward "at least one of [...] exactly one of" + construction and to avoid references to bullet numbers in the body text. + * Reordered parsing and formatting sections to the end. + * Removed descriptions for `operator!=`, `operator>`, `operator<=`, `operator>=` overloads + that are covered by [operators] + * Removed some tutorial front-matter and design discussion from `day`, `month`, `year`, `weekday`, etc. + * `operator-(month, month)`, `operator-(weekday, weekday)`: + specify returned value in *Returns:* element rather than + splitting the specification across *Returns:* and *Remarks:*. + * Added subheadings for the new classes to separate member and non-member function descriptions + * Modified `time_of_day` examples to include sample code producing the given output + * Removed exposition-only members `tzdb::next` and `tzdb_list::head_` + that are not actually used in the exposition, after consultation with LWG. + * Modified leap-second example to not require updates each time a leap-second is added. + +### LWG motion 15 + + * Rearranged sectioning to match our normal style. + * Removed `std::` from type names in class definition. + * Reordered member descriptions to match the style we use elsewhere. + * Rewrote the `subspan()` wording to avoid deeply-nested expression and to + clarify what type is denoted by the *see below* in the synopsis. + +### Simplification of non-member `swap` presentation + +The specification for the non-member `swap` function for container types has +been consolidated in the container requirements table, replacing the former +presentation which repeated the description once for each container. + +This removes the subclauses +[deque.special], +[forwardlist.special], +[list.special], +[vector.special], +[map.special], +[multimap.special], +[set.special], +[multiset.special], +[unord.map.swap], +[unord.multimap.swap], +[unord.set.swap], +and +[unord.multiset.swap]. + +### `reverse_iterator` subclause consolidation + +`reverse_iterator` previously had one subclause for each member function, +in violation of our normal presentation style. These subclauses have been +merged into groups of related functionality as follows: + + * [reverse.iter.op=] has been merged into [reverse.iter.cons] + * [reverse.iter.{op==, op<, op!=, op>, op>=, op<=}] have been merged into [reverse.iter.cmp] + * [reverse.iter.{op.star, opref, opindex}] have been merged into [reverse.iter.elem] + * [reverse.iter.{op+, op-, op++, op+=, op--, op-=}] have been merged into [reverse.iter.nav] + * [reverse.iter.{opdiff, opsum, make}] have been merged into [reverse.iter.nonmember] + * [reverse.iter.ops] became empty after the above changes and has been removed. + +### Simplification of `basic_regex` constant presentation + +The presentation style used for the synopsis of the `basic_regex` synonyms +for the `std::regex_constants` has been shortened by use of a typedef, and +the subclause [re.regex.const] containing redundant out-of-line descriptions +of those flags has been removed. + +### Cleanup of uses of the word "concept" + +In the Working Draft, the word "concept" is used both in the technical sense, +denoting a C++ concept, and informally, denoting an idea or notion. We have +editorially cleaned up a few of the more confusing and ambiguous instances of +the term; most notably, Clause 6, formerly named "Basic concepts", is now +named "Basics". + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4727 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/n4727...n4741). + + commit 17191eca85eebcacbc3ef37e61ee51103d892268 + Author: Jens Maurer + Date: Wed Mar 28 21:05:41 2018 +0200 + + [any.class] Rephrase small-object optimization + + commit 05675f74017966048a4db1a5c5419be357082622 + Author: Thomas Köppe + Date: Mon Apr 2 22:44:03 2018 +0100 + + [any.class, optional.optional] Add missing "namespace std" around class definitions. + + commit 2fcacf3f23a5fbf9cd95611342803ba536904d01 + Author: Richard Smith + Date: Mon Apr 2 13:45:41 2018 -0700 + + [container.node] Remove placeholder class name from subheadings. + + Partially addresses #1242. + + commit 87ae756d027d7e611d6e89f7d3232a95b6c72203 + Author: Jens Maurer + Date: Mon Apr 2 21:56:40 2018 +0200 + + [xrefdelta] Fixes for reverse_iterator cleanup (#2015) + + commit 4aa55de012f85e9f250f2c608e00a351fc9db9f1 + Author: Thomas Köppe + Date: Mon Apr 2 13:40:32 2018 +0100 + + [layout] Place footnotes at the bottom of the page. (#1830) + + This uses a feature introduced by memoir 3.7e, '\feetatbottom', + which makes footnotes appear at the bottom of the page, rather + than immediately following the main text. + + commit 5b5d225156372b717d84e0137ab759626a8886f4 + Author: Hubert Tong + Date: Mon Apr 2 00:29:33 2018 -0400 + + [temp.concept]: Use note; no syntax for explicit specialization, etc. + + Explicit specialization, etc. of a concept cannot be formed + syntactically. As such, a further rule to prevent such constructs is + redundant as normative text. + + Implements the proposed direction from core/2017/07/2719. + + commit bec67956e817d7edd02bdbffe5b1254113102928 + Author: Richard Smith + Date: Sun Apr 1 20:11:03 2018 -0700 + + [over.match.best] Use new "rewritten candidates" terminology to simplify + wording. + + commit 51684d21aa98c6cf20a44274f38ffd07b191e2f2 + Author: Richard Smith + Date: Mon Mar 26 18:53:28 2018 -0700 + + [over.match.oper] Refactor the <=> rewrite candidate rules for clarity. + + commit e0a88df11e5cf0988b40dd65218d7ce9f456c763 + Author: Jens Maurer + Date: Fri Mar 30 11:15:42 2018 +0200 + + [ostream.manip,time] Replace "can not" with "cannot" + + commit 6c9e27dab526298771cdbf1a8dacf165f6547ead + Author: Tony Van Eerd + Date: Sun Apr 1 22:14:59 2018 -0400 + + [sequence.reqmts] Convert advice on container selection into a note. + + Also separate out the advice for std::array from that for std::vector and emphasize the main message. + + commit 7e4b556f44c47c70c4d1e93c5b3c82b01a949326 + Author: Jens Maurer + Date: Sat Mar 24 19:42:20 2018 +0100 + + [implimits] Clarify meaning of implementation limits + + commit b1c4c87a7ca880e4d2e46cb9b62517e940ef0339 + Author: Jens Maurer + Date: Tue Feb 20 22:55:17 2018 +0100 + + [lib] Replace 'requirements of FrobMunchable' + + with 'FrobMunchable requirements'. + + commit 2a1d53b1820a460066ae374a95529c7def2dda16 + Author: Jens Maurer + Date: Tue Feb 20 22:27:27 2018 +0100 + + [lib] Use table references for CamelCase requirements. + + commit dbeb68f0dd7bb8fd950f33a94409b9d5ba778729 + Author: Jens Maurer + Date: Mon Feb 19 22:44:54 2018 +0100 + + [lib] Use "shall satisfy", not "shall meet", for requirements. + + commit 8738c6b38db45d06724e4a75afd2134d3f6e6f3f + Author: Jens Maurer + Date: Fri Mar 23 21:27:11 2018 +0100 + + [containers] Removed redundant specifications of non-member swap + + commit 4d3434c2c9ed41c31925172948ff81166f623f64 + Author: eus + Date: Mon Apr 2 03:41:11 2018 +0200 + + [expr.ass] Clarify description of simple assignment + + Replace vague "value of the expression" wording with more-precise "result of the right operand". + + commit 1b4da01c47fcf7522fa3df0d8c0b96ed840f4103 + Author: Jens Maurer + Date: Sun Mar 18 17:56:14 2018 +0100 + + [associative.reqmts] Turn emphasis into a note. + + commit 1a9fd49cdf58d6dfe8da51dcad93ce8f73f144e0 + Author: Jens Maurer + Date: Mon Feb 19 18:37:49 2018 +0100 + + [expr.dynamic.cast] Remove redundant statements on casting away constness + + commit 73bfbf2d8a40822779dfdd544f5112fd2096a7d9 + Author: Jens Maurer + Date: Sat Feb 17 11:26:07 2018 +0100 + + [stmt.while] Generalize the equivalence for a declaration as the condition. + + commit 1d50d2d2d2b39dda529bbfe26d5f144a8ec3eee0 + Author: Jens Maurer + Date: Thu Feb 15 22:02:06 2018 +0100 + + [over.match.oper] Add a note for conversions on synthesized candidates. + + commit 63dd5c67b22fb48d79e86028ea0564a3d02ffd7f + Author: Richard Smith + Date: Sun Apr 1 17:31:39 2018 -0700 + + [utility] Convert hanging paragraph into [utility.syn] introduction. + + For #1771. + + commit eb4d1fec2fc26285b9586e2ace2c289167934811 + Author: Jens Maurer + Date: Tue Feb 13 22:36:16 2018 +0100 + + 'floating type' is not a defined term in C++ + + commit 4b5d9adaaff8b2bf09f1a5a88e8875347adb6714 + Author: Jens Maurer + Date: Thu Nov 16 00:48:48 2017 +0100 + + [unique.ptr] Remove definition of 'transfers ownership'. + + It is mostly subsumed by the detailed descriptions of the move + constructors and assignment operators. + + commit a257a072efe2b6f2fe2dbdc5529b14315b08fbd8 + Author: Jens Maurer + Date: Wed Feb 28 10:08:02 2018 +0100 + + [dcl.spec.auto] Use of undeduced placeholder types + + As discussed for CWG 2285, variables declared with a + placeholder type should never reference itself in the + initializer. Similarly, clarify the treatment of + deduced function return types. + + commit 27d7912784f9a092b1c5263aeb6d80838d04eac6 + Author: Jens Maurer + Date: Wed Feb 28 23:49:26 2018 +0100 + + [std] Review cross-references to [expr.prim] + + Cross-references to [expr.prim] should instead point to one + of its subclauses. + + commit a7fc1b661981367e3976053420488e99e22f79af + Author: Jens Maurer + Date: Sun Mar 25 16:31:20 2018 +0200 + + [lib] Avoid 'shall' and 'should' in footnotes. + + commit 340eac6a322c3f70734f506c627237fe58ef9e22 + Author: timsong-cpp + Date: Sat Mar 31 15:55:36 2018 -0400 + + [ostream.manip] Fix typo where "basic_osyncbuf" should be "basic_syncbuf" (#2004) + + commit ff08270c5411ac37c32b7c1161c1ff906b7d324e + Author: Jens Maurer + Date: Sat Mar 31 21:13:57 2018 +0200 + + [span.elem] Fix misplaced colon (#2007) + + commit e7479664be7bacd829a31b8302c5a9f38efb6313 + Author: Jens Maurer + Date: Sat Mar 31 18:12:01 2018 +0200 + + [reverse.iterators] Dissolve single-item subclauses. (#1832) + + commit 6209ca1f73c66cf19c50e558546d1c9e537ba253 + Author: Jens Maurer + Date: Sat Mar 31 16:39:28 2018 +0200 + + [locale] Remove class name repeated in subheadings (#1932) + + commit 296a41539c6e2b8b16f6c706d7d2185f7ef7f255 + Author: Jens Maurer + Date: Sat Mar 31 16:39:02 2018 +0200 + + [containers] Remove class name repeated in subheadings (#1933) + + commit 31d6168980ef064112d1ad5498635fa9ca07bc65 + Author: Jens Maurer + Date: Sat Mar 31 01:35:57 2018 +0200 + + [expr.rel] Clarify auxiliary partial ordering (#1977) + + commit 720b0695962cf4b37d9e0c204131d8d38a4b04de + Author: Jens Maurer + Date: Sat Mar 31 01:32:28 2018 +0200 + + Remove uses of 'concept' with ordinary English meaning. (#1918) + + commit 10bcbb745f0783dfefddab24755c36022c3df798 + Author: Jonathan Wakely + Date: Wed Mar 21 14:17:30 2018 +0000 + + [sequences] Add exposition-only alias template for deduction guides. + + commit 3fca4f451709b90435d3f84ffe5d7b13763cf58d + Author: Jonathan Wakely + Date: Wed Mar 21 14:01:31 2018 +0000 + + [associative], [unord] Use \placeholder for deduction guide alias templates. + + Also rename iter_val_t to iter-mapped-type and then add iter-value-type for value_type. + + Fixes #1523 + + commit 174bec6cf075f5234bebdba8361ebb477bb7a84a + Author: Jens Maurer + Date: Sat Mar 31 00:35:05 2018 +0200 + + [utilities] Move chars_format bitmask statement to [charconv.syn] (#1992) + + commit 22ad3d732bb6f1692693f778bf75d06e5cf8a545 + Author: Jens Maurer + Date: Sat Mar 24 18:46:59 2018 +0100 + + [lib] \xref may refer to standards other than C + + commit 013c6e02583ab0ca723b21be4e4832ec450b4ba3 + Author: Jens Maurer + Date: Sat Mar 31 00:14:20 2018 +0200 + + Index all mentions of 'implementation-dependent' (#1967) + + commit d17c6071d4f1db70b6335b3636150c8266e7d25d + Author: Jens Maurer + Date: Sat Mar 31 00:11:54 2018 +0200 + + Typeset ordinals as "i^\text{th}" instead of "i-th" (#2003) + + commit 3b582e7e19277a8b5a8bb94eab848704a734ef29 + Author: Jens Maurer + Date: Fri Mar 30 23:38:52 2018 +0200 + + [ios.base] Disambiguate names to distinguish parameters from static data members (#1969) + + commit cba9d3374881202621385e70323940780cb1f39b + Author: Jens Maurer + Date: Fri Mar 30 23:35:41 2018 +0200 + + [support.types.byteops] Move 'Remarks' to after 'Effects' (#1973) + + commit ea4048f5899f9136820240aed2703a4762547552 + Author: Jens Maurer + Date: Fri Mar 30 23:32:59 2018 +0200 + + [time.duration.nonmember] Replace type designator "CR" with its definition (#1985) + + commit 131dfa601c0ad1d53124079ee8142ffcbd825490 + Author: Jens Maurer + Date: Fri Mar 30 23:30:46 2018 +0200 + + [conv.fctptr, special] Pointers to members designate their target (#1968) + + commit 47a27a8432016c86d3a20b0600524f0331531761 + Author: FrankHB + Date: Sat Mar 31 05:09:20 2018 +0800 + + [over.best.ics] Fix capitalization of "conversion" in p6 (#1987) + + To avoid confusion, occurrence of "derived-to-base conversion" should not be with capital letter "C", which implies the name of a conversion category. The rank is already specified at the end of the paragraph. + + commit 4143715f45af009dd98ffef02e8e1c695048e324 + Author: Jens Maurer + Date: Fri Mar 30 23:04:05 2018 +0200 + + CWG2345 [stmt.stmt, stmt.dcl] Jumping across initializers in init-statements and conditions (#1949) + + commit 42e35cf1d7a0b8084c310a4ca8ee02a3aeb127df + Author: Jens Maurer + Date: Fri Mar 30 22:59:29 2018 +0200 + + [dcl.fct.def.delete] Adjust 'onlydouble' example. (#1950) + + commit cc5becb7e47b6f7bc53d3ad68bcfd3f0b8087025 + Author: Jens Maurer + Date: Fri Mar 30 22:57:35 2018 +0200 + + [temp.spec] Fix cross-reference to one-definition rule. (#1980) + + commit 174c44e85b419eaedf3f1d97409be889c5d72b17 + Author: Jens Maurer + Date: Fri Mar 30 17:15:42 2018 +0200 + + [temp.local] Fix example not to name the constructor. (#1981) + + commit 9355f5dd3ecf1186f139d16629f180f327ca9e59 + Author: Jens Maurer + Date: Fri Mar 30 17:13:19 2018 +0200 + + [re.regex] Avoid duplicate list of constants (#1984) + + Shorten the synopsis and remove [re.regex.const]. + + commit 9c74ada42d85359d1ef83e78de359fc07de7c0db + Author: Jens Maurer + Date: Fri Mar 30 17:05:55 2018 +0200 + + [class.temporary] Repair example (#1944) + + commit 035bd47dcb5e72b7471892a0fe005ea4daa5ece8 + Author: Eelis + Date: Fri Mar 30 17:03:42 2018 +0200 + + Remove [facets.examples]. (#1957) + + commit dcf7f0514bf02092910788911a52e287d23594ef + Author: Jonathan Wakely + Date: Fri Mar 30 16:01:50 2018 +0100 + + [error.reporting] Change \rSec3 to \rSec2 (#1954) + + Fixes #1953 + + commit 1fe02a2c9ff79d1eb0bbe8c3732ef4a5814751c8 + Author: Jens Maurer + Date: Fri Mar 30 16:59:48 2018 +0200 + + [access] Remove inappropriate uses of \term (#1940) + + commit 031d2bd4729b39be85822cecd7ca340985a8963e + Author: Jens Maurer + Date: Fri Mar 30 16:57:50 2018 +0200 + + [intro.abstract] Change example for unspecified behavior. (#1930) + + commit feb53073b17f9b14787f7aa0d92fa4dde2b5c62e + Author: Jens Maurer + Date: Fri Mar 30 16:54:26 2018 +0200 + + [insert.iterators] Dissolve single-item subclauses. (#1924) + + commit 69ce701c5b37508fcc21b2396476b7f53252dfde + Author: Thomas Köppe + Date: Thu Mar 29 01:48:06 2018 +0100 + + [views.span] Editorial review fixes: + + * [span.sub] Refactor the specification of subspan() slightly to define the return type precisely. Note that when Extent is not dynamic, then Extent and size() are the same, so we can say "size()" in both cases unconditionally. + + * Introduce new heading "Overview [span.overview]" to remove hanging paragraphs in [views.span]. + + * Rephrase "Extent < dynamic_extent" to "Extent is negative and not equal to dynamic_extent" to avoid unnecessary dependency on details of dynamic_extent. + + commit 88d223ccf2aa7d822fc1db6c14719c215816acf6 + Author: Richard Smith + Date: Thu Mar 29 17:47:29 2018 -0700 + + [ostream.manip] Rephrase references to exposition-only variable "buf", + and add "Calls" to Effects: clause to match our style guide. + + commit e1e43280e84f438edd331a8e5142c1a0760d8cf4 + Author: Richard Smith + Date: Mon Mar 26 15:21:35 2018 -0700 + + Add normative references to ISO 8601 and RFC 6557, referenced + normatively by P0355R7. + + Fixes #1971. + + commit 35b73d1ce73e0dae89adae4966eea3197dfc6123 + Author: Richard Smith + Date: Mon Mar 26 18:10:25 2018 -0700 + + [temp.variadic] Clarify what the elements of pack expansions are. + + Also some minor wording cleanups: strike a stray "identifier" and + make paragraph 3 properly parallel to paragraphs 1 and 2. + + commit 13f4e960592e662a275ddcc7be1bc7bc6e00bfa8 + Author: Richard Smith + Date: Mon Mar 26 17:39:24 2018 -0700 + + [temp.res] Convert note to footnote to avoid breaking up flow, + add back introductory sentence for the template validity rule, + and fix formatting of example. + + commit dec138c4f884ff6bc348da80bc7983da0a95455c + Author: Richard Smith + Date: Sat Mar 17 18:06:07 2018 -0400 + + [temp.res] Clarify that we're talking about the declarator-id of + the function or function template, not that of the + parameter-declaration. + + commit 9192d658321ebf900a1c3c52931cbf04a15b5b2f + Author: Dawn Perchik + Date: Mon Mar 26 18:57:26 2018 -0700 + + [diff] Replace "as the following example illustrates" with "For example" for consistency. + + commit 0ad3281f3deb677f939311d3464f1155d6fc3fcc + Author: Dawn Perchik + Date: Mon Mar 26 18:50:58 2018 -0700 + + [diff] Be consistent in formatting and add introductions to examples. + + commit 7066a903c55cffe1ca8ba8318b83b1376ed1c2b8 + Author: Richard Smith + Date: Fri Mar 16 22:00:59 2018 -0400 + + [expr.reinterpret.cast] Clarify that pointer->int type restriction looks at the type not the pointer value. + + We were imprecise in what we meant by "large enough to hold it", but the intent is clear. + + commit 359cc0cbece331e02787b5efd6eee4b3f0906920 + Author: Jens Maurer + Date: Mon Feb 19 18:44:11 2018 +0100 + + [dcl.dcl] Change example for static_assert (#1923) + + commit 5a98cbfbf989151425261cb4a982c4b0b26f1a7d + Author: Casey Carter + Date: Fri Feb 16 09:29:00 2018 -0800 + + [fs.path.nonmember] Fix pluralization/possessive (#1929) + + commit a82582e97b4e4abaed32ea8fbe383b61562fc913 + Author: Jens Maurer + Date: Thu Feb 15 23:59:05 2018 +0100 + + [string.classes] Remove class name repeated in subheadings (#1928) + + commit 4f11b39e4a9b55b5cc74ae8ced01122796aa0b6a + Author: Jens Maurer + Date: Wed Feb 14 22:58:16 2018 +0100 + + [depr.str.strstreams] Add synopsis for header (#1922) diff --git a/papers/n4741.pdf b/papers/n4741.pdf new file mode 100644 index 0000000000..326a997333 Binary files /dev/null and b/papers/n4741.pdf differ diff --git a/papers/n4749.html b/papers/n4749.html new file mode 100644 index 0000000000..cfb8a5c4f6 --- /dev/null +++ b/papers/n4749.html @@ -0,0 +1,317 @@ +N4749 +

N4749 Editors' Report -- Programming Languages -- C++

+ +

2018-05-07
+Richard Smith (editor) (Google Inc)
+Dawn Perchik (co-editor) (Embarcadero Technologies Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to +Jens Maurer +for performing many of the editorial fixes since N4741.

+ +

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

+ +

New papers

+ +
    +
  • N4750 is the current C++ working draft. It replaces N4741.
  • +
  • N4749 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

This revision contains only editorial changes relative to N4741.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4741 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 dc6d80a697df0843b72fca3e2d2555311d8e6b25
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Apr 17 00:03:47 2018 +0200
+
+    [over.oper] Remove incorrect and redundant sentence in a note.
+
+commit aeddcdc6f30b8391bb5c107a1403d6be06bfd1fe
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Apr 21 01:04:19 2018 +0200
+
+    [over.match,over.match.ref] Drop obsolete mention of class prvalues.
+
+commit 067ddaa91a6c57a5ced8e13806b57dc6fa3ce2f4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Apr 28 00:22:06 2018 +0200
+
+    [over.match.copy,over.match.conv] Clarify candidate function selection for references.
+
+commit ddab7e548944a486bc7fcb34cbccaeead627d778
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Apr 17 00:12:55 2018 +0100
+
+    [numerics] Remove some maths typesetting idiosyncrasies.
+
+    * Remove several instances of manual spacing adjustments,
+      where LaTeX's default spacing works just fine and is more
+      consistent.
+    * Replace \mbox'es with more idiomatic \text.
+    * Improve grammar by adding commas before "where".
+    * Improve source code by removing pointless newline-escapes
+      and minor rearrangements.
+
+commit c35c5e3c4a7092af320b776ec27b634ac6d4b028
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Apr 3 22:51:46 2018 +0200
+
+    [dcl.array] Clarify that an array bound is deduced in an explicit type conversion
+
+commit 703381d5f9cdce46ca3532a66463066950bcd6c1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Apr 10 23:23:51 2018 +0200
+
+    [dcl.type.cv,expr.ass] Clarify the meaning of "modify" for an object.
+
+commit df1b2ba8c2035a68f1089c385c29edba64f5aec4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Apr 16 23:53:18 2018 +0200
+
+    [template.gslice.array.overview] Join two single-sentence paragraphs.
+
+commit 01a04366034ccb0c75a1c0713831cdea23e411bb
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Sat May 5 22:31:16 2018 +0300
+
+    Delete redundant and wrong example
+
+    1. Returning/casting to rvalue reference of *object type* is an xvalue. The example misses the "object type" part.
+    2. A complete and correct list of xvalue expressions is just 2 (or 3? I'm bad at counting) paragraph below. So, fixing the example is not rational, better to delete it.
+
+commit 5706664ea6e38b14d00acec1cca9955b7f734b67
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Apr 15 22:51:21 2018 +0200
+
+    [basic.lval] Add array subscripting to note enumerating xvalues.
+
+    Also add cross-references pointing to the normative statements.
+
+commit 8d5a7cef984b6ed02ed4bc6508b4c2ce864593aa
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Mon May 7 06:15:46 2018 +0300
+
+    [dcl.array]: delete note about non-modifiability of arrays (#2048)
+
+    This note doesn't mean anything and contradicts the fact that a non-const-qualified array lvalue is in fact a modifiable lvalue.
+
+commit 78af2e2abed00a650013fca9819b40e3a134cff2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Apr 24 07:35:11 2018 +0200
+
+    [dcl.array,expr.sub] Consolidate notes on symmetry of array subscripting.
+
+commit c9d19d1e584c2dec390f4e010c9c83bd581e1078
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Apr 26 12:59:00 2018 -0700
+
+    Order library comparisons canonically
+
+    The order [==, !=, <, >, <=, >=] seems to be most common. Let's make it canonical and use it uniformly.
+
+commit 78a00260352f275cfe1323b55db1a3ebeb68e007
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Mon Apr 30 13:51:33 2018 +0800
+
+    [basic.scope.pdecl] Change "type-id" to "defining-type-id"
+
+    ... now that _alias-declaration_ uses the _defining-type-id_ nonterminal.
+
+commit 6242d7291cf379a63ec5d4cb65af0d6c2c2273ec
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Apr 30 15:35:42 2018 +0100
+
+    [algorithms.parallel.defns] Fix cross-reference to [algorithms.requirements]
+
+    When [algorithms.general] was split into three subclauses (#1230) the
+    requirements moved to a new subclause, [algorithms.requirements]. That
+    invalidated the cross-reference in [algorithms.parallel.defns].
+
+commit 2062b7f49bd1b87d741a6fb753a7be5b50f3662b
+Author: Gabriel Aubut-Lussier <dalzhim@hotmail.com>
+Date:   Tue May 1 02:17:45 2018 -0400
+
+    [class.dtor] Typo.
+
+commit e22fff1b8d8bffcb3fbf54ffa4730ccad94bd5e1
+Author: Tristan Brindle <t.c.brindle@gmail.com>
+Date:   Fri May 4 19:59:09 2018 +0100
+
+    [span.overview] Fix typo (#2059)
+
+    nnamespace -> namespace
+
+commit 06013de0d00e66204253d2f682b4b879f7686540
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Apr 15 22:51:21 2018 +0200
+
+    [pairs.pair] Missed rename from U,V to U1,U2. (#2037)
+
+commit b92f0912c948b9f39e7e1c28580573c734eb21ae
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Fri Apr 13 18:32:07 2018 -0400
+
+    [time.syn][time.zone] Various editorial fixes (#2028)
+
+commit 1f1b97852aa23f0948511f56b7c0a39d04fe35e5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Apr 9 00:09:28 2018 +0200
+
+    [template.slice.array] Harmonize presentation with neighboring parallel statements (#2024)
+
+commit 8c50cba4d55450575a8faa24173f08cd16dfb46e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Apr 6 00:49:18 2018 +0200
+
+    Clarify which kind of parameter pack is intended. (#2020)
+
+commit c9e60abd503039d881f2d56eb0d10ed4cd555566
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Apr 5 21:42:55 2018 +0100
+
+    [template.gslice.array.overview] [template.mask.array.overview] [template.indirect.array.overview] Remove misplaced uses of itemdescr
+
+commit 6d886642cd163af40ae8c5ec4f98f44acfe405f6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Apr 4 12:50:59 2018 +0200
+
+    [time.syn] Add comments pointing to specification of literal operators (#2018)
+
diff --git a/papers/n4749.md b/papers/n4749.md new file mode 100644 index 0000000000..ebf180c17b --- /dev/null +++ b/papers/n4749.md @@ -0,0 +1,191 @@ +# N4749 Editors' Report -- Programming Languages -- C++ + +2018-05-07 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Embarcadero Technologies Inc) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Special thanks to +Jens Maurer +for performing many of the editorial fixes since N4741. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4750](http://wg21.link/n4750) is the current C++ working draft. It replaces [N4741](http://wg21.link/n4741). + * N4749 is this Editors' Report. + +## Motions incorporated into working draft + +This revision contains only editorial changes relative to N4741. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4741 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/n4741...n4750). + + commit dc6d80a697df0843b72fca3e2d2555311d8e6b25 + Author: Jens Maurer + Date: Tue Apr 17 00:03:47 2018 +0200 + + [over.oper] Remove incorrect and redundant sentence in a note. + + commit aeddcdc6f30b8391bb5c107a1403d6be06bfd1fe + Author: Jens Maurer + Date: Sat Apr 21 01:04:19 2018 +0200 + + [over.match,over.match.ref] Drop obsolete mention of class prvalues. + + commit 067ddaa91a6c57a5ced8e13806b57dc6fa3ce2f4 + Author: Jens Maurer + Date: Sat Apr 28 00:22:06 2018 +0200 + + [over.match.copy,over.match.conv] Clarify candidate function selection for references. + + commit ddab7e548944a486bc7fcb34cbccaeead627d778 + Author: Thomas Köppe + Date: Tue Apr 17 00:12:55 2018 +0100 + + [numerics] Remove some maths typesetting idiosyncrasies. + + * Remove several instances of manual spacing adjustments, + where LaTeX's default spacing works just fine and is more + consistent. + * Replace \mbox'es with more idiomatic \text. + * Improve grammar by adding commas before "where". + * Improve source code by removing pointless newline-escapes + and minor rearrangements. + + commit c35c5e3c4a7092af320b776ec27b634ac6d4b028 + Author: Jens Maurer + Date: Tue Apr 3 22:51:46 2018 +0200 + + [dcl.array] Clarify that an array bound is deduced in an explicit type conversion + + commit 703381d5f9cdce46ca3532a66463066950bcd6c1 + Author: Jens Maurer + Date: Tue Apr 10 23:23:51 2018 +0200 + + [dcl.type.cv,expr.ass] Clarify the meaning of "modify" for an object. + + commit df1b2ba8c2035a68f1089c385c29edba64f5aec4 + Author: Jens Maurer + Date: Mon Apr 16 23:53:18 2018 +0200 + + [template.gslice.array.overview] Join two single-sentence paragraphs. + + commit 01a04366034ccb0c75a1c0713831cdea23e411bb + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Sat May 5 22:31:16 2018 +0300 + + Delete redundant and wrong example + + 1. Returning/casting to rvalue reference of *object type* is an xvalue. The example misses the "object type" part. + 2. A complete and correct list of xvalue expressions is just 2 (or 3? I'm bad at counting) paragraph below. So, fixing the example is not rational, better to delete it. + + commit 5706664ea6e38b14d00acec1cca9955b7f734b67 + Author: Jens Maurer + Date: Sun Apr 15 22:51:21 2018 +0200 + + [basic.lval] Add array subscripting to note enumerating xvalues. + + Also add cross-references pointing to the normative statements. + + commit 8d5a7cef984b6ed02ed4bc6508b4c2ce864593aa + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Mon May 7 06:15:46 2018 +0300 + + [dcl.array]: delete note about non-modifiability of arrays (#2048) + + This note doesn't mean anything and contradicts the fact that a non-const-qualified array lvalue is in fact a modifiable lvalue. + + commit 78af2e2abed00a650013fca9819b40e3a134cff2 + Author: Jens Maurer + Date: Tue Apr 24 07:35:11 2018 +0200 + + [dcl.array,expr.sub] Consolidate notes on symmetry of array subscripting. + + commit c9d19d1e584c2dec390f4e010c9c83bd581e1078 + Author: Casey Carter + Date: Thu Apr 26 12:59:00 2018 -0700 + + Order library comparisons canonically + + The order [==, !=, <, >, <=, >=] seems to be most common. Let's make it canonical and use it uniformly. + + commit 78a00260352f275cfe1323b55db1a3ebeb68e007 + Author: S. B. Tam + Date: Mon Apr 30 13:51:33 2018 +0800 + + [basic.scope.pdecl] Change "type-id" to "defining-type-id" + + ... now that _alias-declaration_ uses the _defining-type-id_ nonterminal. + + commit 6242d7291cf379a63ec5d4cb65af0d6c2c2273ec + Author: Jonathan Wakely + Date: Mon Apr 30 15:35:42 2018 +0100 + + [algorithms.parallel.defns] Fix cross-reference to [algorithms.requirements] + + When [algorithms.general] was split into three subclauses (#1230) the + requirements moved to a new subclause, [algorithms.requirements]. That + invalidated the cross-reference in [algorithms.parallel.defns]. + + commit 2062b7f49bd1b87d741a6fb753a7be5b50f3662b + Author: Gabriel Aubut-Lussier + Date: Tue May 1 02:17:45 2018 -0400 + + [class.dtor] Typo. + + commit e22fff1b8d8bffcb3fbf54ffa4730ccad94bd5e1 + Author: Tristan Brindle + Date: Fri May 4 19:59:09 2018 +0100 + + [span.overview] Fix typo (#2059) + + nnamespace -> namespace + + commit 06013de0d00e66204253d2f682b4b879f7686540 + Author: Jens Maurer + Date: Sun Apr 15 22:51:21 2018 +0200 + + [pairs.pair] Missed rename from U,V to U1,U2. (#2037) + + commit b92f0912c948b9f39e7e1c28580573c734eb21ae + Author: timsong-cpp + Date: Fri Apr 13 18:32:07 2018 -0400 + + [time.syn][time.zone] Various editorial fixes (#2028) + + commit 1f1b97852aa23f0948511f56b7c0a39d04fe35e5 + Author: Jens Maurer + Date: Mon Apr 9 00:09:28 2018 +0200 + + [template.slice.array] Harmonize presentation with neighboring parallel statements (#2024) + + commit 8c50cba4d55450575a8faa24173f08cd16dfb46e + Author: Jens Maurer + Date: Fri Apr 6 00:49:18 2018 +0200 + + Clarify which kind of parameter pack is intended. (#2020) + + commit c9e60abd503039d881f2d56eb0d10ed4cd555566 + Author: Jonathan Wakely + Date: Thu Apr 5 21:42:55 2018 +0100 + + [template.gslice.array.overview] [template.mask.array.overview] [template.indirect.array.overview] Remove misplaced uses of itemdescr + + commit 6d886642cd163af40ae8c5ec4f98f44acfe405f6 + Author: Jens Maurer + Date: Wed Apr 4 12:50:59 2018 +0200 + + [time.syn] Add comments pointing to specification of literal operators (#2018) diff --git a/papers/n4750.pdf b/papers/n4750.pdf new file mode 100644 index 0000000000..f7150e7d9d Binary files /dev/null and b/papers/n4750.pdf differ diff --git a/papers/n4762.pdf b/papers/n4762.pdf new file mode 100644 index 0000000000..4b0f08275e Binary files /dev/null and b/papers/n4762.pdf differ diff --git a/papers/n4764.html b/papers/n4764.html new file mode 100644 index 0000000000..97f0d1a0dd --- /dev/null +++ b/papers/n4764.html @@ -0,0 +1,1350 @@ +N4764 +

N4764 Editors' Report -- Programming Languages -- C++

+ +

2018-07-07
+Richard Smith (editor) (Google Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+Jens Maurer (co-editor)
+Dawn Perchik (co-editor) (Bright Side Computing, LLC)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to Casey Carter for supplying a pull request to merge +P0898R3 (LWG motion 28), +and working with us on editorial cleanups within the +12 pages of added text.

+ +

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

+ +

New papers

+ +
    +
  • N4762 is the current working draft for C++20. It replaces N4750.
  • +
  • N4764 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolutions for 6 issues in "ready" status applied:

+ +
    +
  • 2254 Standard-layout classes and bit-fields
  • +
  • 2293 Requirements for simple-template-id used as a class-name
  • +
  • 2294 Dependent auto static data members
  • +
  • 2321 Conditional operator and cv-qualified class prvalues
  • +
  • 2322 Substitution failure and lexical order
  • +
  • 2339 Underspecified template arguments in structured bindings
  • +
+ +

CWG motion 2: Core issue resolutions for 6 issues in "tentatively ready" status applied:

+ +
    +
  • 2233 Function parameter packs following default arguments
  • +
  • 2249 identifiers and id-expressions
  • +
  • 2285 Issues with structured bindings
  • +
  • 2351 void{}
  • +
  • 2356 Base class copy and move constructors should not be inherited
  • +
  • 2359 Unintended copy initialization with designated initializers (not a DR)
  • +
+ +

CWG motion 3: P0806R2 "Deprecate implicit capture of this via [=]"

+ +

CWG motion 4: P1042R1 "__VA_OPT__ wording clarifications"

+ +

CWG motion 5: P0929R2 "Checking for abstract class types" applied, resolving 2 core issues:

+ +
    +
  • 1640 Array of abstract instance of class template
  • +
  • 1646 decltype-specifiers, abstract classes, and deduction failure
  • +
+ +

CWG motion 6: P0732R2 "Class types in non-type template parameters"

+ +

CWG motion 7 was not approved

+ +

CWG motion 8: P1025R1 "Update the reference to the Unicode standard"

+ +

CWG motion 9: P0528R3 "The curious case of padding bits, featuring atomic compare-and-exchange"

+ +

CWG motion 10: P0722R3 "Efficient sized delete for variable sized classes"

+ +

CWG motion 11: P1064R0 "Allowing virtual function calls in constant expressions"

+ +

CWG motion 12: P1008R1 "Prohibit aggregates with user-declared constructors"

+ +

CWG motion 13: P1120R0 "Consistency improvements for <=> and other comparison operators"

+ +

CWG motion 14: P0542R5 "Contract-based programming" see below

+ +

CWG motion 15: P0941R2 "Feature-test macros" see below

+ +

CWG motion 16: P0892R2 "explicit(bool)"

+ +

Library working group motions

+ +

LWG motions 1-5 apply to the Parallelism TS

+ +

LWG motions 6 and 7 apply to the Reflection TS

+ +

LWG motions 8 and 9 apply to the Coroutines TS

+ +

LWG motion 10 applies to the Networking TS

+ +

LWG motion 11: Library issue resolutions for 14 issues in "Ready" and "Tentatively Ready" status applied:

+ +
    +
  • 2139 What is a user-defined type? see below
  • +
  • 2970 Return type of std::visit misspecified
  • +
  • 3058 Parallel adjacent_difference shouldn't require creating temporaries
  • +
  • 3062 Unnecessary decay_t in is_execution_policy_v should be remove_cvref_t
  • +
  • 3067 recursive_directory_iterator::pop must invalidate
  • +
  • 3074 Non-member functions for valarray should only deduce from the valarray
  • +
  • 3076 basic_string CTAD ambiguity
  • +
  • 3079 LWG 2935 forgot to fix the existing_p overloads of create_directory
  • +
  • 3080 Floating point from_chars pattern specification breaks round-tripping
  • +
  • 3083 What should ios::iword(-1) do?
  • +
  • 3094 [time.duration.io]p4 makes surprising claims about encoding
  • +
  • 3100 Unnecessary and confusing "empty span" wording
  • +
  • 3102 Clarify span iterator and const_iterator behavior
  • +
  • 3104 Fixing duration division
  • +
  • Resolution of 3071 (read_until still refers to +"input sequence") from P1082R0 was not part of this motion, as it applies to +the Networking TS.
  • +
+ +

LWG motion 12: Library issue resolution for 1 issue applied:

+ +
    +
  • 2511 Guaranteed copy elision for piecewise construction
  • +
+ +

LWG motion 13: P0476R2 "Bit-casting object representations"

+ +

LWG motion 14: P0788R3 "Standard library specification in a concepts and contracts world"

+ +

LWG motion 15 was not approved

+ +

LWG motion 16: P0458R2 "Checking for existence of an element in associative containers"

+ +

LWG motion 17: P0759R1 "fpos requirements"

+ +

LWG motion 18: P1023R0 "constexpr comparison operators for std::array"

+ +

LWG motion 19: P0769R2 "Add shift to <algorithm>"

+ +

LWG motion 20: P0887R1 "The identity metafunction"

+ +

LWG motion 21: P0879R0 "constexpr for swap and swap-related functions" applied, resolving 1 issue:

+ +
    +
  • 2800 constexpr swap
  • +
+ +

LWG motion 22: P0758R1 "Implicit conversion traits and utility functions"

+ +

LWG motion 23: P0556R3 "Integral power-of-2 operations"

+ +

LWG motion 24: P0019R8 "atomic_ref"

+ +

LWG motion 25: P0935R0 "Eradicating unnecessarily explicit default constructors from the standard library"

+ +

LWG motion 26: P0646R1 "Improving the return value of erase-like algorithms"

+ +

LWG motion 27: P0619R4 "Reviewing deprecated facilities of C++17 for C++20" see below

+ +

LWG motion 28: P0898R3 "Standard library concepts" see below

+ +

Notable editorial changes

+ +

CWG motion 14

+ +

Subclause structure and paragraph order of [dcl.attr.contracts] was reworked. +Several normatively-redundant statements were converted to notes or removed.

+ +

CWG motion 15

+ +

Multiple papers moved at this meeting included suggested feature-test macros. +However, these were not presented as editing instructions, because we did not +have feature-test macros in the standard wording yet. After consultation with +CWG and LWG, the following feature test macros have been added in addition to +those listed in CWG motion 15 (all with value 201806L):

+ +
    +
  • __has_cpp_attribute(assert)
  • +
  • __has_cpp_attribute(ensures)
  • +
  • __has_cpp_attribute(expects)
  • +
  • __cpp_explicit_bool
  • +
  • __cpp_nontype_template_parameter_class
  • +
  • __cpp_lib_atomic_ref
  • +
  • __cpp_lib_bit_cast
  • +
  • __cpp_lib_concepts
  • +
  • __cpp_lib_constexpr_swap_algorithms
  • +
  • __cpp_lib_list_remove_return_type
  • +
+ +

CWG motions 16 and 12

+ +

CWG motion 16 would have us change wording that was deleted by CWG motion 12. +The requested change in CWG motion 16 (from teletype "explicit" to body font "explicit") +was ignored.

+ +

LWG motion 11: issue 2139

+ +

The underlying text has changed between the drafting of the resolution to this +issue and its application. We believe every requested edit has been applied; +however, an additional use of "user-defined type" has been added to +[namespace.std] that should likely also have been covered by this wording. +It has not been changed.

+ +

LWG motions 13 and 23

+ +

These motions both introduce a <bit> header, but the organizational structure +suggested by motion 23 doesn't make sense for the functionality +added by motion 13. +The wording of motion 23 has been rearranged to fit into +the structure established by motion 13.

+ +

LWG motions 16

+ +

Added the new contains member function for associative containers to the list +of member function templates that do not participate in overload resolution +unless the comparator is transparent, after consultation with LWG.

+ +

LWG motions 19 and 21

+ +

LWG motion 19 adds a shift_right algorithm to <algorithm> +as a non-constexpr function template.

+ +

LWG motion 21 instructs that we mark +all non-parallel algorithms in <algorithm> +as constexpr. +Naturally, however, +its proposed wording change does not list the shift_right algorithm. +After consultation with LWG, shift_right has been marked constexpr +to satisfy the intent of LWG motion 21.

+ +

LWG motion 27

+ +

Synopses for +<ccomplex>, +<cstdalign>, +<cstdbool>, and +<ctgmath> +were not removed; +instead, they have been repurposed as synopses for +<complex.h>, +<stdalign.h>, +<stdbool.h>, and +<tgmath.h>. +(The latter used to be defined in terms of the former, +but can no longer be specified in that way.) +Also introduced a synopsis for <iso646.h>.

+ +

LWG motion 28

+ +

Clause labels shortened and simplified throughout.

+ +

The single-item clauses [concept.movable], [concept.copyable], +[concept.semiregular], and [concept.regular] have been merged into their +parent, [concepts.object].

+ +

The single-item clauses [concept.signed.int] and [concept.unsigned.int] +have been merged into their parent, [concept.integral].

+ +

Legacy concept names changed from Cpp98Something to Cpp17Something. Many of +these concepts did not exist in C++98 (which in any case was revoked and +replaced by C++03).

+ +

Reworked "uniform random bit generator" requirements to describe them in terms +of the UniformRandomBitGenerator concept.

+ +

Removed "there need be no subsumption relationship" wording that is already +implied by the core language rules for concepts.

+ +

Editorial paper P1076R1 "Clause reorganization"

+ +

The claue reorganization described in P1076R1 and discussed at the WG21 +Rapperswil meeting has been applied to the working draft, with the following +modifications:

+ +

[class.copy] was left containing only two paragraphs of text, neither of which +had any normative impact. It has been removed.

+ +

The top-level subclauses of [algorithms] have been reordered to make the +description of the <numeric> header fit better into its structure.

+ +

Several paragraphs of [class] describing various properties of classes have +been moved into a new subclause [class.prop] "Properties of clases".

+ +

Removal of single-item subclauses

+ +

The single-item subclauses +[move.iter.op=] and +[move.iter.op.const] +have been merged into [move.iter.cons].

+ +

The single-item subclauses +[move.iter.op.star], +[move.iter.op.ref], and +[move.iter.op.index] +have been merged into [move.iter.elem].

+ +

The single-item subclauses +[move.iter.op.+], +[move.iter.op.-], +[move.iter.op.incr], +[move.iter.op.+=], +[move.iter.op.decr], and +[move.iter.op.-=] +have been merged into [move.iter.nav].

+ +

The now-empty [move.iter.ops] has been removed.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4750 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 afe115acc28e33e48e2ece9f850820d6faa51757
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jul 6 10:47:19 2018 +0200
+
+    [class] Introduce a subheading 'Properties of classes'.
+
+commit d3f80a4a994a66cc8148a6031d29182aad4f16f6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jul 7 00:49:56 2018 +0200
+
+    [namespace.udecl] Demote normative duplication to notes (#1976)
+
+    The effects of using-declarations naming member functions
+    are discussed in other parts of the standard.
+    The effects of initializing with an inherited constructor are
+    discussed elsewhere, too.
+
+commit 9459c137f138f903d670e6689b3963f0a3f7d083
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jul 6 10:40:09 2018 +0200
+
+    [time.point,time.duration] Remove class name repeated in subheadings (#2249)
+
+commit 56c599f71e8a9cfe77233e5dcd77ccfe72d81af8
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 5 20:22:47 2018 -0700
+
+    [algorithm.syn] Reorder after [algorithms.requirements] and
+    [algorithms.parallel], which apply to both <algorithm> and <numeric>.
+
+commit 8806777151719da531aae976c46f98c485bf0580
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 4 08:39:53 2018 +0200
+
+    [algorithms] Integrate requirements from [numeric.ops].
+
+commit e8d3d7029c5be1494016bc03e0004d0e9eeaa8cd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 4 08:25:30 2018 +0200
+
+    Remove [class.copy] and adjust cross-references pointing there.
+
+    The normative statements that used to be contained in
+    [class.copy] were redundant with [dcl.init] and [over.ass].
+
+commit 006fb15de62c93b6e3de3d32648f276c9ec70181
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 4 00:29:28 2018 +0200
+
+    [class.derived,class.access,special] Move into [class], as appropriate.
+
+    P1076R1: Editorial clause reorganization
+
+commit 3c580cd204fde95a21de1830ace75d14d429f845
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 4 00:07:05 2018 +0200
+
+    [dcl.decl] Move into [dcl.dcl] as appropriate.
+
+    P1076R1: Editorial clause reorganization
+
+commit 40907944b775e4da980b69565dcbaa4bd494d347
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 4 00:00:51 2018 +0200
+
+    [namespace.udecl] Move one level up
+
+    P1076R1: Editorial clause reorganization
+
+commit f87c7fd1d9a258d043b7b22fb13ce6bdf6931a28
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 3 23:54:36 2018 +0200
+
+    [numeric.ops] Move into [algorithms], after [alg.sorting]
+
+    P1076R1: Editorial clause reorganization
+
+commit 40719643c5f237aecf0136a001cce1d85ceaaf59
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 3 23:48:00 2018 +0200
+
+    [localization] Move to before [input.output]
+
+    P1076R1: Editorial clause reorganization
+
+commit a41eef0a98e9727ca85ff12c99b27209969a62b8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 3 23:37:46 2018 +0200
+
+    [time.general] Add summary table
+
+commit 63603768789149c9b46bac7e810ddfb618e8eefe
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 3 23:30:45 2018 +0200
+
+    [time] Promote to a top-level clause.
+
+    P1076R1: Editorial clause reorganization
+
+commit 006a9380cfe9e00bcee9b03884b3b4bf57bf6fa2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 3 23:22:05 2018 +0200
+
+    [conv] Move as a subclause into [expr], immediately before [expr.arith.conv]
+
+    P1076R1: Editorial clause reorganization
+
+commit 70adb738f6edbc0697d1f26c72040d6b3a971421
+Author: Hubert Tong <hubert-reinterpretcast@users.noreply.github.com>
+Date:   Thu Jul 5 16:22:22 2018 -0400
+
+    [intro.defs] Use https in hyperlink URL; see Directives, Part 2:2018 (#2248)
+
+commit 3fe46c716367d6e367b4c5acff344bce3f2a5cd2
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri May 11 11:53:45 2018 +0100
+
+    [class] Reformat paragraph defining standard-layout class
+
+    Move the note before the definition of M(X).
+    Use a nested list for the definition of M(X).
+    Move the example to a new paragraph.
+
+commit 0cac48775c1b1db4038cc0e456ccef81d5dd5fdc
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon Jul 2 17:13:53 2018 -0400
+
+    [concepts.{lang,compare,callable}.general] Replace "section" with "subclause".
+
+commit 9db2f62e966224e8e749913871771dd4ac886c78
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 09:08:21 2018 +0200
+
+    [basic.start,except] Harmonize references to std::terminate
+
+commit 3846e6ba6592099145655420e3b88c6c874cd5fc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 1 10:05:58 2018 +0200
+
+    [over.match.viable] Fix cross-reference to satisfaction of constraints
+
+commit 61e272c36350786e8b3fa1662efb0a8b9484cdd5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 14 11:08:25 2018 +0200
+
+    [dcl.init.ref] Avoid use of 'underlying type' for references
+
+commit c56870954b48305df89133a80e6ab8a21a0a90e9
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Jul 2 17:10:38 2018 -0400
+
+    [temp.constr.constr], [iterator.requirements.general], [re.results.size] Replace "section" with "subclause"
+
+commit f3b625826ae894613c9ec47bd4e1874fc46e71d4
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon Jul 2 17:05:50 2018 -0400
+
+    [concepts.object] Dissolve single-item subclauses. (#2240)
+
+    The following subclause headings have been removed:
+
+      [concept.movable]
+      [concept.copyable]
+      [concept.semiregular]
+      [concept.regular]
+
+    The content for these former subclauses now resides in the parent subclause, [concepts.object].
+
+commit 75c9148c3d810a825765aef9f04f9689f678f7bf
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Jun 16 15:57:32 2018 -0400
+
+    [re.general] Refer to table as done in the other clauses
+
+commit 2fdaf88fcffd65ea2ccc4e032e288c74ac94bb7d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 2 11:52:45 2018 -0700
+
+    [basic.lookup.unqual] Finesse "class definition" footnote to avoid
+    saying that a class definition is one of two components of the
+    definition of a class.
+
+commit 4d757ab4026f2b1af37ea1f3c6fb8fbd4c83f0dc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 30 00:23:57 2018 +0200
+
+    [class.mem] Define complete-class context
+
+    and use it, instead of having separate redundant lists
+    in [basic.scope.class] and [basic.lookup.unqual].
+
+commit ade8b020efbfa8fd220d1ed7f230850f2849d593
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Tue Jul 3 02:32:45 2018 +0800
+
+    [expr.prim.id.{un,}qual] A structured binding name is an lvalue (#2234)
+
+    Fix wording here to match corresponding wording in [dcl.struct.bind].
+
+commit 809a034ac0428dc71d3b07bb15c39a1131d2e3f8
+Author: Michael Adams <mdadams@ece.uvic.ca>
+Date:   Mon Jul 2 11:30:48 2018 -0700
+
+    [class.copy.elision] Fix typo that accidentally makes example ill-formed
+
+commit 61b25c662399e7ebd126ee6771126aa29fed407e
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Sat Jun 30 05:27:09 2018 -0400
+
+    [{i,o}{string,f}stream.cons] Remove unmatched parenthesis (#2233)
+
+commit 0420f57904322da8adc32890687dc914d5c06edc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jun 19 11:23:54 2018 +0200
+
+    [dcl.attr.contract] Introduce subheadings and reorder paragraphs to fit
+
+commit 492e6a79cd4b36488c248771b73b46ba54ec27a6
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Wed Jun 27 21:18:27 2018 -0400
+
+    [variant.get] Consistently place comma after "otherwise"
+
+commit 5326a0d1311682568eccd19b1f8c2512091a2a53
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 28 12:42:25 2018 +0200
+
+    [input.iterators,fs.rec.dir.itr.members] Disambiguate phrasing for previous value of iterators
+
+commit 2f5d2cbcd69c0cb63bad481f44d32082dd68ea6c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 28 23:54:24 2018 +0200
+
+    [depr.locale.stdcvt.req] Add normative references for encoding forms
+
+commit 69d7e1ffeed2187c1986f727882e65890c6dfa0f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 29 00:08:44 2018 +0200
+
+    [optional] Move requirements from header synopsis to class template
+
+commit 6116910802836c517ecde9237b6ffabcdafc26cf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 29 00:15:09 2018 +0200
+
+    [basic.fundamental] Add definition of 'fundamental type'
+
+commit b65061ee7d81079e72b2467ac9307ba9a24aaf00
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 29 13:41:11 2018 +0200
+
+    [expr.prim.lambda,depr.capture.this] Replace 'lambda expression'
+
+    with the grammar term 'lambda-expression'.
+    Also remove the unused definition of 'local lambda expression'.
+
+commit 354fa005c1b8ad55ddd1bca31bf4f8bef67db46e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 25 10:37:36 2018 +0200
+
+    [dcl.init,over.match.ctor] Clarify copy-initialization for empty arguments.
+
+    Also turn the enumeration of direct-initialization cases into
+    a bulleted list, referring to grammar non-terminals.
+
+commit 69259f9d29a571233908c4f9be5afc9b98e9a2e3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 25 01:14:17 2018 +0200
+
+    Drop redundant 'expression'
+
+    when calling out a value category.
+
+commit 09f1354234154602dee9a0afc12f0b160bf455ea
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 29 13:59:12 2018 -0700
+
+    [dcl.attr.contract] Fix mention of odr-use of a parameter value to talk
+    about odr-use of the parameter instead; values can't be odr-used.
+
+    As agreed on the core reflector.
+
+commit 45fa09c5e38057571284c3eda52aa479afa0f3cb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 29 17:38:17 2018 +0200
+
+    [temp.dep] Fix typo 'An expressions...' (#2181)
+
+commit 50a00f2776122a1328d29332f45e3ec20ee6d0fb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 29 00:53:00 2018 +0200
+
+    [lex] Cite ISO/IEC 10646 correctly (#2226)
+
+commit 6f6a5dd6de12968f447940049d7fbf447e0ccf9f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 8 13:29:32 2018 +0200
+
+    [atomics.types.operations] Avoid inappropriate use of 'underlying type'
+
+commit 35e17ec6e2f702be4c31fd99c058404223a865da
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Jun 28 12:28:20 2018 -0700
+
+    [algorithm.syn] Relocate the "partitions" algorithms (#2219)
+
+    Move the synopsis for the "partitions" algorithms between the "binary_search" family and the "merge" family, to agree with the order of the detailed specifications as reordered by #1245.
+
+commit 03e97ca6af73a842d38d40977a2630b0c978eade
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Apr 19 23:12:20 2018 +0200
+
+    [temp.arg.explicit,temp.mem] Clarify note about explicit template arguments
+
+    for conversion function templates and constructor templates.
+
+commit cdad8c27d822e5aec90b86a6e72e6f093d204924
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Apr 3 23:33:29 2018 +0200
+
+    [move.iterators] Dissolve single-item subclauses.
+
+commit 1f9524d9b2a2ec95e7b48ec82ff9782e2b79d413
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jun 27 22:42:53 2018 +0100
+
+    [support.limits.general] Fix typo: '<forwardlist>' should be '<forward_list>'
+
+commit e0d78d373e975ccbc7cd59d5b7292c48f920b959
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Wed Jun 27 17:33:20 2018 -0400
+
+    [span.overview] Fix reverse_iterator for span (#2112)
+
+    There is a common convention to omit 'std::' when not strictly needed,
+    other than for 'std::move' and 'std::forward'.  A third case is for
+    'reverse_iterator' and 'const_reverse_iterator' type aliases inside a
+    class definition, as the leading 'reverse_iterator' type alias hides
+    the 'std' version from the 'const_reverse_iterator' definition, and
+    subsequently fails to compile.  This patch restore the class definition
+    to a safely copy/pastable state.
+
+    An additional review indicated this convention has been applied correctly
+    for every othert potential occurrence in the library.
+
+commit 33e8e2b3c5c2ae9e53ed656f7e3dfe874e55ede3
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Jun 27 14:32:34 2018 -0700
+
+    [output.iterators] Strike useless sentence from note (#2083)
+
+    There's no such thing as an "insert pointer," and the rest of this sentence isn't much better.
+
+commit fe3f46b976c8c19336f0007625fe3e487827ca55
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Wed Jun 27 12:12:45 2018 -0700
+
+    Harmonize phrasings of "this destructor is trivial". (#2191)
+
+    Inspired by P0602 https://lichray.github.io/trivially_variant.html
+    Zhihao suggested that we harmonize "trivially destructible"
+    wording across the rest of the Standard.
+
+commit 14809d0b4b27395ea407734d00d0f6dc9c7b0c05
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 27 21:04:50 2018 +0200
+
+    [expr.spaceship] Fix typo for std::strong_equality::nonequal (#2216)
+
+commit 2954bfccb653504279f101cf1d8c7f9fb96947ff
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Wed Jun 27 15:03:49 2018 -0400
+
+    [diff.cpp17.depr] Fix typo from P0619R4 (#2217)
+
+    In the paper, "raw_memory_iterator" was meant to say "raw_storage_iterator".
+
+commit 264839261e3d0b0cb66415f2c1755d1f84d2cb3d
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Wed Jun 27 06:51:41 2018 -0400
+
+    [istreambuf.iterator.proxy] correct title and remove default template argument (#2078)
+
+    This is a class, not a class template. Also, the default template argument is 1) redundant and 2) ill-formed for violating [temp.param]p12.
+
+commit e6794e6f167db93a519564d5fc986309d194e140
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 27 12:49:39 2018 +0200
+
+    [syserr] Remove class name repeated in subheadings (#2093)
+
+commit f0e7cdd3392e91b427764abf1c9c30058a457143
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 27 12:49:12 2018 +0200
+
+    [smartptr] Remove class name repeated in subheadings (#2092)
+
+commit a92cdcb6ca8aa43e49a54d22f8760e9ca9cbaad7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 27 12:48:03 2018 +0200
+
+    [vector.cons] vector(const Allocator&) should be noexcept (#2182)
+
+    This fixes an oversight in the wording of
+    "N4258: Cleaning‐up noexcept in the Library",
+    which updated the overview, but not the description.
+
+commit f4a6f328137fa59bf3aa319eb4ccb743b2205dfc
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 19:06:44 2018 -0700
+
+    [alg.sorting] Fix grammar.
+
+commit de4ddf0a8fa164c7b451b6bb500c492681a7738c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 20:00:54 2018 -0700
+
+    [cpp.cond], [cpp.predefined], [support.limits.general] Add feature-test
+    macros from 2018-06 motions:
+
+    __has_cpp_attribute(assert)
+    __has_cpp_attribute(ensures)
+    __has_cpp_attribute(expects)
+    __cpp_explicit_bool
+    __cpp_nontype_template_parameter_class
+    __cpp_lib_atomic_ref
+    __cpp_lib_bit_cast
+    __cpp_lib_concepts
+    __cpp_lib_constexpr_swap_algorithms
+    __cpp_lib_list_remove_return_type
+
+    ... all with value 201806L.
+
+commit 1984951deba6caeb117300b198e349b0e9bf841c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 18:24:56 2018 -0700
+
+    [meta.type.trans] Strike redundant and confusing note on type member of
+    basic_common_reference, and replace it with a clarifying description of
+    the primary template.
+
+commit a5a086fada4312ee1794a5d2cb65a7ce5ac284d4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 17:51:24 2018 -0700
+
+    [meta.trans.other] Replace "(possibly cv) void" with just "cv void".
+
+    These two formulations mean the same thing.
+
+commit cc393db472ef7e89fa4e8bc8bcce6e44979efd5e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 17:43:51 2018 -0700
+
+    [concept.strictweakorder] Fix grammar in note.
+
+commit 01f681dd376ec6285fae0253d21745999fd9557f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 14:50:39 2018 -0700
+
+    [concept.equalitycomparable] Remove note that the equality-preserving
+    nature of == implies that == is reflexive. This turns out to not quite
+    be justified by the normative rules.
+
+commit fbc2eef266332b8dea52718640ceca7cde9d6c1f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 25 18:25:06 2018 -0700
+
+    [concept.boolean] Reword satisfaction rules for Boolean to make them not
+    appear to depend on the "given" lvalues b1 and b2.
+
+commit d324da9c1ea4702dfb2d595390114d872f29089e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 25 18:15:28 2018 -0700
+
+    [concept.destructible] Fix meaningless phrase "potentially-throwing,
+    even if non-throwing".
+
+    By definition, non-throwing is the opposite of potentially-throwing for
+    an exception-specification ([except.spec]p1).
+
+commit 4ac1f96f51c998846ce97e81c793484a52318357
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 25 17:34:27 2018 -0700
+
+    [concepts.equality] Add missing paragraph numbers, reorder implicit
+    expression variations in example for clarity and to fix overfull hbox.
+
+commit 60ae4bf7daae6802fefef5a5f32c1d2248a51334
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri Jun 22 20:28:23 2018 -0700
+
+    [concepts] There need be no "there need be no subsumption relationship"
+
+    ... the core language rules already imply it.
+
+commit 11b6f1844a7b43a232d55442f4af7f9ce20faa45
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri Jun 22 21:14:00 2018 -0700
+
+    [structure.requirements] Add paragraph explaining the typographical convention for requirement names
+
+commit bfaea046b5176152a86514a886a5b7ab66e4dffe
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Jun 20 09:39:06 2018 -0700
+
+    [rand.req.urng] Rework URBG requirements for clarity and simplicitly
+
+    ... by removing the redundance between the new concept and the "old" requirements.
+
+    Also fixup the reference in [rand.req.eng] to properly refer [rand.req.urng] instead of the requirements table. The table has been removed, and the reference should have been to the subclause in the first place to clearly incorporate the requirements outside of the table.
+
+commit def89125ccf441d2178e6159d6b9448f17045f6a
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Jun 20 11:21:43 2018 -0700
+
+    [meta.trans.other] Remove basic_common_reference requirement with no normative effect.
+
+    We already say that only T and U can be specialized. We do not need to
+    also say that TQual and UQual cannot be. Also clarify that users may
+    *partially* specialize basic_common_reference.
+
+commit 528d382ca9b350c3aece9a57e23a2560b7ba0651
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jun 19 16:31:00 2018 -0700
+
+    [meta.trans.other] Make style of common_type and common_reference consistent
+
+    ...by tagging the specification of common_reference with "Note C" and basic_common_reference "Note D".
+
+    Also remove the allowance to specialize basic_common_reference "if at least one template parameter in the specialization depends on a program-defined type"; it's redundant with "...pursuant to [namespace.std]". (This is consistent with `common_type`'s wording.)
+
+commit 2aa8b236c8afe09272fba8d0767fbc6552b301b5
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jun 19 16:06:03 2018 -0700
+
+    [structure.requirements] Rephrase para 8 for clarity
+
+commit d9c710c4f13c95d65f96d503bd45f11628fdf68a
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Jun 18 06:55:44 2018 -0700
+
+    [concepts.general][library.general] Concepts constrain template arguments, not parameters
+
+commit a818d5bfb084da10818b830d210d8bb4312912e4
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Jun 21 09:38:44 2018 -0700
+
+    [concepts.swappable] Correct example
+
+commit db9aee9ca04a192f32cd630cf3682d30c62a0bf7
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jun 19 15:34:43 2018 -0700
+
+    [customization.point.object][meta.trans.other] Replace "user-defined" added by P0898R3 with "program-defined"
+
+    ...to be consistent with the intent of LWG2139
+
+commit 03f3764a071dfe30ef1137435a88ea036ca65c1f
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Jun 20 15:16:51 2018 -0700
+
+    [definitions] Redefine expression-equivalent per ISO directives
+
+    To be replaceable in context, and add a clarifying example.
+
+commit d119277cb8864be440a6e0445211c232e87f91a7
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Jun 21 09:18:24 2018 -0700
+
+    [concepts] Rephrase ocurrences of "must"
+
+commit 16b35d651de53654321b584eba2c6c4e126eb7d8
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 18:08:26 2018 -0700
+
+    [depr.c.headers] Undo P0619R4's removal of synopses for <ccomplex>,
+    <cstdalign>, <cstdbool>, and <ctgmath>.
+
+    Instead, repurpose these to be synopses for <complex.h>, <stdalign.h>,
+    <stdbool.h>, and <tgmath.h>, and move them into [depr.c.headers].
+    Also introduce a synopsis for <iso646.h>.
+
+    This avoids three of these five headers being specified as equivalent to
+    a non-existent <cfoo> header, and the other two missing a synopsis.
+
+commit cf0749742b9318143505f9ffe2d4dabb5420d727
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 17:17:41 2018 -0700
+
+    [diff.cpp17.library] Fix description of how to adjust code for the
+    removal of <ccomplex> and <ctgmath>.
+
+commit fa04176c01dd10105eec6590407b2c76384f5c52
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 17:06:40 2018 -0700
+
+    [diff.cpp17.library] Fix list of new headers compared to C++17.
+
+commit 9e80b6c69467fb2fb146637e1f0fca8b7495250f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 16:59:45 2018 -0700
+
+    [diff.cpp17.except] Fix Rationale to be a rationale.
+
+    "This was retained for one additional C++ standard to ease transition"
+    is not a rationale for removing the feature now.
+
+commit 043ee628bc8accbe7f1ac4dc2210e88186bc95a4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 16:41:51 2018 -0700
+
+    [diff.cpp17.except] Add a note that there is no longer a way to write
+    code that is non-throwing in both C++20 and C++03.
+
+commit fd244b515387efde9fb08ffe183985a38e93d184
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 16:29:19 2018 -0700
+
+    [diff.cpp03.language.support] Remove change described in p1, which is no
+    longer a possible change.
+
+    It is not possible to write a global replacement operator new or
+    operator delete in C++20 with code that is also valid C++03, because
+
+    a) operator new must be declared 'throw(std::bad_alloc)' in C++03 and
+       must be declared with no exception specification in C++11 onwards,
+    and
+    b) operator delete must be declared 'throw()' in C++03 and must be
+       declared 'noexcept' in C++20 onwards.
+
+    Therefore there is no code that is valid in C++03 and C++20 and changes
+    meaning due to the change identified in this section.
+
+    Instead, expand [diff.cpp03.language.support]p2 to explain that the
+    affected programs are simply not valid in C++20.
+
+commit 3e80cd4c07563639a8ca55d41d704701ae6d0eb4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 16:07:09 2018 -0700
+
+    [complex.special] Reorder defaulted complex copy constructor to
+    emphasize relationship between it and the converting constructors.
+
+commit 74539419429281072e1f8b787a0ce0dc2bb067db
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jun 21 20:09:23 2018 -0700
+
+    [atomics.ref] Reword introductory sentences to avoid overfull hbox.
+
+commit 3c21cfcfa1091a406d4b384e4677f0fa0e8ea75c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jun 11 19:10:53 2018 +0200
+
+    [alg.shift] Avoid undefined iterator arithmetic on ForwardIterator.
+    Avoid using the undefined concept BidirectionalIterator.
+
+commit 949892305c88abd7c2ecb15a77bde3222366733d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jun 11 23:43:22 2018 +0100
+
+    [structure.specifications] remove "implementation-defined" from example
+    mentioning [[expects]] and add cross-reference to [[expects]] attribute.
+
+commit 23c6b62f321d463792c54db38a89b335dc232f3e
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jun 11 23:41:37 2018 +0100
+
+    [structure.specifications] replace "paragraph" with "element"
+
+commit 4aa23529058e5f17f74e663ff189a1548812e009
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jun 11 23:37:31 2018 +0100
+
+    [res.on.required] replace "paragraph" with "element"
+
+commit 3b24b2dc75bd5b80d2c5fc1cb3fdb62ac3852d8d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 19 17:13:17 2018 -0700
+
+    [diff.cpp17] Correct description of explicit(bool) compatibility.
+
+    Parenthesized names for explicit constructors and conversion functions
+    are still valid if the name doesn't immediately follow the explicit
+    keyword. Add an example using explicit(true) as a hint indicating how
+    to get the same effect.
+
+    Change affected subclauses from [dcl.fct] to the somewhat-more-precise
+    [class.ctor] and [class.conv.fct].
+
+commit 001a2011d172cce2784857a492e2c37e25ade7e9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 18 18:19:39 2018 -0700
+
+    [dcl.attr.contract] Fix typeface of std::terminate in comment.
+
+commit 913c83a98735709462a49613f8993bca4042ed70
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 17 09:18:08 2018 +0200
+
+    [dcl.attr.contract] Move according to alphabetical sorting of headings
+
+commit 463ab8dc3726514b2adf8dcf6816262f58688da3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 11:01:23 2018 +0200
+
+    [except.terminate] Clarify evaluation of a contract
+
+commit f2f60fd4c3f9810ae815a408e1fd3ac1462482c7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:53:18 2018 +0200
+
+    [temp.explicit] Remove redundant rules for contracts
+
+    given that [dcl.attr.grammar] already prohibits
+    attribute-specifier-seqs for an explicit instantiation.
+
+commit a7a0e115dbf5f149936a04f57b9dd3174c9efa6a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:51:04 2018 +0200
+
+    [class.virtual] Fix comment in example
+
+commit ca0d62cc3d8c397d843fe1e1ae4a80f8fa389587
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:42:25 2018 +0200
+
+    [dcl.attr.contract] Fix sentence defining violation handler
+
+commit 0cd3f3dc072d736b4e8572311918bdccbb91e1f7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:33:54 2018 +0200
+
+    [dcl.attr.contract] Clarify evaluation of non-checked contracts
+
+commit 2930dc55b0c5573aad90c22e1909f98bb9bec4c2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:18:18 2018 +0200
+
+    [dcl.attr.contract] Permit modifications of temporaries within the predicate.
+
+commit 87c3c20540b99708b02ce3dfc6a792a3fea454aa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:17:19 2018 +0200
+
+    [dcl.attr.contract] Clarify that assertions may apply to a null statement
+
+commit 072f42df7b298c3677b2a1e8f1a4687d1e005ffc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:10:53 2018 +0200
+
+    [dcl.attr.contract] Clarify rules on std::contract_violation
+
+commit 77579d2f9527552820dfc667867589da12adceda
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:08:09 2018 +0200
+
+    [dcl.attr.contract] Predicates of a contract are potentially evaluated,
+
+    as per the definition in [basic.def.odr], so turn the
+    redundant normative statement into a note.
+
+commit da24c5df270fc17a82b6767aef5baee94fba4a45
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 09:43:43 2018 +0200
+
+    [basic.def.odr] Rephrase ODR rule for contracts
+
+commit 0fc2af6bbe05e16feb03e8f24651ea12e8a6997c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 10 22:53:26 2018 +0200
+
+    [dcl.attr.contract] Reorder paragraphs for more coherence.
+
+    Also move rules on virtual functions to [class.virtual].
+    Rephase assertion checking along pre/postcondition checking.
+
+commit 42019fd86775859393e7e5edc7e8d4c2e64c8019
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 10 22:24:18 2018 +0200
+
+    [basic.def.odr] Rephrase build level and continuation mode requirements
+
+commit ac603143816388fa8fa12a8fb0802130b6643884
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 10 22:17:23 2018 +0200
+
+    [dcl.attr.contract] Rephrase comments in examples
+
+commit 19d07dec4cbe5ae86eb6231eb833d166c5939faf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 10 22:14:46 2018 +0200
+
+    [except.terminate] Add contract violation with continuation mode off
+
+commit f28517ab52f7bf80879a7883fe08bb97020f80da
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 10 21:17:50 2018 +0200
+
+    [dcl.attr.contract] Avoid duplication of 'renaming' in enumeration
+
+commit a8b8e534a7a5235157333f6a9f64c339e48e0e86
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 11 15:56:16 2018 -0700
+
+    [basic.stc.dynamic.deallocation] Remove confusing note.
+
+    This note is only correct due to subtleties of later wording
+    (particularly that a destroying operator delete cannot be a function
+    template). Correcting it results in it simply duplicating existing
+    normative rules and not adding anything. So remove it instead.
+
+commit e4f579e421dac17ff36f98b2211d143991de7850
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 13 09:16:17 2018 +0200
+
+    [temp.arg.nontype] Fix example involving string literal
+
+    P0732R2 contained some changes to this section that were missing
+    explicit markup; apply those changes too. Also fix missing definition of
+    operator<=> in class type used as type of non-type template parameter.
+
+commit 5cca3b5015491a6c8b5d1d63f651073940d1145e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 13 08:34:52 2018 +0200
+
+    [dcl.fct] Move function definition rule to [dcl.fct.def.general]
+
+    This is the rule that requires complete non-abstract
+    types function parameter or return types.
+
+commit b39b44b32394384edcc8f7f682274fbffd22f067
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 13 08:28:26 2018 +0200
+
+    [temp.deduct] Forming an array of abstract class type is not deduction failure
+
+commit ba6cd4c525371eb98c60a025da21e5ca813b4a94
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jun 14 21:48:23 2018 +0100
+
+    [cpp.subst] Reword paragraph to simplify the logical structure and avoid ambiguous references.
+
+commit 4ce05424a8774e13b9958eb9cb9165da5b19edb0
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 12 16:27:40 2018 -0700
+
+    [depr.capture.this] Reorder so the order of Annex D matches the order of the main text
+
+commit 628a32db863ac10fe0fb4c45d6975a50f5497acf
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 12 16:26:37 2018 -0700
+
+    [depr.capture.this] Replace "can" with "may".
+
+    This wording is describing permission, not capability, so should use "may".
+
+commit 5274b2ee4c558d39012a34d104be0d2139115c00
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jun 15 14:31:14 2018 +0100
+
+    [temp.deduct] Fixes from editorial review of CWG2293:
+
+    * Use "not valid" rather than "invalid", since only "valid" has been defined.
+    * Add an "otherwise" to improve flow.
+
+commit 0e771884acfdcb1dc693ef654f34cf717986f803
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Fri Jun 8 08:23:25 2018 +0100
+
+    [time.zone.db.remote] replace "this section" with "this subclause" (#2103)
+
+commit b9c5272c78fb312883cb548219b7fd2cb44280c7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jun 7 23:24:37 2018 +0200
+
+    [cfenv.syn] Add "optional" markers for macros from the C library that are optional (as defined by C)
+
+commit aa77121b3aa9bc566b8d2e428cd21a28493ce57e
+Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com>
+Date:   Thu Jun 7 21:39:51 2018 +0200
+
+    [dcl.attr.likelihood] Fix error in example
+
+commit fbee1d521da91a798d81ecc09f110a0946239630
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 7 21:36:42 2018 +0200
+
+    [views.general] Remove redundant introduction for span. (#2062)
+
+commit 069a179a0d54cad4b3d00f00eae532c827786894
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Mar 27 14:41:13 2018 +0200
+
+    [cmp.syn] Rename to [compare.syn] to match the header name
+
+commit 8a0060d0dcda8c63a2c432016bd038c75a8de9a1
+Author: Marc Mutz <marc.mutz@kdab.com>
+Date:   Thu Jun 7 03:34:12 2018 +0200
+
+    [list.modifiers, forward.list.modifiers] Add missing 'to' in 'referred [to] by' (#2100)
+
+commit 57de3af9d24037d60d996b255c1ded8ee65387d2
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Wed May 30 00:18:13 2018 -0700
+
+    [comparisons] Fix a typo in the note for `std::less`. (#2089)
+
+commit 61b6c21f218e3cbb9d15426975f1a26d8b72a7fe
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu May 10 14:40:22 2018 -0700
+
+    [class.expl.init] Fix example to account for guaranteed copy omission.
+
diff --git a/papers/n4764.md b/papers/n4764.md new file mode 100644 index 0000000000..d4b7fddd1a --- /dev/null +++ b/papers/n4764.md @@ -0,0 +1,1210 @@ +# N4764 Editors' Report -- Programming Languages -- C++ + +2018-07-07 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Special thanks to Casey Carter for supplying a pull request to merge +[P0898R3](http://wg21.link/p0898r3) (LWG motion 28), +and working with us on editorial cleanups within the +12 pages of added text. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4762](http://wg21.link/n4762) is the current working draft for C++20. It replaces [N4750](http://wg21.link/n4750). + * N4764 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p1113r0) for 6 issues in "ready" status applied: + + * [2254](http://wg21.link/cwg2254) Standard-layout classes and bit-fields + * [2293](http://wg21.link/cwg2293) Requirements for *simple-template-id* used as a *class-name* + * [2294](http://wg21.link/cwg2294) Dependent `auto` static data members + * [2321](http://wg21.link/cwg2321) Conditional operator and cv-qualified class prvalues + * [2322](http://wg21.link/cwg2322) Substitution failure and lexical order + * [2339](http://wg21.link/cwg2339) Underspecified template arguments in structured bindings + +CWG motion 2: [Core issue resolutions](http://wg21.link/p1114r0) for 6 issues in "tentatively ready" status applied: + + * [2233](http://wg21.link/cwg2233) Function parameter packs following default arguments + * [2249](http://wg21.link/cwg2249) *identifier*s and *id-expression*s + * [2285](http://wg21.link/cwg2285) Issues with structured bindings + * [2351](http://wg21.link/cwg2351) `void{}` + * [2356](http://wg21.link/cwg2356) Base class copy and move constructors should not be inherited + * [2359](http://wg21.link/cwg2359) Unintended copy initialization with designated initializers **(not a DR)** + +CWG motion 3: [P0806R2 "Deprecate implicit capture of `this` via `[=]`"](http://wg21.link/p0806r2) + +CWG motion 4: [P1042R1 "`__VA_OPT__` wording clarifications"](http://wg21.link/p1042r1) + +CWG motion 5: [P0929R2 "Checking for abstract class types"](http://wg21.link/p0929r2) applied, resolving 2 core issues: + + * [1640](http://wg21.link/cwg1640) Array of abstract instance of class template + * [1646](http://wg21.link/cwg1646) *decltype-specifier*s, abstract classes, and deduction failure + +CWG motion 6: [P0732R2 "Class types in non-type template parameters"](http://wg21.link/p0732r2) + +CWG motion 7 was not approved + +CWG motion 8: [P1025R1 "Update the reference to the Unicode standard"](http://wg21.link/p1025r1) + +CWG motion 9: [P0528R3 "The curious case of padding bits, featuring atomic compare-and-exchange"](http://wg21.link/p0528r3) + +CWG motion 10: [P0722R3 "Efficient sized delete for variable sized classes"](http://wg21.link/p0722r3) + +CWG motion 11: [P1064R0 "Allowing virtual function calls in constant expressions"](http://wg21.link/p1064r0) + +CWG motion 12: [P1008R1 "Prohibit aggregates with user-declared constructors"](http://wg21.link/p1008r1) + +CWG motion 13: [P1120R0 "Consistency improvements for `<=>` and other comparison operators"](http://wg21.link/p1120r0) + +CWG motion 14: [P0542R5 "Contract-based programming"](http://wg21.link/p0542r5) **see below** + +CWG motion 15: [P0941R2 "Feature-test macros"](http://wg21.link/p0941r2) **see below** + +CWG motion 16: [P0892R2 "`explicit(bool)`"](http://wg21.link/p0892r2) + +### Library working group motions + +LWG motions 1-5 apply to the Parallelism TS + +LWG motions 6 and 7 apply to the Reflection TS + +LWG motions 8 and 9 apply to the Coroutines TS + +LWG motion 10 applies to the Networking TS + +LWG motion 11: [Library issue resolutions](http://wg21.link/p1082r0) for 14 issues in "Ready" and "Tentatively Ready" status applied: + + * [2139](http://wg21.link/lwg2139) What is a user-defined type? **see below** + * [2970](http://wg21.link/lwg2970) Return type of `std::visit` misspecified + * [3058](http://wg21.link/lwg3058) Parallel `adjacent_difference` shouldn't require creating temporaries + * [3062](http://wg21.link/lwg3062) Unnecessary `decay_t` in `is_execution_policy_v` should be `remove_cvref_t` + * [3067](http://wg21.link/lwg3067) `recursive_directory_iterator::pop` must invalidate + * [3074](http://wg21.link/lwg3074) Non-member functions for `valarray` should only deduce from the `valarray` + * [3076](http://wg21.link/lwg3076) `basic_string` CTAD ambiguity + * [3079](http://wg21.link/lwg3079) [LWG 2935](http://wg21.link/lwg2935) forgot to fix the `existing_p` overloads of `create_directory` + * [3080](http://wg21.link/lwg3080) Floating point `from_chars` pattern specification breaks round-tripping + * [3083](http://wg21.link/lwg3083) What should `ios::iword(-1)` do? + * [3094](http://wg21.link/lwg3094) [time.duration.io]p4 makes surprising claims about encoding + * [3100](http://wg21.link/lwg3100) Unnecessary and confusing "empty span" wording + * [3102](http://wg21.link/lwg3102) Clarify `span` `iterator` and `const_iterator` behavior + * [3104](http://wg21.link/lwg3104) Fixing `duration` division + * Resolution of [3071](http://wg21.link/lwg3071) (`read_until` still refers to + "input sequence") from P1082R0 was not part of this motion, as it applies to + the Networking TS. + +LWG motion 12: [Library issue resolution](http://wg21.link/p0475r1) for 1 issue applied: + + * [2511](http://wg21.link/lwg2511) Guaranteed copy elision for piecewise construction + +LWG motion 13: [P0476R2 "Bit-casting object representations"](http://wg21.link/p0476r2) + +LWG motion 14: [P0788R3 "Standard library specification in a concepts and contracts world"](http://wg21.link/p0788r3) + +LWG motion 15 was not approved + +LWG motion 16: [P0458R2 "Checking for existence of an element in associative containers"](http://wg21.link/p0458r2) + +LWG motion 17: [P0759R1 "`fpos` requirements"](http://wg21.link/p0759r1) + +LWG motion 18: [P1023R0 "`constexpr` comparison operators for `std::array`"](http://wg21.link/p1023r0) + +LWG motion 19: [P0769R2 "Add `shift` to ``"](http://wg21.link/p0769r2) + +LWG motion 20: [P0887R1 "The `identity` metafunction"](http://wg21.link/p0887r1) + +LWG motion 21: [P0879R0 "`constexpr` for `swap` and `swap`-related functions"](http://wg21.link/p0879r0) applied, resolving 1 issue: + + * [2800](http://wg21.link/lwg2800) `constexpr` `swap` + +LWG motion 22: [P0758R1 "Implicit conversion traits and utility functions"](http://wg21.link/p0758r1) + +LWG motion 23: [P0556R3 "Integral power-of-2 operations"](http://wg21.link/p0556r3) + +LWG motion 24: [P0019R8 "`atomic_ref`"](http://wg21.link/p0019r8) + +LWG motion 25: [P0935R0 "Eradicating unnecessarily explicit default constructors from the standard library"](http://wg21.link/p0935r0) + +LWG motion 26: [P0646R1 "Improving the return value of `erase`-like algorithms"](http://wg21.link/p0646r1) + +LWG motion 27: [P0619R4 "Reviewing deprecated facilities of C++17 for C++20"](http://wg21.link/p0619r4) **see below** + +LWG motion 28: [P0898R3 "Standard library concepts"](http://wg21.link/p0898r3) **see below** + +## Notable editorial changes + +### CWG motion 14 + +Subclause structure and paragraph order of [dcl.attr.contracts] was reworked. +Several normatively-redundant statements were converted to notes or removed. + +### CWG motion 15 + +Multiple papers moved at this meeting included suggested feature-test macros. +However, these were not presented as editing instructions, because we did not +have feature-test macros in the standard wording yet. After consultation with +CWG and LWG, the following feature test macros have been added in addition to +those listed in CWG motion 15 (all with value `201806L`): + + * `__has_cpp_attribute(assert)` + * `__has_cpp_attribute(ensures)` + * `__has_cpp_attribute(expects)` + * `__cpp_explicit_bool` + * `__cpp_nontype_template_parameter_class` + * `__cpp_lib_atomic_ref` + * `__cpp_lib_bit_cast` + * `__cpp_lib_concepts` + * `__cpp_lib_constexpr_swap_algorithms` + * `__cpp_lib_list_remove_return_type` + +### CWG motions 16 and 12 + +CWG motion 16 would have us change wording that was deleted by CWG motion 12. +The requested change in CWG motion 16 (from teletype "`explicit`" to body font "explicit") +was ignored. + +### LWG motion 11: issue 2139 + +The underlying text has changed between the drafting of the resolution to this +issue and its application. We believe every requested edit has been applied; +however, an additional use of "user-defined type" has been added to +[namespace.std] that should likely also have been covered by this wording. +It has *not* been changed. + +### LWG motions 13 and 23 + +These motions both introduce a `` header, but the organizational structure +suggested by motion 23 doesn't make sense for the functionality +added by motion 13. +The wording of motion 23 has been rearranged to fit into +the structure established by motion 13. + +### LWG motions 16 + +Added the new `contains` member function for associative containers to the list +of member function templates that do not participate in overload resolution +unless the comparator is transparent, after consultation with LWG. + +### LWG motions 19 and 21 + +LWG motion 19 adds a `shift_right` algorithm to `` +as a non-`constexpr` function template. + +LWG motion 21 instructs that we mark +all non-parallel algorithms in `` +as `constexpr`. +Naturally, however, +its proposed wording change does not list the `shift_right` algorithm. +After consultation with LWG, `shift_right` has been marked `constexpr` +to satisfy the intent of LWG motion 21. + +### LWG motion 27 + +Synopses for +``, +``, +``, and +`` +were not removed; +instead, they have been repurposed as synopses for +``, +``, +``, and +``. +(The latter used to be defined in terms of the former, +but can no longer be specified in that way.) +Also introduced a synopsis for ``. + +### LWG motion 28 + +Clause labels shortened and simplified throughout. + +The single-item clauses [concept.movable], [concept.copyable], +[concept.semiregular], and [concept.regular] have been merged into their +parent, [concepts.object]. + +The single-item clauses [concept.signed.int] and [concept.unsigned.int] +have been merged into their parent, [concept.integral]. + +Legacy concept names changed from *Cpp98Something* to *Cpp17Something*. Many of +these concepts did not exist in C++98 (which in any case was revoked and +replaced by C++03). + +Reworked "uniform random bit generator" requirements to describe them in terms +of the `UniformRandomBitGenerator` concept. + +Removed "there need be no subsumption relationship" wording that is already +implied by the core language rules for concepts. + +### Editorial paper [P1076R1 "Clause reorganization"](http://wg21.likn/p1076r1) + +The claue reorganization described in P1076R1 and discussed at the WG21 +Rapperswil meeting has been applied to the working draft, with the following +modifications: + +[class.copy] was left containing only two paragraphs of text, neither of which +had any normative impact. It has been removed. + +The top-level subclauses of [algorithms] have been reordered to make the +description of the `` header fit better into its structure. + +Several paragraphs of [class] describing various properties of classes have +been moved into a new subclause [class.prop] "Properties of clases". + +### Removal of single-item subclauses + +The single-item subclauses +[move.iter.op=] and +[move.iter.op.const] +have been merged into [move.iter.cons]. + +The single-item subclauses +[move.iter.op.star], +[move.iter.op.ref], and +[move.iter.op.index] +have been merged into [move.iter.elem]. + +The single-item subclauses +[move.iter.op.+], +[move.iter.op.-], +[move.iter.op.incr], +[move.iter.op.+=], +[move.iter.op.decr], and +[move.iter.op.-=] +have been merged into [move.iter.nav]. + +The now-empty [move.iter.ops] has been removed. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4750 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/n4750...n4762). + + commit afe115acc28e33e48e2ece9f850820d6faa51757 + Author: Jens Maurer + Date: Fri Jul 6 10:47:19 2018 +0200 + + [class] Introduce a subheading 'Properties of classes'. + + commit d3f80a4a994a66cc8148a6031d29182aad4f16f6 + Author: Jens Maurer + Date: Sat Jul 7 00:49:56 2018 +0200 + + [namespace.udecl] Demote normative duplication to notes (#1976) + + The effects of using-declarations naming member functions + are discussed in other parts of the standard. + The effects of initializing with an inherited constructor are + discussed elsewhere, too. + + commit 9459c137f138f903d670e6689b3963f0a3f7d083 + Author: Jens Maurer + Date: Fri Jul 6 10:40:09 2018 +0200 + + [time.point,time.duration] Remove class name repeated in subheadings (#2249) + + commit 56c599f71e8a9cfe77233e5dcd77ccfe72d81af8 + Author: Richard Smith + Date: Thu Jul 5 20:22:47 2018 -0700 + + [algorithm.syn] Reorder after [algorithms.requirements] and + [algorithms.parallel], which apply to both and . + + commit 8806777151719da531aae976c46f98c485bf0580 + Author: Jens Maurer + Date: Wed Jul 4 08:39:53 2018 +0200 + + [algorithms] Integrate requirements from [numeric.ops]. + + commit e8d3d7029c5be1494016bc03e0004d0e9eeaa8cd + Author: Jens Maurer + Date: Wed Jul 4 08:25:30 2018 +0200 + + Remove [class.copy] and adjust cross-references pointing there. + + The normative statements that used to be contained in + [class.copy] were redundant with [dcl.init] and [over.ass]. + + commit 006fb15de62c93b6e3de3d32648f276c9ec70181 + Author: Jens Maurer + Date: Wed Jul 4 00:29:28 2018 +0200 + + [class.derived,class.access,special] Move into [class], as appropriate. + + P1076R1: Editorial clause reorganization + + commit 3c580cd204fde95a21de1830ace75d14d429f845 + Author: Jens Maurer + Date: Wed Jul 4 00:07:05 2018 +0200 + + [dcl.decl] Move into [dcl.dcl] as appropriate. + + P1076R1: Editorial clause reorganization + + commit 40907944b775e4da980b69565dcbaa4bd494d347 + Author: Jens Maurer + Date: Wed Jul 4 00:00:51 2018 +0200 + + [namespace.udecl] Move one level up + + P1076R1: Editorial clause reorganization + + commit f87c7fd1d9a258d043b7b22fb13ce6bdf6931a28 + Author: Jens Maurer + Date: Tue Jul 3 23:54:36 2018 +0200 + + [numeric.ops] Move into [algorithms], after [alg.sorting] + + P1076R1: Editorial clause reorganization + + commit 40719643c5f237aecf0136a001cce1d85ceaaf59 + Author: Jens Maurer + Date: Tue Jul 3 23:48:00 2018 +0200 + + [localization] Move to before [input.output] + + P1076R1: Editorial clause reorganization + + commit a41eef0a98e9727ca85ff12c99b27209969a62b8 + Author: Jens Maurer + Date: Tue Jul 3 23:37:46 2018 +0200 + + [time.general] Add summary table + + commit 63603768789149c9b46bac7e810ddfb618e8eefe + Author: Jens Maurer + Date: Tue Jul 3 23:30:45 2018 +0200 + + [time] Promote to a top-level clause. + + P1076R1: Editorial clause reorganization + + commit 006a9380cfe9e00bcee9b03884b3b4bf57bf6fa2 + Author: Jens Maurer + Date: Tue Jul 3 23:22:05 2018 +0200 + + [conv] Move as a subclause into [expr], immediately before [expr.arith.conv] + + P1076R1: Editorial clause reorganization + + commit 70adb738f6edbc0697d1f26c72040d6b3a971421 + Author: Hubert Tong + Date: Thu Jul 5 16:22:22 2018 -0400 + + [intro.defs] Use https in hyperlink URL; see Directives, Part 2:2018 (#2248) + + commit 3fe46c716367d6e367b4c5acff344bce3f2a5cd2 + Author: Jonathan Wakely + Date: Fri May 11 11:53:45 2018 +0100 + + [class] Reformat paragraph defining standard-layout class + + Move the note before the definition of M(X). + Use a nested list for the definition of M(X). + Move the example to a new paragraph. + + commit 0cac48775c1b1db4038cc0e456ccef81d5dd5fdc + Author: timsong-cpp + Date: Mon Jul 2 17:13:53 2018 -0400 + + [concepts.{lang,compare,callable}.general] Replace "section" with "subclause". + + commit 9db2f62e966224e8e749913871771dd4ac886c78 + Author: Jens Maurer + Date: Fri Jun 15 09:08:21 2018 +0200 + + [basic.start,except] Harmonize references to std::terminate + + commit 3846e6ba6592099145655420e3b88c6c874cd5fc + Author: Jens Maurer + Date: Fri Jun 1 10:05:58 2018 +0200 + + [over.match.viable] Fix cross-reference to satisfaction of constraints + + commit 61e272c36350786e8b3fa1662efb0a8b9484cdd5 + Author: Jens Maurer + Date: Thu Jun 14 11:08:25 2018 +0200 + + [dcl.init.ref] Avoid use of 'underlying type' for references + + commit c56870954b48305df89133a80e6ab8a21a0a90e9 + Author: Johel Ernesto Guerrero Peña + Date: Mon Jul 2 17:10:38 2018 -0400 + + [temp.constr.constr], [iterator.requirements.general], [re.results.size] Replace "section" with "subclause" + + commit f3b625826ae894613c9ec47bd4e1874fc46e71d4 + Author: timsong-cpp + Date: Mon Jul 2 17:05:50 2018 -0400 + + [concepts.object] Dissolve single-item subclauses. (#2240) + + The following subclause headings have been removed: + + [concept.movable] + [concept.copyable] + [concept.semiregular] + [concept.regular] + + The content for these former subclauses now resides in the parent subclause, [concepts.object]. + + commit 75c9148c3d810a825765aef9f04f9689f678f7bf + Author: Johel Ernesto Guerrero Peña + Date: Sat Jun 16 15:57:32 2018 -0400 + + [re.general] Refer to table as done in the other clauses + + commit 2fdaf88fcffd65ea2ccc4e032e288c74ac94bb7d + Author: Richard Smith + Date: Mon Jul 2 11:52:45 2018 -0700 + + [basic.lookup.unqual] Finesse "class definition" footnote to avoid + saying that a class definition is one of two components of the + definition of a class. + + commit 4d757ab4026f2b1af37ea1f3c6fb8fbd4c83f0dc + Author: Jens Maurer + Date: Sat Jun 30 00:23:57 2018 +0200 + + [class.mem] Define complete-class context + + and use it, instead of having separate redundant lists + in [basic.scope.class] and [basic.lookup.unqual]. + + commit ade8b020efbfa8fd220d1ed7f230850f2849d593 + Author: S. B. Tam + Date: Tue Jul 3 02:32:45 2018 +0800 + + [expr.prim.id.{un,}qual] A structured binding name is an lvalue (#2234) + + Fix wording here to match corresponding wording in [dcl.struct.bind]. + + commit 809a034ac0428dc71d3b07bb15c39a1131d2e3f8 + Author: Michael Adams + Date: Mon Jul 2 11:30:48 2018 -0700 + + [class.copy.elision] Fix typo that accidentally makes example ill-formed + + commit 61b25c662399e7ebd126ee6771126aa29fed407e + Author: timsong-cpp + Date: Sat Jun 30 05:27:09 2018 -0400 + + [{i,o}{string,f}stream.cons] Remove unmatched parenthesis (#2233) + + commit 0420f57904322da8adc32890687dc914d5c06edc + Author: Jens Maurer + Date: Tue Jun 19 11:23:54 2018 +0200 + + [dcl.attr.contract] Introduce subheadings and reorder paragraphs to fit + + commit 492e6a79cd4b36488c248771b73b46ba54ec27a6 + Author: Johel Ernesto Guerrero Peña + Date: Wed Jun 27 21:18:27 2018 -0400 + + [variant.get] Consistently place comma after "otherwise" + + commit 5326a0d1311682568eccd19b1f8c2512091a2a53 + Author: Jens Maurer + Date: Thu Jun 28 12:42:25 2018 +0200 + + [input.iterators,fs.rec.dir.itr.members] Disambiguate phrasing for previous value of iterators + + commit 2f5d2cbcd69c0cb63bad481f44d32082dd68ea6c + Author: Jens Maurer + Date: Thu Jun 28 23:54:24 2018 +0200 + + [depr.locale.stdcvt.req] Add normative references for encoding forms + + commit 69d7e1ffeed2187c1986f727882e65890c6dfa0f + Author: Jens Maurer + Date: Fri Jun 29 00:08:44 2018 +0200 + + [optional] Move requirements from header synopsis to class template + + commit 6116910802836c517ecde9237b6ffabcdafc26cf + Author: Jens Maurer + Date: Fri Jun 29 00:15:09 2018 +0200 + + [basic.fundamental] Add definition of 'fundamental type' + + commit b65061ee7d81079e72b2467ac9307ba9a24aaf00 + Author: Jens Maurer + Date: Fri Jun 29 13:41:11 2018 +0200 + + [expr.prim.lambda,depr.capture.this] Replace 'lambda expression' + + with the grammar term 'lambda-expression'. + Also remove the unused definition of 'local lambda expression'. + + commit 354fa005c1b8ad55ddd1bca31bf4f8bef67db46e + Author: Jens Maurer + Date: Fri May 25 10:37:36 2018 +0200 + + [dcl.init,over.match.ctor] Clarify copy-initialization for empty arguments. + + Also turn the enumeration of direct-initialization cases into + a bulleted list, referring to grammar non-terminals. + + commit 69259f9d29a571233908c4f9be5afc9b98e9a2e3 + Author: Jens Maurer + Date: Fri May 25 01:14:17 2018 +0200 + + Drop redundant 'expression' + + when calling out a value category. + + commit 09f1354234154602dee9a0afc12f0b160bf455ea + Author: Richard Smith + Date: Fri Jun 29 13:59:12 2018 -0700 + + [dcl.attr.contract] Fix mention of odr-use of a parameter value to talk + about odr-use of the parameter instead; values can't be odr-used. + + As agreed on the core reflector. + + commit 45fa09c5e38057571284c3eda52aa479afa0f3cb + Author: Jens Maurer + Date: Fri Jun 29 17:38:17 2018 +0200 + + [temp.dep] Fix typo 'An expressions...' (#2181) + + commit 50a00f2776122a1328d29332f45e3ec20ee6d0fb + Author: Jens Maurer + Date: Fri Jun 29 00:53:00 2018 +0200 + + [lex] Cite ISO/IEC 10646 correctly (#2226) + + commit 6f6a5dd6de12968f447940049d7fbf447e0ccf9f + Author: Jens Maurer + Date: Tue May 8 13:29:32 2018 +0200 + + [atomics.types.operations] Avoid inappropriate use of 'underlying type' + + commit 35e17ec6e2f702be4c31fd99c058404223a865da + Author: Casey Carter + Date: Thu Jun 28 12:28:20 2018 -0700 + + [algorithm.syn] Relocate the "partitions" algorithms (#2219) + + Move the synopsis for the "partitions" algorithms between the "binary_search" family and the "merge" family, to agree with the order of the detailed specifications as reordered by #1245. + + commit 03e97ca6af73a842d38d40977a2630b0c978eade + Author: Jens Maurer + Date: Thu Apr 19 23:12:20 2018 +0200 + + [temp.arg.explicit,temp.mem] Clarify note about explicit template arguments + + for conversion function templates and constructor templates. + + commit cdad8c27d822e5aec90b86a6e72e6f093d204924 + Author: Jens Maurer + Date: Tue Apr 3 23:33:29 2018 +0200 + + [move.iterators] Dissolve single-item subclauses. + + commit 1f9524d9b2a2ec95e7b48ec82ff9782e2b79d413 + Author: Thomas Köppe + Date: Wed Jun 27 22:42:53 2018 +0100 + + [support.limits.general] Fix typo: '' should be '' + + commit e0d78d373e975ccbc7cd59d5b7292c48f920b959 + Author: Alisdair Meredith + Date: Wed Jun 27 17:33:20 2018 -0400 + + [span.overview] Fix reverse_iterator for span (#2112) + + There is a common convention to omit 'std::' when not strictly needed, + other than for 'std::move' and 'std::forward'. A third case is for + 'reverse_iterator' and 'const_reverse_iterator' type aliases inside a + class definition, as the leading 'reverse_iterator' type alias hides + the 'std' version from the 'const_reverse_iterator' definition, and + subsequently fails to compile. This patch restore the class definition + to a safely copy/pastable state. + + An additional review indicated this convention has been applied correctly + for every othert potential occurrence in the library. + + commit 33e8e2b3c5c2ae9e53ed656f7e3dfe874e55ede3 + Author: Casey Carter + Date: Wed Jun 27 14:32:34 2018 -0700 + + [output.iterators] Strike useless sentence from note (#2083) + + There's no such thing as an "insert pointer," and the rest of this sentence isn't much better. + + commit fe3f46b976c8c19336f0007625fe3e487827ca55 + Author: Arthur O'Dwyer + Date: Wed Jun 27 12:12:45 2018 -0700 + + Harmonize phrasings of "this destructor is trivial". (#2191) + + Inspired by P0602 https://lichray.github.io/trivially_variant.html + Zhihao suggested that we harmonize "trivially destructible" + wording across the rest of the Standard. + + commit 14809d0b4b27395ea407734d00d0f6dc9c7b0c05 + Author: Jens Maurer + Date: Wed Jun 27 21:04:50 2018 +0200 + + [expr.spaceship] Fix typo for std::strong_equality::nonequal (#2216) + + commit 2954bfccb653504279f101cf1d8c7f9fb96947ff + Author: Sergey Zubkov + Date: Wed Jun 27 15:03:49 2018 -0400 + + [diff.cpp17.depr] Fix typo from P0619R4 (#2217) + + In the paper, "raw_memory_iterator" was meant to say "raw_storage_iterator". + + commit 264839261e3d0b0cb66415f2c1755d1f84d2cb3d + Author: timsong-cpp + Date: Wed Jun 27 06:51:41 2018 -0400 + + [istreambuf.iterator.proxy] correct title and remove default template argument (#2078) + + This is a class, not a class template. Also, the default template argument is 1) redundant and 2) ill-formed for violating [temp.param]p12. + + commit e6794e6f167db93a519564d5fc986309d194e140 + Author: Jens Maurer + Date: Wed Jun 27 12:49:39 2018 +0200 + + [syserr] Remove class name repeated in subheadings (#2093) + + commit f0e7cdd3392e91b427764abf1c9c30058a457143 + Author: Jens Maurer + Date: Wed Jun 27 12:49:12 2018 +0200 + + [smartptr] Remove class name repeated in subheadings (#2092) + + commit a92cdcb6ca8aa43e49a54d22f8760e9ca9cbaad7 + Author: Jens Maurer + Date: Wed Jun 27 12:48:03 2018 +0200 + + [vector.cons] vector(const Allocator&) should be noexcept (#2182) + + This fixes an oversight in the wording of + "N4258: Cleaning‐up noexcept in the Library", + which updated the overview, but not the description. + + commit f4a6f328137fa59bf3aa319eb4ccb743b2205dfc + Author: Richard Smith + Date: Tue Jun 26 19:06:44 2018 -0700 + + [alg.sorting] Fix grammar. + + commit de4ddf0a8fa164c7b451b6bb500c492681a7738c + Author: Richard Smith + Date: Tue Jun 26 20:00:54 2018 -0700 + + [cpp.cond], [cpp.predefined], [support.limits.general] Add feature-test + macros from 2018-06 motions: + + __has_cpp_attribute(assert) + __has_cpp_attribute(ensures) + __has_cpp_attribute(expects) + __cpp_explicit_bool + __cpp_nontype_template_parameter_class + __cpp_lib_atomic_ref + __cpp_lib_bit_cast + __cpp_lib_concepts + __cpp_lib_constexpr_swap_algorithms + __cpp_lib_list_remove_return_type + + ... all with value 201806L. + + commit 1984951deba6caeb117300b198e349b0e9bf841c + Author: Richard Smith + Date: Tue Jun 26 18:24:56 2018 -0700 + + [meta.type.trans] Strike redundant and confusing note on type member of + basic_common_reference, and replace it with a clarifying description of + the primary template. + + commit a5a086fada4312ee1794a5d2cb65a7ce5ac284d4 + Author: Richard Smith + Date: Tue Jun 26 17:51:24 2018 -0700 + + [meta.trans.other] Replace "(possibly cv) void" with just "cv void". + + These two formulations mean the same thing. + + commit cc393db472ef7e89fa4e8bc8bcce6e44979efd5e + Author: Richard Smith + Date: Tue Jun 26 17:43:51 2018 -0700 + + [concept.strictweakorder] Fix grammar in note. + + commit 01f681dd376ec6285fae0253d21745999fd9557f + Author: Richard Smith + Date: Tue Jun 26 14:50:39 2018 -0700 + + [concept.equalitycomparable] Remove note that the equality-preserving + nature of == implies that == is reflexive. This turns out to not quite + be justified by the normative rules. + + commit fbc2eef266332b8dea52718640ceca7cde9d6c1f + Author: Richard Smith + Date: Mon Jun 25 18:25:06 2018 -0700 + + [concept.boolean] Reword satisfaction rules for Boolean to make them not + appear to depend on the "given" lvalues b1 and b2. + + commit d324da9c1ea4702dfb2d595390114d872f29089e + Author: Richard Smith + Date: Mon Jun 25 18:15:28 2018 -0700 + + [concept.destructible] Fix meaningless phrase "potentially-throwing, + even if non-throwing". + + By definition, non-throwing is the opposite of potentially-throwing for + an exception-specification ([except.spec]p1). + + commit 4ac1f96f51c998846ce97e81c793484a52318357 + Author: Richard Smith + Date: Mon Jun 25 17:34:27 2018 -0700 + + [concepts.equality] Add missing paragraph numbers, reorder implicit + expression variations in example for clarity and to fix overfull hbox. + + commit 60ae4bf7daae6802fefef5a5f32c1d2248a51334 + Author: Casey Carter + Date: Fri Jun 22 20:28:23 2018 -0700 + + [concepts] There need be no "there need be no subsumption relationship" + + ... the core language rules already imply it. + + commit 11b6f1844a7b43a232d55442f4af7f9ce20faa45 + Author: Casey Carter + Date: Fri Jun 22 21:14:00 2018 -0700 + + [structure.requirements] Add paragraph explaining the typographical convention for requirement names + + commit bfaea046b5176152a86514a886a5b7ab66e4dffe + Author: Casey Carter + Date: Wed Jun 20 09:39:06 2018 -0700 + + [rand.req.urng] Rework URBG requirements for clarity and simplicitly + + ... by removing the redundance between the new concept and the "old" requirements. + + Also fixup the reference in [rand.req.eng] to properly refer [rand.req.urng] instead of the requirements table. The table has been removed, and the reference should have been to the subclause in the first place to clearly incorporate the requirements outside of the table. + + commit def89125ccf441d2178e6159d6b9448f17045f6a + Author: Casey Carter + Date: Wed Jun 20 11:21:43 2018 -0700 + + [meta.trans.other] Remove basic_common_reference requirement with no normative effect. + + We already say that only T and U can be specialized. We do not need to + also say that TQual and UQual cannot be. Also clarify that users may + *partially* specialize basic_common_reference. + + commit 528d382ca9b350c3aece9a57e23a2560b7ba0651 + Author: Casey Carter + Date: Tue Jun 19 16:31:00 2018 -0700 + + [meta.trans.other] Make style of common_type and common_reference consistent + + ...by tagging the specification of common_reference with "Note C" and basic_common_reference "Note D". + + Also remove the allowance to specialize basic_common_reference "if at least one template parameter in the specialization depends on a program-defined type"; it's redundant with "...pursuant to [namespace.std]". (This is consistent with `common_type`'s wording.) + + commit 2aa8b236c8afe09272fba8d0767fbc6552b301b5 + Author: Casey Carter + Date: Tue Jun 19 16:06:03 2018 -0700 + + [structure.requirements] Rephrase para 8 for clarity + + commit d9c710c4f13c95d65f96d503bd45f11628fdf68a + Author: Casey Carter + Date: Mon Jun 18 06:55:44 2018 -0700 + + [concepts.general][library.general] Concepts constrain template arguments, not parameters + + commit a818d5bfb084da10818b830d210d8bb4312912e4 + Author: Casey Carter + Date: Thu Jun 21 09:38:44 2018 -0700 + + [concepts.swappable] Correct example + + commit db9aee9ca04a192f32cd630cf3682d30c62a0bf7 + Author: Casey Carter + Date: Tue Jun 19 15:34:43 2018 -0700 + + [customization.point.object][meta.trans.other] Replace "user-defined" added by P0898R3 with "program-defined" + + ...to be consistent with the intent of LWG2139 + + commit 03f3764a071dfe30ef1137435a88ea036ca65c1f + Author: Casey Carter + Date: Wed Jun 20 15:16:51 2018 -0700 + + [definitions] Redefine expression-equivalent per ISO directives + + To be replaceable in context, and add a clarifying example. + + commit d119277cb8864be440a6e0445211c232e87f91a7 + Author: Casey Carter + Date: Thu Jun 21 09:18:24 2018 -0700 + + [concepts] Rephrase ocurrences of "must" + + commit 16b35d651de53654321b584eba2c6c4e126eb7d8 + Author: Richard Smith + Date: Fri Jun 22 18:08:26 2018 -0700 + + [depr.c.headers] Undo P0619R4's removal of synopses for , + , , and . + + Instead, repurpose these to be synopses for , , + , and , and move them into [depr.c.headers]. + Also introduce a synopsis for . + + This avoids three of these five headers being specified as equivalent to + a non-existent header, and the other two missing a synopsis. + + commit cf0749742b9318143505f9ffe2d4dabb5420d727 + Author: Richard Smith + Date: Fri Jun 22 17:17:41 2018 -0700 + + [diff.cpp17.library] Fix description of how to adjust code for the + removal of and . + + commit fa04176c01dd10105eec6590407b2c76384f5c52 + Author: Richard Smith + Date: Fri Jun 22 17:06:40 2018 -0700 + + [diff.cpp17.library] Fix list of new headers compared to C++17. + + commit 9e80b6c69467fb2fb146637e1f0fca8b7495250f + Author: Richard Smith + Date: Fri Jun 22 16:59:45 2018 -0700 + + [diff.cpp17.except] Fix Rationale to be a rationale. + + "This was retained for one additional C++ standard to ease transition" + is not a rationale for removing the feature now. + + commit 043ee628bc8accbe7f1ac4dc2210e88186bc95a4 + Author: Richard Smith + Date: Fri Jun 22 16:41:51 2018 -0700 + + [diff.cpp17.except] Add a note that there is no longer a way to write + code that is non-throwing in both C++20 and C++03. + + commit fd244b515387efde9fb08ffe183985a38e93d184 + Author: Richard Smith + Date: Fri Jun 22 16:29:19 2018 -0700 + + [diff.cpp03.language.support] Remove change described in p1, which is no + longer a possible change. + + It is not possible to write a global replacement operator new or + operator delete in C++20 with code that is also valid C++03, because + + a) operator new must be declared 'throw(std::bad_alloc)' in C++03 and + must be declared with no exception specification in C++11 onwards, + and + b) operator delete must be declared 'throw()' in C++03 and must be + declared 'noexcept' in C++20 onwards. + + Therefore there is no code that is valid in C++03 and C++20 and changes + meaning due to the change identified in this section. + + Instead, expand [diff.cpp03.language.support]p2 to explain that the + affected programs are simply not valid in C++20. + + commit 3e80cd4c07563639a8ca55d41d704701ae6d0eb4 + Author: Richard Smith + Date: Fri Jun 22 16:07:09 2018 -0700 + + [complex.special] Reorder defaulted complex copy constructor to + emphasize relationship between it and the converting constructors. + + commit 74539419429281072e1f8b787a0ce0dc2bb067db + Author: Richard Smith + Date: Thu Jun 21 20:09:23 2018 -0700 + + [atomics.ref] Reword introductory sentences to avoid overfull hbox. + + commit 3c21cfcfa1091a406d4b384e4677f0fa0e8ea75c + Author: Jens Maurer + Date: Mon Jun 11 19:10:53 2018 +0200 + + [alg.shift] Avoid undefined iterator arithmetic on ForwardIterator. + Avoid using the undefined concept BidirectionalIterator. + + commit 949892305c88abd7c2ecb15a77bde3222366733d + Author: Jonathan Wakely + Date: Mon Jun 11 23:43:22 2018 +0100 + + [structure.specifications] remove "implementation-defined" from example + mentioning [[expects]] and add cross-reference to [[expects]] attribute. + + commit 23c6b62f321d463792c54db38a89b335dc232f3e + Author: Jonathan Wakely + Date: Mon Jun 11 23:41:37 2018 +0100 + + [structure.specifications] replace "paragraph" with "element" + + commit 4aa23529058e5f17f74e663ff189a1548812e009 + Author: Jonathan Wakely + Date: Mon Jun 11 23:37:31 2018 +0100 + + [res.on.required] replace "paragraph" with "element" + + commit 3b24b2dc75bd5b80d2c5fc1cb3fdb62ac3852d8d + Author: Richard Smith + Date: Tue Jun 19 17:13:17 2018 -0700 + + [diff.cpp17] Correct description of explicit(bool) compatibility. + + Parenthesized names for explicit constructors and conversion functions + are still valid if the name doesn't immediately follow the explicit + keyword. Add an example using explicit(true) as a hint indicating how + to get the same effect. + + Change affected subclauses from [dcl.fct] to the somewhat-more-precise + [class.ctor] and [class.conv.fct]. + + commit 001a2011d172cce2784857a492e2c37e25ade7e9 + Author: Richard Smith + Date: Mon Jun 18 18:19:39 2018 -0700 + + [dcl.attr.contract] Fix typeface of std::terminate in comment. + + commit 913c83a98735709462a49613f8993bca4042ed70 + Author: Jens Maurer + Date: Sun Jun 17 09:18:08 2018 +0200 + + [dcl.attr.contract] Move according to alphabetical sorting of headings + + commit 463ab8dc3726514b2adf8dcf6816262f58688da3 + Author: Jens Maurer + Date: Fri Jun 15 11:01:23 2018 +0200 + + [except.terminate] Clarify evaluation of a contract + + commit f2f60fd4c3f9810ae815a408e1fd3ac1462482c7 + Author: Jens Maurer + Date: Fri Jun 15 10:53:18 2018 +0200 + + [temp.explicit] Remove redundant rules for contracts + + given that [dcl.attr.grammar] already prohibits + attribute-specifier-seqs for an explicit instantiation. + + commit a7a0e115dbf5f149936a04f57b9dd3174c9efa6a + Author: Jens Maurer + Date: Fri Jun 15 10:51:04 2018 +0200 + + [class.virtual] Fix comment in example + + commit ca0d62cc3d8c397d843fe1e1ae4a80f8fa389587 + Author: Jens Maurer + Date: Fri Jun 15 10:42:25 2018 +0200 + + [dcl.attr.contract] Fix sentence defining violation handler + + commit 0cd3f3dc072d736b4e8572311918bdccbb91e1f7 + Author: Jens Maurer + Date: Fri Jun 15 10:33:54 2018 +0200 + + [dcl.attr.contract] Clarify evaluation of non-checked contracts + + commit 2930dc55b0c5573aad90c22e1909f98bb9bec4c2 + Author: Jens Maurer + Date: Fri Jun 15 10:18:18 2018 +0200 + + [dcl.attr.contract] Permit modifications of temporaries within the predicate. + + commit 87c3c20540b99708b02ce3dfc6a792a3fea454aa + Author: Jens Maurer + Date: Fri Jun 15 10:17:19 2018 +0200 + + [dcl.attr.contract] Clarify that assertions may apply to a null statement + + commit 072f42df7b298c3677b2a1e8f1a4687d1e005ffc + Author: Jens Maurer + Date: Fri Jun 15 10:10:53 2018 +0200 + + [dcl.attr.contract] Clarify rules on std::contract_violation + + commit 77579d2f9527552820dfc667867589da12adceda + Author: Jens Maurer + Date: Fri Jun 15 10:08:09 2018 +0200 + + [dcl.attr.contract] Predicates of a contract are potentially evaluated, + + as per the definition in [basic.def.odr], so turn the + redundant normative statement into a note. + + commit da24c5df270fc17a82b6767aef5baee94fba4a45 + Author: Jens Maurer + Date: Fri Jun 15 09:43:43 2018 +0200 + + [basic.def.odr] Rephrase ODR rule for contracts + + commit 0fc2af6bbe05e16feb03e8f24651ea12e8a6997c + Author: Jens Maurer + Date: Sun Jun 10 22:53:26 2018 +0200 + + [dcl.attr.contract] Reorder paragraphs for more coherence. + + Also move rules on virtual functions to [class.virtual]. + Rephase assertion checking along pre/postcondition checking. + + commit 42019fd86775859393e7e5edc7e8d4c2e64c8019 + Author: Jens Maurer + Date: Sun Jun 10 22:24:18 2018 +0200 + + [basic.def.odr] Rephrase build level and continuation mode requirements + + commit ac603143816388fa8fa12a8fb0802130b6643884 + Author: Jens Maurer + Date: Sun Jun 10 22:17:23 2018 +0200 + + [dcl.attr.contract] Rephrase comments in examples + + commit 19d07dec4cbe5ae86eb6231eb833d166c5939faf + Author: Jens Maurer + Date: Sun Jun 10 22:14:46 2018 +0200 + + [except.terminate] Add contract violation with continuation mode off + + commit f28517ab52f7bf80879a7883fe08bb97020f80da + Author: Jens Maurer + Date: Sun Jun 10 21:17:50 2018 +0200 + + [dcl.attr.contract] Avoid duplication of 'renaming' in enumeration + + commit a8b8e534a7a5235157333f6a9f64c339e48e0e86 + Author: Richard Smith + Date: Mon Jun 11 15:56:16 2018 -0700 + + [basic.stc.dynamic.deallocation] Remove confusing note. + + This note is only correct due to subtleties of later wording + (particularly that a destroying operator delete cannot be a function + template). Correcting it results in it simply duplicating existing + normative rules and not adding anything. So remove it instead. + + commit e4f579e421dac17ff36f98b2211d143991de7850 + Author: Jens Maurer + Date: Wed Jun 13 09:16:17 2018 +0200 + + [temp.arg.nontype] Fix example involving string literal + + P0732R2 contained some changes to this section that were missing + explicit markup; apply those changes too. Also fix missing definition of + operator<=> in class type used as type of non-type template parameter. + + commit 5cca3b5015491a6c8b5d1d63f651073940d1145e + Author: Jens Maurer + Date: Wed Jun 13 08:34:52 2018 +0200 + + [dcl.fct] Move function definition rule to [dcl.fct.def.general] + + This is the rule that requires complete non-abstract + types function parameter or return types. + + commit b39b44b32394384edcc8f7f682274fbffd22f067 + Author: Jens Maurer + Date: Wed Jun 13 08:28:26 2018 +0200 + + [temp.deduct] Forming an array of abstract class type is not deduction failure + + commit ba6cd4c525371eb98c60a025da21e5ca813b4a94 + Author: Thomas Köppe + Date: Thu Jun 14 21:48:23 2018 +0100 + + [cpp.subst] Reword paragraph to simplify the logical structure and avoid ambiguous references. + + commit 4ce05424a8774e13b9958eb9cb9165da5b19edb0 + Author: Richard Smith + Date: Tue Jun 12 16:27:40 2018 -0700 + + [depr.capture.this] Reorder so the order of Annex D matches the order of the main text + + commit 628a32db863ac10fe0fb4c45d6975a50f5497acf + Author: Richard Smith + Date: Tue Jun 12 16:26:37 2018 -0700 + + [depr.capture.this] Replace "can" with "may". + + This wording is describing permission, not capability, so should use "may". + + commit 5274b2ee4c558d39012a34d104be0d2139115c00 + Author: Thomas Köppe + Date: Fri Jun 15 14:31:14 2018 +0100 + + [temp.deduct] Fixes from editorial review of CWG2293: + + * Use "not valid" rather than "invalid", since only "valid" has been defined. + * Add an "otherwise" to improve flow. + + commit 0e771884acfdcb1dc693ef654f34cf717986f803 + Author: Jonathan Wakely + Date: Fri Jun 8 08:23:25 2018 +0100 + + [time.zone.db.remote] replace "this section" with "this subclause" (#2103) + + commit b9c5272c78fb312883cb548219b7fd2cb44280c7 + Author: Thomas Köppe + Date: Thu Jun 7 23:24:37 2018 +0200 + + [cfenv.syn] Add "optional" markers for macros from the C library that are optional (as defined by C) + + commit aa77121b3aa9bc566b8d2e428cd21a28493ce57e + Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com> + Date: Thu Jun 7 21:39:51 2018 +0200 + + [dcl.attr.likelihood] Fix error in example + + commit fbee1d521da91a798d81ecc09f110a0946239630 + Author: Jens Maurer + Date: Thu Jun 7 21:36:42 2018 +0200 + + [views.general] Remove redundant introduction for span. (#2062) + + commit 069a179a0d54cad4b3d00f00eae532c827786894 + Author: Jens Maurer + Date: Tue Mar 27 14:41:13 2018 +0200 + + [cmp.syn] Rename to [compare.syn] to match the header name + + commit 8a0060d0dcda8c63a2c432016bd038c75a8de9a1 + Author: Marc Mutz + Date: Thu Jun 7 03:34:12 2018 +0200 + + [list.modifiers, forward.list.modifiers] Add missing 'to' in 'referred [to] by' (#2100) + + commit 57de3af9d24037d60d996b255c1ded8ee65387d2 + Author: Arthur O'Dwyer + Date: Wed May 30 00:18:13 2018 -0700 + + [comparisons] Fix a typo in the note for `std::less`. (#2089) + + commit 61b6c21f218e3cbb9d15426975f1a26d8b72a7fe + Author: Richard Smith + Date: Thu May 10 14:40:22 2018 -0700 + + [class.expl.init] Fix example to account for guaranteed copy omission. diff --git a/papers/n4778.pdf b/papers/n4778.pdf new file mode 100644 index 0000000000..e3ffd53b48 Binary files /dev/null and b/papers/n4778.pdf differ diff --git a/papers/n4779.html b/papers/n4779.html new file mode 100644 index 0000000000..9abdfc9d6f --- /dev/null +++ b/papers/n4779.html @@ -0,0 +1,456 @@ +N4779 +

N4779 Editors' Report -- Programming Languages -- C++

+ +

2018-10-08
+Richard Smith (editor) (Google Inc)
+Dawn Perchik (co-editor) (Bright Side Computing, LLC)
+Jens Maurer (co-editor)
+Thomas Köppe (co-editor) (Google DeepMind)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

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

+ +

New papers

+ +
    +
  • N4778 is the current C++ working draft. It replaces N4762.
  • +
  • N4779 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

This revision contains only editorial changes relative to N4762.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4762 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 51df4bef36abd6a559279634b357e606af5dd9d4
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Jul 16 15:20:16 2018 -0700
+
+    [library.general] Fix up the library categories table (#2262)
+
+    by ordering [localization] correctly, and adding a row for [time]
+
+commit 6cee2110159f4a8abfa5254de044154633a9acdb
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jul 17 06:52:36 2018 -0700
+
+    [iterators.general] Fix up Iterators library summary table (#2263)
+
+    by correcting the title for [predef.iterators] to "Iterator adaptors", and adding rows for [iterator.range] and [iterator.container].
+
+commit a47d6ac11530630d0d1f78f3727e118e5f19070d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jul 19 23:04:51 2018 +0200
+
+    [string.view] Move complexity requirement into [string.view.template]. (#2261)
+
+commit 15715f3347aaba6b2cc03c477a17e1f6462a8074
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jul 19 23:05:53 2018 +0200
+
+    [span.overview] Move requirements on types to after the synposis. (#2260)
+
+    As described in [structure.specifications]
+
+commit 437add693809d43ea30ada757987240d3581f929
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Mon Jul 23 22:05:47 2018 +0100
+
+    [mem.res.class] Add default constructor (#2268)
+
+    The addition of a copy constructor by P0619R4 caused the default
+    constructor to be suppressed, which was not intended.
+
+commit ed0e9c0bc6b54dfe14193345cb85a389b6dd2e5b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jul 23 23:06:38 2018 +0200
+
+    [std] Fix cross-references that should point to [class.prop] (#2253)
+
+commit a07890ba525e87955ac147bfe5b8e7b2ec7ae584
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jul 23 23:05:36 2018 +0200
+
+    [dcl.dcl] Remove incorrect footnote about the implicit int rule.
+
+commit 1091b51ff14a1af1cb3c7524eab261574ec9c732
+Author: Marshall Clow <marshall@idio.com>
+Date:   Wed Jul 25 21:30:14 2018 -0700
+
+    Fix spelling error "Tueday" --> "Tuesday" (4x)
+
+commit b21456eca47a5fcdf3cf6dc647943b45b7bde663
+Author: Marshall Clow <marshall@idio.com>
+Date:   Wed Sep 12 06:07:37 2018 -0700
+
+    [map] Use `mapped_type` rather than `T` for indexing operations (#2330)
+
+    The specification of `unordered_map` already uses `mapped_type`. I'm going to change `flat_map` to do so, too.  We use `mapped_type` in other places. The description (line 6311) even says "a reference to the `mapped_type`".
+
+commit c39932f1fb2a511358040100e8a5ef759a5b0453
+Author: Kazutoshi SATODA <k_satoda@f2.dion.ne.jp>
+Date:   Wed Sep 12 22:08:28 2018 +0900
+
+    [temp.constr.order] Fix typo: conjuctive -> conjunctive (#2322)
+
+commit 5ee42bdd4a7a391865ab2988c806ac908e81a5c2
+Author: Koichi Murase <myoga.murase@gmail.com>
+Date:   Wed Sep 12 22:09:17 2018 +0900
+
+    [expr.prim.id] Fix typo "the the" (#2314)
+
+commit c1007bd673169cfafb43b216476335d20e62411d
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Wed Sep 12 09:41:19 2018 -0700
+
+    [basic.types] Replace redundant "cv-unqualified scalar types" with just "scalar types"
+
+    The redundant phrasing "cv-unqualified scalar types [...] and cv-qualified versions of these types" is cruft that was accidentally left over from the dueling resolutions of CWG 1746 (which added "cv-unqualified") and CWG 2094 (which added "and cv-qualified versions of these types").
+
+commit 414c2706f75f4bb76ecc444e98ac2e2dcc3c6b00
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Sep 19 09:15:36 2018 +0200
+
+    [dcl.init.aggr] initializer-list (grammar) is never empty
+
+commit e160ea1300e21eb412feaa7733f1e7cd0e1875d8
+Author: Olivier <okannen@gmail.com>
+Date:   Sat Sep 22 01:45:19 2018 +0200
+
+    [temp.param] Remove vestigial restriction on non-type template parameters of class type.
+
+    P0732R2 intended to remove this restriction, but missed one of the places where we repeated the rule.
+
+commit 61e5815fd137e3e0ecd03823f507d175be897fb8
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Thu Oct 4 07:17:54 2018 -0700
+
+    [class.copy.ctor] Add missing cross-references to Annex D (#2344)
+
+    Add the missing cross-references to corresponding Annex D entry for the deprecated implicit declaration of copy constructor and copy assignment operator when either the destructor or other
+    copy operation is user-declared.
+
+commit 3f0a2f353aa348e23a334110ae32764588fa6b8a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jul 8 21:45:34 2018 +0200
+
+    [expr.pre] Add note on operator regrouping here,
+
+    moved from [intro.abstract].
+
+commit 5af570b491d11bbd423494c61f2829667c3c74bd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Oct 9 02:15:04 2018 +0200
+
+    [copy.ctor] Rearrange constructor subclauses (#2270)
+
+    * [class.default.ctor] Create new subclause under [class.copy],
+    move [class.copy.ctor] there, and rearrange the general
+    descriptions in [class.copy]. Move a statement that applies
+    during construction to [class.cdtor].
+
+    * Fix cross-references for 'default constructor'
+
+commit 6997ed2799111ddf57dfa49418be581adfd7c03b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jul 20 20:18:01 2018 +0200
+
+    [stmt.switch] Clarify comparison for case labels
+
+commit 214782433d53a93ada321cb19665e1b7719427ba
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sun Jul 22 13:46:03 2018 +0200
+
+    [class.dtor] Clean up awkward '.. is the type of the class' phrasing.
+
+commit 408141121e70bebc943af3fb03ef957ee0f51e43
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 24 21:49:01 2018 +0200
+
+    [containers,utilities] Mark exposition-only names
+
+    with italics teletype and use hyphens, not underscores,
+    to highlight that these are not standard-prescribed names.
+
+commit 16f23d1c59787a6cfbe747c0ec66b1102db26223
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Oct 8 17:43:19 2018 -0700
+
+    [container.node.overview] Remove suggestion that an implementation could
+    define a class named 'node-handle'.
+
+commit e0613813ad63aaaea9883a1067c5a3c04d88328f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jul 27 00:01:46 2018 +0200
+
+    [expr.new] Use 'object', not 'entity', for new-expression.
+
+    The term 'entity' is too generic here.
+    Also move the specification of the non-array return
+    value just before the array case, after the description
+    of the parsing disambiguation.
+
+commit 340573ca6936c39eaec1949e824609d0f9ac51b1
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon Oct 8 20:45:59 2018 -0400
+
+    [temp.param] fix spaceship example (#2291)
+
+    A two parameter spaceship can't be a member, and the parameter types for a defaulted operator can only be const C& ([class.compare.default]p1).
+
+commit e3e8ce46c3d4ff58601e104b6d4c4ba1e789b7b2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Aug 12 00:10:30 2018 +0200
+
+    [std] Replace use of 'structure' by 'class'
+
+commit a5c05c2a07d22cfbbfc32e657017a6e2ce837618
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Oct 9 02:52:47 2018 +0200
+
+    [class.virtual] Define 'virtual function' (#2297)
+
+commit 28bd28f7db5b4d463d1f5fd8b252b45ad3b35528
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Tue Oct 9 08:59:19 2018 +0800
+
+    [dcl.init] Rephrase "user-defined conversion sequence" (#2298)
+
+    1. The conversion sequence is governed by the rules defined here. Saying "conversion sequence" here will cause circular definition.
+    2. Overload resolution selects a function, not a conversion sequence.
+
+commit c85202d90102b8ed9c7e0d9532fdc2ef3b43e7c8
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Tue Oct 9 04:00:53 2018 +0300
+
+    [basic.life] Change "class or aggregate type" to "class or array type" (#2309)
+
+commit 4c431f712a35199f3b9b064a0b6580ec2b224386
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Sep 2 23:38:53 2018 +0200
+
+    [expr.add] Clarify if/otherwise ladder
+
+commit ad121b96df829872565285cca7f00f6bd22cb428
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Sep 2 23:59:14 2018 +0200
+
+    [basic.lval] Clarify result object for prvalues as operands
+
+commit 27675c7bbe749aaaa19c1072a68cedc10114e9bd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Sep 3 00:05:58 2018 +0200
+
+    [class.member.lookup] 'unqualified-id' is the correct complement for 'qualified-id'
+
+commit 897e3dd719499017e9866a21f7eb88433264c67d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Sep 3 00:20:48 2018 +0200
+
+    [class.this] A pointer represents more than an address
+
+commit 32ac0796318a35104f541f33c0ddec6c8c7f8081
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Sep 3 00:33:05 2018 +0200
+
+    [class.temporary] prvalues are not materialized,
+
+    temporary objects are.
+
+commit 846998e6eaf76fb5a0a6bbbe00c5ed0ba8b7523d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Sep 6 22:36:45 2018 +0200
+
+    [basic.def.odr] Replace undefined term 'non-trivial function'
+
+commit a297a3d2b5d98b3ae224223466f8ccddd00fd14e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Sep 6 22:46:44 2018 +0200
+
+    [basic.def.odr] Clarify antecedent for declarative region
+
+commit 781374ba343aafb23772b6326abce1cccade2030
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Sep 6 23:15:13 2018 +0200
+
+    [unique.ptr.single.ctor] Simplify description of unique_ptr constructors
+
+commit cb3d918b38dc439da28e688365c0877685130c85
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 14 22:37:27 2018 +0200
+
+    [class.union] use 'class', not (undefined) 'struct'
+
+commit 9a9a49077702815c49cdb0bd78fe58ca477b16ae
+Author: Louis Dionne <ldionne@apple.com>
+Date:   Sun Sep 23 11:29:35 2018 -0700
+
+    [editorial] Use struct instead of class to make example valid
+
+    P0732R2 [1] was merged in Rapperswil, but one example is invalid because
+    the constructor for A is private, so it can't be constructed from the
+    string literal.
+
+    [1]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0732r2.pdf
+
+commit 6df3eb6de13fd1d98cb2a2988361811556927882
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Sep 24 22:37:52 2018 +0200
+
+    [dcl.attr.contract.check] Violation handlers are not 'user-provided'
+
+commit 82cfc5b67b33ca076a80184b508ed2172af9d3aa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Sep 27 10:22:44 2018 +0200
+
+    [temp] Add 'static' to examples for static data member template
+
+    A non-static data member cannot be a template.
+
+commit f23f1d0613099496e74cabf0c87cceccb94fb919
+Author: JF Bastien <github@jfbastien.com>
+Date:   Mon Oct 8 18:29:41 2018 -0700
+
+    Move "plain ints" statement to a note (#2346)
+
+commit ad6b6f27e803671f0d0280d05990950d16909afa
+Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com>
+Date:   Tue Oct 9 03:38:23 2018 +0200
+
+    [fs.filesystem.syn] Remove vestige of removed trivial-clock type
+
+    The removed paragraph refers to trivial-clock that has now been replaced by chrono::file_clock.
+
diff --git a/papers/n4779.md b/papers/n4779.md new file mode 100644 index 0000000000..86419503df --- /dev/null +++ b/papers/n4779.md @@ -0,0 +1,330 @@ +# N4779 Editors' Report -- Programming Languages -- C++ + +2018-10-08 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +Jens Maurer (co-editor) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4778](http://wg21.link/n4778) is the current C++ working draft. It replaces [N4762](http://wg21.link/n4762). + * N4779 is this Editors' Report. + +## Motions incorporated into working draft + +This revision contains only editorial changes relative to N4762. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4762 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/n4762...n4778). + + commit 51df4bef36abd6a559279634b357e606af5dd9d4 + Author: Casey Carter + Date: Mon Jul 16 15:20:16 2018 -0700 + + [library.general] Fix up the library categories table (#2262) + + by ordering [localization] correctly, and adding a row for [time] + + commit 6cee2110159f4a8abfa5254de044154633a9acdb + Author: Casey Carter + Date: Tue Jul 17 06:52:36 2018 -0700 + + [iterators.general] Fix up Iterators library summary table (#2263) + + by correcting the title for [predef.iterators] to "Iterator adaptors", and adding rows for [iterator.range] and [iterator.container]. + + commit a47d6ac11530630d0d1f78f3727e118e5f19070d + Author: Jens Maurer + Date: Thu Jul 19 23:04:51 2018 +0200 + + [string.view] Move complexity requirement into [string.view.template]. (#2261) + + commit 15715f3347aaba6b2cc03c477a17e1f6462a8074 + Author: Jens Maurer + Date: Thu Jul 19 23:05:53 2018 +0200 + + [span.overview] Move requirements on types to after the synposis. (#2260) + + As described in [structure.specifications] + + commit 437add693809d43ea30ada757987240d3581f929 + Author: Jonathan Wakely + Date: Mon Jul 23 22:05:47 2018 +0100 + + [mem.res.class] Add default constructor (#2268) + + The addition of a copy constructor by P0619R4 caused the default + constructor to be suppressed, which was not intended. + + commit ed0e9c0bc6b54dfe14193345cb85a389b6dd2e5b + Author: Jens Maurer + Date: Mon Jul 23 23:06:38 2018 +0200 + + [std] Fix cross-references that should point to [class.prop] (#2253) + + commit a07890ba525e87955ac147bfe5b8e7b2ec7ae584 + Author: Jens Maurer + Date: Mon Jul 23 23:05:36 2018 +0200 + + [dcl.dcl] Remove incorrect footnote about the implicit int rule. + + commit 1091b51ff14a1af1cb3c7524eab261574ec9c732 + Author: Marshall Clow + Date: Wed Jul 25 21:30:14 2018 -0700 + + Fix spelling error "Tueday" --> "Tuesday" (4x) + + commit b21456eca47a5fcdf3cf6dc647943b45b7bde663 + Author: Marshall Clow + Date: Wed Sep 12 06:07:37 2018 -0700 + + [map] Use `mapped_type` rather than `T` for indexing operations (#2330) + + The specification of `unordered_map` already uses `mapped_type`. I'm going to change `flat_map` to do so, too. We use `mapped_type` in other places. The description (line 6311) even says "a reference to the `mapped_type`". + + commit c39932f1fb2a511358040100e8a5ef759a5b0453 + Author: Kazutoshi SATODA + Date: Wed Sep 12 22:08:28 2018 +0900 + + [temp.constr.order] Fix typo: conjuctive -> conjunctive (#2322) + + commit 5ee42bdd4a7a391865ab2988c806ac908e81a5c2 + Author: Koichi Murase + Date: Wed Sep 12 22:09:17 2018 +0900 + + [expr.prim.id] Fix typo "the the" (#2314) + + commit c1007bd673169cfafb43b216476335d20e62411d + Author: Arthur O'Dwyer + Date: Wed Sep 12 09:41:19 2018 -0700 + + [basic.types] Replace redundant "cv-unqualified scalar types" with just "scalar types" + + The redundant phrasing "cv-unqualified scalar types [...] and cv-qualified versions of these types" is cruft that was accidentally left over from the dueling resolutions of CWG 1746 (which added "cv-unqualified") and CWG 2094 (which added "and cv-qualified versions of these types"). + + commit 414c2706f75f4bb76ecc444e98ac2e2dcc3c6b00 + Author: Jens Maurer + Date: Wed Sep 19 09:15:36 2018 +0200 + + [dcl.init.aggr] initializer-list (grammar) is never empty + + commit e160ea1300e21eb412feaa7733f1e7cd0e1875d8 + Author: Olivier + Date: Sat Sep 22 01:45:19 2018 +0200 + + [temp.param] Remove vestigial restriction on non-type template parameters of class type. + + P0732R2 intended to remove this restriction, but missed one of the places where we repeated the rule. + + commit 61e5815fd137e3e0ecd03823f507d175be897fb8 + Author: Alisdair Meredith + Date: Thu Oct 4 07:17:54 2018 -0700 + + [class.copy.ctor] Add missing cross-references to Annex D (#2344) + + Add the missing cross-references to corresponding Annex D entry for the deprecated implicit declaration of copy constructor and copy assignment operator when either the destructor or other + copy operation is user-declared. + + commit 3f0a2f353aa348e23a334110ae32764588fa6b8a + Author: Jens Maurer + Date: Sun Jul 8 21:45:34 2018 +0200 + + [expr.pre] Add note on operator regrouping here, + + moved from [intro.abstract]. + + commit 5af570b491d11bbd423494c61f2829667c3c74bd + Author: Jens Maurer + Date: Tue Oct 9 02:15:04 2018 +0200 + + [copy.ctor] Rearrange constructor subclauses (#2270) + + * [class.default.ctor] Create new subclause under [class.copy], + move [class.copy.ctor] there, and rearrange the general + descriptions in [class.copy]. Move a statement that applies + during construction to [class.cdtor]. + + * Fix cross-references for 'default constructor' + + commit 6997ed2799111ddf57dfa49418be581adfd7c03b + Author: Jens Maurer + Date: Fri Jul 20 20:18:01 2018 +0200 + + [stmt.switch] Clarify comparison for case labels + + commit 214782433d53a93ada321cb19665e1b7719427ba + Author: Eelis van der Weegen + Date: Sun Jul 22 13:46:03 2018 +0200 + + [class.dtor] Clean up awkward '.. is the type of the class' phrasing. + + commit 408141121e70bebc943af3fb03ef957ee0f51e43 + Author: Jens Maurer + Date: Tue Jul 24 21:49:01 2018 +0200 + + [containers,utilities] Mark exposition-only names + + with italics teletype and use hyphens, not underscores, + to highlight that these are not standard-prescribed names. + + commit 16f23d1c59787a6cfbe747c0ec66b1102db26223 + Author: Richard Smith + Date: Mon Oct 8 17:43:19 2018 -0700 + + [container.node.overview] Remove suggestion that an implementation could + define a class named 'node-handle'. + + commit e0613813ad63aaaea9883a1067c5a3c04d88328f + Author: Jens Maurer + Date: Fri Jul 27 00:01:46 2018 +0200 + + [expr.new] Use 'object', not 'entity', for new-expression. + + The term 'entity' is too generic here. + Also move the specification of the non-array return + value just before the array case, after the description + of the parsing disambiguation. + + commit 340573ca6936c39eaec1949e824609d0f9ac51b1 + Author: timsong-cpp + Date: Mon Oct 8 20:45:59 2018 -0400 + + [temp.param] fix spaceship example (#2291) + + A two parameter spaceship can't be a member, and the parameter types for a defaulted operator can only be const C& ([class.compare.default]p1). + + commit e3e8ce46c3d4ff58601e104b6d4c4ba1e789b7b2 + Author: Jens Maurer + Date: Sun Aug 12 00:10:30 2018 +0200 + + [std] Replace use of 'structure' by 'class' + + commit a5c05c2a07d22cfbbfc32e657017a6e2ce837618 + Author: Jens Maurer + Date: Tue Oct 9 02:52:47 2018 +0200 + + [class.virtual] Define 'virtual function' (#2297) + + commit 28bd28f7db5b4d463d1f5fd8b252b45ad3b35528 + Author: S. B. Tam + Date: Tue Oct 9 08:59:19 2018 +0800 + + [dcl.init] Rephrase "user-defined conversion sequence" (#2298) + + 1. The conversion sequence is governed by the rules defined here. Saying "conversion sequence" here will cause circular definition. + 2. Overload resolution selects a function, not a conversion sequence. + + commit c85202d90102b8ed9c7e0d9532fdc2ef3b43e7c8 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Tue Oct 9 04:00:53 2018 +0300 + + [basic.life] Change "class or aggregate type" to "class or array type" (#2309) + + commit 4c431f712a35199f3b9b064a0b6580ec2b224386 + Author: Jens Maurer + Date: Sun Sep 2 23:38:53 2018 +0200 + + [expr.add] Clarify if/otherwise ladder + + commit ad121b96df829872565285cca7f00f6bd22cb428 + Author: Jens Maurer + Date: Sun Sep 2 23:59:14 2018 +0200 + + [basic.lval] Clarify result object for prvalues as operands + + commit 27675c7bbe749aaaa19c1072a68cedc10114e9bd + Author: Jens Maurer + Date: Mon Sep 3 00:05:58 2018 +0200 + + [class.member.lookup] 'unqualified-id' is the correct complement for 'qualified-id' + + commit 897e3dd719499017e9866a21f7eb88433264c67d + Author: Jens Maurer + Date: Mon Sep 3 00:20:48 2018 +0200 + + [class.this] A pointer represents more than an address + + commit 32ac0796318a35104f541f33c0ddec6c8c7f8081 + Author: Jens Maurer + Date: Mon Sep 3 00:33:05 2018 +0200 + + [class.temporary] prvalues are not materialized, + + temporary objects are. + + commit 846998e6eaf76fb5a0a6bbbe00c5ed0ba8b7523d + Author: Jens Maurer + Date: Thu Sep 6 22:36:45 2018 +0200 + + [basic.def.odr] Replace undefined term 'non-trivial function' + + commit a297a3d2b5d98b3ae224223466f8ccddd00fd14e + Author: Jens Maurer + Date: Thu Sep 6 22:46:44 2018 +0200 + + [basic.def.odr] Clarify antecedent for declarative region + + commit 781374ba343aafb23772b6326abce1cccade2030 + Author: Jens Maurer + Date: Thu Sep 6 23:15:13 2018 +0200 + + [unique.ptr.single.ctor] Simplify description of unique_ptr constructors + + commit cb3d918b38dc439da28e688365c0877685130c85 + Author: Jens Maurer + Date: Fri Sep 14 22:37:27 2018 +0200 + + [class.union] use 'class', not (undefined) 'struct' + + commit 9a9a49077702815c49cdb0bd78fe58ca477b16ae + Author: Louis Dionne + Date: Sun Sep 23 11:29:35 2018 -0700 + + [editorial] Use struct instead of class to make example valid + + P0732R2 [1] was merged in Rapperswil, but one example is invalid because + the constructor for A is private, so it can't be constructed from the + string literal. + + [1]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0732r2.pdf + + commit 6df3eb6de13fd1d98cb2a2988361811556927882 + Author: Jens Maurer + Date: Mon Sep 24 22:37:52 2018 +0200 + + [dcl.attr.contract.check] Violation handlers are not 'user-provided' + + commit 82cfc5b67b33ca076a80184b508ed2172af9d3aa + Author: Jens Maurer + Date: Thu Sep 27 10:22:44 2018 +0200 + + [temp] Add 'static' to examples for static data member template + + A non-static data member cannot be a template. + + commit f23f1d0613099496e74cabf0c87cceccb94fb919 + Author: JF Bastien + Date: Mon Oct 8 18:29:41 2018 -0700 + + Move "plain ints" statement to a note (#2346) + + commit ad6b6f27e803671f0d0280d05990950d16909afa + Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com> + Date: Tue Oct 9 03:38:23 2018 +0200 + + [fs.filesystem.syn] Remove vestige of removed trivial-clock type + + The removed paragraph refers to trivial-clock that has now been replaced by chrono::file_clock. diff --git a/papers/n4791.pdf b/papers/n4791.pdf new file mode 100644 index 0000000000..1ceb9a25d0 Binary files /dev/null and b/papers/n4791.pdf differ diff --git a/papers/n4792.html b/papers/n4792.html new file mode 100644 index 0000000000..5369176202 --- /dev/null +++ b/papers/n4792.html @@ -0,0 +1,1073 @@ +N4792 +

N4792 Editors' Report -- Programming Languages -- C++

+ +

2018-12-07
+Richard Smith (editor) (Google Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+Jens Maurer (co-editor)
+Dawn Perchik (co-editor) (Bright Side Computing, LLC)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to Casey Carter +and Tim Song +for supplying the LaTeX sources for +P0896R4 (LWG motion 25, 208 pages of wording changes) +and +P1148R0 (LWG motion 12, 55 pages of wording changes), +respectively, +and to Tony Van Eerd +for supplying a pull request for +P1085R2 (LWG motion 23).

+ +

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

+ +

New papers

+ +
    +
  • N4791 is the current working draft for C++20. It replaces N4778.
  • +
  • N4792 is this Editors' Report.
  • +
+ +

Papers N4788 and N4789 (earlier versions of the post-San-Diego Working Draft +and Editors' Report) are withdrawn and replaced by the above papers due to an +administrative hiccup.

+ +

Motions incorporated into working draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolutions for 3 issues in "tentatively ready" status applied, resolving 4 issues:

+ +
    +
  • 1636 Bits required for negative enumerator values superseded by CWG Motion 10
  • +
  • 1781 Converting from nullptr_t to bool in overload resolution
  • +
  • 2133 Converting std::nullptr_t to bool resolved by resolution to CWG1781
  • +
  • 2373 Incorrect handling of static member function templates in partial ordering
  • +
+ +

CWG motion 2: P0668R5 "Revising the C++ memory model"

+ +

CWG motion 3: P0982R1 "Weaken release sequences"

+ +

CWG motion 4: P1084R2 "Today's return-type-requirements are insufficient" see below

+ +

CWG motion 5: P1131R2 "simple-template-id is ambiguous between class-name and type-name", resolving 1 core issue:

+ +
    +
  • 2292 simple-template-id is ambiguous between class-name and type-name
  • +
+ +

CWG motion 6: P1289R1 "Access control in contract conditions"

+ +

CWG motion 7 was not approved

+ +

CWG motion 8: P1002R1 "try-catch blocks in constexpr functions"

+ +

CWG motion 9: P1327R1 "Allowing dynamic_cast, polymorphic typeid in constant expressions"

+ +

CWG motion 10: P1236R1 "Signed integers are two's complement" (wording for P0907R4)

+ +

CWG motion 11: P0482R6 "char8_t: a type for UTF-8 characters and strings" see below

+ +

CWG motion 12: P1353R0 "Missing feature test macros"

+ +

CWG motion 13: P1073R3 "Immediate functions"

+ +

CWG motion 14: P0595R2 "std::is_constant_evaluated()" see below

+ +

CWG motion 15: P1141R2 "Yet another approach for constrained declarations" see below

+ +

CWG motion 16: P1094R2 "Nested inline namespaces"

+ +

CWG motion 17: P1330R0 "Changing the active member of a union inside constexpr"

+ +

Core motions added a total of 1 page to Clause 1-14.

+ +

Library working group motions

+ +

LWG motion 1 applies to the Concurrency TS

+ +

LWG motions 2 and 3 apply to the Library Fundamentals TS

+ +

LWG motion 4: Library issue resolutions for 9 issues in "Ready" status and 23 issues in "Tentatively Ready" status applied:

+ +
    +
  • 2183 Muddled allocator requirements for match_results constructors
  • +
  • 2184 Muddled allocator requirements for match_results assignments
  • +
  • 2412 promise::set_value() and promise::get_future() should not race
  • +
  • 2682 filesystem::copy() won't create a symlink to a directory
  • +
  • 2936 Path comparison is defined in terms of the generic format
  • +
  • 2943 Problematic specification of the wide version of basic_filebuf::open
  • +
  • 2995 basic_stringbuf default constructor forbids it from using SSO capacity
  • +
  • 2996 Missing rvalue overloads for shared_ptr operations
  • +
  • 3008 make_shared (sub)object destruction semantics are not specified
  • +
  • 3025 Map-like container deduction guides should use pair<Key, T>, not pair<const Key, T>
  • +
  • 3031 Algorithms and predicates with non-const reference arguments
  • +
  • 3037 polymorphic_allocator and incomplete types
  • +
  • 3038 polymorphic_allocator::allocate should not allow integer overflow to create vulnerabilities
  • +
  • 3054 uninitialized_copy appears to not be able to meet its exception-safety guarantee
  • +
  • 3065 LWG 2989 missed that all path's other operators should be hidden friends as well
  • +
  • 3096 path::lexically_relative is confused by trailing slashes
  • +
  • 3116 OUTERMOST_ALLOC_TRAITS needs remove_reference_t
  • +
  • 3122 __cpp_lib_chrono_udls was accidentally dropped
  • +
  • 3127 basic_osyncstream::rdbuf needs a const_cast
  • +
  • 3128 strstream::rdbuf needs a const_cast
  • +
  • 3129 regex_token_iterator constructor uses wrong pointer arithmetic
  • +
  • 3130 [input.output] needs many addressof
  • +
  • 3131 addressof all the things
  • +
  • 3132 Library needs to ban macros named expects or ensures
  • +
  • 3137 Header for __cpp_lib_to_chars
  • +
  • 3140 COMMON_REF is unimplementable as specified
  • +
  • 3145 file_clock breaks ABI for C++17 implementations
  • +
  • 3147 Definitions of likely and unlikely are likely to cause problems
  • +
  • 3148 <concepts> should be freestanding
  • +
  • 3153 Common and common_type have too little in common
  • +
  • 3154 Common and CommonReference have a common defect
  • +
  • 3160 atomic_ref() = delete; should be deleted
  • +
+ +

LWG motion 5: P1123R0 "Editorial guidance for merging P0019R8 and P0528R3" (see P0019R8, P0528R3)

+ +

LWG motion 6: P0487R1 "Fixing operator>>(basic_istream&, CharT*)", resolving 1 library issue:

+ +
    +
  • 2499 operator>>(basic_istream&, CharT*) makes it hard to avoid buffer overflows
  • +
+ +

LWG motion 7: P0602R4 "variant and optional should propagate copy/move triviality"

+ +

LWG motion 8: P0655R1 "visit<R>: explicit return type for visit"

+ +

LWG motion 9: P0972R0 "<chrono> zero(), min(), and max() should be noexcept"

+ +

LWG motion 10: P1006R1 "constexpr in std::pointer_traits"

+ +

LWG motion 11: P1032R1 "Miscellaneous constexpr bits" see below

+ +

LWG motion 12: P1148R0 "Cleaning up clause 20 (strings)"

+ +

LWG motion 13: P0318R1 "unwrap_ref_decay and unwrap_reference" see below

+ +

LWG motion 14: P0357R3 "reference_wrapper for incomplete types"

+ +

LWG motion 15: P0608R3 "A sane variant converting constructor"

+ +

LWG motion 16: P0771R1 "std::function move constructor should be noexcept"

+ +

LWG motion 17: P1007R3 "std::assume_aligned"

+ +

LWG motion 18: P1020R1 "Smart pointer creation with default initialization"

+ +

LWG motion 19: P1285R0 "Improving completeness requirements for type traits"

+ +

LWG motion 20: P1248R1 "Remove CommonReference requirement from StrictWeakOrdering"

+ +

LWG motion 21: P0591R4 "Utility functions to implement uses-allocator construction"

+ +

LWG motion 22: P0899R1 "LWG 3016 is not a defect" (see LWG 3016)

+ +

LWG motion 23: P1085R2 "Should span be regular?"

+ +

LWG motion 24: P1165R1 "Make stateful allocator propagation more consistent for operator+(basic_string)"

+ +

LWG motion 25: P0896R4 "The One Ranges proposal" see below

+ +

LWG motion 26: P0356R5 "Simplified partial function application" see below

+ +

LWG motion 27: P0919R3 "Heterogeneous lookup for unordered containers"

+ +

LWG motion 28: P1209R0 "Adopt consistent container erasure from Library Fundamentals 2"

+ +

Library motions added a total of 133 pages (and 1 Clause) to Clause 15-31.

+ +

Notable editorial changes

+ +

CWG motion 11 and CWG motion 10

+ +

Rebased char8_t wording on the revised description of fundamental types +introduced by CWG motion 10. The description of unsigned char as the +underlying type of char8_t now renders unnecessary some of the other +wording in CWG motion 11; such wording has consequently not been applied.

+ +

CWG motion 14

+ +

After consulting with CWG, added the missing definition for "usable in constant +expressions" as applied to objects and references.

+ +

CWG motion 15

+ +

Removed now-unused grammar production default-template-argument.

+ +

CWG motion 15 and CWG motion 4

+ +

CWG motion 4 adds new uses of the grammar production qualified-concept-name +that CWG motion 15 removes. These have been updated to instead refer to the +new production type-constraint, and the normative wording of CWG motion 4 +has been rewritten to use the new term "immediately-declared constraint", +both of which were introduced by CWG motion 15.

+ +

LWG motion 11

+ +

Change 10 included an editing instruction to make matching changes elsewhere +in the draft. There does not appear to be any "elsewhere" to make said changes. +This editing instruction was ignored.

+ +

LWG motion 13 and LWG motion 26

+ +

The specification of bind_front was simplified by replacing DECAY_UNWRAP +a use of the new unwrap_ref_decay_t alias template introduced by LWG motion 13.

+ +

LWG motion 25

+ +

The wording paper contained an unmarked modification of [std.iterator.tags], +replacing "the most specific category tag" with "a category tag". +After consulting with the paper authors, the change was intentional, and +the corresponding edit has been applied despite not being marked up.

+ +

LWG motion 25 and CWG motion 4

+ +

CWG motion 4 removes a grammar production from requires-clauses, but +LWG motion 25 adds new uses of said grammar production. Those uses are all +of the form

+ +

+requires { + { expr } -> Same<T>&; +} +

+ +

After consultation with LWG, these uses have been rewritten as

+ +

+requires { + { expr } -> Same<T&>; +} +

+ +

which is believed to both correctly reflect the intent and not change the +meaning in practice of any of the uses introduced by LWG motion 25.

+ +

Additionally, CWG motion 4 contains an instruction to replace all constructs +of the form

+ +

+requires { + E; requires Concept<decltype((E)), Args>; +} +

+ +

with the simpler (but now equivalent)

+ +

+requires { + { E } -> Concept<Args>; +} +

+ +

throughout [concepts]. However, LWG motion 25 adds many more instances of +the former pattern throughout several other clauses. All such instances +throughout the working draft have been replaced.

+ +

LWG motion 26

+ +

A feature test macro name __cpp_lib_bind_front was recommended by the paper, +but no wording changes were included to add said feature test macro to the +working draft's table of feature test macros. The macro has been added to +the table anyway.

+ +

Section label changes

+ +

Several section labels introduced by the motions papers have been modified +to match our style guide. In addition to the section labels affected by the +above motions, the following changes have been made:

+ +

[string.op+=] has been renamed to [string.op.append].
+[string.op+] has been renamed to [string.op.plus].

+ +

[re.regex.nmswap] was the only subclause in its parent [re.regex.nonmemb]. +The former heading has been removed, leaving the old content directly in +[re.regex.nonmemb].

+ +

[istream::sentry], +[ostream::sentry], +[ios::failure], +[ios::fmtflatgs], +[ios::iostate], +[ios::openmode], +[ios::seekdir], and +[ios::Init] +have been renamed, replacing the "::" with a "." +and converting "Init" to lowercase.

+ +

See the appendix "Cross-references from ISO C++ 2017" in the working draft +for a full list of sectoin label changes since C++17.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4778 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 e00fef979f7c0da235351f898010658f1f074b87
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Thu Dec 6 21:48:24 2018 -0400
+
+    [iterator.synopsis] Add reference to [alg.req.sortable]
+
+commit 9d81b4fde6dfe2b28737a79ed39f92ef9a0ee030
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sun Dec 2 06:07:03 2018 +0100
+
+    [view.interface] Use "inherits"/"derives" consistently.
+
+commit 358fcdc442fd620f00673081223e4313cf0af499
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 20:38:28 2018 +0100
+
+    [cpp.subst] Introduce grammar non-terminal 'va-opt-replacement'
+
+    to avoid repeated quotes of the token sequence.
+
+commit 4425a120b9a60d3c9e6aa3f1feb553082a9f1fbd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 7 21:37:02 2018 +0100
+
+    [iterator.concepts.readable] Turn parenthesized explanation into a note.
+
+commit de1093907b6deb7455b866d5c47a6a1a026a90a1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 7 22:27:20 2018 +0100
+
+    [temp.func.order] Adjust example to rules in [temp.deduct.partial].
+
+commit 07901a9f724b019c0b6634a9a0c39e5dd5208324
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 1 17:31:53 2018 +0100
+
+    [input.output] Avoid colons in stable labels
+
+commit 6e5dba392d19241efed299c91670cc31fcbe3826
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 7 22:05:50 2018 +0000
+
+    [template.mask.array.overview] Fix nesting of parentheses; reflow source
+
+commit 36998eae97c6876c1f67dc0425c42555dbf0cea5
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 7 22:02:49 2018 +0000
+
+    [iterator.concept.iterator] Remove stray, mismatched parenthesis
+
+commit a5603f0cf1b35097a9892d9627eb03dc5cc3e154
+Author: JF Bastien <github@jfbastien.com>
+Date:   Fri Dec 7 13:48:16 2018 -0800
+
+    [basic.fundamental] Remove a footnote that was describing a particular possible manifestation of undefined behaviour
+
+    The note was problematic, as (by omission) it suggested that such behaviour might not be true for other types.
+
+commit 8035cdb6de85ff0f541b3fc78f747d060ea50ef6
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri Dec 7 17:43:10 2018 -0400
+
+    [iterator.traits] Present concept requirements consistently (#2566)
+
+commit a4366dc5bf59d826a9b1aee82d317636a6239e9a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 7 21:51:55 2018 +0100
+
+    [iosfwd.syn] Change char_traits from 'class' to 'struct'. (#2570)
+
+commit 888da0bf8d0a07048dab8098197c7a326eda9e19
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 5 01:46:53 2018 +0000
+
+    [algorithms] Add missing closing delimiters
+
+commit 14db6ec65b7c3dbd9da2e112e09015bdcba3501f
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Dec 4 23:01:27 2018 +0100
+
+    [atomics.types.operations]/20 Replace "E.g." at start of sentence with "For example,". (#2558)
+
+commit aadf7684f1e6c2fe1fa15ffa0cf2ee45b5e56cd7
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Dec 3 22:54:57 2018 +0100
+
+    [re.grammar] Add missing closing parentheses. (#2552)
+
+commit 4fc0a426f700c03aeea5b5efe040af9f3c977df8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 1 14:32:10 2018 +0100
+
+    [utilities] Harmonize 'For T in Types' phrasing. (#2543)
+
+    No '...' for a pack expansion should appear after 'Types', and no index on 'T'.
+
+commit 334e9f546dcb786801b9bef428f7c0fb94bee79b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 1 03:34:10 2018 +0100
+
+    [dcl.init] Clarify standard conversions for built-in types (#2534)
+
+commit e6cd48f407698d882a08f2bc5e3aad8ea13b495e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 1 03:32:38 2018 +0100
+
+    [over.best.ics] Clarify ambiguous conversion sequence (#2532)
+
+commit 89f5b1dfbabf0b5755f4e516a3be9b1e2b78ffc2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 22:01:21 2018 +0100
+
+    [over.ics.ref] Use 'implicit conversion sequence',
+
+    not 'standard conversion sequence' where applicable.
+
+commit af1191e9f5a0ab93214849fbfed77f75b2da673b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 22:48:48 2018 +0100
+
+    [class.bit] Bit-fields of sufficient width can store any value of an enumeration,
+
+    not just values of enumerators.
+
+commit 5ef7f9cbb248402f6c74f01acba87292efb0b561
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 22:19:14 2018 +0100
+
+    [dcl.init.aggr] Resolve grammar confusion around arrays of unknown bound
+
+commit 197db8c1fd3e57bc5c622a5e0ea9ac3f0c974e85
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 28 08:04:34 2018 +0100
+
+    [dcl.inline,dcl.align] Strike redundant 'definition'
+
+    in phrases reading 'declaration or definition',
+    because a definition is also a declaration.
+
+commit ad6385ac9730786006205d6fdca92e1d45aea13a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 23:16:26 2018 +0100
+
+    [dcl.spec] Harmonize phrasing of restrictions on decl-specifiers
+
+commit f38c14be051d91bc6492d774d45a325154b7f307
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Nov 27 23:28:09 2018 +0100
+
+    [depr.locale.category] Don't parenthesize reference after 'in'. (#2526)
+
+commit 3ba8b56c0ffa84cf8fe7bf78234fb8694d4d1498
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Nov 27 12:10:20 2018 -0800
+
+    [atomics.types.generic] Remove note that tries to encourage
+    implementations to use the same size for atomic<T> as for T.
+
+    It's not appropriate for a note to contain "should" or implementation
+    encouragement of this kind. It's also bad advice.
+
+commit e23cbb5b79397dd07c4c7adbea35b90075c78268
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Tue Nov 27 03:11:37 2018 -0500
+
+    [allocator.uses.construction] the argument name is alloc, not allocator
+
+commit 41a8baa9f739154f2b8c3f6b9e8339ede031195b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 26 19:21:14 2018 -0800
+
+    [unord.req] Undo change accidentally made in wrong table cell.
+
+    The intended table cell was already correctly updated.
+
+commit 9a720cd36a749057061b245772fb243678876b13
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 11 20:53:10 2018 +0200
+
+    [dcl.enum] Merge duplicate normative paragraphs on redeclarations.
+
+    Also introduce the grammar non-terminal enum-head-name
+    to simplify the description.
+
+commit 5e37f798131c38a4c609af2b8c70ce0b7a6f102f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Apr 2 21:50:03 2018 +0200
+
+    [stmt.while] Simplify rewrite rule.
+
+commit 84d93372e79b218701611ae8599cf885fcaf13b1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 12:45:01 2018 +0100
+
+    [string.classes] Avoid special characters in stable labels
+
+    and rename [string.comparison] to [string.cmp] per convention
+
+commit 05f51e0963f8f7e9186062d97306df128ee1fdcc
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Nov 26 13:06:53 2018 -0800
+
+    [iterator.operations] Simplify distance requirements; change to expects
+
+commit 90bb6f50af1d0181a158552399739cdeaf0b6ad7
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Oct 17 14:09:22 2018 -0700
+
+    [iterator.operations] Simplify advance requirements; change to expects
+
+commit 12589ca08e44ad3c6c215998ccdd92af3c02ca3b
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Oct 17 14:08:27 2018 -0700
+
+    [iterator.operations] advance does not decrement by a negative count
+
+commit 5f757d356d241d4fa6313f7375a275a59958358d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 18 20:20:05 2018 +0200
+
+    [dcl.init.aggr] Add example for anonymous union
+
+    initialized by a designated-initializer-list.
+
+commit b7aa3fe5f4e774edd8fe6239e707e0e0b1b44b41
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 1 10:44:12 2018 +0100
+
+    [numeric.ops] Move [numerics.defns] to the point-of-use.
+
+commit 63d15762f452fcb4787b2ca7896d9bbfde7de3ad
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 12:36:20 2018 +0100
+
+    [alg.find.end] and [alg.search] should not use "subsequence"
+
+commit 0f16b26b5a06b8a3cd0596ead96c54146d7e3178
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Nov 7 14:16:30 2018 -0800
+
+    [over.ics.user] Mark "user-defined conversion sequence" as a term of art
+
+commit 7e32ffd6c031771bb3a7568eb40ebe3d6b3417aa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 15 19:42:52 2018 +0100
+
+    [over.best.ics] Turn 'such as' list into a note
+
+commit 915c784c12ec4570974a67e98d0086e1933d0733
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 23:42:17 2018 +0100
+
+    [iterators] Shorten labels for iterator concepts
+
+commit 3768294e5bac0fac1b40aee14c8615f6c3d2f08c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 23:35:13 2018 +0100
+
+    [iterators] Shorten stable labels for algorithm requirements
+
+commit fc0c0db579234fba09f87ee3fa7053f699066c2f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 11:59:42 2018 +0100
+
+    [ranges] Shorten and adjust stable labels
+
+commit fb5d52d59d6823d0e03b2e7ca85d76f43402efa8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 13:22:09 2018 +0100
+
+    [structure.summary] Add missing templated entities
+
+commit 944a64419594b455759168e089c5cd075ea848be
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 13:33:33 2018 +0100
+
+    [func.bind_front] Use unwrap_ref_decay_t
+
+commit 12c55fcdff724855444d3e3ddfcc24ad93d9dd6a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 13:54:46 2018 +0100
+
+    [dcl.attr.contract.check] Remove redundant statement that violation handler is implementation-defined
+
+commit ae11d65ac5df8a7e605f07bc1d36ed584002fd15
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 14:01:32 2018 +0100
+
+    [expr] Fix cross-references for 'composite pointer type'
+
+    to refer to [expr.type], not [expr.prop].
+
+commit 42f956e7e80a4dfd81608b366e4f7813332d7dc0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 26 18:31:42 2018 +0100
+
+    [temp] Use 'deduced as' instead of 'deduced to'
+
+    in comments explaining examples
+
+commit 602a81d2d88ec98fef3d4feeaf5b24079e1e2110
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Oct 12 17:35:23 2018 +0800
+
+    [class.mem] Add opaque-enum-declaration to member-declaration
+
+commit 8ddcba4252b4a45194b8fdf4ebd2a439cb5e5147
+Author: Kazutoshi SATODA <k_satoda@f2.dion.ne.jp>
+Date:   Tue Oct 30 08:58:23 2018 +0900
+
+    [conv.lval] Improve a bit more the note about std::nullptr_t case
+
+    - "read the object" -> "access the object"
+      The "read" was derived from the rule at [intro.execution], but it
+      didn't fit well here.
+    - "the object" -> "the object to which the glvalue refers"
+      Make it clear what "the object" refers to.
+
+    https://github.com/cplusplus/draft/pull/2372#pullrequestreview-169248002
+
+commit 0b35a4688d09a385488f0d23c296afa622d7b02e
+Author: Kazutoshi SATODA <k_satoda@f2.dion.ne.jp>
+Date:   Thu Oct 25 02:59:31 2018 +0900
+
+    [conv.lval] Improve the note about std::nullptr_t case
+
+    The meaning of "fetched from memory" is vague, and the two uses of term
+    "access" [defns.access] are inappropreate here because
+      - it causes undefined behavior to access an inactive member of a
+        union, based on the rule of out-of-lifetime object [basic.life]:
+        > The program has undefined behavior if:
+        >   - the glvalue is used to access the object, or
+      - it implies reading the referenced object of std::nullptr_t,
+        which is defined to be a side effect for volatile-qualified case.
+        [intro.execution]
+        > Reading an object designated by a volatile glvalue, ... are all
+        > side effects, ...
+
+commit a694c9131618fd71b65faa8022cd6210dfa760f7
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Sun Nov 11 21:31:03 2018 +0100
+
+    [expr.static.cast] Say 'lvalue denoting ...' instead of 'lvalue to ...'
+
+commit 2e054057e5a0db3e5563dd05286b04b55c3a3b87
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 21 12:02:41 2018 +0100
+
+    [basic.stc.dynamic.allocation] Fix cross-reference for get_new_handler
+
+commit d4439240b74cf044bc7626ed364eeba291ca79dd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Oct 9 21:06:30 2018 +0200
+
+    [basic.type.qualifier] Clarify the definitions of const/volatile object
+
+commit d348800a5b0c2e594cf5e0b6e22404d52731e263
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 11 09:47:10 2018 +0200
+
+    [dcl.spec.auto] Return type deduction should refer to templated entity
+
+commit 2aa12aea978a0a79b725ce7552a1803c282a1c93
+Author: Géry Ogam <gery.ogam@gmail.com>
+Date:   Mon Nov 26 10:28:28 2018 +0100
+
+    [basic.lval] Correct an article in the prvalue definition
+
+    An operator can have multiple operands.
+
+commit e63542071ba4acee0adb82bd1221fdb0158a4eef
+Author: Casey Carter <Casey@Carter.net>
+Date:   Sat Nov 17 16:29:38 2018 -0800
+
+    [cmp.categories,time.cal] Change "explicit constexpr" to "constexpr explicit"
+
+    Per discussion in #2371.
+
+commit e6bbbbf62cddcbc6cea43a7589cfbcc48817b74b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 26 00:27:52 2018 -0800
+
+    [unord.req] Clarify what r1 is and remove unnecessary variable e.
+
+commit 38f9dccc5abe1d53e28249bd09be79a25d9b2427
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Fri Nov 16 02:27:56 2018 -0800
+
+    [unord.req] Use bullets for the list of denoting variables.
+
+commit e6b8936788decfb6c29ea527f1195ec3679a1195
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Nov 26 00:17:04 2018 -0800
+
+    [func.def] Simplify "references to functions and references to objects"
+    to simply "references".
+
+commit dafbb9445f11ad231abbf72028c29b6dd77c9334
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 19 09:44:01 2018 +0100
+
+    [func.not_fn,func.bind_front] Some clarifications
+
+    'a target object' -> 'the target object'
+    render 'initializer' as a grammar term and add a cross-reference
+    to dcl.init
+    add cross-references to expr.call
+
+commit 40fc57e9efdf5159a981cd87c9d8d765fd3f29ae
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 23:11:27 2018 -0800
+
+    [iterators] Remove bogus "shall"s is "Expects" elements.
+
+commit 9110f52c0e9550472b55845ba1c063333a94ad17
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 21:46:09 2018 -0800
+
+    [range] [iterators] Replace uses of { I } -> Same<T>& requirement.
+
+    This form of requirement was made ill-formed by P1084R2. In its place,
+    use { I } -> Same<T&>, after discussion on the lib reflector.
+
+commit 00da6c53f744a1781a1ce23cd3026af9d87f1f8a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 21:42:11 2018 -0800
+
+    [incrementable.traits] [readable.traits] Remove redundant remove_const_t
+    on type that cannot be const-qualified.
+
+commit e57b65067a5c73e20f2287b0ca0782d5d7d0333a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 23 22:20:47 2018 -0800
+
+    [std.iterator.tags] Replace "the most specific category tag" with "a
+    category tag".
+
+    The new text was present in the Ranges wording, but with no insertion /
+    deletion markup to indicate that an edit was to be performed. However,
+    consultation with LWG revealed that this was an intentional edit missing
+    markup.
+
+commit 92326665186c9c4e29f058f5b8d0ae5ea9814465
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 17 15:29:01 2018 +0100
+
+    [pairs.spec,tuple.creation] Simplify description
+
+    by inlining unwrap_ref_decay_t into its point of use.
+
+commit d9521a91ab07548e888bd5be386822c0148a111f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 18:44:37 2018 -0800
+
+    [iostream.forward.overview] Convert incomplete wording with no normative
+    effect to an example.
+
+commit 6260a047c0f3120a0570e6418f201294e6442664
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Nov 22 23:58:55 2018 -0800
+
+    [diff.cpp17.input.output] Add ill-formed comment and a still well-formed use.
+
+commit a0a637a0b2797b2809982836c9330052a8465172
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 01:29:58 2018 -0800
+
+    [expr.prim.req.compound] Replace note that restates what
+    'immediately-declared constraint' means with an example.
+
+commit 27797625e16a95b8946a353b09a86544c411ce61
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 01:08:30 2018 -0800
+
+    [temp.param] Remove unused grammar production default-template-argument.
+
+commit 9b525539f0c7bf734be8e01db082fca775dbd028
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Nov 25 00:52:55 2018 -0800
+
+    [dcl.type.simple] Factor out decltype(e) wording into its own subclause.
+
+commit 4cc61d46edce136f5dfaeeee671ea58039b032e2
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 23 19:55:37 2018 -0800
+
+    [expr.prim.req.compound] Resolve conflict between P1084R2 and P1141R2.
+
+    Replace /qualified-concept-name/ with /type-constraint/ in grammar
+    for /return-type-requirement/, and rewrite the new bullet for
+    /return-type-requirement/ added in P1084R2 to use the term
+    immediately-declared constraint introduced in P1141R2.
+
+commit d4d65994bcf692c472cee2ed83db34e4c94266e6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Nov 24 23:40:25 2018 -0800
+
+    [expr.const] Remove redundant bullet from definition of manifestly
+    constant-evaluated. Constexpr variables are always usable in constant
+    expressions.
+
+commit e201f3325d8a91319c37a702e50d8032759fd822
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Nov 24 23:37:02 2018 -0800
+
+    [expr.const] Factor out some commonality from 'manifestly
+    constant-evaluated' and 'potentially constant evaluated'.
+
+commit e58439bce8af85e6569328272c2cfb73f5fc44d6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Nov 24 23:13:58 2018 -0800
+
+    [expr.const] Add missing definition of 'usable in constant expressions'
+    for (sub)objects and reference members.
+
+commit b4eec9d65bcd54430c02ac7e66c88e63360801e6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 14 23:45:01 2018 +0100
+
+    [c.mb.wcs] The parameter is called 's', not 'buf'
+
+commit f892418bf423d6495beaf75093db3dd97aff2d14
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 23 21:26:05 2018 -0800
+
+    [gram] Remove now-incorrect claim that a typedef-name naming a class is
+    a class-name.
+
+commit 8b70fdad014640772691057ada5b528bc8724b12
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 12 03:10:20 2018 +0100
+
+    [expr,class,temp] Remove vestigious references
+
+    to pseudo-destructor-name and the removed section [expr.pseudo].
+
+    Add xrefdelta entry for removed section.
+
+commit fb22bbd60aba1f3aaf9288ab08a7feeb8e4c0101
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Nov 23 19:51:28 2018 -0800
+
+    [expr.prim.req.compound] Change "is" to "has a" when refering to grammar terms.
+
+commit 9bcfe7de3dd5bd4ad429011e169fca583bfa30b0
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Tue Nov 20 23:16:11 2018 +0100
+
+    [dcl.fct] Add missing period after last sentence in example. (#2494)
+
+commit 12935b8549c0412f528b33b7795a19cda7ae8dd6
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Tue Nov 6 02:03:15 2018 -0500
+
+    [class.copy.assign] Use Oxford comma.
+
+    Also convert some text font spaces into tcode spaces.
+
+commit 9437d29c92b8c2e4e779acaa2677e2cbb8800414
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 6 03:37:18 2018 +0100
+
+    [thread] Remove class name repeated in subheadings (#2368)
+
+commit 8ae6a8fbd5e0b19e0c2fad3598c3693b72081606
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 6 03:36:58 2018 +0100
+
+    [input.output] Remove class name repeated in subheadings (#2366)
+
+commit 96028f0000bbe2709bcdefe0fe3edc24862529a7
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Oct 31 04:21:52 2018 -0700
+
+    [iterator.requirements.general] Operations satisfy requirements, not operations (#2375)
+
+    Drive-by: change "satisfy .... requirements" to "meet ... requirements".
+
+commit a43c2b30d71827325d8fdfbbd1488c570993adb7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 19 15:17:52 2018 +0200
+
+    [localization] Remove class name repeated in subheadings (#2364)
+
+commit 9405969f396d371284945904b534bd3f3e029d47
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 18 20:39:54 2018 +0200
+
+    [numerics] Remove class name repeated in subheadings (#2362)
+
+commit 4afc80a9ab5b78cb3c1fe70495e162d40f427116
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Oct 17 02:19:26 2018 -0700
+
+    [output.iterators] Remove misleading italics from note (#2360)
+
+    Since LWG asked me to remove these from P0896's OutputIterator, they probably don't belong in Cpp17OutputIterator either.
+
+commit 853f6bfc029f4d290c8a31da14f4282ee298cdc5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 15 16:10:00 2018 +0200
+
+    [iterators] Remove class name repeated in subheadings (#2358)
+
+commit 3a6d922f5ef5c3c77cfe74e39563879698716768
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 13 15:07:28 2018 +0200
+
+    [re] Remove class name repeated in subheadings (#2356)
+
+commit d0bb9916b779f6b113294ce9387063cad2f4b465
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 13 10:45:05 2018 +0200
+
+    [utilities] Remove class name repeated in subheadings (#2355)
+
+commit 506ec70eab720e757555be0059c5371ff4117fba
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Oct 10 23:35:18 2018 +0200
+
+    [class.this] Turn redundant statement on cv-qualified constructors/destructors
+    into a note.
+
+commit 7c0e7fd6396d5509027c390d9557f9642d30db42
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Oct 10 15:06:10 2018 +0100
+
+    [cpp.cond] Fix "carries_depencency" typo in table
+
+commit e8fee95850cc5a68ea09fb29f4e50c28632ed348
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Oct 9 23:24:28 2018 +0200
+
+    [basic.types] Clarify that 'value representation' does not depend on the value. (#2246)
+
diff --git a/papers/n4792.md b/papers/n4792.md new file mode 100644 index 0000000000..381bc6c844 --- /dev/null +++ b/papers/n4792.md @@ -0,0 +1,939 @@ +# N4792 Editors' Report -- Programming Languages -- C++ + +2018-12-07 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Special thanks to Casey Carter +and Tim Song +for supplying the LaTeX sources for +[P0896R4](http://wg21.link/p0896r4) (LWG motion 25, 208 pages of wording changes) +and +[P1148R0](http://wg21.link/p1148r0) (LWG motion 12, 55 pages of wording changes), +respectively, +and to Tony Van Eerd +for supplying a pull request for +[P1085R2](http://wg21.link/p1085r2) (LWG motion 23). + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4791](http://wg21.link/n4791) is the current working draft for C++20. It replaces [N4778](http://wg21.link/n4778). + * N4792 is this Editors' Report. + +Papers N4788 and N4789 (earlier versions of the post-San-Diego Working Draft +and Editors' Report) are withdrawn and replaced by the above papers due to an +administrative hiccup. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p1350r0) for 3 issues in "tentatively ready" status applied, resolving 4 issues: + + * [1636](http://wg21.link/cwg1636) Bits required for negative enumerator values **superseded by CWG Motion 10** + * [1781](http://wg21.link/cwg1781) Converting from `nullptr_t` to `bool` in overload resolution + * [2133](http://wg21.link/cwg2133) Converting `std::nullptr_t` to `bool` **resolved by resolution to CWG1781** + * [2373](http://wg21.link/cwg2373) Incorrect handling of static member function templates in partial ordering + +CWG motion 2: [P0668R5 "Revising the C++ memory model"](http://wg21.link/p0668r5) + +CWG motion 3: [P0982R1 "Weaken release sequences"](http://wg21.link/p0982r1) + +CWG motion 4: [P1084R2 "Today's *return-type-requirement*s are insufficient"](http://wg21.link/p1084r2) **see below** + +CWG motion 5: [P1131R2 "*simple-template-id* is ambiguous between *class-name* and *type-name*"](http://wg21.link/p1131r2), resolving 1 core issue: + + * [2292](http://wg21.link/cwg2292) *simple-template-id* is ambiguous between *class-name* and *type-name* + +CWG motion 6: [P1289R1 "Access control in contract conditions"](http://wg21.link/p1289r1) + +CWG motion 7 was not approved + +CWG motion 8: [P1002R1 "`try`-`catch` blocks in `constexpr` functions"](http://wg21.link/p1002r1) + +CWG motion 9: [P1327R1 "Allowing `dynamic_cast`, polymorphic `typeid` in constant expressions"](http://wg21.link/p1327r1) + +CWG motion 10: [P1236R1 "Signed integers are two's complement"](http://wg21.link/p1236r1) (wording for [P0907R4](http://wg21.link/p0907r4)) + +CWG motion 11: [P0482R6 "`char8_t`: a type for UTF-8 characters and strings"](http://wg21.link/p0482r6) **see below** + +CWG motion 12: [P1353R0 "Missing feature test macros"](http://wg21.link/p1353r0) + +CWG motion 13: [P1073R3 "Immediate functions"](http://wg21.link/p1073r3) + +CWG motion 14: [P0595R2 "`std::is_constant_evaluated()`"](http://wg21.link/p0595r2) **see below** + +CWG motion 15: [P1141R2 "Yet another approach for constrained declarations"](http://wg21.link/p1141r2) **see below** + +CWG motion 16: [P1094R2 "Nested inline namespaces"](http://wg21.link/p1094r2) + +CWG motion 17: [P1330R0 "Changing the active member of a union inside `constexpr`"](http://wg21.link/p1330r0) + +Core motions added a total of 1 page to Clause 1-14. + +### Library working group motions + +LWG motion 1 applies to the Concurrency TS + +LWG motions 2 and 3 apply to the Library Fundamentals TS + +LWG motion 4: [Library issue resolutions](http://wg21.link/p1224r0) for 9 issues in "Ready" status and 23 issues in "Tentatively Ready" status applied: + + * [2183](http://wg21.link/lwg2183) Muddled allocator requirements for `match_results` constructors + * [2184](http://wg21.link/lwg2184) Muddled allocator requirements for `match_results` assignments + * [2412](http://wg21.link/lwg2412) `promise::set_value()` and `promise::get_future()` should not race + * [2682](http://wg21.link/lwg2682) `filesystem::copy()` won't create a symlink to a directory + * [2936](http://wg21.link/lwg2936) Path comparison is defined in terms of the generic format + * [2943](http://wg21.link/lwg2943) Problematic specification of the wide version of `basic_filebuf::open` + * [2995](http://wg21.link/lwg2995) `basic_stringbuf` default constructor forbids it from using SSO capacity + * [2996](http://wg21.link/lwg2996) Missing rvalue overloads for `shared_ptr` operations + * [3008](http://wg21.link/lwg3008) `make_shared` (sub)object destruction semantics are not specified + * [3025](http://wg21.link/lwg3025) Map-like container deduction guides should use `pair`, not `pair` + * [3031](http://wg21.link/lwg3031) Algorithms and predicates with non-const reference arguments + * [3037](http://wg21.link/lwg3037) `polymorphic_allocator` and incomplete types + * [3038](http://wg21.link/lwg3038) `polymorphic_allocator::allocate` should not allow integer overflow to create vulnerabilities + * [3054](http://wg21.link/lwg3054) `uninitialized_copy` appears to not be able to meet its exception-safety guarantee + * [3065](http://wg21.link/lwg3065) [LWG 2989](http://wg21.link/lwg2989) missed that all `path`'s other operators should be hidden friends as well + * [3096](http://wg21.link/lwg3096) `path::lexically_relative` is confused by trailing slashes + * [3116](http://wg21.link/lwg3116) *OUTERMOST_ALLOC_TRAITS* needs `remove_reference_t` + * [3122](http://wg21.link/lwg3122) `__cpp_lib_chrono_udls` was accidentally dropped + * [3127](http://wg21.link/lwg3127) `basic_osyncstream::rdbuf` needs a `const_cast` + * [3128](http://wg21.link/lwg3128) `strstream::rdbuf` needs a `const_cast` + * [3129](http://wg21.link/lwg3129) `regex_token_iterator` constructor uses wrong pointer arithmetic + * [3130](http://wg21.link/lwg3130) [input.output] needs many `addressof` + * [3131](http://wg21.link/lwg3131) `addressof` all the things + * [3132](http://wg21.link/lwg3132) Library needs to ban macros named `expects` or `ensures` + * [3137](http://wg21.link/lwg3137) Header for `__cpp_lib_to_chars` + * [3140](http://wg21.link/lwg3140) *COMMON_REF* is unimplementable as specified + * [3145](http://wg21.link/lwg3145) `file_clock` breaks ABI for C++17 implementations + * [3147](http://wg21.link/lwg3147) Definitions of `likely` and `unlikely` are likely to cause problems + * [3148](http://wg21.link/lwg3148) `` should be freestanding + * [3153](http://wg21.link/lwg3153) `Common` and `common_type` have too little in common + * [3154](http://wg21.link/lwg3154) `Common` and `CommonReference` have a common defect + * [3160](http://wg21.link/lwg3160) `atomic_ref() = delete;` should be deleted + +LWG motion 5: [P1123R0 "Editorial guidance for merging P0019R8 and P0528R3"](http://wg21.link/p1123r0) (see [P0019R8](http://wg21.link/p0019r8), [P0528R3](http://wg21.link/p0528r3)) + +LWG motion 6: [P0487R1 "Fixing `operator>>(basic_istream&, CharT*)`"](http://wg21.link/p0487r1), resolving 1 library issue: + + * [2499](http://wg21.link/lwg2499) `operator>>(basic_istream&, CharT*)` makes it hard to avoid buffer overflows + +LWG motion 7: [P0602R4 "`variant` and `optional` should propagate copy/move triviality"](http://wg21.link/p0602r4) + +LWG motion 8: [P0655R1 "`visit`: explicit return type for `visit`"](http://wg21.link/p0655r1) + +LWG motion 9: [P0972R0 "`` `zero()`, `min()`, and `max()` should be `noexcept`"](http://wg21.link/p0972r0) + +LWG motion 10: [P1006R1 "`constexpr` in `std::pointer_traits`"](http://wg21.link/p1006r1) + +LWG motion 11: [P1032R1 "Miscellaneous `constexpr` bits"](http://wg21.link/p1032r1) **see below** + +LWG motion 12: [P1148R0 "Cleaning up clause 20 (strings)"](http://wg21.link/p1148r0) + +LWG motion 13: [P0318R1 "`unwrap_ref_decay` and `unwrap_reference`"](http://wg21.link/p0318r1) **see below** + +LWG motion 14: [P0357R3 "`reference_wrapper` for incomplete types"](http://wg21.link/p0357r3) + +LWG motion 15: [P0608R3 "A sane `variant` converting constructor"](http://wg21.link/p0608r3) + +LWG motion 16: [P0771R1 "`std::function` move constructor should be `noexcept`"](http://wg21.link/p0771r1) + +LWG motion 17: [P1007R3 "`std::assume_aligned`"](http://wg21.link/p1007r3) + +LWG motion 18: [P1020R1 "Smart pointer creation with default initialization"](http://wg21.link/p1020r1) + +LWG motion 19: [P1285R0 "Improving completeness requirements for type traits"](http://wg21.link/p1285r0) + +LWG motion 20: [P1248R1 "Remove `CommonReference` requirement from `StrictWeakOrdering`"](http://wg21.link/p1248r1) + +LWG motion 21: [P0591R4 "Utility functions to implement uses-allocator construction"](http://wg21.link/p0591r4) + +LWG motion 22: [P0899R1 "LWG 3016 is not a defect"](http://wg21.link/p0899r1) (see [LWG 3016](http://wg21.link/lwg3016)) + +LWG motion 23: [P1085R2 "Should `span` be regular?"](http://wg21.link/p1085r2) + +LWG motion 24: [P1165R1 "Make stateful allocator propagation more consistent for `operator+(basic_string)`"](http://wg21.link/p1165r1) + +LWG motion 25: [P0896R4 "The One Ranges proposal"](http://wg21.link/p0896r4) **see below** + +LWG motion 26: [P0356R5 "Simplified partial function application"](http://wg21.link/p0356r5) **see below** + +LWG motion 27: [P0919R3 "Heterogeneous lookup for unordered containers"](http://wg21.link/p0919r3) + +LWG motion 28: [P1209R0 "Adopt consistent container erasure from Library Fundamentals 2"](http://wg21.link/p1209r0) + +Library motions added a total of 133 pages (and 1 Clause) to Clause 15-31. + +## Notable editorial changes + +### CWG motion 11 and CWG motion 10 + +Rebased `char8_t` wording on the revised description of fundamental types +introduced by CWG motion 10. The description of `unsigned char` as the +underlying type of `char8_t` now renders unnecessary some of the other +wording in CWG motion 11; such wording has consequently not been applied. + +### CWG motion 14 + +After consulting with CWG, added the missing definition for "usable in constant +expressions" as applied to objects and references. + +### CWG motion 15 + +Removed now-unused grammar production *default-template-argument*. + +### CWG motion 15 and CWG motion 4 + +CWG motion 4 adds new uses of the grammar production *qualified-concept-name* +that CWG motion 15 removes. These have been updated to instead refer to the +new production *type-constraint*, and the normative wording of CWG motion 4 +has been rewritten to use the new term "immediately-declared constraint", +both of which were introduced by CWG motion 15. + +### LWG motion 11 + +Change 10 included an editing instruction to make matching changes elsewhere +in the draft. There does not appear to be any "elsewhere" to make said changes. +This editing instruction was ignored. + +### LWG motion 13 and LWG motion 26 + +The specification of `bind_front` was simplified by replacing *DECAY_UNWRAP* +a use of the new `unwrap_ref_decay_t` alias template introduced by LWG motion 13. + +### LWG motion 25 + +The wording paper contained an unmarked modification of [std.iterator.tags], +replacing "the most specific category tag" with "a category tag". +After consulting with the paper authors, the change was intentional, and +the corresponding edit has been applied despite not being marked up. + +### LWG motion 25 and CWG motion 4 + +CWG motion 4 removes a grammar production from *requires-clause*s, but +LWG motion 25 adds new uses of said grammar production. Those uses are all +of the form + +``` +requires { + { expr } -> Same&; +} +``` + +After consultation with LWG, these uses have been rewritten as + +``` +requires { + { expr } -> Same; +} +``` + +which is believed to both correctly reflect the intent and not change the +meaning in practice of any of the uses introduced by LWG motion 25. + +Additionally, CWG motion 4 contains an instruction to replace all constructs +of the form + +``` +requires { + E; requires Concept; +} +``` + +with the simpler (but now equivalent) + +``` +requires { + { E } -> Concept; +} +``` + +throughout [concepts]. However, LWG motion 25 adds many more instances of +the former pattern throughout several other clauses. All such instances +throughout the working draft have been replaced. + +### LWG motion 26 + +A feature test macro name `__cpp_lib_bind_front` was recommended by the paper, +but no wording changes were included to add said feature test macro to the +working draft's table of feature test macros. The macro has been added to +the table anyway. + +### Section label changes + +Several section labels introduced by the motions papers have been modified +to match our style guide. In addition to the section labels affected by the +above motions, the following changes have been made: + +[string.op+=] has been renamed to [string.op.append]. +[string.op+] has been renamed to [string.op.plus]. + +[re.regex.nmswap] was the only subclause in its parent [re.regex.nonmemb]. +The former heading has been removed, leaving the old content directly in +[re.regex.nonmemb]. + +[istream::sentry], +[ostream::sentry], +[ios::failure], +[ios::fmtflatgs], +[ios::iostate], +[ios::openmode], +[ios::seekdir], and +[ios::Init] +have been renamed, replacing the "::" with a "." +and converting "Init" to lowercase. + +See the appendix "Cross-references from ISO C++ 2017" in the working draft +for a full list of sectoin label changes since C++17. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4778 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/n4778...n4791). + + commit e00fef979f7c0da235351f898010658f1f074b87 + Author: Johel Ernesto Guerrero Peña + Date: Thu Dec 6 21:48:24 2018 -0400 + + [iterator.synopsis] Add reference to [alg.req.sortable] + + commit 9d81b4fde6dfe2b28737a79ed39f92ef9a0ee030 + Author: Eelis van der Weegen + Date: Sun Dec 2 06:07:03 2018 +0100 + + [view.interface] Use "inherits"/"derives" consistently. + + commit 358fcdc442fd620f00673081223e4313cf0af499 + Author: Jens Maurer + Date: Tue Nov 27 20:38:28 2018 +0100 + + [cpp.subst] Introduce grammar non-terminal 'va-opt-replacement' + + to avoid repeated quotes of the token sequence. + + commit 4425a120b9a60d3c9e6aa3f1feb553082a9f1fbd + Author: Jens Maurer + Date: Fri Dec 7 21:37:02 2018 +0100 + + [iterator.concepts.readable] Turn parenthesized explanation into a note. + + commit de1093907b6deb7455b866d5c47a6a1a026a90a1 + Author: Jens Maurer + Date: Fri Dec 7 22:27:20 2018 +0100 + + [temp.func.order] Adjust example to rules in [temp.deduct.partial]. + + commit 07901a9f724b019c0b6634a9a0c39e5dd5208324 + Author: Jens Maurer + Date: Sat Dec 1 17:31:53 2018 +0100 + + [input.output] Avoid colons in stable labels + + commit 6e5dba392d19241efed299c91670cc31fcbe3826 + Author: Thomas Köppe + Date: Fri Dec 7 22:05:50 2018 +0000 + + [template.mask.array.overview] Fix nesting of parentheses; reflow source + + commit 36998eae97c6876c1f67dc0425c42555dbf0cea5 + Author: Thomas Köppe + Date: Fri Dec 7 22:02:49 2018 +0000 + + [iterator.concept.iterator] Remove stray, mismatched parenthesis + + commit a5603f0cf1b35097a9892d9627eb03dc5cc3e154 + Author: JF Bastien + Date: Fri Dec 7 13:48:16 2018 -0800 + + [basic.fundamental] Remove a footnote that was describing a particular possible manifestation of undefined behaviour + + The note was problematic, as (by omission) it suggested that such behaviour might not be true for other types. + + commit 8035cdb6de85ff0f541b3fc78f747d060ea50ef6 + Author: Johel Ernesto Guerrero Peña + Date: Fri Dec 7 17:43:10 2018 -0400 + + [iterator.traits] Present concept requirements consistently (#2566) + + commit a4366dc5bf59d826a9b1aee82d317636a6239e9a + Author: Jens Maurer + Date: Fri Dec 7 21:51:55 2018 +0100 + + [iosfwd.syn] Change char_traits from 'class' to 'struct'. (#2570) + + commit 888da0bf8d0a07048dab8098197c7a326eda9e19 + Author: Thomas Köppe + Date: Wed Dec 5 01:46:53 2018 +0000 + + [algorithms] Add missing closing delimiters + + commit 14db6ec65b7c3dbd9da2e112e09015bdcba3501f + Author: Eelis + Date: Tue Dec 4 23:01:27 2018 +0100 + + [atomics.types.operations]/20 Replace "E.g." at start of sentence with "For example,". (#2558) + + commit aadf7684f1e6c2fe1fa15ffa0cf2ee45b5e56cd7 + Author: Eelis + Date: Mon Dec 3 22:54:57 2018 +0100 + + [re.grammar] Add missing closing parentheses. (#2552) + + commit 4fc0a426f700c03aeea5b5efe040af9f3c977df8 + Author: Jens Maurer + Date: Sat Dec 1 14:32:10 2018 +0100 + + [utilities] Harmonize 'For T in Types' phrasing. (#2543) + + No '...' for a pack expansion should appear after 'Types', and no index on 'T'. + + commit 334e9f546dcb786801b9bef428f7c0fb94bee79b + Author: Jens Maurer + Date: Sat Dec 1 03:34:10 2018 +0100 + + [dcl.init] Clarify standard conversions for built-in types (#2534) + + commit e6cd48f407698d882a08f2bc5e3aad8ea13b495e + Author: Jens Maurer + Date: Sat Dec 1 03:32:38 2018 +0100 + + [over.best.ics] Clarify ambiguous conversion sequence (#2532) + + commit 89f5b1dfbabf0b5755f4e516a3be9b1e2b78ffc2 + Author: Jens Maurer + Date: Tue Nov 27 22:01:21 2018 +0100 + + [over.ics.ref] Use 'implicit conversion sequence', + + not 'standard conversion sequence' where applicable. + + commit af1191e9f5a0ab93214849fbfed77f75b2da673b + Author: Jens Maurer + Date: Tue Nov 27 22:48:48 2018 +0100 + + [class.bit] Bit-fields of sufficient width can store any value of an enumeration, + + not just values of enumerators. + + commit 5ef7f9cbb248402f6c74f01acba87292efb0b561 + Author: Jens Maurer + Date: Tue Nov 27 22:19:14 2018 +0100 + + [dcl.init.aggr] Resolve grammar confusion around arrays of unknown bound + + commit 197db8c1fd3e57bc5c622a5e0ea9ac3f0c974e85 + Author: Jens Maurer + Date: Wed Nov 28 08:04:34 2018 +0100 + + [dcl.inline,dcl.align] Strike redundant 'definition' + + in phrases reading 'declaration or definition', + because a definition is also a declaration. + + commit ad6385ac9730786006205d6fdca92e1d45aea13a + Author: Jens Maurer + Date: Tue Nov 27 23:16:26 2018 +0100 + + [dcl.spec] Harmonize phrasing of restrictions on decl-specifiers + + commit f38c14be051d91bc6492d774d45a325154b7f307 + Author: Eelis + Date: Tue Nov 27 23:28:09 2018 +0100 + + [depr.locale.category] Don't parenthesize reference after 'in'. (#2526) + + commit 3ba8b56c0ffa84cf8fe7bf78234fb8694d4d1498 + Author: Richard Smith + Date: Tue Nov 27 12:10:20 2018 -0800 + + [atomics.types.generic] Remove note that tries to encourage + implementations to use the same size for atomic as for T. + + It's not appropriate for a note to contain "should" or implementation + encouragement of this kind. It's also bad advice. + + commit e23cbb5b79397dd07c4c7adbea35b90075c78268 + Author: Sergey Zubkov + Date: Tue Nov 27 03:11:37 2018 -0500 + + [allocator.uses.construction] the argument name is alloc, not allocator + + commit 41a8baa9f739154f2b8c3f6b9e8339ede031195b + Author: Richard Smith + Date: Mon Nov 26 19:21:14 2018 -0800 + + [unord.req] Undo change accidentally made in wrong table cell. + + The intended table cell was already correctly updated. + + commit 9a720cd36a749057061b245772fb243678876b13 + Author: Jens Maurer + Date: Thu Oct 11 20:53:10 2018 +0200 + + [dcl.enum] Merge duplicate normative paragraphs on redeclarations. + + Also introduce the grammar non-terminal enum-head-name + to simplify the description. + + commit 5e37f798131c38a4c609af2b8c70ce0b7a6f102f + Author: Jens Maurer + Date: Mon Apr 2 21:50:03 2018 +0200 + + [stmt.while] Simplify rewrite rule. + + commit 84d93372e79b218701611ae8599cf885fcaf13b1 + Author: Jens Maurer + Date: Mon Nov 26 12:45:01 2018 +0100 + + [string.classes] Avoid special characters in stable labels + + and rename [string.comparison] to [string.cmp] per convention + + commit 05f51e0963f8f7e9186062d97306df128ee1fdcc + Author: Casey Carter + Date: Mon Nov 26 13:06:53 2018 -0800 + + [iterator.operations] Simplify distance requirements; change to expects + + commit 90bb6f50af1d0181a158552399739cdeaf0b6ad7 + Author: Casey Carter + Date: Wed Oct 17 14:09:22 2018 -0700 + + [iterator.operations] Simplify advance requirements; change to expects + + commit 12589ca08e44ad3c6c215998ccdd92af3c02ca3b + Author: Casey Carter + Date: Wed Oct 17 14:08:27 2018 -0700 + + [iterator.operations] advance does not decrement by a negative count + + commit 5f757d356d241d4fa6313f7375a275a59958358d + Author: Jens Maurer + Date: Thu Oct 18 20:20:05 2018 +0200 + + [dcl.init.aggr] Add example for anonymous union + + initialized by a designated-initializer-list. + + commit b7aa3fe5f4e774edd8fe6239e707e0e0b1b44b41 + Author: Jens Maurer + Date: Thu Nov 1 10:44:12 2018 +0100 + + [numeric.ops] Move [numerics.defns] to the point-of-use. + + commit 63d15762f452fcb4787b2ca7896d9bbfde7de3ad + Author: Jens Maurer + Date: Mon Nov 26 12:36:20 2018 +0100 + + [alg.find.end] and [alg.search] should not use "subsequence" + + commit 0f16b26b5a06b8a3cd0596ead96c54146d7e3178 + Author: Casey Carter + Date: Wed Nov 7 14:16:30 2018 -0800 + + [over.ics.user] Mark "user-defined conversion sequence" as a term of art + + commit 7e32ffd6c031771bb3a7568eb40ebe3d6b3417aa + Author: Jens Maurer + Date: Thu Nov 15 19:42:52 2018 +0100 + + [over.best.ics] Turn 'such as' list into a note + + commit 915c784c12ec4570974a67e98d0086e1933d0733 + Author: Jens Maurer + Date: Mon Nov 26 23:42:17 2018 +0100 + + [iterators] Shorten labels for iterator concepts + + commit 3768294e5bac0fac1b40aee14c8615f6c3d2f08c + Author: Jens Maurer + Date: Mon Nov 26 23:35:13 2018 +0100 + + [iterators] Shorten stable labels for algorithm requirements + + commit fc0c0db579234fba09f87ee3fa7053f699066c2f + Author: Jens Maurer + Date: Mon Nov 26 11:59:42 2018 +0100 + + [ranges] Shorten and adjust stable labels + + commit fb5d52d59d6823d0e03b2e7ca85d76f43402efa8 + Author: Jens Maurer + Date: Mon Nov 26 13:22:09 2018 +0100 + + [structure.summary] Add missing templated entities + + commit 944a64419594b455759168e089c5cd075ea848be + Author: Jens Maurer + Date: Mon Nov 26 13:33:33 2018 +0100 + + [func.bind_front] Use unwrap_ref_decay_t + + commit 12c55fcdff724855444d3e3ddfcc24ad93d9dd6a + Author: Jens Maurer + Date: Mon Nov 26 13:54:46 2018 +0100 + + [dcl.attr.contract.check] Remove redundant statement that violation handler is implementation-defined + + commit ae11d65ac5df8a7e605f07bc1d36ed584002fd15 + Author: Jens Maurer + Date: Mon Nov 26 14:01:32 2018 +0100 + + [expr] Fix cross-references for 'composite pointer type' + + to refer to [expr.type], not [expr.prop]. + + commit 42f956e7e80a4dfd81608b366e4f7813332d7dc0 + Author: Jens Maurer + Date: Mon Nov 26 18:31:42 2018 +0100 + + [temp] Use 'deduced as' instead of 'deduced to' + + in comments explaining examples + + commit 602a81d2d88ec98fef3d4feeaf5b24079e1e2110 + Author: S. B. Tam + Date: Fri Oct 12 17:35:23 2018 +0800 + + [class.mem] Add opaque-enum-declaration to member-declaration + + commit 8ddcba4252b4a45194b8fdf4ebd2a439cb5e5147 + Author: Kazutoshi SATODA + Date: Tue Oct 30 08:58:23 2018 +0900 + + [conv.lval] Improve a bit more the note about std::nullptr_t case + + - "read the object" -> "access the object" + The "read" was derived from the rule at [intro.execution], but it + didn't fit well here. + - "the object" -> "the object to which the glvalue refers" + Make it clear what "the object" refers to. + + https://github.com/cplusplus/draft/pull/2372#pullrequestreview-169248002 + + commit 0b35a4688d09a385488f0d23c296afa622d7b02e + Author: Kazutoshi SATODA + Date: Thu Oct 25 02:59:31 2018 +0900 + + [conv.lval] Improve the note about std::nullptr_t case + + The meaning of "fetched from memory" is vague, and the two uses of term + "access" [defns.access] are inappropreate here because + - it causes undefined behavior to access an inactive member of a + union, based on the rule of out-of-lifetime object [basic.life]: + > The program has undefined behavior if: + > - the glvalue is used to access the object, or + - it implies reading the referenced object of std::nullptr_t, + which is defined to be a side effect for volatile-qualified case. + [intro.execution] + > Reading an object designated by a volatile glvalue, ... are all + > side effects, ... + + commit a694c9131618fd71b65faa8022cd6210dfa760f7 + Author: Eelis van der Weegen + Date: Sun Nov 11 21:31:03 2018 +0100 + + [expr.static.cast] Say 'lvalue denoting ...' instead of 'lvalue to ...' + + commit 2e054057e5a0db3e5563dd05286b04b55c3a3b87 + Author: Jens Maurer + Date: Wed Nov 21 12:02:41 2018 +0100 + + [basic.stc.dynamic.allocation] Fix cross-reference for get_new_handler + + commit d4439240b74cf044bc7626ed364eeba291ca79dd + Author: Jens Maurer + Date: Tue Oct 9 21:06:30 2018 +0200 + + [basic.type.qualifier] Clarify the definitions of const/volatile object + + commit d348800a5b0c2e594cf5e0b6e22404d52731e263 + Author: Jens Maurer + Date: Thu Oct 11 09:47:10 2018 +0200 + + [dcl.spec.auto] Return type deduction should refer to templated entity + + commit 2aa12aea978a0a79b725ce7552a1803c282a1c93 + Author: Géry Ogam + Date: Mon Nov 26 10:28:28 2018 +0100 + + [basic.lval] Correct an article in the prvalue definition + + An operator can have multiple operands. + + commit e63542071ba4acee0adb82bd1221fdb0158a4eef + Author: Casey Carter + Date: Sat Nov 17 16:29:38 2018 -0800 + + [cmp.categories,time.cal] Change "explicit constexpr" to "constexpr explicit" + + Per discussion in #2371. + + commit e6bbbbf62cddcbc6cea43a7589cfbcc48817b74b + Author: Richard Smith + Date: Mon Nov 26 00:27:52 2018 -0800 + + [unord.req] Clarify what r1 is and remove unnecessary variable e. + + commit 38f9dccc5abe1d53e28249bd09be79a25d9b2427 + Author: Dawn Perchik + Date: Fri Nov 16 02:27:56 2018 -0800 + + [unord.req] Use bullets for the list of denoting variables. + + commit e6b8936788decfb6c29ea527f1195ec3679a1195 + Author: Richard Smith + Date: Mon Nov 26 00:17:04 2018 -0800 + + [func.def] Simplify "references to functions and references to objects" + to simply "references". + + commit dafbb9445f11ad231abbf72028c29b6dd77c9334 + Author: Jens Maurer + Date: Mon Nov 19 09:44:01 2018 +0100 + + [func.not_fn,func.bind_front] Some clarifications + + 'a target object' -> 'the target object' + render 'initializer' as a grammar term and add a cross-reference + to dcl.init + add cross-references to expr.call + + commit 40fc57e9efdf5159a981cd87c9d8d765fd3f29ae + Author: Richard Smith + Date: Sun Nov 25 23:11:27 2018 -0800 + + [iterators] Remove bogus "shall"s is "Expects" elements. + + commit 9110f52c0e9550472b55845ba1c063333a94ad17 + Author: Richard Smith + Date: Sun Nov 25 21:46:09 2018 -0800 + + [range] [iterators] Replace uses of { I } -> Same& requirement. + + This form of requirement was made ill-formed by P1084R2. In its place, + use { I } -> Same, after discussion on the lib reflector. + + commit 00da6c53f744a1781a1ce23cd3026af9d87f1f8a + Author: Richard Smith + Date: Sun Nov 25 21:42:11 2018 -0800 + + [incrementable.traits] [readable.traits] Remove redundant remove_const_t + on type that cannot be const-qualified. + + commit e57b65067a5c73e20f2287b0ca0782d5d7d0333a + Author: Richard Smith + Date: Fri Nov 23 22:20:47 2018 -0800 + + [std.iterator.tags] Replace "the most specific category tag" with "a + category tag". + + The new text was present in the Ranges wording, but with no insertion / + deletion markup to indicate that an edit was to be performed. However, + consultation with LWG revealed that this was an intentional edit missing + markup. + + commit 92326665186c9c4e29f058f5b8d0ae5ea9814465 + Author: Jens Maurer + Date: Sat Nov 17 15:29:01 2018 +0100 + + [pairs.spec,tuple.creation] Simplify description + + by inlining unwrap_ref_decay_t into its point of use. + + commit d9521a91ab07548e888bd5be386822c0148a111f + Author: Richard Smith + Date: Sun Nov 25 18:44:37 2018 -0800 + + [iostream.forward.overview] Convert incomplete wording with no normative + effect to an example. + + commit 6260a047c0f3120a0570e6418f201294e6442664 + Author: Dawn Perchik + Date: Thu Nov 22 23:58:55 2018 -0800 + + [diff.cpp17.input.output] Add ill-formed comment and a still well-formed use. + + commit a0a637a0b2797b2809982836c9330052a8465172 + Author: Richard Smith + Date: Sun Nov 25 01:29:58 2018 -0800 + + [expr.prim.req.compound] Replace note that restates what + 'immediately-declared constraint' means with an example. + + commit 27797625e16a95b8946a353b09a86544c411ce61 + Author: Richard Smith + Date: Sun Nov 25 01:08:30 2018 -0800 + + [temp.param] Remove unused grammar production default-template-argument. + + commit 9b525539f0c7bf734be8e01db082fca775dbd028 + Author: Richard Smith + Date: Sun Nov 25 00:52:55 2018 -0800 + + [dcl.type.simple] Factor out decltype(e) wording into its own subclause. + + commit 4cc61d46edce136f5dfaeeee671ea58039b032e2 + Author: Richard Smith + Date: Fri Nov 23 19:55:37 2018 -0800 + + [expr.prim.req.compound] Resolve conflict between P1084R2 and P1141R2. + + Replace /qualified-concept-name/ with /type-constraint/ in grammar + for /return-type-requirement/, and rewrite the new bullet for + /return-type-requirement/ added in P1084R2 to use the term + immediately-declared constraint introduced in P1141R2. + + commit d4d65994bcf692c472cee2ed83db34e4c94266e6 + Author: Richard Smith + Date: Sat Nov 24 23:40:25 2018 -0800 + + [expr.const] Remove redundant bullet from definition of manifestly + constant-evaluated. Constexpr variables are always usable in constant + expressions. + + commit e201f3325d8a91319c37a702e50d8032759fd822 + Author: Richard Smith + Date: Sat Nov 24 23:37:02 2018 -0800 + + [expr.const] Factor out some commonality from 'manifestly + constant-evaluated' and 'potentially constant evaluated'. + + commit e58439bce8af85e6569328272c2cfb73f5fc44d6 + Author: Richard Smith + Date: Sat Nov 24 23:13:58 2018 -0800 + + [expr.const] Add missing definition of 'usable in constant expressions' + for (sub)objects and reference members. + + commit b4eec9d65bcd54430c02ac7e66c88e63360801e6 + Author: Jens Maurer + Date: Wed Nov 14 23:45:01 2018 +0100 + + [c.mb.wcs] The parameter is called 's', not 'buf' + + commit f892418bf423d6495beaf75093db3dd97aff2d14 + Author: Richard Smith + Date: Fri Nov 23 21:26:05 2018 -0800 + + [gram] Remove now-incorrect claim that a typedef-name naming a class is + a class-name. + + commit 8b70fdad014640772691057ada5b528bc8724b12 + Author: Jens Maurer + Date: Mon Nov 12 03:10:20 2018 +0100 + + [expr,class,temp] Remove vestigious references + + to pseudo-destructor-name and the removed section [expr.pseudo]. + + Add xrefdelta entry for removed section. + + commit fb22bbd60aba1f3aaf9288ab08a7feeb8e4c0101 + Author: Richard Smith + Date: Fri Nov 23 19:51:28 2018 -0800 + + [expr.prim.req.compound] Change "is" to "has a" when refering to grammar terms. + + commit 9bcfe7de3dd5bd4ad429011e169fca583bfa30b0 + Author: Eelis + Date: Tue Nov 20 23:16:11 2018 +0100 + + [dcl.fct] Add missing period after last sentence in example. (#2494) + + commit 12935b8549c0412f528b33b7795a19cda7ae8dd6 + Author: Arthur O'Dwyer + Date: Tue Nov 6 02:03:15 2018 -0500 + + [class.copy.assign] Use Oxford comma. + + Also convert some text font spaces into tcode spaces. + + commit 9437d29c92b8c2e4e779acaa2677e2cbb8800414 + Author: Jens Maurer + Date: Tue Nov 6 03:37:18 2018 +0100 + + [thread] Remove class name repeated in subheadings (#2368) + + commit 8ae6a8fbd5e0b19e0c2fad3598c3693b72081606 + Author: Jens Maurer + Date: Tue Nov 6 03:36:58 2018 +0100 + + [input.output] Remove class name repeated in subheadings (#2366) + + commit 96028f0000bbe2709bcdefe0fe3edc24862529a7 + Author: Casey Carter + Date: Wed Oct 31 04:21:52 2018 -0700 + + [iterator.requirements.general] Operations satisfy requirements, not operations (#2375) + + Drive-by: change "satisfy .... requirements" to "meet ... requirements". + + commit a43c2b30d71827325d8fdfbbd1488c570993adb7 + Author: Jens Maurer + Date: Fri Oct 19 15:17:52 2018 +0200 + + [localization] Remove class name repeated in subheadings (#2364) + + commit 9405969f396d371284945904b534bd3f3e029d47 + Author: Jens Maurer + Date: Thu Oct 18 20:39:54 2018 +0200 + + [numerics] Remove class name repeated in subheadings (#2362) + + commit 4afc80a9ab5b78cb3c1fe70495e162d40f427116 + Author: Casey Carter + Date: Wed Oct 17 02:19:26 2018 -0700 + + [output.iterators] Remove misleading italics from note (#2360) + + Since LWG asked me to remove these from P0896's OutputIterator, they probably don't belong in Cpp17OutputIterator either. + + commit 853f6bfc029f4d290c8a31da14f4282ee298cdc5 + Author: Jens Maurer + Date: Mon Oct 15 16:10:00 2018 +0200 + + [iterators] Remove class name repeated in subheadings (#2358) + + commit 3a6d922f5ef5c3c77cfe74e39563879698716768 + Author: Jens Maurer + Date: Sat Oct 13 15:07:28 2018 +0200 + + [re] Remove class name repeated in subheadings (#2356) + + commit d0bb9916b779f6b113294ce9387063cad2f4b465 + Author: Jens Maurer + Date: Sat Oct 13 10:45:05 2018 +0200 + + [utilities] Remove class name repeated in subheadings (#2355) + + commit 506ec70eab720e757555be0059c5371ff4117fba + Author: Jens Maurer + Date: Wed Oct 10 23:35:18 2018 +0200 + + [class.this] Turn redundant statement on cv-qualified constructors/destructors + into a note. + + commit 7c0e7fd6396d5509027c390d9557f9642d30db42 + Author: Jonathan Wakely + Date: Wed Oct 10 15:06:10 2018 +0100 + + [cpp.cond] Fix "carries_depencency" typo in table + + commit e8fee95850cc5a68ea09fb29f4e50c28632ed348 + Author: Jens Maurer + Date: Tue Oct 9 23:24:28 2018 +0200 + + [basic.types] Clarify that 'value representation' does not depend on the value. (#2246) diff --git a/papers/n4799.html b/papers/n4799.html new file mode 100644 index 0000000000..25dc644168 --- /dev/null +++ b/papers/n4799.html @@ -0,0 +1,572 @@ +N4799 +

N4799 Editors' Report -- Programming Languages -- C++

+ +

2019-01-21
+Richard Smith (editor) (Google Inc)
+Dawn Perchik (co-editor) (Bright Side Computing, LLC)
+Jens Maurer (co-editor)
+Thomas Köppe (co-editor) (Google DeepMind)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

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

+ +

New papers

+ +
    +
  • N4800 is the current C++ working draft. It replaces N4791.
  • +
  • N4799 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

This revision contains only editorial changes relative to N4791.

+ +

Notable editorial changes

+ +

DECAY_COPY

+ +

DECAY_COPY has been renamed to decay-copy +for consistency with other exposition-only entities, +and moved from +[thread.decaycopy] to [expos.only.func].

+ +

Other changes to section labels

+ +

[iterator.container] has been merged into [iterator.range], and +[range.prim] has been merged into [range.access].

+ +

The parts of [range.adaptors] that create new ranges rather than adapting +existing ranges have been split into a separate [range.factories].

+ +

The parts of [dcl.init] relating to indeterminate values have been moved to a +new [basic.indet].

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4791 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 2831ba3b8e1862a8a0e52d540b61062e72e89d6d
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Mon Jan 14 11:15:11 2019 -0500
+
+    [depr.strstreambuf.virtuals] Hyphenate "implementation-defined"
+
+commit d333390f0dd56dc9143731c1be00f66bc3752479
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 29 12:54:56 2018 +0100
+
+    [range.prim] merge into [range.access]
+
+commit dc3be11dd06a5edfa81061dce4b79fec2a8024df
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 29 12:54:26 2018 +0100
+
+    [iterator.container] merge into [iterator.range]
+
+commit 75dde78fd9ac709ff4843d1d5572d5cbfe4ac6d2
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Mon Jan 21 23:24:52 2019 +0800
+
+    [meta.const.eval] Fix typo in function name (#2650)
+
+commit 55577a76181134d1dd442af3f4eb36c4d861c7c9
+Author: kiroma <krzysio.kurek@wp.pl>
+Date:   Tue Jan 15 00:56:07 2019 +0100
+
+    [thread.condition] Improve description of efficiency of condition_variable.
+
+commit 281a8bd29f97b5249eae68fe0280e2dfda5ac714
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Mon Jan 7 18:37:20 2019 -0500
+
+    [ranges.syn] Fix a typo: "fowarding"
+
+commit 099022dbf1642541ab0d1c380ed26e8fb1244d86
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jan 2 22:29:51 2019 +0100
+
+    [unreachable.sentinel] 'open interval' -> 'unbounded interval'
+
+commit a9fdd8589a51617d5d60bf59263d1567076718ba
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Tue Jan 1 21:40:09 2019 -0500
+
+    Fix some `operator<=>` declarations with the wrong number of parameters.
+
+    Also one `operator<` that should at least have been a const member function.
+
+commit d42648926f4131586943b7dccb7df41bfbd8df5b
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Tue Jan 1 14:56:43 2019 +0100
+
+    [expr.prim.id.dtor] Fix comment in example.
+
+    In translation phase 3, the "0.T" in the line of code is parsed as a (single) preprocessing-token.
+
+    In phase 7, this preprocessing token is converted into a user-defined-floating-literal whose ud-suffix component is "T".
+
+    At no point is the "0." partial token a floating-point literal. At most, it is the fractional-constant component in a bigger user-defined-floating-literal token.
+
+    Fixes #2630.
+
+commit bac5e8438a9238730ae76e7ecf0899a52ef20fe0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 31 09:19:20 2018 +0100
+
+    [range.cmp] Deconfuse subclause heading.
+
+commit ede68b76f56ebb5bdf0692ab0ac2e5bcb68de96a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Dec 30 10:45:33 2018 +0100
+
+    [description] Drop 'informative' from the heading.
+
+    This subclause contains many normative definitions
+    (e.g. [operators]); marking it as 'informative' is
+    misleading.
+
+commit 5884d91293055be8b1ab494ef2ee5e675caad00c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Dec 30 10:41:21 2018 +0100
+
+    [expos.only.types] Exposition-only types apply more generally,
+
+    not just to capture language linkage.  For example,
+    'node-handle' is an entire exposition-only class.
+
+commit ce10ce47647e61ef8a308ad0aefcb2ff1094017a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Dec 30 10:28:16 2018 +0100
+
+    [expos.only.func] New home for global exposition-only functions.
+
+    Also introduce the descriptive mechanism of an
+    exposition-only function.
+    Remove [thread.decaycopy] by moving its contents here.
+    Use the spelling 'decay-copy' (italics code font) instead of
+    introducing an intermediate meta-macro DECAY_COPY.
+
+commit 6833990f6e090644df012c11ebc55b26c7580565
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 29 21:33:54 2018 +0100
+
+    [range.refinements] Rephrase heading to not use 'common range'
+
+    'Common range' means iterator and end marker have the same type;
+    see [range.req.general].  This is not what this subclause is about.
+
+commit 5874ecd6f82612873d4a40e14a3e93947b2ebab6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 29 13:27:54 2018 +0100
+
+    [special.mem.concepts] Use 'models ... only if' phrasing for semantic constraints.
+
+commit 1c3b991fac1b6668f42bde6824435f8ece037a10
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 29 12:43:27 2018 +0100
+
+    [range.factories] New subclause, split off from [range.adaptors]
+
+    Range adaptors take a range and produce a new range;
+    range factories take something else (or nothing) and produce a range.
+
+commit 3afb777a04ddb2e31292c4cf011475db5b65a9fc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 28 00:25:45 2018 +0100
+
+    [dcl.typedef] Use 'redeclare', not 'redefine'
+
+commit e88e605f3561546ab47d327d1865a576c415bc7b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 28 00:12:18 2018 +0100
+
+    [basic.life] Adjust subclause heading
+
+    and clarify that references are treated as-if requiring storage.
+
+commit 5d35f0c24e0724aee7993cef6085108fdfcd4590
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 21 20:44:23 2018 +0100
+
+    [iterators] Qualify declarator-id with sub-namespace.
+
+commit 4beab059b54b2fb859cc404b79682cbb71d76364
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 21 00:42:42 2018 +0100
+
+    [expr.new] A new-expression might not invoke a constructor
+
+commit 90467df5ce5b0dd92058dd13b082f6ed3bc16efc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 21 00:37:06 2018 +0100
+
+    [over.ics.user,over.ics.rank] Reference binding is part of the second SCS
+
+commit 8909a8f20249435788fa4f43e5199f2595a1e623
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Mon Dec 17 18:54:04 2018 +0100
+
+    [diff.dcl] Capitalize sentence.
+
+commit 64f01ee78bfac1450c6ffefbfe345a65ce951da1
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sun Dec 9 18:59:21 2018 -0400
+
+    [counted.iter.cmp] Add missing colon to specification element
+
+commit 3ff583af0448540f40e9db7cd07c30489696ecd7
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Dec 10 15:14:50 2018 -0400
+
+    [istreambuf.iterator] Remove duplicated declarations
+
+commit 64d61459522873003f4af52d4abab65cac2f48c5
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Dec 10 15:13:34 2018 -0400
+
+    [istream.iterator] Remove duplicated declarations
+
+commit 48acf476dedcb443407cadc189a79eb89f623097
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Dec 8 15:26:39 2018 -0400
+
+    [insert.iterators] Remove duplicated declarations
+
+commit 45f889a3fe071cadc80f97d58e1f905e8213455b
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Dec 8 14:14:55 2018 -0400
+
+    [iterator.synopsis] Drive-by add semantic breaks
+
+commit b72a3447c2a602aa6362fd0073c6683cedee2098
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Dec 8 14:13:36 2018 -0400
+
+    [move.iterator] Remove duplicated declarations
+
+commit 0fd872506cf6d30101eacd654b2133a5e090b654
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Dec 8 14:09:08 2018 -0400
+
+    [reverse.iterator] Remove duplicated declarations
+
+commit a1c3e9c0319f96e549fae711e616e41ff571cb6d
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Dec 8 14:08:20 2018 -0400
+
+    [iterators] Move specialization to synopsis
+
+commit eb1067835df26c6eef46d006420be2129758d7d0
+Author: Nicolas Lesser <blitzrakete@gmail.com>
+Date:   Sat Dec 8 19:32:21 2018 +0100
+
+    [expr.and,expr.or,expr.xor] Add grouping sentence to the binary and/or/xor operators.
+
+commit 27d19661fbb0a5424f72330724d9809618efbb8b
+Author: Géry Ogam <gery.ogam@gmail.com>
+Date:   Sat Jan 19 00:59:08 2019 +0100
+
+    [basic.lval] clarify the contexts where void expressions can appear and their value category
+
+commit 9c3b921635b041895d44f378ea3f534145e05006
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 25 19:16:06 2018 +0200
+
+    [basic.lookup,over.call.func] Clarify lookup rules for function calls.
+
+    Also add cross-references to [class.member.lookup] when
+    talking about 'looked up in the class of the object expression'
+    in [basic.lookup.classref].
+
+commit 0cd2126ddab16740d38a302f0da7fee5658f5fbb
+Author: Jonathan Caves <joncaves@microsoft.com>
+Date:   Mon Dec 17 14:16:45 2018 -0800
+
+    [expr.prim.lambda.capture] Add missing semicolons after statements ending in lambda expressions
+
+commit 1111bf9d422ebd3765730d95155860aeda07234a
+Author: Casey Carter <Casey@Carter.net>
+Date:   Sun Jan 6 04:16:39 2019 -0800
+
+    [allocator.requirements] relocate example to end of subclause
+
+    and add paragraph number.
+
+    Fixes #2639.
+
+commit b4f5a7e426c8b55c08e414aee434fe85c41e2a48
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Dec 29 21:01:42 2018 -0400
+
+    [ostreambuf.iterator] Remove tutorial-like sentence
+
+commit d902c5bfe137dc303fb5c7c54b6409cddac61cdc
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sun Dec 9 23:13:07 2018 -0400
+
+    [ostreambuf.iterator] Move description before the synopsis
+
+commit 486e7a2f8308a5f4d8aca20a74dd7a1ed2974a84
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Dec 29 20:59:51 2018 -0400
+
+    [istreambuf.iterator.proxy] Move description before class synopsis
+
+commit ca07d4deb68ffb9630d3f73a33f552d5040bab17
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sun Dec 9 21:54:51 2018 -0400
+
+    [istreambuf.iterator] Use nullptr instead of 0
+
+commit f9995862feaf47b85aabf7ec63ead2d5b00d5573
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sun Dec 9 21:49:56 2018 -0400
+
+    [ostream.iterator.ops] Check for non nullptr value implicitly
+
+commit b2cfef81694aa61a7c197ad58c96ee44f20f18ca
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sun Dec 9 21:28:50 2018 -0400
+
+    [ostream.iterator.cons.des] Use nullptr instead of null
+
+commit a97f9c18edcbcfb3cf10149116f4126a422ce1fe
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Dec 29 20:11:38 2018 -0400
+
+    [ostream.iterator] Remove redundant paragraph
+
+commit 8098533eabd9361b7798de7a44dea0277fc767e3
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Dec 29 20:11:03 2018 -0400
+
+    [ostream.iterator] Remove tutorial-like description
+
+commit c3a5aa19594a534f8bb9adc9b83f0eb703870699
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sun Dec 9 20:31:29 2018 -0400
+
+    [istream.iterator.ops] Unparenthesize return object name
+
+commit c84872ba9679e322ee2cded0b1a129d7b8faf2d0
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sun Dec 9 19:43:59 2018 -0400
+
+    [istream.iterator] Use nullptr instead of 0
+
+commit 169f0c41b51ba081e2c3e662276e9a4061567eaa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 19 22:01:18 2018 +0100
+
+    [iterator.primitives] Rescue introductory sentence.
+
+commit 98f1e9f668cbe109511fd8cee1afc03c4bb9f007
+Author: JF Bastien <github@jfbastien.com>
+Date:   Thu Dec 20 11:27:51 2018 -0800
+
+    [optional.assign] use injected class name consistently
+
+commit 597b6900151f810acd776e452f08c1e2941857b9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 19 21:41:46 2018 +0100
+
+    [reverse.iterators] Use the public accessor function,
+
+    not the exposition-only member 'current', from non-member functions.
+
+commit 3d9f80e990daf459a85cff539bd2ce64c0986886
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Dec 11 15:50:03 2018 -0400
+
+    [ranges.syn] Complete requires clause of view_interface
+
+commit a61eb25d048b96fd23b7544d12f43299ccf51026
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Dec 11 20:23:37 2018 -0400
+
+    [ranges.syn] Complete requires clause of filter_view
+
+commit 687b718c431c67a80888552c5055b0903fb197ba
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Dec 19 13:39:05 2018 -0800
+
+    [alg.min.max] Fix typo in returns element of ranges::minmax (#2600)
+
+    Also add linebreaks as appropriate after template-heads in declarations of `min`, `max`, and `minmax`.
+
+commit e7c5655a9a4746b895937aee4fdadfad30f02cfa
+Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com>
+Date:   Tue Dec 18 16:02:35 2018 +0100
+
+    [dcl.constexpr] Add "consteval" to subclause heading (#2597)
+
+commit a88d02d8d77e730bbf2730b6988a8b63319496c3
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Wed Dec 12 16:43:21 2018 +0100
+
+    [temp.mem.func] Remove inappropriate parentheses in 'Array<T>::operator[]()'.
+
+commit 4d9447fb590bf7fdc302706eb1560e6a402eca95
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Dec 8 10:09:29 2018 -0400
+
+    [reverse.iterator] Remove stray backslashes
+
+commit 54ddae362645af5028e622f92b795cd6d198c8a0
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri Dec 7 21:09:52 2018 -0400
+
+    [indirectcallable.general] Fix reference
+
+    Just 6 lines below, it is correct.
+
+commit 5aaec13ef8f29527e762f8e4bf8e2362c8b1419c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 7 23:03:51 2018 +0100
+
+    [basic.indet] Indeterminate values
+
+    Create a new section, moved from parts of [dcl.init].
+
+commit 9cf2dd2247af79721f4961c96dd9c57003556c94
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Dec 7 16:06:05 2018 -0800
+
+    [lex.key] Fix relative order of 'do' and 'double' in keywords table.
+
+commit 607ec0d6d6ce7c6e72c1cae63d22bbdf40eebd2c
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri Dec 7 19:28:30 2018 -0400
+
+    [iterator.concept.bidir] Add comma for clarity
+
diff --git a/papers/n4799.md b/papers/n4799.md new file mode 100644 index 0000000000..2d7736db33 --- /dev/null +++ b/papers/n4799.md @@ -0,0 +1,446 @@ +# N4799 Editors' Report -- Programming Languages -- C++ + +2019-01-21 +Richard Smith (editor) (Google Inc) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +Jens Maurer (co-editor) +Thomas Köppe (co-editor) (Google DeepMind) +`` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4800](http://wg21.link/n4800) is the current C++ working draft. It replaces [N4791](http://wg21.link/n4791). + * N4799 is this Editors' Report. + +## Motions incorporated into working draft + +This revision contains only editorial changes relative to N4791. + +## Notable editorial changes + +### `DECAY_COPY` + +`DECAY_COPY` has been renamed to *decay-copy* +for consistency with other exposition-only entities, +and moved from +[thread.decaycopy] to [expos.only.func]. + +### Other changes to section labels + +[iterator.container] has been merged into [iterator.range], and +[range.prim] has been merged into [range.access]. + +The parts of [range.adaptors] that create new ranges rather than adapting +existing ranges have been split into a separate [range.factories]. + +The parts of [dcl.init] relating to indeterminate values have been moved to a +new [basic.indet]. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4791 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/n4791...n4800). + + commit 2831ba3b8e1862a8a0e52d540b61062e72e89d6d + Author: Arthur O'Dwyer + Date: Mon Jan 14 11:15:11 2019 -0500 + + [depr.strstreambuf.virtuals] Hyphenate "implementation-defined" + + commit d333390f0dd56dc9143731c1be00f66bc3752479 + Author: Jens Maurer + Date: Sat Dec 29 12:54:56 2018 +0100 + + [range.prim] merge into [range.access] + + commit dc3be11dd06a5edfa81061dce4b79fec2a8024df + Author: Jens Maurer + Date: Sat Dec 29 12:54:26 2018 +0100 + + [iterator.container] merge into [iterator.range] + + commit 75dde78fd9ac709ff4843d1d5572d5cbfe4ac6d2 + Author: S. B. Tam + Date: Mon Jan 21 23:24:52 2019 +0800 + + [meta.const.eval] Fix typo in function name (#2650) + + commit 55577a76181134d1dd442af3f4eb36c4d861c7c9 + Author: kiroma + Date: Tue Jan 15 00:56:07 2019 +0100 + + [thread.condition] Improve description of efficiency of condition_variable. + + commit 281a8bd29f97b5249eae68fe0280e2dfda5ac714 + Author: Arthur O'Dwyer + Date: Mon Jan 7 18:37:20 2019 -0500 + + [ranges.syn] Fix a typo: "fowarding" + + commit 099022dbf1642541ab0d1c380ed26e8fb1244d86 + Author: Jens Maurer + Date: Wed Jan 2 22:29:51 2019 +0100 + + [unreachable.sentinel] 'open interval' -> 'unbounded interval' + + commit a9fdd8589a51617d5d60bf59263d1567076718ba + Author: Arthur O'Dwyer + Date: Tue Jan 1 21:40:09 2019 -0500 + + Fix some `operator<=>` declarations with the wrong number of parameters. + + Also one `operator<` that should at least have been a const member function. + + commit d42648926f4131586943b7dccb7df41bfbd8df5b + Author: Eelis van der Weegen + Date: Tue Jan 1 14:56:43 2019 +0100 + + [expr.prim.id.dtor] Fix comment in example. + + In translation phase 3, the "0.T" in the line of code is parsed as a (single) preprocessing-token. + + In phase 7, this preprocessing token is converted into a user-defined-floating-literal whose ud-suffix component is "T". + + At no point is the "0." partial token a floating-point literal. At most, it is the fractional-constant component in a bigger user-defined-floating-literal token. + + Fixes #2630. + + commit bac5e8438a9238730ae76e7ecf0899a52ef20fe0 + Author: Jens Maurer + Date: Mon Dec 31 09:19:20 2018 +0100 + + [range.cmp] Deconfuse subclause heading. + + commit ede68b76f56ebb5bdf0692ab0ac2e5bcb68de96a + Author: Jens Maurer + Date: Sun Dec 30 10:45:33 2018 +0100 + + [description] Drop 'informative' from the heading. + + This subclause contains many normative definitions + (e.g. [operators]); marking it as 'informative' is + misleading. + + commit 5884d91293055be8b1ab494ef2ee5e675caad00c + Author: Jens Maurer + Date: Sun Dec 30 10:41:21 2018 +0100 + + [expos.only.types] Exposition-only types apply more generally, + + not just to capture language linkage. For example, + 'node-handle' is an entire exposition-only class. + + commit ce10ce47647e61ef8a308ad0aefcb2ff1094017a + Author: Jens Maurer + Date: Sun Dec 30 10:28:16 2018 +0100 + + [expos.only.func] New home for global exposition-only functions. + + Also introduce the descriptive mechanism of an + exposition-only function. + Remove [thread.decaycopy] by moving its contents here. + Use the spelling 'decay-copy' (italics code font) instead of + introducing an intermediate meta-macro DECAY_COPY. + + commit 6833990f6e090644df012c11ebc55b26c7580565 + Author: Jens Maurer + Date: Sat Dec 29 21:33:54 2018 +0100 + + [range.refinements] Rephrase heading to not use 'common range' + + 'Common range' means iterator and end marker have the same type; + see [range.req.general]. This is not what this subclause is about. + + commit 5874ecd6f82612873d4a40e14a3e93947b2ebab6 + Author: Jens Maurer + Date: Sat Dec 29 13:27:54 2018 +0100 + + [special.mem.concepts] Use 'models ... only if' phrasing for semantic constraints. + + commit 1c3b991fac1b6668f42bde6824435f8ece037a10 + Author: Jens Maurer + Date: Sat Dec 29 12:43:27 2018 +0100 + + [range.factories] New subclause, split off from [range.adaptors] + + Range adaptors take a range and produce a new range; + range factories take something else (or nothing) and produce a range. + + commit 3afb777a04ddb2e31292c4cf011475db5b65a9fc + Author: Jens Maurer + Date: Fri Dec 28 00:25:45 2018 +0100 + + [dcl.typedef] Use 'redeclare', not 'redefine' + + commit e88e605f3561546ab47d327d1865a576c415bc7b + Author: Jens Maurer + Date: Fri Dec 28 00:12:18 2018 +0100 + + [basic.life] Adjust subclause heading + + and clarify that references are treated as-if requiring storage. + + commit 5d35f0c24e0724aee7993cef6085108fdfcd4590 + Author: Jens Maurer + Date: Fri Dec 21 20:44:23 2018 +0100 + + [iterators] Qualify declarator-id with sub-namespace. + + commit 4beab059b54b2fb859cc404b79682cbb71d76364 + Author: Jens Maurer + Date: Fri Dec 21 00:42:42 2018 +0100 + + [expr.new] A new-expression might not invoke a constructor + + commit 90467df5ce5b0dd92058dd13b082f6ed3bc16efc + Author: Jens Maurer + Date: Fri Dec 21 00:37:06 2018 +0100 + + [over.ics.user,over.ics.rank] Reference binding is part of the second SCS + + commit 8909a8f20249435788fa4f43e5199f2595a1e623 + Author: Eelis van der Weegen + Date: Mon Dec 17 18:54:04 2018 +0100 + + [diff.dcl] Capitalize sentence. + + commit 64f01ee78bfac1450c6ffefbfe345a65ce951da1 + Author: Johel Ernesto Guerrero Peña + Date: Sun Dec 9 18:59:21 2018 -0400 + + [counted.iter.cmp] Add missing colon to specification element + + commit 3ff583af0448540f40e9db7cd07c30489696ecd7 + Author: Johel Ernesto Guerrero Peña + Date: Mon Dec 10 15:14:50 2018 -0400 + + [istreambuf.iterator] Remove duplicated declarations + + commit 64d61459522873003f4af52d4abab65cac2f48c5 + Author: Johel Ernesto Guerrero Peña + Date: Mon Dec 10 15:13:34 2018 -0400 + + [istream.iterator] Remove duplicated declarations + + commit 48acf476dedcb443407cadc189a79eb89f623097 + Author: Johel Ernesto Guerrero Peña + Date: Sat Dec 8 15:26:39 2018 -0400 + + [insert.iterators] Remove duplicated declarations + + commit 45f889a3fe071cadc80f97d58e1f905e8213455b + Author: Johel Ernesto Guerrero Peña + Date: Sat Dec 8 14:14:55 2018 -0400 + + [iterator.synopsis] Drive-by add semantic breaks + + commit b72a3447c2a602aa6362fd0073c6683cedee2098 + Author: Johel Ernesto Guerrero Peña + Date: Sat Dec 8 14:13:36 2018 -0400 + + [move.iterator] Remove duplicated declarations + + commit 0fd872506cf6d30101eacd654b2133a5e090b654 + Author: Johel Ernesto Guerrero Peña + Date: Sat Dec 8 14:09:08 2018 -0400 + + [reverse.iterator] Remove duplicated declarations + + commit a1c3e9c0319f96e549fae711e616e41ff571cb6d + Author: Johel Ernesto Guerrero Peña + Date: Sat Dec 8 14:08:20 2018 -0400 + + [iterators] Move specialization to synopsis + + commit eb1067835df26c6eef46d006420be2129758d7d0 + Author: Nicolas Lesser + Date: Sat Dec 8 19:32:21 2018 +0100 + + [expr.and,expr.or,expr.xor] Add grouping sentence to the binary and/or/xor operators. + + commit 27d19661fbb0a5424f72330724d9809618efbb8b + Author: Géry Ogam + Date: Sat Jan 19 00:59:08 2019 +0100 + + [basic.lval] clarify the contexts where void expressions can appear and their value category + + commit 9c3b921635b041895d44f378ea3f534145e05006 + Author: Jens Maurer + Date: Thu Oct 25 19:16:06 2018 +0200 + + [basic.lookup,over.call.func] Clarify lookup rules for function calls. + + Also add cross-references to [class.member.lookup] when + talking about 'looked up in the class of the object expression' + in [basic.lookup.classref]. + + commit 0cd2126ddab16740d38a302f0da7fee5658f5fbb + Author: Jonathan Caves + Date: Mon Dec 17 14:16:45 2018 -0800 + + [expr.prim.lambda.capture] Add missing semicolons after statements ending in lambda expressions + + commit 1111bf9d422ebd3765730d95155860aeda07234a + Author: Casey Carter + Date: Sun Jan 6 04:16:39 2019 -0800 + + [allocator.requirements] relocate example to end of subclause + + and add paragraph number. + + Fixes #2639. + + commit b4f5a7e426c8b55c08e414aee434fe85c41e2a48 + Author: Johel Ernesto Guerrero Peña + Date: Sat Dec 29 21:01:42 2018 -0400 + + [ostreambuf.iterator] Remove tutorial-like sentence + + commit d902c5bfe137dc303fb5c7c54b6409cddac61cdc + Author: Johel Ernesto Guerrero Peña + Date: Sun Dec 9 23:13:07 2018 -0400 + + [ostreambuf.iterator] Move description before the synopsis + + commit 486e7a2f8308a5f4d8aca20a74dd7a1ed2974a84 + Author: Johel Ernesto Guerrero Peña + Date: Sat Dec 29 20:59:51 2018 -0400 + + [istreambuf.iterator.proxy] Move description before class synopsis + + commit ca07d4deb68ffb9630d3f73a33f552d5040bab17 + Author: Johel Ernesto Guerrero Peña + Date: Sun Dec 9 21:54:51 2018 -0400 + + [istreambuf.iterator] Use nullptr instead of 0 + + commit f9995862feaf47b85aabf7ec63ead2d5b00d5573 + Author: Johel Ernesto Guerrero Peña + Date: Sun Dec 9 21:49:56 2018 -0400 + + [ostream.iterator.ops] Check for non nullptr value implicitly + + commit b2cfef81694aa61a7c197ad58c96ee44f20f18ca + Author: Johel Ernesto Guerrero Peña + Date: Sun Dec 9 21:28:50 2018 -0400 + + [ostream.iterator.cons.des] Use nullptr instead of null + + commit a97f9c18edcbcfb3cf10149116f4126a422ce1fe + Author: Johel Ernesto Guerrero Peña + Date: Sat Dec 29 20:11:38 2018 -0400 + + [ostream.iterator] Remove redundant paragraph + + commit 8098533eabd9361b7798de7a44dea0277fc767e3 + Author: Johel Ernesto Guerrero Peña + Date: Sat Dec 29 20:11:03 2018 -0400 + + [ostream.iterator] Remove tutorial-like description + + commit c3a5aa19594a534f8bb9adc9b83f0eb703870699 + Author: Johel Ernesto Guerrero Peña + Date: Sun Dec 9 20:31:29 2018 -0400 + + [istream.iterator.ops] Unparenthesize return object name + + commit c84872ba9679e322ee2cded0b1a129d7b8faf2d0 + Author: Johel Ernesto Guerrero Peña + Date: Sun Dec 9 19:43:59 2018 -0400 + + [istream.iterator] Use nullptr instead of 0 + + commit 169f0c41b51ba081e2c3e662276e9a4061567eaa + Author: Jens Maurer + Date: Wed Dec 19 22:01:18 2018 +0100 + + [iterator.primitives] Rescue introductory sentence. + + commit 98f1e9f668cbe109511fd8cee1afc03c4bb9f007 + Author: JF Bastien + Date: Thu Dec 20 11:27:51 2018 -0800 + + [optional.assign] use injected class name consistently + + commit 597b6900151f810acd776e452f08c1e2941857b9 + Author: Jens Maurer + Date: Wed Dec 19 21:41:46 2018 +0100 + + [reverse.iterators] Use the public accessor function, + + not the exposition-only member 'current', from non-member functions. + + commit 3d9f80e990daf459a85cff539bd2ce64c0986886 + Author: Johel Ernesto Guerrero Peña + Date: Tue Dec 11 15:50:03 2018 -0400 + + [ranges.syn] Complete requires clause of view_interface + + commit a61eb25d048b96fd23b7544d12f43299ccf51026 + Author: Johel Ernesto Guerrero Peña + Date: Tue Dec 11 20:23:37 2018 -0400 + + [ranges.syn] Complete requires clause of filter_view + + commit 687b718c431c67a80888552c5055b0903fb197ba + Author: Casey Carter + Date: Wed Dec 19 13:39:05 2018 -0800 + + [alg.min.max] Fix typo in returns element of ranges::minmax (#2600) + + Also add linebreaks as appropriate after template-heads in declarations of `min`, `max`, and `minmax`. + + commit e7c5655a9a4746b895937aee4fdadfad30f02cfa + Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com> + Date: Tue Dec 18 16:02:35 2018 +0100 + + [dcl.constexpr] Add "consteval" to subclause heading (#2597) + + commit a88d02d8d77e730bbf2730b6988a8b63319496c3 + Author: Eelis van der Weegen + Date: Wed Dec 12 16:43:21 2018 +0100 + + [temp.mem.func] Remove inappropriate parentheses in 'Array::operator[]()'. + + commit 4d9447fb590bf7fdc302706eb1560e6a402eca95 + Author: Johel Ernesto Guerrero Peña + Date: Sat Dec 8 10:09:29 2018 -0400 + + [reverse.iterator] Remove stray backslashes + + commit 54ddae362645af5028e622f92b795cd6d198c8a0 + Author: Johel Ernesto Guerrero Peña + Date: Fri Dec 7 21:09:52 2018 -0400 + + [indirectcallable.general] Fix reference + + Just 6 lines below, it is correct. + + commit 5aaec13ef8f29527e762f8e4bf8e2362c8b1419c + Author: Jens Maurer + Date: Fri Dec 7 23:03:51 2018 +0100 + + [basic.indet] Indeterminate values + + Create a new section, moved from parts of [dcl.init]. + + commit 9cf2dd2247af79721f4961c96dd9c57003556c94 + Author: Richard Smith + Date: Fri Dec 7 16:06:05 2018 -0800 + + [lex.key] Fix relative order of 'do' and 'double' in keywords table. + + commit 607ec0d6d6ce7c6e72c1cae63d22bbdf40eebd2c + Author: Johel Ernesto Guerrero Peña + Date: Fri Dec 7 19:28:30 2018 -0400 + + [iterator.concept.bidir] Add comma for clarity diff --git a/papers/n4800.pdf b/papers/n4800.pdf new file mode 100644 index 0000000000..39de74ca82 Binary files /dev/null and b/papers/n4800.pdf differ diff --git a/papers/n4810.pdf b/papers/n4810.pdf new file mode 100644 index 0000000000..00eb319796 Binary files /dev/null and b/papers/n4810.pdf differ diff --git a/papers/n4811.html b/papers/n4811.html new file mode 100644 index 0000000000..bd7f20b7b7 --- /dev/null +++ b/papers/n4811.html @@ -0,0 +1,808 @@ +N4811 +

N4811 Editors' Report -- Programming Languages -- C++

+ +

2019-03-15
+Richard Smith (editor) (Google Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+Jens Maurer (co-editor)
+Dawn Perchik (co-editor) (Bright Side Computing, LLC)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to Marshall Clow +for supplying the LaTeX sources for

+ +
    +
  • P1458R1 (LWG motion 7, 42 pages of wording changes)
  • +
  • P1459R1 (LWG motion 8, 15 pages of wording changes)
  • +
  • P1463R1 (LWG motion 10, 119 pages of wording changes) and
  • +
  • P1464R1 (LWG motion 11, 60 pages of wording changes)
  • +
+ +

and to Gor Nishanov +for supplying a pull request for +P0912R5 (CWG motion 15, 22 pages of wording changes).

+ +

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

+ +

New papers

+ +
    +
  • N4810 is the current working draft for C++20. It replaces N4800.
  • +
  • N4811 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolutions for 14 issues in "ready" status applied, 1 not applied:

+ +
    +
  • 2256 Lifetime of trivially-destructible objects
  • +
  • 2267 Copy-initialization of temporary in reference direct-initialization
  • +
  • 2278 Copy elision in constant expressions reconsidered
  • +
  • 2303 Partial ordering and recursive variadic inheritance
  • +
  • 2309 Restrictions on nested statements within constexpr functions
  • +
  • 2310 Type completeness and derived-to-base pointer conversions see below
  • +
  • 2317 Self-referential default member initializers
  • +
  • 2318 Nondeduced contexts in deduction from a braced-init-list
  • +
  • 2330 Missing references to variable templates
  • +
  • 2331 Redundancy in description of class scope not applied, see below
  • +
  • 2332 template-name as simple-type-name vs injected-class-name see below
  • +
  • 2336 Destructor characteristics vs potentially-constructed subobjects
  • +
  • 2352 Similar types and reference binding
  • +
  • 2358 Explicit capture of value
  • +
  • 2360 [[maybe_unused]] and structured bindings
  • +
+ +

CWG motion 2: Core issue resolutions for 22 issues in "tentatively ready" status applied, resolving 24 issues:

+ +
    +
  • 581 Can a templated constructor be explicitly instantiated or specialized?
  • +
  • 1937 Incomplete specification of function pointer from lambda
  • +
  • 1938 Should hosted/freestanding be implementation-defined?
  • +
  • 2020 Inadequate description of odr-use of implicitly-invoked functions see below
  • +
  • 2051 Simplifying alias rules
  • +
  • 2083 Incorrect cases of odr-use
  • +
  • 2103 Lvalue-to-rvalue conversion is irrelevant in odr-use of a reference resolved by 2083
  • +
  • 2170 Unclear definition of odr-use for arrays resolved by 2083
  • +
  • 2257 Lifetime extension of references vs exceptions
  • +
  • 2266 Has dependent type vs is type-dependent
  • +
  • 2289 Uniqueness of structured binding names
  • +
  • 2353 Potential results of a member access expression for a static data member
  • +
  • 2354 Extended alignment and object representation
  • +
  • 2365 Confusing specification for dynamic_cast
  • +
  • 2368 Differences in relational and three-way constant comparisons
  • +
  • 2372 Incorrect matching rules for block-scope extern declarations
  • +
  • 2379 Missing prohibition against constexpr in friend declaration
  • +
  • 2380 capture-default makes too many references odr-usable
  • +
  • 2381 Composite pointer type of pointers to plain and noexcept member functions
  • +
  • 2384 Conversion function templates and qualification conversions
  • +
  • 2385 Lookup for conversion-function-ids
  • +
  • 2386 tuple_size requirements for structured binding
  • +
  • 2387 Linkage of const-qualified variable template
  • +
  • 2394 Const-default-constructible for members
  • +
+ +

CWG motion 3: P1286R2 "Contra CWG DR1778" (DR)

+ +
    +
  • Alters resolution of 1778 exception-specification in explicitly-defaulted functions
  • +
+ +

CWG motion 4: P1091R3 "Extending structured bindings to be more like variable declarations"

+ +

CWG motion 5: P1381R1 "Reference capture of structured bindings"

+ +

CWG motion 6: P1041R4 "Make char16_t/char32_t string literals be UTF-16/32"

+ +

CWG motion 7: P1139R2 "Address wording issues related to ISO 10646"

+ +

CWG motion 8: P1323R2 "Contract postconditions and return type deduction"

+ +

CWG motion 9: P0960R3 "Allow initializing aggregates from a parenthesized list of values"

+ +

CWG motion 10: P1009R2 "Array size deduction in new-expressions" (DR)

+ +

CWG motion 11: P1103R3 "Modules"

+ +

CWG motion 12: P1185R2 "<=> != =="

+ +

CWG motions 13 and 14 apply to the Reflection TS

+ +

CWG motion 15: P0912R5 "Coroutines"

+ +

Core motions added a total of 24 pages (and 1 Clause) to Clause 1-15

+ +

Library working group motions

+ +

LWG motion 1 applies to the Library Fundamentals TS

+ +

LWG motion 2: Library issue resolutions for 2 issues in Ready status and 11 issues in Tentatively Ready status applied:

+ +
    +
  • 3012 atomic is unimplementable for non-is_trivially_copy_constructible T
  • +
  • 3040 basic_string_view::starts_with Effects are incorrect
  • +
  • 3077 (push|emplace)_back should invalidate the end iterator
  • +
  • 3087 One final &x in [list.ops]
  • +
  • 3101 span's Container constructors need another constraint
  • +
  • 3112 system_error and filesystem_error constructors taking a string may not be able to meet their postconditions
  • +
  • 3119 Program-definedness of closure types
  • +
  • 3133 Modernizing numeric type requirements
  • +
  • 3144 span does not have a const_pointer typedef
  • +
  • 3173 Enable CTAD for ref-view
  • +
  • 3179 subrange should always model Range
  • +
  • 3180 Inconsistently named return type for ranges::minmax_element
  • +
  • 3182 Specification of Same could be clearer
  • +
+ +

LWG motion 3: P0339R6 "polymorphic_allocator<> as a vocabulary type"

+ +

LWG motion 4: P0340R3 "Making std::underlying_type SFINAE-friendly"

+ +

LWG motion 5 was retracted

+ +

LWG motion 6: P0738R2 "I Stream, You Stream, We All Stream for istream_iterator"

+ +

LWG motion 7: P1458R1 "Mandating the standard library: clause 16 - language support library"

+ +

LWG motion 8: P1459R1 "Mandating the standard library: clause 18 - diagnostics library"

+ +

LWG motion 9: P1462R1 "Mandating the standard library: clause 20 - strings library"

+ +

LWG motion 10: P1463R1 "Mandating the standard library: clause 21 - containers library"

+ +

LWG motion 11: P1464R1 "Mandating the standard library: clause 22 - iterators library"

+ +

LWG motion 12: P1164R1 "Make create_directory() intuitive" (DR)

+ +

LWG motion 13: P0811R3 "Well-behaved interpolation for numbers and pointers"

+ +

LWG motion 14: P1001R2 "Target vectorization policies from Parallelism V2 TS"

+ +

LWG motion 15: P1227R2 "Signed ssize() functions, unsigned size() functions "

+ +

LWG motion 16: P1252R2 "Ranges design cleanup"

+ +

LWG motion 17: P1024R3 "Usability enhancements for std::span"

+ +

LWG motion 18: P0920R2 "Precalculated hash values in lookup"

+ +

LWG motion 19: P1357R1 "Traits for [un]bounded arrays"

+ +

Library motions added a total of 7 pages to Clause 16-32.

+ +

Notable editorial changes

+ +

CWG motion 1

+ +

The edits for CWG2310 inadvertantly required the base class to be complete +instead of the derived class in one of the edits. After consultation with CWG, +the derived class is now required to be complete in all cases.

+ +

The edits for CWG2331 were intended to be an editorial cleanup and wording +simplification, but were found to have unintentional normative effect. This +issue is being returned to CWG for redrafting.

+ +

The edits for CWG2332 added a note that was not entirely accurate. The note, +along with the normative text that it references, have been rephrased to +clarify that an injected-class-name is never interpreted as a template-name +in a context in which class template argument deduction would apply (even +though it can be interpreted as a template-name in some cases in a context +where a decl-specifier might be parsed, such as in a template-argument).

+ +

CWG motion 2

+ +

The wording moved for CWG2020 inadvertantly omitted some edits that were part +of the wording reviewed by CWG. Those edits were not substantive, and have been +restored editorially.

+ +

CWG motion 12

+ +

Removed redundant restatement of the operator== symmetry rule in defaulted +operator!=; looking for reversed candidates and rewriting == expressions is +already handled by overload resolution, and a reversed operator== can never +be selected anyway because the two arguments are of the same type.

+ +

Likewise the corresponding redundant wording was removed from the rules for +defaulted operators <, >, <=, and >= that inaccurately claimed they +could select a reversed operator<=>.

+ +

CWG motion 15

+ +

Modernized the wording to follow current editorial conventions, and simplified +where possible.

+ +

Fixed a contradiction between the core and library wording; the library wording +allowed a coroutine_handle<> to resume any coroutine, but the core wording +did not account for that possibility and only permitted resumption via a +coroutine_handle<P> with the right promise type P.

+ +

LWG motion 2

+ +

Replaced the references to CopyConstructible and CopyAssignable with the +intended Cpp17CopyConstructible and Cpp17CopyAssignable after consultation +with LWG.

+ +

Section label changes

+ +

Several section labels introduced by the motions papers have been modified +to match our style guide. In addition to the section labels affected by the +above motions, all section labels containing underscores have been renamed +to instead use periods.

+ +

Reversion of prior editorial change

+ +

In N4791 (the post-San-Diego working draft), an editorial change was applied +to repair missing wording in 2018-11 CWG motion 14 +(P0595R2 "std::is_constant_evaluated()"). +This change added a definition of the term "usable in constant expressions" +as applied to objects and references that was inadvertantly dropped from the +wording during CWG review.

+ +

Further review within CWG has shown that the dropped wording is also incorrect, +so the editorial fix has been reverted (leaving the definition absent rather +than incorrect), and a proper definition will be inserted by a core issue.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4800 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 142acf0bbde8d6fd20cb67c051d896fec33a84b6
+Author: stryku <stryku2393@gmail.com>
+Date:   Thu Oct 11 18:41:18 2018 +0200
+
+    [decl.init]/10 Fix specified initialization.
+
+    According to [basic.start.static]/2, for objects with static storage duration,
+    zero initialization performs only if constant initialization does not.
+    [decl.init]/10 can be generalized to static initialization.
+    This is an editorial note change.
+
+commit 74def77454a15b6cdb45be0f31916396b4b63b72
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 15 13:45:06 2019 -0700
+
+    [util.smartptr.atomic.shared] [util.smartptr.atomic.weak] Clarify
+    grouping of "either".
+
+commit 4c5701a79cc7c4cc7b9cd9c6070e3cd88961aca7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 21 21:04:43 2018 +0100
+
+    [mismatch] LWG3178 std::mismatch is missing an upper bound
+
+commit 04a5e31a02e19e5d1c9e9a0b05c40ce8730c7064
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jan 26 00:30:13 2019 +0100
+
+    [algorithms] Qualify declarator-id with sub-namespace.
+
+    Also qualify return types where appropriate.
+
+commit 6c844190a533950fc0100eac4da7785d99c87400
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 15 20:25:59 2019 +0100
+
+    [time.clock.req] Change 'satisfy' to 'meet'.
+
+commit c3adaef44b94cc63a8a8806f398185046461947c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 15 19:23:30 2019 +0100
+
+    [numeric.requirements] Define 'numeric type'.
+
+commit 1ce86a62a3cff9fb2bcf6c1a2c37168e023e338b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 9 22:18:26 2019 +0100
+
+    [time.clock.req] Simplify requirements for Cpp17TrivialClock.
+
+commit 0ba5424c1beddfd8c8403ce882b96dee0f530c7f
+Author: JF Bastien <github@jfbastien.com>
+Date:   Fri Mar 15 13:52:39 2019 -0700
+
+    [basic.fundamental] Rename 'range exponent' to 'width' to align with C
+
+commit 9e00558f2a824421406a6703d1232cc4fb89bb15
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Fri Mar 15 16:43:16 2019 -0400
+
+    [std] Fix a bunch of faulty parallelism with "either".
+
+commit 54ddcb970132bfe026c9d9d62d967632b56ae303
+Author: BRevzin <barry.revzin@gmail.com>
+Date:   Fri Mar 15 15:30:07 2019 -0500
+
+    [class.rel] Simplifying wording to avoid talking about a reversed <=>.
+
+    We can never select a reversed <=> here because the operands are of the same type.
+
+commit 5d174b05d8cd08717ed7efc05d0271409651071c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 15 12:33:42 2019 -0700
+
+    [expr.prim.lambda.capture] Convert paragraphs repeating the
+    "non-odr-usable local entities shall not be odr-used" rule from
+    [basic.def.odr] into notes.
+
+commit 41853024e5e6fcd5feb496f64767d2888d76154f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 15 11:38:57 2019 -0700
+
+    Revert "[expr.const] Add missing definition of 'usable in constant expressions'"
+
+    The prior editorial fix was an attempt to re-add wording that was
+    missing from P0595R2 (moved as 2018-11 CWG Motion 14). However, CWG
+    analysis has indicated that the editorial fix is incomplete, so we're
+    reverting it to restore the wording to the as-moved state.
+
+    This reverts commit e58439bce8af85e6569328272c2cfb73f5fc44d6.
+
+commit 154f2c59c4377897937f4b0722cfe2b6d726cc59
+Author: birbacher <frank.birbacher@gmail.com>
+Date:   Fri Mar 15 18:39:16 2019 +0000
+
+    [container.node] Add 3 "template" keywords for dependent name (#2676)
+
+    On:
+    [container.node.overview]/4
+    [container.node.cons]/3.1
+    [container.node.dtor]/1
+
+commit 2585d7f5894b46e0aa2f961183060a5201b2cca7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 21 19:29:38 2018 +0100
+
+    [std] Replace underscores in stable labels with periods.
+
+commit 554a8926404bd5e0f772a6cb72c04bd12a5b7984
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Mar 4 09:29:50 2019 -0800
+
+    [specialized.algorithms] Rename voidify's parameter
+
+    `ptr` is an odd name for a parameter that is a reference to storage for an object.
+
+commit a2dfa61a0d50a24e7be6cbc004bb0f076b8c62b5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 8 22:25:38 2019 +0100
+
+    [queue.syn,stack.syn] Add partial specialization of uses_allocator
+
+commit 721f2d606f90cc20a16ad9b4383bc78cb368abdc
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Fri Mar 15 02:53:18 2019 +0000
+
+    [func.not_fn], [func.bind_front] fix phrasing of \mandates and \expects (#2750)
+
+    The Mandates: element should just state its condition, and not say "shall".
+    Cpp17 concept requirements should be phrased as "X meets the
+    Y requirements" not "X shall meet the requirements of Y".
+
+commit 48484c967ee5f3ecb65ff857f8f4794e108ba0cb
+Author: Krystian <sdkrystian@gmail.com>
+Date:   Thu Mar 14 22:49:33 2019 -0400
+
+    [temp.class.spec.mfunc] Correct "class template specialization" to the intended "class template partial specialization"
+
+commit 3117814eaf800a5e1dd387f4c5a0522f2627689e
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Fri Mar 15 05:48:28 2019 +0300
+
+    [expr.sizeof] Remove the redundant paragraph 3
+
+    Paragraph 1 already says that functions are disallowed and function pointers are allowed.
+
+commit c769f835dadd4a35df9febad684a296d6cb71a53
+Author: JF Bastien <github@jfbastien.com>
+Date:   Thu Mar 14 19:45:53 2019 -0700
+
+    [dcl.attr.contract.cond] Replace return type with 'void' in example that does not return
+
+    Also remove the (unused) name for the return value in the postcondition.
+
+commit d48c79e223cfbd5ec134703e20989235208e9364
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 8 01:14:16 2019 +0100
+
+    [dcl.enum] Fix singular/plural mismatch.
+
+commit c5fb73ba6a9b71f6e247103ab4baac1c9f72e210
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 8 01:13:35 2019 +0100
+
+    [conv.prom] b_min and b_max are no longer defined in [dcl.enum]
+
+commit d7d2580c7d8fabe25ada4dd0e091f9997c0916f5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 9 22:36:47 2019 +0100
+
+    [range.iota,range.adaptors] Add cross-references for private member types.
+
+commit b8fd249c737ff2c3652cf6ef77db25712038d353
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Mar 10 20:20:10 2019 +0100
+
+    [dcl.init] Prepend 'Otherwise' to a bullet
+
+commit dd227824ade24ab51dd4cc926c4b9e87cc29becf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Mar 10 20:28:41 2019 +0100
+
+    [dcl.attr.contract.cond] References cannot be modified.
+
+    Avoid confusion caused by using the words "makes [...]
+    modifications of the value of [a] parameter" by excluding
+    references.
+
+commit b0116b87bf33fed9648e6e8b1b0c7cee0d90b311
+Author: Jason Merrill <jason@redhat.com>
+Date:   Tue Mar 12 09:06:23 2019 -0400
+
+    [over.match.best] Add number for paragraph 2.
+
+commit f0f7ba234644d3690d18fcba73f618648014a47c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 13 22:21:42 2019 +0100
+
+    [lib] Use '(inclusive)', not other punctuation
+
+    to indicate inclusive ranges in prose.
+
+commit 5ba461ec9836f95ed7a54b563b06d480f564e987
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 13 22:46:19 2019 +0100
+
+    [class.eq,class.spaceship] Clarify order of comparison.
+
+commit 42e5df5c08c9ef805da304fe05fe387cfc3d33d5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Mar 14 00:02:25 2019 +0100
+
+    [basic.lookup.argdep] Reorder bullets to group semantics.
+
+commit 927dc13e1010e031692f3a94d8e9599beeb877ac
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 14 17:22:07 2019 -0700
+
+    [array.tuple] Fix broken description of tuple_element for std::array.
+
+commit 0b06fcd5f92bc0439a868471a5fdfdba8a181941
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 8 22:12:14 2019 +0100
+
+    [ranges.syn] Add ref_view to header synopsis.
+
+commit 6f6e5772b2a2dcf41e3db4f68b6cbc3c0628c061
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 14 16:05:33 2019 -0700
+
+    [algorithms.parallel.exec] Rephrase to avoid incorrect use of "may not".
+
+    Convert rationale sentence to a note.
+
+commit de76c7de8c4f9734e0e4351d2088d4786ee62135
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Mar 5 21:57:10 2019 +0100
+
+    [char.traits.typedefs] Change 'shall meet' to 'meets'
+
+commit e11e27a7873953f0c078901f7ddbb0d7d701c5f7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 6 21:15:37 2019 +0100
+
+    [mem.poly.allocator.mem] Avoid duplicate colons.
+
+commit 2956ba37186d7e9cbe728cc3870a2a26fb1f0168
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 13 14:14:43 2019 -0700
+
+    [dcl.fct.def.coroutine] Update wording to align with current editorial
+    conventions.
+
+    Reorder and rearrange to reduce the number of variables with long scopes
+    that we define in the wording.
+
+    Fix mismatch between core and library wording where library permits
+    coroutine_handle<void> to resume a coroutine with any promise type, and
+    the core language does not.
+
+commit 8dd4539b24473677809163f5e6d399ba6aa0b27d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Mar 12 18:15:59 2019 -0700
+
+    [expr.await] Rephrase and modernize wording.
+
+    Invoke temporary materialization conversion directly rather than
+    handwaving about a temporary object. Specify that the o expression is
+    evaluated. Bulletize description of the three different ways that
+    await-suspend is called.
+
+    Fix wording that uses values and objects on the left-hand side of a
+    class member access to instead consistently use expressions.
+
+    Fixes #2774.
+
+commit d69814f61077f7e549ccc39a21fc3b90db4223d6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 11 20:12:17 2019 -0700
+
+    [temp.param] "a type that is literal" -> "a literal type".
+
+commit c0058816fdfe079095ca8717ad692dc2d498d6a3
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 11 20:11:46 2019 -0700
+
+    [class.eq] Remove redundant repetition of the operator== symmetry rule.
+
+commit 007c0c1a619417f94c2c4efb57be71c09f2c2870
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 6 21:32:09 2019 +0100
+
+    [temp.type] Do not refer to operator==, which excludes built-in ==.
+
+commit caa5c8aedecdf68cfda4f5d95ec9d20451953117
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Mar 5 19:05:25 2019 +0100
+
+    [class.compare.default] Add a note that friends are found by ADL only.
+
+commit c9074b533c835bbf820f5ea09957810ed2c04dab
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 6 20:56:58 2019 +0100
+
+    [expr.new] Move treatment of arrays of unknown bound
+
+commit ce2f08ab94123adb44e58f1176c6ae4f3209eb60
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 11 17:20:25 2019 -0700
+
+    [dcl.init] Merge new direct aggregate init wording into class direct
+    initialization bullet to avoid the wording being unreachable due to an
+    "Otherwise" chain.
+
+commit 691b7c10530d3265afbf445dff3dd129c7c5692e
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Sun Mar 10 16:15:53 2019 -0700
+
+    [dcl.init] Moved the changed bullet in 17.5 to before 17.6.3.
+
+commit 5f7461d24bc0e9867458a043adf04aa8c4ceed73
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 8 16:11:34 2019 -0800
+
+    [temp.dep.type] Rephrase to avoid suggesting that an expression can be
+    the current instantiation.
+
+    A type can't be the current instantiation either, but that's a
+    pre-existing prevalent problem.
+
+commit cbb21fb0210b6aade5591de94e3a27d7059e9d06
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 8 16:08:02 2019 -0800
+
+    [basic.def.odr] Apply additional edits from CWG review that were not
+    transcribed into P1359R0.
+
+commit ac732bfe4eef01e9e2443dac6138270695d7cbf9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 8 12:24:49 2019 -0800
+
+    [expr.prim.lambda.capture] Add missing close parentheses in CWG2358
+    examples.
+
+    Fixes #2680.
+
+commit 502e419ca75c9656394d1998036b4b810e8bdb17
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 8 12:00:26 2019 -0800
+
+    [dcl.type.simple] Fix inaccurate note added by CWG2332
+
+    [temp.local] Clarify that the surrounding syntax and construct directly
+    dictates whether an injected-class-name is syntactically a template-name
+    or a type-name, not just what it means.
+
+commit f4346ece403e469e800d635a75baafb9c411aa1b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 8 11:39:36 2019 -0800
+
+    [expr.static.cast] Fix wording of CWG2310 to match CWG intent (verified
+    on core reflector):
+
+     - in p11, require D to be a complete class type, not B
+     - in p12, rephrase to avoid the suggestion that we're talking about a
+       different D than the one already in scope
+
+commit 6f34b0513ed6d974b86a27429f8f4d02a6c18b88
+Author: Hana Dusíková <hanicka@hanicka.net>
+Date:   Fri Feb 22 11:03:29 2019 -1000
+
+    [pair.astuple, tuple.helper] Fix inconsistent class key in tuple_size/tuple_element. (#2679)
+
+    It was declared as a struct and specializations were classes.
+
+commit 102a791b446f70f939a9b1e2e66fc3553aade19c
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri Feb 22 02:30:23 2019 -0400
+
+    [array.syn] Add reference to [array.tuple]
+
+commit 7fe655909b4e5f01d8a8b71d6b508785c42c739e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Feb 20 17:04:55 2019 -1000
+
+    [temp.dep] [temp.dep.res] Remove redundant restatement of the two-phase
+    lookup rule. The primary location of the rule is [temp.dep.candidate].
+
+commit 8fbeb52ae5daccc0352798ff023f6cba6aebcd42
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Feb 18 17:15:39 2019 -1000
+
+    [basic.link] The notion of the linkage of a type is no longer used for
+    any purpose. Remove it and move its example next to the rule that
+    justifies it, and simplify said example.
+
+commit cafdbd8036f3cf19e9cfc2f56584b219fb190602
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Fri Jan 25 00:12:44 2019 +0300
+
+    [expr.sizeof]/2: there are no expressions of reference type
+
+commit 35ce0ae2eb2582dbc00fc824afbfa1d53a64de8d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Feb 13 17:51:58 2019 -0800
+
+    [depr.array.comp] Fix example of deprecated array comparison
+
+commit 2f0bd979f41953890129fcbdc6ef37e3e90387ad
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sun Feb 10 16:53:15 2019 -0500
+
+    Add missing noexcept cross-refs for invokable traits (#2662)
+
+    All the other traits that use the phrase 'is known not to throw exceptions' also cross-reference the core clause for the noexcept operator, so add the missing cross reference to the more recently added traits.
+
+commit 9f261368736c3666791329145292c1563a291861
+Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com>
+Date:   Sun Feb 10 22:52:36 2019 +0100
+
+    [temp.mem.func] Fixed text in example, which was not updated by CWG 249 (#2658)
+
+commit f668df034ebf27ad53b5addad22af4f1293f829f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 10 22:50:42 2019 +0100
+
+    [algorithms.general,concepts.general] Add missing entries for summary tables (#2663)
+
diff --git a/papers/n4811.md b/papers/n4811.md new file mode 100644 index 0000000000..525110b06f --- /dev/null +++ b/papers/n4811.md @@ -0,0 +1,672 @@ +# N4811 Editors' Report -- Programming Languages -- C++ + +2019-03-15 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Special thanks to Marshall Clow +for supplying the LaTeX sources for + + * [P1458R1](http://wg21.link/p1458r1) (LWG motion 7, 42 pages of wording changes) + * [P1459R1](http://wg21.link/p1459r1) (LWG motion 8, 15 pages of wording changes) + * [P1463R1](http://wg21.link/p1463r1) (LWG motion 10, 119 pages of wording changes) and + * [P1464R1](http://wg21.link/p1464r1) (LWG motion 11, 60 pages of wording changes) + +and to Gor Nishanov +for supplying a pull request for +[P0912R5](http://wg21.link/p0912r5) (CWG motion 15, 22 pages of wording changes). + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4810](http://wg21.link/n4810) is the current working draft for C++20. It replaces [N4800](http://wg21.link/n4800). + * N4811 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p1358r0) for 14 issues in "ready" status applied, 1 not applied: + + * [2256](http://wg21.link/cwg2256) Lifetime of trivially-destructible objects + * [2267](http://wg21.link/cwg2267) Copy-initialization of temporary in reference direct-initialization + * [2278](http://wg21.link/cwg2278) Copy elision in constant expressions reconsidered + * [2303](http://wg21.link/cwg2303) Partial ordering and recursive variadic inheritance + * [2309](http://wg21.link/cwg2309) Restrictions on nested statements within constexpr functions + * [2310](http://wg21.link/cwg2310) Type completeness and derived-to-base pointer conversions **see below** + * [2317](http://wg21.link/cwg2317) Self-referential default member initializers + * [2318](http://wg21.link/cwg2318) Nondeduced contexts in deduction from a *braced-init-list* + * [2330](http://wg21.link/cwg2330) Missing references to variable templates + * [2331](http://wg21.link/cwg2331) Redundancy in description of class scope **not applied, see below** + * [2332](http://wg21.link/cwg2332) *template-name* as *simple-type-name* vs *injected-class-name* **see below** + * [2336](http://wg21.link/cwg2336) Destructor characteristics vs potentially-constructed subobjects + * [2352](http://wg21.link/cwg2352) Similar types and reference binding + * [2358](http://wg21.link/cwg2358) Explicit capture of value + * [2360](http://wg21.link/cwg2360) `[[maybe_unused]]` and structured bindings + +CWG motion 2: [Core issue resolutions](http://wg21.link/p1359r0) for 22 issues in "tentatively ready" status applied, resolving 24 issues: + + * [581](http://wg21.link/cwg581) Can a templated constructor be explicitly instantiated or specialized? + * [1937](http://wg21.link/cwg1937) Incomplete specification of function pointer from lambda + * [1938](http://wg21.link/cwg1938) Should hosted/freestanding be implementation-defined? + * [2020](http://wg21.link/cwg2020) Inadequate description of odr-use of implicitly-invoked functions **see below** + * [2051](http://wg21.link/cwg2051) Simplifying alias rules + * [2083](http://wg21.link/cwg2083) Incorrect cases of odr-use + * [2103](http://wg21.link/cwg2103) Lvalue-to-rvalue conversion is irrelevant in odr-use of a reference **resolved by 2083** + * [2170](http://wg21.link/cwg2170) Unclear definition of odr-use for arrays **resolved by 2083** + * [2257](http://wg21.link/cwg2257) Lifetime extension of references vs exceptions + * [2266](http://wg21.link/cwg2266) Has dependent type vs is type-dependent + * [2289](http://wg21.link/cwg2289) Uniqueness of structured binding names + * [2353](http://wg21.link/cwg2353) Potential results of a member access expression for a static data member + * [2354](http://wg21.link/cwg2354) Extended alignment and object representation + * [2365](http://wg21.link/cwg2365) Confusing specification for `dynamic_cast` + * [2368](http://wg21.link/cwg2368) Differences in relational and three-way constant comparisons + * [2372](http://wg21.link/cwg2372) Incorrect matching rules for block-scope extern declarations + * [2379](http://wg21.link/cwg2379) Missing prohibition against `constexpr` in friend declaration + * [2380](http://wg21.link/cwg2380) *capture-default* makes too many references odr-usable + * [2381](http://wg21.link/cwg2381) Composite pointer type of pointers to plain and `noexcept` member functions + * [2384](http://wg21.link/cwg2384) Conversion function templates and qualification conversions + * [2385](http://wg21.link/cwg2385) Lookup for *conversion-function-id*s + * [2386](http://wg21.link/cwg2386) `tuple_size` requirements for structured binding + * [2387](http://wg21.link/cwg2387) Linkage of const-qualified variable template + * [2394](http://wg21.link/cwg2394) Const-default-constructible for members + +CWG motion 3: [P1286R2 "Contra CWG DR1778"](http://wg21.link/p1286r2) **(DR)** + + * Alters resolution of [1778](http://wg21.link/cwg1778) *exception-specification* in explicitly-defaulted functions + +CWG motion 4: [P1091R3 "Extending structured bindings to be more like variable declarations"](http://wg21.link/p109133) + +CWG motion 5: [P1381R1 "Reference capture of structured bindings"](http://wg21.link/p138131) + +CWG motion 6: [P1041R4 "Make `char16_t`/`char32_t` string literals be UTF-16/32"](http://wg21.link/p104134) + +CWG motion 7: [P1139R2 "Address wording issues related to ISO 10646"](http://wg21.link/p113932) + +CWG motion 8: [P1323R2 "Contract postconditions and return type deduction"](http://wg21.link/p132332) + +CWG motion 9: [P0960R3 "Allow initializing aggregates from a parenthesized list of values"](http://wg21.link/p096033) + +CWG motion 10: [P1009R2 "Array size deduction in *new-expressions*"](http://wg21.link/p1009r2) **(DR)** + +CWG motion 11: [P1103R3 "Modules"](http://wg21.link/p110333) + +CWG motion 12: [P1185R2 "`<=>` `!=` `==`"](http://wg21.link/p118532) + +CWG motions 13 and 14 apply to the Reflection TS + +CWG motion 15: [P0912R5 "Coroutines"](http://wg21.link/p091235) + +Core motions added a total of 24 pages (and 1 Clause) to Clause 1-15 + +### Library working group motions + +LWG motion 1 applies to the Library Fundamentals TS + +LWG motion 2: [Library issue resolutions](http://wg21.link/p1457r0) for 2 issues in Ready status and 11 issues in Tentatively Ready status applied: + + * [3012](http://wg21.link/lwg3012) `atomic` is unimplementable for non-`is_trivially_copy_constructible` `T` + * [3040](http://wg21.link/lwg3040) `basic_string_view::starts_with` *Effects* are incorrect + * [3077](http://wg21.link/lwg3077) (`push`|`emplace`)`_back` should invalidate the end iterator + * [3087](http://wg21.link/lwg3087) One final `&x` in [list.ops] + * [3101](http://wg21.link/lwg3101) `span`'s `Container` constructors need another constraint + * [3112](http://wg21.link/lwg3112) `system_error` and `filesystem_error` constructors taking a `string` may not be able to meet their postconditions + * [3119](http://wg21.link/lwg3119) Program-definedness of closure types + * [3133](http://wg21.link/lwg3133) Modernizing numeric type requirements + * [3144](http://wg21.link/lwg3144) `span` does not have a `const_pointer` typedef + * [3173](http://wg21.link/lwg3173) Enable CTAD for *`ref-view`* + * [3179](http://wg21.link/lwg3179) `subrange` should always model `Range` + * [3180](http://wg21.link/lwg3180) Inconsistently named return type for `ranges::minmax_element` + * [3182](http://wg21.link/lwg3182) Specification of `Same` could be clearer + +LWG motion 3: [P0339R6 "`polymorphic_allocator<>` as a vocabulary type"](http://wg21.link/p033936) + +LWG motion 4: [P0340R3 "Making `std::underlying_type` SFINAE-friendly"](http://wg21.link/p034033) + +LWG motion 5 was retracted + +LWG motion 6: [P0738R2 "I Stream, You Stream, We All Stream for `istream_iterator`"](http://wg21.link/p073832) + +LWG motion 7: [P1458R1 "Mandating the standard library: clause 16 - language support library"](http://wg21.link/p145831) + +LWG motion 8: [P1459R1 "Mandating the standard library: clause 18 - diagnostics library"](http://wg21.link/p145931) + +LWG motion 9: [P1462R1 "Mandating the standard library: clause 20 - strings library"](http://wg21.link/p146231) + +LWG motion 10: [P1463R1 "Mandating the standard library: clause 21 - containers library"](http://wg21.link/p146331) + +LWG motion 11: [P1464R1 "Mandating the standard library: clause 22 - iterators library"](http://wg21.link/p146431) + +LWG motion 12: [P1164R1 "Make `create_directory()` intuitive"](http://wg21.link/p116431) **(DR)** + +LWG motion 13: [P0811R3 "Well-behaved interpolation for numbers and pointers"](http://wg21.link/p081133) + +LWG motion 14: [P1001R2 "Target vectorization policies from Parallelism V2 TS"](http://wg21.link/p100132) + +LWG motion 15: [P1227R2 "Signed `ssize()` functions, unsigned `size()` functions "](http://wg21.link/p122732) + +LWG motion 16: [P1252R2 "Ranges design cleanup"](http://wg21.link/p125232) + +LWG motion 17: [P1024R3 "Usability enhancements for `std::span`"](http://wg21.link/p102433) + +LWG motion 18: [P0920R2 "Precalculated hash values in lookup"](http://wg21.link/p092032) + +LWG motion 19: [P1357R1 "Traits for [un]bounded arrays"](http://wg21.link/p135731) + +Library motions added a total of 7 pages to Clause 16-32. + +## Notable editorial changes + +### CWG motion 1 + +The edits for CWG2310 inadvertantly required the base class to be complete +instead of the derived class in one of the edits. After consultation with CWG, +the derived class is now required to be complete in all cases. + +The edits for CWG2331 were intended to be an editorial cleanup and wording +simplification, but were found to have unintentional normative effect. This +issue is being returned to CWG for redrafting. + +The edits for CWG2332 added a note that was not entirely accurate. The note, +along with the normative text that it references, have been rephrased to +clarify that an injected-class-name is never interpreted as a *template-name* +in a context in which class template argument deduction would apply (even +though it can be interpreted as a *template-name* in some cases in a context +where a *decl-specifier* might be parsed, such as in a *template-argument*). + +### CWG motion 2 + +The wording moved for CWG2020 inadvertantly omitted some edits that were part +of the wording reviewed by CWG. Those edits were not substantive, and have been +restored editorially. + +### CWG motion 12 + +Removed redundant restatement of the `operator==` symmetry rule in defaulted +`operator!=`; looking for reversed candidates and rewriting `==` expressions is +already handled by overload resolution, and a reversed `operator==` can never +be selected anyway because the two arguments are of the same type. + +Likewise the corresponding redundant wording was removed from the rules for +defaulted operators `<`, `>`, `<=`, and `>=` that inaccurately claimed they +could select a reversed `operator<=>`. + +### CWG motion 15 + +Modernized the wording to follow current editorial conventions, and simplified +where possible. + +Fixed a contradiction between the core and library wording; the library wording +allowed a `coroutine_handle<>` to resume any coroutine, but the core wording +did not account for that possibility and only permitted resumption via a +`coroutine_handle

` with the right promise type `P`. + +### LWG motion 2 + +Replaced the references to *CopyConstructible* and *CopyAssignable* with the +intended *Cpp17CopyConstructible* and *Cpp17CopyAssignable* after consultation +with LWG. + +### Section label changes + +Several section labels introduced by the motions papers have been modified +to match our style guide. In addition to the section labels affected by the +above motions, all section labels containing underscores have been renamed +to instead use periods. + +### Reversion of prior editorial change + +In N4791 (the post-San-Diego working draft), an editorial change was applied +to repair missing wording in 2018-11 CWG motion 14 +([P0595R2 "`std::is_constant_evaluated()`"](http://wg21.link/p0595r2)). +This change added a definition of the term "usable in constant expressions" +as applied to objects and references that was inadvertantly dropped from the +wording during CWG review. + +Further review within CWG has shown that the dropped wording is also incorrect, +so the editorial fix has been reverted (leaving the definition absent rather +than incorrect), and a proper definition will be inserted by a core issue. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4800 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/n4800...n4810). + + commit 142acf0bbde8d6fd20cb67c051d896fec33a84b6 + Author: stryku + Date: Thu Oct 11 18:41:18 2018 +0200 + + [decl.init]/10 Fix specified initialization. + + According to [basic.start.static]/2, for objects with static storage duration, + zero initialization performs only if constant initialization does not. + [decl.init]/10 can be generalized to static initialization. + This is an editorial note change. + + commit 74def77454a15b6cdb45be0f31916396b4b63b72 + Author: Richard Smith + Date: Fri Mar 15 13:45:06 2019 -0700 + + [util.smartptr.atomic.shared] [util.smartptr.atomic.weak] Clarify + grouping of "either". + + commit 4c5701a79cc7c4cc7b9cd9c6070e3cd88961aca7 + Author: Jens Maurer + Date: Fri Dec 21 21:04:43 2018 +0100 + + [mismatch] LWG3178 std::mismatch is missing an upper bound + + commit 04a5e31a02e19e5d1c9e9a0b05c40ce8730c7064 + Author: Jens Maurer + Date: Sat Jan 26 00:30:13 2019 +0100 + + [algorithms] Qualify declarator-id with sub-namespace. + + Also qualify return types where appropriate. + + commit 6c844190a533950fc0100eac4da7785d99c87400 + Author: Jens Maurer + Date: Fri Mar 15 20:25:59 2019 +0100 + + [time.clock.req] Change 'satisfy' to 'meet'. + + commit c3adaef44b94cc63a8a8806f398185046461947c + Author: Jens Maurer + Date: Fri Mar 15 19:23:30 2019 +0100 + + [numeric.requirements] Define 'numeric type'. + + commit 1ce86a62a3cff9fb2bcf6c1a2c37168e023e338b + Author: Jens Maurer + Date: Sat Mar 9 22:18:26 2019 +0100 + + [time.clock.req] Simplify requirements for Cpp17TrivialClock. + + commit 0ba5424c1beddfd8c8403ce882b96dee0f530c7f + Author: JF Bastien + Date: Fri Mar 15 13:52:39 2019 -0700 + + [basic.fundamental] Rename 'range exponent' to 'width' to align with C + + commit 9e00558f2a824421406a6703d1232cc4fb89bb15 + Author: Arthur O'Dwyer + Date: Fri Mar 15 16:43:16 2019 -0400 + + [std] Fix a bunch of faulty parallelism with "either". + + commit 54ddcb970132bfe026c9d9d62d967632b56ae303 + Author: BRevzin + Date: Fri Mar 15 15:30:07 2019 -0500 + + [class.rel] Simplifying wording to avoid talking about a reversed <=>. + + We can never select a reversed <=> here because the operands are of the same type. + + commit 5d174b05d8cd08717ed7efc05d0271409651071c + Author: Richard Smith + Date: Fri Mar 15 12:33:42 2019 -0700 + + [expr.prim.lambda.capture] Convert paragraphs repeating the + "non-odr-usable local entities shall not be odr-used" rule from + [basic.def.odr] into notes. + + commit 41853024e5e6fcd5feb496f64767d2888d76154f + Author: Richard Smith + Date: Fri Mar 15 11:38:57 2019 -0700 + + Revert "[expr.const] Add missing definition of 'usable in constant expressions'" + + The prior editorial fix was an attempt to re-add wording that was + missing from P0595R2 (moved as 2018-11 CWG Motion 14). However, CWG + analysis has indicated that the editorial fix is incomplete, so we're + reverting it to restore the wording to the as-moved state. + + This reverts commit e58439bce8af85e6569328272c2cfb73f5fc44d6. + + commit 154f2c59c4377897937f4b0722cfe2b6d726cc59 + Author: birbacher + Date: Fri Mar 15 18:39:16 2019 +0000 + + [container.node] Add 3 "template" keywords for dependent name (#2676) + + On: + [container.node.overview]/4 + [container.node.cons]/3.1 + [container.node.dtor]/1 + + commit 2585d7f5894b46e0aa2f961183060a5201b2cca7 + Author: Jens Maurer + Date: Fri Dec 21 19:29:38 2018 +0100 + + [std] Replace underscores in stable labels with periods. + + commit 554a8926404bd5e0f772a6cb72c04bd12a5b7984 + Author: Casey Carter + Date: Mon Mar 4 09:29:50 2019 -0800 + + [specialized.algorithms] Rename voidify's parameter + + `ptr` is an odd name for a parameter that is a reference to storage for an object. + + commit a2dfa61a0d50a24e7be6cbc004bb0f076b8c62b5 + Author: Jens Maurer + Date: Fri Mar 8 22:25:38 2019 +0100 + + [queue.syn,stack.syn] Add partial specialization of uses_allocator + + commit 721f2d606f90cc20a16ad9b4383bc78cb368abdc + Author: Jonathan Wakely + Date: Fri Mar 15 02:53:18 2019 +0000 + + [func.not_fn], [func.bind_front] fix phrasing of \mandates and \expects (#2750) + + The Mandates: element should just state its condition, and not say "shall". + Cpp17 concept requirements should be phrased as "X meets the + Y requirements" not "X shall meet the requirements of Y". + + commit 48484c967ee5f3ecb65ff857f8f4794e108ba0cb + Author: Krystian + Date: Thu Mar 14 22:49:33 2019 -0400 + + [temp.class.spec.mfunc] Correct "class template specialization" to the intended "class template partial specialization" + + commit 3117814eaf800a5e1dd387f4c5a0522f2627689e + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Fri Mar 15 05:48:28 2019 +0300 + + [expr.sizeof] Remove the redundant paragraph 3 + + Paragraph 1 already says that functions are disallowed and function pointers are allowed. + + commit c769f835dadd4a35df9febad684a296d6cb71a53 + Author: JF Bastien + Date: Thu Mar 14 19:45:53 2019 -0700 + + [dcl.attr.contract.cond] Replace return type with 'void' in example that does not return + + Also remove the (unused) name for the return value in the postcondition. + + commit d48c79e223cfbd5ec134703e20989235208e9364 + Author: Jens Maurer + Date: Fri Mar 8 01:14:16 2019 +0100 + + [dcl.enum] Fix singular/plural mismatch. + + commit c5fb73ba6a9b71f6e247103ab4baac1c9f72e210 + Author: Jens Maurer + Date: Fri Mar 8 01:13:35 2019 +0100 + + [conv.prom] b_min and b_max are no longer defined in [dcl.enum] + + commit d7d2580c7d8fabe25ada4dd0e091f9997c0916f5 + Author: Jens Maurer + Date: Sat Mar 9 22:36:47 2019 +0100 + + [range.iota,range.adaptors] Add cross-references for private member types. + + commit b8fd249c737ff2c3652cf6ef77db25712038d353 + Author: Jens Maurer + Date: Sun Mar 10 20:20:10 2019 +0100 + + [dcl.init] Prepend 'Otherwise' to a bullet + + commit dd227824ade24ab51dd4cc926c4b9e87cc29becf + Author: Jens Maurer + Date: Sun Mar 10 20:28:41 2019 +0100 + + [dcl.attr.contract.cond] References cannot be modified. + + Avoid confusion caused by using the words "makes [...] + modifications of the value of [a] parameter" by excluding + references. + + commit b0116b87bf33fed9648e6e8b1b0c7cee0d90b311 + Author: Jason Merrill + Date: Tue Mar 12 09:06:23 2019 -0400 + + [over.match.best] Add number for paragraph 2. + + commit f0f7ba234644d3690d18fcba73f618648014a47c + Author: Jens Maurer + Date: Wed Mar 13 22:21:42 2019 +0100 + + [lib] Use '(inclusive)', not other punctuation + + to indicate inclusive ranges in prose. + + commit 5ba461ec9836f95ed7a54b563b06d480f564e987 + Author: Jens Maurer + Date: Wed Mar 13 22:46:19 2019 +0100 + + [class.eq,class.spaceship] Clarify order of comparison. + + commit 42e5df5c08c9ef805da304fe05fe387cfc3d33d5 + Author: Jens Maurer + Date: Thu Mar 14 00:02:25 2019 +0100 + + [basic.lookup.argdep] Reorder bullets to group semantics. + + commit 927dc13e1010e031692f3a94d8e9599beeb877ac + Author: Richard Smith + Date: Thu Mar 14 17:22:07 2019 -0700 + + [array.tuple] Fix broken description of tuple_element for std::array. + + commit 0b06fcd5f92bc0439a868471a5fdfdba8a181941 + Author: Jens Maurer + Date: Fri Mar 8 22:12:14 2019 +0100 + + [ranges.syn] Add ref_view to header synopsis. + + commit 6f6e5772b2a2dcf41e3db4f68b6cbc3c0628c061 + Author: Richard Smith + Date: Thu Mar 14 16:05:33 2019 -0700 + + [algorithms.parallel.exec] Rephrase to avoid incorrect use of "may not". + + Convert rationale sentence to a note. + + commit de76c7de8c4f9734e0e4351d2088d4786ee62135 + Author: Jens Maurer + Date: Tue Mar 5 21:57:10 2019 +0100 + + [char.traits.typedefs] Change 'shall meet' to 'meets' + + commit e11e27a7873953f0c078901f7ddbb0d7d701c5f7 + Author: Jens Maurer + Date: Wed Mar 6 21:15:37 2019 +0100 + + [mem.poly.allocator.mem] Avoid duplicate colons. + + commit 2956ba37186d7e9cbe728cc3870a2a26fb1f0168 + Author: Richard Smith + Date: Wed Mar 13 14:14:43 2019 -0700 + + [dcl.fct.def.coroutine] Update wording to align with current editorial + conventions. + + Reorder and rearrange to reduce the number of variables with long scopes + that we define in the wording. + + Fix mismatch between core and library wording where library permits + coroutine_handle to resume a coroutine with any promise type, and + the core language does not. + + commit 8dd4539b24473677809163f5e6d399ba6aa0b27d + Author: Richard Smith + Date: Tue Mar 12 18:15:59 2019 -0700 + + [expr.await] Rephrase and modernize wording. + + Invoke temporary materialization conversion directly rather than + handwaving about a temporary object. Specify that the o expression is + evaluated. Bulletize description of the three different ways that + await-suspend is called. + + Fix wording that uses values and objects on the left-hand side of a + class member access to instead consistently use expressions. + + Fixes #2774. + + commit d69814f61077f7e549ccc39a21fc3b90db4223d6 + Author: Richard Smith + Date: Mon Mar 11 20:12:17 2019 -0700 + + [temp.param] "a type that is literal" -> "a literal type". + + commit c0058816fdfe079095ca8717ad692dc2d498d6a3 + Author: Richard Smith + Date: Mon Mar 11 20:11:46 2019 -0700 + + [class.eq] Remove redundant repetition of the operator== symmetry rule. + + commit 007c0c1a619417f94c2c4efb57be71c09f2c2870 + Author: Jens Maurer + Date: Wed Mar 6 21:32:09 2019 +0100 + + [temp.type] Do not refer to operator==, which excludes built-in ==. + + commit caa5c8aedecdf68cfda4f5d95ec9d20451953117 + Author: Jens Maurer + Date: Tue Mar 5 19:05:25 2019 +0100 + + [class.compare.default] Add a note that friends are found by ADL only. + + commit c9074b533c835bbf820f5ea09957810ed2c04dab + Author: Jens Maurer + Date: Wed Mar 6 20:56:58 2019 +0100 + + [expr.new] Move treatment of arrays of unknown bound + + commit ce2f08ab94123adb44e58f1176c6ae4f3209eb60 + Author: Richard Smith + Date: Mon Mar 11 17:20:25 2019 -0700 + + [dcl.init] Merge new direct aggregate init wording into class direct + initialization bullet to avoid the wording being unreachable due to an + "Otherwise" chain. + + commit 691b7c10530d3265afbf445dff3dd129c7c5692e + Author: Dawn Perchik + Date: Sun Mar 10 16:15:53 2019 -0700 + + [dcl.init] Moved the changed bullet in 17.5 to before 17.6.3. + + commit 5f7461d24bc0e9867458a043adf04aa8c4ceed73 + Author: Richard Smith + Date: Fri Mar 8 16:11:34 2019 -0800 + + [temp.dep.type] Rephrase to avoid suggesting that an expression can be + the current instantiation. + + A type can't be the current instantiation either, but that's a + pre-existing prevalent problem. + + commit cbb21fb0210b6aade5591de94e3a27d7059e9d06 + Author: Richard Smith + Date: Fri Mar 8 16:08:02 2019 -0800 + + [basic.def.odr] Apply additional edits from CWG review that were not + transcribed into P1359R0. + + commit ac732bfe4eef01e9e2443dac6138270695d7cbf9 + Author: Richard Smith + Date: Fri Mar 8 12:24:49 2019 -0800 + + [expr.prim.lambda.capture] Add missing close parentheses in CWG2358 + examples. + + Fixes #2680. + + commit 502e419ca75c9656394d1998036b4b810e8bdb17 + Author: Richard Smith + Date: Fri Mar 8 12:00:26 2019 -0800 + + [dcl.type.simple] Fix inaccurate note added by CWG2332 + + [temp.local] Clarify that the surrounding syntax and construct directly + dictates whether an injected-class-name is syntactically a template-name + or a type-name, not just what it means. + + commit f4346ece403e469e800d635a75baafb9c411aa1b + Author: Richard Smith + Date: Fri Mar 8 11:39:36 2019 -0800 + + [expr.static.cast] Fix wording of CWG2310 to match CWG intent (verified + on core reflector): + + - in p11, require D to be a complete class type, not B + - in p12, rephrase to avoid the suggestion that we're talking about a + different D than the one already in scope + + commit 6f34b0513ed6d974b86a27429f8f4d02a6c18b88 + Author: Hana Dusíková + Date: Fri Feb 22 11:03:29 2019 -1000 + + [pair.astuple, tuple.helper] Fix inconsistent class key in tuple_size/tuple_element. (#2679) + + It was declared as a struct and specializations were classes. + + commit 102a791b446f70f939a9b1e2e66fc3553aade19c + Author: Johel Ernesto Guerrero Peña + Date: Fri Feb 22 02:30:23 2019 -0400 + + [array.syn] Add reference to [array.tuple] + + commit 7fe655909b4e5f01d8a8b71d6b508785c42c739e + Author: Richard Smith + Date: Wed Feb 20 17:04:55 2019 -1000 + + [temp.dep] [temp.dep.res] Remove redundant restatement of the two-phase + lookup rule. The primary location of the rule is [temp.dep.candidate]. + + commit 8fbeb52ae5daccc0352798ff023f6cba6aebcd42 + Author: Richard Smith + Date: Mon Feb 18 17:15:39 2019 -1000 + + [basic.link] The notion of the linkage of a type is no longer used for + any purpose. Remove it and move its example next to the rule that + justifies it, and simplify said example. + + commit cafdbd8036f3cf19e9cfc2f56584b219fb190602 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Fri Jan 25 00:12:44 2019 +0300 + + [expr.sizeof]/2: there are no expressions of reference type + + commit 35ce0ae2eb2582dbc00fc824afbfa1d53a64de8d + Author: Richard Smith + Date: Wed Feb 13 17:51:58 2019 -0800 + + [depr.array.comp] Fix example of deprecated array comparison + + commit 2f0bd979f41953890129fcbdc6ef37e3e90387ad + Author: Alisdair Meredith + Date: Sun Feb 10 16:53:15 2019 -0500 + + Add missing noexcept cross-refs for invokable traits (#2662) + + All the other traits that use the phrase 'is known not to throw exceptions' also cross-reference the core clause for the noexcept operator, so add the missing cross reference to the more recently added traits. + + commit 9f261368736c3666791329145292c1563a291861 + Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com> + Date: Sun Feb 10 22:52:36 2019 +0100 + + [temp.mem.func] Fixed text in example, which was not updated by CWG 249 (#2658) + + commit f668df034ebf27ad53b5addad22af4f1293f829f + Author: Jens Maurer + Date: Sun Feb 10 22:50:42 2019 +0100 + + [algorithms.general,concepts.general] Add missing entries for summary tables (#2663) diff --git a/papers/n4812.html b/papers/n4812.html new file mode 100644 index 0000000000..78aa63fbd7 --- /dev/null +++ b/papers/n4812.html @@ -0,0 +1,813 @@ +N4812 +

N4812 Editors' Report -- Programming Languages -- C++

+ +

2019-03-21
+Richard Smith (editor) (Google Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+Jens Maurer (co-editor)
+Dawn Perchik (co-editor) (Bright Side Computing, LLC)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to Marshall Clow +for supplying the LaTeX sources for

+ +
    +
  • P1458R1 (LWG motion 7, 42 pages of wording changes)
  • +
  • P1459R1 (LWG motion 8, 15 pages of wording changes)
  • +
  • P1463R1 (LWG motion 10, 119 pages of wording changes) and
  • +
  • P1464R1 (LWG motion 11, 60 pages of wording changes)
  • +
+ +

and to Gor Nishanov +for supplying a pull request for +P0912R5 (CWG motion 15, 22 pages of wording changes).

+ +

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

+ +

New papers

+ +
    +
  • N4810 is the current working draft for C++20. It replaces N4800.
  • +
  • N4812 is this Editors' Report.
  • +
+ +

N4811 is a prior version of this Editors' Report, and is hereby rescinded and +replaced by this version. Thanks to Akira Takahashi for identifying errors in +some hyperlink destinations in that document; the hyperlinks in this version of +the Editors' Report have been corrected.

+ +

Motions incorporated into working draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolutions for 14 issues in "ready" status applied, 1 not applied:

+ +
    +
  • 2256 Lifetime of trivially-destructible objects
  • +
  • 2267 Copy-initialization of temporary in reference direct-initialization
  • +
  • 2278 Copy elision in constant expressions reconsidered
  • +
  • 2303 Partial ordering and recursive variadic inheritance
  • +
  • 2309 Restrictions on nested statements within constexpr functions
  • +
  • 2310 Type completeness and derived-to-base pointer conversions see below
  • +
  • 2317 Self-referential default member initializers
  • +
  • 2318 Nondeduced contexts in deduction from a braced-init-list
  • +
  • 2330 Missing references to variable templates
  • +
  • 2331 Redundancy in description of class scope not applied, see below
  • +
  • 2332 template-name as simple-type-name vs injected-class-name see below
  • +
  • 2336 Destructor characteristics vs potentially-constructed subobjects
  • +
  • 2352 Similar types and reference binding
  • +
  • 2358 Explicit capture of value
  • +
  • 2360 [[maybe_unused]] and structured bindings
  • +
+ +

CWG motion 2: Core issue resolutions for 22 issues in "tentatively ready" status applied, resolving 24 issues:

+ +
    +
  • 581 Can a templated constructor be explicitly instantiated or specialized?
  • +
  • 1937 Incomplete specification of function pointer from lambda
  • +
  • 1938 Should hosted/freestanding be implementation-defined?
  • +
  • 2020 Inadequate description of odr-use of implicitly-invoked functions see below
  • +
  • 2051 Simplifying alias rules
  • +
  • 2083 Incorrect cases of odr-use
  • +
  • 2103 Lvalue-to-rvalue conversion is irrelevant in odr-use of a reference resolved by 2083
  • +
  • 2170 Unclear definition of odr-use for arrays resolved by 2083
  • +
  • 2257 Lifetime extension of references vs exceptions
  • +
  • 2266 Has dependent type vs is type-dependent
  • +
  • 2289 Uniqueness of structured binding names
  • +
  • 2353 Potential results of a member access expression for a static data member
  • +
  • 2354 Extended alignment and object representation
  • +
  • 2365 Confusing specification for dynamic_cast
  • +
  • 2368 Differences in relational and three-way constant comparisons
  • +
  • 2372 Incorrect matching rules for block-scope extern declarations
  • +
  • 2379 Missing prohibition against constexpr in friend declaration
  • +
  • 2380 capture-default makes too many references odr-usable
  • +
  • 2381 Composite pointer type of pointers to plain and noexcept member functions
  • +
  • 2384 Conversion function templates and qualification conversions
  • +
  • 2385 Lookup for conversion-function-ids
  • +
  • 2386 tuple_size requirements for structured binding
  • +
  • 2387 Linkage of const-qualified variable template
  • +
  • 2394 Const-default-constructible for members
  • +
+ +

CWG motion 3: P1286R2 "Contra CWG DR1778" (DR)

+ +
    +
  • Alters resolution of 1778 exception-specification in explicitly-defaulted functions
  • +
+ +

CWG motion 4: P1091R3 "Extending structured bindings to be more like variable declarations"

+ +

CWG motion 5: P1381R1 "Reference capture of structured bindings"

+ +

CWG motion 6: P1041R4 "Make char16_t/char32_t string literals be UTF-16/32"

+ +

CWG motion 7: P1139R2 "Address wording issues related to ISO 10646"

+ +

CWG motion 8: P1323R2 "Contract postconditions and return type deduction"

+ +

CWG motion 9: P0960R3 "Allow initializing aggregates from a parenthesized list of values"

+ +

CWG motion 10: P1009R2 "Array size deduction in new-expressions" (DR)

+ +

CWG motion 11: P1103R3 "Modules"

+ +

CWG motion 12: P1185R2 "<=> != =="

+ +

CWG motions 13 and 14 apply to the Reflection TS

+ +

CWG motion 15: P0912R5 "Coroutines"

+ +

Core motions added a total of 24 pages (and 1 Clause) to Clause 1-15

+ +

Library working group motions

+ +

LWG motion 1 applies to the Library Fundamentals TS

+ +

LWG motion 2: Library issue resolutions for 2 issues in Ready status and 11 issues in Tentatively Ready status applied:

+ +
    +
  • 3012 atomic is unimplementable for non-is_trivially_copy_constructible T
  • +
  • 3040 basic_string_view::starts_with Effects are incorrect
  • +
  • 3077 (push|emplace)_back should invalidate the end iterator
  • +
  • 3087 One final &x in [list.ops]
  • +
  • 3101 span's Container constructors need another constraint
  • +
  • 3112 system_error and filesystem_error constructors taking a string may not be able to meet their postconditions
  • +
  • 3119 Program-definedness of closure types
  • +
  • 3133 Modernizing numeric type requirements
  • +
  • 3144 span does not have a const_pointer typedef
  • +
  • 3173 Enable CTAD for ref-view
  • +
  • 3179 subrange should always model Range
  • +
  • 3180 Inconsistently named return type for ranges::minmax_element
  • +
  • 3182 Specification of Same could be clearer
  • +
+ +

LWG motion 3: P0339R6 "polymorphic_allocator<> as a vocabulary type"

+ +

LWG motion 4: P0340R3 "Making std::underlying_type SFINAE-friendly"

+ +

LWG motion 5 was retracted

+ +

LWG motion 6: P0738R2 "I Stream, You Stream, We All Stream for istream_iterator"

+ +

LWG motion 7: P1458R1 "Mandating the standard library: clause 16 - language support library"

+ +

LWG motion 8: P1459R1 "Mandating the standard library: clause 18 - diagnostics library"

+ +

LWG motion 9: P1462R1 "Mandating the standard library: clause 20 - strings library"

+ +

LWG motion 10: P1463R1 "Mandating the standard library: clause 21 - containers library"

+ +

LWG motion 11: P1464R1 "Mandating the standard library: clause 22 - iterators library"

+ +

LWG motion 12: P1164R1 "Make create_directory() intuitive" (DR)

+ +

LWG motion 13: P0811R3 "Well-behaved interpolation for numbers and pointers"

+ +

LWG motion 14: P1001R2 "Target vectorization policies from Parallelism V2 TS"

+ +

LWG motion 15: P1227R2 "Signed ssize() functions, unsigned size() functions "

+ +

LWG motion 16: P1252R2 "Ranges design cleanup"

+ +

LWG motion 17: P1024R3 "Usability enhancements for std::span"

+ +

LWG motion 18: P0920R2 "Precalculated hash values in lookup"

+ +

LWG motion 19: P1357R1 "Traits for [un]bounded arrays"

+ +

Library motions added a total of 7 pages to Clause 16-32.

+ +

Notable editorial changes

+ +

CWG motion 1

+ +

The edits for CWG2310 inadvertently required the base class to be complete +instead of the derived class in one of the edits. After consultation with CWG, +the derived class is now required to be complete in all cases.

+ +

The edits for CWG2331 were intended to be an editorial cleanup and wording +simplification, but were found to have unintentional normative effect. This +issue is being returned to CWG for redrafting.

+ +

The edits for CWG2332 added a note that was not entirely accurate. The note, +along with the normative text that it references, have been rephrased to +clarify that an injected-class-name is never interpreted as a template-name +in a context in which class template argument deduction would apply (even +though it can be interpreted as a template-name in some cases in a context +where a decl-specifier might be parsed, such as in a template-argument).

+ +

CWG motion 2

+ +

The wording moved for CWG2020 inadvertently omitted some edits that were part +of the wording reviewed by CWG. Those edits were not substantive, and have been +restored editorially.

+ +

CWG motion 12

+ +

Removed redundant restatement of the operator== symmetry rule in defaulted +operator!=; looking for reversed candidates and rewriting == expressions is +already handled by overload resolution, and a reversed operator== can never +be selected anyway because the two arguments are of the same type.

+ +

Likewise the corresponding redundant wording was removed from the rules for +defaulted operators <, >, <=, and >= that inaccurately claimed they +could select a reversed operator<=>.

+ +

CWG motion 15

+ +

Modernized the wording to follow current editorial conventions, and simplified +where possible.

+ +

Fixed a contradiction between the core and library wording; the library wording +allowed a coroutine_handle<> to resume any coroutine, but the core wording +did not account for that possibility and only permitted resumption via a +coroutine_handle<P> with the right promise type P.

+ +

LWG motion 2

+ +

Replaced the references to CopyConstructible and CopyAssignable with the +intended Cpp17CopyConstructible and Cpp17CopyAssignable after consultation +with LWG.

+ +

Section label changes

+ +

Several section labels introduced by the motions papers have been modified +to match our style guide. In addition to the section labels affected by the +above motions, all section labels containing underscores have been renamed +to instead use periods.

+ +

Reversion of prior editorial change

+ +

In N4791 (the post-San-Diego working draft), an editorial change was applied +to repair missing wording in 2018-11 CWG motion 14 +(P0595R2 "std::is_constant_evaluated()"). +This change added a definition of the term "usable in constant expressions" +as applied to objects and references that was inadvertently dropped from the +wording during CWG review.

+ +

Further review within CWG has shown that the dropped wording is also incorrect, +so the editorial fix has been reverted (leaving the definition absent rather +than incorrect), and a proper definition will be inserted by a core issue.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4800 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 142acf0bbde8d6fd20cb67c051d896fec33a84b6
+Author: stryku <stryku2393@gmail.com>
+Date:   Thu Oct 11 18:41:18 2018 +0200
+
+    [decl.init]/10 Fix specified initialization.
+
+    According to [basic.start.static]/2, for objects with static storage duration,
+    zero initialization performs only if constant initialization does not.
+    [decl.init]/10 can be generalized to static initialization.
+    This is an editorial note change.
+
+commit 74def77454a15b6cdb45be0f31916396b4b63b72
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 15 13:45:06 2019 -0700
+
+    [util.smartptr.atomic.shared] [util.smartptr.atomic.weak] Clarify
+    grouping of "either".
+
+commit 4c5701a79cc7c4cc7b9cd9c6070e3cd88961aca7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 21 21:04:43 2018 +0100
+
+    [mismatch] LWG3178 std::mismatch is missing an upper bound
+
+commit 04a5e31a02e19e5d1c9e9a0b05c40ce8730c7064
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jan 26 00:30:13 2019 +0100
+
+    [algorithms] Qualify declarator-id with sub-namespace.
+
+    Also qualify return types where appropriate.
+
+commit 6c844190a533950fc0100eac4da7785d99c87400
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 15 20:25:59 2019 +0100
+
+    [time.clock.req] Change 'satisfy' to 'meet'.
+
+commit c3adaef44b94cc63a8a8806f398185046461947c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 15 19:23:30 2019 +0100
+
+    [numeric.requirements] Define 'numeric type'.
+
+commit 1ce86a62a3cff9fb2bcf6c1a2c37168e023e338b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 9 22:18:26 2019 +0100
+
+    [time.clock.req] Simplify requirements for Cpp17TrivialClock.
+
+commit 0ba5424c1beddfd8c8403ce882b96dee0f530c7f
+Author: JF Bastien <github@jfbastien.com>
+Date:   Fri Mar 15 13:52:39 2019 -0700
+
+    [basic.fundamental] Rename 'range exponent' to 'width' to align with C
+
+commit 9e00558f2a824421406a6703d1232cc4fb89bb15
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Fri Mar 15 16:43:16 2019 -0400
+
+    [std] Fix a bunch of faulty parallelism with "either".
+
+commit 54ddcb970132bfe026c9d9d62d967632b56ae303
+Author: BRevzin <barry.revzin@gmail.com>
+Date:   Fri Mar 15 15:30:07 2019 -0500
+
+    [class.rel] Simplifying wording to avoid talking about a reversed <=>.
+
+    We can never select a reversed <=> here because the operands are of the same type.
+
+commit 5d174b05d8cd08717ed7efc05d0271409651071c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 15 12:33:42 2019 -0700
+
+    [expr.prim.lambda.capture] Convert paragraphs repeating the
+    "non-odr-usable local entities shall not be odr-used" rule from
+    [basic.def.odr] into notes.
+
+commit 41853024e5e6fcd5feb496f64767d2888d76154f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 15 11:38:57 2019 -0700
+
+    Revert "[expr.const] Add missing definition of 'usable in constant expressions'"
+
+    The prior editorial fix was an attempt to re-add wording that was
+    missing from P0595R2 (moved as 2018-11 CWG Motion 14). However, CWG
+    analysis has indicated that the editorial fix is incomplete, so we're
+    reverting it to restore the wording to the as-moved state.
+
+    This reverts commit e58439bce8af85e6569328272c2cfb73f5fc44d6.
+
+commit 154f2c59c4377897937f4b0722cfe2b6d726cc59
+Author: birbacher <frank.birbacher@gmail.com>
+Date:   Fri Mar 15 18:39:16 2019 +0000
+
+    [container.node] Add 3 "template" keywords for dependent name (#2676)
+
+    On:
+    [container.node.overview]/4
+    [container.node.cons]/3.1
+    [container.node.dtor]/1
+
+commit 2585d7f5894b46e0aa2f961183060a5201b2cca7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 21 19:29:38 2018 +0100
+
+    [std] Replace underscores in stable labels with periods.
+
+commit 554a8926404bd5e0f772a6cb72c04bd12a5b7984
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Mar 4 09:29:50 2019 -0800
+
+    [specialized.algorithms] Rename voidify's parameter
+
+    `ptr` is an odd name for a parameter that is a reference to storage for an object.
+
+commit a2dfa61a0d50a24e7be6cbc004bb0f076b8c62b5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 8 22:25:38 2019 +0100
+
+    [queue.syn,stack.syn] Add partial specialization of uses_allocator
+
+commit 721f2d606f90cc20a16ad9b4383bc78cb368abdc
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Fri Mar 15 02:53:18 2019 +0000
+
+    [func.not_fn], [func.bind_front] fix phrasing of \mandates and \expects (#2750)
+
+    The Mandates: element should just state its condition, and not say "shall".
+    Cpp17 concept requirements should be phrased as "X meets the
+    Y requirements" not "X shall meet the requirements of Y".
+
+commit 48484c967ee5f3ecb65ff857f8f4794e108ba0cb
+Author: Krystian <sdkrystian@gmail.com>
+Date:   Thu Mar 14 22:49:33 2019 -0400
+
+    [temp.class.spec.mfunc] Correct "class template specialization" to the intended "class template partial specialization"
+
+commit 3117814eaf800a5e1dd387f4c5a0522f2627689e
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Fri Mar 15 05:48:28 2019 +0300
+
+    [expr.sizeof] Remove the redundant paragraph 3
+
+    Paragraph 1 already says that functions are disallowed and function pointers are allowed.
+
+commit c769f835dadd4a35df9febad684a296d6cb71a53
+Author: JF Bastien <github@jfbastien.com>
+Date:   Thu Mar 14 19:45:53 2019 -0700
+
+    [dcl.attr.contract.cond] Replace return type with 'void' in example that does not return
+
+    Also remove the (unused) name for the return value in the postcondition.
+
+commit d48c79e223cfbd5ec134703e20989235208e9364
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 8 01:14:16 2019 +0100
+
+    [dcl.enum] Fix singular/plural mismatch.
+
+commit c5fb73ba6a9b71f6e247103ab4baac1c9f72e210
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 8 01:13:35 2019 +0100
+
+    [conv.prom] b_min and b_max are no longer defined in [dcl.enum]
+
+commit d7d2580c7d8fabe25ada4dd0e091f9997c0916f5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 9 22:36:47 2019 +0100
+
+    [range.iota,range.adaptors] Add cross-references for private member types.
+
+commit b8fd249c737ff2c3652cf6ef77db25712038d353
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Mar 10 20:20:10 2019 +0100
+
+    [dcl.init] Prepend 'Otherwise' to a bullet
+
+commit dd227824ade24ab51dd4cc926c4b9e87cc29becf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Mar 10 20:28:41 2019 +0100
+
+    [dcl.attr.contract.cond] References cannot be modified.
+
+    Avoid confusion caused by using the words "makes [...]
+    modifications of the value of [a] parameter" by excluding
+    references.
+
+commit b0116b87bf33fed9648e6e8b1b0c7cee0d90b311
+Author: Jason Merrill <jason@redhat.com>
+Date:   Tue Mar 12 09:06:23 2019 -0400
+
+    [over.match.best] Add number for paragraph 2.
+
+commit f0f7ba234644d3690d18fcba73f618648014a47c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 13 22:21:42 2019 +0100
+
+    [lib] Use '(inclusive)', not other punctuation
+
+    to indicate inclusive ranges in prose.
+
+commit 5ba461ec9836f95ed7a54b563b06d480f564e987
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 13 22:46:19 2019 +0100
+
+    [class.eq,class.spaceship] Clarify order of comparison.
+
+commit 42e5df5c08c9ef805da304fe05fe387cfc3d33d5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Mar 14 00:02:25 2019 +0100
+
+    [basic.lookup.argdep] Reorder bullets to group semantics.
+
+commit 927dc13e1010e031692f3a94d8e9599beeb877ac
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 14 17:22:07 2019 -0700
+
+    [array.tuple] Fix broken description of tuple_element for std::array.
+
+commit 0b06fcd5f92bc0439a868471a5fdfdba8a181941
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 8 22:12:14 2019 +0100
+
+    [ranges.syn] Add ref_view to header synopsis.
+
+commit 6f6e5772b2a2dcf41e3db4f68b6cbc3c0628c061
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Mar 14 16:05:33 2019 -0700
+
+    [algorithms.parallel.exec] Rephrase to avoid incorrect use of "may not".
+
+    Convert rationale sentence to a note.
+
+commit de76c7de8c4f9734e0e4351d2088d4786ee62135
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Mar 5 21:57:10 2019 +0100
+
+    [char.traits.typedefs] Change 'shall meet' to 'meets'
+
+commit e11e27a7873953f0c078901f7ddbb0d7d701c5f7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 6 21:15:37 2019 +0100
+
+    [mem.poly.allocator.mem] Avoid duplicate colons.
+
+commit 2956ba37186d7e9cbe728cc3870a2a26fb1f0168
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Mar 13 14:14:43 2019 -0700
+
+    [dcl.fct.def.coroutine] Update wording to align with current editorial
+    conventions.
+
+    Reorder and rearrange to reduce the number of variables with long scopes
+    that we define in the wording.
+
+    Fix mismatch between core and library wording where library permits
+    coroutine_handle<void> to resume a coroutine with any promise type, and
+    the core language does not.
+
+commit 8dd4539b24473677809163f5e6d399ba6aa0b27d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Mar 12 18:15:59 2019 -0700
+
+    [expr.await] Rephrase and modernize wording.
+
+    Invoke temporary materialization conversion directly rather than
+    handwaving about a temporary object. Specify that the o expression is
+    evaluated. Bulletize description of the three different ways that
+    await-suspend is called.
+
+    Fix wording that uses values and objects on the left-hand side of a
+    class member access to instead consistently use expressions.
+
+    Fixes #2774.
+
+commit d69814f61077f7e549ccc39a21fc3b90db4223d6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 11 20:12:17 2019 -0700
+
+    [temp.param] "a type that is literal" -> "a literal type".
+
+commit c0058816fdfe079095ca8717ad692dc2d498d6a3
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 11 20:11:46 2019 -0700
+
+    [class.eq] Remove redundant repetition of the operator== symmetry rule.
+
+commit 007c0c1a619417f94c2c4efb57be71c09f2c2870
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 6 21:32:09 2019 +0100
+
+    [temp.type] Do not refer to operator==, which excludes built-in ==.
+
+commit caa5c8aedecdf68cfda4f5d95ec9d20451953117
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Mar 5 19:05:25 2019 +0100
+
+    [class.compare.default] Add a note that friends are found by ADL only.
+
+commit c9074b533c835bbf820f5ea09957810ed2c04dab
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 6 20:56:58 2019 +0100
+
+    [expr.new] Move treatment of arrays of unknown bound
+
+commit ce2f08ab94123adb44e58f1176c6ae4f3209eb60
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 11 17:20:25 2019 -0700
+
+    [dcl.init] Merge new direct aggregate init wording into class direct
+    initialization bullet to avoid the wording being unreachable due to an
+    "Otherwise" chain.
+
+commit 691b7c10530d3265afbf445dff3dd129c7c5692e
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Sun Mar 10 16:15:53 2019 -0700
+
+    [dcl.init] Moved the changed bullet in 17.5 to before 17.6.3.
+
+commit 5f7461d24bc0e9867458a043adf04aa8c4ceed73
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 8 16:11:34 2019 -0800
+
+    [temp.dep.type] Rephrase to avoid suggesting that an expression can be
+    the current instantiation.
+
+    A type can't be the current instantiation either, but that's a
+    pre-existing prevalent problem.
+
+commit cbb21fb0210b6aade5591de94e3a27d7059e9d06
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 8 16:08:02 2019 -0800
+
+    [basic.def.odr] Apply additional edits from CWG review that were not
+    transcribed into P1359R0.
+
+commit ac732bfe4eef01e9e2443dac6138270695d7cbf9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 8 12:24:49 2019 -0800
+
+    [expr.prim.lambda.capture] Add missing close parentheses in CWG2358
+    examples.
+
+    Fixes #2680.
+
+commit 502e419ca75c9656394d1998036b4b810e8bdb17
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 8 12:00:26 2019 -0800
+
+    [dcl.type.simple] Fix inaccurate note added by CWG2332
+
+    [temp.local] Clarify that the surrounding syntax and construct directly
+    dictates whether an injected-class-name is syntactically a template-name
+    or a type-name, not just what it means.
+
+commit f4346ece403e469e800d635a75baafb9c411aa1b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Mar 8 11:39:36 2019 -0800
+
+    [expr.static.cast] Fix wording of CWG2310 to match CWG intent (verified
+    on core reflector):
+
+     - in p11, require D to be a complete class type, not B
+     - in p12, rephrase to avoid the suggestion that we're talking about a
+       different D than the one already in scope
+
+commit 6f34b0513ed6d974b86a27429f8f4d02a6c18b88
+Author: Hana Dusíková <hanicka@hanicka.net>
+Date:   Fri Feb 22 11:03:29 2019 -1000
+
+    [pair.astuple, tuple.helper] Fix inconsistent class key in tuple_size/tuple_element. (#2679)
+
+    It was declared as a struct and specializations were classes.
+
+commit 102a791b446f70f939a9b1e2e66fc3553aade19c
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri Feb 22 02:30:23 2019 -0400
+
+    [array.syn] Add reference to [array.tuple]
+
+commit 7fe655909b4e5f01d8a8b71d6b508785c42c739e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Feb 20 17:04:55 2019 -1000
+
+    [temp.dep] [temp.dep.res] Remove redundant restatement of the two-phase
+    lookup rule. The primary location of the rule is [temp.dep.candidate].
+
+commit 8fbeb52ae5daccc0352798ff023f6cba6aebcd42
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Feb 18 17:15:39 2019 -1000
+
+    [basic.link] The notion of the linkage of a type is no longer used for
+    any purpose. Remove it and move its example next to the rule that
+    justifies it, and simplify said example.
+
+commit cafdbd8036f3cf19e9cfc2f56584b219fb190602
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Fri Jan 25 00:12:44 2019 +0300
+
+    [expr.sizeof]/2: there are no expressions of reference type
+
+commit 35ce0ae2eb2582dbc00fc824afbfa1d53a64de8d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Feb 13 17:51:58 2019 -0800
+
+    [depr.array.comp] Fix example of deprecated array comparison
+
+commit 2f0bd979f41953890129fcbdc6ef37e3e90387ad
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sun Feb 10 16:53:15 2019 -0500
+
+    Add missing noexcept cross-refs for invokable traits (#2662)
+
+    All the other traits that use the phrase 'is known not to throw exceptions' also cross-reference the core clause for the noexcept operator, so add the missing cross reference to the more recently added traits.
+
+commit 9f261368736c3666791329145292c1563a291861
+Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com>
+Date:   Sun Feb 10 22:52:36 2019 +0100
+
+    [temp.mem.func] Fixed text in example, which was not updated by CWG 249 (#2658)
+
+commit f668df034ebf27ad53b5addad22af4f1293f829f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 10 22:50:42 2019 +0100
+
+    [algorithms.general,concepts.general] Add missing entries for summary tables (#2663)
+
diff --git a/papers/n4812.md b/papers/n4812.md new file mode 100644 index 0000000000..095aac97ab --- /dev/null +++ b/papers/n4812.md @@ -0,0 +1,677 @@ +# N4812 Editors' Report -- Programming Languages -- C++ + +2019-03-21 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Special thanks to Marshall Clow +for supplying the LaTeX sources for + + * [P1458R1](http://wg21.link/p1458r1) (LWG motion 7, 42 pages of wording changes) + * [P1459R1](http://wg21.link/p1459r1) (LWG motion 8, 15 pages of wording changes) + * [P1463R1](http://wg21.link/p1463r1) (LWG motion 10, 119 pages of wording changes) and + * [P1464R1](http://wg21.link/p1464r1) (LWG motion 11, 60 pages of wording changes) + +and to Gor Nishanov +for supplying a pull request for +[P0912R5](http://wg21.link/p0912r5) (CWG motion 15, 22 pages of wording changes). + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4810](http://wg21.link/n4810) is the current working draft for C++20. It replaces [N4800](http://wg21.link/n4800). + * N4812 is this Editors' Report. + +N4811 is a prior version of this Editors' Report, and is hereby rescinded and +replaced by this version. Thanks to Akira Takahashi for identifying errors in +some hyperlink destinations in that document; the hyperlinks in this version of +the Editors' Report have been corrected. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p1358r0) for 14 issues in "ready" status applied, 1 not applied: + + * [2256](http://wg21.link/cwg2256) Lifetime of trivially-destructible objects + * [2267](http://wg21.link/cwg2267) Copy-initialization of temporary in reference direct-initialization + * [2278](http://wg21.link/cwg2278) Copy elision in constant expressions reconsidered + * [2303](http://wg21.link/cwg2303) Partial ordering and recursive variadic inheritance + * [2309](http://wg21.link/cwg2309) Restrictions on nested statements within constexpr functions + * [2310](http://wg21.link/cwg2310) Type completeness and derived-to-base pointer conversions **see below** + * [2317](http://wg21.link/cwg2317) Self-referential default member initializers + * [2318](http://wg21.link/cwg2318) Nondeduced contexts in deduction from a *braced-init-list* + * [2330](http://wg21.link/cwg2330) Missing references to variable templates + * [2331](http://wg21.link/cwg2331) Redundancy in description of class scope **not applied, see below** + * [2332](http://wg21.link/cwg2332) *template-name* as *simple-type-name* vs *injected-class-name* **see below** + * [2336](http://wg21.link/cwg2336) Destructor characteristics vs potentially-constructed subobjects + * [2352](http://wg21.link/cwg2352) Similar types and reference binding + * [2358](http://wg21.link/cwg2358) Explicit capture of value + * [2360](http://wg21.link/cwg2360) `[[maybe_unused]]` and structured bindings + +CWG motion 2: [Core issue resolutions](http://wg21.link/p1359r0) for 22 issues in "tentatively ready" status applied, resolving 24 issues: + + * [581](http://wg21.link/cwg581) Can a templated constructor be explicitly instantiated or specialized? + * [1937](http://wg21.link/cwg1937) Incomplete specification of function pointer from lambda + * [1938](http://wg21.link/cwg1938) Should hosted/freestanding be implementation-defined? + * [2020](http://wg21.link/cwg2020) Inadequate description of odr-use of implicitly-invoked functions **see below** + * [2051](http://wg21.link/cwg2051) Simplifying alias rules + * [2083](http://wg21.link/cwg2083) Incorrect cases of odr-use + * [2103](http://wg21.link/cwg2103) Lvalue-to-rvalue conversion is irrelevant in odr-use of a reference **resolved by 2083** + * [2170](http://wg21.link/cwg2170) Unclear definition of odr-use for arrays **resolved by 2083** + * [2257](http://wg21.link/cwg2257) Lifetime extension of references vs exceptions + * [2266](http://wg21.link/cwg2266) Has dependent type vs is type-dependent + * [2289](http://wg21.link/cwg2289) Uniqueness of structured binding names + * [2353](http://wg21.link/cwg2353) Potential results of a member access expression for a static data member + * [2354](http://wg21.link/cwg2354) Extended alignment and object representation + * [2365](http://wg21.link/cwg2365) Confusing specification for `dynamic_cast` + * [2368](http://wg21.link/cwg2368) Differences in relational and three-way constant comparisons + * [2372](http://wg21.link/cwg2372) Incorrect matching rules for block-scope extern declarations + * [2379](http://wg21.link/cwg2379) Missing prohibition against `constexpr` in friend declaration + * [2380](http://wg21.link/cwg2380) *capture-default* makes too many references odr-usable + * [2381](http://wg21.link/cwg2381) Composite pointer type of pointers to plain and `noexcept` member functions + * [2384](http://wg21.link/cwg2384) Conversion function templates and qualification conversions + * [2385](http://wg21.link/cwg2385) Lookup for *conversion-function-id*s + * [2386](http://wg21.link/cwg2386) `tuple_size` requirements for structured binding + * [2387](http://wg21.link/cwg2387) Linkage of const-qualified variable template + * [2394](http://wg21.link/cwg2394) Const-default-constructible for members + +CWG motion 3: [P1286R2 "Contra CWG DR1778"](http://wg21.link/p1286r2) **(DR)** + + * Alters resolution of [1778](http://wg21.link/cwg1778) *exception-specification* in explicitly-defaulted functions + +CWG motion 4: [P1091R3 "Extending structured bindings to be more like variable declarations"](http://wg21.link/p1091r3) + +CWG motion 5: [P1381R1 "Reference capture of structured bindings"](http://wg21.link/p1381r1) + +CWG motion 6: [P1041R4 "Make `char16_t`/`char32_t` string literals be UTF-16/32"](http://wg21.link/p1041r4) + +CWG motion 7: [P1139R2 "Address wording issues related to ISO 10646"](http://wg21.link/p1139r2) + +CWG motion 8: [P1323R2 "Contract postconditions and return type deduction"](http://wg21.link/p1323r2) + +CWG motion 9: [P0960R3 "Allow initializing aggregates from a parenthesized list of values"](http://wg21.link/p0960r3) + +CWG motion 10: [P1009R2 "Array size deduction in *new-expressions*"](http://wg21.link/p1009r2) **(DR)** + +CWG motion 11: [P1103R3 "Modules"](http://wg21.link/p1103r3) + +CWG motion 12: [P1185R2 "`<=>` `!=` `==`"](http://wg21.link/p1185r2) + +CWG motions 13 and 14 apply to the Reflection TS + +CWG motion 15: [P0912R5 "Coroutines"](http://wg21.link/p0912r5) + +Core motions added a total of 24 pages (and 1 Clause) to Clause 1-15 + +### Library working group motions + +LWG motion 1 applies to the Library Fundamentals TS + +LWG motion 2: [Library issue resolutions](http://wg21.link/p1457r0) for 2 issues in Ready status and 11 issues in Tentatively Ready status applied: + + * [3012](http://wg21.link/lwg3012) `atomic` is unimplementable for non-`is_trivially_copy_constructible` `T` + * [3040](http://wg21.link/lwg3040) `basic_string_view::starts_with` *Effects* are incorrect + * [3077](http://wg21.link/lwg3077) (`push`|`emplace`)`_back` should invalidate the end iterator + * [3087](http://wg21.link/lwg3087) One final `&x` in [list.ops] + * [3101](http://wg21.link/lwg3101) `span`'s `Container` constructors need another constraint + * [3112](http://wg21.link/lwg3112) `system_error` and `filesystem_error` constructors taking a `string` may not be able to meet their postconditions + * [3119](http://wg21.link/lwg3119) Program-definedness of closure types + * [3133](http://wg21.link/lwg3133) Modernizing numeric type requirements + * [3144](http://wg21.link/lwg3144) `span` does not have a `const_pointer` typedef + * [3173](http://wg21.link/lwg3173) Enable CTAD for *`ref-view`* + * [3179](http://wg21.link/lwg3179) `subrange` should always model `Range` + * [3180](http://wg21.link/lwg3180) Inconsistently named return type for `ranges::minmax_element` + * [3182](http://wg21.link/lwg3182) Specification of `Same` could be clearer + +LWG motion 3: [P0339R6 "`polymorphic_allocator<>` as a vocabulary type"](http://wg21.link/p0339r6) + +LWG motion 4: [P0340R3 "Making `std::underlying_type` SFINAE-friendly"](http://wg21.link/p0340r3) + +LWG motion 5 was retracted + +LWG motion 6: [P0738R2 "I Stream, You Stream, We All Stream for `istream_iterator`"](http://wg21.link/p0738r2) + +LWG motion 7: [P1458R1 "Mandating the standard library: clause 16 - language support library"](http://wg21.link/p1458r1) + +LWG motion 8: [P1459R1 "Mandating the standard library: clause 18 - diagnostics library"](http://wg21.link/p1459r1) + +LWG motion 9: [P1462R1 "Mandating the standard library: clause 20 - strings library"](http://wg21.link/p1462r1) + +LWG motion 10: [P1463R1 "Mandating the standard library: clause 21 - containers library"](http://wg21.link/p1463r1) + +LWG motion 11: [P1464R1 "Mandating the standard library: clause 22 - iterators library"](http://wg21.link/p1464r1) + +LWG motion 12: [P1164R1 "Make `create_directory()` intuitive"](http://wg21.link/p1164r1) **(DR)** + +LWG motion 13: [P0811R3 "Well-behaved interpolation for numbers and pointers"](http://wg21.link/p0811r3) + +LWG motion 14: [P1001R2 "Target vectorization policies from Parallelism V2 TS"](http://wg21.link/p1001r2) + +LWG motion 15: [P1227R2 "Signed `ssize()` functions, unsigned `size()` functions "](http://wg21.link/p1227r2) + +LWG motion 16: [P1252R2 "Ranges design cleanup"](http://wg21.link/p1252r2) + +LWG motion 17: [P1024R3 "Usability enhancements for `std::span`"](http://wg21.link/p1024r3) + +LWG motion 18: [P0920R2 "Precalculated hash values in lookup"](http://wg21.link/p0920r2) + +LWG motion 19: [P1357R1 "Traits for [un]bounded arrays"](http://wg21.link/p1357r1) + +Library motions added a total of 7 pages to Clause 16-32. + +## Notable editorial changes + +### CWG motion 1 + +The edits for CWG2310 inadvertently required the base class to be complete +instead of the derived class in one of the edits. After consultation with CWG, +the derived class is now required to be complete in all cases. + +The edits for CWG2331 were intended to be an editorial cleanup and wording +simplification, but were found to have unintentional normative effect. This +issue is being returned to CWG for redrafting. + +The edits for CWG2332 added a note that was not entirely accurate. The note, +along with the normative text that it references, have been rephrased to +clarify that an injected-class-name is never interpreted as a *template-name* +in a context in which class template argument deduction would apply (even +though it can be interpreted as a *template-name* in some cases in a context +where a *decl-specifier* might be parsed, such as in a *template-argument*). + +### CWG motion 2 + +The wording moved for CWG2020 inadvertently omitted some edits that were part +of the wording reviewed by CWG. Those edits were not substantive, and have been +restored editorially. + +### CWG motion 12 + +Removed redundant restatement of the `operator==` symmetry rule in defaulted +`operator!=`; looking for reversed candidates and rewriting `==` expressions is +already handled by overload resolution, and a reversed `operator==` can never +be selected anyway because the two arguments are of the same type. + +Likewise the corresponding redundant wording was removed from the rules for +defaulted operators `<`, `>`, `<=`, and `>=` that inaccurately claimed they +could select a reversed `operator<=>`. + +### CWG motion 15 + +Modernized the wording to follow current editorial conventions, and simplified +where possible. + +Fixed a contradiction between the core and library wording; the library wording +allowed a `coroutine_handle<>` to resume any coroutine, but the core wording +did not account for that possibility and only permitted resumption via a +`coroutine_handle

` with the right promise type `P`. + +### LWG motion 2 + +Replaced the references to *CopyConstructible* and *CopyAssignable* with the +intended *Cpp17CopyConstructible* and *Cpp17CopyAssignable* after consultation +with LWG. + +### Section label changes + +Several section labels introduced by the motions papers have been modified +to match our style guide. In addition to the section labels affected by the +above motions, all section labels containing underscores have been renamed +to instead use periods. + +### Reversion of prior editorial change + +In N4791 (the post-San-Diego working draft), an editorial change was applied +to repair missing wording in 2018-11 CWG motion 14 +([P0595R2 "`std::is_constant_evaluated()`"](http://wg21.link/p0595r2)). +This change added a definition of the term "usable in constant expressions" +as applied to objects and references that was inadvertently dropped from the +wording during CWG review. + +Further review within CWG has shown that the dropped wording is also incorrect, +so the editorial fix has been reverted (leaving the definition absent rather +than incorrect), and a proper definition will be inserted by a core issue. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4800 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/n4800...n4810). + + commit 142acf0bbde8d6fd20cb67c051d896fec33a84b6 + Author: stryku + Date: Thu Oct 11 18:41:18 2018 +0200 + + [decl.init]/10 Fix specified initialization. + + According to [basic.start.static]/2, for objects with static storage duration, + zero initialization performs only if constant initialization does not. + [decl.init]/10 can be generalized to static initialization. + This is an editorial note change. + + commit 74def77454a15b6cdb45be0f31916396b4b63b72 + Author: Richard Smith + Date: Fri Mar 15 13:45:06 2019 -0700 + + [util.smartptr.atomic.shared] [util.smartptr.atomic.weak] Clarify + grouping of "either". + + commit 4c5701a79cc7c4cc7b9cd9c6070e3cd88961aca7 + Author: Jens Maurer + Date: Fri Dec 21 21:04:43 2018 +0100 + + [mismatch] LWG3178 std::mismatch is missing an upper bound + + commit 04a5e31a02e19e5d1c9e9a0b05c40ce8730c7064 + Author: Jens Maurer + Date: Sat Jan 26 00:30:13 2019 +0100 + + [algorithms] Qualify declarator-id with sub-namespace. + + Also qualify return types where appropriate. + + commit 6c844190a533950fc0100eac4da7785d99c87400 + Author: Jens Maurer + Date: Fri Mar 15 20:25:59 2019 +0100 + + [time.clock.req] Change 'satisfy' to 'meet'. + + commit c3adaef44b94cc63a8a8806f398185046461947c + Author: Jens Maurer + Date: Fri Mar 15 19:23:30 2019 +0100 + + [numeric.requirements] Define 'numeric type'. + + commit 1ce86a62a3cff9fb2bcf6c1a2c37168e023e338b + Author: Jens Maurer + Date: Sat Mar 9 22:18:26 2019 +0100 + + [time.clock.req] Simplify requirements for Cpp17TrivialClock. + + commit 0ba5424c1beddfd8c8403ce882b96dee0f530c7f + Author: JF Bastien + Date: Fri Mar 15 13:52:39 2019 -0700 + + [basic.fundamental] Rename 'range exponent' to 'width' to align with C + + commit 9e00558f2a824421406a6703d1232cc4fb89bb15 + Author: Arthur O'Dwyer + Date: Fri Mar 15 16:43:16 2019 -0400 + + [std] Fix a bunch of faulty parallelism with "either". + + commit 54ddcb970132bfe026c9d9d62d967632b56ae303 + Author: BRevzin + Date: Fri Mar 15 15:30:07 2019 -0500 + + [class.rel] Simplifying wording to avoid talking about a reversed <=>. + + We can never select a reversed <=> here because the operands are of the same type. + + commit 5d174b05d8cd08717ed7efc05d0271409651071c + Author: Richard Smith + Date: Fri Mar 15 12:33:42 2019 -0700 + + [expr.prim.lambda.capture] Convert paragraphs repeating the + "non-odr-usable local entities shall not be odr-used" rule from + [basic.def.odr] into notes. + + commit 41853024e5e6fcd5feb496f64767d2888d76154f + Author: Richard Smith + Date: Fri Mar 15 11:38:57 2019 -0700 + + Revert "[expr.const] Add missing definition of 'usable in constant expressions'" + + The prior editorial fix was an attempt to re-add wording that was + missing from P0595R2 (moved as 2018-11 CWG Motion 14). However, CWG + analysis has indicated that the editorial fix is incomplete, so we're + reverting it to restore the wording to the as-moved state. + + This reverts commit e58439bce8af85e6569328272c2cfb73f5fc44d6. + + commit 154f2c59c4377897937f4b0722cfe2b6d726cc59 + Author: birbacher + Date: Fri Mar 15 18:39:16 2019 +0000 + + [container.node] Add 3 "template" keywords for dependent name (#2676) + + On: + [container.node.overview]/4 + [container.node.cons]/3.1 + [container.node.dtor]/1 + + commit 2585d7f5894b46e0aa2f961183060a5201b2cca7 + Author: Jens Maurer + Date: Fri Dec 21 19:29:38 2018 +0100 + + [std] Replace underscores in stable labels with periods. + + commit 554a8926404bd5e0f772a6cb72c04bd12a5b7984 + Author: Casey Carter + Date: Mon Mar 4 09:29:50 2019 -0800 + + [specialized.algorithms] Rename voidify's parameter + + `ptr` is an odd name for a parameter that is a reference to storage for an object. + + commit a2dfa61a0d50a24e7be6cbc004bb0f076b8c62b5 + Author: Jens Maurer + Date: Fri Mar 8 22:25:38 2019 +0100 + + [queue.syn,stack.syn] Add partial specialization of uses_allocator + + commit 721f2d606f90cc20a16ad9b4383bc78cb368abdc + Author: Jonathan Wakely + Date: Fri Mar 15 02:53:18 2019 +0000 + + [func.not_fn], [func.bind_front] fix phrasing of \mandates and \expects (#2750) + + The Mandates: element should just state its condition, and not say "shall". + Cpp17 concept requirements should be phrased as "X meets the + Y requirements" not "X shall meet the requirements of Y". + + commit 48484c967ee5f3ecb65ff857f8f4794e108ba0cb + Author: Krystian + Date: Thu Mar 14 22:49:33 2019 -0400 + + [temp.class.spec.mfunc] Correct "class template specialization" to the intended "class template partial specialization" + + commit 3117814eaf800a5e1dd387f4c5a0522f2627689e + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Fri Mar 15 05:48:28 2019 +0300 + + [expr.sizeof] Remove the redundant paragraph 3 + + Paragraph 1 already says that functions are disallowed and function pointers are allowed. + + commit c769f835dadd4a35df9febad684a296d6cb71a53 + Author: JF Bastien + Date: Thu Mar 14 19:45:53 2019 -0700 + + [dcl.attr.contract.cond] Replace return type with 'void' in example that does not return + + Also remove the (unused) name for the return value in the postcondition. + + commit d48c79e223cfbd5ec134703e20989235208e9364 + Author: Jens Maurer + Date: Fri Mar 8 01:14:16 2019 +0100 + + [dcl.enum] Fix singular/plural mismatch. + + commit c5fb73ba6a9b71f6e247103ab4baac1c9f72e210 + Author: Jens Maurer + Date: Fri Mar 8 01:13:35 2019 +0100 + + [conv.prom] b_min and b_max are no longer defined in [dcl.enum] + + commit d7d2580c7d8fabe25ada4dd0e091f9997c0916f5 + Author: Jens Maurer + Date: Sat Mar 9 22:36:47 2019 +0100 + + [range.iota,range.adaptors] Add cross-references for private member types. + + commit b8fd249c737ff2c3652cf6ef77db25712038d353 + Author: Jens Maurer + Date: Sun Mar 10 20:20:10 2019 +0100 + + [dcl.init] Prepend 'Otherwise' to a bullet + + commit dd227824ade24ab51dd4cc926c4b9e87cc29becf + Author: Jens Maurer + Date: Sun Mar 10 20:28:41 2019 +0100 + + [dcl.attr.contract.cond] References cannot be modified. + + Avoid confusion caused by using the words "makes [...] + modifications of the value of [a] parameter" by excluding + references. + + commit b0116b87bf33fed9648e6e8b1b0c7cee0d90b311 + Author: Jason Merrill + Date: Tue Mar 12 09:06:23 2019 -0400 + + [over.match.best] Add number for paragraph 2. + + commit f0f7ba234644d3690d18fcba73f618648014a47c + Author: Jens Maurer + Date: Wed Mar 13 22:21:42 2019 +0100 + + [lib] Use '(inclusive)', not other punctuation + + to indicate inclusive ranges in prose. + + commit 5ba461ec9836f95ed7a54b563b06d480f564e987 + Author: Jens Maurer + Date: Wed Mar 13 22:46:19 2019 +0100 + + [class.eq,class.spaceship] Clarify order of comparison. + + commit 42e5df5c08c9ef805da304fe05fe387cfc3d33d5 + Author: Jens Maurer + Date: Thu Mar 14 00:02:25 2019 +0100 + + [basic.lookup.argdep] Reorder bullets to group semantics. + + commit 927dc13e1010e031692f3a94d8e9599beeb877ac + Author: Richard Smith + Date: Thu Mar 14 17:22:07 2019 -0700 + + [array.tuple] Fix broken description of tuple_element for std::array. + + commit 0b06fcd5f92bc0439a868471a5fdfdba8a181941 + Author: Jens Maurer + Date: Fri Mar 8 22:12:14 2019 +0100 + + [ranges.syn] Add ref_view to header synopsis. + + commit 6f6e5772b2a2dcf41e3db4f68b6cbc3c0628c061 + Author: Richard Smith + Date: Thu Mar 14 16:05:33 2019 -0700 + + [algorithms.parallel.exec] Rephrase to avoid incorrect use of "may not". + + Convert rationale sentence to a note. + + commit de76c7de8c4f9734e0e4351d2088d4786ee62135 + Author: Jens Maurer + Date: Tue Mar 5 21:57:10 2019 +0100 + + [char.traits.typedefs] Change 'shall meet' to 'meets' + + commit e11e27a7873953f0c078901f7ddbb0d7d701c5f7 + Author: Jens Maurer + Date: Wed Mar 6 21:15:37 2019 +0100 + + [mem.poly.allocator.mem] Avoid duplicate colons. + + commit 2956ba37186d7e9cbe728cc3870a2a26fb1f0168 + Author: Richard Smith + Date: Wed Mar 13 14:14:43 2019 -0700 + + [dcl.fct.def.coroutine] Update wording to align with current editorial + conventions. + + Reorder and rearrange to reduce the number of variables with long scopes + that we define in the wording. + + Fix mismatch between core and library wording where library permits + coroutine_handle to resume a coroutine with any promise type, and + the core language does not. + + commit 8dd4539b24473677809163f5e6d399ba6aa0b27d + Author: Richard Smith + Date: Tue Mar 12 18:15:59 2019 -0700 + + [expr.await] Rephrase and modernize wording. + + Invoke temporary materialization conversion directly rather than + handwaving about a temporary object. Specify that the o expression is + evaluated. Bulletize description of the three different ways that + await-suspend is called. + + Fix wording that uses values and objects on the left-hand side of a + class member access to instead consistently use expressions. + + Fixes #2774. + + commit d69814f61077f7e549ccc39a21fc3b90db4223d6 + Author: Richard Smith + Date: Mon Mar 11 20:12:17 2019 -0700 + + [temp.param] "a type that is literal" -> "a literal type". + + commit c0058816fdfe079095ca8717ad692dc2d498d6a3 + Author: Richard Smith + Date: Mon Mar 11 20:11:46 2019 -0700 + + [class.eq] Remove redundant repetition of the operator== symmetry rule. + + commit 007c0c1a619417f94c2c4efb57be71c09f2c2870 + Author: Jens Maurer + Date: Wed Mar 6 21:32:09 2019 +0100 + + [temp.type] Do not refer to operator==, which excludes built-in ==. + + commit caa5c8aedecdf68cfda4f5d95ec9d20451953117 + Author: Jens Maurer + Date: Tue Mar 5 19:05:25 2019 +0100 + + [class.compare.default] Add a note that friends are found by ADL only. + + commit c9074b533c835bbf820f5ea09957810ed2c04dab + Author: Jens Maurer + Date: Wed Mar 6 20:56:58 2019 +0100 + + [expr.new] Move treatment of arrays of unknown bound + + commit ce2f08ab94123adb44e58f1176c6ae4f3209eb60 + Author: Richard Smith + Date: Mon Mar 11 17:20:25 2019 -0700 + + [dcl.init] Merge new direct aggregate init wording into class direct + initialization bullet to avoid the wording being unreachable due to an + "Otherwise" chain. + + commit 691b7c10530d3265afbf445dff3dd129c7c5692e + Author: Dawn Perchik + Date: Sun Mar 10 16:15:53 2019 -0700 + + [dcl.init] Moved the changed bullet in 17.5 to before 17.6.3. + + commit 5f7461d24bc0e9867458a043adf04aa8c4ceed73 + Author: Richard Smith + Date: Fri Mar 8 16:11:34 2019 -0800 + + [temp.dep.type] Rephrase to avoid suggesting that an expression can be + the current instantiation. + + A type can't be the current instantiation either, but that's a + pre-existing prevalent problem. + + commit cbb21fb0210b6aade5591de94e3a27d7059e9d06 + Author: Richard Smith + Date: Fri Mar 8 16:08:02 2019 -0800 + + [basic.def.odr] Apply additional edits from CWG review that were not + transcribed into P1359R0. + + commit ac732bfe4eef01e9e2443dac6138270695d7cbf9 + Author: Richard Smith + Date: Fri Mar 8 12:24:49 2019 -0800 + + [expr.prim.lambda.capture] Add missing close parentheses in CWG2358 + examples. + + Fixes #2680. + + commit 502e419ca75c9656394d1998036b4b810e8bdb17 + Author: Richard Smith + Date: Fri Mar 8 12:00:26 2019 -0800 + + [dcl.type.simple] Fix inaccurate note added by CWG2332 + + [temp.local] Clarify that the surrounding syntax and construct directly + dictates whether an injected-class-name is syntactically a template-name + or a type-name, not just what it means. + + commit f4346ece403e469e800d635a75baafb9c411aa1b + Author: Richard Smith + Date: Fri Mar 8 11:39:36 2019 -0800 + + [expr.static.cast] Fix wording of CWG2310 to match CWG intent (verified + on core reflector): + + - in p11, require D to be a complete class type, not B + - in p12, rephrase to avoid the suggestion that we're talking about a + different D than the one already in scope + + commit 6f34b0513ed6d974b86a27429f8f4d02a6c18b88 + Author: Hana Dusíková + Date: Fri Feb 22 11:03:29 2019 -1000 + + [pair.astuple, tuple.helper] Fix inconsistent class key in tuple_size/tuple_element. (#2679) + + It was declared as a struct and specializations were classes. + + commit 102a791b446f70f939a9b1e2e66fc3553aade19c + Author: Johel Ernesto Guerrero Peña + Date: Fri Feb 22 02:30:23 2019 -0400 + + [array.syn] Add reference to [array.tuple] + + commit 7fe655909b4e5f01d8a8b71d6b508785c42c739e + Author: Richard Smith + Date: Wed Feb 20 17:04:55 2019 -1000 + + [temp.dep] [temp.dep.res] Remove redundant restatement of the two-phase + lookup rule. The primary location of the rule is [temp.dep.candidate]. + + commit 8fbeb52ae5daccc0352798ff023f6cba6aebcd42 + Author: Richard Smith + Date: Mon Feb 18 17:15:39 2019 -1000 + + [basic.link] The notion of the linkage of a type is no longer used for + any purpose. Remove it and move its example next to the rule that + justifies it, and simplify said example. + + commit cafdbd8036f3cf19e9cfc2f56584b219fb190602 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Fri Jan 25 00:12:44 2019 +0300 + + [expr.sizeof]/2: there are no expressions of reference type + + commit 35ce0ae2eb2582dbc00fc824afbfa1d53a64de8d + Author: Richard Smith + Date: Wed Feb 13 17:51:58 2019 -0800 + + [depr.array.comp] Fix example of deprecated array comparison + + commit 2f0bd979f41953890129fcbdc6ef37e3e90387ad + Author: Alisdair Meredith + Date: Sun Feb 10 16:53:15 2019 -0500 + + Add missing noexcept cross-refs for invokable traits (#2662) + + All the other traits that use the phrase 'is known not to throw exceptions' also cross-reference the core clause for the noexcept operator, so add the missing cross reference to the more recently added traits. + + commit 9f261368736c3666791329145292c1563a291861 + Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com> + Date: Sun Feb 10 22:52:36 2019 +0100 + + [temp.mem.func] Fixed text in example, which was not updated by CWG 249 (#2658) + + commit f668df034ebf27ad53b5addad22af4f1293f829f + Author: Jens Maurer + Date: Sun Feb 10 22:50:42 2019 +0100 + + [algorithms.general,concepts.general] Add missing entries for summary tables (#2663) diff --git a/papers/n4820.pdf b/papers/n4820.pdf new file mode 100644 index 0000000000..026c8a569b Binary files /dev/null and b/papers/n4820.pdf differ diff --git a/papers/n4821.html b/papers/n4821.html new file mode 100644 index 0000000000..4cdd33c605 --- /dev/null +++ b/papers/n4821.html @@ -0,0 +1,734 @@ +N4821 +

N4821 Editors' Report -- Programming Languages -- C++

+ +

2019-06-17
+Richard Smith (editor) (Google Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+Jens Maurer (co-editor)
+Dawn Perchik (co-editor) (Bright Side Computing, LLC)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

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

+ +

New papers

+ +
    +
  • N4820 is the current C++ working draft. It replaces N4810.
  • +
  • N4821 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Fixed missing application of a portion of P1032R1, +originally applied by 2018-11 LWG Motion 11.

+ +

P1032R1 section 10 instructs that a set of changes be systematically applied to +all char_traits specializations. As part of the same set of motions, +P0482R6 (2018-11 CWG Motion 11) added two new +char_traits specializations. The intent was for P1032R1 to also apply to the +new specializations, assuming both motions passed (which they did).

+ +

The application of P1032R1 section 10 to the char_traits specializations +added by P0482R6 was missed by editorial oversight, which is repaired in +N4820.

+ +

Notable editorial changes

+ +

Changes to section labels

+ +

To increase stability of references to the standard, labels are now also shown +for tables and figures, in addition to the existing labels for sections.

+ +

The editors hope that the use of stable table labels enables papers to say +which tables the changes the papers describe affect increases clarity.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4810 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 62c2f858b7c954750069f3514e2de2f58464df65
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Mar 18 14:06:16 2019 -0700
+
+    [lex.header] Fix note describing where a header-name token is formed to
+    match the changes applied by P1103R3.
+
+commit fccd9773064e596c4efa58b408bea0615623ff78
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Mar 20 17:32:25 2019 -0700
+
+    [limits.syn,numeric.limits] Declare partial specializations in header synopsis, not class synopsis
+
+    Moves the declarations of the partial specializations of numeric_limits into the header synopsis, out of the class template synopsis.
+
+commit b5ee2beccbe6c39d90768142e564ac749e45f47f
+Author: Krystian <sdkrystian@gmail.com>
+Date:   Thu Mar 28 18:21:23 2019 -0400
+
+    [temp.expl.spec] Fix grammar (add missing article)
+
+    Added "an" before "explicit" to make the sentence grammatically correct.
+
+commit d45c031e2b504cf5b609595751ae22e7122dd4e3
+Author: Akira Takahashi <faithandbrave@gmail.com>
+Date:   Thu Apr 11 19:54:15 2019 +0900
+
+    [memory.syn] Add declaration of primary template "atomic"
+
+    Partial specializations are declared thereafter.
+
+commit f64094025dbbec5daa268f1b5a98f6de37c4e2c2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Apr 11 12:55:18 2019 +0200
+
+    [equal.range] Fix formatting of 'Returns' clause. (#2823)
+
+commit f90f4ea7ba38fef6675c0900d93543dded8c7260
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Thu Apr 11 06:56:42 2019 -0400
+
+    [iterator.traits] Remove redundant required expression in cpp17-input-iterator (#2817)
+
+commit 7c1c2611eac4b970a98bf3dd675daa19f9a7fd5c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Apr 15 15:14:43 2019 -0700
+
+    [expr.ass] Move higher-precedence productions to before the assignment
+    production in the grammar, to be consistent with how we order these
+    productions throughout [expr].
+
+commit 4c21c0c2565effa6c1e672b09540bd6533c02f15
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Apr 20 01:08:09 2019 +0200
+
+    [time.cal.ym.nonmembers] Add missing \pnum for Complexity element. (#2836)
+
+commit fdd3787e0cf76b9c6a3461a32789cf1ffcf9c39d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Apr 26 16:27:52 2019 -0700
+
+    [temp.inst] Fix bogus double-spacing after colon in example.
+
+commit 40c9aa75e8f32e8bab935c04459bf8f648aa89b0
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Apr 29 10:52:32 2019 -0700
+
+    [atomics.types.operations] Fix typo "indeteminate"
+
+    Fixes #2849
+
+commit 569f41ce7410becceaf5537c148b1bc420139bb0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Apr 30 11:21:10 2019 +0200
+
+    [macros] Adjust \tref to include the word 'Table' in the link text. (#2851)
+
+commit 0bae532004c6117b2111d6622d85bd13577a4aaa
+Author: Random Internet Cat <jason.e.cobb@gmail.com>
+Date:   Tue Apr 30 14:57:04 2019 -0400
+
+    [basic.life] Remove erroneous comma in description of treatment of storage out-of-lifetime (#2842)
+
+commit 0f666fa7b5c5a1f869ca0e3bb2506389546a45bd
+Author: Natsu <chino@hotococoa.moe>
+Date:   Wed May 1 03:20:56 2019 +0800
+
+    [cstdio.syn] Rename parameter of function "rename" (#2840)
+
+    The second parameter of function "rename" is called "new", which is a keyword in C++.
+
+commit 8b3480987ee9962cb4191b9230fd9ff6083a273d
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Apr 30 15:23:12 2019 -0400
+
+    [alg.unique] Remove <> after ranges::equal_to (#2826)
+
+commit 65194f717a16bb57da02e7bd1aea02c835dc89d1
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Apr 30 15:33:17 2019 -0400
+
+    [algorithms.requirements] Say 'below to account for clause move (#2812)
+
+commit 27e371dae3fc6484cc2f1bf65d06f9578efd3c32
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Apr 30 16:00:01 2019 -0400
+
+    [iterator.cust] Introduce expression-equivalent list as in [ranges]. (#2845)
+
+commit 205f6c7dff00a5e8c41bc454b0ffe5ac610853ae
+Author: Glen Fernandes <glen.fernandes@gmail.com>
+Date:   Wed May 1 06:05:42 2019 +1000
+
+    [pointer.conversion] Reorder overloads of to_address (#2814)
+
+    pointer.conver
+
+commit da5050ce1092b76ba93699bfd0d6424cd984830a
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Apr 30 13:10:02 2019 -0700
+
+    [coroutine.traits.primary] Hyphenate "program-defined" (#2810)
+
+commit f3d90566f3ca7798fec4fe36c425d03d7dfd8e0f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 1 07:24:45 2019 +0100
+
+    [ranges.dangling] Fix namespace of ranges::dangling (#2829)
+
+    This fixes an editorial mistake in P1252R2; the original proposal correctly
+    defined "dangling" in namespace std::ranges (see P0896R1).
+
+commit 70f8c128e6bef2bf01373ab7c673dee318a89fd6
+Author: frederick-vs-ja <de34@live.cn>
+Date:   Fri May 3 05:29:59 2019 +0800
+
+    [iterators] Add "ranges::" for "iterator_t" (#2860)
+
+    "inserter" and "insert_iterator" are in namespace "std", so
+    "ranges::iterator_t" should be used in their declarations.
+
+commit 7ac32d9c5b134b7e899186b6df8e57aeed7253f1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat May 4 00:57:42 2019 +0200
+
+    [utilities,containers] Harmonize presentation of tuple_element. (#2868)
+
+commit 2eadc8c192dc60981dffd11a1904acda9df5ad01
+Author: Agustín Bergé <k@fusionfenix.com>
+Date:   Sun May 5 19:34:17 2019 -0300
+
+    [optional.ctor] Remove extra dot. (#2875)
+
+commit e095f2d889f382f0ebfb4f16018bda55d437ed2e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun May 5 22:44:42 2019 +0200
+
+    [expr.prim.lambda] Simplify grammar for lambda-expression.
+
+commit 6c87900e78191d1d5d8f79d09b9f78fca83321ff
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 7 02:22:36 2019 +0200
+
+    [map,multimap] Add index entries for members of value_compare. (#2861)
+
+commit f031dfcd84ad9901a552db8241e50cee4bbd5386
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon May 13 16:08:32 2019 -0700
+
+    [module.global] Make the note that only preprocessing directives can
+    appear in the global module fragment prior to preprocessing a bit more
+    obvious and prominent.
+
+commit 32c67d4ee782903e1f051c94e68816a9e188b11f
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat May 18 11:24:20 2019 -0400
+
+    [fs.path.query,fs.op.equivalent] Use 'otherwise', not 'else' (#2883)
+
+commit 40241be416a0babfc41015be4a69ce1a9aa76358
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue May 21 11:21:54 2019 -0700
+
+    [concept.boolean] Simplify first requirement (#2888)
+
+    See P1084 and P0896.
+
+commit 1b7c624e0339d838d8c91253262e0379d22506a5
+Author: frederick-vs-ja <de34@live.cn>
+Date:   Wed May 22 02:24:07 2019 +0800
+
+    [view.interface] Drop unused exposition-only templates (#2881)
+
+commit 5c1728b61a0a66fe7f1818b399f742274fce36ed
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Fri May 24 01:26:25 2019 +0300
+
+    [dcl.init.aggr] Aggregates can have inherited non-public data members (#2892)
+
+commit 665a94500cb78d4b6d2795d396b51df2054094a1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 24 20:24:47 2019 +0200
+
+    [expr.alignof,expr.unary.noexcept] Reorder to after [expr.sizeof]. (#2862)
+
+commit 3526e99dc1257aa6fce561dc2dc020068982b42f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri May 24 20:27:24 2019 +0100
+
+    [fs.rec.dir.itr.members] Change \ensures to \remarks for pop() (#2830)
+
+commit 68c7072ddb7d5ba66aca6d25a054c0eca8c01775
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 24 21:31:22 2019 +0200
+
+    [views.span] Move description of iterators to [span.iterators]. (#2864)
+
+commit aa9fe1fc99da36602e2600ac16636fa7b504b4e5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 24 22:15:00 2019 +0200
+
+    [time.cal.ymwd.nonmembers] Fix typo in parameter names. (#2895)
+
+commit 8cef0f3c119459670335a4a7846344b38ac51918
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 27 09:04:34 2019 +0200
+
+    [char.traits.specializations.char8.t] Make all members constexpr. (#2833)
+
+    Fix missed application of P1032R1 to the result of applying P0482R6;
+    both papers were moved at the 2018-11 meeting.
+
+commit 127bb3653647a350836bb99b4fdc16716de3957a
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue May 28 16:02:20 2019 -0400
+
+    [except.terminate] thread has move-assignment, not copy (#2903)
+
+    The copy-assignment operator for std::thread is deleted, but the
+    move-assignment operator documents a call to std::terminate.
+
+commit f788e132dbfe4252f2852b6123d0bac4674e7dd5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 28 22:28:49 2019 +0200
+
+    [allocator.adaptor.syn] Avoid confusing term 'memory resource'. (#2904)
+
+commit b2e16a61cdbbf177fd8f9e868c9d611d4d9fa50f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 29 20:07:18 2019 +0100
+
+    [dcl.mptr] Add \pnum to note already in a separate paragraph (#2907)
+
+commit 5dce3660fdf06d4c63efeffc329d9a9436c51ea5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 29 21:54:28 2019 +0200
+
+    [time.zone.info] Add missing 'Returns' items. (#2901)
+
+    Also add a missing 'Effects' item.
+
+commit b9f2d303359502de27d399b13e5de41432ce6909
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 29 22:33:01 2019 +0200
+
+    [stmt.stmt,basic.scope.block] Remove normative redundancy.
+
+commit 871b9e1d91ad939afe46b66e6139a527e773200e
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu May 30 11:29:17 2019 -0700
+
+    [coroutine.handle,coroutine.handle.export.import] "static" before "constexpr" (#2811)
+
+commit 899cce08197bb3311e6942dee134cee470625342
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 1 14:23:54 2019 +0200
+
+    [except.uncaught] Clarify duration of uncaught exception.
+
+commit 5df26e149d1cf89c54614fe5f837eef7c6104208
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 3 12:28:49 2019 -0700
+
+    [basic.def.odr] Make case consistent in first word of bullets.
+
+commit a61da77b992f7346bb559ba59c5f53a7df90a569
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jun 4 14:07:18 2019 -0700
+
+    [dcl.fct.def.default] Add missing comma
+
+commit 5b8ed33fdb283364a6a5e7b9572f3e5e16650f40
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 30 23:42:08 2017 +0100
+
+    [language.support, utilities] Condense description of exception classes
+
+commit b6f44de194a2e5702d9658c0e5ed1a8f4f647ece
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 5 22:39:40 2019 +0200
+
+    [module.interface] Use 'namespace-definition',
+
+    not the undefined term 'namespace-declaration'.
+
+commit 04e32a6e79d2a51eeb930e89356dfda27bed841d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 7 01:56:40 2019 +0200
+
+    [unord.req] Consistently use 'Average case x, worst case y.' (#2921)
+
+    Changed from sometimes having 'Worst case' start a separate sentence.
+
+commit 7830d39615bf46563303156ca5f6609c02dd5820
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Jun 11 18:23:12 2019 +0100
+
+    [algorithms.parallel.exec],[alg.set.operations],[alg.min.max],[alg.c.library] remove empty parens (#2925)
+
+    When referring to a function, use its name, not a call expression.
+
+commit 12a28a2eb9f182794fdaf25f1ee5a24e8fa71f1d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jun 11 23:02:46 2019 +0200
+
+    [time.cal.ymwdlast.members] Move statement on class properties (#2927)
+
+    to [time.cal.ymwdlast.overview], consistent with
+    neighboring similar subclauses.
+
+commit 18e005d77a64c930252c2f9f809dc2b40124f7f1
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jun 11 14:54:54 2019 -0700
+
+    [alg.random.sample] Remove redundant requirement (#2798)
+
+    [rand.req.urng]/1 requires that UniformRandomBitGenerator
+    model UnsignedIntegral. [alg.random.sample]/1.5 requires Distance
+    to be an integer type. Any integral type is convertible to any other
+    integral type.
+
+commit daa9a7d0937feb54bc9389096324e5ba36df2f9e
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue May 28 08:15:29 2019 +0100
+
+    [fs.path.append] Fix examples to show correct results for Windows
+
+    Also correct the fact that the results were shown as string literals,
+    not paths, and that the examples for path::operator/=(const path&) were
+    actually using the non-member operator/(const path&, const path&)
+    instead.
+
+    Also line up the comments to the 32nd column.
+
+commit 85f634a82a6f23518245ed251690df52b3555c38
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 28 09:20:53 2019 +0000
+
+    [dcl.type.elab] Mix struct/class in example
+
+    Extend the example to show that the choice of 'class' or 'struct' in an
+    elaborated-type-name referring to a class is not significant.
+
+commit a0f56d5ceb8aeb45549b173164302ef263f0d3c4
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Jun 12 15:46:55 2019 -0700
+
+    [istream.sentry] Remove unreferenced private typedef-name traits_type (#2818)
+
+commit a3eec72ed7a7cd942081b5d5a90737614c67d057
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Apr 10 23:53:39 2019 +0200
+
+    [basic.lookup.elab] Clarify example to refer to injected-class-name
+
+commit 99ec26cfca252dd5f8843ccf54ded17ed95b2436
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Apr 29 22:34:58 2019 +0200
+
+    [dcl.stc,dcl.type.cv] Avoid redundancy when specifying 'mutable'.
+
+commit 506b67005b66af3afbc6edd7bedc772750d0710b
+Author: Krystian Stasiowski <sdkrystian@gmail.com>
+Date:   Wed Jun 12 18:57:20 2019 -0400
+
+    [namespace.def] Remove redundant mention of "global scope".
+
+    The global scope is a namespace scope.
+
+commit 76a0595989a140d142efc236afbb66d1b6e975b6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 3 01:10:13 2019 +0200
+
+    [expr.call,expr.reinterpret.cast] Adjust cross-references for
+    type violations in function calls.
+
+commit dd7b5190279d29f09db4e3009d37398ed6f24de3
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri May 3 14:03:19 2019 -0400
+
+    [string.view.template][string.view.iterators] Move requirements to a more appropriate place
+
+commit 490d0dad072759b448b097eff8fb7b2c304573cd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun May 5 22:30:29 2019 +0200
+
+    [dcl.dcl,temp.spec] Move normative statements on restrictions for
+    explicit specializations and explicit instantiations
+    to [temp.spec] and its subsections.
+
+commit 8845c5c95a62ab7a196016ff484412ce826d2725
+Author: Jason Cobb <jason.e.cobb@gmail.com>
+Date:   Fri May 10 23:07:40 2019 -0400
+
+    [dcl.dcl]/11 Storage from object definitions has proper alignment
+
+commit 373176cfe330ab22a8f6a4273da4817ab9d17438
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed May 22 07:44:42 2019 -0700
+
+    [concept.swappable] Strike array poison pill swap overload
+
+    Since lookup is only performed when at least one argument has class or enumeration type, template argument deduction can never succeed for the poisin pill overload with two parameters of reference-to-array type; it can be struck with no normative impact.
+
+commit 8eff9b95eeedd9fb08816c51f2bb4e4c151de40f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 28 08:55:10 2019 +0200
+
+    [expr.sizeof,expr.alignof,expr.unary.noexcept] Clarify value category.
+
+    Also remove the undefined term 'constant' and
+    instead add a note pointing to [expr.const].
+
+commit 45d9fae43d97355735d81a839a5dbb7abec60aa4
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 29 09:48:09 2019 +0100
+
+    [basic.compound] Replace four refs with a single one to [dcl.meaning]
+
+commit 2c5066bde3eb4300a4f190b491a89400b827334d
+Author: Jason Cobb <jason.e.cobb@gmail.com>
+Date:   Mon Jun 3 12:26:31 2019 -0400
+
+    [over.call.object] Fix surrogate calls with regards to cv-qualifiers
+
+    Standardizes existing practice. All of GCC, Clang, MSVC, ICC in pedantic mode already behave as if all of these changes were made.
+
+commit a02993d3ca83b88140eb5b03f5798ba2f9a77203
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jun 4 18:28:48 2019 -0700
+
+    [range.semi.wrap] Rename "semiregular" to "semiregular-box"
+
+    ...to avoid confusion with the concept `Semiregular`. Update the uses in [range.single.view, range.filter.view,range.transform.view], and add a reference to [range.single.view] which now precedes [range.semi.wrap] since the "range factories" were pulled out into a separate subclause before the "range adaptors."
+
+commit 042e0356bced518954c5ca1c9425226dbeb8b64a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 5 22:44:29 2019 +0200
+
+    [stmt.return.coroutine] Move one level up to avoid hanging paragraphs.
+
+commit 5c5570d29e64c3c143dad6175df7a41e7cef6d3d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 7 00:02:22 2019 +0200
+
+    [expr.add] Avoid x[i] syntax when defining pointer arithmetic.
+
+commit 7756db991e1343bb60bccf43ae825ff55713bfdb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 7 00:26:34 2019 +0200
+
+    [expr.unary.op] Use bullets to clarify the address-of operator.
+
+    Also cover the missed case of a prvalue qualified-id.
+
+commit c60c94398be23f2e5a407c8e3461b692c8fe508d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jun 11 20:24:38 2019 +0200
+
+    [lex] Fix stray uses of 'source character set'
+
+    where it is obvious that 'basic source character set'
+    is meant.
+
+commit 2ee3d07e93049866f6602829dd0ebf469e25f0d2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jun 11 20:32:42 2019 +0200
+
+    [range.split.outer] Convert trailing cross-reference to prefix style.
+
+commit 6f9959805eb3e8e802192b0fb71dbe160ed68a06
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jul 21 16:21:40 2018 +0200
+
+    [dcl.array] Rework description.
+
+    Group examples with the corresponding normative statements.
+    Clarify the meaning of 'array type'.
+    Use 'declarator-id' instead of 'identifier'.
+
+commit f6ad222bfafd939180c9c65f7b0116d0d340001b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 27 09:20:57 2019 +0200
+
+    [range.prim.size] Clarify by adding 'respectively'.
+
+commit b3b1f637f12e2d0b71e351f5c9c3f6acd5059eaa
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri Jun 14 14:21:05 2019 -0700
+
+    [library-wide] Use "model" instead of "satisfy" for semantic library concept requirements
+
+    Consistently use "satisfy" to mean the syntactic requirements are met, and "model" to mean the semantic requirements are met.
+
+    Updates: [structure.requirements],[customization.point.object],[res.on.requirements],[concepts], and [range.semi.wrap].
+
+    Fixes #2591.
+
+commit b50067fe2dec316efc24ae80ae352f33eb31c3af
+Author: Casey Carter <Casey@Carter.net>
+Date:   Sun Apr 14 12:36:57 2019 -0700
+
+    [range.counted] Introduce "Counted view"
+
+    Fixes #2825.
+
+commit da3660306d52d7c1813b6cfae71e78851cd37831
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 6 09:21:12 2019 +0200
+
+    [expr.unary.op] Modernize wording for obtaining a pointer.
+
+commit 97066177229afe6f2935da73b848254ea27a16a2
+Author: Marc Mutz <marc.mutz@kdab.com>
+Date:   Mon Jun 17 12:50:30 2019 +0200
+
+    [list.erasure][forward.list.erasure] Fix missing lambda braces (#2936)
+
+commit f8b8c257ae5bce961c0de29ed8e0ce2d88497acc
+Author: Kazutoshi SATODA <k_satoda@f2.dion.ne.jp>
+Date:   Sun Sep 9 00:11:36 2018 +0900
+
+    [expr.new] Harmonize rules of constant array bounds > 0
+
+    While "shall evaluate to a strictly positive value" is not wrong,
+    "shall be greater than zero" is easier and is used in [dcl.array] to
+    describe the same rule.
+
+commit 15c8259726b565f2a9b3adacdcc85a0727841c7c
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Jun 17 09:52:08 2019 -0700
+
+    [library-wide] Use "meet" for non-concept type requirements (#2796)
+
+    Partially addresses #1263.
+
diff --git a/papers/n4821.md b/papers/n4821.md new file mode 100644 index 0000000000..c917761e68 --- /dev/null +++ b/papers/n4821.md @@ -0,0 +1,608 @@ +# N4821 Editors' Report -- Programming Languages -- C++ + +2019-06-17 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4820](http://wg21.link/n4820) is the current C++ working draft. It replaces [N4810](http://wg21.link/n4810). + * N4821 is this Editors' Report. + +## Motions incorporated into working draft + +Fixed missing application of a portion of [P1032R1](http://wg21.link/p1032r1), +originally applied by 2018-11 LWG Motion 11. + +P1032R1 section 10 instructs that a set of changes be systematically applied to +all `char_traits` specializations. As part of the same set of motions, +[P0482R6](http://wg21.link/p0482r6) (2018-11 CWG Motion 11) added two new +`char_traits` specializations. The intent was for P1032R1 to also apply to the +new specializations, assuming both motions passed (which they did). + +The application of P1032R1 section 10 to the `char_traits` specializations +added by P0482R6 was missed by editorial oversight, which is repaired in +N4820. + +## Notable editorial changes + +### Changes to section labels + +To increase stability of references to the standard, labels are now also shown +for tables and figures, in addition to the existing labels for sections. + +The editors hope that the use of stable table labels enables papers to say +which tables the changes the papers describe affect increases clarity. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4810 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/n4810...n4820). + + commit 62c2f858b7c954750069f3514e2de2f58464df65 + Author: Richard Smith + Date: Mon Mar 18 14:06:16 2019 -0700 + + [lex.header] Fix note describing where a header-name token is formed to + match the changes applied by P1103R3. + + commit fccd9773064e596c4efa58b408bea0615623ff78 + Author: Casey Carter + Date: Wed Mar 20 17:32:25 2019 -0700 + + [limits.syn,numeric.limits] Declare partial specializations in header synopsis, not class synopsis + + Moves the declarations of the partial specializations of numeric_limits into the header synopsis, out of the class template synopsis. + + commit b5ee2beccbe6c39d90768142e564ac749e45f47f + Author: Krystian + Date: Thu Mar 28 18:21:23 2019 -0400 + + [temp.expl.spec] Fix grammar (add missing article) + + Added "an" before "explicit" to make the sentence grammatically correct. + + commit d45c031e2b504cf5b609595751ae22e7122dd4e3 + Author: Akira Takahashi + Date: Thu Apr 11 19:54:15 2019 +0900 + + [memory.syn] Add declaration of primary template "atomic" + + Partial specializations are declared thereafter. + + commit f64094025dbbec5daa268f1b5a98f6de37c4e2c2 + Author: Jens Maurer + Date: Thu Apr 11 12:55:18 2019 +0200 + + [equal.range] Fix formatting of 'Returns' clause. (#2823) + + commit f90f4ea7ba38fef6675c0900d93543dded8c7260 + Author: Johel Ernesto Guerrero Peña + Date: Thu Apr 11 06:56:42 2019 -0400 + + [iterator.traits] Remove redundant required expression in cpp17-input-iterator (#2817) + + commit 7c1c2611eac4b970a98bf3dd675daa19f9a7fd5c + Author: Richard Smith + Date: Mon Apr 15 15:14:43 2019 -0700 + + [expr.ass] Move higher-precedence productions to before the assignment + production in the grammar, to be consistent with how we order these + productions throughout [expr]. + + commit 4c21c0c2565effa6c1e672b09540bd6533c02f15 + Author: Eelis + Date: Sat Apr 20 01:08:09 2019 +0200 + + [time.cal.ym.nonmembers] Add missing \pnum for Complexity element. (#2836) + + commit fdd3787e0cf76b9c6a3461a32789cf1ffcf9c39d + Author: Richard Smith + Date: Fri Apr 26 16:27:52 2019 -0700 + + [temp.inst] Fix bogus double-spacing after colon in example. + + commit 40c9aa75e8f32e8bab935c04459bf8f648aa89b0 + Author: Richard Smith + Date: Mon Apr 29 10:52:32 2019 -0700 + + [atomics.types.operations] Fix typo "indeteminate" + + Fixes #2849 + + commit 569f41ce7410becceaf5537c148b1bc420139bb0 + Author: Jens Maurer + Date: Tue Apr 30 11:21:10 2019 +0200 + + [macros] Adjust \tref to include the word 'Table' in the link text. (#2851) + + commit 0bae532004c6117b2111d6622d85bd13577a4aaa + Author: Random Internet Cat + Date: Tue Apr 30 14:57:04 2019 -0400 + + [basic.life] Remove erroneous comma in description of treatment of storage out-of-lifetime (#2842) + + commit 0f666fa7b5c5a1f869ca0e3bb2506389546a45bd + Author: Natsu + Date: Wed May 1 03:20:56 2019 +0800 + + [cstdio.syn] Rename parameter of function "rename" (#2840) + + The second parameter of function "rename" is called "new", which is a keyword in C++. + + commit 8b3480987ee9962cb4191b9230fd9ff6083a273d + Author: Johel Ernesto Guerrero Peña + Date: Tue Apr 30 15:23:12 2019 -0400 + + [alg.unique] Remove <> after ranges::equal_to (#2826) + + commit 65194f717a16bb57da02e7bd1aea02c835dc89d1 + Author: Johel Ernesto Guerrero Peña + Date: Tue Apr 30 15:33:17 2019 -0400 + + [algorithms.requirements] Say 'below to account for clause move (#2812) + + commit 27e371dae3fc6484cc2f1bf65d06f9578efd3c32 + Author: Johel Ernesto Guerrero Peña + Date: Tue Apr 30 16:00:01 2019 -0400 + + [iterator.cust] Introduce expression-equivalent list as in [ranges]. (#2845) + + commit 205f6c7dff00a5e8c41bc454b0ffe5ac610853ae + Author: Glen Fernandes + Date: Wed May 1 06:05:42 2019 +1000 + + [pointer.conversion] Reorder overloads of to_address (#2814) + + pointer.conver + + commit da5050ce1092b76ba93699bfd0d6424cd984830a + Author: Casey Carter + Date: Tue Apr 30 13:10:02 2019 -0700 + + [coroutine.traits.primary] Hyphenate "program-defined" (#2810) + + commit f3d90566f3ca7798fec4fe36c425d03d7dfd8e0f + Author: Jonathan Wakely + Date: Wed May 1 07:24:45 2019 +0100 + + [ranges.dangling] Fix namespace of ranges::dangling (#2829) + + This fixes an editorial mistake in P1252R2; the original proposal correctly + defined "dangling" in namespace std::ranges (see P0896R1). + + commit 70f8c128e6bef2bf01373ab7c673dee318a89fd6 + Author: frederick-vs-ja + Date: Fri May 3 05:29:59 2019 +0800 + + [iterators] Add "ranges::" for "iterator_t" (#2860) + + "inserter" and "insert_iterator" are in namespace "std", so + "ranges::iterator_t" should be used in their declarations. + + commit 7ac32d9c5b134b7e899186b6df8e57aeed7253f1 + Author: Jens Maurer + Date: Sat May 4 00:57:42 2019 +0200 + + [utilities,containers] Harmonize presentation of tuple_element. (#2868) + + commit 2eadc8c192dc60981dffd11a1904acda9df5ad01 + Author: Agustín Bergé + Date: Sun May 5 19:34:17 2019 -0300 + + [optional.ctor] Remove extra dot. (#2875) + + commit e095f2d889f382f0ebfb4f16018bda55d437ed2e + Author: Jens Maurer + Date: Sun May 5 22:44:42 2019 +0200 + + [expr.prim.lambda] Simplify grammar for lambda-expression. + + commit 6c87900e78191d1d5d8f79d09b9f78fca83321ff + Author: Jens Maurer + Date: Tue May 7 02:22:36 2019 +0200 + + [map,multimap] Add index entries for members of value_compare. (#2861) + + commit f031dfcd84ad9901a552db8241e50cee4bbd5386 + Author: Richard Smith + Date: Mon May 13 16:08:32 2019 -0700 + + [module.global] Make the note that only preprocessing directives can + appear in the global module fragment prior to preprocessing a bit more + obvious and prominent. + + commit 32c67d4ee782903e1f051c94e68816a9e188b11f + Author: Johel Ernesto Guerrero Peña + Date: Sat May 18 11:24:20 2019 -0400 + + [fs.path.query,fs.op.equivalent] Use 'otherwise', not 'else' (#2883) + + commit 40241be416a0babfc41015be4a69ce1a9aa76358 + Author: Casey Carter + Date: Tue May 21 11:21:54 2019 -0700 + + [concept.boolean] Simplify first requirement (#2888) + + See P1084 and P0896. + + commit 1b7c624e0339d838d8c91253262e0379d22506a5 + Author: frederick-vs-ja + Date: Wed May 22 02:24:07 2019 +0800 + + [view.interface] Drop unused exposition-only templates (#2881) + + commit 5c1728b61a0a66fe7f1818b399f742274fce36ed + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Fri May 24 01:26:25 2019 +0300 + + [dcl.init.aggr] Aggregates can have inherited non-public data members (#2892) + + commit 665a94500cb78d4b6d2795d396b51df2054094a1 + Author: Jens Maurer + Date: Fri May 24 20:24:47 2019 +0200 + + [expr.alignof,expr.unary.noexcept] Reorder to after [expr.sizeof]. (#2862) + + commit 3526e99dc1257aa6fce561dc2dc020068982b42f + Author: Jonathan Wakely + Date: Fri May 24 20:27:24 2019 +0100 + + [fs.rec.dir.itr.members] Change \ensures to \remarks for pop() (#2830) + + commit 68c7072ddb7d5ba66aca6d25a054c0eca8c01775 + Author: Jens Maurer + Date: Fri May 24 21:31:22 2019 +0200 + + [views.span] Move description of iterators to [span.iterators]. (#2864) + + commit aa9fe1fc99da36602e2600ac16636fa7b504b4e5 + Author: Jens Maurer + Date: Fri May 24 22:15:00 2019 +0200 + + [time.cal.ymwd.nonmembers] Fix typo in parameter names. (#2895) + + commit 8cef0f3c119459670335a4a7846344b38ac51918 + Author: Jens Maurer + Date: Mon May 27 09:04:34 2019 +0200 + + [char.traits.specializations.char8.t] Make all members constexpr. (#2833) + + Fix missed application of P1032R1 to the result of applying P0482R6; + both papers were moved at the 2018-11 meeting. + + commit 127bb3653647a350836bb99b4fdc16716de3957a + Author: Alisdair Meredith + Date: Tue May 28 16:02:20 2019 -0400 + + [except.terminate] thread has move-assignment, not copy (#2903) + + The copy-assignment operator for std::thread is deleted, but the + move-assignment operator documents a call to std::terminate. + + commit f788e132dbfe4252f2852b6123d0bac4674e7dd5 + Author: Jens Maurer + Date: Tue May 28 22:28:49 2019 +0200 + + [allocator.adaptor.syn] Avoid confusing term 'memory resource'. (#2904) + + commit b2e16a61cdbbf177fd8f9e868c9d611d4d9fa50f + Author: Jonathan Wakely + Date: Wed May 29 20:07:18 2019 +0100 + + [dcl.mptr] Add \pnum to note already in a separate paragraph (#2907) + + commit 5dce3660fdf06d4c63efeffc329d9a9436c51ea5 + Author: Jens Maurer + Date: Wed May 29 21:54:28 2019 +0200 + + [time.zone.info] Add missing 'Returns' items. (#2901) + + Also add a missing 'Effects' item. + + commit b9f2d303359502de27d399b13e5de41432ce6909 + Author: Jens Maurer + Date: Wed May 29 22:33:01 2019 +0200 + + [stmt.stmt,basic.scope.block] Remove normative redundancy. + + commit 871b9e1d91ad939afe46b66e6139a527e773200e + Author: Casey Carter + Date: Thu May 30 11:29:17 2019 -0700 + + [coroutine.handle,coroutine.handle.export.import] "static" before "constexpr" (#2811) + + commit 899cce08197bb3311e6942dee134cee470625342 + Author: Jens Maurer + Date: Sat Jun 1 14:23:54 2019 +0200 + + [except.uncaught] Clarify duration of uncaught exception. + + commit 5df26e149d1cf89c54614fe5f837eef7c6104208 + Author: Richard Smith + Date: Mon Jun 3 12:28:49 2019 -0700 + + [basic.def.odr] Make case consistent in first word of bullets. + + commit a61da77b992f7346bb559ba59c5f53a7df90a569 + Author: Casey Carter + Date: Tue Jun 4 14:07:18 2019 -0700 + + [dcl.fct.def.default] Add missing comma + + commit 5b8ed33fdb283364a6a5e7b9572f3e5e16650f40 + Author: Jens Maurer + Date: Thu Nov 30 23:42:08 2017 +0100 + + [language.support, utilities] Condense description of exception classes + + commit b6f44de194a2e5702d9658c0e5ed1a8f4f647ece + Author: Jens Maurer + Date: Wed Jun 5 22:39:40 2019 +0200 + + [module.interface] Use 'namespace-definition', + + not the undefined term 'namespace-declaration'. + + commit 04e32a6e79d2a51eeb930e89356dfda27bed841d + Author: Jens Maurer + Date: Fri Jun 7 01:56:40 2019 +0200 + + [unord.req] Consistently use 'Average case x, worst case y.' (#2921) + + Changed from sometimes having 'Worst case' start a separate sentence. + + commit 7830d39615bf46563303156ca5f6609c02dd5820 + Author: Jonathan Wakely + Date: Tue Jun 11 18:23:12 2019 +0100 + + [algorithms.parallel.exec],[alg.set.operations],[alg.min.max],[alg.c.library] remove empty parens (#2925) + + When referring to a function, use its name, not a call expression. + + commit 12a28a2eb9f182794fdaf25f1ee5a24e8fa71f1d + Author: Jens Maurer + Date: Tue Jun 11 23:02:46 2019 +0200 + + [time.cal.ymwdlast.members] Move statement on class properties (#2927) + + to [time.cal.ymwdlast.overview], consistent with + neighboring similar subclauses. + + commit 18e005d77a64c930252c2f9f809dc2b40124f7f1 + Author: Casey Carter + Date: Tue Jun 11 14:54:54 2019 -0700 + + [alg.random.sample] Remove redundant requirement (#2798) + + [rand.req.urng]/1 requires that UniformRandomBitGenerator + model UnsignedIntegral. [alg.random.sample]/1.5 requires Distance + to be an integer type. Any integral type is convertible to any other + integral type. + + commit daa9a7d0937feb54bc9389096324e5ba36df2f9e + Author: Jonathan Wakely + Date: Tue May 28 08:15:29 2019 +0100 + + [fs.path.append] Fix examples to show correct results for Windows + + Also correct the fact that the results were shown as string literals, + not paths, and that the examples for path::operator/=(const path&) were + actually using the non-member operator/(const path&, const path&) + instead. + + Also line up the comments to the 32nd column. + + commit 85f634a82a6f23518245ed251690df52b3555c38 + Author: Jonathan Wakely + Date: Thu Mar 28 09:20:53 2019 +0000 + + [dcl.type.elab] Mix struct/class in example + + Extend the example to show that the choice of 'class' or 'struct' in an + elaborated-type-name referring to a class is not significant. + + commit a0f56d5ceb8aeb45549b173164302ef263f0d3c4 + Author: Casey Carter + Date: Wed Jun 12 15:46:55 2019 -0700 + + [istream.sentry] Remove unreferenced private typedef-name traits_type (#2818) + + commit a3eec72ed7a7cd942081b5d5a90737614c67d057 + Author: Jens Maurer + Date: Wed Apr 10 23:53:39 2019 +0200 + + [basic.lookup.elab] Clarify example to refer to injected-class-name + + commit 99ec26cfca252dd5f8843ccf54ded17ed95b2436 + Author: Jens Maurer + Date: Mon Apr 29 22:34:58 2019 +0200 + + [dcl.stc,dcl.type.cv] Avoid redundancy when specifying 'mutable'. + + commit 506b67005b66af3afbc6edd7bedc772750d0710b + Author: Krystian Stasiowski + Date: Wed Jun 12 18:57:20 2019 -0400 + + [namespace.def] Remove redundant mention of "global scope". + + The global scope is a namespace scope. + + commit 76a0595989a140d142efc236afbb66d1b6e975b6 + Author: Jens Maurer + Date: Fri May 3 01:10:13 2019 +0200 + + [expr.call,expr.reinterpret.cast] Adjust cross-references for + type violations in function calls. + + commit dd7b5190279d29f09db4e3009d37398ed6f24de3 + Author: Johel Ernesto Guerrero Peña + Date: Fri May 3 14:03:19 2019 -0400 + + [string.view.template][string.view.iterators] Move requirements to a more appropriate place + + commit 490d0dad072759b448b097eff8fb7b2c304573cd + Author: Jens Maurer + Date: Sun May 5 22:30:29 2019 +0200 + + [dcl.dcl,temp.spec] Move normative statements on restrictions for + explicit specializations and explicit instantiations + to [temp.spec] and its subsections. + + commit 8845c5c95a62ab7a196016ff484412ce826d2725 + Author: Jason Cobb + Date: Fri May 10 23:07:40 2019 -0400 + + [dcl.dcl]/11 Storage from object definitions has proper alignment + + commit 373176cfe330ab22a8f6a4273da4817ab9d17438 + Author: Casey Carter + Date: Wed May 22 07:44:42 2019 -0700 + + [concept.swappable] Strike array poison pill swap overload + + Since lookup is only performed when at least one argument has class or enumeration type, template argument deduction can never succeed for the poisin pill overload with two parameters of reference-to-array type; it can be struck with no normative impact. + + commit 8eff9b95eeedd9fb08816c51f2bb4e4c151de40f + Author: Jens Maurer + Date: Tue May 28 08:55:10 2019 +0200 + + [expr.sizeof,expr.alignof,expr.unary.noexcept] Clarify value category. + + Also remove the undefined term 'constant' and + instead add a note pointing to [expr.const]. + + commit 45d9fae43d97355735d81a839a5dbb7abec60aa4 + Author: Jonathan Wakely + Date: Wed May 29 09:48:09 2019 +0100 + + [basic.compound] Replace four refs with a single one to [dcl.meaning] + + commit 2c5066bde3eb4300a4f190b491a89400b827334d + Author: Jason Cobb + Date: Mon Jun 3 12:26:31 2019 -0400 + + [over.call.object] Fix surrogate calls with regards to cv-qualifiers + + Standardizes existing practice. All of GCC, Clang, MSVC, ICC in pedantic mode already behave as if all of these changes were made. + + commit a02993d3ca83b88140eb5b03f5798ba2f9a77203 + Author: Casey Carter + Date: Tue Jun 4 18:28:48 2019 -0700 + + [range.semi.wrap] Rename "semiregular" to "semiregular-box" + + ...to avoid confusion with the concept `Semiregular`. Update the uses in [range.single.view, range.filter.view,range.transform.view], and add a reference to [range.single.view] which now precedes [range.semi.wrap] since the "range factories" were pulled out into a separate subclause before the "range adaptors." + + commit 042e0356bced518954c5ca1c9425226dbeb8b64a + Author: Jens Maurer + Date: Wed Jun 5 22:44:29 2019 +0200 + + [stmt.return.coroutine] Move one level up to avoid hanging paragraphs. + + commit 5c5570d29e64c3c143dad6175df7a41e7cef6d3d + Author: Jens Maurer + Date: Fri Jun 7 00:02:22 2019 +0200 + + [expr.add] Avoid x[i] syntax when defining pointer arithmetic. + + commit 7756db991e1343bb60bccf43ae825ff55713bfdb + Author: Jens Maurer + Date: Fri Jun 7 00:26:34 2019 +0200 + + [expr.unary.op] Use bullets to clarify the address-of operator. + + Also cover the missed case of a prvalue qualified-id. + + commit c60c94398be23f2e5a407c8e3461b692c8fe508d + Author: Jens Maurer + Date: Tue Jun 11 20:24:38 2019 +0200 + + [lex] Fix stray uses of 'source character set' + + where it is obvious that 'basic source character set' + is meant. + + commit 2ee3d07e93049866f6602829dd0ebf469e25f0d2 + Author: Jens Maurer + Date: Tue Jun 11 20:32:42 2019 +0200 + + [range.split.outer] Convert trailing cross-reference to prefix style. + + commit 6f9959805eb3e8e802192b0fb71dbe160ed68a06 + Author: Jens Maurer + Date: Sat Jul 21 16:21:40 2018 +0200 + + [dcl.array] Rework description. + + Group examples with the corresponding normative statements. + Clarify the meaning of 'array type'. + Use 'declarator-id' instead of 'identifier'. + + commit f6ad222bfafd939180c9c65f7b0116d0d340001b + Author: Jens Maurer + Date: Mon May 27 09:20:57 2019 +0200 + + [range.prim.size] Clarify by adding 'respectively'. + + commit b3b1f637f12e2d0b71e351f5c9c3f6acd5059eaa + Author: Casey Carter + Date: Fri Jun 14 14:21:05 2019 -0700 + + [library-wide] Use "model" instead of "satisfy" for semantic library concept requirements + + Consistently use "satisfy" to mean the syntactic requirements are met, and "model" to mean the semantic requirements are met. + + Updates: [structure.requirements],[customization.point.object],[res.on.requirements],[concepts], and [range.semi.wrap]. + + Fixes #2591. + + commit b50067fe2dec316efc24ae80ae352f33eb31c3af + Author: Casey Carter + Date: Sun Apr 14 12:36:57 2019 -0700 + + [range.counted] Introduce "Counted view" + + Fixes #2825. + + commit da3660306d52d7c1813b6cfae71e78851cd37831 + Author: Jens Maurer + Date: Thu Jun 6 09:21:12 2019 +0200 + + [expr.unary.op] Modernize wording for obtaining a pointer. + + commit 97066177229afe6f2935da73b848254ea27a16a2 + Author: Marc Mutz + Date: Mon Jun 17 12:50:30 2019 +0200 + + [list.erasure][forward.list.erasure] Fix missing lambda braces (#2936) + + commit f8b8c257ae5bce961c0de29ed8e0ce2d88497acc + Author: Kazutoshi SATODA + Date: Sun Sep 9 00:11:36 2018 +0900 + + [expr.new] Harmonize rules of constant array bounds > 0 + + While "shall evaluate to a strictly positive value" is not wrong, + "shall be greater than zero" is easier and is used in [dcl.array] to + describe the same rule. + + commit 15c8259726b565f2a9b3adacdcc85a0727841c7c + Author: Casey Carter + Date: Mon Jun 17 09:52:08 2019 -0700 + + [library-wide] Use "meet" for non-concept type requirements (#2796) + + Partially addresses #1263. diff --git a/papers/n4829.html b/papers/n4829.html new file mode 100644 index 0000000000..6c821330f4 --- /dev/null +++ b/papers/n4829.html @@ -0,0 +1,1279 @@ +N4829 +

N4829 Editors' Report -- Programming Languages -- C++

+ +

2019-08-15
+Richard Smith (editor) (Google Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+Jens Maurer (co-editor)
+Dawn Perchik (co-editor) (Bright Side Computing, LLC)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Special thanks to several paper authors +for supplying the LaTeX sources for their papers.

+ +

Special thanks also to the Editing Committee -- +Daniel Krügler, Davis Herring, Nina Ranns, and Ville Voutilainen -- +for providing a careful review of the application of these motions +and the editorial changes described below +to ensure the correctness of the C++20 Committee Draft.

+ +

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

+ +

New papers

+ +
    +
  • N4830 is the committee draft for C++20. It replaces N4820.
  • +
  • N4829 is this Editors' Report.
  • +
+ +

Note: +A working draft was circulated to the editing committee for review, +and was mistakenly published with paper number N4828. +N4828 is not the C++20 Committee Draft, +and does not contain the results of addressing feedback from +the editing committee.

+ +

Motions incorporated into working draft

+ +

Core working group motions

+ +

CWG motion 1: Core issue resolutions for 10 issues in "tentatively ready" status applied: (DR)

+ +
    +
  • 682 Missing description of lookup of template aliases
  • +
  • 2207 Alignment of allocation function return value
  • +
  • 2300 Lambdas in multiple definitions
  • +
  • 2366 Can default initialization be constant initialization?
  • +
  • 2376 Class template argument deduction with array declarator
  • +
  • 2390 Is the argument of __has_cpp_attribute macro-expanded?
  • +
  • 2400 Constexpr virtual functions and temporary objects
  • +
  • 2404 [[no_unique_address]] and allocation order
  • +
  • 2406 [[fallthrough]] attribute and iteration statements
  • +
  • 2418 Missing cases in definition of "usable in constant expressions"
  • +
+ +

CWG motion 2: P1161R3 "Deprecate uses of the comma operator in subscripting expressions"

+ +

CWG motion 3: P1331R2 "Permitting trivial default initialization in constexpr contexts"

+ +

CWG motion 4: P0735R1 "Interaction of memory_order_consume with release sequences"

+ +

CWG motion 5: P0848R3 "Conditionally trivial special member functions"

+ +

CWG motion 6: P1186R3 "When do you actually use <=>?"

+ +

CWG motion 7: P1301R4 "[[nodiscard("should have a reason")]]"

+ +

CWG motion 8: P1099R5 "using enum"

+ +

CWG motion 9: P1630R1 "Spaceship needs a tune-up"

+ +

CWG motion 10: P1616R1 "Using unconstrained template template parameters with constrained templates"

+ +

CWG motion 11: P1816R0 "Class template argument deduction for aggregates"

+ +

CWG motion 12: P1668R1 "Enabling constexpr intrinsics by permitting unevaluated inline assembly in constexpr functions"

+ +

CWG motion 13: P1766R1 "Mitigating minor modules maladies" (DR)

+ +

CWG motion 14: P1811R0 "Relaxing redefinition restrictions for re-exportation robustness"

+ +

CWG motion 15: P0388R4 "Permit conversions to arrays of unknown bound"

+ +

CWG motion 16: P1823R0 "Remove contracts"

+ +

CWG motion 17: P1143R2 "Adding the constinit keyword"

+ +

CWG motion 18: P1452R2 "On the non-uniform semantics of return-type-requirements"

+ +

CWG motion 19: P1152R4 "Deprecating volatile"

+ +

CWG motion 20: P1771R1 "[[nodiscard]] for constructors" (DR)

+ +

CWG motion 21: P1814R0 "Class template argument deduction for alias templates"

+ +

CWG motion 22 was withdrawn

+ +

CWG motion 23: P1825R0 "Merged wording for P0527R1 and P1155R3" (DR)

+ + + +

CWG motion 24: P1703R1 "Recognizing header unit imports requires full preprocessing"

+ +

CWG motion 25: P0784R7 "More constexpr containers"

+ +

Library working group motions

+ +

LWG motion 1: Library issue resolutions for 17 issues in "Ready" and "Tentatively Ready" status applied: (DR)

+ +
    +
  • 3209 Expression in year::ok() returns clause is ill-formed
  • +
  • 3208 Boolean's expression requirements are ordered inconsistently
  • +
  • 3206 year_month_day conversion to sys_days uses not-existing member function
  • +
  • 3202 P0318R1 was supposed to be revised
  • +
  • 3199 istream >> bitset<0> fails
  • +
  • 3198 Bad constraint on std::span::span()
  • +
  • 3196 std::optional<T> is ill-formed if T is an array
  • +
  • 3191 std::ranges::shuffle synopsis does not match algorithm definition
  • +
  • 3187 P0591R4 reverted DR 2586 fixes to scoped_allocator_adaptor::construct()
  • +
  • 3186 Ranges remove, partition, and partial_sort_copy algorithms discard useful information
  • +
  • 3185 Uses-allocator construction functions missing constexpr and noexcept
  • +
  • 3184 Inconsistencies in bind_front wording
  • +
  • 3183 Normative permission to specialize ranges variable templates
  • +
  • 3169 Ranges permutation generators discard useful information
  • +
  • 3158 tuple(allocator_arg_t, const Alloc&) should be conditionally explicit
  • +
  • 3055 path::operator+=(single-character) misspecified
  • +
  • 2899 is_(nothrow_)move_constructible and tuple, optional and unique_ptr
  • +
+ +

LWG motion 2: P1355R2 "Exposing a narrow contract for ceil2"

+ +

LWG motion 3: P0553R4 "Bit operations"

+ +

LWG motion 4: P1424R1 "constexpr feature macro concerns"

+ +

LWG motion 5: P0645R10 "Text formatting"

+ +

LWG motion 6: P1361R2 "Integration of chrono with text formatting"

+ +

LWG motion 7: P1652R1 "Printf corner cases in std::format"

+ +

LWG motion 8: P0631R8 "Math constants"

+ +

LWG motion 9: Synchronization library:

+ + + +

LWG motion 10: P1466R3 "Miscellaneous minor fixes for chrono"

+ +

LWG motion 11: P1754R1 "Rename concepts to standard_case for C++20, while we still can"

+ +

LWG motion 12: P1614R2 "The mothership has landed"

+ +

LWG motion 13: P0325R4 "to_array from LFTS with updates"

+ +

LWG motion 14: P0408R7 "Efficient access to basic_stringbuf's buffer"

+ +

LWG motion 15: P1423R3 "char8_t backward compatibility remediation"

+ +

LWG motion 16: P1502R1 "Standard library header units"

+ +

LWG motion 17: P1612R1 "Relocate endian's specification"

+ +

LWG motion 18: P1661R1 "Remove dedicated precalculated hash lookup interface"

+ +

LWG motion 19: P1650R0 "Output std::chrono::days with d suffix"

+ +

LWG motion 20: P1651R0 "bind_front should not unwrap reference_wrapper"

+ +

LWG motion 21: P1065R2 "Constexpr invoke"

+ +

LWG motion 22: P1207R4 "Movability of single-pass iterators"

+ +

LWG motion 23: P1035R7 "Input range adaptors"

+ +

LWG motion 24: P1638R1 "basic_istream_view::iterator should not be copyable"

+ +

LWG motion 25: P1522R1 "Iterator difference type and integer overflow"

+ +

LWG motion 26: P1004R2 "Making std::vector constexpr"

+ +

LWG motion 27: P0980R1 "Making std::string constexpr"

+ +

LWG motion 28: P0660R10 "Stop token and joining thread"

+ +

LWG motion 29: P1474R1 "Helpful pointers for ContiguousIterator"

+ +

LWG motion 30: P1523R1 "Views and size types"

+ +

LWG motion 31: P0466R5 "Layout-compatibility and pointer-interconvertibility traits"

+ +

LWG motion 32: P1208R6 "source_location"

+ +

Notable editorial changes

+ +

CWG motion 21

+ +

The changes for this motion in [over.match.class.deduct] +described the matching of a simple-template-id against +the defining-type-id of an alias template +in imprecise terms +(quoting only part of the grammar to which the change intended to apply). +This has been made more precise by repeating the full grammar +previously specified in [dcl.type.simple] +in [over.match.class.deduct].

+ +

LWG motions 5-7

+ +

The new std::format library underwent substantial editorial rework +for clarity and precision. +Thanks to Tomasz Kamiński and +Johel Ernesto Guerrero Peña +for reviewing the resulting edits, +and to Victor Zverovich for responding to various questions about intent.

+ +

LWG motion 10

+ +

The operator<< added for hh_mm_ss was written in terms of +the old chrono formatting machinery that was replaced by +std::format-based machinery by LWG motion 6. +It has been rephrased in terms of std::format. +Thanks to Howard Hinnant for providing wording.

+ +

LWG motion 11

+ +

In addition to the requested renames, the following concepts were also renamed, +following the editorial instructions to rename all other concepts:

+ +
    +
  • ThreeWayComparableWith -> three_way_comparable_with
  • +
  • ThreeWayComparable -> three_way_comparable
  • +
  • ForwardRange -> forward_range
  • +
+ +

LWG motion 14

+ +

This motion requested that the same constructor be added to basic_stringbuf +twice. It was only added once.

+ +

LWG motion 23

+ +

The wording paper proposed making changes to the algorithms

+ +
    +
  • std::ranges::sample
  • +
  • std::ranges::shift_left
  • +
  • std::ranges::shift_right
  • +
+ +

However, these algorithms were never adopted into the C++ working draft from +the Ranges Technical Specification, so after consulting with the Library +Working Group, the requested changes to these algorithms were ignored.

+ +

LWG motion 26, 27

+ +

These motions would have added constexpr to +operator<, operator>, operator<=, operator>=, and operator!= functions +that LWG motion 12 removed. +Instead constexpr was added to the replacement operator<=>.

+ +

In addition, following the paper's request to add constexpr to any +std::basic_string functions that the wording missed, and after consulting +with the LWG chair as directed, the overloads of std::erase and +std::erase_if for std::basic_string were also marked contexpr.

+ +

Section label changes

+ +

Several section labels introduced by the motions papers have been modified +to match our style guide. In addition to the section labels affected by the +above motions, the following section labels have been renamed:

+ +
    +
  • [concept.convertibleto] => [concept.convertible]
  • +
  • [concept.derivedfrom] => [concept.derived]
  • +
  • [concept.stricttotallyordered] => [concept.totallyordered]
  • +
+ +

Feature test macros

+ +

Attention should be drawn to the fact that multiple papers updated feature test +macros to the same version:

+ +
    +
  • __cpp_constexpr was updated to 201907L by both +P1331R2 (CWG motion 3) and +P1668R1 (CWG motion 12).
  • +
  • __has_cpp_attribute(nodiscard) was updated to 201907L by both +P1304R4 (CWG motion 7) and +P1771R1 (CWG motion 20).
  • +
+ +

Implementers should be aware that the new version of the feature test macro +advertises support for both papers in these cases (in addition to advertising +support for prior papers that gave smaller version numbers to the relevant +macro).

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4820 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 44ea29778d15cd5d9f2b5c706c6b3f4338548ec2
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jun 25 06:04:14 2019 -0700
+
+    [range.filter.sentinel] Correct typo in constructor Effects (#2937)
+
+commit 97b615a5a6ab0598b624ee05402c531d0421cff6
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jun 25 06:09:55 2019 -0700
+
+    [iterator.synopsis] Copy constraint for iterator_traits<T*> from [iterator.traits]/5 (#2943)
+
+commit da7eac5e621b5fab12c0b1992100c4bfd983ed8e
+Author: Saar Raz <saar@raz.email>
+Date:   Mon Jul 1 22:46:37 2019 +0300
+
+    [Concepts] Remove qualified-concept-name reference
+
+    Update 'qualified-concept-name' (the previous incarnation of 'type-constraint') reference to 'type-constraint' in [temp.over.link]p6.
+
+commit f54f306c3b9fad27e70766963840e3df14f20b28
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jul 4 15:34:38 2019 +0200
+
+    [func.bind] Remove bogus 'shall's. (#2955)
+
+commit 72cc844ef44ae47aebb1ad346146138d3279be9e
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Jul 5 16:16:58 2019 +0200
+
+    [expr.reinterpret.cast] Properly capitalize full-sentence bullets. (#2956)
+
+commit c635711cdd81346ad41c7861adb8035176fa236f
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Jul 5 23:55:22 2019 +0200
+
+    [temp.constr.constr] Add missing period at end of sentence. (#2957)
+
+commit 4f9942cafadc17fb902610b4c67afb6fcf81ff64
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jul 7 19:38:20 2019 +0200
+
+    [dcl.asm] Rename grammar term 'asm-definition' to 'asm-declaration'
+
+commit 51c5b01217799fdfa754179c20af888ec8c1889d
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Jul 10 00:40:19 2019 -0700
+
+    [temp.constr.order] Remove extraneous "the". (#2964)
+
+commit 67db9422b6bc58f5399c7c019ec5ede28d8ac4f5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 28 17:01:54 2019 +0200
+
+    [expr.prim.req] Fix cross-reference for substituting into constraints.
+
+commit 98c2c56ab5e945452586270d72d2fb606b71cd94
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 22 02:24:42 2019 +0200
+
+    [class.prop] [special] Move definition of eligible special member
+    functions to the section on special member functions.
+
+commit 94a72b5c11a20cfd6c92a4faa5bd0df4b8ebc620
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 22 02:28:15 2019 +0200
+
+    [class.dtor] Reorder the introduction of an implicit prospective
+    destructor to before we describe the overload resolution to pick the
+    actual destructor.
+
+commit 6bd3daeae3a3e9ae6174c35ab020dbfe4504b75b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Aug 1 20:04:36 2019 -0700
+
+    [class.ctor], [class.dtor] Introduce actual definitions for
+    "constructor" and "prospective destructor".
+
+commit dc45e8c329eeb0076d074fa671c2be2fc605555a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 22 03:18:33 2019 +0200
+
+    [class.spaceship] Remove incorrect note.
+
+commit d6a291776858bc647fc6826888767284f305c799
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 22 03:58:34 2019 +0200
+
+    [dcl.attr.nodiscard] Simplify note describing the string-literal in a
+    nodiscard attribute and make it less confusing.
+
+commit 46ba985402de963f50d364b26b594707be16c7c9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 22 04:42:43 2019 +0200
+
+    [dcl.enum] Avoid hanging paragraphs by moving "Enumeration declarations"
+    down one level to a sibling of "The using enum declaration".
+
+    [namespace.udir] Rename section to "Using namespace directive" to
+    further distinguish this from a using enum declaration.
+
+commit 5d1bb1c7f8ed44016c38bfeb9797e363d52cfc51
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Aug 1 20:42:13 2019 -0700
+
+    [over.match.oper] Replace "member, non-member, and built-in candidates"
+    with "non-rewritten candidates"
+
+    This simplifies the wording, implicitly explains why we're considering
+    only some candidates, and avoids overtly suggesting that we could ever
+    pick a reversed-parameter-order built-in candidate.
+
+commit 1fbc1c315008152770eea8bd383aa2a4fa47cfd5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jul 26 16:56:13 2019 +0200
+
+    [basic.def.odr] Turn long comma-separate list into bullets.
+
+commit c0c589881759871b2183105f315d4ddd0d2734be
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 1 22:47:19 2019 +0200
+
+    [expr.const.cast] Clarify pairwise correspondence for P_i.
+    [over.ics.rank] Move cross-reference pointing to [conv.qual].
+
+commit 47539b965a84f69c548fe043a632af17db3cb315
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Aug 2 15:49:39 2019 -0700
+
+    [conv.qual] Move note after the rule that implies it.
+
+commit f10e3751b39138746b601fa702c9ed9e67777c96
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Aug 2 15:59:50 2019 -0700
+
+    [over.ics.rank] Reorder examples to match order of normative text.
+
+commit 813a4300a036f12d5ff6b82965b83a8e87b1ae8d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Aug 2 16:55:56 2019 -0700
+
+    [dcl.attr.nodiscard] Fix vexing-parse bug in example. Make sure the
+    missiles actually get launched, not merely redeclared.
+
+commit 6e845457bfd83f20c2f61bf4015afcd96cbd0cec
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Aug 2 17:17:52 2019 -0700
+
+    [over.match.class.deduct] Fix failure to handle the case where a
+    deducible alias template's defining-type-id contains a
+    nested-name-specifier (or 'typename' or 'template' keywords).
+
+commit 7226ced32fe3cda28eb05f044985427684397128
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Aug 2 17:26:53 2019 -0700
+
+    [over.match.class.deduct] Switch from imperative to passive, and clarify
+    what happens if the various 'if' conditions are not met.
+
+commit 6552c03d3793e7532793097d760edc3a93e150b1
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Aug 2 17:32:40 2019 -0700
+
+    [over.match.class.deduct] Put all bullets describing the properties of
+    f' at the same depth, and guard them all by the condition that we're
+    actually adding an f' to the set of guides.
+
+commit b3b7d37c073051826c21c231bd386c10d64433dc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Aug 2 22:09:14 2019 +0200
+
+    [class.copy.elision] Add cross-reference, fix example.
+
+commit 4a657ca3e26850a993c2015bbecd6287e817a615
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 3 18:51:09 2019 -0700
+
+    [iterator.concept.sizedsentinel], [range.sized], [range.view]
+    Provide proper descriptions for disable_sized_sentinel,
+    disable_sized_range, and enable_view.
+
+commit 796c871f9b14a42fea634ec97a35032bfe3c422a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 23 09:57:04 2019 +0200
+
+    [bit] Avoid std::numeric_limits<...>
+
+    Referring to numeric_limits (without std:: prefix) is sufficient.
+
+commit fb97956bc9eee5a50c10df9148d9422e260e352c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jul 31 17:28:28 2019 -0700
+
+    [format.formatter] Add subclause heading to avoid hanging paragraphs.
+
+commit eae84a0a10b4409da01ae5c9e7c734e113973cdf
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jul 31 17:34:37 2019 -0700
+
+    [format.string] Clarify that "other characters" means "characters other
+    than { and }".
+
+commit b62dc39c0541a1968ac1717773574f4ef868934c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jul 31 18:05:00 2019 -0700
+
+    [format.string] Change 'integer' grammar to be left-recursive and factor
+    out separate positive-integer and nonnegative-integer productions for
+    clarity.
+
+commit 2db4bd64f7f157266ae0f7c7c44c4fe7c68c6070
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jul 31 18:14:56 2019 -0700
+
+    [format.string] Fix wording that talks about omitting arg-ids but
+    presupposes that they are all present to instead specify what happens
+    when some or all are absent.
+
+commit 5a32fd1040b8a7c4c997ba8841c4f28a34a6c97d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jul 31 18:26:41 2019 -0700
+
+    [format.string] Add missing grammar definition for custom-format-spec
+    rather than leaving it dangling.
+
+commit d529b96f3be22332d4a88de646f56cb636680f6c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jul 31 18:33:05 2019 -0700
+
+    [format.string] Make tone of wording more formal and less tutorialesque.
+
+commit 3ced91d524f3c2a850243863440151735276b38a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Jul 31 18:41:56 2019 -0700
+
+    [format.context] Add specification of wformat_context analogous to that
+    of format_context, as discussed on lib reflector.
+
+commit ed00761315546c11b48441e1bcef6aa5927f76c8
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Aug 1 18:17:10 2019 -0700
+
+    [format.string] Explicitly list all the possible formatting types for
+    bool and charT in their respective tables rather than requiring the
+    reader to infer how to merge the integer table into the bool and charT
+    tables.
+
+commit 46622695da52f8080f7280207eecd93bd950cc1a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 3 19:57:13 2019 -0700
+
+    [format.functions] Use clamp rather than min(max(a,b),c)
+
+    Co-Authored-By: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+
+commit a870403a2dc47924e7f607f7c69694291d43007c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 3 20:39:06 2019 -0700
+
+    [format.arg] Don't use placeholder name for private member char-type.
+
+commit d17fd4d5f10f6af87654fdc73bd6417313a295f2
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Aug 4 14:04:04 2019 -0700
+
+    [format.string] Avoid duplicating the specification of '#' for integers.
+
+    Fix the specification for '#' being different for octal integers in the
+    two places it's specified.
+
+commit e30b8a69d485b96ddacfa31b7eb411c5a64d83a5
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Aug 4 14:23:48 2019 -0700
+
+    [format.string] Separate out the general (type-independent) description
+    of formatting from the format specifiers for arithmetic and string
+    types, and make the presentation of the latter consistent with the
+    presentation for chrono types.
+
+commit f430bec8e7a4437b69d1ad31b2c1f4246e753770
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Aug 4 15:09:26 2019 -0700
+
+    [format.string.std] Convert normative duplication to a note to avoid
+    creating the impression that alignment is only applied to non-string
+    types.
+
+commit b6454e39ede7ab11ce0958fa2ee3b487c8983ae1
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Aug 4 15:32:02 2019 -0700
+
+    [format.string] Further clarify description of cases where formatting is
+    described in terms of a call to to_chars.
+
+commit 895f30bd225d050bcb2ab9f0a793af9865dcd513
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Aug 4 20:02:33 2019 -0700
+
+    [format.formatter] Reorder Formatter requirements before the
+    descriptions of specializations that meet those requirements.
+
+commit c7ada4d28ae7be82ef64104617e216fd738a4d0f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 30 16:07:16 2019 +0200
+
+    [numbers] Use 'template<class T>', not 'typename'.
+
+commit 14aa4ed0d323c163f0559bd7c8555d77f2dc8093
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 30 16:12:59 2019 +0200
+
+    [math.constants] Expand 'math' to 'mathematical'.
+
+commit 3f761c76b5daf9f1a75695226514c323ba6619f0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 1 10:50:09 2019 +0200
+
+    [numbers.syn] Use 'namespace std::numbers'.
+
+commit dc61857d3779253c6cdeec572cdcb43077b0ce86
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Aug 4 20:51:47 2019 -0700
+
+    [atomics.lockfree] "are" -> "is"; "along with" is not a coordinating
+    conjunction.
+
+commit 3d3f16f99454d3ffffcfbf92a02b9bcaac9b375b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Aug 4 21:50:27 2019 -0700
+
+    [thread.barrier.class] Rename constructor parameter from `phase_count`
+    to `expected`.
+
+    The parameter is not a phase count, and is referred to by other
+    normative wording as `expected`; also, `expected` is the name we use for
+    the same parameter in the constructor of `latch`.
+
+commit 2e82327045fb92d89dd1431cc7e771da63c982dc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 1 10:37:25 2019 +0200
+
+    [time.hms.members] Rephrased note.
+    [time.hms.overview] Removed redundant declaration of operator<<.
+    [time.hms.overview] Moved exposition-only data members to the bottom.
+
+commit 1a37c22bb6b621f14d01b4e16378c9cd08724183
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sun Aug 4 23:36:25 2019 -0700
+
+    [time.hms.nonmembers] Finish rebase on std::format: rewrite hh_mm_ss
+    operator<< in terms of format rather than using (removed) old formatting
+    terminology.
+
+commit 584a87ec1d48862b9e68a269d0a5eb7b05d6999d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Aug 5 13:57:50 2019 -0700
+
+    [time.hms.nonmembers] Fix editorial error in hh_mm_ss operator<< (only
+    stream to 'os' once). This formulation was proposed by Howard Hinnant
+    on the lib reflector.
+
+commit d243672db3269754d4ee91a5fbcdfb82ae6f2539
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 30 16:01:10 2019 +0200
+
+    Apply P1452R2 On the non-uniform semantics of return-type-requirements
+    to newly-introduced return type requirements.
+
+commit 90f64792ec7d5372a093d3bea69dffff2f7af28a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Aug 5 13:48:59 2019 -0700
+
+    Rename _s to -s in placeholder names per editorial guidelines.
+
+commit ad685c42b18103ace094b375a4fde1a7ec6aba02
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Tue Jul 30 19:33:10 2019 -0700
+
+    [stringbuf] Name string parameters "s" instead of "str" for consistency and to avoid confusion with "str" methods.
+
+commit 26f7cd6d3b2d271c74e1d2022f972f833de940f6
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Thu Aug 1 13:35:42 2019 -0700
+
+    [stringbuf.members] Minor fixes to P0408R7 wording.
+
+    "str()" should be "str"; we're talking about all str member functions here.
+    Add comma after "For efficiency reasons".
+    "i.e." -> "e.g." since we're describing an example case.
+
+commit b4a8b798e00bce697af9b477a214828b69e9e383
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Aug 5 17:31:21 2019 -0700
+
+    [module.unit] Add "either" to clarify that we're talking about
+    module-names containing a reserved identifier, not module names starting
+    with an identifier that contains a reserved identifier.
+
+commit 906fd4d0519994e06659ce066c8252df186c23b9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Aug 5 17:57:35 2019 -0700
+
+    [func.require] Convert restrictive 'which' to 'that'.
+
+commit 7e862f0f238257b2cbb1f7296a593b4587029e39
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Aug 5 18:46:55 2019 -0700
+
+    [range.transform.sentinel] Reinstate transform_view::sentinel::operator-
+    overloads, accidentally removed during application of P1614R2.
+
+commit e02aa79ca43de3fdf6e1887d4fd02bc58874e190
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 31 22:55:50 2019 +0200
+
+    [range.istream.view] Do not repeat declaration of function istream_view
+    [range.elements.iterator] Renamed from [range.elements_view.iterator]
+    [range.elements.iterator] Use local typedef difference_type
+    [range.elements.iterator] Use reference return type for compound assignment
+
+commit a0b5a70fade22203ebfbaeb4828e0c304b1f62ab
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Aug 5 23:02:38 2019 -0700
+
+    [ranges] Fix 'constexpr friend' to our preferred order 'friend constexpr'.
+
+commit f0256ab73cd6a9fae611af95526d16fe59968d4c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Aug 5 23:08:59 2019 -0700
+
+    [range.drop.view] Fix typo "requirement" -> "required".
+
+commit 7698c3dc28251540b4a4733cc4a6b3f6942f13ed
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Aug 6 00:40:47 2019 -0700
+
+    [range.iota.view] Rename IOTA_DIFF_T to the preferred IOTA-DIFF-T.
+
+commit cf1bc270c0e7d7b1670502c69268b0373bbf9799
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Aug 6 01:35:47 2019 -0700
+
+    [thread] Update headings, comments, and line wrapping to match editorial
+    conventions.
+
+commit 7f4e95e3296b31c23bfb358f31294d384a955e3b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Aug 3 08:38:34 2019 +0200
+
+    [support.srcloc] Fix comments in example.
+
+commit 06ab7ebef8a763e36f87f504ed7765528aa25fc7
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Aug 6 02:28:42 2019 -0700
+
+    [support.srcloc.cons] Use term "default member initialier" rather than
+    describing it indirectly.
+
+commit 7beed51f4388074f46fd55a7c5f559cd82b7c40c
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Tue Jul 30 20:36:34 2019 -0700
+
+    [alg.is.permutation] Add parameters to \libconcept{sized_sentinel_for} as suggested in PR #3099.
+
+commit fbb0691134e39059adaa4a886e7d746b0e56c81c
+Author: Dawn Perchik <dperchik@embarcadero.com>
+Date:   Wed Jul 31 12:52:26 2019 -0700
+
+    [concepts] Renamed concepts' section names to remove trailing prepositions for consistency.
+
+    * concept.convertibleto => concept.convertible
+    * concept.derivedfrom => concept.derived
+    * concept.stricttotallyordered => concept.totallyordered
+
+commit e2a070f7a5484e272c10e4ab31359fede5ff24a1
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Aug 6 13:51:24 2019 -0700
+
+    [diff.cpp17.library], [tab:headers.cpp] Add missing <coroutine> entry
+    to the list of headers, and add various missing entries to the list of
+    new-in-C++20 headers.
+
+    Fixes #3122.
+
+commit 54a87d7849e7d5283c2d0a34f8200ef6a67bb0da
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Aug 6 23:17:24 2019 +0200
+
+    [conv.qual,expr.static.cast] Harmonize notes on cv-qualified function types.
+
+commit ee234abfbfa7deb5c585b67590205e1660df180f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 1 16:45:51 2019 +0200
+
+    [time.clock,bit.cast] Replace template<typename...> with template<class...>
+
+    as per library specification policy.
+
+commit a374c4f3664cf84a4440feb3c236076b25cfe736
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Thu Jul 25 21:24:06 2019 +0200
+
+    [tuple] Use "objects" instead of "variables"
+    with "temporary" in the definition of `forward_as_tuple`
+
+commit 7e02aa3d7d3e5e9dfc2c66451e112d40f4491465
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jul 22 23:27:57 2019 +0100
+
+    [is.sorted] Add missing "return" and semi-colon
+
+    This was lost when changing "Returns:" to "Effects:" for P0896R4. The
+    paper included this change, but it was lost when applying it.
+
+commit cc421307fb4ce393e7ab1dcf0d0f1298d163fbe0
+Author: Yehezkel Bernat <yehezkelshb@gmail.com>
+Date:   Sun Jul 21 22:16:23 2019 +0300
+
+    Delete irrelevant copy-paste from previous section
+
+commit d4c4cc0ac037c51ec10cf6f7c80d8c761b517cba
+Author: onihusube <44743040+onihusube@users.noreply.github.com>
+Date:   Wed Jul 17 22:46:24 2019 +0900
+
+    [basic.lookup.argdep]/5 add export to apply()
+
+    fix #2968
+
+commit 557cfa9dd706780fb672bfe9e5e2f0ef3b2f3d4a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jul 4 09:31:57 2019 +0200
+
+    [basic.life] Lifetime of class objects is treated uniformly
+    under CWG2256, regardless of triviality of the destructor.
+
+commit 4c3b9f50ecd230263974c81e1df2fb07b541c58d
+Author: onihusube <44743040+onihusube@users.noreply.github.com>
+Date:   Mon Jul 1 16:26:16 2019 +0900
+
+    [module.global] fix sample code comment
+
+commit 06bd4b02febcb43c014ffd46b7a07dab8d66aa4b
+Author: onihusube <44743040+onihusube@users.noreply.github.com>
+Date:   Mon Jul 1 16:41:33 2019 +0900
+
+    [cpp.module] fix sample code comment
+
+commit 1be069efaa41f4df376364290f8069ec030b13cc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 28 17:11:44 2019 +0200
+
+    [time.parse] Fix description of %Ex and %EX parse flags.
+
+    Also refer to the table number instead of 'the table below'.
+
+commit f038d86fb9112b62adaaebaf95dc70d786412cbd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 28 16:50:03 2019 +0200
+
+    [res.on.functions] Properly capitalize full-sentence bullets.
+
+    Also add periods at the end of sentences.
+
+commit 43945886b4ff4481da3d29b3f624d55bc9b5d124
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jun 24 22:43:30 2019 +0200
+
+    [conv.qual] Fix example for cv-decomposition.
+
+    After CWG2051, a cv-decomposition can also be a no-op.
+
+commit 915031ddbf75f856efcea43928d9f459140834fd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Aug 6 09:31:52 2019 +0200
+
+    [meta.trans.other] Use hyphens, not underscores, for meta-functions.
+
+commit be443affbf06bfb14c2295311ed469896ae39d6c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Aug 7 17:59:27 2019 -0700
+
+    [range.drop.while.overview] Add missing space in example.
+
+commit 1e09011ff3627db60ae10fa8fee2e2f5ef7dc5c9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 18:13:55 2019 -0700
+
+    [format.string.general] indexes -> indices
+
+commit 71251ae592a49149faec1389ec85f22322aa0ba5
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 18:23:43 2019 -0700
+
+    [format.string.std] Fix space collapse in example. Use commas rather
+    than spaces to separate fields to more clearly show where whitespace is
+    introduced by a field rather than between fields.
+
+commit ee719cb98574ade2c113a17a16e6af247913456b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 18:30:01 2019 -0700
+
+    [tab:format.type.float] Add "equivalent to" to remaining calls to
+    to_chars for consistency.
+
+commit add4ff3339153382b0e59d45e6bfeee4f923060a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 18:35:05 2019 -0700
+
+    [time.format] Fix some minor issues (comma rather than period, moving a
+    "Let" sentence out of a Remarks clause to a separate paragraph, using
+    'class' rather than 'typename').
+
+commit d4b47a09e9089bc661c4ad6bb882a46f4aae92b6
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 18:38:26 2019 -0700
+
+    [time.syn] Fix specifier order in declarations to match library style.
+    Rename parameter 't' to 'hms' to make declaration and later description
+    match.
+
+commit 550553189899e1687629827dbb3fbf9c401f5d96
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 18:40:49 2019 -0700
+
+    [range.istream.iterator] Fix 'parent_' to the obviously-intended 'parent'.
+
+commit 791a19a1d206c77b97e7725aa9a8ea779bf94d7a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 19:08:16 2019 -0700
+
+    [chrono], [iostreams], [support] Fix 'template <' and 'typename T' to
+    the conventional 'template<' and 'class T' throughout the library.
+
+commit ac72157b97d4b7b85ddb7ca412b5a4ee1806614d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 19:11:57 2019 -0700
+
+    [cmp.object] Add missing template-head to function description.
+
+commit b050fd474f11441942c88ef69b8622c8036656ac
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 19:26:09 2019 -0700
+
+    [re.submatch.op] Fix inconsistency between declaration and description
+    of sub_match operator<=>: remove 'constexpr' from declaration, and
+    change return type in definition from 'bool' to 'auto'.
+
+commit 1335e42809151ecfdb671ea2aea1dab0c8d5db53
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 19:33:48 2019 -0700
+
+    [iterator.concept.sizedsentinel] Avoid potential ambiguity between
+    inclusive and exclusive "or" by using "and/or".
+
+commit 1b2bfda98c20ecd71a35b7321662f8f976134793
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 19:51:39 2019 -0700
+
+    [atomic] Remove invalid trailing 'const' from non-member function
+    atomic_flag_notify_all.
+
+commit afed449f0fa1324001260c9d658f6d05da90a9f9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 19:55:21 2019 -0700
+
+    [thread.sema.cnt] "Class" -> "Class template" in description of a class
+    template.
+
+commit 7445919de1bcf4780693b7870a245486839587ea
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 19:58:05 2019 -0700
+
+    [thread.latch] Remove italics from non-definition of "latch".
+
+commit 224384ab43e4e9829eee5d97f09218850026d342
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Sat Aug 10 20:05:07 2019 -0700
+
+    [atomic] Consistently order atomic<...> and atomic_ref<...> definitions:
+    keep compare_exchange and fetch_* operations together because the latter
+    are a particular form of compare_exchange operation.
+
+commit 8644a2ce2faa6e979e224f069e4ca48238ea8570
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Aug 12 16:47:06 2019 -0700
+
+    [atomics.syn], [atomics.flag] Clean up presentation around
+    ATOMIC_FLAG_INIT.
+
+     * Add some vertical whitespace in description of atomic_flag operations.
+     * Reorder ATOMIC_FLAG_INIT earlier in synopsis for consistency.
+     * Add proper item description for ATOMIC_FLAG_INIT.
+     * Remove repetition of declarations of atomic_flag non-member functions
+       and the ATOMIC_FLAG_INIT macro from [atomics.flag].
+
+commit 2c1ab9775cc53e848a1efff4f9976455538994d4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Aug 12 16:56:24 2019 -0700
+
+    [string.erasure] Following the guidance given by P0980R1, and after
+    consultation with LWG chair, mark the std::erase and std::erase_if
+    overloads for std::basic_string as constexpr in addition to those
+    explicitly called out by the wording paper.
+
+commit 009d46f9b057a635383dce8bbcad121c86f1d306
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Aug 13 18:16:48 2019 -0700
+
+    [over.match.class.deduct] Replace "therefrom" with a more common
+    construction, and more directly talk about the class template for which
+    we are ultimately performing deduction.
+
+commit ac9189f351bf0407a31968199c22274ff41fe9e7
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Aug 13 18:21:14 2019 -0700
+
+    [diff.cpp17.class] Remove redundant cross-reference.
+
+commit ba642aa699973f21613cbe3e6a0b6d9c1e0f2e6a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Aug 14 16:16:48 2019 -0700
+
+    [ostream] Add back the comments that P1423R3 requested, but now as a
+    note.
+
+commit 37ccff2c0e9be3a62fcd85b55e4d05c2b312335f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Aug 14 16:48:00 2019 -0700
+
+    [dcl.fct.def.default] Clarify that the rule concerning how the type of a
+    defaulted function can differ from the type of an implicitly-declared
+    function only applies to the functions that are implicitly declared.
+
+commit 42ee105f5804a74bb15960944ee7fe1cd4420e04
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Aug 14 16:56:23 2019 -0700
+
+    [over.match.class.deduct] Clarify that an incomplete class type is never
+    treated as being an aggregate.
+
+commit fce4ac9764e10042bd8d0bb4152e83d697c8bdae
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Aug 14 17:02:06 2019 -0700
+
+    [dcl.typedef] Split paragraph on typedef name for linkage into two parts
+    (how you know when you have one, and the restrictions on types that have
+    one).
+
+commit 90a29c08bc80091c093937a7d96ce28df5ceee44
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Aug 14 17:21:15 2019 -0700
+
+    [conv.qual] Avoid bouncing back and forth between subscripts and regular
+    scripts for T1 and T2, and add missing definition for cv^j_i and P^j_i.
+
+commit 03bcd8d3e5ece969af846e23cd451549185fdac4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 8 01:07:54 2019 +0200
+
+    [expr.ass] Remove mention of class types.
+
+commit 173905005c2c419548418239518db72bfda9dd9a
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Aug 14 17:48:53 2019 -0700
+
+    [dcl.attr.nodiscard] Make the constructor case better parallel the
+    function case by duplicating the implied "through a reachable
+    declaration" wording.
+
+commit acbe5e429499d0eaf6c118f0bca4bbc26830bcaf
+Author: Davis Herring <herring@lanl.gov>
+Date:   Mon Aug 12 12:07:06 2019 -0600
+
+    [dcl.attr.nodiscard], [diff.cpp17.dcl.dcl] Fix grammar/usage
+
+commit 5aa019b19118973d99a2b2282d3f6264da81c9d8
+Author: Davis Herring <herring@lanl.gov>
+Date:   Mon Aug 12 12:13:20 2019 -0600
+
+    [basic.def.odr] Clean up new bullets
+
+commit eb443396ac48b4e2ac9c6be0d9ec6bf9dda107eb
+Author: Davis Herring <herring@lanl.gov>
+Date:   Mon Aug 12 12:27:41 2019 -0600
+
+    [module.reach], [over.ics.rank] Fix punctuation
+
+commit 37d2e59e8deb847f5ebdade20604bdf5c119649a
+Author: Davis Herring <herring@lanl.gov>
+Date:   Mon Aug 12 14:14:50 2019 -0600
+
+    [expr.ass] Improve preposition
+
+commit 4a0fd9aa43a0d63d6fe875b886cdea8ec24d7f9d
+Author: Davis Herring <herring@lanl.gov>
+Date:   Mon Aug 12 15:03:56 2019 -0600
+
+    [over.match.class.deduct] Supply missing word
+
+commit 05c786cc68bf14a828cc59f32d34fae2baf33794
+Author: Davis Herring <herring@lanl.gov>
+Date:   Tue Aug 13 00:49:41 2019 -0600
+
+    [expr.new] Use typical \iref
+
+commit fc1863291a3f62a684d9bffa51fdc2837e9edcd0
+Author: Davis Herring <herring@lanl.gov>
+Date:   Tue Aug 13 14:55:54 2019 -0600
+
+    [class.spaceship] Remove vacuous conversion
+
+    The synthesized three-way comparison always produces a value of type R
+
+commit 80f2c46251f07abf422cdd86a3f3d30c47fda587
+Author: Davis Herring <herring@lanl.gov>
+Date:   Tue Aug 13 14:59:46 2019 -0600
+
+    [over.match.class.deduct] Fix terminology
+
+    An element with a dependent type might not be a subaggregate
+    Add cross-reference
+
+commit bfa0e698359d44e8a2b0a056e13e908a8185e296
+Author: Davis Herring <herring@lanl.gov>
+Date:   Tue Aug 13 15:02:06 2019 -0600
+
+    [over.match.class.deduct] Use "deduces"
+
+    ...for consistency in example
+
+commit 174edca593a860440860f95c3ee61aa739e2afdc
+Author: Davis Herring <herring@lanl.gov>
+Date:   Tue Aug 13 23:41:02 2019 -0600
+
+    [over.match.class.deduct] Simplify example
+
+commit a9f901af95f16540444144a397fe3b598ae2961b
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Wed Aug 14 17:51:44 2019 -0700
+
+    [class.dtor] "The defaulted destructor" -> "A defaulted destructor",
+    since the destructor for a class might not be defaulted.
+
diff --git a/papers/n4829.md b/papers/n4829.md new file mode 100644 index 0000000000..0fee37aa7b --- /dev/null +++ b/papers/n4829.md @@ -0,0 +1,1137 @@ +# N4829 Editors' Report -- Programming Languages -- C++ + +2019-08-15 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Special thanks to several paper authors +for supplying the LaTeX sources for their papers. + +Special thanks also to the Editing Committee -- +Daniel Krügler, Davis Herring, Nina Ranns, and Ville Voutilainen -- +for providing a careful review of the application of these motions +and the editorial changes described below +to ensure the correctness of the C++20 Committee Draft. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4830](http://wg21.link/n4830) is the committee draft for C++20. It replaces [N4820](http://wg21.link/n4820). + * N4829 is this Editors' Report. + +**Note**: +A working draft was circulated to the editing committee for review, +and was mistakenly published with paper number N4828. +N4828 is not the C++20 Committee Draft, +and does not contain the results of addressing feedback from +the editing committee. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p1510r0) for 10 issues in "tentatively ready" status applied: **(DR)** + + * [682](http://wg21.link/cwg682) Missing description of lookup of template aliases + * [2207](http://wg21.link/cwg2207) Alignment of allocation function return value + * [2300](http://wg21.link/cwg2300) Lambdas in multiple definitions + * [2366](http://wg21.link/cwg2366) Can default initialization be constant initialization? + * [2376](http://wg21.link/cwg2376) Class template argument deduction with array declarator + * [2390](http://wg21.link/cwg2390) Is the argument of `__has_cpp_attribute` macro-expanded? + * [2400](http://wg21.link/cwg2400) Constexpr virtual functions and temporary objects + * [2404](http://wg21.link/cwg2404) `[[no_unique_address]]` and allocation order + * [2406](http://wg21.link/cwg2406) `[[fallthrough]]` attribute and iteration statements + * [2418](http://wg21.link/cwg2418) Missing cases in definition of "usable in constant expressions" + +CWG motion 2: [P1161R3 "Deprecate uses of the comma operator in subscripting expressions"](http://wg21.link/p1161r3) + +CWG motion 3: [P1331R2 "Permitting trivial default initialization in constexpr contexts"](http://wg21.link/p1331r2) + +CWG motion 4: [P0735R1 "Interaction of `memory_order_consume` with release sequences"](http://wg21.link/p0735r1) + +CWG motion 5: [P0848R3 "Conditionally trivial special member functions"](http://wg21.link/p0848r3) + +CWG motion 6: [P1186R3 "When do you actually use `<=>`?"](http://wg21.link/p1186r3) + +CWG motion 7: [P1301R4 "`[[nodiscard("should have a reason")]]`"](http://wg21.link/p1301r4) + +CWG motion 8: [P1099R5 "`using enum`"](http://wg21.link/p1099r5) + +CWG motion 9: [P1630R1 "Spaceship needs a tune-up"](http://wg21.link/p1630r1) + +CWG motion 10: [P1616R1 "Using unconstrained template template parameters with constrained templates"](http://wg21.link/p1616r1) + +CWG motion 11: [P1816R0 "Class template argument deduction for aggregates"](http://wg21.link/p1816r0) + +CWG motion 12: [P1668R1 "Enabling `constexpr` intrinsics by permitting unevaluated inline assembly in `constexpr` functions"](http://wg21.link/p1668r1) + +CWG motion 13: [P1766R1 "Mitigating minor modules maladies"](http://wg21.link/p1766r1) **(DR)** + +CWG motion 14: [P1811R0 "Relaxing redefinition restrictions for re-exportation robustness"](http://wg21.link/p1811r0) + +CWG motion 15: [P0388R4 "Permit conversions to arrays of unknown bound"](http://wg21.link/p0388r4) + +CWG motion 16: [P1823R0 "Remove contracts"](http://wg21.link/p1823r0) + +CWG motion 17: [P1143R2 "Adding the `constinit` keyword"](http://wg21.link/p1143r2) + +CWG motion 18: [P1452R2 "On the non-uniform semantics of *return-type-requirement*s"](http://wg21.link/p1452r2) + +CWG motion 19: [P1152R4 "Deprecating `volatile`"](http://wg21.link/p1152r4) + +CWG motion 20: [P1771R1 "`[[nodiscard]]` for constructors"](http://wg21.link/p1771r1) **(DR)** + +CWG motion 21: [P1814R0 "Class template argument deduction for alias templates"](http://wg21.link/p1814r0) + +CWG motion 22 was withdrawn + +CWG motion 23: [P1825R0 "Merged wording for P0527R1 and P1155R3"](http://wg21.link/p1825r0) **(DR)** + + * [P0527R1 "Implicitly move from rvalue references in return statements"](http://wg21.link/p0527r1) + * [P1155R3 "More implicit moves"](http://wg21.link/p1155r3) + +CWG motion 24: [P1703R1 "Recognizing header unit imports requires full preprocessing"](http://wg21.link/p1703r1) + +CWG motion 25: [P0784R7 "More `constexpr` containers"](http://wg21.link/p0784r7) + +### Library working group motions + +LWG motion 1: [Library issue resolutions](http://wg21.link/p1724r0) for 17 issues in "Ready" and "Tentatively Ready" status applied: **(DR)** + + * [3209](http://wg21.link/lwg3209) Expression in `year::ok()` returns clause is ill-formed + * [3208](http://wg21.link/lwg3208) `Boolean`'s expression requirements are ordered inconsistently + * [3206](http://wg21.link/lwg3206) `year_month_day` conversion to `sys_days` uses not-existing member function + * [3202](http://wg21.link/lwg3202) [P0318R1](http://wg21.link/p0318r1) was supposed to be revised + * [3199](http://wg21.link/lwg3199) `istream >> bitset<0>` fails + * [3198](http://wg21.link/lwg3198) Bad constraint on `std::span::span()` + * [3196](http://wg21.link/lwg3196) `std::optional` is ill-formed if `T` is an array + * [3191](http://wg21.link/lwg3191) `std::ranges::shuffle` synopsis does not match algorithm definition + * [3187](http://wg21.link/lwg3187) [P0591R4](http://wg21.link/p0591r4) reverted [DR 2586](http://wg21.link/lwg2586) fixes to `scoped_allocator_adaptor::construct()` + * [3186](http://wg21.link/lwg3186) Ranges `remove`, `partition`, and `partial_sort_copy` algorithms discard useful information + * [3185](http://wg21.link/lwg3185) Uses-allocator construction functions missing `constexpr` and `noexcept` + * [3184](http://wg21.link/lwg3184) Inconsistencies in `bind_front` wording + * [3183](http://wg21.link/lwg3183) Normative permission to specialize ranges variable templates + * [3169](http://wg21.link/lwg3169) Ranges permutation generators discard useful information + * [3158](http://wg21.link/lwg3158) `tuple(allocator_arg_t, const Alloc&)` should be conditionally explicit + * [3055](http://wg21.link/lwg3055) `path::operator+=(`single-character`)` misspecified + * [2899](http://wg21.link/lwg2899) `is_(nothrow_)move_constructible` and `tuple`, `optional` and `unique_ptr` + +LWG motion 2: [P1355R2 "Exposing a narrow contract for `ceil2`"](http://wg21.link/p1355r2) + +LWG motion 3: [P0553R4 "Bit operations"](http://wg21.link/p0553r4) + +LWG motion 4: [P1424R1 "`constexpr` feature macro concerns"](http://wg21.link/p1424r1) + +LWG motion 5: [P0645R10 "Text formatting"](http://wg21.link/p0645r10) + +LWG motion 6: [P1361R2 "Integration of chrono with text formatting"](http://wg21.link/p1361r2) + +LWG motion 7: [P1652R1 "Printf corner cases in `std::format`"](http://wg21.link/p1652r1) + +LWG motion 8: [P0631R8 "Math constants"](http://wg21.link/p0631r8) + +LWG motion 9: Synchronization library: + + * [P1135R6 "The C++20 synchronization library"](http://wg21.link/p1135r6) + * [P1643R1 "Add wait/notify to `atomic_ref`"](http://wg21.link/p1643r1) + * [P1644R0 "Add wait/notify to `atomic`"](http://wg21.link/p1644r0) + +LWG motion 10: [P1466R3 "Miscellaneous minor fixes for chrono"](http://wg21.link/p1466r3) + +LWG motion 11: [P1754R1 "Rename concepts to `standard_case` for C++20, while we still can"](http://wg21.link/p1754r1) + +LWG motion 12: [P1614R2 "The mothership has landed"](http://wg21.link/p1614r2) + +LWG motion 13: [P0325R4 "`to_array` from LFTS with updates"](http://wg21.link/p0325r4) + +LWG motion 14: [P0408R7 "Efficient access to `basic_stringbuf`'s buffer"](http://wg21.link/p0408r7) + +LWG motion 15: [P1423R3 "`char8_t` backward compatibility remediation"](http://wg21.link/p1423r3) + +LWG motion 16: [P1502R1 "Standard library header units"](http://wg21.link/p1502r1) + +LWG motion 17: [P1612R1 "Relocate `endian`'s specification"](http://wg21.link/p1612r1) + +LWG motion 18: [P1661R1 "Remove dedicated precalculated hash lookup interface"](http://wg21.link/p1661r1) + +LWG motion 19: [P1650R0 "Output `std::chrono::days` with `d` suffix"](http://wg21.link/p1650r0) + +LWG motion 20: [P1651R0 "`bind_front` should not unwrap `reference_wrapper`"](http://wg21.link/p1651r0) + +LWG motion 21: [P1065R2 "Constexpr `invoke`"](http://wg21.link/p1065r2) + +LWG motion 22: [P1207R4 "Movability of single-pass iterators"](http://wg21.link/p1207r4) + +LWG motion 23: [P1035R7 "Input range adaptors"](http://wg21.link/p1035r7) + +LWG motion 24: [P1638R1 "`basic_istream_view::iterator` should not be copyable"](http://wg21.link/p1638r1) + +LWG motion 25: [P1522R1 "Iterator difference type and integer overflow"](http://wg21.link/p1522r1) + +LWG motion 26: [P1004R2 "Making `std::vector` constexpr"](http://wg21.link/p1004r2) + +LWG motion 27: [P0980R1 "Making `std::string` constexpr"](http://wg21.link/p0980r1) + +LWG motion 28: [P0660R10 "Stop token and joining thread"](http://wg21.link/p0660r10) + +LWG motion 29: [P1474R1 "Helpful pointers for `ContiguousIterator`"](http://wg21.link/p1474r1) + +LWG motion 30: [P1523R1 "Views and size types"](http://wg21.link/p1523r1) + +LWG motion 31: [P0466R5 "Layout-compatibility and pointer-interconvertibility traits"](http://wg21.link/p0466r5) + +LWG motion 32: [P1208R6 "`source_location`"](http://wg21.link/p1208r6) + +## Notable editorial changes + +### CWG motion 21 + +The changes for this motion in [over.match.class.deduct] +described the matching of a *simple-template-id* against +the *defining-type-id* of an alias template +in imprecise terms +(quoting only part of the grammar to which the change intended to apply). +This has been made more precise by repeating the full grammar +previously specified in [dcl.type.simple] +in [over.match.class.deduct]. + +### LWG motions 5-7 + +The new `std::format` library underwent substantial editorial rework +for clarity and precision. +Thanks to Tomasz Kamiński and +Johel Ernesto Guerrero Peña +for reviewing the resulting edits, +and to Victor Zverovich for responding to various questions about intent. + +### LWG motion 10 + +The `operator<<` added for `hh_mm_ss` was written in terms of +the old chrono formatting machinery that was replaced by +`std::format`-based machinery by LWG motion 6. +It has been rephrased in terms of `std::format`. +Thanks to Howard Hinnant for providing wording. + +### LWG motion 11 + +In addition to the requested renames, the following concepts were also renamed, +following the editorial instructions to rename all other concepts: + + * `ThreeWayComparableWith` -> `three_way_comparable_with` + * `ThreeWayComparable` -> `three_way_comparable` + * `ForwardRange` -> `forward_range` + +### LWG motion 14 + +This motion requested that the same constructor be added to `basic_stringbuf` +twice. It was only added once. + +### LWG motion 23 + +The wording paper proposed making changes to the algorithms + + * `std::ranges::sample` + * `std::ranges::shift_left` + * `std::ranges::shift_right` + +However, these algorithms were never adopted into the C++ working draft from +the Ranges Technical Specification, so after consulting with the Library +Working Group, the requested changes to these algorithms were ignored. + +### LWG motion 26, 27 + +These motions would have added `constexpr` to +`operator<`, `operator>`, `operator<=`, `operator>=`, and `operator!=` functions +that LWG motion 12 removed. +Instead `constexpr` was added to the replacement `operator<=>`. + +In addition, following the paper's request to add `constexpr` to any +`std::basic_string` functions that the wording missed, and after consulting +with the LWG chair as directed, the overloads of `std::erase` and +`std::erase_if` for `std::basic_string` were also marked `contexpr`. + +### Section label changes + +Several section labels introduced by the motions papers have been modified +to match our style guide. In addition to the section labels affected by the +above motions, the following section labels have been renamed: + + * [concept.convertibleto] => [concept.convertible] + * [concept.derivedfrom] => [concept.derived] + * [concept.stricttotallyordered] => [concept.totallyordered] + +## Feature test macros + +Attention should be drawn to the fact that multiple papers updated feature test +macros to the same version: + + * `__cpp_constexpr` was updated to `201907L` by both + [P1331R2](http://wg21.link/p1331r2) (CWG motion 3) and + [P1668R1](http://wg21.link/p1668r1) (CWG motion 12). + * `__has_cpp_attribute(nodiscard)` was updated to `201907L` by both + [P1304R4](http://wg21.link/p1304r4) (CWG motion 7) and + [P1771R1](http://wg21.link/p1771r1) (CWG motion 20). + +Implementers should be aware that the new version of the feature test macro +advertises support for both papers in these cases (in addition to advertising +support for prior papers that gave smaller version numbers to the relevant +macro). + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4820 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/n4820...n4830). + + commit 44ea29778d15cd5d9f2b5c706c6b3f4338548ec2 + Author: Casey Carter + Date: Tue Jun 25 06:04:14 2019 -0700 + + [range.filter.sentinel] Correct typo in constructor Effects (#2937) + + commit 97b615a5a6ab0598b624ee05402c531d0421cff6 + Author: Casey Carter + Date: Tue Jun 25 06:09:55 2019 -0700 + + [iterator.synopsis] Copy constraint for iterator_traits from [iterator.traits]/5 (#2943) + + commit da7eac5e621b5fab12c0b1992100c4bfd983ed8e + Author: Saar Raz + Date: Mon Jul 1 22:46:37 2019 +0300 + + [Concepts] Remove qualified-concept-name reference + + Update 'qualified-concept-name' (the previous incarnation of 'type-constraint') reference to 'type-constraint' in [temp.over.link]p6. + + commit f54f306c3b9fad27e70766963840e3df14f20b28 + Author: Jens Maurer + Date: Thu Jul 4 15:34:38 2019 +0200 + + [func.bind] Remove bogus 'shall's. (#2955) + + commit 72cc844ef44ae47aebb1ad346146138d3279be9e + Author: Eelis + Date: Fri Jul 5 16:16:58 2019 +0200 + + [expr.reinterpret.cast] Properly capitalize full-sentence bullets. (#2956) + + commit c635711cdd81346ad41c7861adb8035176fa236f + Author: Eelis + Date: Fri Jul 5 23:55:22 2019 +0200 + + [temp.constr.constr] Add missing period at end of sentence. (#2957) + + commit 4f9942cafadc17fb902610b4c67afb6fcf81ff64 + Author: Jens Maurer + Date: Sun Jul 7 19:38:20 2019 +0200 + + [dcl.asm] Rename grammar term 'asm-definition' to 'asm-declaration' + + commit 51c5b01217799fdfa754179c20af888ec8c1889d + Author: Casey Carter + Date: Wed Jul 10 00:40:19 2019 -0700 + + [temp.constr.order] Remove extraneous "the". (#2964) + + commit 67db9422b6bc58f5399c7c019ec5ede28d8ac4f5 + Author: Jens Maurer + Date: Fri Jun 28 17:01:54 2019 +0200 + + [expr.prim.req] Fix cross-reference for substituting into constraints. + + commit 98c2c56ab5e945452586270d72d2fb606b71cd94 + Author: Richard Smith + Date: Mon Jul 22 02:24:42 2019 +0200 + + [class.prop] [special] Move definition of eligible special member + functions to the section on special member functions. + + commit 94a72b5c11a20cfd6c92a4faa5bd0df4b8ebc620 + Author: Richard Smith + Date: Mon Jul 22 02:28:15 2019 +0200 + + [class.dtor] Reorder the introduction of an implicit prospective + destructor to before we describe the overload resolution to pick the + actual destructor. + + commit 6bd3daeae3a3e9ae6174c35ab020dbfe4504b75b + Author: Richard Smith + Date: Thu Aug 1 20:04:36 2019 -0700 + + [class.ctor], [class.dtor] Introduce actual definitions for + "constructor" and "prospective destructor". + + commit dc45e8c329eeb0076d074fa671c2be2fc605555a + Author: Richard Smith + Date: Mon Jul 22 03:18:33 2019 +0200 + + [class.spaceship] Remove incorrect note. + + commit d6a291776858bc647fc6826888767284f305c799 + Author: Richard Smith + Date: Mon Jul 22 03:58:34 2019 +0200 + + [dcl.attr.nodiscard] Simplify note describing the string-literal in a + nodiscard attribute and make it less confusing. + + commit 46ba985402de963f50d364b26b594707be16c7c9 + Author: Richard Smith + Date: Mon Jul 22 04:42:43 2019 +0200 + + [dcl.enum] Avoid hanging paragraphs by moving "Enumeration declarations" + down one level to a sibling of "The using enum declaration". + + [namespace.udir] Rename section to "Using namespace directive" to + further distinguish this from a using enum declaration. + + commit 5d1bb1c7f8ed44016c38bfeb9797e363d52cfc51 + Author: Richard Smith + Date: Thu Aug 1 20:42:13 2019 -0700 + + [over.match.oper] Replace "member, non-member, and built-in candidates" + with "non-rewritten candidates" + + This simplifies the wording, implicitly explains why we're considering + only some candidates, and avoids overtly suggesting that we could ever + pick a reversed-parameter-order built-in candidate. + + commit 1fbc1c315008152770eea8bd383aa2a4fa47cfd5 + Author: Jens Maurer + Date: Fri Jul 26 16:56:13 2019 +0200 + + [basic.def.odr] Turn long comma-separate list into bullets. + + commit c0c589881759871b2183105f315d4ddd0d2734be + Author: Jens Maurer + Date: Thu Aug 1 22:47:19 2019 +0200 + + [expr.const.cast] Clarify pairwise correspondence for P_i. + [over.ics.rank] Move cross-reference pointing to [conv.qual]. + + commit 47539b965a84f69c548fe043a632af17db3cb315 + Author: Richard Smith + Date: Fri Aug 2 15:49:39 2019 -0700 + + [conv.qual] Move note after the rule that implies it. + + commit f10e3751b39138746b601fa702c9ed9e67777c96 + Author: Richard Smith + Date: Fri Aug 2 15:59:50 2019 -0700 + + [over.ics.rank] Reorder examples to match order of normative text. + + commit 813a4300a036f12d5ff6b82965b83a8e87b1ae8d + Author: Richard Smith + Date: Fri Aug 2 16:55:56 2019 -0700 + + [dcl.attr.nodiscard] Fix vexing-parse bug in example. Make sure the + missiles actually get launched, not merely redeclared. + + commit 6e845457bfd83f20c2f61bf4015afcd96cbd0cec + Author: Richard Smith + Date: Fri Aug 2 17:17:52 2019 -0700 + + [over.match.class.deduct] Fix failure to handle the case where a + deducible alias template's defining-type-id contains a + nested-name-specifier (or 'typename' or 'template' keywords). + + commit 7226ced32fe3cda28eb05f044985427684397128 + Author: Richard Smith + Date: Fri Aug 2 17:26:53 2019 -0700 + + [over.match.class.deduct] Switch from imperative to passive, and clarify + what happens if the various 'if' conditions are not met. + + commit 6552c03d3793e7532793097d760edc3a93e150b1 + Author: Richard Smith + Date: Fri Aug 2 17:32:40 2019 -0700 + + [over.match.class.deduct] Put all bullets describing the properties of + f' at the same depth, and guard them all by the condition that we're + actually adding an f' to the set of guides. + + commit b3b7d37c073051826c21c231bd386c10d64433dc + Author: Jens Maurer + Date: Fri Aug 2 22:09:14 2019 +0200 + + [class.copy.elision] Add cross-reference, fix example. + + commit 4a657ca3e26850a993c2015bbecd6287e817a615 + Author: Richard Smith + Date: Sat Aug 3 18:51:09 2019 -0700 + + [iterator.concept.sizedsentinel], [range.sized], [range.view] + Provide proper descriptions for disable_sized_sentinel, + disable_sized_range, and enable_view. + + commit 796c871f9b14a42fea634ec97a35032bfe3c422a + Author: Jens Maurer + Date: Tue Jul 23 09:57:04 2019 +0200 + + [bit] Avoid std::numeric_limits<...> + + Referring to numeric_limits (without std:: prefix) is sufficient. + + commit fb97956bc9eee5a50c10df9148d9422e260e352c + Author: Richard Smith + Date: Wed Jul 31 17:28:28 2019 -0700 + + [format.formatter] Add subclause heading to avoid hanging paragraphs. + + commit eae84a0a10b4409da01ae5c9e7c734e113973cdf + Author: Richard Smith + Date: Wed Jul 31 17:34:37 2019 -0700 + + [format.string] Clarify that "other characters" means "characters other + than { and }". + + commit b62dc39c0541a1968ac1717773574f4ef868934c + Author: Richard Smith + Date: Wed Jul 31 18:05:00 2019 -0700 + + [format.string] Change 'integer' grammar to be left-recursive and factor + out separate positive-integer and nonnegative-integer productions for + clarity. + + commit 2db4bd64f7f157266ae0f7c7c44c4fe7c68c6070 + Author: Richard Smith + Date: Wed Jul 31 18:14:56 2019 -0700 + + [format.string] Fix wording that talks about omitting arg-ids but + presupposes that they are all present to instead specify what happens + when some or all are absent. + + commit 5a32fd1040b8a7c4c997ba8841c4f28a34a6c97d + Author: Richard Smith + Date: Wed Jul 31 18:26:41 2019 -0700 + + [format.string] Add missing grammar definition for custom-format-spec + rather than leaving it dangling. + + commit d529b96f3be22332d4a88de646f56cb636680f6c + Author: Richard Smith + Date: Wed Jul 31 18:33:05 2019 -0700 + + [format.string] Make tone of wording more formal and less tutorialesque. + + commit 3ced91d524f3c2a850243863440151735276b38a + Author: Richard Smith + Date: Wed Jul 31 18:41:56 2019 -0700 + + [format.context] Add specification of wformat_context analogous to that + of format_context, as discussed on lib reflector. + + commit ed00761315546c11b48441e1bcef6aa5927f76c8 + Author: Richard Smith + Date: Thu Aug 1 18:17:10 2019 -0700 + + [format.string] Explicitly list all the possible formatting types for + bool and charT in their respective tables rather than requiring the + reader to infer how to merge the integer table into the bool and charT + tables. + + commit 46622695da52f8080f7280207eecd93bd950cc1a + Author: Richard Smith + Date: Sat Aug 3 19:57:13 2019 -0700 + + [format.functions] Use clamp rather than min(max(a,b),c) + + Co-Authored-By: Johel Ernesto Guerrero Peña + + commit a870403a2dc47924e7f607f7c69694291d43007c + Author: Richard Smith + Date: Sat Aug 3 20:39:06 2019 -0700 + + [format.arg] Don't use placeholder name for private member char-type. + + commit d17fd4d5f10f6af87654fdc73bd6417313a295f2 + Author: Richard Smith + Date: Sun Aug 4 14:04:04 2019 -0700 + + [format.string] Avoid duplicating the specification of '#' for integers. + + Fix the specification for '#' being different for octal integers in the + two places it's specified. + + commit e30b8a69d485b96ddacfa31b7eb411c5a64d83a5 + Author: Richard Smith + Date: Sun Aug 4 14:23:48 2019 -0700 + + [format.string] Separate out the general (type-independent) description + of formatting from the format specifiers for arithmetic and string + types, and make the presentation of the latter consistent with the + presentation for chrono types. + + commit f430bec8e7a4437b69d1ad31b2c1f4246e753770 + Author: Richard Smith + Date: Sun Aug 4 15:09:26 2019 -0700 + + [format.string.std] Convert normative duplication to a note to avoid + creating the impression that alignment is only applied to non-string + types. + + commit b6454e39ede7ab11ce0958fa2ee3b487c8983ae1 + Author: Richard Smith + Date: Sun Aug 4 15:32:02 2019 -0700 + + [format.string] Further clarify description of cases where formatting is + described in terms of a call to to_chars. + + commit 895f30bd225d050bcb2ab9f0a793af9865dcd513 + Author: Richard Smith + Date: Sun Aug 4 20:02:33 2019 -0700 + + [format.formatter] Reorder Formatter requirements before the + descriptions of specializations that meet those requirements. + + commit c7ada4d28ae7be82ef64104617e216fd738a4d0f + Author: Jens Maurer + Date: Tue Jul 30 16:07:16 2019 +0200 + + [numbers] Use 'template', not 'typename'. + + commit 14aa4ed0d323c163f0559bd7c8555d77f2dc8093 + Author: Jens Maurer + Date: Tue Jul 30 16:12:59 2019 +0200 + + [math.constants] Expand 'math' to 'mathematical'. + + commit 3f761c76b5daf9f1a75695226514c323ba6619f0 + Author: Jens Maurer + Date: Thu Aug 1 10:50:09 2019 +0200 + + [numbers.syn] Use 'namespace std::numbers'. + + commit dc61857d3779253c6cdeec572cdcb43077b0ce86 + Author: Richard Smith + Date: Sun Aug 4 20:51:47 2019 -0700 + + [atomics.lockfree] "are" -> "is"; "along with" is not a coordinating + conjunction. + + commit 3d3f16f99454d3ffffcfbf92a02b9bcaac9b375b + Author: Richard Smith + Date: Sun Aug 4 21:50:27 2019 -0700 + + [thread.barrier.class] Rename constructor parameter from `phase_count` + to `expected`. + + The parameter is not a phase count, and is referred to by other + normative wording as `expected`; also, `expected` is the name we use for + the same parameter in the constructor of `latch`. + + commit 2e82327045fb92d89dd1431cc7e771da63c982dc + Author: Jens Maurer + Date: Thu Aug 1 10:37:25 2019 +0200 + + [time.hms.members] Rephrased note. + [time.hms.overview] Removed redundant declaration of operator<<. + [time.hms.overview] Moved exposition-only data members to the bottom. + + commit 1a37c22bb6b621f14d01b4e16378c9cd08724183 + Author: Richard Smith + Date: Sun Aug 4 23:36:25 2019 -0700 + + [time.hms.nonmembers] Finish rebase on std::format: rewrite hh_mm_ss + operator<< in terms of format rather than using (removed) old formatting + terminology. + + commit 584a87ec1d48862b9e68a269d0a5eb7b05d6999d + Author: Richard Smith + Date: Mon Aug 5 13:57:50 2019 -0700 + + [time.hms.nonmembers] Fix editorial error in hh_mm_ss operator<< (only + stream to 'os' once). This formulation was proposed by Howard Hinnant + on the lib reflector. + + commit d243672db3269754d4ee91a5fbcdfb82ae6f2539 + Author: Jens Maurer + Date: Tue Jul 30 16:01:10 2019 +0200 + + Apply P1452R2 On the non-uniform semantics of return-type-requirements + to newly-introduced return type requirements. + + commit 90f64792ec7d5372a093d3bea69dffff2f7af28a + Author: Richard Smith + Date: Mon Aug 5 13:48:59 2019 -0700 + + Rename _s to -s in placeholder names per editorial guidelines. + + commit ad685c42b18103ace094b375a4fde1a7ec6aba02 + Author: Dawn Perchik + Date: Tue Jul 30 19:33:10 2019 -0700 + + [stringbuf] Name string parameters "s" instead of "str" for consistency and to avoid confusion with "str" methods. + + commit 26f7cd6d3b2d271c74e1d2022f972f833de940f6 + Author: Dawn Perchik + Date: Thu Aug 1 13:35:42 2019 -0700 + + [stringbuf.members] Minor fixes to P0408R7 wording. + + "str()" should be "str"; we're talking about all str member functions here. + Add comma after "For efficiency reasons". + "i.e." -> "e.g." since we're describing an example case. + + commit b4a8b798e00bce697af9b477a214828b69e9e383 + Author: Richard Smith + Date: Mon Aug 5 17:31:21 2019 -0700 + + [module.unit] Add "either" to clarify that we're talking about + module-names containing a reserved identifier, not module names starting + with an identifier that contains a reserved identifier. + + commit 906fd4d0519994e06659ce066c8252df186c23b9 + Author: Richard Smith + Date: Mon Aug 5 17:57:35 2019 -0700 + + [func.require] Convert restrictive 'which' to 'that'. + + commit 7e862f0f238257b2cbb1f7296a593b4587029e39 + Author: Richard Smith + Date: Mon Aug 5 18:46:55 2019 -0700 + + [range.transform.sentinel] Reinstate transform_view::sentinel::operator- + overloads, accidentally removed during application of P1614R2. + + commit e02aa79ca43de3fdf6e1887d4fd02bc58874e190 + Author: Jens Maurer + Date: Wed Jul 31 22:55:50 2019 +0200 + + [range.istream.view] Do not repeat declaration of function istream_view + [range.elements.iterator] Renamed from [range.elements_view.iterator] + [range.elements.iterator] Use local typedef difference_type + [range.elements.iterator] Use reference return type for compound assignment + + commit a0b5a70fade22203ebfbaeb4828e0c304b1f62ab + Author: Richard Smith + Date: Mon Aug 5 23:02:38 2019 -0700 + + [ranges] Fix 'constexpr friend' to our preferred order 'friend constexpr'. + + commit f0256ab73cd6a9fae611af95526d16fe59968d4c + Author: Richard Smith + Date: Mon Aug 5 23:08:59 2019 -0700 + + [range.drop.view] Fix typo "requirement" -> "required". + + commit 7698c3dc28251540b4a4733cc4a6b3f6942f13ed + Author: Richard Smith + Date: Tue Aug 6 00:40:47 2019 -0700 + + [range.iota.view] Rename IOTA_DIFF_T to the preferred IOTA-DIFF-T. + + commit cf1bc270c0e7d7b1670502c69268b0373bbf9799 + Author: Richard Smith + Date: Tue Aug 6 01:35:47 2019 -0700 + + [thread] Update headings, comments, and line wrapping to match editorial + conventions. + + commit 7f4e95e3296b31c23bfb358f31294d384a955e3b + Author: Jens Maurer + Date: Sat Aug 3 08:38:34 2019 +0200 + + [support.srcloc] Fix comments in example. + + commit 06ab7ebef8a763e36f87f504ed7765528aa25fc7 + Author: Richard Smith + Date: Tue Aug 6 02:28:42 2019 -0700 + + [support.srcloc.cons] Use term "default member initialier" rather than + describing it indirectly. + + commit 7beed51f4388074f46fd55a7c5f559cd82b7c40c + Author: Dawn Perchik + Date: Tue Jul 30 20:36:34 2019 -0700 + + [alg.is.permutation] Add parameters to \libconcept{sized_sentinel_for} as suggested in PR #3099. + + commit fbb0691134e39059adaa4a886e7d746b0e56c81c + Author: Dawn Perchik + Date: Wed Jul 31 12:52:26 2019 -0700 + + [concepts] Renamed concepts' section names to remove trailing prepositions for consistency. + + * concept.convertibleto => concept.convertible + * concept.derivedfrom => concept.derived + * concept.stricttotallyordered => concept.totallyordered + + commit e2a070f7a5484e272c10e4ab31359fede5ff24a1 + Author: Richard Smith + Date: Tue Aug 6 13:51:24 2019 -0700 + + [diff.cpp17.library], [tab:headers.cpp] Add missing entry + to the list of headers, and add various missing entries to the list of + new-in-C++20 headers. + + Fixes #3122. + + commit 54a87d7849e7d5283c2d0a34f8200ef6a67bb0da + Author: Jens Maurer + Date: Tue Aug 6 23:17:24 2019 +0200 + + [conv.qual,expr.static.cast] Harmonize notes on cv-qualified function types. + + commit ee234abfbfa7deb5c585b67590205e1660df180f + Author: Jens Maurer + Date: Thu Aug 1 16:45:51 2019 +0200 + + [time.clock,bit.cast] Replace template with template + + as per library specification policy. + + commit a374c4f3664cf84a4440feb3c236076b25cfe736 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Thu Jul 25 21:24:06 2019 +0200 + + [tuple] Use "objects" instead of "variables" + with "temporary" in the definition of `forward_as_tuple` + + commit 7e02aa3d7d3e5e9dfc2c66451e112d40f4491465 + Author: Jonathan Wakely + Date: Mon Jul 22 23:27:57 2019 +0100 + + [is.sorted] Add missing "return" and semi-colon + + This was lost when changing "Returns:" to "Effects:" for P0896R4. The + paper included this change, but it was lost when applying it. + + commit cc421307fb4ce393e7ab1dcf0d0f1298d163fbe0 + Author: Yehezkel Bernat + Date: Sun Jul 21 22:16:23 2019 +0300 + + Delete irrelevant copy-paste from previous section + + commit d4c4cc0ac037c51ec10cf6f7c80d8c761b517cba + Author: onihusube <44743040+onihusube@users.noreply.github.com> + Date: Wed Jul 17 22:46:24 2019 +0900 + + [basic.lookup.argdep]/5 add export to apply() + + fix #2968 + + commit 557cfa9dd706780fb672bfe9e5e2f0ef3b2f3d4a + Author: Jens Maurer + Date: Thu Jul 4 09:31:57 2019 +0200 + + [basic.life] Lifetime of class objects is treated uniformly + under CWG2256, regardless of triviality of the destructor. + + commit 4c3b9f50ecd230263974c81e1df2fb07b541c58d + Author: onihusube <44743040+onihusube@users.noreply.github.com> + Date: Mon Jul 1 16:26:16 2019 +0900 + + [module.global] fix sample code comment + + commit 06bd4b02febcb43c014ffd46b7a07dab8d66aa4b + Author: onihusube <44743040+onihusube@users.noreply.github.com> + Date: Mon Jul 1 16:41:33 2019 +0900 + + [cpp.module] fix sample code comment + + commit 1be069efaa41f4df376364290f8069ec030b13cc + Author: Jens Maurer + Date: Fri Jun 28 17:11:44 2019 +0200 + + [time.parse] Fix description of %Ex and %EX parse flags. + + Also refer to the table number instead of 'the table below'. + + commit f038d86fb9112b62adaaebaf95dc70d786412cbd + Author: Jens Maurer + Date: Fri Jun 28 16:50:03 2019 +0200 + + [res.on.functions] Properly capitalize full-sentence bullets. + + Also add periods at the end of sentences. + + commit 43945886b4ff4481da3d29b3f624d55bc9b5d124 + Author: Jens Maurer + Date: Mon Jun 24 22:43:30 2019 +0200 + + [conv.qual] Fix example for cv-decomposition. + + After CWG2051, a cv-decomposition can also be a no-op. + + commit 915031ddbf75f856efcea43928d9f459140834fd + Author: Jens Maurer + Date: Tue Aug 6 09:31:52 2019 +0200 + + [meta.trans.other] Use hyphens, not underscores, for meta-functions. + + commit be443affbf06bfb14c2295311ed469896ae39d6c + Author: Richard Smith + Date: Wed Aug 7 17:59:27 2019 -0700 + + [range.drop.while.overview] Add missing space in example. + + commit 1e09011ff3627db60ae10fa8fee2e2f5ef7dc5c9 + Author: Richard Smith + Date: Sat Aug 10 18:13:55 2019 -0700 + + [format.string.general] indexes -> indices + + commit 71251ae592a49149faec1389ec85f22322aa0ba5 + Author: Richard Smith + Date: Sat Aug 10 18:23:43 2019 -0700 + + [format.string.std] Fix space collapse in example. Use commas rather + than spaces to separate fields to more clearly show where whitespace is + introduced by a field rather than between fields. + + commit ee719cb98574ade2c113a17a16e6af247913456b + Author: Richard Smith + Date: Sat Aug 10 18:30:01 2019 -0700 + + [tab:format.type.float] Add "equivalent to" to remaining calls to + to_chars for consistency. + + commit add4ff3339153382b0e59d45e6bfeee4f923060a + Author: Richard Smith + Date: Sat Aug 10 18:35:05 2019 -0700 + + [time.format] Fix some minor issues (comma rather than period, moving a + "Let" sentence out of a Remarks clause to a separate paragraph, using + 'class' rather than 'typename'). + + commit d4b47a09e9089bc661c4ad6bb882a46f4aae92b6 + Author: Richard Smith + Date: Sat Aug 10 18:38:26 2019 -0700 + + [time.syn] Fix specifier order in declarations to match library style. + Rename parameter 't' to 'hms' to make declaration and later description + match. + + commit 550553189899e1687629827dbb3fbf9c401f5d96 + Author: Richard Smith + Date: Sat Aug 10 18:40:49 2019 -0700 + + [range.istream.iterator] Fix 'parent_' to the obviously-intended 'parent'. + + commit 791a19a1d206c77b97e7725aa9a8ea779bf94d7a + Author: Richard Smith + Date: Sat Aug 10 19:08:16 2019 -0700 + + [chrono], [iostreams], [support] Fix 'template <' and 'typename T' to + the conventional 'template<' and 'class T' throughout the library. + + commit ac72157b97d4b7b85ddb7ca412b5a4ee1806614d + Author: Richard Smith + Date: Sat Aug 10 19:11:57 2019 -0700 + + [cmp.object] Add missing template-head to function description. + + commit b050fd474f11441942c88ef69b8622c8036656ac + Author: Richard Smith + Date: Sat Aug 10 19:26:09 2019 -0700 + + [re.submatch.op] Fix inconsistency between declaration and description + of sub_match operator<=>: remove 'constexpr' from declaration, and + change return type in definition from 'bool' to 'auto'. + + commit 1335e42809151ecfdb671ea2aea1dab0c8d5db53 + Author: Richard Smith + Date: Sat Aug 10 19:33:48 2019 -0700 + + [iterator.concept.sizedsentinel] Avoid potential ambiguity between + inclusive and exclusive "or" by using "and/or". + + commit 1b2bfda98c20ecd71a35b7321662f8f976134793 + Author: Richard Smith + Date: Sat Aug 10 19:51:39 2019 -0700 + + [atomic] Remove invalid trailing 'const' from non-member function + atomic_flag_notify_all. + + commit afed449f0fa1324001260c9d658f6d05da90a9f9 + Author: Richard Smith + Date: Sat Aug 10 19:55:21 2019 -0700 + + [thread.sema.cnt] "Class" -> "Class template" in description of a class + template. + + commit 7445919de1bcf4780693b7870a245486839587ea + Author: Richard Smith + Date: Sat Aug 10 19:58:05 2019 -0700 + + [thread.latch] Remove italics from non-definition of "latch". + + commit 224384ab43e4e9829eee5d97f09218850026d342 + Author: Richard Smith + Date: Sat Aug 10 20:05:07 2019 -0700 + + [atomic] Consistently order atomic<...> and atomic_ref<...> definitions: + keep compare_exchange and fetch_* operations together because the latter + are a particular form of compare_exchange operation. + + commit 8644a2ce2faa6e979e224f069e4ca48238ea8570 + Author: Richard Smith + Date: Mon Aug 12 16:47:06 2019 -0700 + + [atomics.syn], [atomics.flag] Clean up presentation around + ATOMIC_FLAG_INIT. + + * Add some vertical whitespace in description of atomic_flag operations. + * Reorder ATOMIC_FLAG_INIT earlier in synopsis for consistency. + * Add proper item description for ATOMIC_FLAG_INIT. + * Remove repetition of declarations of atomic_flag non-member functions + and the ATOMIC_FLAG_INIT macro from [atomics.flag]. + + commit 2c1ab9775cc53e848a1efff4f9976455538994d4 + Author: Richard Smith + Date: Mon Aug 12 16:56:24 2019 -0700 + + [string.erasure] Following the guidance given by P0980R1, and after + consultation with LWG chair, mark the std::erase and std::erase_if + overloads for std::basic_string as constexpr in addition to those + explicitly called out by the wording paper. + + commit 009d46f9b057a635383dce8bbcad121c86f1d306 + Author: Richard Smith + Date: Tue Aug 13 18:16:48 2019 -0700 + + [over.match.class.deduct] Replace "therefrom" with a more common + construction, and more directly talk about the class template for which + we are ultimately performing deduction. + + commit ac9189f351bf0407a31968199c22274ff41fe9e7 + Author: Richard Smith + Date: Tue Aug 13 18:21:14 2019 -0700 + + [diff.cpp17.class] Remove redundant cross-reference. + + commit ba642aa699973f21613cbe3e6a0b6d9c1e0f2e6a + Author: Richard Smith + Date: Wed Aug 14 16:16:48 2019 -0700 + + [ostream] Add back the comments that P1423R3 requested, but now as a + note. + + commit 37ccff2c0e9be3a62fcd85b55e4d05c2b312335f + Author: Richard Smith + Date: Wed Aug 14 16:48:00 2019 -0700 + + [dcl.fct.def.default] Clarify that the rule concerning how the type of a + defaulted function can differ from the type of an implicitly-declared + function only applies to the functions that are implicitly declared. + + commit 42ee105f5804a74bb15960944ee7fe1cd4420e04 + Author: Richard Smith + Date: Wed Aug 14 16:56:23 2019 -0700 + + [over.match.class.deduct] Clarify that an incomplete class type is never + treated as being an aggregate. + + commit fce4ac9764e10042bd8d0bb4152e83d697c8bdae + Author: Richard Smith + Date: Wed Aug 14 17:02:06 2019 -0700 + + [dcl.typedef] Split paragraph on typedef name for linkage into two parts + (how you know when you have one, and the restrictions on types that have + one). + + commit 90a29c08bc80091c093937a7d96ce28df5ceee44 + Author: Richard Smith + Date: Wed Aug 14 17:21:15 2019 -0700 + + [conv.qual] Avoid bouncing back and forth between subscripts and regular + scripts for T1 and T2, and add missing definition for cv^j_i and P^j_i. + + commit 03bcd8d3e5ece969af846e23cd451549185fdac4 + Author: Jens Maurer + Date: Thu Aug 8 01:07:54 2019 +0200 + + [expr.ass] Remove mention of class types. + + commit 173905005c2c419548418239518db72bfda9dd9a + Author: Richard Smith + Date: Wed Aug 14 17:48:53 2019 -0700 + + [dcl.attr.nodiscard] Make the constructor case better parallel the + function case by duplicating the implied "through a reachable + declaration" wording. + + commit acbe5e429499d0eaf6c118f0bca4bbc26830bcaf + Author: Davis Herring + Date: Mon Aug 12 12:07:06 2019 -0600 + + [dcl.attr.nodiscard], [diff.cpp17.dcl.dcl] Fix grammar/usage + + commit 5aa019b19118973d99a2b2282d3f6264da81c9d8 + Author: Davis Herring + Date: Mon Aug 12 12:13:20 2019 -0600 + + [basic.def.odr] Clean up new bullets + + commit eb443396ac48b4e2ac9c6be0d9ec6bf9dda107eb + Author: Davis Herring + Date: Mon Aug 12 12:27:41 2019 -0600 + + [module.reach], [over.ics.rank] Fix punctuation + + commit 37d2e59e8deb847f5ebdade20604bdf5c119649a + Author: Davis Herring + Date: Mon Aug 12 14:14:50 2019 -0600 + + [expr.ass] Improve preposition + + commit 4a0fd9aa43a0d63d6fe875b886cdea8ec24d7f9d + Author: Davis Herring + Date: Mon Aug 12 15:03:56 2019 -0600 + + [over.match.class.deduct] Supply missing word + + commit 05c786cc68bf14a828cc59f32d34fae2baf33794 + Author: Davis Herring + Date: Tue Aug 13 00:49:41 2019 -0600 + + [expr.new] Use typical \iref + + commit fc1863291a3f62a684d9bffa51fdc2837e9edcd0 + Author: Davis Herring + Date: Tue Aug 13 14:55:54 2019 -0600 + + [class.spaceship] Remove vacuous conversion + + The synthesized three-way comparison always produces a value of type R + + commit 80f2c46251f07abf422cdd86a3f3d30c47fda587 + Author: Davis Herring + Date: Tue Aug 13 14:59:46 2019 -0600 + + [over.match.class.deduct] Fix terminology + + An element with a dependent type might not be a subaggregate + Add cross-reference + + commit bfa0e698359d44e8a2b0a056e13e908a8185e296 + Author: Davis Herring + Date: Tue Aug 13 15:02:06 2019 -0600 + + [over.match.class.deduct] Use "deduces" + + ...for consistency in example + + commit 174edca593a860440860f95c3ee61aa739e2afdc + Author: Davis Herring + Date: Tue Aug 13 23:41:02 2019 -0600 + + [over.match.class.deduct] Simplify example + + commit a9f901af95f16540444144a397fe3b598ae2961b + Author: Richard Smith + Date: Wed Aug 14 17:51:44 2019 -0700 + + [class.dtor] "The defaulted destructor" -> "A defaulted destructor", + since the destructor for a class might not be defaulted. diff --git a/papers/n4830.pdf b/papers/n4830.pdf new file mode 100644 index 0000000000..9342aa6d06 Binary files /dev/null and b/papers/n4830.pdf differ diff --git a/papers/n4835.pdf b/papers/n4835.pdf new file mode 100644 index 0000000000..291ee317b2 Binary files /dev/null and b/papers/n4835.pdf differ diff --git a/papers/n4836.html b/papers/n4836.html new file mode 100644 index 0000000000..21c926d358 --- /dev/null +++ b/papers/n4836.html @@ -0,0 +1,617 @@ +N4836 +

N4836 Editors' Report -- Programming Languages -- C++

+ +

2019-10-08
+Richard Smith (editor) (Google Inc)
+Thomas Köppe (co-editor) (Google DeepMind)
+Jens Maurer (co-editor)
+Dawn Perchik (co-editor) (Bright Side Computing, LLC)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

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

+ +

New papers

+ +
    +
  • N4835 is the current C++ working draft. It replaces N4830.
  • +
  • N4836 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Fixed application of P1643R1 (2019-07 LWG Motion 9): +two added paragraphs should have been labeled Effects: instead of Expects:.

+ +

Fixed application of P1463R1 (2019-03 LWG Motion 10): +an added != in [list.ops] has been replaced with the correct ==.

+ +

Notable editorial changes

+ +

Improved indices

+ +
    +
  • The index of library headers now shows the location of the header synopsis in boldface.
  • +
  • An index presenting all concept names (including exposition-only concepts) was added.
  • +
  • The main index and the index of library names now show subdivisions per letter.
  • +
+ +

Changes to section labels

+ +
    +
  • [source_location.syn] -> [source.location.syn]
  • +
  • [atomics.ref.operations] -> [atomics.ref.ops]
  • +
+ +

Several "Preamble" sections were added to avoid hanging paragraphs.

+ +

Feature test macros

+ +

An explicit synopsis for the <version> header has been added. +This synopsis describes the complete set of library feature test macros +and replaces the prior use of a table for this purpose. +For wording papers, we will continue to accept instructions of the form +"Add a feature test macro __cpp_lib_blah with a suitable value"; +explicit lists of edits to [version.syn] are also acceptable.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4830 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 4fe8325ff6cf63055f9d064ba1b4f24614863649
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Tue Aug 20 05:14:29 2019 +0800
+
+    [thread.jthread.class] fix typos (#3183)
+
+commit aaea74e8dcfa456043ec315511463fb6d4a80108
+Author: David Olsen <dolsen@nvidia.com>
+Date:   Mon Aug 19 14:17:33 2019 -0700
+
+    [atomics.ref.operations] Change Expects to Effects for atomic_ref::notify_{one,all} (#3180)
+
+    Fix an editorial issue that resulted from an incorrect merge.  In the
+    description of atomic_ref::notify_one and atomic_ref::notify_all in
+    [atomics.ref.operations] p25 and p27, N4830 has "Expects" in both of
+    those paragraphs.  But the paper that was merged in, P1643R1
+    ( http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1643r1.html )
+    has "Effects".  "Effects" is correct, and it matches notify_one and
+    notify_all in the four other atomics-related classes.
+
+commit 538f7c69f1423551628fdc638e8c4654bf1c7662
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Aug 19 23:20:53 2019 +0200
+
+    [std] Add/fix periods at end of sentences. (#3177)
+
+commit 600f1c0d1e94b0b6198c99516a95ec5ba439237a
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Mon Aug 19 23:22:26 2019 +0200
+
+    [std] Use consistent punctuation to terminate non-final list items. (#3175)
+
+commit fc240342df42f090563ed09c991c01925f1f4f27
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Aug 19 23:31:56 2019 +0200
+
+    [tuple.elem] Canonicalize comments in example. (#3161)
+
+commit 221f1062d929688811aaa96c9752b54443ba29db
+Author: Dan Raviv <dan.raviv@gmail.com>
+Date:   Fri Aug 23 10:00:40 2019 +0300
+
+    [lex.key,diff.header.iso646.h] Consistent tokens order (#3190)
+
+    Order the alternative tokens in [diff.header.iso646.h] in the same way
+    they are ordered in Table 6 in [lex.key].
+
+commit 92f599b75123280d0ef17f00a1717f0ca89a19f8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Aug 24 22:20:56 2019 +0200
+
+    [basic.def] Move rule on template definition here
+
+    from its original location in [temp] p3.
+
+commit ee7b223aad941219d583b4a6cbf058abb740d63f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Sep 3 14:50:19 2019 +0100
+
+    [span.syn] Fix inconsistent class key in tuple_size/tuple_element (#3211)
+
+commit fad5d71d46953f73d50e4629671dc83022f53d38
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Sep 3 14:53:56 2019 +0100
+
+    [span.tuple] Simplify definition of get(span<T, I>) (#3210)
+
+commit c241ddeeb2fb2d4b9930ecc0fd84f12249953e12
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Sep 3 14:06:55 2019 -0700
+
+    [diff.cpp17] Add 'constinit' to one more list of new keywords in C++20.
+
+commit ab2ae01387d493148693ee5ae63e032eae3b0bb4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Sep 14 00:25:48 2019 +0200
+
+    [basic.stc.dynamic.safety] Avoid undefined term 'dynamic object'. (#3225)
+
+commit a9f6cedab5ea58cd74f809086accc2a7779a078c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Sep 14 00:40:05 2019 +0200
+
+    [temp.param] Define X in the example. (#3226)
+
+commit df69a5194d0903a8a2a574aeffd4a486d98d7122
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Sep 14 21:32:26 2019 +0200
+
+    [basic.stc.dynamic.safety] Fix ambiguous antecedent for 'it'. (#3228)
+
+commit af85c4c882efc554a99cf46cc0044b23ef7da322
+Author: onihusube <44743040+onihusube@users.noreply.github.com>
+Date:   Thu Sep 19 03:21:35 2019 +0900
+
+    [class.spaceship] Fix weak_ordering::equal to equivalent (#3220)
+
+commit e02bdecfb150dbd9f1086912317024d1c9d06cd7
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Sep 18 19:24:06 2019 +0100
+
+    [concepts.arithmetic] Fix notes that use undefined terms (#3223)
+
+    The terms "signed integral types" and "unsigned integral types" are not
+    defined in [basic.fundamental]. The notes are trying to talk about
+    signed/unsigned *integer* types. char and bool are not signed or
+    unsigned *integer* types, but they certainly are *integral* types, and
+    so they model one of signed_integral or unsigned_integral.
+
+commit 8fdd7d4307f1ea0ecf1af00503142f46e23bd15f
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Sep 23 22:39:44 2019 -0700
+
+    [ostream.iterator] Correct typo (#3240)
+
+commit 7fc9efbdda5a7ff77dc28ea81f56f9479e471869
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Oct 1 12:23:55 2019 +0200
+
+    [meta] Harmonize ordering in descriptions. (#3166)
+
+commit 338edc433819e6d4fc7237f29ff372d223eda150
+Author: mordante <zar-rpg@xs4all.nl>
+Date:   Tue Oct 1 12:37:11 2019 +0200
+
+    [re.regex] Rename template parameters for "assign". (#3198)
+
+    basic_regex::assign uses template parameters `class string_traits' and
+    `class A' while similar places use `class ST' and `class SA'.
+
+commit 7f45b9e37b02c9f75b9d401ae77560468bd2df5c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Oct 1 13:20:08 2019 +0100
+
+    [list.ops] Fix misapplication of P1463R1, "!=" should be "==". (#3258)
+
+    Misapplication in 019baa941945c1c8529fcaa0288ed5e98944f7a4.
+
+    Also restore the edit "." -> ", and".
+
+commit d2cc230ad3795f6b367bfa60e6b2bac5a7644f69
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Oct 2 18:17:31 2019 +0200
+
+    [lib] Remove parameter names from deleted special member functions. (#3259)
+
+commit 17d48e05aed86d965f33efc75d73addf04e7d436
+Author: Casey Carter <cartec69@gmail.com>
+Date:   Fri Oct 4 01:13:07 2019 -0700
+
+    [span.iterators] Fix typo in paragraph 5 (#3276)
+
+    "Returns: Equivalent To:" is not a library wording form, but an obvious misspelling of "Effects: Equivalent to:".
+
+commit 311f57196dc94eebcba61799401fd20bebb27c62
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 4 19:20:57 2019 +0200
+
+    [concept.boolean] Avoid undefined phrase 'Boolean context'. (#3269)
+
+commit 8a13bc1a109a0b0672120da3fabec360bd6823ed
+Author: 江添亮 <boostcpp@gmail.com>
+Date:   Sun Oct 6 12:18:14 2019 +0900
+
+    [rand] Use 1.0, not 1, as a literal of floating-point type
+
+commit 63427e429d11e40a9f2796459ff31b379354f7e1
+Author: frederick-vs-ja <de34@live.cn>
+Date:   Sat Jun 15 10:54:36 2019 +0800
+
+    [move.sent.ops] Add missing description of move_sentinel::base
+
+    Or add a section like `\rSec3[move.sent.ops.conv]{Conversion}` ?
+
+commit ecbe188a5fd7d889a602180c656bddc6a125149e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 8 00:14:33 2019 +0200
+
+    [std] Harmonize cross-references for explicit casts.
+
+commit 3cd1ef2343a3aa705c97157186abbfda890835bf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 8 21:37:49 2019 +0200
+
+    [tuple] Make descriptions of non-members siblings of [tuple.tuple].
+
+commit ed20772b95de38a927d17ec6c5afaed51cec5d39
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 8 21:53:52 2019 +0200
+
+    [thread.jthread.class] Rephrase introductory sentence.
+
+commit 997aa48537482815b4a1098e84496778a80884c2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Aug 9 21:34:57 2019 +0200
+
+    [std] Hyphenate floating-point and avoid 'floating'.
+
+commit d11e53e3ac075e72d373a92a4975d2ed55298fc3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Aug 10 09:18:30 2019 +0200
+
+    [std] Rename 'floating literal' to 'floating-point literal'.
+
+commit 4455bf4c5694d1fc09eaf68a75c370666467962a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Aug 20 22:04:30 2019 +0200
+
+    [temp.names] Remove misleading note.
+
+commit 37cc5affe2c52a3dde21ca38e3aa70afc756db9b
+Author: Dan Raviv <dan.raviv@gmail.com>
+Date:   Wed Aug 21 23:27:19 2019 +0300
+
+    [diff.library] Consistency for wide char types
+
+    [diff.char16] says `char16_t` and `char_32t`
+    > ...do not appear as *macro* names...
+
+    [diff.wchar.t] says `wchar_t`
+    > ...does not appear as a *type* name...
+
+commit 97977a1d742340d2198910912df3c511b8154afa
+Author: Dan Raviv <dan.raviv@gmail.com>
+Date:   Wed Aug 21 23:25:49 2019 +0300
+
+    [intro.compliance] Fix reference in footnote
+
+    It seems this footnote is supposed to point at [intro.abstract] which describes how the implementation's documentations also defines implementation-defined behavior; In the same way that the footnote in [intro.abstract] points into [intro.compliance] where it says that the documentation also includes things which are listed there.
+
+commit 94cf6f3a6408929088c546661094009ae921a725
+Author: Roger Orr <rogero@howzatt.demon.co.uk>
+Date:   Sat Aug 24 19:36:51 2019 +0100
+
+    [temp.param] Remove unused class template from example.
+
+commit 089b47bf447d5ef199380053d08b3c99734cd41c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Sep 4 00:15:56 2019 +0200
+
+    [lex.pptoken] Mention import keywords in the category list.
+
+commit 34cc4a7ce6155e75d1b5df0e9cea6d1e46cf790e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Sep 4 00:21:08 2019 +0200
+
+    [class.dtor] Group declaration properties vs. behavior.
+
+commit eaf23727c160e22a47f54419d5a66abfd672cc50
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Sep 5 21:22:41 2019 +0200
+
+    [thread.latch] Subordinate [latch.syn] and [thread.latch.class]
+
+commit 901b742c1caf74deab046599264e7d5c9862eb55
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Sep 14 00:43:55 2019 +0200
+
+    [dcl.spec.auto] Add example to show variable redeclaration with 'auto'.
+
+    CWG2389 Agreement of deduced and explicitly-specified variable types
+
+commit 219506555b1a943a94db546a5d68745e1a7de242
+Author: mordante <koraq@xs4all.nl>
+Date:   Sun Oct 6 07:06:26 2019 +0200
+
+    [re.regex] Use consistent names for function parameters
+
+commit e2c85a91953b0bd672960d0cf662c85ba1ba7470
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Sep 24 21:19:51 2019 +0200
+
+    [locale] Fix example.
+
+commit 081375e2d152beea2c246119bd2b2c6fa42d0954
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Sep 24 21:35:07 2019 +0200
+
+    [class.temporary] Fix typo in example.
+
+commit 37ca3fadf39edb7e6453515e386e6e6c7ae46d1e
+Author: Jason Cobb <jason.e.cobb@gmail.com>
+Date:   Tue Sep 24 21:30:00 2019 -0400
+
+    [expr.prim.id] Fix immediate function id-expression requirement
+
+    Move possibilities into a list, and add "only" after "appear".
+
+    Reason for being editorial: not intent to require all programs
+    to use an "id-expression that denotes an immediate function",
+    and moving the possiblities into a list does not change the meaning.
+
+commit 2845d903cb36f7567fcda36746cac95fc43f147a
+Author: Daveed Vandevoorde <daveed@vandevoorde.com>
+Date:   Wed Sep 25 11:43:19 2019 -0400
+
+    Avoid confusion between lookup and overall overload resolution
+
+commit e71fce40a3eded0d9ff573eb41b9b1e33ce3d883
+Author: Krystian Stasiowski <sdkrystian@gmail.com>
+Date:   Sun Oct 6 01:21:02 2019 -0400
+
+    [temp.alias] Change type-id to defining-type-id in the running text
+
+     to match the portion of the grammar that it's referring to.
+
+commit b04e94bba0c7998920bd09c6cc462ccda93efaa4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 27 09:42:25 2019 +0200
+
+    [std] Introduce 'Preamble' sections to avoid hanging paragraphs.
+
+commit c3b2c86e5e218ee6e80bd170eae653a6ad0d4047
+Author: frederick-vs-ja <de34@live.cn>
+Date:   Sun Oct 6 13:23:04 2019 +0800
+
+    [class.copy.elision] Update example to match resolution of CWG 2278
+
+commit 5fe6230c72e29a8595cc8f66ba149a560282ec3e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 3 00:07:58 2019 +0200
+
+    [expr.typeid] Add note highlighting prohibition of bad function types.
+
+    Function types that can only be used for member functions
+    (because they have cv-qualifiers or a ref-qualifier)
+    cannot appear as a typeid operand.
+
+commit 599635d72caf3a9c768f5137f0bc19765ab4db2e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 3 09:39:14 2019 +0200
+
+    [atomics] Reorder members of atomic, atomic_ref, atomic_flag
+
+    for a more conventional and meaningful order.
+
+commit ca09b84c8dcd0d7d0b15923a28b1be6692ccf37d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 3 15:01:05 2019 +0200
+
+    [expr.const] Excise 'initialization full-expression'
+
+    which is an undefined term. Instead, use 'full-expression
+    of the initialization'.
+
+commit d0a0da6bdb2ff02175d4c01bf60fb3274e37f5ee
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 3 15:07:56 2019 +0200
+
+    [atomics.ref.ops] Rename stable label from .operations
+
+commit 97a85b438144ba083301ce234da27f028c5a7e97
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 3 15:11:30 2019 +0200
+
+    [basic.def.odr] Replace misleading 'for which' with 'where'.
+
+commit 1327a34586617c26c48e615316f243b0ebf9d6d9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 3 15:25:33 2019 +0200
+
+    [support.srcloc] Canonicalize presentation.
+
+    - Avoid hanging paragraph.
+    - Rename label [source_location.syn] to [source.location.syn].
+    - Add automated check for clean labels.
+    - Separate header synopsis from class synopsis.
+
+commit 7724f6d359e72a981206c312c9d42903e988d1bd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 4 19:10:06 2019 +0200
+
+    [class.mem] Avoid 'shall have been defined'
+
+    when describing implicit definitions of defaulted
+    special member functions.  Instead, use plain 'are'.
+
+commit 8685db27c43a5b41c0682318c07a00906fe6c7d1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 15 10:25:22 2019 +0200
+
+    [locale.numpunct,locale.moneypunct] Canonicalize local grammar presentation.
+
+    In [locale.numpunct], rename the 'integer' non-terminal
+    to 'intval', consistent with 'floatval'.
+    Also remove the superfluous 'plusminus' non-terminal.
+
+commit 03dd1b8abfe921d4e6b643cd109310c03801cbfb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 13 23:43:15 2019 +0200
+
+    [over.match.funcs] Remove bullet for single-item bulleted list.
+
+commit d0e718b6a514a22118367a815107281a9a24c805
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 28 22:33:54 2019 +0200
+
+    [std] Consistently use 'immediately-declared constraint'.
+
+    Harmonize the phrasing in [expr.prim.req.compound],
+    [dcl.type.auto.deduct], [temp], and [temp.param].
+
+commit 2c2b29248d04dc0ce3c22a74a9537c0582c36ee2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 8 22:06:21 2019 +0200
+
+    [version.syn] Add synopsis for <version> header.
+
+    This replaces the table of feature-test macros for the library.
+
+commit e9fb3f03f05e48aa02d36ee42305f00bc056356b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 7 21:11:30 2019 +0200
+
+    [rand.predef] Add digit separators to large numbers.
+
+commit 7edac42a3b64406242c0c71b62264e05eab7e1a3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 7 22:24:16 2019 +0200
+
+    [intro.defs] Hyphenate parameter-type-list.
+
+commit d8935d972ee4f07f4507eea55df209ab7b1a508d
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Tue Oct 8 09:25:11 2019 -0400
+
+    [expr.const] drop unused declaration from example
+
diff --git a/papers/n4836.md b/papers/n4836.md new file mode 100644 index 0000000000..971f653df8 --- /dev/null +++ b/papers/n4836.md @@ -0,0 +1,487 @@ +# N4836 Editors' Report -- Programming Languages -- C++ + +2019-10-08 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4835](http://wg21.link/n4835) is the current C++ working draft. It replaces [N4830](http://wg21.link/n4830). + * N4836 is this Editors' Report. + +## Motions incorporated into working draft + +Fixed application of [P1643R1](http://wg21.link/p1643r1) (2019-07 LWG Motion 9): +two added paragraphs should have been labeled *Effects:* instead of *Expects:*. + +Fixed application of [P1463R1](http://wg21.link/p1463r1) (2019-03 LWG Motion 10): +an added `!=` in [list.ops] has been replaced with the correct `==`. + +## Notable editorial changes + +### Improved indices + + * The index of library headers now shows the location of the header synopsis in boldface. + * An index presenting all concept names (including exposition-only concepts) was added. + * The main index and the index of library names now show subdivisions per letter. + +### Changes to section labels + + * [source_location.syn] -> [source.location.syn] + * [atomics.ref.operations] -> [atomics.ref.ops] + +Several "Preamble" sections were added to avoid hanging paragraphs. + +### Feature test macros + +An explicit synopsis for the `` header has been added. +This synopsis describes the complete set of library feature test macros +and replaces the prior use of a table for this purpose. +For wording papers, we will continue to accept instructions of the form +"Add a feature test macro `__cpp_lib_blah` with a suitable value"; +explicit lists of edits to [version.syn] are also acceptable. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4830 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/n4830...n4835). + + commit 4fe8325ff6cf63055f9d064ba1b4f24614863649 + Author: S. B. Tam + Date: Tue Aug 20 05:14:29 2019 +0800 + + [thread.jthread.class] fix typos (#3183) + + commit aaea74e8dcfa456043ec315511463fb6d4a80108 + Author: David Olsen + Date: Mon Aug 19 14:17:33 2019 -0700 + + [atomics.ref.operations] Change Expects to Effects for atomic_ref::notify_{one,all} (#3180) + + Fix an editorial issue that resulted from an incorrect merge. In the + description of atomic_ref::notify_one and atomic_ref::notify_all in + [atomics.ref.operations] p25 and p27, N4830 has "Expects" in both of + those paragraphs. But the paper that was merged in, P1643R1 + ( http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1643r1.html ) + has "Effects". "Effects" is correct, and it matches notify_one and + notify_all in the four other atomics-related classes. + + commit 538f7c69f1423551628fdc638e8c4654bf1c7662 + Author: Eelis + Date: Mon Aug 19 23:20:53 2019 +0200 + + [std] Add/fix periods at end of sentences. (#3177) + + commit 600f1c0d1e94b0b6198c99516a95ec5ba439237a + Author: Eelis + Date: Mon Aug 19 23:22:26 2019 +0200 + + [std] Use consistent punctuation to terminate non-final list items. (#3175) + + commit fc240342df42f090563ed09c991c01925f1f4f27 + Author: Jens Maurer + Date: Mon Aug 19 23:31:56 2019 +0200 + + [tuple.elem] Canonicalize comments in example. (#3161) + + commit 221f1062d929688811aaa96c9752b54443ba29db + Author: Dan Raviv + Date: Fri Aug 23 10:00:40 2019 +0300 + + [lex.key,diff.header.iso646.h] Consistent tokens order (#3190) + + Order the alternative tokens in [diff.header.iso646.h] in the same way + they are ordered in Table 6 in [lex.key]. + + commit 92f599b75123280d0ef17f00a1717f0ca89a19f8 + Author: Jens Maurer + Date: Sat Aug 24 22:20:56 2019 +0200 + + [basic.def] Move rule on template definition here + + from its original location in [temp] p3. + + commit ee7b223aad941219d583b4a6cbf058abb740d63f + Author: Jonathan Wakely + Date: Tue Sep 3 14:50:19 2019 +0100 + + [span.syn] Fix inconsistent class key in tuple_size/tuple_element (#3211) + + commit fad5d71d46953f73d50e4629671dc83022f53d38 + Author: Jonathan Wakely + Date: Tue Sep 3 14:53:56 2019 +0100 + + [span.tuple] Simplify definition of get(span) (#3210) + + commit c241ddeeb2fb2d4b9930ecc0fd84f12249953e12 + Author: Richard Smith + Date: Tue Sep 3 14:06:55 2019 -0700 + + [diff.cpp17] Add 'constinit' to one more list of new keywords in C++20. + + commit ab2ae01387d493148693ee5ae63e032eae3b0bb4 + Author: Jens Maurer + Date: Sat Sep 14 00:25:48 2019 +0200 + + [basic.stc.dynamic.safety] Avoid undefined term 'dynamic object'. (#3225) + + commit a9f6cedab5ea58cd74f809086accc2a7779a078c + Author: Jens Maurer + Date: Sat Sep 14 00:40:05 2019 +0200 + + [temp.param] Define X in the example. (#3226) + + commit df69a5194d0903a8a2a574aeffd4a486d98d7122 + Author: Jens Maurer + Date: Sat Sep 14 21:32:26 2019 +0200 + + [basic.stc.dynamic.safety] Fix ambiguous antecedent for 'it'. (#3228) + + commit af85c4c882efc554a99cf46cc0044b23ef7da322 + Author: onihusube <44743040+onihusube@users.noreply.github.com> + Date: Thu Sep 19 03:21:35 2019 +0900 + + [class.spaceship] Fix weak_ordering::equal to equivalent (#3220) + + commit e02bdecfb150dbd9f1086912317024d1c9d06cd7 + Author: Jonathan Wakely + Date: Wed Sep 18 19:24:06 2019 +0100 + + [concepts.arithmetic] Fix notes that use undefined terms (#3223) + + The terms "signed integral types" and "unsigned integral types" are not + defined in [basic.fundamental]. The notes are trying to talk about + signed/unsigned *integer* types. char and bool are not signed or + unsigned *integer* types, but they certainly are *integral* types, and + so they model one of signed_integral or unsigned_integral. + + commit 8fdd7d4307f1ea0ecf1af00503142f46e23bd15f + Author: Casey Carter + Date: Mon Sep 23 22:39:44 2019 -0700 + + [ostream.iterator] Correct typo (#3240) + + commit 7fc9efbdda5a7ff77dc28ea81f56f9479e471869 + Author: Jens Maurer + Date: Tue Oct 1 12:23:55 2019 +0200 + + [meta] Harmonize ordering in descriptions. (#3166) + + commit 338edc433819e6d4fc7237f29ff372d223eda150 + Author: mordante + Date: Tue Oct 1 12:37:11 2019 +0200 + + [re.regex] Rename template parameters for "assign". (#3198) + + basic_regex::assign uses template parameters `class string_traits' and + `class A' while similar places use `class ST' and `class SA'. + + commit 7f45b9e37b02c9f75b9d401ae77560468bd2df5c + Author: Thomas Köppe + Date: Tue Oct 1 13:20:08 2019 +0100 + + [list.ops] Fix misapplication of P1463R1, "!=" should be "==". (#3258) + + Misapplication in 019baa941945c1c8529fcaa0288ed5e98944f7a4. + + Also restore the edit "." -> ", and". + + commit d2cc230ad3795f6b367bfa60e6b2bac5a7644f69 + Author: Jens Maurer + Date: Wed Oct 2 18:17:31 2019 +0200 + + [lib] Remove parameter names from deleted special member functions. (#3259) + + commit 17d48e05aed86d965f33efc75d73addf04e7d436 + Author: Casey Carter + Date: Fri Oct 4 01:13:07 2019 -0700 + + [span.iterators] Fix typo in paragraph 5 (#3276) + + "Returns: Equivalent To:" is not a library wording form, but an obvious misspelling of "Effects: Equivalent to:". + + commit 311f57196dc94eebcba61799401fd20bebb27c62 + Author: Jens Maurer + Date: Fri Oct 4 19:20:57 2019 +0200 + + [concept.boolean] Avoid undefined phrase 'Boolean context'. (#3269) + + commit 8a13bc1a109a0b0672120da3fabec360bd6823ed + Author: 江添亮 + Date: Sun Oct 6 12:18:14 2019 +0900 + + [rand] Use 1.0, not 1, as a literal of floating-point type + + commit 63427e429d11e40a9f2796459ff31b379354f7e1 + Author: frederick-vs-ja + Date: Sat Jun 15 10:54:36 2019 +0800 + + [move.sent.ops] Add missing description of move_sentinel::base + + Or add a section like `\rSec3[move.sent.ops.conv]{Conversion}` ? + + commit ecbe188a5fd7d889a602180c656bddc6a125149e + Author: Jens Maurer + Date: Thu Aug 8 00:14:33 2019 +0200 + + [std] Harmonize cross-references for explicit casts. + + commit 3cd1ef2343a3aa705c97157186abbfda890835bf + Author: Jens Maurer + Date: Thu Aug 8 21:37:49 2019 +0200 + + [tuple] Make descriptions of non-members siblings of [tuple.tuple]. + + commit ed20772b95de38a927d17ec6c5afaed51cec5d39 + Author: Jens Maurer + Date: Thu Aug 8 21:53:52 2019 +0200 + + [thread.jthread.class] Rephrase introductory sentence. + + commit 997aa48537482815b4a1098e84496778a80884c2 + Author: Jens Maurer + Date: Fri Aug 9 21:34:57 2019 +0200 + + [std] Hyphenate floating-point and avoid 'floating'. + + commit d11e53e3ac075e72d373a92a4975d2ed55298fc3 + Author: Jens Maurer + Date: Sat Aug 10 09:18:30 2019 +0200 + + [std] Rename 'floating literal' to 'floating-point literal'. + + commit 4455bf4c5694d1fc09eaf68a75c370666467962a + Author: Jens Maurer + Date: Tue Aug 20 22:04:30 2019 +0200 + + [temp.names] Remove misleading note. + + commit 37cc5affe2c52a3dde21ca38e3aa70afc756db9b + Author: Dan Raviv + Date: Wed Aug 21 23:27:19 2019 +0300 + + [diff.library] Consistency for wide char types + + [diff.char16] says `char16_t` and `char_32t` + > ...do not appear as *macro* names... + + [diff.wchar.t] says `wchar_t` + > ...does not appear as a *type* name... + + commit 97977a1d742340d2198910912df3c511b8154afa + Author: Dan Raviv + Date: Wed Aug 21 23:25:49 2019 +0300 + + [intro.compliance] Fix reference in footnote + + It seems this footnote is supposed to point at [intro.abstract] which describes how the implementation's documentations also defines implementation-defined behavior; In the same way that the footnote in [intro.abstract] points into [intro.compliance] where it says that the documentation also includes things which are listed there. + + commit 94cf6f3a6408929088c546661094009ae921a725 + Author: Roger Orr + Date: Sat Aug 24 19:36:51 2019 +0100 + + [temp.param] Remove unused class template from example. + + commit 089b47bf447d5ef199380053d08b3c99734cd41c + Author: Jens Maurer + Date: Wed Sep 4 00:15:56 2019 +0200 + + [lex.pptoken] Mention import keywords in the category list. + + commit 34cc4a7ce6155e75d1b5df0e9cea6d1e46cf790e + Author: Jens Maurer + Date: Wed Sep 4 00:21:08 2019 +0200 + + [class.dtor] Group declaration properties vs. behavior. + + commit eaf23727c160e22a47f54419d5a66abfd672cc50 + Author: Jens Maurer + Date: Thu Sep 5 21:22:41 2019 +0200 + + [thread.latch] Subordinate [latch.syn] and [thread.latch.class] + + commit 901b742c1caf74deab046599264e7d5c9862eb55 + Author: Jens Maurer + Date: Sat Sep 14 00:43:55 2019 +0200 + + [dcl.spec.auto] Add example to show variable redeclaration with 'auto'. + + CWG2389 Agreement of deduced and explicitly-specified variable types + + commit 219506555b1a943a94db546a5d68745e1a7de242 + Author: mordante + Date: Sun Oct 6 07:06:26 2019 +0200 + + [re.regex] Use consistent names for function parameters + + commit e2c85a91953b0bd672960d0cf662c85ba1ba7470 + Author: Jens Maurer + Date: Tue Sep 24 21:19:51 2019 +0200 + + [locale] Fix example. + + commit 081375e2d152beea2c246119bd2b2c6fa42d0954 + Author: Jens Maurer + Date: Tue Sep 24 21:35:07 2019 +0200 + + [class.temporary] Fix typo in example. + + commit 37ca3fadf39edb7e6453515e386e6e6c7ae46d1e + Author: Jason Cobb + Date: Tue Sep 24 21:30:00 2019 -0400 + + [expr.prim.id] Fix immediate function id-expression requirement + + Move possibilities into a list, and add "only" after "appear". + + Reason for being editorial: not intent to require all programs + to use an "id-expression that denotes an immediate function", + and moving the possiblities into a list does not change the meaning. + + commit 2845d903cb36f7567fcda36746cac95fc43f147a + Author: Daveed Vandevoorde + Date: Wed Sep 25 11:43:19 2019 -0400 + + Avoid confusion between lookup and overall overload resolution + + commit e71fce40a3eded0d9ff573eb41b9b1e33ce3d883 + Author: Krystian Stasiowski + Date: Sun Oct 6 01:21:02 2019 -0400 + + [temp.alias] Change type-id to defining-type-id in the running text + + to match the portion of the grammar that it's referring to. + + commit b04e94bba0c7998920bd09c6cc462ccda93efaa4 + Author: Jens Maurer + Date: Fri Sep 27 09:42:25 2019 +0200 + + [std] Introduce 'Preamble' sections to avoid hanging paragraphs. + + commit c3b2c86e5e218ee6e80bd170eae653a6ad0d4047 + Author: frederick-vs-ja + Date: Sun Oct 6 13:23:04 2019 +0800 + + [class.copy.elision] Update example to match resolution of CWG 2278 + + commit 5fe6230c72e29a8595cc8f66ba149a560282ec3e + Author: Jens Maurer + Date: Thu Oct 3 00:07:58 2019 +0200 + + [expr.typeid] Add note highlighting prohibition of bad function types. + + Function types that can only be used for member functions + (because they have cv-qualifiers or a ref-qualifier) + cannot appear as a typeid operand. + + commit 599635d72caf3a9c768f5137f0bc19765ab4db2e + Author: Jens Maurer + Date: Thu Oct 3 09:39:14 2019 +0200 + + [atomics] Reorder members of atomic, atomic_ref, atomic_flag + + for a more conventional and meaningful order. + + commit ca09b84c8dcd0d7d0b15923a28b1be6692ccf37d + Author: Jens Maurer + Date: Thu Oct 3 15:01:05 2019 +0200 + + [expr.const] Excise 'initialization full-expression' + + which is an undefined term. Instead, use 'full-expression + of the initialization'. + + commit d0a0da6bdb2ff02175d4c01bf60fb3274e37f5ee + Author: Jens Maurer + Date: Thu Oct 3 15:07:56 2019 +0200 + + [atomics.ref.ops] Rename stable label from .operations + + commit 97a85b438144ba083301ce234da27f028c5a7e97 + Author: Jens Maurer + Date: Thu Oct 3 15:11:30 2019 +0200 + + [basic.def.odr] Replace misleading 'for which' with 'where'. + + commit 1327a34586617c26c48e615316f243b0ebf9d6d9 + Author: Jens Maurer + Date: Thu Oct 3 15:25:33 2019 +0200 + + [support.srcloc] Canonicalize presentation. + + - Avoid hanging paragraph. + - Rename label [source_location.syn] to [source.location.syn]. + - Add automated check for clean labels. + - Separate header synopsis from class synopsis. + + commit 7724f6d359e72a981206c312c9d42903e988d1bd + Author: Jens Maurer + Date: Fri Oct 4 19:10:06 2019 +0200 + + [class.mem] Avoid 'shall have been defined' + + when describing implicit definitions of defaulted + special member functions. Instead, use plain 'are'. + + commit 8685db27c43a5b41c0682318c07a00906fe6c7d1 + Author: Jens Maurer + Date: Thu Aug 15 10:25:22 2019 +0200 + + [locale.numpunct,locale.moneypunct] Canonicalize local grammar presentation. + + In [locale.numpunct], rename the 'integer' non-terminal + to 'intval', consistent with 'floatval'. + Also remove the superfluous 'plusminus' non-terminal. + + commit 03dd1b8abfe921d4e6b643cd109310c03801cbfb + Author: Jens Maurer + Date: Fri Sep 13 23:43:15 2019 +0200 + + [over.match.funcs] Remove bullet for single-item bulleted list. + + commit d0e718b6a514a22118367a815107281a9a24c805 + Author: Jens Maurer + Date: Tue May 28 22:33:54 2019 +0200 + + [std] Consistently use 'immediately-declared constraint'. + + Harmonize the phrasing in [expr.prim.req.compound], + [dcl.type.auto.deduct], [temp], and [temp.param]. + + commit 2c2b29248d04dc0ce3c22a74a9537c0582c36ee2 + Author: Jens Maurer + Date: Thu Aug 8 22:06:21 2019 +0200 + + [version.syn] Add synopsis for header. + + This replaces the table of feature-test macros for the library. + + commit e9fb3f03f05e48aa02d36ee42305f00bc056356b + Author: Jens Maurer + Date: Mon Oct 7 21:11:30 2019 +0200 + + [rand.predef] Add digit separators to large numbers. + + commit 7edac42a3b64406242c0c71b62264e05eab7e1a3 + Author: Jens Maurer + Date: Mon Oct 7 22:24:16 2019 +0200 + + [intro.defs] Hyphenate parameter-type-list. + + commit d8935d972ee4f07f4507eea55df209ab7b1a508d + Author: Sergey Zubkov + Date: Tue Oct 8 09:25:11 2019 -0400 + + [expr.const] drop unused declaration from example diff --git a/papers/n4843.md b/papers/n4843.md new file mode 100644 index 0000000000..d470098b2d --- /dev/null +++ b/papers/n4843.md @@ -0,0 +1,1590 @@ +# N4843 Editors' Report -- Programming Languages -- C++ + +2019-11-27 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Special thanks to +Marshall Clow, +Jeff Garland, +and +Daniel Sunderland +for providing LaTeX sources for the LWG "Mandating" papers. + +Special thanks to +Johel Ernesto Guerrero Peña +for reviewing the edits for many of the motions +and catching numerous issues. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4842](http://wg21.link/n4842) is the committee draft for C++20. It replaces [N4835](http://wg21.link/n4835). + * N4843 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p1969r0) for 4 issues in "ready" status applied: **(DR)** + + * [2280](http://wg21.link/cwg2280) Matching a usual deallocation function with placement `new` + * [2382](http://wg21.link/cwg2382) Array allocation overhead for non-allocating placement `new` + * [2416](http://wg21.link/cwg2416) Explicit specializations vs `constexpr` and `consteval` + * [2441](http://wg21.link/cwg2441) Inline function parameters + +CWG motion 2: [Core issue resolutions](http://wg21.link/p1968r0) for 18 issues in "tentatively ready" status applied, resolving 19 issues: **(DR)** + + * [1621](http://wg21.link/cwg1621) Member initializers in anonymous unions + * [2126](http://wg21.link/cwg2126) Lifetime-extended temporaries in constant expressions + * [2282](http://wg21.link/cwg2282) Consistency with mismatched aligned/non-over-aligned allocation/deallocation functions + * [2347](http://wg21.link/cwg2347) Passing short scoped enumerations to ellipsis + * [2374](http://wg21.link/cwg2374) Overly permissive specification of `enum` *direct-list-initialization* + * [2399](http://wg21.link/cwg2399) Unclear referent of “expression” in *assignment-expression* + * [2419](http://wg21.link/cwg2419) Loss of generality treating pointers to objects as one-element arrays + * [2422](http://wg21.link/cwg2422) Incorrect grammar for *deduction-guide* + * [2424](http://wg21.link/cwg2424) `constexpr` initialization requirements for variant members + * [2426](http://wg21.link/cwg2426) Reference to destructor that cannot be invoked + * [2427](http://wg21.link/cwg2427) Deprecation of volatile operands and unevaluated contexts + * [2429](http://wg21.link/cwg2429) Initialization of `thread_local` variables referenced by lambdas + * [2430](http://wg21.link/cwg2430) Completeness of return and parameter types of member functions + * [2431](http://wg21.link/cwg2431) Full-expressions and temporaries bound to references + * [2432](http://wg21.link/cwg2432) Return types for defaulted `<=>` + * [2433](http://wg21.link/cwg2433) Variable templates in the ODR + * [2437](http://wg21.link/cwg2437) Conversion of `std::strong_ordering` in a defaulted `operator<=>` + * [2439](http://wg21.link/cwg2439) Undefined term in definition of "usable in constant expressions" **resolved by CWG 2126** + * [2442](http://wg21.link/cwg2442) Incorrect requirement for default arguments + +CWG motion 3: [Core NB comment resolutions](http://wg21.link/p1971r0), resolving 17 NB comments: + + * NB RU 007: Relax pointer value / aliasing rules + * NB US 019: Update ISO 9899 document reference from C11 to C17 + * NB US 020: Update ISO 9899 document reference from C11 to C17 + * NB CA 038: Consider trailing *requires-clause*s for function identity + * NB US 042: Relax pointer value / aliasing rules **in P1971R1 this is incorrectly listed as US047** + * NB CZ 044: Allow constexpr `construct_at` / `destroy_at` for automatic storage duration + * NB US 052: Non-executed `return` statements in coroutines + * NB US 053: Mandate the return type for `return_void` and `return_value` to be `void` + * NB US 065: Apply Coroutines TS issue 24 from [P0664R8](http://wg21.link/p0664r8) + * NB GB 079: Add example for *private-module-fragment* **with editorial changes; see below** + * NB US 087: Header unit imports cannot be cyclic, either + * NB US 095: Equivalence of *requires-clause*s + * NB US 109: Non-templates may also have associated constraints + * NB CA 110: Associated constraints for non-template functions + * NB US 111: Constraint normalization and negation + * NB US 132: Macros from the command-line not exported by header units + * NB US 367: Instead of header inclusion, also permit header unit import + * NB CA 378: Remove constrained non-template functions + +CWG motion 4: [P1972R0 "US105 Check satisfaction of constraints for non-templates when forming pointer to function"](http://wg21.link/p1972r0), resolving 1 NB comment: + + * NB US 105: Check satisfaction of constraints for non-templates when forming pointer to function + +CWG motion 5: [P1975R0 "Fixing the wording of parenthesized aggregate-initialization"](http://wg21.link/p1975r0) + +CWG motion 6: [P1874R1 "Dynamic initialization order of non-local variables in modules"](http://wg21.link/p1874r1), resolving 1 NB comment: + + * NB US 082: Define order of initialization for globals in modules + +CWG motion 7: [P1946R0 "Allow defaulting comparisons by value"](http://wg21.link/p1946r0) + +CWG motion 8: [P1907R1 "Inconsistencies with non-type template parameters"](http://wg21.link/p1907r1), resolving 5 NB comments: **with changes; see below** + + * NB US 092: Array members should have strong structural equality + * NB US 093: Move definition of "strong structural equality" near its use in [temp.param] + * NB US 100: Reference types should not have strong structural equality + * NB US 102: Allow non-type template parameters of floating-point type + * NB US 114: Class types as non-type template arguments + +CWG motion 9: [P1979R0 "Resolution to US086"](http://wg21.link/p1979r0), resolving 1 NB comment: + + * NB US 086: Treatment of non-exported imports + +CWG motion 10: [P1980R0 "Declaration matching for non-dependent *requires-clause*s"](http://wg21.link/p1980r0), resolving 2 NB comments: + + * NB US 095: Equivalence of *requires-clause*s + * NB CA 096: Declaration matching for non-dependent *requires-clause*s + +### Library working group motions + +#### Issues + +LWG motion 1: [Library issue resolutions](http://wg21.link/p1917r0) for 27 issues in "Ready" and "Tentatively Ready" status, resolving 3 NB comments: + + * [3070](http://wg21.link/lwg3070) `path::lexically_relative` causes surprising results if a filename can also be a *root-name* + * [3103](http://wg21.link/lwg3103) Errors in taking subview of `span` should be ill-formed where possible + * [3149](http://wg21.link/lwg3149) `default_constructible` should require default initialization + * [3190](http://wg21.link/lwg3190) `std::allocator::allocate` sometimes returns too little storage + * [3218](http://wg21.link/lwg3218) Modifier for `%d` parse flag does not match POSIX and format specification + * [3221](http://wg21.link/lwg3221) Result of `year_month` arithmetic with `months` is ambiguous + * [3222](http://wg21.link/lwg3222) [P0574R1](http://wg21.link/p0574r1) introduced preconditions on non-existent parameters + * [3224](http://wg21.link/lwg3224) `zoned_time` constructor from `TimeZonePtr` does not specify initialization of `tp_` + * [3225](http://wg21.link/lwg3225) `zoned_time` converting constructor shall not be `noexcept` + * [3230](http://wg21.link/lwg3230) Format specifier `%y`/`%Y` is missing locale alternative versions + * [3231](http://wg21.link/lwg3231) year_month_day_last::day specification does not cover !ok() values + * [3232](http://wg21.link/lwg3232) Inconsistency in `zoned_time` deduction guides + * [3235](http://wg21.link/lwg3235) `parse` manipulator without abbreviation is not callable + * [3241](http://wg21.link/lwg3241) *chrono-spec* grammar ambiguity in [time.format] + * [3244](http://wg21.link/lwg3244) Constraints for `Source` in [fs.path.req] insufficiently constrainty + * [3245](http://wg21.link/lwg3245) Unnecessary restriction on `%p` parse specifier + * [3246](http://wg21.link/lwg3246) What are the constraints on the template parameter of `basic_format_arg`? + * [3253](http://wg21.link/lwg3253) `basic_syncbuf::basic_syncbuf()` should not be `explicit` + * [3256](http://wg21.link/lwg3256) Feature testing macro for `constexpr` algorithms + * [3257](http://wg21.link/lwg3257) Missing feature testing macro update from [P0858](http://wg21.link/p0858) + * [3259](http://wg21.link/lwg3259) The definition of constexpr iterators should be adjusted + * [3266](http://wg21.link/lwg3266) `to_chars(bool)` should be deleted + * [3272](http://wg21.link/lwg3272) `%I%p` should parse/format `duration` since midnight + * [3273](http://wg21.link/lwg3273) Specify `weekday_indexed` to range of [0, 7] + * [3274](http://wg21.link/lwg3274) Missing feature test macro for `` + * [3276](http://wg21.link/lwg3276) Class `split_view::outer_iterator::value_type` should inherit from `view_interface` + * [3277](http://wg21.link/lwg3277) Pre-increment on prvalues is not a requirement of `weakly_incrementable` + * NB GB 166: Feature-test macro for `span` **resolved by LWG 3274** + * NB US 261: Pre-increment on an rvalue iterator **resolved by LWG 3277** + * NB US 297: `split_view::iterator::value_type` should inherit from `view_interface` **resolved by LWG 3276** + +#### Papers + +LWG motion 2: [P1855R0 "Make `` freestanding"](http://wg21.link/p1855r0), resolving 6 NB comments: + * NB RU 009: Make `` a freestanding header + * NB FI 010: Make `` a freestanding header + * NB US 158: Ensure `` can be used as a freestanding header despite including `` + * NB US 159: Make `` a freestanding header + * NB GB 160: Make `` a freestanding header + * NB PL 161: Make `` a freestanding header + +LWG motion 3: [P1690R1 "Refinement proposal for P0919 heterogeneous lookup for unordered containers"](http://wg21.link/p1690r1), resolving 4 NB comments: + + * NB US 235: Heterogenous lookup using `Hash::transparent_key_equal` is problematic + * NB US 236: Novel heterogenous lookup is problematic + * NB PL 237: Novel heterogenous hash lookup is problematic + * NB US 238: Heterogenous lookup using `Hash::transparent_key_equal` is problematic + +LWG motion 4: [P1872R0 "`span` should have `size_type`, not `index_type`"](http://wg21.link/p1872r0), resolving 3 NB comments: + + * NB FR 240: Rename `span::index_type` to `span::size_type` + * NB PL 248: Rename `span::index_type` to `span::size_type` + * NB US 245: Rename `span::index_type` to `span::size_type` + +LWG motion 5: [P1965R0 "Hidden friends"](http://wg21.link/p1965r0), resolving 1 LWG issue and 1 NB comment: + + * [3239](http://wg21.link/lwg3239) Hidden friends should be specified more narrowly + * NB DE 165: Regular unqualified lookup of functions specified as friends + +LWG motion 6: [P1716R3 "`ranges` comparison algorithms are over-constrained"](http://wg21.link/p1716r3), resolving 4 NB comments: + + * NB GB 183: Adopt P1716 + * NB US 267: Ranges compare algorithms are over-constrained + * NB US 306: Relax constraints on ranges comparison algorithms + * NB PL 312: Fix constraints on ranges comparison algorithms + +LWG motion 7: [P1869R1 "Rename `condition_variable_any` interruptible wait methods"](http://wg21.link/p1869r1), resolving 1 NB comment: + + * NB PL 363: `wait_until` has misleading naming + +LWG motion 8: [P1961R0 "Harmonizing the definitions of total order for pointers"](http://wg21.link/p1961r0), resolving 2 NB comments: + + * NB US 176: Harmonize definitions of total order for pointers + * NB US 220: Harmonize definitions of total order for pointers + +LWG motion 9: [P1878R1 "Constraining `readable` types"](http://wg21.link/p1878r1), resolving 1 LWG issue and 3 NB comments: + + * [3279](http://wg21.link/lwg3279) `shared_ptr&` does not not satisfy `readable` + * NB US 263: Make `shared_ptr&` satisfy `readable` + * NB US 264: Problems with `readable` concept + * NB US 268: `iter_swap` should be callable with rvalue iterators + +LWG motion 10: [P1871R1 "Concept traits should be named after concepts"](http://wg21.link/p1871r1), resolving 1 NB comment: + + * NB US 257: Avoid double negatives for ranges opt-in variable templates + +LWG motion 11: [P1456R1 "Move-only views"](http://wg21.link/p1456r1), resolving 2 NB comments: **with changes; see below** + + * NB GB 277: Conflict of `istream_view` and `view` requirements + * NB FR 281: Copyability of `view` + +LWG motion 12: [P1391R4 "Range constructor for `std::string_view`"](http://wg21.link/p1391r4), resolving 1 NB comment: + + * NB US 232: Make `string_view` constructible from contiguous character ranges + +LWG motion 13: [P1394R4 "Range constructor for `std::span`"](http://wg21.link/p1394r4), resolving 3 NB comments: + + * NB US 233: Integrate `span` constructors with range concepts + * NB US 246: `span` should be constructible from a contiguous range + * NB PL 251: `span` should be constructible from a contiguous range + +LWG motion 14 was withdrawn. + +LWG motion 15: [P1862R1 "Ranges adaptors for non-copyable iterators"](http://wg21.link/p1862r1) + +LWG motions 11 and 15 together resolve 1 NB comment: + + * NB GB 270: Collateral damage with move-only input iterators + +LWG motions 11-15 together resolve 2 NB comments: + + * NB US 272: API improvements for ranges + * NB DE 288: Overspecification of return types of view adaptors + +LWG motion 16: [P1870R1 "`forwarding-range` is too subtle"](http://wg21.link/p1870r1), resolving 2 NB comments: **with changes; see below** + + * NB US 279: Use variable template opt-in for *`forwarding-range`* + * NB GB 280: Rename *`forwarding-range`* to avoid near-clash with `forward_range` + +LWG motion 17: [P1865R1 "Add `max()` to `latch` and `barrier`"](http://wg21.link/p1865r1), resolving 1 NB comment: + + * NB US 365: For `latch` and `barrier`, do not require full range of `ptrdiff_t` + +LWG motion 18: [P1960R0 "NB comment changes reviewed by SG1"](http://wg21.link/p1960r0), resolving 5 NB comments: + + * NB US 355: Make `atomic_ref::notify_one` and `atomic_ref::notify_all` `const` + * NB US 356: Make `atomic_ref::is_lock_free` type-specific, not object-specifc + * NB US 358: Make `atomic_ref<`*float*`>::operator=` `const` + * NB US 359: Incorrect return value in specification of atomic increment / decrement + * NB US 364: Clarify spurious failure for `try_acquire` + +LWG motion 19: [P1902R1 "Missing feature-test macros 2017-2019"](http://wg21.link/p1902r1), resolving 6 NB comments: **with changes; see below** + + * NB FI 015: Missing feature-testing macros + * NB GB 146: Add a feature-test macro for concepts + * NB GB 147: Add a feature-test macro for `consteval` + * NB US 150: Add feature-test macro for "familiar template syntax for generic lambdas" + * NB US 167: Feature-test macro for non-member `ssize()` + * NB DE 168: Feature-test macros for `constexpr` + +LWG motion 20: [P0883R2 "Fixing atomic initialization"](http://wg21.link/p0883r2), resolving 1 LWG issue and 4 NB comments: + + * [2334](http://wg21.link/lwg2334) `atomic`'s default constructor requires "uninitialized" state even for types with non-trivial default-constructor + * NB RU 006: Adopt P0883 (value-initialize atomics by default) + * NB DE 018: Value-initialize atomics by default + * NB US 351: Value-initialize atomics by default + * NB CA 353: Value-initialize atomics by default + +LWG motion 21: [P1959R0 "Remove `std::weak_equality` and `std::strong_equality`"](http://wg21.link/p1959r0), resolving 2 NB comments: + + * NB US 170: Remove `strong_equality` and `weak_equality` + * NB CA 173: Remove `weak_equality` + +LWG motion 22: [P1892R1 "Extended locale-specific presentation specifiers for `std::format`"](http://wg21.link/p1892r1), resolving 1 NB comment: + + * NB GB 226: Make locale-dependent formats for `std::format()` congruent with default formatting + +LWG motion 23: [P1645R1 "`constexpr` for `` algorithms"](http://wg21.link/p1645r1), resolving 1 NB comment: + + * NB US 320: Make numeric algorithms `constexpr` + +#### Mandating + +LWG motion 24: [P1718R2 "Mandating the standard library: Clause 25 - Algorithms library"](http://wg21.link/p1718r2) + +LWG motion 25: [P1719R2 "Mandating the standard library: Clause 26 - Numerics library"](http://wg21.link/p1719r2) + +LWG motion 26: [P1686R2 "Mandating the standard library: Clause 27 - Time library"](http://wg21.link/p1686r2) + +LWG motion 27: [P1720R2 "Mandating the standard library: Clause 28 - Localization library"](http://wg21.link/p1720r2) + +LWG motion 28: [P1721R2 "Mandating the standard library: Clause 29 - Input/Output library"](http://wg21.link/p1721r2) + +LWG motion 29: [P1722R2 "Mandating the standard library: Clause 30 - Regular Expression library"](http://wg21.link/p1722r2) + +LWG motion 30: [P1723R2 "Mandating the standard library: Clause 31 - Atomics library"](http://wg21.link/p1723r2) + +LWG motion 31: [P1622R3 "Mandating the standard library: Clause 32 - Thread support library"](http://wg21.link/p1622r3) + +## Notable changes to papers as moved + +### CWG motion 3 + +The note added as part of the resolution of NB GB 079 was reworded editorially, +as described below in the list of editorial NB comment resolutions. + +### CWG motion 8 + +The following feature test macro changes were made for this paper, +after consultation with SG10: + +The feature test macro `__cpp_nontype_template_parameter_class` has been removed +to indicate that the feature added by [P0732R2](http://wg21.link/p0732r2) +is no longer present in the same form. + +The value of the feature test macro `__cpp_nontype_template_args` has been increased +to `201911L` to indicate support for [P1907R1](http://wg21.link/p1907r1). + +### LWG motion 11 + +The description of this paper specifies that: + +> each such `base()` member [of a range adaptor, that returns a copy of the underlying view] +> be replaced to by two overloads: +> a `const`-qualified overload that requires the type of the underlying view to model CopyConstructible, and +> a `&&`-qualified overload that extracts the underlying view from the adaptor + +but the wording changes omitted explicit editing instructions +to make these changes to the +`take_while_view`, `drop_view`, `drop_while_view` and `elements_view` +range adaptors, which were added by [P1035R7](http://wg21.link/p1035r7) +(2019-07 LWG Motion 23), after R0 of this paper was authored. + +Consistent with the proposal in the paper, +and after consulting the paper authors and the LWG chair, +the corresponding changes were also applied to +the additional range adaptors listed above. + +### LWG motion 16 + +This paper removed the exposition-only concept *`range-impl`*, +inlining it into its only remaining user, the `range` concept. +However, two uses of *`range-impl`* were left behind. +These have been updated and suitably adjusted +to refer to `range` instead. + +LWG motion 13 ([P1394R4](http://wg21.link/p1394r4)) +added a couple of new uses of +the exposition-only concept *`forwarding-range`*, +which was removed by this paper. +These uses have been replaced with `safe_range`. + +### LWG motion 19 + +Did not add the macro `__cpp_lib_atomic_ref`. +This macro already existed with the specified value. + +Did not change the value of the `__cpp_lib_chrono` macro. +The requested new value of this macro (`201803L`) +is actually lower than the current value +(`201907L`, not `201611L` as listed in [P1902R1](http://wg21.link/p1902r1)). +The chair of SG10 has confirmed that the request to change this macro's value +is an error. The pre-existing, higher value is retained. + +Did not change the value of the `__cpp_lib_ranges` macro. +The requested new value of this macro (`201907L`) +is lower than the value `201911L` introduced by +[P1716R3](http://wg21.link/po1716r3) (LWG motion 6). + +## Disposition of editorial NB comments on C++ 2020 CD1 + +Listed below are draft disposition for all comments that were +filed as editorial in the ISO 14882 CD (2019) NB comments. +Except where otherwise noted, these dispositions only represent the current +viewpoint of the Project Editor. + +US 021: Accepted, fixed in 50e55ce9. + + * Split index entries to "block (execution)" and "block (statement)". + * Also added the statement form to Clause 3, Terms and Definitions. + +GB 022: Accepted with modifications, fixed in 8cc6bd34. + + * The relevant change had already been made to [using.headers], + but this corresponding change was missed. + + * **Modified resolution:** + Added a cross-reference to [using.headers] instead of + the suggested cross-reference to [headers]. + +JP 023: Accepted, fixed in 868934f7. + +JP 030: No consensus for change. + + * The text immediately following the grammar makes it clear that + both lowercase `p` and uppercase `P` are permitted. + +US 031: No consensus for change. + + * The example appears to be valid as-is; + adding `!= 0` does not appear to serve any purpose. + +GB 032: Accepted, fixed in 84a1cd53. + +US 037: No consensus for change. + + * The proposed change is not editorial. + Forwarded to SG2 for consideration and rejected. + +FR 039: Accepted with modifications, fixed in 68a6dfef. + + * **Filed as technical**; SG2 concluded the wording is confusing, + already does what the comment requests + (except that ADL also finds friend declarations in a class + in the same conditions under which + member lookup would find member declarations in the class). + Recategorized as editorial to clarify the wording. + + * **Modified resolution:** + Definition of "interface" (of a module) inlined into its only use (and removed), + making it clear that [basic.lookup.argdep]/4.4 only finds exported declarations. + +JP 045: Accepted, fixed in d401794f. + + * This fixes a misapplication of the resolution of CWG 2381. + +US 047: Accepted with modifications, fixed in 785f689d. + + * **Modified resolution:** + Instead of removing the redundant sentence, it was converted into a note + and moved after the following sentence of which it is a consequence. + +US 052: Accepted, fixed by [P1971R0](http://wg21.link/p1971r0) (CWG motion 3). + + * The proposed change is not editorial. + Forwarded to CWG for consideration and accepted. + +JP 057: Accepted, fixed in a06b7a49. + +GB 078: Accepted, fixed in e3bb2eba. + + * Italicized references to *digit*s that intended to refer to the grammar production. + * Also made some nearby editorial improvements: + added cross-references and fixed an adjacent grammar issue ("is" / "are") in [diff.cpp14.library]. + +GB 079: Accepted, fixed by [P1971R0](http://wg21.link/p1971r0) (CWG motion 3). + + * Forwarded to SG2 for consideration. Accepted and example added by CWG. + * Added note prior to example editorially revised after consultation with CWG. + +US 085: No consensus for change. + + * Per the description in [module.import], + translation units are imported, modules are not. + The wording appears to be correct as-is. + +US 088: Accepted with modifications, fixed in d382ea4e. + + * **Modified resolution:** + Instead of either of the proposed renamings, + renamed [module.global] to [module.global.frag] and + renamed [cpp.glob.frag] to [cpp.global.frag]. + +GB 089: Accepted, fixed in fa42d5a6. + +US 099: Accepted, fixed in 9b0502bf. + +US 106: No consensus for change. + + * Forwarded to CWG for consideration and rejected. + +US 108: Accepted, fixed in 2f42a930. + +US 153: No consensus for change. + + * Forwarded to LWG for consideration; rejected by LEWG. + +US 154: Duplicate of US 153. + +GB 155: Accepted, fixed in 98e57ff5. + + * **LWG concurs with this direction** + +JP 177: Accepted, fixed in 8be40ff0. + + * Replaces a reference to ISO/IEC/IEEE 60599 with a reference to the intended ISO/IEC/IEEE 60559. + * IEC 60599 is "Mineral oil-filled electrical equipment in service -- + guidance on the interpretation of dissolved and free gases analysis" + * ISO/IEC/IEEE 60559 is "Information Technology - Microprocessor Systems -- + Floating-Point Arithmetic" + +GB 200: No consensus for change. + + * The example already includes all combinations of `const`/non-`const` LHS and RHS, + as described by paragraph 6. + The suggested combinations `b == d` and `a == c` are both identical to `a == d`. + (Note that only `a` and `c` are used on the LHS, + and only `b` and `d` are used on the RHS.) + +US 216: Accepted, fixed in dfcc4691. + + * **LWG concurs with this direction** + +JP 218: **Unresolved, reassigned to LWG** + + * Forwarded to LWG for consideration; + [LWG issue 3310](https://cplusplus.github.io/LWG/issue3310) opened to track this comment. + +JP 219: **Unresolved, reassigned to LWG** + + * Forwarded to LWG for consideration; + [LWG issue 3310](https://cplusplus.github.io/LWG/issue3310) opened to track this comment. + +GB 225: **Unresolved, reassigned to LWG** + + * Proposed change is not editorial. Forwarded to LWG for consideration. + [LWG issue 3327](https://cplusplus.github.io/LWG/issue3327) opened to track this comment. + +US 242: No consensus for change. + + * Organizationally, it seems more consistent to list `span` near the + sequence containers, just as we list `string_view` near `string. + + * Forwarded to LWG for consideration and rejected. + +US 258: Accepted, fixed in f36f871c. + +GB 280: Accepted, fixed by [P1870R1](http://wg21.link/p1870r1) (LWG motion 16). + + * Forwarded to LEWG to select a better name or reject, + LEWG selected `safe_range` as a replacement non-exposition-only concept name. + +US 295: Accepted with modifications, fixed in 53f0651e. + + * Instead of proposed change, incorporated the leading + "If `ref_is_glvalue` is `true`" into the bullets + and removed the bullet nesting + to clarify the meaning of the "Otherwise"s. + +JP 314: Accepted with modifications, fixed in 136312cf. + + * This is not an ISO "Terms and Definitions" Clause, + so the rules for such a Clause do not apply. + * **Modified resolution:** + Renamed subclause from "Terms and Definitions" to "Preamble" + to make it clear that this is not an ISO "Terms and Definitions" Clause. + Also moved [algorithms.parallel] paragraph 1 into this subclause + to avoid a hanging paragraph. + +JP 319: Accepted, fixed in 5ac298cc. + +US 325: No consensus for change. + + * We do not wish to perform this reorganization at this stage, + but will reconsider the organization of the standard library clauses + for a future standard. + +US 327: **Unresolved, reassigned to LEWG** + + * The proposed change is not editorial. + Forwarded to LEWG for consideration. + * Duplicate of PL 326, which may be addressed by [P1956](http://wg21.link/p1956). + +US 328: **Unresolved, reassigned to LEWG** + + * The proposed change is not editorial. + Forwarded to LEWG for consideration. + * Duplicate of PL 326, which may be addressed by [P1956](http://wg21.link/p1956). + +US 330: No consensus for change. + + * The wording to which this comment is objecting + was removed by [P1355R2](http://wg21.link/p1355r2), + which was adopted by 2019-07 LWG Motion 2. + +JP 338: Accepted, fixed in 742f1086. + +JP 339: Accepted, fixed in 25a08918. + +JP 340: Accepted, fixed in f88f6747. + +JP 341: Accepted, fixed in d545c37d. + +JP 343: Accepted, fixed in 9252441e. + +JP 348: Accepted, fixed in 01dea5f5. + + * Per [iosfwd.syn]p1, the duplication of default template arguments + between `` and `` + does not prevent a translation unit including both. + * An LWG issue will be opened to consider + whether we should require more of the iostreams headers to include ``; + currently only `` and `` are guaranteed to provide the forward declarations. + Similarly LWG should consider whether `` and `` should + be guaranteed to include ``. + +JP 349: Accepted, fixed in adcf12ea. + + * See JP 348. + +JP 350: Accepted, fixed in 53b429c9. + + * See JP 348. + +US 357: Accepted with modifications, fixed in af747d64. + + * **Modified resolution:** + A different revised wording was chosen for the notes: + "The specialization `atomic` uses the primary template." + +US 359: Accepted, fixed by [P1960R0](http://wg21.link/p1960r0) (LWG motion 18). + + * Forwarded to SG1 for consideration and accepted by LWG. + +JP 362: Accepted with modifications, fixed in 195d5bab. + + * **Modified resolution:** + In addition to adding the missing `[[nodiscard]]`, + also added the missing `static` and `int` from the synopsis. + +CA 366: Accepted, fixed in eaf23727. + +JP 373: Accepted with modifications, fixed in 41058d90. + + * **Modified resolution:** In addition to requested changes, + also added cross-reference to [temp.pre] + for the *requires-clause* grammar production. + +JP 374: Accepted, fixed in dbc3d6a5. + +JP 376: Accepted, fixed in 8b5c768e. + +### Late comments + +CH 02: Accepted, fixed in 5ee93fd7. + +## Notable editorial changes + +### Typeface + +The typeface used for grammar productions has been changed +from italic to a slanted sans-serif font +in order to distinguish grammar productions +from defined terms. +Many other options have been considered, +but this option provided the most visually appealing outcome. + +Please inform the editors if you discover +any places where the wrong typeface is used +for a grammar production or other italicized term. + +### Section moves + +Moved [temp.deduct.guide] under [temp.class], +alongside the description of members of class templates. + +Moved [range.istream] under [range.factories]. +`basic_istream_view` is a range factory not a range adaptor. + +### Section label changes + + * [module.global] -> [module.global.frag] + * [cpp.glob.frag] -> [cpp.global.frag] + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4835 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/n4835...n4842). + + commit 8a4e51ea8270705e747383c7e7d0513228d94e94 + Author: Jens Maurer + Date: Thu Oct 10 22:49:36 2019 +0200 + + [basic.lval] Adjust cross-reference in the note. (#3288) + + commit 6af984eaa62b63e60dd34d6a609807a85f4c8d36 + Author: Jens Maurer + Date: Thu Oct 10 22:30:19 2019 +0200 + + [over.binary] Define 'comparison operator function' and related terms + + and use them consistently. + + commit 29c5bda6e44e3742109f6f2af415caa8c198619c + Author: Casey Carter + Date: Fri Oct 11 14:13:29 2019 -0700 + + [set.symmetric.difference] Strike duplicated sentence from paragraph 2 (#3293) + + commit 5ac298cc18601a4da82a25f9ed3c3dd8e24021d9 + Author: Casey Carter + Date: Fri Oct 11 14:14:33 2019 -0700 + + [alg.min.max] Correct errors in paragraph 22 (#3292) + + ...from incorporation of P0896R4. + + commit 767f7a885ef28e9a1c66d1b90cb344296eefebc4 + Author: Jonathan Wakely + Date: Sat Oct 12 08:26:49 2019 +0100 + + [readable.traits] Add template argument list to constrained specialization (#3294) + + commit bfff83e94a1d66abcd90b813a4c0d31c1e637cf9 + Author: Jonathan Wakely + Date: Wed Oct 16 20:14:54 2019 +0100 + + [range.subrange.access] Fix typo (#3299) + + commit f741def78c391a329bc694733c4fb8626457886e + Author: Jonathan Wakely + Date: Wed Oct 16 20:16:27 2019 +0100 + + [iterator.concept.winc] Fix "extended integral type" (#3301) + + The term defined in [basic.fundamental] is "extended integer type". + + commit 723b75c03633b43c8c1dbe3b75d2e8f70a2f8fe0 + Author: Jens Maurer + Date: Wed Oct 16 21:46:29 2019 +0200 + + [class.dtor] Remove incorrect note about trivial vs. constexpr. (#3249) + + commit 242354653b6d8412c9ab5a9fd6e47eb3805e0e93 + Author: Jens Maurer + Date: Fri Oct 18 22:04:27 2019 +0200 + + [time.cal.ymd.overview] Typo fix: comma at end of sentence. (#3304) + + commit 5a31c73501ef440d7f1e8414a8e59c64778f0433 + Author: Jens Maurer + Date: Fri Oct 18 22:29:19 2019 +0200 + + [time.zone.db.tzdb] Add missing '\pnum'. (#3305) + + commit 271360753f2a5b8f7701a007ebb1f240d95cccea + Author: Richard Smith + Date: Sat Oct 19 18:19:37 2019 -0700 + + [cmp.alg] Correct weak_ordering::equal to the intended + weak_ordering::equivalent. + + Also add some missing formatting. + + commit 9af3fc206fb538760af373b78d49f9658a0eeec8 + Author: Thomas Köppe + Date: Mon Oct 21 21:06:07 2019 +0100 + + [basic.scope.class] Reinstate a qualification that was lost in 0e26279b88c3b8b0a09babdeec8418d383f07419. + + Without the introductory sentence that was deleted by that commit, we need to say explicitly that we are talking about a declaration _in a class_. + + commit 22725b81fd2afc383aa793a740776024c33457a8 + Author: Krystian Stasiowski + Date: Tue Oct 22 04:46:48 2019 -0400 + + [class.access] Allocation order of data members is described in [expr.rel] (#3316) + + commit e4b690b6bafc31681b97b7d301e4ab25f881a185 + Author: Krystian Stasiowski + Date: Tue Oct 22 04:48:20 2019 -0400 + + [stmt.dcl] Vacuous initialization is defined in [basic.life] (#3314) + + commit 9f23d5cdd291492980bbd3a4cea6650a600c87f9 + Author: Casey Carter + Date: Thu Oct 24 00:19:56 2019 -0700 + + [multimap.modifiers] "Mandates" should be "Constraints" (#3322) + + Fixes an editorial error merging P1463R1. + + commit 868934f7330c1444d09451a50fac224e9ed2eb62 + Author: Jens Maurer + Date: Sat Oct 26 21:56:52 2019 +0200 + + [intro.structure] 'Note n to entry' is also a note. + + Fixes NB JP 23 (C++20 CD) + + commit 84a1cd53841535b72b798a7349cfc914b26eae91 + Author: Jens Maurer + Date: Sat Oct 26 21:16:11 2019 +0200 + + [basic.lookup.argdep] Add missing namespace qualification in example. + + Fixes NB GB 032 (C++20 CD) + + commit d401794faf9b136c7f85aa109afdd6d03a767c9a + Author: Jens Maurer + Date: Sat Oct 26 21:10:51 2019 +0200 + + [expr.type] Fix typo when using 'reference-related'. + + Fixes NB JP 045 (C++20 CD) + + commit fa42d5a6e20abe9e8aab3276202d4f23b31b782e + Author: Jens Maurer + Date: Fri Oct 25 22:04:25 2019 +0200 + + [module.reach] Clearly separate translation units in example. + + Fixes NB GB 089 (C++20 CD) + + commit 9b0502bf56cbfe4fe2b8407d1e2367613213080b + Author: Jens Maurer + Date: Sat Oct 26 15:58:21 2019 +0200 + + [temp.param] Strike redundant normative sentence. + + Non-type template parameters of non-reference non-class type are + prvalues, thus the usual reference initialization rules + create a temporary. + + Fixes NB US099 (C++20 CD) + + commit 8be40ff0693d5a09310c25a5fff6c14dcfc89717 + Author: Jens Maurer + Date: Fri Oct 25 21:56:34 2019 +0200 + + [cmp.alg] Fix typo for 'ISO/IEC/IEEE 60559'. + + Fixes NB JP 177 (C++20 CD) + + commit f36f871c3bc780c13a5ba5ef2b7952c45d6d4cf5 + Author: Jens Maurer + Date: Sat Oct 26 15:42:02 2019 +0200 + + [iterator.requirements.general] Define 'reachable from' to avoid confusion + + with 'reachable' used finding declarations in modules. + + Fixes NB US 258 (C++20 CD) + + commit 742f108675594d0c116eda7faa75ebf9637dbee2 + Author: Jens Maurer + Date: Sat Oct 26 10:51:40 2019 +0200 + + [time.cal.day.nonmembers] Fix return type of operator""d + + Fixes NB JP 338 (C++20 CD) + + commit 9252441e422b601301c20c93d6117f07d0e1128c + Author: Jens Maurer + Date: Sat Oct 26 10:52:56 2019 +0200 + + [time.cal.year.nonmembers] Fix return type of operator""y + + Fixes NB JP 343 (C++20 CD) + + commit d545c37d9306fe70d41ed24f93dc36b2728d0383 + Author: Jens Maurer + Date: Fri Oct 25 21:44:43 2019 +0200 + + [time.cal.month.members] Remove nested-name-specifier from declaration. + + Fixes NB JP 341 (C++20 CD) + + commit 25a089189834ab99c3150ff5fb2b3eb342d8a0e4 + Author: Jens Maurer + Date: Fri Oct 25 21:45:45 2019 +0200 + + [time.cal.month.members] Remove nested-name-specifier from declaration. + + Fixes NB JP 339 (C++20 CD) + + commit f88f6747eb11504bd8a811576a5375f86bf815cd + Author: Jens Maurer + Date: Fri Oct 25 21:46:33 2019 +0200 + + [time.cal.month.members] Remove nested-name-specifier from declaration. + + Fixes NB JP 340 (C++20 CD) + + commit 53b429c9fd826876c80b150d913986c815d69932 + Author: Jens Maurer + Date: Fri Oct 25 21:23:00 2019 +0200 + + [syncstream.osyncstream.overview] Add default template arguments for 'basic_osyncstream'. + + Fixes NB JP 350 (C++20 CD) + + commit adcf12ea4385a1e2fb122b078a36c38d956b57be + Author: Jens Maurer + Date: Fri Oct 25 21:25:34 2019 +0200 + + [syncstream.syncbuf.overview] Add default template arguments for 'basic_syncbuf'. + + Fixes NB JP 349 (C++20 CD) + + commit 01dea5f57681a079b6da91b872fe0ce68d261c5f + Author: Jens Maurer + Date: Fri Oct 25 21:27:50 2019 +0200 + + [syncstream.syn] Add default template arguments + + in the header synopsis for 'basic_syncbuf' and 'basic_osyncstream'. + + Fixes NB JP 348 (C++20 CD) + + commit 41058d905c1b232ee574f318f0ba9c8b747eaaac + Author: Jens Maurer + Date: Fri Oct 25 21:06:30 2019 +0200 + + [diff.cpp17.lex] Add cross-references for 'requires' keyword. + + Fixes NB JP 373 (C++20 CD) + + commit dbc3d6a57cbf3e3c281d77c5492ffdc418a42658 + Author: Jens Maurer + Date: Fri Oct 25 20:48:56 2019 +0200 + + [xrefdelta] Fix typo for 'fmtflags'. + + Fixes NB NL 374 (C++20 CD) + + commit 8b5c768e3fdcd5fbd99bdb501ca3a48e710737c3 + Author: Jens Maurer + Date: Fri Oct 25 20:54:29 2019 +0200 + + [depr.impldec] Fix cross-reference for 'deleted function'. + + Fixes NB JP 376 (C++20 CD) + + commit b421913edbb17ba66c1dc57caf5264a19cbb7668 + Author: Thomas Köppe + Date: Mon Oct 28 18:56:14 2019 +0000 + + [ios.members.static] Add "static" to declaration + + commit a06b7a497ef2950c07144e97ae0d5919c2dca5d9 + Author: Jens Maurer + Date: Tue Oct 29 12:31:36 2019 +0100 + + [dcl.list.init] Make spacing around & declarator operator locally consistent. (#3353) + + Fixes NB JP 057 (C++20 CD) + + commit d382ea4e94f9d2d99bb08936d13f5a90772a292e + Author: Jens Maurer + Date: Tue Oct 29 12:32:05 2019 +0100 + + [module.global,cpp.glob.frag] Rename labels to ...global.frag. (#3351) + + That is, rename [module.global] to [module.global.frag] + and [cpp.glob.frag] to [cpp.global.frag]. + + Fixes NB US 088 (C++20 CD) + + commit 136312cffd9014daa49afe907d2da45d3dd5dfe8 + Author: Jens Maurer + Date: Tue Oct 29 12:32:44 2019 +0100 + + [algorithms.parallel.defns] Rename to 'Preamble' (#3350) + + and avoid hanging paragraph in [algorithms.parallel] + by moving it here. + + Fixes NB JP 314 (C++20 CD) + + commit 195d5bab790c05c5f049c490b0af28fe1b94c22d + Author: Jens Maurer + Date: Tue Oct 29 12:36:56 2019 +0100 + + [thread.jthread.static] Repeat '[[nodiscard]]' from synopsis. (#3326) + + Fixes NB JP 362 (C++20 CD) + + commit af747d6426c77527c681a5d8dd9cb0a4d66cfbf0 + Author: Jens Maurer + Date: Sat Oct 26 11:12:26 2019 +0200 + + [atomics.ref.int,atomics.types.int] Clarify notes on atomic/_ref specializations. + + Fixes NB US 357 (C++20 CD) + + commit 785f689d314f45719ee7036b3d7420d7ed7b5ab2 + Author: Jens Maurer + Date: Sat Oct 26 20:41:34 2019 +0200 + + [expr.prim.id.unqual] Excise redundant special case for the type + + of the template parameter object. + + Fixes NB US 047 (C++20 CD) + + commit 2f42a9303a61a498294a21ce73e6513ec43be011 + Author: Jens Maurer + Date: Sat Oct 26 21:05:37 2019 +0200 + + [temp.constr.decl] Missing case when constraints are associated with a declaration. + + Fixes NB US 108 (C++20 CD) + + commit 50e55ce976e2c3ce02340dd034ea2f0c373f0f53 + Author: Jens Maurer + Date: Sat Oct 26 22:34:52 2019 +0200 + + [defns.block.stmt] Add definition of block as a compound statement. + + Also clean up index entries to differentiate + 'to block execution' from 'compound statement'. + + Fixes NB US 021 (C++20 CD) + + commit e3bb2eba678062aa433e49758fd5c1f99c2760a6 + Author: Jens Maurer + Date: Sun Oct 27 21:03:12 2019 +0100 + + [namespace.future,diff.cpp14.library] Properly refer to grammar 'digit' + + when defining reserved namespace names. + + Fixes NB GB 078 (C++20 CD) + + commit 8cc6bd34b1075d9e1ad4e8226fcffd56084a9396 + Author: Jens Maurer + Date: Thu Oct 31 01:08:46 2019 +0100 + + [intro.compliance] The standard library also offers header units. + + Fixes NB GB 022 (C++20 CD) + + commit f563f13c549f85a227d33100b17118acd2fae22b + Author: Casey Carter + Date: Wed Oct 30 17:53:51 2019 -0700 + + [range.join.iterator] Remove spurious paragraph number. (#3358) + + commit 53f0651e981ac5a1b22eedc16e0c3ba54a585f08 + Author: Jens Maurer + Date: Thu Oct 31 02:01:42 2019 +0100 + + [range.join.iterator] Clarify if ... otherwise ladder. + + Fixes NB US 295 (C++20 CD) + + commit 673d504e1b61c1a392aa9dea8318e66fb08744ae + Author: Jens Maurer + Date: Fri Nov 1 08:26:28 2019 +0100 + + [class.copy.assign] Remove semicolon in 'of the form' phrase. + + This improves consistency with other such phrases. + + Fixes late comment CH 02. + + commit 42eddb8cedc876bf0df4f9f7e0c28febec38454d + Author: Richard Smith + Date: Mon Oct 21 11:46:26 2019 -0700 + + [lex.key] Don't use a colon to introduce a floating table. + + This table floated off to a different page, so the colon pointed + nowhere. + + commit 2bb2cd92adf5f73f62c502a595528c52321852f8 + Author: Nikita Kniazev + Date: Mon Nov 4 22:50:05 2019 +0300 + + [basic.types] Replace macro constant with constexpr variable + + commit ee2879195da176ab31a841b8c5c833730d55b756 + Author: Sebastian <12844423+seb-mtl@users.noreply.github.com> + Date: Tue Nov 5 11:23:55 2019 -0500 + + [thread.jthread.class] close namespace in synopsis + + commit f8a564a086d539202f8811a0fe004eda6dc0ddbc + Author: Akira Takahashi + Date: Thu Nov 7 17:44:07 2019 +0900 + + [time.cal.day.nonmembers] Add missing closing brace to p6 (operator-) + + commit cff2b503ae97fa83529cb274fe12043510e0f1e9 + Author: Thomas Köppe + Date: Fri Nov 8 21:01:46 2019 +0000 + + [conv.rank] Fix cross-reference to expr.arith.conv (#3384) + + commit 68a6dfef6e0880c33193f68a5c035efc8cdf3e09 + Author: Jens Maurer + Date: Fri Nov 8 23:14:49 2019 +0100 + + [basic.lookup.argdep] Inline the definition of 'interface'. + + Fixes NB FR 039 (C++20 CD) + + commit 98e57ff591d2bd1d258074e06d51fe1cb3e7279d + Author: Thomas Köppe + Date: Fri Nov 8 21:57:42 2019 +0000 + + [macros, structure.specifications] Rename "Expects:"/"Ensures:" to "Preconditions:"/"Postconditions:" + + Also adjust a few hyphenation hints where needed. + + Fixes NB GB 155 (C++20 CD) + + commit dfcc469164f05145aa029a3d33a0ab8721ad0d2f + Author: Thomas Köppe + Date: Fri Nov 8 22:16:00 2019 +0000 + + [util.smartpr.atomic] Moves subclause from "Utilities" to "Atomics". + + Also renames several headings from "Atomic specializations ..." to + "Partial specializations ...", and adds a cross reference to [smartptr]. + + Fixes NB US 216 (C++20 CD) + + commit 4d1e9eb84636960724a5553101d578bc1683e702 + Author: S. B. Tam + Date: Mon Nov 11 18:20:16 2019 +0800 + + [structure.specifications] Rename remaining "Expects"/"Ensures" to "Preconditions"/"Postconditions" + + commit 7b08a8bac497cc297a38c925bc87a64dc79bde32 + Author: Casey Carter + Date: Tue Nov 12 11:24:18 2019 -0800 + + [iterator.concept.writable] Correct repeated word. (#3369) + + commit 81f1d689f51fe823d7f6faa659f03b2d787aebf6 + Author: Casey Carter + Date: Tue Nov 12 11:25:47 2019 -0800 + + [range.filter.overview] Avoid double-negative. (#3355) + + commit a6f1f0000d274b406900a462297160f6de3a6d55 + Author: Richard Smith + Date: Tue Nov 19 14:46:46 2019 -0800 + + [temp.expl.spec] There is no such thing as a "consteval property". + Rephrase to use the correct term "immediate function". + + commit 2ea2858eda939494fce400ea265965cce6b84e1e + Author: Richard Smith + Date: Tue Nov 19 14:51:00 2019 -0800 + + [dcl.inline] Move note that 'inline' doesn't affect linkage somewhere + more suitable. + + commit 7e730f899be7336a1d0c87a24a53167be7f834d6 + Author: Richard Smith + Date: Tue Nov 19 15:58:44 2019 -0800 + + [basic.compound] [numeric.ops.midpoint] Unify terminology used to + identify array elements. + + [expr.add] [expr.rel] [expr.eq] [numeric.ops.midpoint] Remove unused + name "x" from footnote. + + commit e9a3d1ddf21212a160c3b57aeec57acf8fe84c97 + Author: Richard Smith + Date: Tue Nov 19 17:32:07 2019 -0800 + + [expr.const] Fix wording confusion over "is a core constant expression" + versus "does not disqualify some other expression from being a core + constant expression". + + commit 19148dbc8e3a92148a5fb28bee62994998743605 + Author: Richard Smith + Date: Tue Nov 19 19:39:09 2019 -0800 + + [module.private.frag] Fix description of the private module fragment in + the note, and update the example to match a revised version from Nathan + Sidwell. + + commit 88b87a2f54e44501d84385d1f07d6cdc6b3f4857 + Author: Dawn Perchik + Date: Mon Nov 18 14:34:28 2019 -0800 + + [temp.constr.op] Reword comment in example added for US111 as suggested by Casey + + commit 818e377c13b4b2cc80b292310aba2430538f0d56 + Author: Richard Smith + Date: Wed Nov 20 12:44:00 2019 -0800 + + [temp.constr.op] Stop talking about the programmer's intent being + unclear in a note; instead merely clarify the language's response + to the various options available to the programmer. + + commit b369c9229f9b3223c967ab00ccb1e54eafec6a7a + Author: Richard Smith + Date: Wed Nov 20 13:37:07 2019 -0800 + + [over.over] Extract the non-template function case from the description + of the target type and rearrange so that it better parallels the + function template specialization case. + + commit 6ec7eb80fcf30c44632bba59826e4f26c53688ee + Author: Richard Smith + Date: Tue Nov 12 19:11:20 2019 -0800 + + [temp.param] [temp.arg.nontype] Update examples and redundant duplicated + wording to match P1907R1. + + commit 0c61ad109ef8847f9bcaea4cb725537fda0ba99d + Author: Richard Smith + Date: Fri Nov 15 16:57:10 2019 -0800 + + [cpp.predefined] Bump value of __cpp_nontype_template_args to 201911L + for P1907R1, and remove __cpp_nontype_template_parameter_class to + indicate that the feature added by P0732R2 is no longer present in that + form. + + commit 7bf810a07f8223b57a0ab1d7eb5d9e82e99cdef7 + Author: Richard Smith + Date: Wed Nov 13 18:12:12 2019 -0800 + + [concept.equivalencerelation] Rename to [concept.equiv]. + + commit dde89d6d2a478b18351a4ba94a0523417fe05996 + Author: Jens Maurer + Date: Wed Nov 13 22:15:27 2019 +0100 + + [range.cmp] Avoid introducing unused 'P' + + commit 1dd384aad27415a1415ad9e81273141ce73a7ce2 + Author: Richard Smith + Date: Fri Nov 15 16:37:26 2019 -0800 + + [range.adaptors] Extend the changes from P1456R1 to also apply to + take_while_view, drop_view, drop_while_view, and elements_view. + + These are covered by the direction proposed in the paper, but were + inadvertently omitted from the list of things to change in the wording. + + commit 6d9db6ae5b3ece80558b95a519d939b58db67623 + Author: Richard Smith + Date: Wed Nov 20 17:52:31 2019 -0800 + + [range.view] Make the requirement for constant-time move operations and + destruction explicit in the description of when a type models view. + + commit de25e23ff5306c69fa74893824d8df7c03197429 + Author: Richard Smith + Date: Fri Nov 15 16:52:09 2019 -0800 + + [string.view] Shorten stable name [string.view.deduction] -> [string.view.deduct] + + Also replace commas with periods in lists of constraints. + + commit 6c4806f2704b758b8af506e4f24a4a0931cfdcdf + Author: Jens Maurer + Date: Thu Nov 14 10:01:08 2019 +0100 + + [span.cons] Rephrase constraint on input element type to avoid + overfull \hbox. + + commit 25738f733e5e720fc303effa73da391679750499 + Author: Jens Maurer + Date: Thu Nov 14 22:22:17 2019 +0100 + + [span.cons] Do not attempt to initialize size_ with an iterator. + + commit 39665f5324d82b92947d6594a04693e28faf7d81 + Author: Dawn Perchik + Date: Fri Nov 15 17:44:07 2019 -0800 + + [range.range] Fix example to clarify who/what is being specialized for/with/on what. + + commit bceff414a33f9ceed3a1823a885067a5d0ba6091 + Author: Richard Smith + Date: Sat Nov 23 17:57:05 2019 -0800 + + [range.range] [span.cons] Update remaining uses of removed + exposition-only concepts range-impl and forwarding-range with range and + safe_range as appropriate. + + commit e6428e59d58c1c2822c98a15605e2443552a5d35 + Author: Dawn Perchik + Date: Tue Nov 19 13:32:22 2019 -0800 + + [version.syn] Revert __cpp_lib_chrono back to 201907L as directed by @brevzin in #3476. + + commit af48b063f9618123d2890796ae9dc95e39fc92f9 + Author: Dawn Perchik + Date: Fri Nov 15 13:15:36 2019 -0800 + + [atomics.types.generic] Added reference to [atomics.types.operations] in synopsis + + commit ab483d487983af8c5ee0c2b25b9da40908f1ed9a + Author: Dawn Perchik + Date: Sat Nov 16 01:50:56 2019 -0800 + + [basic.compound] Fix the wording "A pointer to objects". + + commit ad91aa2b2b62305250e7667c53276c794e3eee8d + Author: Dawn Perchik + Date: Thu Nov 14 17:10:58 2019 -0800 + + [format.string.std] Use bullets to list the effects of the locale-specific form on each arithmetic type. + + commit dea4ded28cf7e315b728f3ad31f0af96f9ff58e8 + Author: Dawn Perchik + Date: Thu Nov 14 17:15:49 2019 -0800 + + [format.string.std] Provide a definition for the locale-specific form. + + commit d1d3793c1fa08eb4246ac8f218e7a949ae61e28b + Author: Richard Smith + Date: Fri Nov 22 20:51:26 2019 -0800 + + [format.string.std] 'decimal radix separator' -> 'radix separator'. + + The use of the word 'decimal' here is not intended to mean "only base + 10", and so serves only to confuse the reader. + + commit 411531100c0d3e922753935f30835e2cfded2ded + Author: Dawn Perchik + Date: Thu Nov 14 10:38:32 2019 -0800 + + [numeric.ops] Reformat itemdecl declarations to match the synopsis. + + commit 6c20c2b4cdfc304d58a093e2ce1f49944ac4e8da + Author: Richard Smith + Date: Sat Nov 16 01:51:16 2019 +0000 + + [rand.util.seedseq] Add cross-reference for "writable". + + Co-Authored-By: Johel Ernesto Guerrero Peña + + commit 6ceb2a6b7627d608bd5e4dde5ccd12da70fe20bb + Author: Richard Smith + Date: Mon Nov 18 16:29:30 2019 -0800 + + [time.clock.cast.fn] Fix inappropriate phrasing of "Mandates:" element. + + commit 938c089abd5a0516b18dd965a74a68ebd571b2dc + Author: Johel Ernesto Guerrero Peña + Date: Wed Nov 20 12:13:53 2019 -0800 + + [thread] Add missing _v's to uses of type traits in Mandates elements. + + commit dd294d43f074dd5f218aaa6e216afb1ce512a5ac + Author: Richard Smith + Date: Wed Nov 20 12:15:33 2019 -0800 + + [thread.req.timing] Remove "note" markers around note. + + This change was present in P1622R3 but the markup for the change was + missing. However, the change was requested by LWG and intended to be + made by this paper. + + commit ff9a0d2ce8ffb31b6a6a7321aaf7d6c2653b2029 + Author: Richard Smith + Date: Sat Nov 23 21:44:21 2019 -0800 + + [atomics.types.operations] Remove uses of deprecated ATOMIC_VAR_INIT + from examples. + + commit fc48c9b846c348a78eae1592d1c0f1aee1336008 + Author: Jens Maurer + Date: Sun Nov 24 23:04:53 2019 +0100 + + [dcl.decl] Avoid double negative. + + commit c16eb1cb7b104090f9cc41d6fd31ae5ed7fcb30e + Author: Eelis van der Weegen + Date: Sun Nov 24 14:30:28 2019 +0100 + + [complex.ops] Remove empty paragraph. + + commit abf6868cbdbcbe16fcd699c878e2533cbe4c800a + Author: Krystian Stasiowski + Date: Fri Nov 22 16:15:04 2019 -0500 + + [temp.local] Change "template-parameter" to "name of a template parameter" + + commit 739c4d48ed7a3b7d4f365e344cd178165dee2c2e + Author: Jens Maurer + Date: Thu Nov 21 23:36:54 2019 +0100 + + [lib] Replace 'this subclause' with numbered subclause references. + + commit bffe678f815d3dd241cc71ed5816074b80d2dfff + Author: Jens Maurer + Date: Thu Nov 21 21:29:32 2019 +0100 + + [lib] Remove 'Constructs an object of type ...' phrases + + for constructors; this effect is implied by the + core language. Only simple phrases are removed; + more complex sentence structures are left unchanged. + + commit ad5767e6057bb05d8bd185e3bb3bfb18eed87dc0 + Author: Jens Maurer + Date: Thu Nov 21 00:41:14 2019 +0100 + + [dcl.fct.def.coroutine] Use 'encloses' instead of imprecise 'contains'. + + The phrase 'the function-body encloses X' is also used + in [dcl.constexpr]. + + commit c1c6a1d1a402f421e70faf233256c36d43d05d95 + Author: Richard Smith + Date: Mon Nov 25 11:46:54 2019 -0800 + + [dcl.constexpr] Make cross-reference for "encloses" more precise. + + commit 1457b30569d1611af2e12e50ed481673042e0875 + Author: Richard Smith + Date: Mon Nov 25 12:04:35 2019 -0800 + + [dcl.type.elab] Make cross-references for "class" and "union" more precise. + + commit 129f699e50e3052ca65da1ff69776fa277f86ef5 + Author: Richard Smith + Date: Mon Nov 25 12:11:05 2019 -0800 + + [class.pre] [class.union] Clean up definition of 'union'. + + Move primary definition from [class.pre] to [class.union]. Add note to + [class.pre] specifying where to look for the meaning of the class-key. + Move note on aggregate classes from [class.pre] to [class.prop]. + + commit 02e9b5da556ff8c6476dbb9648e692266cf2bb22 + Author: Jens Maurer + Date: Wed Nov 20 23:54:35 2019 +0100 + + [any.cons,any.assign] Remove redundant postconndition for moves. + + [lib.types.movedfrom] already specifies that moved-from + objects are left in a valid but unspecified state. + + commit 19a66878a8c7ba122c06b5b14a43ec206b8f59bd + Author: Jens Maurer + Date: Wed Nov 20 21:46:19 2019 +0100 + + [temp.deduct.guide] Move into [temp.class]. + + Deduction guides apply only to class templates, so their + descriptions should be located in close proximity. + + commit 0ef6404655fb0d94b15cab11aef7bb5899d47a78 + Author: Jens Maurer + Date: Wed Nov 20 23:44:45 2019 +0100 + + [temp.concept] Move grammar non-terminal concept-definition here. + + Also move concept-name here, both from [temp.pre]. + + commit 0606c872e07ac3658ad32050d79449a7379c4e70 + Author: S. B. Tam + Date: Tue Nov 19 17:14:41 2019 +0800 + + [time.cal.wdidx.nonmembers] Remove extra " + + commit c64f4bd12c57e883bdb32ff69e00f2e3e26ed665 + Author: morinmorin + Date: Sun Nov 17 12:46:48 2019 +0900 + + [concept.regularinvocable] move iref to a better place + + commit 2ca40df7253fd4be7e730950e57159584bf7b5f6 + Author: Richard Smith + Date: Fri Nov 15 17:34:13 2019 -0800 + + [defns.access] Clarify definition of "access". + + Add cross-linking between the places that introduce accesses and the + definition of the term, and add a note explaining that we only ever + access objects of scalar type. + + commit 24f3e89e08993598a297ab00af5468ce81a2ec05 + Author: Casey Carter + Date: Fri Nov 15 17:06:23 2019 -0800 + + [range.istream] Relocate under [range.factories] + + Resolves #3468. + + commit 4bec8476c91d0c731dd19f637e76a34fdc9422fd + Author: Jens Maurer + Date: Fri Nov 15 22:08:46 2019 +0100 + + [format.arg] Fix parameter type for basic_format_arg constructor. + + commit 16972c271e418d2aaf9689e936fa5c61447c17e3 + Author: Kerdek + Date: Wed Nov 13 22:50:23 2019 -0500 + + [basic.life] Use idiomatic wording. + + Periods of construction and destruction are not referred to as phases anywhere else. + + commit 1586e4b48ca6b787c282c1731e738226068c8de9 + Author: Jens Maurer + Date: Sun Oct 20 21:57:20 2019 +0200 + + [numerics,input.output] Consistently use ios_base::failure. + + Do not refer to the inherited member in a derived class. + + commit f426cfbdbae8aed86273e3868ce7382e647926c0 + Author: Jens Maurer + Date: Sat Oct 19 22:17:34 2019 +0200 + + [std] Remove 'shall' from notes. + + Also update the automatic check script to prevent + future regressions. + + commit d26d3bd5c4fa6e9c2e7ecd2c00c5a6080c9ea4de + Author: Jens Maurer + Date: Wed Oct 16 23:27:10 2019 +0200 + + [std] Fix cross-references pointing to entire clauses now that we have 'preamble' sections. + + commit 02e41833de8737368fe1f31c19dfff468050012e + Author: Richard Smith + Date: Mon Nov 25 16:51:27 2019 -0800 + + [dcl.type.elab] Clarify that there is no expected correlation between + using 'class' or 'struct' in a class definition and using the same + keyword in an elaborated-type-specifier. + + commit 225cc43d7d92c7854cdb3726b951f96032e0f48b + Author: Arthur O'Dwyer + Date: Mon Sep 16 00:06:39 2019 -0600 + + [lib] Replace "shall not X" with "does not X" when it describes library behavior. + + In these places we aren't saying "it's UB if X happens"; we're literally + specifying the behavior of a library function as "X does not happen, + we promise." + + Jonathan Wakely points out that there is still room for the user to cause UB + by specializing `pair`, `duration`, `function`, etc. such that their specializations + do X. In that case, the UB happens due to [namespace.std] p2, which requires + that "the [program-defined] specialization meets the standard library requirements + for the original template." + + commit 035d46b4c40655e5f4f69f77e8c5a1106eab89bd + Author: Jens Maurer + Date: Wed Oct 16 21:37:17 2019 +0200 + + [time.duration.cast,time.point.cast] Rename subclause to 'Conversions'. + + The subclause describes functions beyond + duration_cast and time_point_cast. + + commit 029f630c324dc958b288e8bd2268ae7791a7089c + Author: Richard Smith + Date: Mon Mar 11 16:20:44 2019 -0700 + + [lex.charset] Fix various issues with the description of UCNs. + + Clarify that \U sequences not beginning 00 are ill-formed. Clarify + handling of code points naming reserved or noncharacter code points. + Remove unnecessary circumlocution through "short identifiers" by + directly talking about code points. Use code point values directly + rather than using C++ 0x notation. + + [lex.string] Fix description of what UCNs mean, and convert it to a + note. + + commit b5cd9909ffa2b0a44509aebabac7df8b92385298 + Author: Johel Ernesto Guerrero Peña + Date: Tue Nov 26 12:25:22 2019 -0400 + + [ranges.syn, range.adaptors] Name view template parameter V for consistency (#3514) + + P1035 used `R` for such template parameters, introducing an inconsistency. + + commit bddd47cb9ded922626b9930b5165af438dcd6c72 + Author: Jens Maurer + Date: Tue Nov 26 21:01:07 2019 +0100 + + [temp.param] Move grammar non-terminal 'type-constraint' here + + from [temp.pre]. + Also move the definition of 'immediately-declared + constraint' and fix all cross-references. + + commit 7e4a9fb3da65dbd04843c865e3ae6728063242a0 + Author: Jens Maurer + Date: Sun Nov 24 23:51:12 2019 +0100 + + [over.match.list] Acknowledge [over.ics.list] and clarify text. + + commit 782cad5e446a765aee1c674f4a316178185c5c19 + Author: Jens Maurer + Date: Fri Nov 15 22:02:32 2019 +0100 + + [basic.def.odr] Split long-winded bulleted sentence. diff --git a/papers/n4850.md b/papers/n4850.md new file mode 100644 index 0000000000..0be1578e0a --- /dev/null +++ b/papers/n4850.md @@ -0,0 +1,366 @@ +# N4850 Editors' Report -- Programming Languages -- C++ + +2020-01-14 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4849](http://wg21.link/n4849) is the current C++ working draft. It replaces [N4842](http://wg21.link/n4842). + * N4850 is this Editors' Report. + +## Notable editorial changes + +Only minor editorial changes have been made since N4842. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4842 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/n4842...n4849). + + commit aed2cbc451be619f3788387b02379067ae5fcb9c + Author: Richard Smith + Date: Wed Nov 27 18:01:16 2019 -0800 + + [basic.life] Rename "Object and reference lifetime" to simply "Lifetime" + + commit 1b0c11b682a907555950430290823371d65bb7c7 + Author: Jens Maurer + Date: Mon Dec 2 18:24:29 2019 +0100 + + [support.srcloc.class] Highlight unspecified properties (#3309) + + of the source_location constructors and copy assignment + operators. + + commit 4dd1859d3bb23893e4fa7499e38367d890323a59 + Author: Christopher Di Bella + Date: Tue Dec 10 14:26:21 2019 +0000 + + [iterator.concept.readable] Use ranges::iter_move in indirectly-readable-impl (#3532) + + The exposition-only concept indirectly-readable-impl relies on + ranges::iter_move, but the text was missing the ranges:: qualifier. + + commit b2efb60c2c79f612c6b17784385b33cb47f7b4cf + Author: Jens Maurer + Date: Tue Dec 10 15:47:41 2019 +0100 + + [class.derived,class.member.lookup] Reference figures in running text. (#3526) + + commit 93c581cbcfe7465fb417c9a3a191ce4a02fe9494 + Author: Bryce Adelstein Lelbach aka wash + Date: Tue Dec 10 10:27:19 2019 -0800 + + [time.syn] Move treat_as_floating_point_v next to treat_as_floating_point. (#3533) + + commit 4fccf29bdca0d3e709e330fd9deb1301b14d469b + Author: Bryce Adelstein Lelbach aka wash + Date: Wed Dec 11 11:03:29 2019 -0800 + + [functional.syn] Move variable templates next to traits. (#3536) + + commit 1c5672447cc6aa4d7f688f0b824d538e2dc00d25 + Author: Jonathan Wakely + Date: Thu Dec 12 20:54:18 2019 +0000 + + [span.cons] add missing \pnum + + Fixes #3540 + + commit e01989e83849323ab49089ea18a52ccbac08d90a + Author: Jens Maurer + Date: Sat Dec 14 09:28:30 2019 +0100 + + [span.cons] Do not suggest that to_address could throw. (#3546) + + commit a106d8e89b6bffdc3c89411e1e1850f4f699916f + Author: Jens Maurer + Date: Sat Dec 14 11:25:59 2019 +0100 + + [alg.partitions] Add missing \pnum. (#3549) + + Also extend the check script to flag missing \pnum in + library descriptions. + Limit the checking to library clauses other than [library]. + + commit 4c6f1e8a51092560b51640461794f2e8ab6bb1a0 + Author: Casey Carter + Date: Sat Dec 14 12:42:29 2019 -0800 + + [string.view.synop,span.syn,span.cons] enable_/safe_range are defined in std::ranges (#3551) + + commit 7989bb445478b41a9fee3539bebffcaa46ba5270 + Author: Jens Maurer + Date: Sun Dec 15 23:43:58 2019 +0100 + + [ranges] Mark exposition-only names as kebab-case. + + commit 89abe001f5cba2775ec1f908eadf765572413fd5 + Author: Jens Maurer + Date: Thu Dec 19 00:38:11 2019 +0100 + + [ranges] Missed markings for exposition-only names. (#3562) + + commit 108bb54ad091301591b1926817cfbbf595eec611 + Author: Richard Smith + Date: Wed Dec 18 16:12:19 2019 -0800 + + [over.match.funcs] Correct comment in example. + + Per the normative wording, excluded functions are not candidates; don't suggest they are candidates by describing them as not being viable. + + commit 8166369c5d5ce508d92ec35e72c14c0aa707e486 + Author: Jens Maurer + Date: Sun Dec 15 18:34:31 2019 +0100 + + [lib] Consistently use ios_base::failbit and ios_base::badbit. + + commit d825a2f4c0edbd1610de4dc602f9184dc6262a92 + Author: Johel Ernesto Guerrero Peña + Date: Tue Dec 31 04:58:59 2019 -0400 + + [range.common.view] Declare size after begin/end like in the other views (#3598) + + commit 5c5e8f13590a27740bf9d82b8b07c147bb9c82af + Author: Dan Raviv + Date: Thu Jan 2 19:51:16 2020 +0000 + + [expr.pre] Change note to use grammatical English (#3601) + + commit 45abe6732549540bbde151e16312fcca97d0b7b3 + Author: Johel Ernesto Guerrero Peña + Date: Sun Jan 5 13:33:57 2020 -0400 + + [range.take.while.sentinel] Add missing template parameter (#3604) + + Also add a cross-reference for the declaration of sentinel in [range.take.while]. + + commit 6e769c32615e4d71b9a67f6fe37fca505c85f69d + Author: Johel Ernesto Guerrero Peña + Date: Sun Jan 5 13:56:39 2020 -0400 + + [range.istream, range.take.while.sentinel] Harmonize default member initializer (#3605) + + for pointers to use "= nullptr", not value-initialization. + + commit 3974bc16a91e0be3b741d3ebbc2eea563c5873c8 + Author: Johel Ernesto Guerrero Peña + Date: Tue Jan 7 04:06:10 2020 -0400 + + [range.elements.iterator] Add missing \expos comment (#3609) + + commit 07741c01b2815bbb38b08ed373443dc55f8fc663 + Author: Jens Maurer + Date: Sat Jan 11 12:47:54 2020 +0100 + + [cmath.syn] Turn a consequence into a note. + + Also replace a numbered list with a bulleted one. + + commit 4e82f14c3f3cd168c23543f21382fb618b9422bc + Author: Jens Maurer + Date: Fri Jan 10 23:21:21 2020 +0100 + + [over.oper] Clarify that operator= cannot be overloaded for enumerations. + + commit 6816060ed8ee4fec41f642c469deca26552c521c + Author: Jens Maurer + Date: Fri Jan 10 23:07:31 2020 +0100 + + [locale.codecvt] Do not claim that 'Unicode' is a character encoding. + + commit e0ea8f0f88eefdb40bf973bce4ba4c53729705ef + Author: Jens Maurer + Date: Fri Jan 10 22:49:24 2020 +0100 + + [format.arg] Move 'otherwise' to the start of the bullets. + + commit 4d03cd8843189bb7020396f9e2a9a6e37994d75a + Author: Jens Maurer + Date: Fri Jan 10 22:43:54 2020 +0100 + + [thread.lock.unique.locking] Fix typo in try_lock_for. + + commit be996b318df8da69d4c15b498baf4d8137cd041d + Author: Dan Raviv + Date: Mon Jan 13 19:43:34 2020 +0000 + + [expr.prim.lambda.closure] Fix wording inaccuracy in note + + A generic lambda has a function call operator template, not a function call operator. + + commit 331d1a0a288ccdcb320a334f7c3ff8270ef66145 + Author: Jens Maurer + Date: Fri Jan 3 00:05:52 2020 +0100 + + [iterator.requirements.general,range.counted] Rework notation for counted ranges. + + Introduce a new macro \countedrange. + + commit 2950e9fe2e5050b45130081a47d56a5498589304 + Author: Johel Ernesto Guerrero Peña + Date: Mon Dec 30 18:28:03 2019 -0400 + + [iterator.concept.sizedsentinel] Improve description + + commit a689a53fa67577528c6d6aa9b257980b2e8c5c83 + Author: Jens Maurer + Date: Sun Dec 29 01:04:55 2019 +0100 + + [over.built] Avoid confusing term 'promoted arithmetic type'. + + commit 2fb11cffd398014d5ebc163bf07f6eee85596862 + Author: Richard Smith + Date: Mon Jan 13 12:09:54 2020 -0800 + + [over.built] Only unscoped enumeration types are subject to integral promotions + + commit 4a222eae3994f60676a3b7b235fda39366f59d6f + Author: Richard Smith + Date: Mon Jan 13 12:12:30 2020 -0800 + + [over.built] Convert to singular. + + commit fcd5b78c796b25e4028d450fe3fd31f73122f442 + Author: Jens Maurer + Date: Sat Dec 28 22:11:55 2019 +0100 + + [stringbuf] Use phrases from [bitmask.types]. + + commit a930484135422be1797060b6e819219cb8a628f8 + Author: Jens Maurer + Date: Sat Dec 28 21:07:20 2019 +0100 + + [expr.call] Clarify result of function call vs. return operand. + + commit 51f1b73307958683a60f31a20f5b1bfadc5c4fef + Author: Jens Maurer + Date: Fri Jan 10 23:34:34 2020 +0100 + + [ptr.launder] Fix note and example for std::launder. + + The applicable rules have changed in response to + NB RU 007, US 042 (C++20 CD). + + commit 1a4e37c71836fcb4077b8257dd1feb0bb6e1a33e + Author: Jens Maurer + Date: Sat Dec 28 19:12:05 2019 +0100 + + [expr.compound] Use sequencing on expressions + + as defined in [intro.execution] as an abbreviation + for value computations and side effects. + + commit 1de6c6168372d83644400e54cb769431a14419c1 + Author: Jens Maurer + Date: Sat Dec 28 18:45:38 2019 +0100 + + [temp.type,temp.over.link] Define and use 'same template-id'. + + commit 35641b4877d86ebd454b640bbb82d6127a24b545 + Author: Jens Maurer + Date: Sat Dec 28 00:33:59 2019 +0100 + + [thread.condvarany.intwait] Fix invocation of wait_until. + + P1869R1 Rename condition_variable_any interruptible wait methods + reordered the parameters of the wait_until function, but + neglected to adjust the 'Equivalent to' code for wait_for. + + commit 3b417555e214a50959fb8d718bf39c9fe14f13a5 + Author: Jens Maurer + Date: Fri Dec 27 14:13:01 2019 +0100 + + [class.static.data] Cleanup description for local/unnamed classes. + + commit b973550df3bb9348df1a4f62020a1e2822f5795f + Author: Jens Maurer + Date: Thu Dec 26 23:26:36 2019 +0100 + + [class.this] Member functions are not cv-qualified. + + commit 0a7b3603aa3f5311e784677ae99e8ffbfcb00eef + Author: Jens Maurer + Date: Thu Dec 26 23:33:01 2019 +0100 + + [class.this] Cleanup verbose and redundant exposition. + + commit 2069ec64c66767b0ac349554fb9a02a13989b5d6 + Author: Casey Carter + Date: Thu Dec 19 08:33:55 2019 -0800 + + [defns.signature] functions never have trailing requires-clauses + + ...after application of P1971R0. + + commit 2094aa84d669e8e852d2ed04a4b7183ebb7801a4 + Author: Jens Maurer + Date: Sun Dec 15 21:55:04 2019 +0100 + + [std] Harmonize comments indicating errors. + + commit 9600b0cc37dbb39b8d3fad33fae4638d4f6587c1 + Author: Jens Maurer + Date: Sun Dec 15 21:10:48 2019 +0100 + + [ranges] Integrate adaptor subclauses into overviews. + + commit c71826505953488db2005909113c526ab3760cdf + Author: Jens Maurer + Date: Sat Dec 14 01:07:47 2019 +0100 + + [cpp.replace] Distribute examples from [cpp.scope] + + where they fit more naturally, omitting some of the + now-redundant introductory phrases. + + commit 32f346c466dd5e45a4ae8fe3a1bf11e275fb08b9 + Author: Krystian Stasiowski + Date: Mon Jan 13 20:07:27 2020 -0500 + + [temp.spec] Convert description of "specialization" to a proper definition + + commit a4bf504f32d2840f74c00836265c6353e3e8ebf6 + Author: Johel Ernesto Guerrero Peña + Date: Mon Jan 13 21:12:47 2020 -0400 + + [algorithms] Split list items conventionally. + + commit 9a19e01fed4cf1c13164b1c57eeaee06ccec44f5 + Author: Jens Maurer + Date: Thu Dec 26 23:06:53 2019 +0100 + + [basic.scope.pdecl] Fix example of self-referential initialization. + + commit 54dc015ca8d40b7628abf470511e3baac975ae4a + Author: Jens Maurer + Date: Sat Jan 11 00:07:00 2020 +0100 + + [dcl.fct,expr.ref] Fix description of class member access expressions + + involving non-static member functions. + + commit 24bb2a0d3c753420c9196565b1bf2fd3fb596232 + Author: Jens Maurer + Date: Sat Dec 28 21:41:32 2019 +0100 + + [std] Consistently use 'overload set'. + + Define the term in [basic.lookup] and use it throughout. + Avoid the term 'set of overloaded functions', because it + is ambiguous with the declaration view in [over.load]. + (An overload set might contain functions from different + scopes that cannot be overloaded per [over.load].) diff --git a/papers/n4859.md b/papers/n4859.md new file mode 100644 index 0000000000..b5f496c320 --- /dev/null +++ b/papers/n4859.md @@ -0,0 +1,1718 @@ +# N4859 Editors' Report -- Programming Languages -- C++ + +2020-03-31 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Special thanks to +Marshall Clow +for providing LaTeX sources for the LWG "Mandating" papers. + +Special thanks to +Johel Ernesto Guerrero Peña +for reviewing the edits for many of the motions +and catching numerous issues, and to +Krystian Stasiowski +for providing many pull requests to improve +the consistency and precision of the standard wording. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * N4859 is this Editors' Report. + * [N4860](http://wg21.link/n4860) is the C++20 Draft International Standard. + * [N4861](http://wg21.link/n4861) is the current working draft for C++23. It replaces [N4849](http://wg21.link/n4849). + +The contents of N4860 and N4861 are identical +except for the cover sheet, page headers and footers, and +except that N4861 does not contain an index of +cross references from ISO C++ 2017. + +## Papers incorporated into working draft + +### Core working group polls + +CWG poll 1: [NB comment resolutions](http://wg21.link/p2103r0) for 7 NB comments applied: + + * NB US 028: Define grammar for *punctuator* **(DR)** + * NB US 033: Allow `import` inside *linkage-specification*s + * NB US 041: Enforce correspondence of containing objects for pointer values / aliasing **(DR)** + * NB CA 104: Clarify declaration matching and partial ordering requiring substitution into constraints + * NB CA 107: Parameter mapping for non-dependent entities + * NB US 115: Hidden non-template friends need a *requires-clause* + * NB US 117: Comparing types and *type-constraint*s + +CWG poll 2: [P1779R3 "ABI isolation for member functions"](http://wg21.link/p1779r3), resolving 1 NB comment: + + * NB US 090: Apply [P1779](http://wg21.link/p1779) after [P1815](http://wg21.link/p1815) + +CWG poll 3: [P1857R3 "Modules dependency discovery"](http://wg21.link/p1857r3), resolving 11 NB comments: **with changes; see below** + + * NB US 026: Make `module` also a directive + * NB US 121: Treat `module` declarations as preprocessing directives + * NB US 125: Repair *control-line* lexing of `import` + * NB GB 126: `import` as a preprocessing directive vs Modules Tooling TR + * NB US 127: Add more context for `import` preprocessing + * NB US 128: Clarify *control-line* pass-through for `import` + * NB US 136: Bad definition of *pp-global-module-fragment* + * NB US 137: Empty macros in `module` declarations + * NB US 138: `import` *control-line* vs *pp-balanced-token-sequence* + * NB US 139: Inconsistent restrictions on `module` keyword + * NB US 140: `module` from `#include` or macro expansion + +CWG poll 4: [P0593R6 "Implicit creation of objects for low-level object manipulation"](http://wg21.link/p0593r6), resolving 1 NB comment: **(DR)** + + * NB US 040: Adopt implicit object creation for C++20 + +CWG poll 5: [P1957R2 "Converting from `T*` to `bool` should be considered narrowing"](http://wg21.link/p1957r2), resolving 1 LWG issue and 1 NB comment: **(DR)** + + * [LWG 3228](http://wg21.link/lwg3228) Surprising `variant` construction + * NB US 212: Surprising `variant` construction + +CWG poll 6: [P2104R0 "Disallow changing concept values"](http://wg21.link/p2104r0), resolving 1 NB comment: + + * NB GB 046: Allow caching of evaluations of concept-ids + +CWG poll 7: [P2107R0 "Copy semantics of coroutine parameters"](http://wg21.link/p2107r0), resolving 1 CWG issue and 1 NB comment: + + * [2436](http://wg21.link/cwg2436) Copy semantics of coroutine parameters + * NB US 064: Apply Coroutines TS issue 33 from [P0664](http://wg21.link/p0664) + +CWG poll 8: [P2092R0 "Disambiguating *nested-requirement*s"](http://wg21.link/p2092r0) + +CWG poll 9: [Core issue resolutions](http://wg21.link/p2108r0) for 3 issues in "ready" status, resolving 4 issues: **(DR)** + + * [2053](http://wg21.link/cwg2053) `auto` in non-generic lambdas **resolved by CWG 2447** + * [2445](http://wg21.link/cwg2445) Partial ordering with rewritten candidates + * [2446](http://wg21.link/cwg2446) Questionable type-dependency of concept-ids + * [2447](http://wg21.link/cwg2447) Unintended description of abbreviated function templates + +CWG poll 10: [P2109R0 "Disallow `export import foo` outside of module interface"](http://wg21.link/p2109r0), resolving 1 NB comment: + + * NB US 084: Disallow `export import foo` outside of module interface + +CWG poll 11: [P2082R1 "Fixing CTAD for aggregates"](http://wg21.link/p2082r1) + +CWG poll 12: [NB comment resolution](http://wg21.link/p2113r0), resolving 2 NB comments: + + * NB CA 112: Matching of template parameters appearing in substituted parameter mappings + * NB US 120: "The same template parameter" in parameter mappings + +CWG poll 13: [P2115R0 "Merging of multiple definitions for unnamed unscoped enumerations"](http://wg21.link/p2115r0), resolving 1 NB comment: + + * NB US 069: Merging of multiple definitions for unnamed unscoped enumerations + +CWG poll 14: [P1815R2 "Translation-unit-local entities"](http://wg21.link/p1815r2), resolving 3 NB comments: + + * NB US 035: Referring to internal-linkage entities from certain exported ones should be ill-formed + * NB US 133: Header units containing internal-linkage entities + * NB US 134: Header units containing external-linkage entities + +CWG poll 15: [P2095R0 "Resolve lambda *init-capture* pack grammar"](http://wg21.link/p2095r0), resolving 1 issue: **with changes; see below** + + * [2378](http://wg21.link/cwg2378) Inconsistent grammar for reference *init-capture* of pack + +CWG poll 16: [P2002R1 "Defaulted comparison specification cleanups"](http://wg21.link/p2002r1) + +CWG poll 17: [P2085R0 "Consistent defaulted comparisons"](http://wg21.link/p2085r0) + +CWG poll 18: [P1908R1 "Reserving attribute namespaces for future use"](http://wg21.link/p1908r1) + +CWG poll 19: [P1937R2 "Fixing inconsistencies between `constexpr` and `consteval` functions"](http://wg21.link/p1937r2) + +### Library working group polls + +LWG poll 1 applies to the Library Fundamentals TS + +LWG poll 2: [Library issue resolutions](http://wg21.link/p2051r0) for 43 issues in "Ready" and "Tentatively Ready" status applied, resolving 26 NB comments: + + * [3194](http://wg21.link/lwg3194) ConvertibleTo prose does not match code + * [3233](http://wg21.link/lwg3233) Broken requirements for `shared_ptr` converting constructors + * [3254](http://wg21.link/lwg3254) Strike `stop_token`'s `operator!=` + * [3264](http://wg21.link/lwg3264) `sized_range` and `ranges::size` redundantly use `disable_sized_range` + * [3280](http://wg21.link/lwg3280) View converting constructors can cause constraint recursion and are unneeded + * [3281](http://wg21.link/lwg3281) Conversion from pair-like types to `subrange` is a silent semantic promotion **not applied; superseded by LWG3282 (LWG poll 3)** + * [3284](http://wg21.link/lwg3284) `random_access_iterator` semantic constraints accidentally promote difference type using unary negate + * [3285](http://wg21.link/lwg3285) The type of a customization point object shall satisfy `semiregular` + * [3286](http://wg21.link/lwg3286) `ranges::size` is not required to be valid after a call to `ranges::begin` on an `input range` + * [3291](http://wg21.link/lwg3291) `iota_view::iterator` has the wrong `iterator_category` + * [3292](http://wg21.link/lwg3292) `iota_view` is under-constrained + * [3294](http://wg21.link/lwg3294) `zoned_time` deduction guides misinterprets `string`/`char*` + * [3296](http://wg21.link/lwg3296) Inconsistent default argument for `basic_regex<>::assign` + * [3299](http://wg21.link/lwg3299) Pointers don't need customized iterator behavior + * [3300](http://wg21.link/lwg3300) Non-array `ssize` overload is underconstrained + * [3302](http://wg21.link/lwg3302) Range adaptor objects `keys` and `values` are unspecified + * [3303](http://wg21.link/lwg3303) Bad `constexpr` marker for `destroy`/`destroy_n` + * [3304](http://wg21.link/lwg3304) Allocate functions of `std::polymorphic_allocator` should require `[[nodiscard]]` + * [3307](http://wg21.link/lwg3307) `std::allocator().allocate(n)` + * [3310](http://wg21.link/lwg3310) Replace `SIZE_MAX` with `numeric_limits::max()` + * [3313](http://wg21.link/lwg3313) `join_view::iterator::operator--` is incorrectly constrained + * [3315](http://wg21.link/lwg3315) Correct allocator default behavior + * [3316](http://wg21.link/lwg3316) Correctly define epoch for `utc_clock` / `utc_timepoint` + * [3317](http://wg21.link/lwg3317) Incorrect `operator<<` for floating-point durations + * [3318](http://wg21.link/lwg3318) Clarify whether clocks can represent time before their epoch + * [3319](http://wg21.link/lwg3319) Properly reference specification of IANA time zone database + * [3320](http://wg21.link/lwg3320) `span::{cbegin,cend}` methods produce different results than `std::[ranges::]{cbegin,cend}` + * [3321](http://wg21.link/lwg3321) `uninitialized_construct_using_allocator` should use `construct_at` + * [3323](http://wg21.link/lwg3323) *`has-tuple-element`* helper concept needs `convertible_to` + * [3324](http://wg21.link/lwg3324) Special-case `std::{strong,weak,partial}_order` for pointers + * [3325](http://wg21.link/lwg3325) Constrain return type of transformation function for `transform_view` + * [3326](http://wg21.link/lwg3326) `enable_view` has false positives + * [3327](http://wg21.link/lwg3327) Format alignment specifiers vs. text direction + * [3329](http://wg21.link/lwg3329) `totally_ordered_with` both directly and indirectly requires `common_reference_with` + * [3330](http://wg21.link/lwg3330) Include `` from most library headers + * [3331](http://wg21.link/lwg3331) Define `totally_ordered[_with]` in terms of *`partially-ordered-with`* + * [3332](http://wg21.link/lwg3332) Issue in [time.format] + * [3338](http://wg21.link/lwg3338) Rename `default_constructible` to `default_initializable` + * [3346](http://wg21.link/lwg3346) `pair` and `tuple` copy and move constructor have backwards specification + * [3349](http://wg21.link/lwg3349) Missing `__cpp_lib_constexpr_complex` for [P0415R1](http://wg21.link/p0415r1) + * [3350](http://wg21.link/lwg3350) Simplify return type of `lexicographical_compare_three_way` + * [3351](http://wg21.link/lwg3351) `ranges::enable_safe_range` should not be constrained + * [3356](http://wg21.link/lwg3356) `__cpp_lib_nothrow_convertible` should be `__cpp_lib_is_nothrow_convertible` + * [3360](http://wg21.link/lwg3360) `three_way_comparable_with` is inconsistent with similar concepts + * NB US 156: Ignore cv-qualifiers for customization point objects + * NB US 162: Default behavior for `destroy` is `destroy_at` + * NB US 163: Default behavior for `construct` is `construct_at` + * NB CA 178: Special-case `std::{strong,weak,partial}_order` for pointers + * NB US 181: Include `` from most library headers + * NB US 201: `totally_ordered_with` both directly and indirectly requires `common_reference_with` + * NB GB 202: Define `totally_ordered[_with]` in terms of *`partially-ordered-with`* + * NB US 213: `uninitialized_construct_using_allocator` should use `construct_at` + * NB US 217: `polymorphic_allocator::*_object` should be `[[nodiscard]]` + * NB JP 218: Replace `SIZE_MAX` with `numeric_limits::max()` + * NB JP 219: Replace `SIZE_MAX` with `numeric_limits::max()` + * NB GB 225: Format alignment specifiers vs. text direction + * NB PL 247: `span::c[r]{begin,end}` return type confusion + * NB US 262: Avoid unary negation in definition of `random_access_iterator` + * NB DE 282: Make `enable_view` less greedy + * NB US 286: Constraints on `iota_view`, *`forwarding-range`* + * NB US 287: `iota_view::iterator` is a Cpp17InputIterator + * NB US 294: `join_view::iterator::operator--` is improperly constrained + * NB GB 299: *`has-tuple-element`* helper concept needs `convertible_to` + * NB US 302: Remove some converting constructors for views to avoid constraint recursion + * NB US 303: Constrain return type of transformation function for `transform_view` + * NB US 304: Interaction between `begin` and `size` on input ranges + * NB GB 333: Correctly define epoch for `utc_clock` / `utc_timepoint` + * NB US 334: Incorrect `operator<<` for floating-point durations + * NB GB 335: Clarify whether clocks can represent time before their epoch + * NB DE 344: Properly reference specification of IANA time zone database + +LWG poll 3: [Library issue resolutions](http://wg21.link/p2117r0) for 65 issues in "Immediate" status applied, resolving 8 NB comments: + + * [1203](http://wg21.link/lwg1203) More useful rvalue stream insertion + * [2859](http://wg21.link/lwg2859) Definition of reachable in [ptr.launder] misses pointer arithmetic from pointer-interconvertible object + * [3018](http://wg21.link/lwg3018) `shared_ptr` of function type + * [3050](http://wg21.link/lwg3050) Conversion specification problem in `chrono::duration` constructor + * [3141](http://wg21.link/lwg3141) CopyConstructible doesn't preserve source values + * [3150](http://wg21.link/lwg3150) UniformRandomBitGenerator should validate `min` and `max` + * [3175](http://wg21.link/lwg3175) The CommonReference requirement of concept SwappableWith is not satisfied in the example + * [3200](http://wg21.link/lwg3200) `midpoint` should not constrain `T` is complete + * [3201](http://wg21.link/lwg3201) `lerp` should be marked as `noexcept` + * [3226](http://wg21.link/lwg3226) `zoned_time` constructor from `string_view` should accept `zoned_time` + * [3237](http://wg21.link/lwg3237) LWG [3038](http://wg21.link/lwg3038) and [3190](http://wg21.link/lwg3190) have inconsistent PRs + * [3238](http://wg21.link/lwg3238) Insufficiently-defined behavior of `std::function` deduction guides + * [3242](http://wg21.link/lwg3242) `std::format` missing rules for *arg-id* in *width* and *precision* + * [3243](http://wg21.link/lwg3243) `std::format` and negative zeroes + * [3247](http://wg21.link/lwg3247) `ranges::iter_move` should perform ADL-only lookup of `iter_move` + * [3248](http://wg21.link/lwg3248) `std::format` `#b`, `#B`, `#o`, `#x`, and `#X` presentation types misformat negative numbers + * [3250](http://wg21.link/lwg3250) `std::format` `#` (alternate form) for NaN and inf + * [3251](http://wg21.link/lwg3251) Are `std::format` alignment specifiers applied to string arguments? + * [3252](http://wg21.link/lwg3252) `parse`'s locale aware modifiers for commands are not consistent with POSIX spec + * [3255](http://wg21.link/lwg3255) `span`'s array constructor is too strict + * [3260](http://wg21.link/lwg3260) `year_month*` arithmetic rejects durations convertible to `years` + * [3262](http://wg21.link/lwg3262) Formatting of negative durations is not specified **with changes; see below** + * [3269](http://wg21.link/lwg3269) Parse manipulators do not specify the result of the extraction from stream + * [3270](http://wg21.link/lwg3270) Parsing and formatting `%j` with durations + * [3282](http://wg21.link/lwg3282) `subrange` converting constructor should disallow derived to base conversions + * [3301](http://wg21.link/lwg3301) `transform_view::iterator` has incorrect `iterator_category` + * [3314](http://wg21.link/lwg3314) Is stream insertion behavior locale dependent when `Period::type` is `micro`? + * [3328](http://wg21.link/lwg3328) Clarify that `std::string` is not good for UTF-8 + * [3334](http://wg21.link/lwg3334) `basic_osyncstream` move assignment and destruction calls `basic_syncbuf::emit()` twice + * [3335](http://wg21.link/lwg3335) Resolve C++20 NB comments US 273 and GB 274 + * [3340](http://wg21.link/lwg3340) Formatting functions should throw on argument/format string mismatch in [format.functions] + * [3347](http://wg21.link/lwg3347) `std::pair` now requires `T` and `U` to be *`less-than-comparable`* + * [3348](http://wg21.link/lwg3348) `__cpp_lib_unwrap_ref` in wrong header + * [3352](http://wg21.link/lwg3352) `strong_equality` isn't a thing + * [3354](http://wg21.link/lwg3354) `has_strong_structural_equality` has a meaningless definition + * [3355](http://wg21.link/lwg3355) The memory algorithms should support move-only input iterators introduced by [P1207](http://wg21.link/p1207) + * [3358](http://wg21.link/lwg3358) [span.cons] is mistaken that `to_address` can throw + * [3359](http://wg21.link/lwg3359) `` leap second support should allow for negative leap seconds + * [3362](http://wg21.link/lwg3362) Strike `stop_source`'s `operator!=` + * [3363](http://wg21.link/lwg3363) `drop_while_view` should opt-out of `sized_range` + * [3364](http://wg21.link/lwg3364) Initialize data members of ranges and their iterators + * [3367](http://wg21.link/lwg3367) Integer-class conversions should not throw + * [3369](http://wg21.link/lwg3369) `span`'s deduction-guide for built-in arrays doesn't work + * [3371](http://wg21.link/lwg3371) `visit_format_arg` and `make_format_args` are not hidden friends + * [3372](http://wg21.link/lwg3372) `format_to` should not try to deduce `Out` twice + * [3373](http://wg21.link/lwg3373) `{to,from}_chars_result` and `format_to_n_result` need the "we really mean what we say" wording + * [3374](http://wg21.link/lwg3374) [P0653](http://wg21.link/p0653) + [P1006](http://wg21.link/p1006) should have made the other `std::to_address` overload `constexpr` + * [3375](http://wg21.link/lwg3375) `decay` in `viewable_range` should be `remove_cvref` + * [3377](http://wg21.link/lwg3377) `elements_view::iterator` befriends a specialization of itself + * [3379](http://wg21.link/lwg3379) `safe` in several library names is misleading + * [3380](http://wg21.link/lwg3380) `common_type` and comparison categories + * [3381](http://wg21.link/lwg3381) `begin` and `data` must agree for `contiguous_range` + * [3382](http://wg21.link/lwg3382) NTTP support for `pair` and `array` + * [3383](http://wg21.link/lwg3383) [time.zone.leap.nonmembers] `sys_seconds` should be replaced with `seconds` + * [3384](http://wg21.link/lwg3384) `transform_view::sentinel` has an incorrect `operator-` + * [3385](http://wg21.link/lwg3385) `common_iterator` is not sufficiently constrained for non-copyable iterators + * [3387](http://wg21.link/lwg3387) `reverse_view` unintentionally requires `range` + * [3388](http://wg21.link/lwg3388) `view` iterator types have ill-formed `<=>` operators + * [3389](http://wg21.link/lwg3389) A move-only iterator still does not have a `counted_iterator` + * [3390](http://wg21.link/lwg3390) `make_move_iterator()` cannot be used to construct a `move_iterator` for a move-only iterator + * [3393](http://wg21.link/lwg3393) Missing/incorrect feature test macro for coroutines + * [3395](http://wg21.link/lwg3395) Definition for three-way comparison needs to be updated (US 152) + * [3396](http://wg21.link/lwg3396) Clarify point of reference for `source_location::current()` (DE 169) + * [3397](http://wg21.link/lwg3397) `ranges::basic_istream_view::iterator` should not provide `iterator_category` + * [3398](http://wg21.link/lwg3398) `tuple_element_t` is also wrong for `const subrange` + * NB US 152: Update definition for three-way comparison + * NB DE 169: Clarify point of reference for `source_location::current()` + * NB GB 229: Allow `std::format` to throw for argument / format string mismatch + * NB US 273: Rename `all_view` + * NB GB 274: Add `range_size_t` + * NB US 284: Prevent conversion from pair-like types to `subrange`s + * NB US 285: Prevent derived-to-base slicing with `subrange` constructors + * NB NL 375: Clarify that `std::string` is not good for UTF-8 + +LWG poll 4: [P2045R1 "Missing *Mandates:* for the standard library"](http://wg21.link/p2045r1) + +LWG poll 5: [P1460R1 "Mandating the Standard Library: Clause 20 - Utilities library"](http://wg21.link/p1460r1) **with changes; see below** + +LWG poll 6: [NB comment resolution](http://wg21.link/p1963r0) for 1 comment applied, also resolving 1 issue: + + * [3156](http://wg21.link/lwg3156) `ForwardIterator` should only mean forward iterator + * NB US 313: Properly define scope of subclause [algorithms.requirements] to cover [specialized.algorithms] + +LWG poll 7: [NB comment resolution](http://wg21.link/p1983r0) for 5 comments applied, also resolving 1 issue: + + * [3278](http://wg21.link/lwg3278) `join_view::iterator` tries to write through `const join_view` pointer + * NB US 283: Specification of *`has-arrow`* concept is ill-formed + * NB US 291: `join_view::begin` requires mutable data + * NB US 292: Incorrect constructor for `join_view::iterator` + * NB US 296: Converting constructor for `split_view::outer_iterator` is slightly wrong + * NB GB 301: Add `filter_view::pred()` accessor + +LWG poll 8: [P1981R0 "Rename `leap` to `leap_second`"](http://wg21.link/p1981r0), resolving 1 NB comment: + + * NB DE 345: Rename `leap` to `utc_leap` + +LWG poll 9: [P1982R0 "Rename `link` to `time_zone_link`"](http://wg21.link/p1982r0), resolving 1 NB comment: + + * NB DE 346: Rename `link` to `zone_link` + +LWG poll 10: [P2101R0 "'Models' subsumes 'satisfies'"](http://wg21.link/p2101r0), resolving 1 issue and 2 NB comments: + + * [3345](http://wg21.link/lwg3345) Incorrect usages of "models" versus "satisfies" + * NB US 298: `views::common` incorrectly uses "models" + * NB US 300: Specification of *`semiregular-box`* should not use "models" + +LWG poll 11: [P1115R3 "Improving the return value of erase-like algorithms, part 2: free `erase[_if]`"](http://wg21.link/p1115r3), resolving 2 NB comments: + + * NB DE 231: Non-member `erase[_if]` should return the number of elements deleted + * NB GB 234: Non-member `erase[_if]` should return the number of elements deleted + +LWG poll 12: [P2102R0 "Make 'implicit expression variations' more explicit"](http://wg21.link/p2102r0), resolving 1 NB comment: + + * NB US 185: Specify "implicit expression variations" + +LWG poll 13: [P1994R1 "`elements_view` needs its own sentinel"](http://wg21.link/p1994r1), resolving 1 issue: + + * [3386](http://wg21.link/lwg3386) `elements_view` needs its own `sentinel` type + +LWG poll 14: [P1868R2 "🦄 width: clarifying units of width and precision in `std::format`"](http://wg21.link/p1868r2), resolving 1 issue and 1 NB comment: + + * [3290](http://wg21.link/lwg3290) Are `std::format` field widths code units, code points, or something else? + * NB US 228: Specify units of width and precision + +LWG poll 15: [P1956R1 "On the names of low-level bit manipulation functions"](http://wg21.link/p1956r1), resolving 5 NB comment: + + * NB PL 326: Rename `log2p1` to `bit_length` + * NB US 327: `log2p1` collides with IEEE-754 floating-point operation + * NB US 328: Rename `ceil2` and `floor2` + * NB GB 331: Rename `ceil2` and `floor2` + * NB GB 332: `log2p1` collides with IEEE-754 + +LWG poll 16: [P1976R2 "Fixed-size `span` construction from dynamic range"](http://wg21.link/p1976r2), resolving 1 NB comment: + + * NB PL 250: Size mismatch for fixed-sized `span` + +LWG poll 17: [P1964R2 "Wording for *`boolean-testable`*"](http://wg21.link/p1964r2), resolving 4 NB comments: + + * NB US 195: Remove concept *`boolean`* and use `convertible_to` instead + * NB US 196: Simplify concept *`boolean`* + * NB GB 197: Remove concept *`boolean`* and use `convertible_to` instead + * NB US 198: Fix concept definition of *`boolean`* + +LWG poll 18: [P2091R0 "Issues with range access customization point objects"](http://wg21.link/p2091r0), resolving 3 issues and 1 NB comment: + + * [3258](http://wg21.link/lwg3258) Range access and `initializer_list` + * [3299](http://wg21.link/lwg3299) Pointers don't need customized iterator behavior + * [3368](http://wg21.link/lwg3368) `memory_order::memory_order_foo` broken in C++20 + * NB GB 275: `ranges::{begin,end}` should not accept arrays of unknown bound + +LWG poll 19: [P0586R2 "Safe integral comparisons"](http://wg21.link/p0586r2), resolving 1 NB comment: **with changes; see below** + + * NB DE 208: Comparing values of different arithmetic types + +LWG poll 20: [P1831R1 "Deprecating `volatile`: library"](http://wg21.link/p1831r1), resolving 3 NB comments: **with changes; see below** + + * NB CZ 004: Adopt P1831 (deprecating `volatile`: library) + * NB CA 210: Deprecate some uses of `volatile` in the library + * NB US 211: Deprecate some uses of `volatile` in the library + +LWG poll 21: [P1973R1 "Rename `_default_init` functions"](http://wg21.link/p1973r1), resolving 1 NB comment: **with changes; see below** + + * NB DE 002: Rename `make_{unique,shared}_default_init` to `make_{unique,shared}_nonvalue_init` + +LWG poll 22: [P1243R4 "Rangify new algorithms"](http://wg21.link/p1243r4), resolving 3 NB comments: + + * NB FR 305: Add more range-enabled algorithms + * NB US 307: Add more range-enabled algorithms + * NB US 318: Handle negative shift counts + +LWG poll 23: [NB comment resolutions](http://wg21.link/p2106r0) for 2 NB comments: + + * NB GB 315: Define conversion operators for `next_permutation_result` + * NB GB 316: Algorithm result types should be distinct types, not aliases + +LWG poll 24: [P1739R4 "Avoid template bloat for `safe_ranges` in combination with "subrange-y" view adaptors"](http://wg21.link/p1739r4), resolving 2 NB comments: + + * NB US 272: API improvements for ranges + * NB DE 288: Overspecification of return types of view adaptors + +LWG poll 25: [P2116R0 "Remove tuple-like protocol support from fixed-extent `span`"](http://wg21.link/p2116r0), resolving 1 issue: + + * [3212](http://wg21.link/lwg3212) `tuple_element_t<1, const span>` is `const int` + +LWG poll 26: [P1970R2 "Consistency for `size` functions: add `ranges::ssize`"](http://wg21.link/p1970r2), resolving 1 NB comment: + + * NB DE 269: Enable `ssize()` on ranges + +## Notable changes to papers as polled + +### CWG poll 3 + +Replaced reference to non-existent grammar production *import-directive* with +the intended grammar production *pp-import*. + +### CWG poll 15 + +The location of the ellipsis in the quoted grammar in +[expr.prim.lambda.capture]p2 didn't match the grammar production being quoted, +and was relocated to the intended position. + +### LWG poll 3 + +The example added by LWG3262 did not take into account that +the *chrono-specs* in a *chrono-format-spec* are required to start with +a `%` character, so the `-` inserted for a negative duration is always +at the start of the field. +Consultation with LWG indicates that the result of this rule interaction +is desirable, so the example has been updated to match. + +### LWG poll 5 + +This paper replaced *Requires:* with *Mandates:* +in the `tuple(tuple&&)` constructor. +The resolution of LWG issue 2899 (from 2019-08 LWG motion 1) +already replaced *Requires:* with *Constraints:*. +The change in this paper was not applied, +as it would violate the intent established in LWG 2899 +that the `is_move_constructible` trait can detect +the move-constructibility of `tuple`. + +### LWG poll 19 + +As requested by the poll, +the feature test macro added by this paper was changed +from `__cpp_lib_cmp_equal` to `__cpp_lib_integer_comparison_functions`. + +### LWG poll 20 + +This paper suggested adding a *Constraints:* clause to `atomic_init`, but +also adding wording that would remove those constraints as a deprecated +feature. However, `atomic_init` has itself been deprecated since the +wording was created. The result is that all calls to the function are +deprecated, but calls that violate the *Constraints:* are deprecated in +two different ways. Therefore the *Constraints:* have no effect, and have +been removed. + +### LWG poll 21 + +This paper renamed a feature test macro but didn't suggest bumping its number +to the date of the rename. After consultation with SG10, the macro's version +has been increased to `202002L`. + +## Disposition of editorial NB comments on C++ 2020 CD1 + +Listed below are disposition for all comments that were +filed as editorial in the ISO 14882 CD (2019) NB comments +and not resolved in [N4842](http://wg21.link/n4842). +For the disposition of comments resolved in N4842, see +the corresponding Editors' Report, [N4843](http://wg21.link/n4843). + +JP 218: **Accepted** + + * Forwarded to LWG for consideration; + [LWG issue 3310](https://cplusplus.github.io/LWG/issue3310) opened to track this comment. + * LWG accepted; resolved by LWG poll 2. + +JP 219: **Accepted** + + * Forwarded to LWG for consideration; + [LWG issue 3310](https://cplusplus.github.io/LWG/issue3310) opened to track this comment. + * LWG accepted; resolved by LWG poll 2. + +GB 225: **Accepted** + + * Proposed change is not editorial. Forwarded to LWG for consideration. + [LWG issue 3327](https://cplusplus.github.io/LWG/issue3327) opened to track this comment. + * LWG accepted; resolved by LWG poll 2. + +US 327: **Accepted** + + * The proposed change is not editorial. + Forwarded to LEWG for consideration. + * Duplicate of PL 326. + * LWG accepted; resolved by LWG poll 15 ([P1956](http://wg21.link/p1956)). + +US 328: **Accepted** + + * The proposed change is not editorial. + Forwarded to LEWG for consideration. + * Duplicate of PL 326. + * LWG accepted; resolved by LWG poll 15 ([P1956](http://wg21.link/p1956)). + +## Notable editorial changes + +### Value of `__cplusplus` + +The value of the `__cplusplus` macro has been increased to `202002L` for C++20. + + +### "Recommended practice" sections + +Some wording that was previously expressing normative encouragement +by way of notes has been replaced with "Recommended practice" sections, +following the example of the C standard. + +### Fixed misapplication of part of P0896R4 + +Due to a copy-paste error, the default constructor of `front_insert_iterator` +was inadvertently changed to a non-default constructor +when P0896R4 was applied by 2018-11 LWG Motion 25. This has been corrected. + +### Fixed misapplication of part of P1878R1 + +P1878R1, applied by 2019-11 LWG Motion 9, +requested that the concept `writable` +be globally renamed to `indirectly_writable`. +The rename missed some instances that were added by other papers +also moved at the 2019-11 meeting. +This has been corrected. + +### Fixed misapplication of part of P0815R0 + +The application of the resolution of LWG2950, +applied as part of P0815R0 by 2017-11 LWG Motion 4, +inadvertently removed the `b =` +from the specification of `operator>>=(byte& b, IntType shift)`. +This has been corrected. + +### Section labels + +The section [language.support] has been renamed to [support] +in order to prevent the section heading being broken across two lines. + +Some missing entries in the "Cross references from ISO C++ 17" appendix +have been added; all section labels present in C++17 but not in C++20 +are now listed. + +### *Requires:* element + +As a result of the various "Mandating" papers, the *Requires:* element is +unused outside of Annex D, so the description of that element has been +moved there too. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4849 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/n4849...n4861). + + commit 235e9a0cf66a997d05d068903ea5aeebc2e8e82f + Author: Casey Carter + Date: Wed Jan 15 08:27:29 2020 -0800 + + [span.overview] Correct typo (#3633) + + Fixes #3632. + + commit 1c0171894b791258539854d98fa5b157b8d6822b + Author: Johel Ernesto Guerrero Peña + Date: Wed Jan 22 07:48:32 2020 -0400 + + [optional.optional, optional.ctor] Fix constexpr/explicit position (#3644) + + commit d29ae50e1d39d56e54e142b13737d627709d39dc + Author: Casey Carter + Date: Wed Jan 22 08:19:13 2020 -0800 + + [expr.prim.req.nested] Add missing semicolon to example + + commit 9b6c64fabdb05432ecdd238900ca03ee63c33cf1 + Author: Andrzej Krzemieński + Date: Fri Jan 24 00:30:17 2020 +0100 + + [temp.constr.op] Fix missing parentheses in example (#3643) + + commit 22a182262f25f9fe79d8ff7a4e1d1460002bf9cd + Author: Casey Carter + Date: Fri Jan 24 09:49:58 2020 -0800 + + [lib] Do not use "for some" to mean "for an arbitrary" (#3146) + + commit 76e7c18a1255a42c94cb3073de47969dc17549f1 + Author: Casey Carter + Date: Mon Oct 21 12:20:13 2019 -0700 + + [ranges] Rename make-unsigned-like to to-unsigned-like + + Resolves #3300. + + commit bf7a213db29cbd3f7c8f21798a1e6552d161594b + Author: Casey Carter + Date: Mon Oct 21 12:24:10 2019 -0700 + + [ranges] make-unsigned-like-t is an exposition-only alias template + + ...instead of an exposition-only macro. In other words, it's used as `make-unsigned-like-t` instead of `make-unsigned-like-t(meow)`. + + commit 90ded44703e48b32401fc766337d3e0bf0a8eaca + Author: Casey Carter + Date: Mon Oct 21 12:29:09 2019 -0700 + + [ranges.syn] to-unsigned-like operates on expressions, not objects + + commit 85e5aeb00ae69803a3ff10f96387d151af654f9c + Author: Daveed Vandevoorde + Date: Tue Jan 28 14:35:02 2020 -0500 + + [temp.constr.normal] Remove extraneous parentheses on concept use (#3651) + + commit 61952121cc594d4d290bfb17b0ea95d50c6ed534 + Author: Daveed Vandevoorde + Date: Wed Jan 29 16:34:44 2020 -0500 + + [temp.constr.normal] Confusing identifier used in explanation (#3652) + + commit 694d84cae2e5496f59102f3eb7f386925be199dd + Author: pppalka + Date: Wed Feb 5 16:11:04 2020 -0500 + + [range.istream.iterator] Fix bad reference to member name (#3661) + + The description of basic_istream_view::iterator::operator*() refers to a + nonexistent data member value_ of basic_istream_view instead of the data + member object_. + + commit cbbbbc53b68c18a611bf75c5e626ad2c6aa56a3c + Author: pppalka + Date: Wed Feb 5 17:27:51 2020 -0500 + + [range.join.sentinel], [range.split.view] Fix typos (#3656) + + commit 634695586ebe9060f20a4b104aaefd9db9237f75 + Author: Thomas Köppe + Date: Mon Feb 10 21:21:33 2020 +0100 + + [depr.c.headers] Rename heading to just "C headers". + + The term "C headers" is just a label for a certain part of the C++ standard library; there is no deeper connection to the C language. + + commit 0354125f1cdfef949d80053528c4a1a4f74b1dea + Author: Richard Smith + Date: Mon Feb 10 21:54:51 2020 +0100 + + [temp.func.order] Fix comment to refer to correct overload resolution result. + + #1a is a fiction invented by partial ordering. The callee is #1 from which #1a was generated. + + commit fe46a2b9142c8f3e931806f0433a13d5a8478100 + Author: Richard Smith + Date: Mon Feb 10 23:19:00 2020 +0100 + + Update value of __cplusplus to 202002L + + commit 977961d675f77c0874b10a3f834984e7576cacfb + Author: Thomas Köppe + Date: Mon Feb 10 23:59:08 2020 +0100 + + [dcl.fct] Fix reference to temp.fct. + + This reference was originally spelled "17.6.5" in the wording paper P1141R2, + where it was relative to the Concepts TS, and the error slipped through. + During motion application, we spotted the error, but not the cause, and + picked temp.over.link as a "best-fit" replacement, when in fact the correct + reference is temp.fct. + + commit d668fd6d52f39aab030628185f5f1b747837f62a + Author: Thomas Köppe + Date: Fri Feb 14 10:51:20 2020 +0100 + + [conv.rank] Change "size" to "width" in conversion rank relation (#3675) + + "size" has no defined meaning here; CWG confirmed that this is intended to be interpreted as "width". + + commit 7918bc2a036e71fca76468f341c8302a676be580 + Author: Thomas Köppe + Date: Tue Feb 11 16:12:21 2020 +0100 + + [cmp, comparisons] Move description of compare_three_way. + + Moves the definition and specification of class compare_three_way from + [cmp, 17.11] to [comparisons, 20.14.7]. Also adds a declaration of this + class to the synopsis of and removes a paragraph that says + (now redundantly) that the class is available also via inclusion of + . + + This is a partial response to NB GB 175 (C++20 CD). + + commit 43876c3008180b7e6b398bc0320baf7d06ac9d7f + Author: Jens Maurer + Date: Mon Jan 13 20:46:47 2020 +0100 + + [dcl.attr] Introduce 'Recommended practice' paragraphs. + + commit 78de92453c9c58450ac0574529ad9a4673786124 + Author: Jens Maurer + Date: Sun Feb 23 15:19:09 2020 +0100 + + [temp.func.order] Add bullets to clarify long sentence. + + commit 887d0f58a6a2f15617084bac462d730a23001571 + Author: Richard Smith + Date: Tue Feb 25 17:44:13 2020 -0800 + + [basic.def.odr] Clarify that translation units lacking a + private-module-fragment are definition domains. + + commit f32471ed53b621309fca9b1a75341bd9b9f6ede6 + Author: Dawn Perchik + Date: Fri Feb 21 12:49:20 2020 -0800 + + [expr.prim.lambda.capture]/p2 Fix P2095R0 wording: move "...opt" after "identifier" + + commit 090d7d8c96ec5e6371e087fd3f1d4455a6dbb7bd + Author: Dawn Perchik + Date: Fri Feb 21 13:39:40 2020 -0800 + + [allocator.uses.construction] Give a name to generic lambda type + parameter to allow idiomatic use of std::forward. + + commit 193040646cc01368e8c20b4600452046e8eaf660 + Author: Jens Maurer + Date: Mon Feb 24 07:54:11 2020 +0100 + + [algorithms.requirements] Fix non-sensical English for NoThrowForwardIterator + + commit 2eec680c4bfde4ec961041a71f5de95c59c8a4e8 + Author: Jens Maurer + Date: Wed Feb 26 00:34:24 2020 +0100 + + [uninitialized.move,uninitialized.copy] Use \countedrange where applicable. + + commit 14fd38fd5ed2cfebe608b2ed2c7d1f00d88a9baf + Author: Jens Maurer + Date: Wed Feb 26 00:40:25 2020 +0100 + + [specialized.algorithms] Whitespace and punctuation tweaks. + + - Hyphenate 'potentially-overlapping subobject'. + - Add whitespace in range. + + commit eff97945e2e8148d6fb204a96db7b6ba6845fd49 + Author: Dawn Perchik + Date: Sun Feb 23 19:44:27 2020 -0800 + + [range.elements.sentinel] Fix template-head for elements_view::sentinel added by P1994R1 + + commit cfd03b579bba7247bc826ed4a00fbf64c603d5bf + Author: Richard Smith + Date: Mon Mar 2 16:10:05 2020 -0800 + + [format.string.std] Put code point ranges in numerical order and collapse two adjacent code points into a range. + + commit 9ce9b23148af2f744ef6707713839aa550f44999 + Author: Richard Smith + Date: Mon Mar 2 16:41:36 2020 -0800 + + [intro.ack] Add Unicode to the list of registered trademarks we mention. + + commit 8dc23664d32a21c89eaeacd8ecd6cc675b1bcc4a + Author: Richard Smith + Date: Mon Mar 2 17:31:45 2020 -0800 + + [span.sub], [span.objectrep] Use direct-list-initialization in span + construction to compensate for changes in P1976R2. + + commit 39a1f591610040c0c53ed741ecbee52543c7ce47 + Author: Dawn Perchik + Date: Sun Feb 23 12:25:17 2020 -0800 + + [range.prim.size] Change "make-unsigned-like" to "to-unsigned-like" as per #3311 + + commit 8b5636fe7379cf4f1a4a0eb3eee32d9574b93a8a + Author: Dawn Perchik + Date: Sun Feb 23 12:46:23 2020 -0800 + + [ranges] Fix issues with wording of P2091R0 as suggested in #3752 + + [range.prim.data] Fix typo "expresssion-equivalent" + [range.access.rend] Fix cases where "rbegin" should be "rend" + [range.prim.size] Fix "E" to be "t" in "expression-equivalent to" expressions + + commit 202bef9db425c5d51c8b0aced9fb5c65778e914f + Author: Richard Smith + Date: Tue Mar 3 12:53:38 2020 -0800 + + [atomics] Remove redundant (and wrong in several places) qualification + of is_always_lock_free. + + commit a63805dc0719bebdc065b63498613b9c742f2bc2 + Author: Richard Smith + Date: Tue Mar 3 12:56:49 2020 -0800 + + [atomics.types.float] Remove meaningless A:: qualification. + + commit f3825d77e61b7140c2fbd9b8ef3e11b3bda35e46 + Author: Richard Smith + Date: Wed Mar 4 13:25:33 2020 -0800 + + [atomics.types.operations] Remove inaccurate introductory note + concerning 'volatile'. + + Fixes #3816. + + commit e8121bf5223690fddb459ab45d1fa474dda1134a + Author: Richard Smith + Date: Wed Mar 4 13:27:10 2020 -0800 + + [version.syn] Bump value of __cpp_lib_smart_ptr_for_overwrite to 202002L + to match the adoption date of the paper that introduced it. + + Fixes #3817. + + commit 65e3f2d3cdcb076d452c33cce0dd22ab05e65451 + Author: Dawn Perchik + Date: Wed Feb 19 15:41:14 2020 -0800 + + [cpp.pre][cpp.module][cpp.import] Fix neither-nor wording to include verbs after the "nor" and add punctuation. + + commit 1fb2610634d54893eee344451cd517b964ea9815 + Author: Richard Smith + Date: Tue Feb 25 14:39:19 2020 -0800 + + [cpp.pre] Improve phrasing of restrictions around defining + module/import/export as macros before encountering a module/import + directive. + + commit f4512779aef04905e5238ac9630073cb7c892412 + Author: Richard Smith + Date: Tue Feb 25 13:26:08 2020 -0800 + + [lex.pptoken] Update English description of preprocessing-token to match + the updated grammar. + + commit ef53989b095cc68960fdf4f6e91586c2cc976a91 + Author: Richard Smith + Date: Tue Feb 25 14:19:35 2020 -0800 + + [cpp.pre] Avoid awkward phrasing "the last token in the sequence is the + first token in the sequence [...]". + + commit 2aa4d39cddf0b3bd38138c1cf16ee2e852734162 + Author: Richard Smith + Date: Tue Feb 25 14:25:54 2020 -0800 + + [cpp.pre] Reorder grammar before paragraph 1. + + Avoids a grammar description immediately following an example. + + commit 0b2916563f378fd44d6f0d62080042f6c360e440 + Author: Richard Smith + Date: Tue Feb 25 14:27:54 2020 -0800 + + [cpp.pre] Rearrange grammar into topological order. + + commit 3405cbec344e2be32ff80816d24bcad48e3f29e6 + Author: Richard Smith + Date: Tue Feb 25 14:32:00 2020 -0800 + + [cpp.pre] Clarify that the rule for conditionally-supported-declarations + resolves a parse ambiguity rather than determining program validity. + + commit 19e6a5982e3d5f1837d7415c918628018ca70af3 + Author: Richard Smith + Date: Tue Feb 25 15:29:20 2020 -0800 + + [lex.key] Add a proper grammar production for 'keyword'. + + Move export-keyword, import-keyword, and module-keyword out of our table + of keyword identifiers (where they don't fit) and make them directly be + grammar productions for keyword instead. + + commit ff98c30ce690ef375c73c0a9cf8555e8a774eefe + Author: Richard Smith + Date: Wed Mar 4 13:41:48 2020 -0800 + + [util.smartptr.atomic] Add example from Matthew Butler. + + commit e15a52a4ab45ceed8ce5731558df1c84a4e47c7f + Author: Richard Smith + Date: Wed Mar 4 13:44:35 2020 -0800 + + [temp.constr.atomic] Rephrase to make the meaning of "the same + *expression*" more obvious. + + commit 1eaf966e08f82b327a6ecf2d12a8e207d79c2916 + Author: Richard Smith + Date: Wed Mar 4 13:47:42 2020 -0800 + + [format.string.std] Clarify that "extended grapheme clusters" is defined + by UAX #29, but "estimated widths" is not. + + commit 02fe22bb9aaae190949ab4df53213d6f931eb827 + Author: Richard Smith + Date: Wed Mar 4 13:50:28 2020 -0800 + + [expr.const] Remove example that was made incorrect by P1937R2. + + Fixes #3792. + + commit 1119ab4d9560ca1007a7588b41d3151d2c579c44 + Author: Richard Smith + Date: Wed Mar 4 13:54:00 2020 -0800 + + [time.format] Fix description of - insertion and examples. + + * Place :% in correct order in example. + * Ensure that format specifier is at start of format-specs as required + by the grammar. + * Clarify that 'leftmost' means 'initial', and doesn't mean the final + format specifier in an RTL locale. + + Fixes #3810. + + commit 65784102a44ea16d590145e9468c9bd9d9254dc4 + Author: Richard Smith + Date: Wed Mar 4 14:03:18 2020 -0800 + + [std] Replace undefined term "automatic object" with "object with automatic storage duration" + + Similarly, replace "static object" with "object with static storage duration". + + commit a4589f234e216cb1c0bfd329e1f35d3a3334bc29 + Author: Richard Smith + Date: Wed Mar 4 14:06:34 2020 -0800 + + [temp.pre] Define "templated" not "templated entity" so that we can refer to "templated classes" and "templated functions". + + commit b1343bc461d0a9b03926f1251c419447c8bb57fb + Author: Richard Smith + Date: Wed Mar 4 14:20:09 2020 -0800 + + [expr.comma] Remove vestigial wording describing "temporary expression"s + + This term was replaced by machinery in [class.temporary], which properly handles this case. + + commit a7fc3f39067eeed59b089e9fdf4f2d53d91d9637 + Author: Jens Maurer + Date: Fri Jan 17 21:01:27 2020 +0100 + + [except.spec] Avoid reference to undeclared identifier in example. + + commit 3e9bb331467a32e757e218391f28f1190b80607b + Author: Jens Maurer + Date: Fri Jan 17 21:08:48 2020 +0100 + + [basic.fundamental] Clarify that in C, padding bits may cause traps. + + commit 8ad04ca4a3dfc35ae0096e14ce32acd2424c0d26 + Author: Richard Smith + Date: Wed Mar 4 14:29:10 2020 -0800 + + [dcl.constexpr] Add a note explaining that the result of a constexpr function can vary based on the result of is_constant_evaluated(). + + commit 8d587443a9f09fb040f8620b994ebeb1ea94fa49 + Author: Richard Smith + Date: Wed Mar 4 14:43:16 2020 -0800 + + [dcl.init] Add sub-bullets to description of class value-initialization. + + commit bd4c6deae766fc81388a1cb15e97af8a90784a75 + Author: Thomas Köppe + Date: Wed Mar 4 22:46:31 2020 +0000 + + [swappable.requirements] Add missing \pnum to example and remove stray paragraph breaks around notes. + + commit f7647912cde34959694a128beb1be7f56225c18b + Author: Richard Smith + Date: Wed Mar 4 15:00:43 2020 -0800 + + [class.mem] Add explicit-specialization to member-declaration grammar. + + This is an obvious oversight in the wording changes for CWG 727, whose purpose was to permit explicit specializations as member declarations. + + commit 6639bda6999ee917b6e653bb0971cb29b6606f2e + Author: Richard Smith + Date: Mon Feb 24 18:19:44 2020 -0800 + + [utilities] Cleanups after application of P1460R1. + + * Fix some cases where the library descriptive elements were not in the + right order. + * Remove redundant && in second argument of is_constructible_v to match + similar changes made by P1460R1. + + commit ce2e915455a2f297fff73b5788bc38b5b0841713 + Author: Richard Smith + Date: Mon Feb 24 19:29:04 2020 -0800 + + [basic.life] Add variable names for the old and new object in the + definition of "transparently replaceable" and simplify the exposition a + little. + + commit de25ccdaeda47a5719c9fa6bea1669ad85160d25 + Author: Richard Smith + Date: Wed Mar 4 15:39:34 2020 -0800 + + [extern.types] Strike footnote listing C stdlib types + + This footnote seemed like it was trying to exhaustively list all types imported from the C stdlib, but it was incomplete. Most notably, it was missing the types from ``. Removing rather than fixing since the list is of questionable value and would be likely to become stale again. + + commit 86d9ba406195fd8e0b0fb72723c5258b6cd422f1 + Author: Krystian Stasiowski + Date: Wed Feb 5 02:15:42 2020 -0500 + + [basic.types] Change "(possibly cv-qualified) void" to cv void + + commit 6de55fc7095bedb3aa9bc1f381767c5a6646eb1d + Author: Krystian Stasiowski + Date: Wed Feb 5 02:36:54 2020 -0500 + + [over.match.copy] Change "reference to (possibly cv-qualified) T" to "reference to cv2 T" + + commit 0886da388e11a5777e761df5538bbf84e98847e7 + Author: Krystian Stasiowski + Date: Wed Feb 5 02:41:47 2020 -0500 + + [dcl.init.list] Change "possibly cv-qualified" to cv + + commit 4570e3aacba6cff4add7f9acea652504b1604f2a + Author: Krystian Stasiowski + Date: Wed Feb 5 03:36:22 2020 -0500 + + [class.copy.ctor] Change "optionally cv-qualified" to cv + + commit a9a1e5faa0b805ea8ce8a961789caad5b5c3bb0e + Author: Krystian Stasiowski + Date: Wed Feb 5 03:37:44 2020 -0500 + + [dcl.init] Remove unused definition of a variable + + commit f611368d43b76cb0054c22cbe8cb987a18314e08 + Author: Krystian Stasiowski + Date: Thu Feb 6 15:08:29 2020 -0500 + + [temp.param] Change "optionally cv-qualified" to "possibly cv-qualified" + + commit d1d7769ab58636200e47f1365c61bbde85d8e287 + Author: Alisdair Meredith + Date: Thu Feb 6 03:32:23 2020 -0500 + + [diff.cpp17.iterators] Added compatibility note on iterator_traits + + The specialization of iterator_traits for pointers 'T*' in C++20 is now + constrained by 'is_object_v' and so no longer applies to pointers to + function, or to void. + + commit 1fda54c697dedd973459f67a552b79fd74dd47cb + Author: Casey Carter + Date: Sat Feb 15 14:56:12 2020 +0100 + + [functional.syn] Correct text in cross-reference comment + + commit af6e2d4da60d27cd230f321652868bf118deb001 + Author: Jens Maurer + Date: Sat Feb 22 09:31:04 2020 +0100 + + [concept.swappable,iterator.cust] Fix phrasing 'with no diagnostic required' + + commit 51364a8a7fed97dae305b5264b5204429ac71f6a + Author: Davis Herring + Date: Thu Aug 15 11:45:44 2019 -0600 + + [expr.type] Add "cv-combined" cross-reference + + It was moved to [conv.qual] + + commit 75f00f111ca0650542b2112c98496663870e416a + Author: Davis Herring + Date: Fri Nov 1 17:45:15 2019 -0600 + + [class] Remove misleading [expr.ass] reference + + commit 6db1c3cbb9f056ad6b41a3f3e44bdeddaa526063 + Author: Davis Herring + Date: Tue Feb 25 14:52:59 2020 -0700 + + [rand.util.canonical] Remove self-cross-reference + + commit 1f1c6eac3efc314be2f2a91c15d84f197a3f818a + Author: Dan Raviv + Date: Tue Feb 11 14:38:30 2020 +0100 + + [basic.pre] Improve consistency in list + + commit 63da1a59b0f932bee3f0a5b60286f97bd0c51f02 + Author: Richard Smith + Date: Wed Mar 4 15:59:19 2020 -0800 + + [rand.util.canonical] Convert normative duplication into a note. + + commit 344e9d2180f03eb667fa2cbe6127b82f13017b42 + Author: Frank Birbacher + Date: Fri Feb 14 20:55:30 2020 +0100 + + [stmt.return.coroutine] Use notion of "enclosing" for "return" + + commit 9cdb5763c5449bc1f94cfee6a75cff820060d3d5 + Author: Jens Maurer + Date: Thu Mar 5 21:25:03 2020 +0100 + + [temp.explicit] Add missing comma (#3822) + + commit 12620243dea3c4dd6881f9a1eab39a776b20727a + Author: Casey Carter + Date: Fri Mar 6 09:58:51 2020 -0800 + + [range.prim.cdata] Properly qualify ranges::cdata (#3793) + + commit 417053a6c695e69dc8b2be3ba690ae3e5eff0964 + Author: Casey Carter + Date: Thu Mar 5 11:33:33 2020 -0800 + + [front.insert.iterator] Correct mis-incorporation of P0896R4 + + What should be a defaulted default constructor is instead an ill-formed defaulted non-default constructor. This appears to be copy pasta from the original merge of P0896R4 in e85af9533ab6ab0f0b101ac61fc01ba47c406503. + + commit 8197fe6fce017d4929817541a5ffcdc9a6080242 + Author: Jens Maurer + Date: Sat Jan 11 11:58:25 2020 +0100 + + [over.oper] Clarify handling of individual operators. + + commit 9a408b17e1f20dad977b83deffe041f3d83b91b5 + Author: Jens Maurer + Date: Sat Jan 11 12:04:54 2020 +0100 + + [over] Use \keyword{operator} markup. + + Also use "cv1 T1" to concisely express that T1 is cv-unqualified. + + commit 9bf27483a8ac7603d70810ed0373338494820d71 + Author: Jens Maurer + Date: Mon Jan 13 22:34:49 2020 +0100 + + [over.oper] Clarify that operator functions must declare one of the allowed operators. + + Also turn explanatory material into a note. + + commit 2092becfe2fed97d95257efb78199f917cd0aa09 + Author: Jens Maurer + Date: Thu Jan 16 23:30:59 2020 +0100 + + [over.literal] Move out of [over.oper]. + + commit 00b66a1b8bd9389811ab81d0528ad09ad1960455 + Author: Richard Smith + Date: Fri Mar 6 15:40:33 2020 -0800 + + [over.oper] Consistently separate rewritten forms out from the running + text. + + [over.ref] Convert "->" to code font in rewritten form. + + commit 309f0afcb75d644cc52590cee2198a1f5626a19b + Author: Richard Smith + Date: Wed Feb 19 17:58:34 2020 -0800 + + [diff] Consistently format name of prior standards. + + commit df2f32725d6481b900e0b0f32fca51fceeb7ecfd + Author: Richard Smith + Date: Wed Feb 19 18:01:44 2020 -0800 + + [diff.cpp17.basic] Fix example added by P0593R6. + + Pseudo-destructors weren't permitted in constant expressions before + C++20. + + Fixes #3742. + + commit b4f66cf75f74f752f082ec495309cf36ef63be77 + Author: Richard Smith + Date: Wed Feb 19 18:07:54 2020 -0800 + + [basic.life] Update out-of-date wording to mention that + pseudo-destructors end the lifetime of an object. + + Fixes #3743. + + commit e1292d9747f16114b5ba83e82358552474902aa3 + Author: Richard Smith + Date: Tue Feb 25 15:53:20 2020 -0800 + + [intro.object] Remove note unhelpfully pointing out that C++ has types. + + commit b79babd1f932cf4db11eb9e05713c015ce4855c7 + Author: Johel Ernesto Guerrero Peña + Date: Thu Feb 27 19:01:45 2020 -0400 + + [any.synop,any.class,any.nonmembers] Format pack conventionally + + commit 98e736fac115efe282d635ab2b793cb89998c55a + Author: Jens Maurer + Date: Sat Jan 25 13:13:12 2020 +0100 + + [lex.icon,lex.fcon] Rework description to avoid redundancies. + + Also use the grammar non-terminals integer-literal and + floating-point-literal throughout the standard. + + commit cd3c0765aecfaf0167b4a9c88ad152a10b803e29 + Author: Jens Maurer + Date: Sat Mar 7 08:11:25 2020 +0100 + + [algorithms] Rename concept 'writable' to 'indirectly_writable'. + + Missed edits from application of P1878R1 (2019-11 LWG Motion 9). + + commit 18788a7812efc1e23a29b360fc7d98ad8b9a92e9 + Author: Kerdek + Date: Sat Mar 7 13:38:40 2020 -0500 + + [expr.ref] Fix terminology in description of access of non-static data members + + Objects have subjects, not members. + + commit 1e18d4cbf57fcd6a88452c1b54748980c88c5b6a + Author: Johel Ernesto Guerrero Peña + Date: Wed Feb 26 22:11:30 2020 -0400 + + [allocator.members] Replace SIZE_MAX with numeric_limits::max() + + commit 052b91a8e145bb5e01ae9b6bd307fb490c201cef + Author: Hubert Tong + Date: Tue Mar 3 12:25:48 2020 -0500 + + [class.friend] Add cross-reference for the namespace of the friend + + The cross-reference for "linkage of the namespace of which it is a + member" is useful for determining the linkage if the namespace is known; + however, there was no cross-reference to assist with determining the + namespace. + + A cross-reference to [namespace.memdef] is added. + + commit 24d517bc210a6e5f032da92785126c5fe77c36f3 + Author: Alisdair Meredith + Date: Sat Mar 7 13:49:33 2020 -0500 + + [util.smartptr.atomic] Apply conventional order to members of atomic smart pointers + + There is a consistent ordering of declarations for members + of std::atomc specializations, other than for the atomic + smart pointers. This patch reorders the declarations to + follow that convention. + + commit 8fc95077300d2691f4c5c25fcfd7b15e8987cc67 + Author: Krystian Stasiowski + Date: Mon Feb 17 21:03:16 2020 -0500 + + [basic.type.qualifier] Remove redundant wording + + commit e3fa5b5d10decc7b99ca37cc05dcddb2dee845a5 + Author: timsong-cpp + Date: Sat Mar 7 22:05:38 2020 +0100 + + [concept.constructible] is-default-initializable is not a concept (#3834) + + commit 34fcf8b77d33940ae564384ccb9264a6a52589c9 + Author: Jens Maurer + Date: Sun Mar 8 22:41:22 2020 +0100 + + [module.interface] Fix typo. (#3840) + + commit 645a1e4ff7d1ef1ad3ce527e758f9a350b1b6702 + Author: Jens Maurer + Date: Mon Mar 9 08:49:30 2020 +0100 + + [algorithms.general] Add [specialized.algorithms] to summary table. (#3838) + + commit 188de05527a9ea59ad7cf4f3a294a8356a4400f3 + Author: timsong-cpp + Date: Tue Mar 10 08:30:41 2020 +0100 + + [time.zone.zonedtime.overview] Fix typo (#3846) + + commit bcfa94647bf461766ba76fc4513aa75f4dc36394 + Author: Jonathan Wakely + Date: Tue Mar 10 19:44:05 2020 +0000 + + [range.split.outer,range.split.inner] Fix misuses of current_ (#3849) + + This restores references to the 'current' placeholder. + + commit f195f2300c212e7485f05606b28afa58a91c47f2 + Author: Jens Maurer + Date: Tue Mar 10 23:01:57 2020 +0100 + + [expr.prim.req,temp.concept] Add std:: qualification for library concepts + + used in core language clauses. + + commit 0559394e1c43f0595ff04868d809d289496e3ae4 + Author: Jens Maurer + Date: Tue Mar 10 22:50:28 2020 +0100 + + [basic,support] Correctly use 'startup' and 'start of program' + + commit 146c98453bf6292186a9020f0598ae03e050aae3 + Author: Jens Maurer + Date: Tue Mar 10 22:38:58 2020 +0100 + + [support] Renamed from [language.support]. + + commit 6025a8825ee068093064919274a1286a3ceb8df1 + Author: Jens Maurer + Date: Tue Mar 10 21:55:16 2020 +0100 + + [depr.conversions] Rename snake_case template parameters to CamelCase. + + commit c5be3ccf5cd5635ba3847acce70de64bf72a9ae9 + Author: Jens Maurer + Date: Sun Mar 8 22:43:03 2020 +0100 + + [over.oper] Make statement about non-overloadable operators a note. + + commit 4f0377b81e2b470d2d141c3ab6758957a74b21fa + Author: Jens Maurer + Date: Tue Mar 10 22:35:07 2020 +0100 + + [range.take.while.sentinel,range.elements.iterator] Rename exposition-only base-t to Base. + + commit 829b921bdc8be954fc3680088ffc38dc1d4d106a + Author: Jens Maurer + Date: Tue Mar 10 21:45:45 2020 +0100 + + [res.on.requires] Move description of 'Requires' element to Annex D + + commit cb02e1103df3f0c8744ca6620ec02e0ca5bc41a6 + Author: Jens Maurer + Date: Tue Mar 10 21:33:52 2020 +0100 + + [contents] Some standard library functions are not defined. + + commit 52e653f6211326beeceb2e68bda8a12abcb9e062 + Author: Jens Maurer + Date: Tue Mar 10 21:26:45 2020 +0100 + + [span.deduct] Rename template parameter 'End' to 'EndOrSize' + + because it also covers the size_type constructor of span. + + commit 611fda7e0caad0977ba40a836f9eaa1e30904ae7 + Author: Krystian Stasiowski + Date: Sun Mar 8 18:39:15 2020 -0400 + + [class] [over] Redundant specification of ignoring move special members + + commit 37deb529b19609e2494626af5d8bdf25f3833ab3 + Author: Jens Maurer + Date: Sun Mar 8 22:16:48 2020 +0100 + + [module.interface] Remove redundant bullet for exported declaration. + + commit aaf725a9363213124afd7edf7494b88ac77728e6 + Author: Alisdair Meredith + Date: Sat Mar 7 12:10:07 2020 -0500 + + [atomics] Consistent use of enum class memory_order + + Since the application of P0439R0, the library wording has been partially + updated to use the new scoped enumaration values whenever memory order + constants are required, and partially retains use of the inline + constants supplied for back compatibility. + + This patch conistently uses the memory_order::enumerators, retaining + the old name only for their declaration, the index, and for Annex C + wording on C++17 compatibility, which /should/ use the old spelling. + + commit f61e49e572f53e91ff6ffee2842dc8cfcd32f9d3 + Author: timsong-cpp + Date: Wed Mar 11 18:43:11 2020 +0100 + + [support.types.byteops] Fix misapplication of LWG2950 (#3863) + + commit 7d54b05c80c0907e97a3b49bd905f91ed3d8a186 + Author: timsong-cpp + Date: Tue Mar 10 23:46:14 2020 -0500 + + [module.unit] module-declarations no longer contain \tcode{export} + + commit 14eb15322b7b2ef1be249d6ce7ce447123504237 + Author: Jens Maurer + Date: Tue Mar 10 22:23:35 2020 +0100 + + [range.access] Introduce 'reified object' to simplify the descriptions. + + commit 65158c0bdc7705f41f0dbcc102dd456cba6ad496 + Author: Jens Maurer + Date: Mon Mar 9 08:47:31 2020 +0100 + + [class.mfct] consteval member functions are also inline. + + commit f471be1e24be13549e375af62e05b2b22ff17e12 + Author: Jens Maurer + Date: Wed Mar 11 22:45:27 2020 +0100 + + [depr.atomics] Use enum class memory_order + + commit 9c30324fc1347757075f2631eb3a99df6c916560 + Author: Jens Maurer + Date: Thu Mar 12 02:11:37 2020 +0100 + + [lex.ccon,lex.string] Remove redundant repetition of the grammar. + + Also use the grammar non-terminals character-literal and + string-literal throughout the standard. + + commit 74a9547bf3910d68f5c8a07a5625444d58354ee2 + Author: timsong-cpp + Date: Wed Mar 11 19:37:03 2020 -0500 + + [support.types.byteops] remove redundant static_cast to unsigned char + + These casts are redundant after CWG2338. + + commit 85121a254c5f013af41a305ad008586a595b208e + Author: Casey Carter + Date: Tue Feb 18 21:41:23 2020 -0800 + + [ranges] Correct outer template-heads to match primary template constraints + + commit ac3fceec6107d67ed69535583ad83e35da9de218 + Author: Casey Carter + Date: Tue Feb 18 21:47:29 2020 -0800 + + [range.elements.view] Add cross-reference to elements_view::iterator + + commit b83f0203f473289f2252c0c5489f7226c1abdeb4 + Author: Alisdair Meredith + Date: Thu Mar 12 17:15:52 2020 -0400 + + [support.dynamic] Improve cross-referencing for dynamic memory subclauses + + Update several cross-references to subclause 17.6 with more precise + references to subclauses nested one level deeper. For the synopsis + of the header, added a couple of banner comments with cross-references + too. + + commit 3139172b410bd975d29e3074c137542ce2b64467 + Author: Krystian Stasiowski + Date: Fri Mar 6 14:52:18 2020 -0500 + + [basic], [expr] Fix incorrect cross-references to [conv.ptr] for null pointer values + + commit 56c88a59e31413f94203e6a4f5dc961e84dd79de + Author: Daveed Vandevoorde + Date: Thu Mar 12 17:45:52 2020 -0400 + + [expr.const] Add article to bullet start, to parallel the other bullets. + + commit 61763ed574e73949323008b8c8479c793408ea06 + Author: Jens Maurer + Date: Thu Mar 12 23:06:46 2020 +0100 + + [allocator.requirements] Fix punctuation in tables. + + commit 31a1a94d409ceb0c699849af807364142bcd8026 + Author: Casey Carter + Date: Fri Feb 21 11:05:40 2020 -0800 + + [alg.clamp] Reword for clarity + + Define `comp` and `proj` for the overloads with no such parameters and spell out the meaning of the handwavy "is no greater than" and "is less than". + + commit b7c0d7130f6a28e42f5f7252248ec29b7fee17fa + Author: Jonathan Wakely + Date: Fri Feb 21 12:13:22 2020 +0000 + + [ostream] Fix poor grammar to be consistent with [istream] + + Also fix grammar in [istream], [istream.extractors] and + [ostream.inserters] to refer to "*the* error state", and use "is set in" + when talking about a bitmask element being set in a value of a bitmask + type. + + Fixes #3333 + + commit 948775f73bfc51fec14d6b6fb200a88d199c6f1a + Author: Johel Ernesto Guerrero Peña + Date: Mon Dec 30 18:20:11 2019 -0400 + + [range.req.general, range.sized] Fix and improve description + + commit b6d9e27e75b10cfb0a5f0a99343cce3697042c21 + Author: JF Bastien + Date: Thu Mar 12 17:39:44 2020 -0700 + + [depr.volatile] Add examples of deprecated constructs + + commit 1866b054b98ad872fd50a017a99502398f8cc96a + Author: Richard Smith + Date: Fri Mar 13 17:13:23 2020 -0700 + + [diff] Reverse order of subclauses and add "in addition to those listed + above" to each introductory sentence after the first. + + Fixes #537. + + commit b2e7b06b5855bc43d92bde86c0fd716f4a847b22 + Author: Thomas Köppe + Date: Tue Mar 17 01:25:07 2020 +0000 + + [depr.strstreambuf] Remove extraneous parenthesis and excessive linebreaks + + commit 6c6e08479d7f83b33134e8d52049fddc120d25bb + Author: Jens Maurer + Date: Thu Mar 12 22:46:22 2020 +0100 + + [alg.replace] Clarify which value gets assigned depending on E. + + commit 25f6538adb1b2a9cfaca257137befa8aabcf879f + Author: Davis Herring + Date: Mon Mar 16 23:55:18 2020 -0600 + + [tuple.cnstr] Remove (redundant) && per P1460R1 + + commit cc4b3a7aca374d76ec11b870a353bd47ce53d803 + Author: Davis Herring + Date: Tue Mar 17 00:06:50 2020 -0600 + + [bitset.cons] Remove () per P1460R1 + + commit d34fb9a542c3a9873e49e53a8a86eccfdd336109 + Author: Casey Carter + Date: Tue Mar 17 15:41:38 2020 -0700 + + [version.syn] Fix mis-ordering of __cpp_lib_{bind_front, bit_cast} + + commit 0391d1f1ffe3fab1e6052b9c61ddefae13083637 + Author: Davis Herring + Date: Mon Mar 2 14:51:57 2020 -0700 + + [temp.inst] Make note more precisely describe when function (template) constraints are checked. + + commit aa92bdb2b29af48820f0e0a45c85e4533fd5ed01 + Author: Davis Herring + Date: Mon Mar 2 16:25:59 2020 -0700 + + [lex.pptoken] Fix note grammar + + commit 1c20e8179aba5bbb61c4644ab840677deff470fa + Author: Davis Herring + Date: Mon Mar 2 18:00:34 2020 -0700 + + [diff.cpp17.lex] Harmonize example comments + + commit 906dacd0b6424689537abb7349fdad0c83d1c62c + Author: Davis Herring + Date: Fri Mar 13 17:56:23 2020 -0600 + + [temp.func.order] Clarify that optional parameters count + + Move note to avoid confusion + + commit fad3cd32b97f61cc5d1e1a7e49fac4eaeacf5c89 + Author: Davis Herring + Date: Mon Mar 16 12:47:28 2020 -0600 + + [module.private.frag] Add missing inline cross reference + + commit 36ac6c50b197b5d1c1fea8d0a2faf15f07bbfab2 + Author: Davis Herring + Date: Mon Mar 16 13:55:16 2020 -0600 + + [class.compare.default] Trim pedagogical <=>/== note + + commit 1208fce3fa53ce9107068b6ef9c57c9f65532037 + Author: Richard Smith + Date: Tue Mar 17 17:08:45 2020 -0700 + + [cpp.pre] Simplify global module fragment restriction + + commit 8bc2a1a4bb38b4f0e9de09bd0ac3d6d0565a1f79 + Author: Davis Herring + Date: Mon Mar 2 17:47:07 2020 -0700 + + [cpp.pre] Simplify macro restrictions + + commit 263597b8755d815fcfc894cde8047be72d7d0b1b + Author: Davis Herring + Date: Mon Mar 2 18:11:47 2020 -0700 + + [intro.object] Avoid implying multiple sets of implicit objects + + commit 515da67958cf95d803f8b8a117dbb16c5bc152f2 + Author: Davis Herring + Date: Fri Mar 13 14:00:32 2020 -0600 + + [temp.over.link] Clarify type-constraint equivalence requirement + + commit 49cb1f0e5c769ad1589555b0a79f8e3cb576a575 + Author: Davis Herring + Date: Fri Mar 13 14:10:25 2020 -0600 + + [temp.func.order] Use English for deducible template parameters + + commit 7f7eecb699b304ae6f67b290554ef253e0048869 + Author: Davis Herring + Date: Fri Mar 13 17:59:45 2020 -0600 + + [basic.def.odr] Remove vestigial comma + + commit 604f0962c027b52aff0edbfae2cbcf43a52863cc + Author: Davis Herring + Date: Fri Mar 13 18:01:06 2020 -0600 + + [basic.def.odr] Clarify cohorts of unnamed enum definitions + + commit cb6658e192e99038bb6138f959f311e96203835f + Author: Davis Herring + Date: Fri Mar 13 18:10:53 2020 -0600 + + [basic.def.odr] Remove redundant "of D" + + commit 656b9ec8ba52b6c926d5ceffa186b93317307669 + Author: Davis Herring + Date: Mon Mar 16 13:02:26 2020 -0600 + + [temp.variadic] A capture has only one relevant ellipsis + + commit 7b96c0ecd0542ac5a53ac63c52e6d75bdbdee83f + Author: Davis Herring + Date: Mon Mar 16 14:39:49 2020 -0600 + + [dcl.attr.grammar] Fix parallelism + + commit a6f9f98a4270b79da91de633a0dfcd919c3bb587 + Author: Davis Herring + Date: Mon Mar 16 14:40:31 2020 -0600 + + [dcl.attr.grammar] Simplify std:: for attributes + + commit 33cdcf1ff118c6dc5513bf48e351f5ee723eca48 + Author: Davis Herring + Date: Tue Mar 24 12:32:13 2020 -0600 + + [module.import] Clarify interface dependency definition + + commit 81eaf24933acff460376d40602dbfa33af1131f8 + Author: Davis Herring + Date: Fri Mar 20 10:21:33 2020 -0600 + + [lib] Fix ;s in itemdecls + + One was missed from P1983R0 + + commit 7feffc4cfde21241a4734c5d9cf554a2d14b7fe2 + Author: Davis Herring + Date: Tue Mar 24 08:51:16 2020 -0600 + + [concepts.equality] Fix grammar for P2102R0 + + commit 10f2bf5f7c1c222d41fb57085f7ddf0e0362d835 + Author: Davis Herring + Date: Tue Mar 24 11:24:58 2020 -0600 + + [stmt.expr] Fix cross reference + + commit a48408f12ad8d25fa99214748853ddcbba299634 + Author: Davis Herring + Date: Tue Mar 24 14:47:15 2020 -0600 + + [concept.booleantestable] Use tie before cross references + + commit 4b34a8a2e32268de7aba8f091af1282e45b8744f + Author: Davis Herring + Date: Tue Mar 24 14:47:22 2020 -0600 + + [concept.booleantestable] Provide value category to deduction + + commit db4208f1ebdad13b99ad1a8b34f051d0fa92039e + Author: Davis Herring + Date: Wed Mar 25 22:19:37 2020 -0600 + + [module.reach] Remove impossible private-module-fragment case + + commit 30f37e0027b06a233b4d572ed3c8d577a3a11a7d + Author: Richard Smith + Date: Thu Mar 26 17:47:07 2020 -0700 + + [intro.object] Fix hyphenation. + + commit 69d331ff4d7ba651da8b1f998f74fedaca0c9aa4 + Author: Richard Smith + Date: Thu Mar 26 17:47:33 2020 -0700 + + [temp.func.order] Fix hyphenation. + + commit 5e01d592a2276bd48c16bf199b8f3c38f57e41a9 + Author: Richard Smith + Date: Thu Mar 26 17:47:48 2020 -0700 + + [temp.variadic] Make xref more precise. + + commit 2fa3e8c8cea3ab90e04f459568b06f91ebd5b233 + Author: Richard Smith + Date: Thu Mar 26 19:27:37 2020 -0700 + + [expr.prim.literal] Rephrase slightly to avoid 'which' sounding + restrictive. + + commit 4f2f5811d4d4f45679e0a09e2cf105f9535db8c6 + Author: Richard Smith + Date: Thu Mar 26 19:32:25 2020 -0700 + + [class.copy.elision] Make wording more parallel by removing redundant wording. + + commit 224ad02b418f104ddebdc41c3267fddfbe2c4542 + Author: Richard Smith + Date: Tue Mar 31 11:52:37 2020 -0700 + + [time.zone.db.tzdb] Say where we look for time_zones, and avoid + readability problem with 'If a time_zone tz is found' phrasing. + + Fixes #3892. diff --git a/papers/n4867.md b/papers/n4867.md new file mode 100644 index 0000000000..7d23979723 --- /dev/null +++ b/papers/n4867.md @@ -0,0 +1,1375 @@ +# N4867 Editors' Report -- Programming Languages -- C++ + +2020-10-18 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Special thanks to +Eelis van der Weegen and +Krystian Stasiowski +for providing numerous editorial fixes, and to +Jonathan Wakely +for checking the correctness of +several editorial changes to the library specification. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4868](http://wg21.link/n4868) is the current working draft for C++23. It + replaces [N4861](http://wg21.link/n4861). + * N4867 is this Editors' Report. + +In addition, NB and ISO/CS comments provided on ISO/IEC DIS 14882:2020(E) have +been addressed and an editorially revised final C++20 standard has been +transmitted to ISO for publication. The below text indicates which changes were +applied to both the C++20 IS and which were applied only to the C++23 working +draft. + +## Motions incorporated into working draft + +This revision contains only editorial changes relative to N4861. + +## Notable editorial changes to C++20 and the working draft + +The changes listed below were mostly driven by comments received on the C++20 +DIS, and were applied to both the C++20 IS and the current working draft. + +### Clause 2: Normative References + +At the request of ISO/CS, we have ensured that all documents listed in Clause 2 +are normatively referenced by the body text, and moved the remaining instances +to the Bibliography. + +Subclause [fs.norm.ref], the "Normative References" subclause for the +filesystem portion of the library, was merged into Clause 2 and dissolved. + +### Clause 3: Terms and Definitions + +At the request of ISO/CS, the standard library "Terms and definitions" +subclause has been merged into Clause 3. + +### Hanging paragraphs + +At the request of ISO/CS, each section contains either two or more subclauses +or some body text, never a combination of both. To support this, a few +single-item subclauses were dissolved, and many "General" subclauses were added +to contain the body text in sections that used to contain both subclauses and +body text. + +### Notes and examples + +At the request of ISO/CS, each note and example is now separated from +surrounding text by line breaks, and notes and examples are rendered in a font +size one point smaller than the body text. + +### Modal verbs + +At the request of ISO/CS, we have fixed a number of occurrences of +inappropriate use of the modal verbs "shall", "may", "can", "must", "should", +"might", and "could" and implemented automated checking to ensure that the +normative verbs "shall", "should", and "may" do not appear in non-normative +contexts. + +The fixes included changing the verb in use, rephrasing, and in some cases +converting notes that contained normative requirements or normative +encouragement into non-note body text. + +### Misapplied motions + +We found a small number of cases where a motion for C++20 had not been fully +applied and fixed them. + +## Notable editorial changes to the working draft only + +### Terms and definitions + +The subclause [re.def], which is another "Terms and definitions" subclause, has +been merged into Clause 3. Unfortunately, this additional subclause was not +noticed in time to be fixed for the C++20 IS. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4861 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/n4861...n4868). + +### Changes in both the C++20 IS and the C++23 working draft + + commit 7b21df79e0e33b541c4ca298a0eed795223f3a72 + Author: Davis Herring + Date: Thu Mar 26 13:59:18 2020 -0600 + + [basic.link] Add word missing from P1815R2 + + commit d7f2e2c99116b0b16b311abba5a3a741638ec442 + Author: Krystian Stasiowski + Date: Fri Apr 3 21:44:35 2020 -0400 + + [over.match.class.deduct] Fix self-referential cross-references + + commit 58082ce1724e74799abc89b658ea3a4132f88b7f + Author: Krystian Stasiowski + Date: Fri Apr 10 03:59:18 2020 -0400 + + [dcl.fct.def] Fix incorrect cross-reference referring to "this" (#3925) + + commit cf14e9fb59c89d7811ca15b3f678ff27f079c42f + Author: Krystian Stasiowski + Date: Fri Apr 10 04:10:51 2020 -0400 + + [class.temporary, expr, dcl.ref] Fix incorrect cross-references for decltype (#3918) + + commit b545c32e23b0d8bbc98c91c4c8fb9501ec40c33e + Author: Casey Carter + Date: Sat Mar 21 18:46:07 2020 -0700 + + [iterator.synopsis] move_iterator non-member operator+ should agree with [move.iter.nonmember] + + P0896R4 changed the declaration in [move.iter.nonmember], but failed to update the header synopsis. + + commit b9780b4f4ffe3b3c226e0d227e3b30e2b2f80797 + Author: Jens Maurer + Date: Sun Apr 19 20:49:14 2020 +0200 + + [depr.atomics] Fix header name. (#3948) + + The typo was introduced in commit bbb46260d5dd0bb8b561cc74f929ac9a982629a9 + while applying P0883R2 Fixing Atomic Initialization. + + commit c4c52b55bdcf2f8cd3a7250d452a154863983502 + Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com> + Date: Thu Apr 23 20:39:19 2020 +0200 + + [format.syn] Add missing reference to [format.context] in header synopsis (#3954) + + commit 8419960fc7125ff442ee98f55f8c07fb0e34d4f8 + Author: Krystian Stasiowski + Date: Sun May 3 16:41:55 2020 -0400 + + [over.ics.ref] Remove erroneous capitalization (#3972) + + commit f28e328813d9e4bbcf1a78affbfd8112ac739832 + Author: Casey Carter + Date: Sun May 3 13:55:00 2020 -0700 + + [meta.trans.other] "C++ object type" is overly precise (#3969) + + ... suggesting that the more common plain "object type" means something different. + + commit 6e2fa20c9a9109eba96ceaecac0bb54c60833985 + Author: cor3ntin + Date: Wed May 6 19:35:40 2020 +0200 + + [range.elements.iterator] Fix typo in declaration of operator<= (#3981) + + commit 932e40cb5ebf786c5992b552a538949f667acdeb + Author: NinaRanns <57705710+NinaRanns@users.noreply.github.com> + Date: Tue May 12 19:50:45 2020 +0200 + + [common.iter.cust] Pluralize subclause heading (#3995) + + to match [counted.iter.cust] + + commit e674373e2515868ca17b24157f30515fad62b8e6 + Author: Johel Ernesto Guerrero Peña + Date: Sun May 17 15:47:04 2020 -0400 + + [atomics.types.operations] Fix typo in exposition-only code (#4001) + + commit fc974c321e130e15e3be4eb12e213be00929d43a + Author: Sergey Zubkov + Date: Mon May 18 18:21:03 2020 -0400 + + [class.temporary] Omit hyphen from "trivially copyable" (#4002) + + commit 79c665c562cb6452b56aa02193eccccc8d4e40fa + Author: Johel Ernesto Guerrero Peña + Date: Sat May 23 04:39:07 2020 -0400 + + [range.single.view] Add missing requires-clause to \itemdecl (#4009) + + commit f258f946045daac7d8d83f45342ec64eedce8068 + Author: frederick-vs-ja + Date: Sat May 23 16:47:59 2020 +0800 + + [thread.syn] Do not mandate including when including (#3991) + + This was accidentally introduced while applying + LWG3330 Include from most library headers. + + commit 4d73f95a6d246ba465fd3880d2b530dc54625543 + Author: Jens Maurer + Date: Sat May 23 10:55:08 2020 +0200 + + [vector.capacity] Remove duplicate \pnum (#3983) + + Also prevent future occurrences by updating check.sh + + commit f87e0d26f1ca7d13bbf889f065b53cbd25f5d49a + Author: Eelis + Date: Fri May 29 21:01:26 2020 +0200 + + [iterator.concept.forward] Undo spurious list item capitalization. (#4017) + + commit dd52b4778a6c68c0a707ac5c067de5e4eabf96fc + Author: Johel Ernesto Guerrero Peña + Date: Tue Jun 2 05:45:38 2020 -0400 + + [algorithms.general] Add [algorithms.results] to summary table (#4020) + + commit 6f9b5e8e57dbf8c1bd46309926418df7b177a88c + Author: Johel Ernesto Guerrero Peña + Date: Tue Jun 9 02:37:32 2020 -0400 + + [ranges.general] Capitalize the word 'clause' (#4029) + + commit 657711448680df5aaa4e7a7e8e62184b14f79638 + Author: Johel Ernesto Guerrero Peña + Date: Thu Jun 11 02:36:22 2020 -0400 + + [string.view.template] Wrap synopsis in its namespace (#4038) + + commit 983e8ee95f490284680f23487fac221333f4ba62 + Author: Eelis + Date: Sat Jun 13 08:45:58 2020 +0200 + + [container.requirements.general] Remove parentheses for 'equal()' outside of a function call expression. (#4043) + + commit 3a3350ee86fb2dbc86752af66d56102d237d8c4f + Author: Jens Maurer + Date: Mon Jun 15 20:52:16 2020 +0200 + + [structure.specifications] Integrate [res.on.expects]. (#4042) + + The latter consisted of a single sentence that is + best integrated into the place where the Preconditions: + element is introduced. + + Also fixes LWG3168. + + commit 239dfe7ed9e0f361e8f2d799d97305cfb8ace5be + Author: Johel Ernesto Guerrero Peña + Date: Wed Jun 24 01:53:45 2020 -0400 + + [expr.const] Remove duplicate cross-reference (#4055) + + commit 640d6a2dd50fe32b122fe4050a3c072c4d9a43ba + Author: frederick-vs-ja + Date: Wed Jul 22 03:33:07 2020 +0800 + + [istream.syn,ostream.syn] update synopses according to LWG1203 (#4084) + + Edits missed by commit ffb23d0521af5a8795fc051d2915858d00518d41. + + commit e688140e955fc747ca06cc705e60144536bde4d6 + Author: Eelis van der Weegen + Date: Fri Jul 3 05:03:45 2020 +0200 + + [iterator.requirements.general] Add missing comma. + + commit de443df351fdecd010633fbadde0d793d0005616 + Author: Eelis van der Weegen + Date: Sun Jul 5 20:26:39 2020 +0200 + + [list.ops] Add missing full stop at end of sentence. + + commit e86af2d73eab36c93a6e471cb0503d280e59abe4 + Author: Casey Carter + Date: Mon Jul 27 23:14:52 2020 -0700 + + [mask.array.assign] Replace "it" with its antecedent (#4095) + + Many nouns appear in this sentence before "it", _none_ of which is the proper antecedent. + + commit e224430986ce8800de375ee975e0d89a64365fc7 + Author: Casey Carter + Date: Mon Jul 27 23:16:07 2020 -0700 + + [mask.array.comp.assign] Clarify "mask object" (#4096) + + Use "mask_array object" instead. + + commit 7d1367694aa31775b9ef1c0ff094d6e4b9892a19 + Author: Eelis van der Weegen + Date: Fri Jul 31 06:15:52 2020 +0200 + + [std] Add missing \pnums. + + commit 1c5f448f2edc4cbab1cb9c006ea10f022b3d57e7 + Author: Casey Carter + Date: Sat Aug 1 13:08:19 2020 -0700 + + [ranges.syn] Properly capitalize "this Clause" (#4103) + + commit 521b49ae7c3a641c3dc6e9161e01abd69eb2a16d + Author: Billy O'Neal + Date: Tue Aug 18 13:31:30 2020 -0700 + + [thread.condvarany.intwait] Remove reference to nonexistent variable "cv". (#4115) + + commit 5170ca37e665950ac0731e8a296c4dfa4cf405ae + Author: Johel Ernesto Guerrero Peña + Date: Mon Aug 24 03:04:33 2020 -0400 + + [fs.race.behavior] Fix cross-reference to self (#4122) + + commit 72144dd1bd9dcd8f84db64eb3fedf365d86db3b7 + Author: Casey Carter + Date: Mon Aug 31 03:47:32 2020 -0700 + + [ranges.syn] Fix declaration of transform_view (#4132) + + ... to agree with the declaration in [range.transform.view] as modified by LWG3325. + The resolution of this LWG issue failed to direct the Editor to also change + the declaration in [ranges.syn]. + + commit d52a10d0f85a6822ba01d29740eac013e6ddb231 + Author: Eelis + Date: Thu Sep 3 22:27:11 2020 +0200 + + [tab:atomic.types.pointer.comp] Fix column captions. (#4137) + + commit 95adee080d2b75e65a0662cdd37e26dd6e016187 + Author: Casey Carter + Date: Thu Sep 3 13:29:33 2020 -0700 + + [ranges.syn] Remove bogus ; after requires-clause (#4128) + + commit 392c6d319aac290885820eb4ef029ea458cbb12e + Author: Johel Ernesto Guerrero Peña + Date: Thu Sep 3 16:38:22 2020 -0400 + + [lib] Fix uses of "clause" (#4104) + + commit 43b739bf5a7a3edc47bb712bfb873f48b26d3f2a + Author: Jens Maurer + Date: Tue Sep 8 21:02:40 2020 +0200 + + [range.elements.iterator] Add missing 'friend' for operator-. (#4158) + + commit 06b83178c131cde51526a1fd68925b73f2f699e5 + Author: Jens Maurer + Date: Mon Sep 7 23:13:15 2020 +0200 + + [macros] Fix PDF links to clauses and annexes + + Such links were pointing to immediately after the clause + or annex title, not to immediately before them. The issue + was introduced with commit beb88157cc49f76677fc467db8ec4a523dbc41d0. + + Fixes NB JP 014 and JP 015 (C++20 DIS) + + commit 33f4041750b8ee43b5ff10f8be8e451d1a94eec9 + Author: Jens Maurer + Date: Mon Sep 7 09:19:58 2020 +0200 + + [except.uncaught] Remove parentheses when not invoking a function + + Fixes NB JP 013 (C++20 DIS) + + commit 2850139be6285ba10a64fb718125a80ca967c631 + Author: Richard Smith + Date: Wed Sep 9 11:55:23 2020 -0700 + + Fix all hanging paragraphs by adding "General" sections. + + Fixes ISO/CS 018 (C++20 DIS). + + commit 5ca9b3590698fc23e36fbc6078739d2ae137b292 + Author: Richard Smith + Date: Wed Sep 9 14:56:24 2020 -0700 + + Replace "this subclause" with an explicit reference in all + formerly-hanging paragraphs. + + These typically mean the parent subclause now. Mechanically: + + "this subclause" became "\ref{parent}". + + "This subclause" became "Subclause \ref{parent}", because it doesn't + look great to start a sentennce with a subclause number. + + ... with some manual fixups for cases where that didn't work out well. + + commit 5afb4eefc9de26d3425a9cd0ec0476c5a1ce1dc4 + Author: Jens Maurer + Date: Thu Sep 10 00:19:45 2020 +0200 + + [intro.ack] Dissolve subclause. + + Integrate trademark acknowledgements into [intro.refs]. + Add base works to the bibliography. + Remove introductory sentence from the bibliography. + + Partially addresses ISO/CS 016 (C++20 DIS) + + commit 488e83da234d92bd750dc451cbd7dbd8d58a2a56 + Author: Jens Maurer + Date: Wed Sep 9 17:52:16 2020 +0200 + + [std] Use prefix 'Annex' for chapters in the table of contents. + + Partially addresses ISO/CS 016 (C++20 DIS) + + commit 2ff5f6dd755b67e32aa609c8a2d00ab4554bcd16 + Author: Jens Maurer + Date: Wed Sep 9 18:07:07 2020 +0200 + + [std] Remove 'of this document' after hyperlinked clause references. + + Partially addresses ISO/CS 016 (C++20 DIS) + + commit 2b2cf34a217779d245cb6c805fa377884bc1b9ec + Author: Jens Maurer + Date: Wed Sep 9 18:17:29 2020 +0200 + + [description] Remove vacuous 'normative' statement. + + Partially addresses ISO/CS 016 (C++20 DIS) + + commit 42f74e4fb3e466d5460b70b1d8a98bcde7b6ab8e + Author: Richard Smith + Date: Wed Sep 9 17:26:24 2020 -0700 + + Fix solitary subclauses. + + ISO rules don't permit us to have a subclause with no siblings. We had + six of these, for various reasons. Fold them together or add more + subclauses to un-isolate. + + For ISO/CS 018 (C++20 DIS). + + commit 7d8a631a56ced05b5b0f0af296cb992d55f93e7f + Author: Jens Maurer + Date: Sat Sep 5 22:39:18 2020 +0200 + + [util.smartptr.shared.cast] Add hyphen for 'well-formed'. + + Fixes NB JP 007 (C++20 DIS) + + commit 8742d396465918eba7d106ef7fbeb69bdebfe34e + Author: Jens Maurer + Date: Mon Sep 7 08:59:35 2020 +0200 + + [variant.helper] Use 'struct' for variant_size and variant_alternative + + Fixes NB JP 005 and JP 006 (C++20 DIS) + + commit 54c9b1703e19ecf81b212c2bcaedd9ff6244d596 + Author: Jens Maurer + Date: Mon Sep 7 09:09:30 2020 +0200 + + [mem.res.syn] Add default template argument for polymorphic_allocator + + Fixes NB JP 008 (C++20 DIS) + + commit 6bdf8a0e0b9b38a21da584b36890b1db7d4d8a11 + Author: Jens Maurer + Date: Mon Sep 7 09:14:12 2020 +0200 + + [mem.poly.allocator.mem] Fix syntax for variadic template declaration + + Fixes NB JP 009 + + commit d1f2db3f751ee04600d5fff443daf3fe85226305 + Author: Jens Maurer + Date: Sun Sep 6 10:55:51 2020 +0200 + + [defns.undefined] Move cross-reference to [expr.const] + + Fixes NB JP 003 (C++20 DIS) + + commit 521b52fb52bb2a4a3115f2511e7a740d83e0e123 + Author: Jens Maurer + Date: Thu Sep 10 11:43:10 2020 +0200 + + [definitions] Integrate into [intro.defs] + + Partially addresses ISO/CS 016 (C++20 DIS) + + commit c76a8a7038907975eaaa0d0b61b6212abefc8895 + Author: Jens Maurer + Date: Thu Sep 10 16:17:38 2020 +0200 + + [lib] Replace 'comparison function' with 'comparison operator function'. + + commit 5f11e2276e047d9e6a959413c2a4b17bbd1a3340 + Author: Jens Maurer + Date: Thu Sep 10 21:40:58 2020 +0200 + + [defns.projection] Fix context to 'library'. + + commit efb808f8809e1af33b795c3c28189f930ebf757c + Author: Jens Maurer + Date: Thu Sep 10 16:35:56 2020 +0200 + + [intro.refs] Fix clause reference to ISO/IEC 9899. + + commit aeca07e11ffcbfe62c12bc818e6e2376817721a1 + Author: Jens Maurer + Date: Thu Sep 10 17:00:14 2020 +0200 + + [intro.refs] Update from ISO/IEC 10646-1:1993 to ISO/IEC 10646:2003. + + This is the most recent version of ISO/IEC 10646 that + specifies the encoding form UCS-2. + + Partially addresses ISO/CS 016 (C++20 DIS) + + commit d59f2a96e3e79a6c7274fea72214d6a54d8793f0 + Author: Jens Maurer + Date: Thu Sep 10 21:19:27 2020 +0200 + + [intro.defs] Refer to undated ISO/IEC 2382 for the terminology. + + Partially addresses ISO/CS 016 (C++20 DIS) + + commit b82fd548ecbbb5149e943ef207594b7ae48e5309 + Author: Casey Carter + Date: Thu Sep 10 19:12:52 2020 -0700 + + [ranges.syn] Update iota_view constraints + + ... to agree with [range.iota.view] as modified by LWG3292. + + commit 1e5d2d5f9b9fd20f9091fcfe4b2675d04e9ff4b7 + Author: Jens Maurer + Date: Thu Sep 10 22:23:52 2020 +0200 + + [intro.refs,time.format] Fix normative references. + + ISO/IEC/IEEE 60559:2011 and UAX#29 are not normative + requirements of C++ and thus were moved to the bibliography. + For ISO 8601:2004, highlighted its normative impact on + time formatting. + Move the footnote about the Unicode trademark to the + new first mention of the term in [intro.memory]. + + Fixes ISO/CS 002 (C++20 DIS) + + commit 42a9c8df549500def82700ba4fa7228fc3f5c315 + Author: Jens Maurer + Date: Thu Sep 10 22:41:34 2020 +0200 + + [intro.compliance.general] Properly reference normative clauses + + including Annex D. + + Partially addresses ISO/CS 016 (C++20 DIS) + + commit 0f23bdeef8064b9f79855a4df8ffbac0521764a3 + Author: Jens Maurer + Date: Thu Sep 10 23:41:07 2020 +0200 + + [intro.defs] Remove cross-references from the Terms and Definitions + + Definitions of terms cannot refer to subclauses in the main + body of the standard. + + Partially addresses ISO/CS 016 (C++20 DIS) + + commit 1d49c93884920c855e76f979b924a33379354c06 + Author: Richard Smith + Date: Tue Sep 15 14:42:23 2020 -0700 + + [time.format] Date reference to ISO 8601 to match the normative + reference. + + commit 87ffbb6a12662ddb361b1b450e307f4c482e0e8f + Author: Richard Smith + Date: Tue Sep 15 15:03:47 2020 -0700 + + [depr] Don't claim this Annex is a Clause. + + commit 11f83dbee1956d1bb36d95ba74ba7cfe6972659e + Author: Richard Smith + Date: Tue Sep 15 15:18:05 2020 -0700 + + [xrefs] Don't claim this appendix is an annex. + + ISO has a special definition for "Annex" that this doesn't conform to. + + commit bbcd6bb0ad7bcebcaa611fa01af9692fe9c10f5b + Author: Richard Smith + Date: Thu Sep 10 13:50:34 2020 -0700 + + [everywhere] Number notes and examples, make them one point smaller, and + move them to (un-numbered) paragraphs of their own. + + Partially addresses ISO/CS 016 (C++20 DIS). + + commit ca1554365d4f9f7413984ed9a7a6a9627f3bc060 + Author: Richard Smith + Date: Tue Sep 15 16:01:06 2020 -0700 + + [everywhere] Stop talking about C++ International Standards. + + As far as ISO is concerned, there is only one International Standard for + C++, and in any case, we don't mean the document here, we mean the + language in the abstract and don't care whether that's an ISO standard + or not. Refer to "revisions of C++" instead of revisions of particular + ISO documents. + + Partially addresses ISO/CS 016 (C++20 DIS). + + commit ea3ff76613e1fdb19f7ba2bdb11fad87a16ba159 + Author: Jens Maurer + Date: Wed Sep 16 21:39:28 2020 +0200 + + [dcl.fct.def.coroutine] Add missing 'noexcept' for final_suspend. + + The invocation of final_suspend is guaranteed to be non-throwing, + thus final_suspend in the example needs to be declared 'noexcept'. + + commit a6b5e4b43f19e871d2457dfc35f715fdf6a8ad12 + Author: Jens Maurer + Date: Tue Jun 9 08:58:28 2020 +0200 + + [predef.iterators] Singularize heading of singular sentinels. + + Also adjust stable labels. + + commit 8570672d74846141b85fd367825acdf8c38876aa + Author: Eelis van der Weegen + Date: Fri Aug 28 18:35:00 2020 +0200 + + [std] Fix dangling \grammarterms. + + commit 8b83ec074de3042771d7ba78790b948f88d024f0 + Author: Jens Maurer + Date: Tue Sep 8 19:52:50 2020 +0200 + + [expr.const] Disambiguate 'it' by introducing the name V. + + commit 3a1e8d1081245c88afdd9d1d000988d6abebc257 + Author: Jens Maurer + Date: Fri Jul 10 00:06:58 2020 +0200 + + [expr.const] Add cross-reference for 'constant initialization'. + + commit 4d9bd0de1a5dba9fd95cb68a0f8f404581371547 + Author: Jens Maurer + Date: Fri May 22 23:31:59 2020 +0200 + + [class.derived] Clean up cross-references. + + commit 122a89231b6aa0cab6ad591679859343e51f0b55 + Author: Mathias Stearn + Date: Wed Jun 10 10:56:09 2020 +0200 + + [module.reach] Clarify that only TUs with an interface dependency may be incidentally reachable + + I think this is the intent of that sentence. Another possible reading, and the one my rewording attempts to prevent, is that because it doesn't say that no other TUs may be reachable, any TU may be, and it is just giving an example of a specific likely case of incidental reachability. But if that is the intent, then we probably shouldn't have it in normative text. + + There is an existing issue in the wording in that http://eel.is/c++draft/module#import-10 defines "has an interface dependency" as a relationship between two TUs, but this uses it as a relationship between "point with the program" and a TU. This makes it ambiguous about whether TU imported later in a file may be reachable at an earlier point. I am not trying to resolve that ambiguity with this change. + + commit f6d9e95b75c434ef5b0b81b3572c65367bd7c427 + Author: Jens Maurer + Date: Fri May 15 22:04:07 2020 +0200 + + [module.import] Clarify that only header imports make macros visible. + + commit 8406cfa14d64f1ee0849ced187accf5223c0dc0a + Author: Krystian Stasiowski + Date: Sun May 3 00:55:16 2020 -0400 + + [basic.def.odr] Change "is required" to "shall" + + commit 44c69ba373016fdc7b74d0a0d0fa0a12abfb5c98 + Author: Krystian Stasiowski + Date: Sun May 3 00:44:14 2020 -0400 + + [over.ics.user] Small grammatical nit-picks + + commit 9de05694d302b924e2d686d4af9a55b9b388eb3a + Author: Krystian Stasiowski + Date: Wed Apr 29 00:29:02 2020 -0400 + + [class.dtor] Remove incorrect uses of virtual as a keyword + + commit f469a543a9231ac77a9287dd1d7d99498abc8625 + Author: Jens Maurer + Date: Fri Apr 17 11:44:35 2020 +0200 + + [std] Remove cross-references to the very same subclause + + and add an automatic check. + + commit 66f9fad3c4d90dc30388a27a594a002e2f4bbd3b + Author: Krystian Stasiowski + Date: Mon Apr 13 18:42:34 2020 -0400 + + [expr.reinterpret.cast] Strike definition in footnote + + commit cd729c4eccdc76138ba94ba812eabc6a0c274e25 + Author: Krystian Stasiowski + Date: Mon Apr 13 18:52:22 2020 -0400 + + [expr.comma] Turn redundant normative wording into a note + + commit c471327880bec613a9bad99d01d0e97349532c3a + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Tue Sep 8 23:06:28 2020 +0300 + + [intro.object] Say "member subobject" instead of "data member" + + when talking about objects + + commit 1a9e80eb69d44ace6d82c55636b3d1f87be46c2f + Author: Bruno Ricci + Date: Mon Sep 7 13:42:25 2020 +0100 + + [expr.prim.lambda.capture] Use the term "local entity". + + The term "local entity" can be used here now that structured bindings + can be captured (after P1091R3 and P1381R1). + + commit 8cd9d0491f0950eb1b0f9e68cca00fbde4047685 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Wed Aug 12 16:04:06 2020 +0300 + + [stmt.return] Improve CWG2426 wording + + commit 2b1961486a0a41593aee7f04b8db1d1dc3605738 + Author: Jens Maurer + Date: Fri Jun 26 23:23:47 2020 +0200 + + [stmt.block] Rephrase introductory sentence. + + commit 4d8475d8b2c8687c1c43b1589ea749ab1fe8ab64 + Author: Jens Maurer + Date: Tue Sep 8 20:15:42 2020 +0200 + + [over.literal] Mark uses of a reserved identifier + + with 'ill-formed, no diagnostic required'. + Also mark grammar terms as appropriate. + + commit cdb8ac9a9bbcb19acc962d0589b92d457d1e1dcd + Author: Jens Maurer + Date: Tue Sep 8 19:42:10 2020 +0200 + + [conv.qual] Fix punctuation in bulleted list. + + commit d4e685e7abec40d7627575971fca0288f3e03ee1 + Author: onihusube <44743040+onihusube@users.noreply.github.com> + Date: Sat Sep 19 04:58:21 2020 +0900 + + [range.prim.empty] Fix misapplication of P2091R0 + + Replace "Given a subexpression ranges::empty(E)" with the intended wording "Given a subexpression E". + + commit 13b9047b0ff437c82d2a16f0ed4c29615a2223b6 + Author: Krystian Stasiowski + Date: Sun May 3 00:29:33 2020 -0400 + + [dcl.init.ref] Remove "type" from "reference to type T" + + commit 6ea1fa4235f98b2de3ac8300c37956dd6d6fe996 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Sun Apr 12 04:41:55 2020 +0300 + + [temp.over] Fix example + + commit d34065476ab3e930a4470a02271f13709a96a4b6 + Author: Krystian Stasiowski + Date: Wed Apr 8 19:20:15 2020 -0400 + + [class.virtual] Fix example with constrained non-templated function + + commit 209e05d247736a06b0f3c0f150b8cb04c6a2171e + Author: Krystian Stasiowski + Date: Wed Apr 8 18:27:14 2020 -0400 + + [dcl.fct.spec] Remove "class" from "non-static class member function" + + commit bd518f2a053f777b6f43f2fde16ace42138a73c6 + Author: Krystian Stasiowski + Date: Wed Mar 25 16:27:25 2020 -0400 + + [class.union.anon] Turn redundant wording into a note + + commit 3cc8595691bac854ec66c68e72744036d84ee014 + Author: Casey Carter + Date: Thu Dec 12 17:10:57 2019 -0800 + + [cmp.categories.pre] Remove unused enumerators + + Fixes #3541. + + commit 69321564a0c79ce2e5d492c7d913427e3cbf1e91 + Author: Casey Carter + Date: Tue Jan 14 13:10:35 2020 -0800 + + [cmp.categories.pre] Merge enumerators from eq into ord + + commit d10a1132472f18bbfec269bdb3169a306d622caa + Author: Jens Maurer + Date: Sat Sep 19 01:07:26 2020 +0200 + + [concepts.equality] Replace spurious 'this document' with 'the library Clauses'. + + commit 2976a219434eed674db28b8ae984a4ee11a7eafe + Author: Jens Maurer + Date: Sun Sep 20 22:14:29 2020 +0200 + + [fs.norm.ref] Dissolve subclause. + + There should only be one subclause called "normative + references". + + commit bf5a7e48c6c05bc27918e5e149f582d9bcbc5b34 + Author: Jens Maurer + Date: Sat Sep 19 10:14:45 2020 +0200 + + [cpp.predefined] Shuffle items to avoid an unfortunate page break. + + commit 7212a360bd6aca5b0539597eb02371e9956219b2 + Author: Jens Maurer + Date: Sun Sep 20 21:04:53 2020 +0200 + + [vector.cons] Fix subclause heading. + + Remove mention of "assignment", which is not specified here. + + commit 9fd8ca55d82a2b8e4e9b182b87ae222a460931fb + Author: Richard Smith + Date: Mon Sep 21 12:58:22 2020 -0700 + + [over.match.best.general] Remove mid-sentence period. + + commit 64b5913f6b3cefc42a98f86e68d88e9cef752c82 + Author: Jens Maurer + Date: Sat Sep 12 07:37:58 2020 +0200 + + [std] Replace 'might' in normative context. + + Partially addresses ISO/CS 017 (C++20 DIS) + + commit e5455e3bb745c82b98569d692265c6ab559eb00c + Author: Jens Maurer + Date: Sun Sep 13 21:05:37 2020 +0200 + + [std] Replace 'may' in notes. + + Partially addresses ISO/CS 017 (C++20 DIS) + + commit 84f8f1aaa3fbd535dd02af3107d9271ac705c330 + Author: Jens Maurer + Date: Wed Sep 16 11:15:52 2020 +0200 + + [std] Replace 'must'. + + Partially addresses ISO/CS 017 (C++20 DIS) + + commit 75bea3cfb49cd07fb267d46b22aa0a5d40dc6735 + Author: Jens Maurer + Date: Thu Sep 17 16:18:16 2020 +0200 + + [std] Move implementation recommendations to outside notes + + and prefix them with "Recommended practice" + + Partially addresses ISO/CS 017 (C++20 DIS) + + commit 866c95d5696da673ff61d9c1a549880079797feb + Author: Jens Maurer + Date: Thu Sep 17 16:47:51 2020 +0200 + + [std] Rephrase notes giving advice to the programmer. + + Partially addresses ISO/CS 017 (C++20 DIS) + + commit de9ea0d4577a0eb06dc760911c92eb9994520529 + Author: Jens Maurer + Date: Thu Sep 17 17:28:41 2020 +0200 + + [check] Flag 'shall', 'may', or 'should' inside notes. + + commit cb07613ed7c6cfa19a5ce024a5a8ed1c6d9bf869 + Author: Jens Maurer + Date: Fri Sep 18 22:39:40 2020 +0200 + + [std] Remove 'should' and 'may' from footnotes. + + Partially addresses ISO/CS 017 (C++20 DIS) + + commit 710838f9beb683e567e2473708a3ad9754fd23ea + Author: Jens Maurer + Date: Tue Sep 22 23:12:21 2020 +0200 + + [temp.constr.order] Remove example markers from footnote. + + commit 84087b3d3f0f60a2878a89810a1c4d0e354722d9 + Author: burblebee + Date: Tue Sep 22 16:29:42 2020 -0700 + + [std] "must" fixes and suggested rewordings. + + Partially addresses ISO/CS 017 (C++20 DIS). + + commit 33245dfce3787fac03c438ff54f667dc08b53989 + Author: Jens Maurer + Date: Wed Sep 23 00:05:21 2020 +0200 + + [std] Fix the remainder of 'may' and 'shall' in footnotes. + + commit 6608a61d9d4f66492d3ac2a735549bc242f260da + Author: Thomas Köppe + Date: Thu Sep 24 16:33:48 2020 +0100 + + [iostream.objects.overview] Delete duplicate paragraph. + + Initially, 75bea3cfb49cd07fb267d46b22aa0a5d40dc6735 moved a footnote + into a new "recommended practice" paragraph. Later, + cb07613ed7c6cfa19a5ce024a5a8ed1c6d9bf869 added the same "recommended + practice" into the middle of the paragraph that originally contained + the footnote. + + commit a331285dfb02275862428455f2af8bd69d5d4b4a + Author: Thomas Köppe + Date: Fri Sep 25 00:43:54 2020 +0100 + + [lex.charset] Replace "is required" wording in footnote with simple statement. + + commit 398dfb57151bd1cfde744931770bcff28814485d + Author: Jens Maurer + Date: Fri Sep 25 00:19:03 2020 +0200 + + [futures.async] Avoid note within a sentence. + + commit 7e66cc0c7d0c4fea57fff2c283dd0900d6333f8e + Author: Thomas Köppe + Date: Tue Sep 29 00:24:29 2020 +0100 + + [intro.compliance.general, implimits] Cite Annex B normatively. + + This change also promotes Annex B [implimits] to a "normative" annex. + The existing wording in the annex is already normative in character. + + commit bc720d58fcbfd9426838a060a679a779594b0b86 + Author: Thomas Köppe + Date: Tue Sep 29 19:34:36 2020 +0100 + + [class.mem.general] Move note to the end of the list item. + + With the new note style, notes should no longer appear in the middle of a sentence. + + commit f37ca4bbc39542722677e7abc201379e2e19de76 + Author: Thomas Köppe + Date: Thu Oct 1 00:36:32 2020 +0100 + + [iterator.concept.sentinel] Spell "see" with lower-case 's'. + + commit dee7c4acbfa040292bede71419bcc4e6fd8096a8 + Author: Dawn Perchik + Date: Sat Sep 26 12:59:13 2020 -0700 + + [expr.const] Replace notes in sentences with footnotes. + + commit 3ac649a6ecf1dd47a497c781b2db8e777543b37d + Author: Dawn Perchik + Date: Fri Oct 2 01:21:53 2020 -0700 + + [temp.dep.type] Replace note in sentence with footnote. + + commit 88ec08948c822ecddba35e33c556817ebe32f607 + Author: Richard Smith + Date: Wed Sep 30 18:27:36 2020 -0700 + + [intro.refs], Bibliography: Reorder ISO before all others and in + numerical order. + + Add a footnote to ISO/IEC 10646:2003 noting that it's withdrawn. + + As suggested by the new ISO house style rules. + + commit 062d9ee605291694f2c5dc05ade194204caeb03e + Author: Richard Smith + Date: Sun Oct 4 21:22:08 2020 -0700 + + [container.requirements.general] Add missing paragraph number. + + commit 425841a5bcbce7f81bc2d517e2fdf9d90d3586cc + Author: Richard Smith + Date: Sun Oct 4 22:45:58 2020 -0700 + + [ostream.formatted.reqmts] Fix incomplete sentence in footnote. + +### Changes only in the C++23 working draft + + commit 3f3f3f32fb4c3409b40792655383494ec42dcbff + Author: Krystian Stasiowski + Date: Sun Apr 5 19:51:20 2020 -0400 + + [except.handle] Simplify void pointer cv-qualification + + commit 9d14da2c06f9e86c894665397e5c58cff38bb8ef + Author: Krystian Stasiowski + Date: Fri Apr 10 17:07:04 2020 -0400 + + [expr.const] Change "dynamic cast" to "dynamic_cast" and move throw-expression to its own item (#3919) + + commit 7eab56033812482643ae1df26b1e4f51cc8c78de + Author: Casey Carter + Date: Wed Mar 25 11:39:21 2020 -0700 + + [iterator.synopsis,reverse.iter.nonmember] Simplify declaration of reverse_iterator's non-member operator+ + + ...with iter_difference_t to harmonize with the style of move_iterator. + + commit 891cafcb450b6ddd80da319cb52ae77310d23fec + Author: Casey Carter + Date: Wed Apr 15 13:36:22 2020 -0700 + + [alg.clamp] Add missing calls to invoke (#3902) + + ...which were accidentally ommitted from 31a1a94d. Note that this doesn't alter the semantics of the overload in `std`: `comp`'s type `Compare` is required to be a function object (and therefore not a pointer-to-member for which `invoke` would be significant) by [alg.sorting]/2. + + commit 8030a5b12f2cbef295bdea72a787701be8739c28 + Author: Krystian Stasiowski + Date: Mon Apr 13 19:30:08 2020 -0400 + + [basic.type.qualifier] Incomplete and complete object types are just object types + + commit 9e5415a8c6d0de718384f83e2aed776898b1dff4 + Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com> + Date: Fri Apr 17 01:51:14 2020 +0200 + + [string.conversions] Replace comparisons of a pointer against 0 with comparision against nullptr, for consistency with other parts of the library + + commit f683a26571b442107f18ba77a754243df9e2af0e + Author: Jens Maurer + Date: Tue Apr 21 08:45:34 2020 +0200 + + [iterator.concepts.general] Remove synthesizeable operator!= in example. (#3950) + + commit 331777a66aa2aac278a88cdd3168a26dfbe30d1f + Author: Paul "TBBle" Hampson + Date: Sat May 9 21:44:14 2020 +1000 + + [class.mem] Add cross-reference for data member order (#3990) + + commit a0216fe5fe1ef486832f9782e227dc4d25aa7ef9 + Author: NinaRanns <57705710+NinaRanns@users.noreply.github.com> + Date: Mon May 11 22:44:15 2020 +0200 + + [concept.swappable] Use 'customization point object' for ranges::swap (#3992) + + commit a656ee5413cc8a486434ccb5e04faa161a33d940 + Author: NinaRanns <57705710+NinaRanns@users.noreply.github.com> + Date: Mon May 11 22:46:20 2020 +0200 + + [iterator.cust] Use 'customization point object' in heading (#3994) + + Adjust the reference in [iterator.synopsis] accordingly. + + commit b55a360bc8a115bacde1f84b5e9d03d561c3e63e + Author: NinaRanns <57705710+NinaRanns@users.noreply.github.com> + Date: Mon May 11 22:48:26 2020 +0200 + + [range.refinements] Use 'customization point object' for ranges::data (#3993) + + commit 66e24a733ef481831e3cd3b98d5aadb851f92ce9 + Author: Krystian Stasiowski + Date: Thu Jun 25 17:29:36 2020 -0400 + + [basic.fundamental] Use canonical types in [tab:basic.fundamental.width] (#4057) + + commit 39e8f2a00bb74e531ac3c59d8a8ae964e5d3a59e + Author: Casey Carter + Date: Sun Jul 5 13:19:58 2020 -0700 + + [alg.is.permutation] Rephrase to simplify (#4071) + + Defines "last2" and "pred" for the overloads with no such parameters + so the remainder of the specification need not exhaustively describe + each case. + + commit b1df284a1d52bf6d981f6a21cd7cb4d0debaa3f3 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Thu Jul 16 18:21:19 2020 +0300 + + [expr.reinterpret.cast] Fix note on round-tripping pointer values. (#4080) + + commit a0d72768102ec6e3fe6bc6b70a26b6d4c062e52b + Author: Jens Maurer + Date: Wed Jul 22 00:11:08 2020 +0200 + + [lib] Canonicalize order of library descriptive elements. (#4067) + + commit 60a9591c8d04889cfadfde1934899dc62d8cfe44 + Author: Casey Carter + Date: Sun Aug 2 01:05:37 2020 -0700 + + [memory.syn,specialized.algorithms] Append "-for" to exposition-only concept "no-throw-sentinel" (#4100) + + ... for consistency with the renaming of the concept `sentinel` to `sentinel_for` from P1754R1. + + commit 493b10e567a44a5148b8c8da6df8823e995cff50 + Author: Jens Maurer + Date: Mon Aug 31 17:22:58 2020 +0200 + + [format.syn] Avoid forward references (#4129) + + by moving the declarations of w/format_context and + w/format_args to the front. + + commit 882560453076c87dc33a4b4a808c20fd1e1db3b1 + Author: Johel Ernesto Guerrero Peña + Date: Thu Sep 3 18:32:47 2020 -0400 + + [lib] Harmonize presentation of "The expression in...is equivalent to" (#4108) + + commit 9cc50c1d9e251fc0cbbf9590a0cf25beaa4f667a + Author: Johel Ernesto Guerrero Peña + Date: Sat Sep 5 08:37:21 2020 -0400 + + [span.iterators] Specify iterator value_type and reference (#4062) + + commit aca06a26a0048a4437fafeed573b347ef4209f5e + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Sun Sep 6 11:46:29 2020 +0300 + + [expr.post] Fix scope of \opt markup (#4142) + + commit 90696c5c2cb79c35f9abf113ad3ddfefc8d82b57 + Author: Johel Ernesto Guerrero Peña + Date: Mon Sep 7 02:52:16 2020 -0400 + + [numeric.ops.gcd,numeric.ops.lcm] Say "other than cv bool" (#4147) + + commit d27fe139ab36ac115f3191f05da18782756a4d53 + Author: Thomas Köppe + Date: Tue Sep 8 15:41:49 2020 +0100 + + [diff.mods.to.declarations] Also mention 'byte' and 'to_integer'. (#4145) + + These names, as well as operators for std::byte, are part of . + + commit e340a6ed6e03ccffb974d7ca8efccc9e898a5117 + Author: Jens Maurer + Date: Sun May 24 20:39:56 2020 +0200 + + [thread.mutex.requirements] Harmonize wording for try_lock. + + commit 7d6aca4633515ca04e7741e45d22141ec2276824 + Author: Richard Smith + Date: Tue Sep 22 16:49:16 2020 -0700 + + [expr.cond] Clarify what "subject to the constraint" means. + + commit 2c48e4e4b0265779dbabb7207f6b2507d91f53c1 + Author: Jonathan Wakely + Date: Mon Oct 5 09:53:42 2020 +0100 + + [locale.codecvt.virtuals] Add missing pnum + + Fixes #4281 + + commit 9893b652d7d9eb44906c4e7362bdb6f5c85e8d28 + Author: timsong-cpp + Date: Sun Oct 4 18:44:05 2020 -0500 + + [expr.prim.id.unqual] Restore "Otherwise" + + It is still needed for the naming-local-entity-in-lambda case. + + commit 20408d86ce9617ea0ae6decc9582785cc079c279 + Author: Jens Maurer + Date: Sat Oct 3 23:26:00 2020 +0200 + + [iomanip.syn] Use 'unspecified' instead of type meta-variables. + + commit 3eb2e0994622d3ddec758128d7f597c64bc7b207 + Author: Jens Maurer + Date: Fri Oct 2 22:39:28 2020 +0200 + + [tab:filebuf.open.modes] Consistently order table rows. + + commit 9e0afe3b1cc76d7c1f01566070d7026aed05d593 + Author: Patrick Palka + Date: Thu Oct 1 10:46:54 2020 -0400 + + [move.iter.elem] Add missing 'return' + + commit 7b220a5d64e66c29a69cae097e00cc804e765668 + Author: timsong-cpp + Date: Sun Sep 27 20:09:41 2020 -0500 + + [range.reverse.overview] Use \cv{} instead of "cv-qualified" + + commit 77ed91000fead8e3c4089664c71409af2ab7723e + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Mon Sep 21 14:15:59 2020 +0300 + + [expr.prim.paren] Replace "value" with "result" + + E can be a glvalue + + commit c269824bdf629b3949e52a78a2c3cc600e7e1429 + Author: Jens Maurer + Date: Fri Oct 2 22:34:16 2020 +0200 + + [tab:container.assoc.req] Add missing 'Effects' + + commit d45e12181707e987837e261258d3d801516865c1 + Author: Jens Maurer + Date: Tue Oct 6 17:10:17 2020 +0200 + + [intro.defs] Integrate [re.def]. + + Also rephrase the regular expression definitions to fit + the ISO-mandate style. + + commit f183ffa97d9da2c2c6ee83c3d1c58d1a74bb682e + Author: Jens Maurer + Date: Tue Sep 8 20:07:02 2020 +0200 + + [specialized.algorithms] Fold away unnecessary compound-statements. + + commit c91afba23278f55468b07ec14d97d3a79d09bff7 + Author: Jens Maurer + Date: Sun Sep 20 22:18:54 2020 +0200 + + [expr.unary.op] Use 'negative', not 'negation'. + + commit 1536e33399d27ab36e1fdfc706e630705e1f0529 + Author: Jens Maurer + Date: Fri Jun 26 23:45:28 2020 +0200 + + [dcl.array] Clarify that arrays do not have extra padding. + + commit 38b6811b6cf552b1af1ed5e6f2b2ae11c0e30668 + Author: Jonathan Wakely + Date: Fri Aug 28 13:10:11 2020 +0100 + + [numeric.limits] use "primary template" and "value-initialized" + + Improve the language used to describe the primary template and the + values of its members. + + commit c19ff8763500ac0f576b80c46e120d286ca5e8d5 + Author: Michael Schellenberger Costa + Date: Fri Oct 9 15:05:02 2020 +0200 + + [range.istream.view] Fix missing `ranges::` qualifier in example (#4296) + + commit 98a10e21d09b0883b7ee00bb19be8ffd27612e8d + Author: Krystian Stasiowski + Date: Thu Mar 19 13:09:15 2020 -0400 + + [basic.types] Change redundant normative wording into note + + commit dda32792a606a63bc4ecd23a4cdc18f861e474d9 + Author: Krystian Stasiowski + Date: Thu Mar 19 16:12:26 2020 -0400 + + [dcl.init] Remove redundant specification of when value-initialization occurs + + commit 17e732c5e2193531b812978c91440a43188003f9 + Author: Krystian Stasiowski + Date: Sat Apr 11 17:50:17 2020 -0400 + + [class.mem] Deduction guides do not declare new members + + commit 6e10c48be791f2560d1c41c594b947be0ffa4bf4 + Author: Krystian Stasiowski + Date: Sat Apr 11 18:54:46 2020 -0400 + + [dcl.spec.auto] Denoise wording for when placeholders can deduce from an initializer + + commit 0c95d56e5cf9a13c96d0ab1dddf06840d6cbc7c1 + Author: Krystian Stasiowski + Date: Mon Apr 13 18:39:02 2020 -0400 + + [expr.static.cast] Remove unused cv-qualifier notation + + commit a85ec2685fe451a1982282e30ab04ba6bcd9491f + Author: Jens Maurer + Date: Sat Apr 25 22:48:19 2020 +0200 + + [expr.spaceship] Clarify treatment of pointers. + + commit c025a57c3678a920d663acd402c464bb4788270e + Author: Krystian Stasiowski + Date: Wed Apr 29 01:13:19 2020 -0400 + + [class.static.mfct] Strike redundant normative wording + + commit 89f8412f7d7ea8182e5249224b48450fd566bbec + Author: Krystian Stasiowski + Date: Sun May 3 01:17:44 2020 -0400 + + [dcl.enum] Turn redundant and informal wording into a note + + commit 08df35fa555074e5a9ffe98d5273360ed490aa14 + Author: Krystian Stasiowski + Date: Wed May 6 20:24:58 2020 -0400 + + [temp.mem] Change "virtual" to "declared virtual" + + commit 3566bbca64d2d602badf66aeb93eb0ba438efe78 + Author: Krystian Stasiowski + Date: Wed May 6 20:26:07 2020 -0400 + + [temp.mem] Change instantiation to specialization + + commit cea53d6065c333bd8c5ff781a31bc86f4e6912d5 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Sat Jul 4 09:20:52 2020 +0300 + + [basic.lval] Named bit-fields are objects + + no need to mention them separately + + commit 7ff057c71924b9233988b91a800a8f06e61638da + Author: Erich Keane + Date: Wed Jul 22 07:28:03 2020 -0700 + + [temp.deduct.call] Add additional example to the examples added by + CWG2303 to clarify meaning. + + commit cd41f4aec8b21e81ab882a1f611e388853f2f8f1 + Author: Jens Maurer + Date: Sun Oct 18 05:03:38 2020 +0200 + + [everywhere] Consistently use 'whitespace'. (#4211) + + Do not use 'white space' or 'white-space'. + + commit 7bde32c6dd732963b91e234e9cf273661f9858c1 + Author: Jens Maurer + Date: Sun Sep 20 20:57:38 2020 +0200 + + [class.union.anon] Remove duplicate normative wording. + + commit ec8fefadaeba05ebd40ec9461bb481fd50114f29 + Author: Jens Maurer + Date: Fri Oct 2 22:29:19 2020 +0200 + + [tab:container.hash.req] Capitalize start of sentence. + + commit 70e76e148e846f11a08f5dd768b29f80374dbd43 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Tue Oct 6 01:43:06 2020 +0300 + + [class.dtor] Fix wording about object's lifetime + + commit 791f80773459cb000b251890faf2ee9953718a7a + Author: Jens Maurer + Date: Tue Oct 6 19:39:13 2020 +0200 + + [declval] Indent example and fix phrasing in example + + that refers to participation in overload resolution. diff --git a/papers/n4879.html b/papers/n4879.html new file mode 100644 index 0000000000..1384663b21 --- /dev/null +++ b/papers/n4879.html @@ -0,0 +1,626 @@ + + + + + + N4879 + + +

N4879 Editors’ Report:
Programming Languages — C++

+ +

2020-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)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Many thanks to Casey Carter, Davis Herring, and Jonathan Wakely +for checking the correctness of several editorial changes.

+ +

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

+ +

New papers

+ +
    +
  • N4878 is the +current working draft for C++23. It replaces +N4868.
  • +
  • N4879 is this Editors' Report.
  • +
+ +

Wide-ranging editorial changes to modal verbs

+ +

Recall that during the DIS review for C++20, ISO had already requested that we +fix inappropriate use of the modal verbs "shall", "may", "can", "must", +"should", "might", and "could", according to the ISO drafting directives. Many of +those changes had been made for the C++20 document and had also been applied to +the C++23 working draft.

+ +

However, during the final stages of publication of C++20, ISO pointed out +further inappropriate uses of specifically "could" and "might". Previously we +had removed those verbs from normative text, but ISO clarified that they also +must not appear in notes. We have reviewed the use of these modal verbs +comprehensively and applied editorial changes wherever we found them to improve +the overall quality of the text:

+ + + +

Many further occurrences of "could" and "might" remain in the text, where we did +not see an obvious solution. We plan on describing ISO's policy in a separate +paper, for the attention of the committee, so as to help future papers to avoid +the banned constructions. We also plan to liaise with the wording groups, either +informally or via papers, to resolve the remaining occurrences.

+ +

Motions incorporated into working draft

+ +

Core working group polls

+ +

CWG poll 1: Core issue resolutions for "Tentatively Ready" issues in +P2238R0 +applied: (DR)

+ +
    +
  • 2461 Diagnosing non-bool type constraints
  • +
  • 2460 C language linkage and constrained non-template friends
  • +
  • 2457 Unexpanded parameter packs don't make a function type dependent
  • +
  • 2452 Flowing off the end of a coroutine
  • +
  • 2369 Ordering between constraints and substitution
  • +
  • 2312 Structured bindings and mutable
  • +
+ +

CWG poll 2: P0330R8 Literal Suffix for (signed) size_t.

+ +

CWG poll 3: P2096R2 Generalized wording for partial specializations.

+ +

CWG poll 4: P2029R4 Numeric and universal character escapes in character and string literals.

+ +

CWG poll 5: P1787R6 Declarations and where to find them.

+ +

Library working group polls

+ +

LWG poll 1 applies to the Library Fundamentals TS.

+ +

LWG poll 2 applies to the Networking TS.

+ +

LWG poll 3: Library issue resolutions for "Ready" and "Tentatively Ready" issues +in P2236R0, +except for issues 3413 and 3443, applied. Note that Issue 3265 is subsumed by +Issue 3435, and is therefore missing from the following list.

+ +
    +
  • 3483 transform_view::iterator's difference is overconstrained
  • +
  • 3482 drop_view's const begin should additionally require sized_range
  • +
  • 3477 Simplify constraints for semiregular-box
  • +
  • 3476 thread and jthread constructors require that the parameters be move-constructible but never move construct the parameters
  • +
  • 3474 Nesting join_views is broken because of CTAD
  • +
  • 3473 Normative encouragement in non-normative note
  • +
  • 3472 counted_iterator is missing preconditions
  • +
  • 3467 bool can't be an integer-like type
  • +
  • 3466 Specify the requirements for promise/future/shared_future consistently
  • +
  • 3465 compare_partial_order_fallback requires F < E
  • +
  • 3461 convertible_to's description mishandles cv-qualified void
  • +
  • 3460 Unimplementable noop_coroutine_handle guarantees
  • +
  • 3455 Incorrect Postconditions on unique_ptr move assignment
  • +
  • 3453 Generic code cannot call ranges::advance(i, s)
  • +
  • 3449 take_view and take_while_view's sentinel<false> not comparable with their const iterator
  • +
  • 3448 transform_view's sentinel<false> not comparable with iterator<true>
  • +
  • 3446 indirectly_readable_traits ambiguity for types with both value_type and element_type
  • +
  • 3437 __cpp_lib_polymorphic_allocator is in the wrong header
  • +
  • 3434 ios_base never reclaims memory for iarray and parray
  • +
  • 3428 single_view's in place constructor should be explicit
  • +
  • 3427 operator<=>(const shared_ptr<T>&, nullptr_t) definition ill-formed
  • +
  • 3426 operator<=>(const unique_ptr<T, D>&, nullptr_t) can't get no satisfaction
  • +
  • 3425 condition_variable_any fails to constrain its Lock parameters
  • +
  • 3421 Imperfect ADL emulation for boolean-testable
  • +
  • 3420 cpp17-iterator should check that the type looks like an iterator first
  • +
  • 3419 [algorithms.requirements]/15 doesn't reserve as many rights as it intends to
  • +
  • 3406 elements_view::begin() and elements_view::end() have incompatible constraints
  • +
  • 3405 common_view's converting constructor is bad, too
  • +
  • 3404 Finish removing subrange's conversions from pair-like
  • +
  • 3403 Domain of ranges::ssize(E) doesn't match ranges::size(E)
  • +
  • 3306 ranges::advance violates its preconditions
  • +
  • 3171 LWG2989 breaks directory_entry stream insertion
  • +
  • 3036 polymorphic_allocator::destroy is extraneous
  • +
  • 3170 is_always_equal added to std::allocator makes the standard library treat derived types as always equal
  • +
  • 3120 Unclear behavior of monotonic_buffer_resource::release()
  • +
  • 2820 Clarify <cstdint> macros
  • +
  • 2743 P0083R3 node_handle private members missing "exposition only" comment
  • +
  • 2731 Existence of lock_guard<MutexTypes...>::mutex_type typedef unclear
  • +
  • 3464 istream::gcount() can overflow
  • +
  • 3450 The const overloads of take_while_view::begin/end are underconstrained
  • +
  • 3447 Deduction guides for take_view and drop_view have different constraints
  • +
  • 3432 Missing requirement for comparison_category
  • +
  • 3435 three_way_comparable_with<reverse_iterator<int*>, reverse_iterator<const int*>>
  • +
  • 3249 There are no 'pointers' in [atomics.lockfree]
  • +
  • 3236 Random access iterator requirements lack limiting relational operators domain to comparing those from the same range
  • +
  • 3211 std::tuple<> should be trivially constructible
  • +
  • 3195 What is the stored pointer value of an empty weak_ptr?
  • +
  • 3143 monotonic_buffer_resource growth policy is unclear
  • +
  • 3117 Missing packaged_task deduction guides
  • +
  • 2839 Self-move-assignment of library types, again
  • +
+ +

LWG poll 4: P1679R3 string contains function.

+ +

LWG poll 5: P0881R7 A proposal to add stacktrace library.

+ +

LWG poll 6: P2227R0 Update normative reference to POSIX.

+ +

LWG poll 7: P1048R1 A proposal for a type trait to detect scoped enumerations.

+ +

LWG poll 8: P0943R6 Support C atomics in C++

+ +

Editorial fixes

+ +

Changes to motions

+ +
    +
  • Poll CWG-5, P1787R6: This large paper conflicted with polls CWG-1 and +CWG-3, and also with the aforementioned modal verb changes. +
      +
    • The conflict with CWG-1 had a clear resolution.
    • +
    • The conflict with CWG-3 resulted in a small set of follow-up changes +proposed by the paper author and reviewed by CWG.
    • +
    • [dcl.pre] Turn 'must' into a note.
    • +
    • [dcl.link] Clarify sentence structure.
    • +
    • [dcl.type.elab] Clarify 'declaration'.
    • +
    • [dcl.spec.auto.general] Clarify redeclarations vs. placeholder types.
    • +
    • [dcl.meaning.general] Clarify origin of 'declarator-id'.
    • +
  • +
  • LWG2820: The formatting of "see below" and "optional" were changed for consistency.
  • +
  • LWG3448: The issue resolution introduced the exposition-only template +maybe-const. Subsequently, all uses of using Base = conditional_t<Const, +const V, V>; have been replaced by using Base = maybe-const<Const, V>; +throughout the document.
  • +
  • LWG3460: The phrase "returns the same value" was clarified to "returns the +same non-null value" on suggestion of and with review by LWG members.
  • +
  • LWG3472: The words "is true" were added to expressions in preconditions, +according to our conventions.
  • +
  • Poll LWG-5, P0881R7: +
      +
    • Removed [stacktrace.def] subheading to avoid confusion with "Terms and Definitions" clause.
    • +
    • Turned a note with "should" into "Recommended practice".
    • +
    • Added some missing articles.
    • +
    • Appended "is true" to expressions in preconditions.
    • +
  • +
  • Poll LWG-8, P0943R6: +
      +
    • The stable label was renamed to [stdatomic.h.syn] according to our convention.
    • +
    • A missing entry in the Clause's summary table was added.
    • +
    • References to the (absence of) the header "stdatomic.h" elsewhere in the +document have been updated.
    • +
  • +
+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4868 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 b5ba91f2d1753716cc20154ce06e9d274d75e4ff
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Oct 19 14:43:24 2020 +0100
+
+    README: Add splitindex and imakeidx to list of packages for Fedora
+
+commit b5b2f60824f09f9a619c389b47808be4d58febdc
+Author: Stephan T. Lavavej <stl@microsoft.com>
+Date:   Tue Oct 20 19:24:50 2020 -0700
+
+    [thread.stoptoken.intro] Fix typo
+
+commit 94b872a1305256080739c2bf468d78fe86a9b556
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Oct 26 11:29:00 2020 -0700
+
+    [ranges] Add missing "is true"s to \expects
+
+commit ae06f3ec62117bfc3a875e7c6b63cf8cecc24e51
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Oct 26 14:59:09 2020 -0700
+
+    [everywhere] Replace "might" and "could" with "can" when expressing "an
+    ability of the user of the document or [...] a possibility open to
+    him/her" (quoting the ISO Drafting Directives, Part 2).
+
+    As insisted upon by ISO/CS.
+
+commit fa67415507f1abae67c5929f76ce3d6fcad94a1b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Oct 6 19:22:28 2020 +0200
+
+    [stmt.ranged] Align font for begin-expr and end-expr.
+
+    Those are placeholders for expressions.
+
+commit b5806999b50e5cd0e07bbb618b7c782138d14498
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 29 23:09:59 2020 +0100
+
+    [std] Harmonize phrasing 'terminate is invoked' (#4005)
+
+    instead of saying 'is called'.
+    Also add cross-references to [except.terminate].
+    Also use 'exits via an exception' consistently.
+
+commit cc74b25ebec38ee9aa6a13433699c600a1375fc1
+Author: Stephan T. Lavavej <stl@microsoft.com>
+Date:   Fri Oct 30 03:59:08 2020 -0700
+
+    [stringbuf.assign] Fix typo ("s" => "rhs"). (#4306)
+
+    The parameter of swap is "rhs"; there is no "s" here. (This appears to have been
+    copy-pasted from [string.swap] where the parameter is named "s".)
+
+commit 517e2e6233ed4e33509066136d03514d1bb04560
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 2 12:44:55 2020 +0100
+
+    [ptr.launder] Fix font for object meta-variable 'X'. (#4311)
+
+commit 4376ecc4ce4e045fc7af6696c24cd80b40538a09
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 30 23:51:48 2020 +0100
+
+    [re] Remove library names from general index.
+
+commit f8a79909f491924a2d1f9e44ea579634f195ff36
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 31 23:38:51 2020 +0100
+
+    [rand] Remove library names from general index.
+
+commit 0a1ce7e47e97f50b3b7240819e97c7830acfe81b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 31 23:40:00 2020 +0100
+
+    [macros] Remove library headers from general index.
+
+commit 8131f4c4d295ca1132f8cabd3537d8cb6ad2c578
+Author: Akira Takahashi <faithandbrave@gmail.com>
+Date:   Fri Nov 6 05:34:47 2020 +0900
+
+    [time.cal.ymwd.members] Fix object name in year_month_weekday constructor (#4304)
+
+commit 6c12819b6a5bd270bfb901726f73d4d147d16a5a
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Nov 10 14:22:05 2020 -0800
+
+    [stringbuf.cons] Insert missing space after comma (#4335)
+
+    This is the common library style.
+
+commit 69b41bbbc2436d9f1b4176b14883e945757fed0c
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Sat Nov 14 08:43:03 2020 -0600
+
+    [thread.sharedtimedmutex.requirements.general] Fix typo
+
+commit a888cfb1ed98cf50be397e0614cc5130762227c0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 17 01:05:53 2020 +0000
+
+    Revert "[everywhere] Replace "might" and "could" ...".
+
+    This reverts commit ae06f3ec62117bfc3a875e7c6b63cf8cecc24e51.
+
+    We will make these changes in a more careful series of smaller commits.
+
+commit c890f0eeb26b70a3f6ec943f814c4b934ff687ba
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Wed Nov 18 10:15:25 2020 -0600
+
+    [iterators.common] fix typo and add "is true" to Preconditions: clauses (#4382)
+
+commit f124033f68060252988e469a3cdd661571a0b387
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 23 18:28:21 2020 +0000
+
+    [std] Add "implemented" to hyphenation rules
+
+commit 431818492f83ca3c3a188906ad562ec24d9aa664
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 25 11:56:48 2020 +0000
+
+    Replace "could" and "might", Clauses 1-15. (#4384)
+
+commit b2df3252873f18f272fcc6e72649312a19c8b5ad
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 25 11:58:22 2020 +0000
+
+    Replace "could" and "might", Clauses 16-32. (#4386)
+
+commit 6bf61cfdabec7b1c7c0076c9aacc1ebcabd02b05
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 25 21:54:34 2020 +0000
+
+    Replace "could" and "might" in Annexes. (#4390)
+
+commit 2432acacbce559ac6cd3e2878ff68e3b917484ec
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Dec 14 12:36:20 2020 +0000
+
+    [basic.lookup.unqual] Fix placement of cross reference
+
+commit 15987c3025f9b87121f20b4706e6fafe00c1bd74
+Author: Dawn Perchik <dawn@brightsidecomputing.com>
+Date:   Thu Nov 19 03:44:50 2020 -0800
+
+    [ranges] Change "using Parent" declarations to use "maybe-const" after LWG3448
+
+commit f73990eb8a63aa2444103a4b7334d8bdd401962f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 4 16:31:43 2020 +0100
+
+    [iterator.requirements.general] Fix indexing around 'valid range'.
+
+commit 9da9ebf4842358b8aa5212376a637807f097c272
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Dec 6 21:40:26 2020 +0100
+
+    [atomics.syn] Move macro definitions to the global namespace.
+
+commit 09bdfbde0049fec454b2ec8ccce3622c7e991999
+Author: Jason Cobb <jason.e.cobb@gmail.com>
+Date:   Mon Dec 14 08:17:55 2020 -0500
+
+    [expr.type.conv] Remove indirection of "specified type" (#4397)
+
+    The resulting type is always unqualified void, and the indirection is unnecessary.
+
+commit d8707dd332b1eb4c2abd1adf9679665a419abeb5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 14 17:28:48 2020 +0100
+
+    [diff.cpp03.temp] 'export' was resurrected for modules. (#4316)
+
+commit 70ae569a8bc9c016fef9f03abf26e5fb4e18b12e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 14 17:29:37 2020 +0100
+
+    [except.spec] Excise undefined term 'instantiation directive'. (#4312)
+
+commit e0b3fe1abde8b34b5e5fc6371a10ca6fec41f063
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Dec 14 12:33:08 2020 -0400
+
+    [util.smartptr.weak] Remove redundant declaration of 'swap' (#4037)
+
+    The declaration of the non-member function is already present in the header synopsis [memory.syn] and does not need to be repeated in the class synopsis. We generally don't do this for any other free 'swap' function, either.
+
+commit 29022b485c8ff69a36cd70912b6802d3f341723c
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Dec 14 16:46:09 2020 +0000
+
+    [time.cal.year.nonmembers] Avoid narrowing conversion (#4184)
+
+    The years::rep type could be a signed integer wider than int.
+
+commit 2adf4ac572bf8e90f8e6bcab295e977ccdf6e2f0
+Author: MattStephanson <68978048+MattStephanson@users.noreply.github.com>
+Date:   Mon Dec 14 09:34:17 2020 -0800
+
+     [time.clock.gps.members] Fix misspelled return type. (#4318)
+
+    The returns specification for `gps_clock::to_utc` says `gps_time` instead of `utc_time`, probably a copy-paste typo from p3. The original proposal, P0355R7, also says `gps_time`, but the intent seems obvious, and the status quo doesn't compile.
+
+commit c422198deca08a63374a0834880c2e10ca63f8fd
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Mar 25 11:48:56 2020 +0000
+
+    [expr.sub] Make deprecation of commas in brackets normative.
+
+    Core language deprecations are stated in core wording, and then
+    cross-referenced from Annex D. All current references to deprecating
+    this feature are notes, hence there is no normative deprecation.
+
+    This change promotes a note to non-note, normative text.
+
+commit 3b4b8d3f896aff977d8d8c438dea799f82b9c460
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 14 18:57:37 2020 +0100
+
+    Move punctuation to before the footnote mark. (#4402)
+
+    Also add a programmatic check to catch ill-placed footnote marks in the future.
+
+commit 305443c9d521d26f4b0fcd5d0e6e36fd998d131b
+Author: Christopher Di Bella <cjdb.ns@gmail.com>
+Date:   Mon Dec 16 10:42:17 2019 +0000
+
+    [range.istream] Rename expos-only member 'object_' to 'value_'.
+
+    The latter name is used everywhere else, the former was only used in
+    the four instances renamed by this change.
+
+commit d8ef9845fe9dcf950f397704714574d983e0a1f4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 3 22:39:28 2020 +0100
+
+    [thread.req.timing] Capitalize sentences in bullets.
+
+commit 69e0382cbdf03671ae5cc384f0f85d0694de1531
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 3 22:39:53 2020 +0100
+
+    [class.access.general] Fix list item punctuation.
+
+commit 4eb65b35e986a9b3911c5ab03b142ecadd555d87
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 14 22:23:27 2020 +0100
+
+    [stmt.return] Remove unhelpful example. (#4309)
+
+    Also split subsequent text up into two new numbered paragraphs.
+
+commit 93c32455b5c8449f39d69e60773a923f593575f7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 14 22:12:41 2020 +0100
+
+    [dcl.constexpr] Remove use of 'identifier label'.
+
+    The definition of the term was removed by
+    P1787R6 Declarations and where to find them.
+
+commit dfb01cdf6c902a811c5fe523e2f6caa53f16e94d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Nov 10 20:51:52 2020 +0000
+
+    [syncstream.syncbuf.cons] Remove bogus rdbuf() calls
+
+    You don't call rdbuf() to get to the streambuf, this type is the streambuf.
+
+commit 06630ddedd7fb7fa101d1c36188328ff0b54f5e6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 30 15:04:18 2020 +0100
+
+    [class.access.base] Clarify 'direct member' for access checks.
+
+commit 9f894e73d4ae8eeff6a2eedc48ac7877047b9f30
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Dec 15 12:26:53 2020 -0400
+
+    [func.wrap.func] Remove redundant declarations of swap and op== (#4411)
+
+    The declarations of the non-member functions swap and operator==
+    are already present in the header synopsis [functional.syn] and do not
+    need to be repeated in the class synopsis.
+
+ + diff --git a/papers/n4879.md b/papers/n4879.md new file mode 100644 index 0000000000..cc5d3fdb37 --- /dev/null +++ b/papers/n4879.md @@ -0,0 +1,475 @@ +# N4879 Editors' Report -- Programming Languages -- C++ + +2020-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) +`` + +## Acknowledgements + +Many thanks to Casey Carter, Davis Herring, and Jonathan Wakely +for checking the correctness of several editorial changes. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4878](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4878.pdf) is the + current working draft for C++23. It replaces + [N4868](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4868.pdf). + * N4879 is this Editors' Report. + +## Wide-ranging editorial changes to modal verbs + +Recall that during the DIS review for C++20, ISO had already requested that we +fix inappropriate use of the modal verbs "shall", "may", "can", "must", +"should", "might", and "could", according to the ISO drafting directives. Many of +those changes had been made for the C++20 document and had also been applied to +the C++23 working draft. + +However, during the final stages of publication of C++20, ISO pointed out +further inappropriate uses of specifically "could" and "might". Previously we +had removed those verbs from normative text, but ISO clarified that they also +must not appear in notes. We have reviewed the use of these modal verbs +comprehensively and applied editorial changes wherever we found them to improve +the overall quality of the text: + +* [Replace "could" and "might", Clauses 1-15](https://github.com/cplusplus/draft/commit/431818492f83ca3c3a188906ad562ec24d9aa664) +* [Replace "could" and "might", Clauses 16-32](https://github.com/cplusplus/draft/commit/b2df3252873f18f272fcc6e72649312a19c8b5ad) +* [Replace "could" and "might" in Annexes](https://github.com/cplusplus/draft/commit/6bf61cfdabec7b1c7c0076c9aacc1ebcabd02b05) + +Many further occurrences of "could" and "might" remain in the text, where we did +not see an obvious solution. We plan on describing ISO's policy in a separate +paper, for the attention of the committee, so as to help future papers to avoid +the banned constructions. We also plan to liaise with the wording groups, either +informally or via papers, to resolve the remaining occurrences. + +## Motions incorporated into working draft + +### Core working group polls + +CWG poll 1: Core issue resolutions for "Tentatively Ready" issues in +[P2238R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2238r0.html) +applied: **(DR)** + + * [2461](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2238r0.html#2461) Diagnosing non-`bool` type constraints + * [2460](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2238r0.html#2460) C language linkage and constrained non-template friends + * [2457](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2238r0.html#2457) Unexpanded parameter packs don't make a function type dependent + * [2452](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2238r0.html#2452) Flowing off the end of a coroutine + * [2369](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2238r0.html#2369) Ordering between constraints and substitution + * [2312](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2238r0.html#2312) Structured bindings and `mutable` + +CWG poll 2: [P0330R8 Literal Suffix for (signed) size_t](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0330r8.html). + +CWG poll 3: [P2096R2 Generalized wording for partial specializations](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2096r2.html). + +CWG poll 4: [P2029R4 Numeric and universal character escapes in character and string literals](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2029r4.html). + +CWG poll 5: [P1787R6 Declarations and where to find them](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html). + +### Library working group polls + +LWG poll 1 applies to the Library Fundamentals TS. + +LWG poll 2 applies to the Networking TS. + +LWG poll 3: Library issue resolutions for "Ready" and "Tentatively Ready" issues +in [P2236R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html), +except for issues 3413 and 3443, applied. Note that Issue 3265 is subsumed by +Issue 3435, and is therefore missing from the following list. + + * [3483](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3483) `transform_view::iterator`'s difference is overconstrained + * [3482](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3482) `drop_view`'s const begin should additionally require `sized_range` + * [3477](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3477) Simplify constraints for semiregular-box + * [3476](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3476) `thread` and `jthread` constructors require that the parameters be move-constructible but never move construct the parameters + * [3474](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3474) Nesting `join_views` is broken because of CTAD + * [3473](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3473) Normative encouragement in non-normative note + * [3472](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3472) `counted_iterator` is missing preconditions + * [3467](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3467) `bool` can't be an integer-like type + * [3466](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3466) Specify the requirements for `promise`/`future`/`shared_future` consistently + * [3465](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3465) `compare_partial_order_fallback` requires `F < E` + * [3461](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3461) `convertible_to`'s description mishandles cv-qualified `void` + * [3460](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3460) Unimplementable `noop_coroutine_handle` guarantees + * [3455](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3455) Incorrect Postconditions on `unique_ptr` move assignment + * [3453](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3453) Generic code cannot call `ranges::advance(i, s)` + * [3449](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3449) `take_view` and `take_while_view`'s `sentinel` not comparable with their `const iterator` + * [3448](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3448) `transform_view`'s `sentinel` not comparable with `iterator` + * [3446](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3446) `indirectly_readable_traits` ambiguity for types with both `value_type` and `element_type` + * [3437](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3437) `__cpp_lib_polymorphic_allocator` is in the wrong header + * [3434](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3434) `ios_base` never reclaims memory for `iarray` and `parray` + * [3428](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3428) `single_view`'s in place constructor should be explicit + * [3427](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3427) `operator<=>(const shared_ptr&, nullptr_t)` definition ill-formed + * [3426](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3426) `operator<=>(const unique_ptr&, nullptr_t)` can't get no satisfaction + * [3425](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3425) `condition_variable_any` fails to constrain its `Lock` parameters + * [3421](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3421) Imperfect ADL emulation for boolean-testable + * [3420](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3420) cpp17-iterator should check that the type looks like an iterator first + * [3419](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3419) [algorithms.requirements]/15 doesn't reserve as many rights as it intends to + * [3406](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3406) `elements_view::begin()` and `elements_view::end()` have incompatible constraints + * [3405](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3405) `common_view's` converting constructor is bad, too + * [3404](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3404) Finish removing `subrange`'s conversions from `pair`-like + * [3403](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3403) Domain of `ranges::ssize(E)` doesn't match `ranges::size(E)` + * [3306](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3306) `ranges::advance` violates its preconditions + * [3171](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3171) LWG2989 breaks `directory_entry` stream insertion + * [3036](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3036) `polymorphic_allocator::destroy` is extraneous + * [3170](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3170) `is_always_equal` added to `std::allocator` makes the standard library treat derived types as always equal + * [3120](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3120) Unclear behavior of `monotonic_buffer_resource::release()` + * [2820](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#2820) Clarify `` macros + * [2743](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#2743) P0083R3 `node_handle` private members missing "exposition only" comment + * [2731](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#2731) Existence of `lock_guard::mutex_type` typedef unclear + * [3464](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3464) `istream::gcount()` can overflow + * [3450](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3450) The const overloads of `take_while_view::begin`/`end` are underconstrained + * [3447](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3447) Deduction guides for `take_view` and `drop_view` have different constraints + * [3432](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3432) Missing requirement for `comparison_category` + * [3435](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3435) `three_way_comparable_with`, `reverse_iterator>` + * [3249](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3249) There are no 'pointers' in [atomics.lockfree] + * [3236](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3236) Random access iterator requirements lack limiting relational operators domain to comparing those from the same range + * [3211](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3211) `std::tuple<>` should be trivially constructible + * [3195](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3195) What is the stored pointer value of an empty `weak_ptr`? + * [3143](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3143) `monotonic_buffer_resource` growth policy is unclear + * [3117](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#3117) Missing `packaged_task` deduction guides + * [2839](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2236r0.html#2839) Self-move-assignment of library types, again + +LWG poll 4: [P1679R3 string contains function](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1679r3.html). + +LWG poll 5: [P0881R7 A proposal to add stacktrace library](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0881r7.html). + +LWG poll 6: [P2227R0 Update normative reference to POSIX](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2227r0.html). + +LWG poll 7: [P1048R1 A proposal for a type trait to detect scoped enumerations](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1048r1.pdf). + +LWG poll 8: [P0943R6 Support C atomics in C++](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0943r6.html) + +## Editorial fixes + +### Changes to motions + +* **Poll CWG-5, P1787R6:** This large paper conflicted with polls CWG-1 and + CWG-3, and also with the aforementioned modal verb changes. + - The conflict with CWG-1 had a clear resolution. + - The conflict with CWG-3 resulted in a small set of follow-up changes + proposed by the paper author and reviewed by CWG. + - [dcl.pre] Turn 'must' into a note. + - [dcl.link] Clarify sentence structure. + - [dcl.type.elab] Clarify 'declaration'. + - [dcl.spec.auto.general] Clarify redeclarations vs. placeholder types. + - [dcl.meaning.general] Clarify origin of 'declarator-id'. +* **LWG2820:** The formatting of "see below" and "optional" were changed for consistency. +* **LWG3448:** The issue resolution introduced the exposition-only template + *`maybe-const`*. Subsequently, all uses of `using Base = conditional_t;` have been replaced by using Base = maybe-const<Const, V>; + throughout the document. +* **LWG3460:** The phrase "returns the same value" was clarified to "returns the + same non-null value" on suggestion of and with review by LWG members. +* **LWG3472:** The words "is `true`" were added to expressions in preconditions, + according to our conventions. +* **Poll LWG-5, P0881R7:** + - Removed [stacktrace.def] subheading to avoid confusion with "Terms and Definitions" clause. + - Turned a note with "should" into "Recommended practice". + - Added some missing articles. + - Appended "is `true`" to expressions in preconditions. +* **Poll LWG-8, P0943R6:** + - The stable label was renamed to [stdatomic.h.syn] according to our convention. + - A missing entry in the Clause's summary table was added. + - References to the (absence of) the header "stdatomic.h" elsewhere in the + document have been updated. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4868 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/n4868...n4878). + + commit b5ba91f2d1753716cc20154ce06e9d274d75e4ff + Author: Jonathan Wakely + Date: Mon Oct 19 14:43:24 2020 +0100 + + README: Add splitindex and imakeidx to list of packages for Fedora + + commit b5b2f60824f09f9a619c389b47808be4d58febdc + Author: Stephan T. Lavavej + Date: Tue Oct 20 19:24:50 2020 -0700 + + [thread.stoptoken.intro] Fix typo + + commit 94b872a1305256080739c2bf468d78fe86a9b556 + Author: Casey Carter + Date: Mon Oct 26 11:29:00 2020 -0700 + + [ranges] Add missing "is true"s to \expects + + commit ae06f3ec62117bfc3a875e7c6b63cf8cecc24e51 + Author: Richard Smith + Date: Mon Oct 26 14:59:09 2020 -0700 + + [everywhere] Replace "might" and "could" with "can" when expressing "an + ability of the user of the document or [...] a possibility open to + him/her" (quoting the ISO Drafting Directives, Part 2). + + As insisted upon by ISO/CS. + + commit fa67415507f1abae67c5929f76ce3d6fcad94a1b + Author: Jens Maurer + Date: Tue Oct 6 19:22:28 2020 +0200 + + [stmt.ranged] Align font for begin-expr and end-expr. + + Those are placeholders for expressions. + + commit b5806999b50e5cd0e07bbb618b7c782138d14498 + Author: Jens Maurer + Date: Thu Oct 29 23:09:59 2020 +0100 + + [std] Harmonize phrasing 'terminate is invoked' (#4005) + + instead of saying 'is called'. + Also add cross-references to [except.terminate]. + Also use 'exits via an exception' consistently. + + commit cc74b25ebec38ee9aa6a13433699c600a1375fc1 + Author: Stephan T. Lavavej + Date: Fri Oct 30 03:59:08 2020 -0700 + + [stringbuf.assign] Fix typo ("s" => "rhs"). (#4306) + + The parameter of swap is "rhs"; there is no "s" here. (This appears to have been + copy-pasted from [string.swap] where the parameter is named "s".) + + commit 517e2e6233ed4e33509066136d03514d1bb04560 + Author: Jens Maurer + Date: Mon Nov 2 12:44:55 2020 +0100 + + [ptr.launder] Fix font for object meta-variable 'X'. (#4311) + + commit 4376ecc4ce4e045fc7af6696c24cd80b40538a09 + Author: Jens Maurer + Date: Fri Oct 30 23:51:48 2020 +0100 + + [re] Remove library names from general index. + + commit f8a79909f491924a2d1f9e44ea579634f195ff36 + Author: Jens Maurer + Date: Sat Oct 31 23:38:51 2020 +0100 + + [rand] Remove library names from general index. + + commit 0a1ce7e47e97f50b3b7240819e97c7830acfe81b + Author: Jens Maurer + Date: Sat Oct 31 23:40:00 2020 +0100 + + [macros] Remove library headers from general index. + + commit 8131f4c4d295ca1132f8cabd3537d8cb6ad2c578 + Author: Akira Takahashi + Date: Fri Nov 6 05:34:47 2020 +0900 + + [time.cal.ymwd.members] Fix object name in year_month_weekday constructor (#4304) + + commit 6c12819b6a5bd270bfb901726f73d4d147d16a5a + Author: Casey Carter + Date: Tue Nov 10 14:22:05 2020 -0800 + + [stringbuf.cons] Insert missing space after comma (#4335) + + This is the common library style. + + commit 69b41bbbc2436d9f1b4176b14883e945757fed0c + Author: timsong-cpp + Date: Sat Nov 14 08:43:03 2020 -0600 + + [thread.sharedtimedmutex.requirements.general] Fix typo + + commit a888cfb1ed98cf50be397e0614cc5130762227c0 + Author: Thomas Köppe + Date: Tue Nov 17 01:05:53 2020 +0000 + + Revert "[everywhere] Replace "might" and "could" ...". + + This reverts commit ae06f3ec62117bfc3a875e7c6b63cf8cecc24e51. + + We will make these changes in a more careful series of smaller commits. + + commit c890f0eeb26b70a3f6ec943f814c4b934ff687ba + Author: timsong-cpp + Date: Wed Nov 18 10:15:25 2020 -0600 + + [iterators.common] fix typo and add "is true" to Preconditions: clauses (#4382) + + commit f124033f68060252988e469a3cdd661571a0b387 + Author: Thomas Köppe + Date: Mon Nov 23 18:28:21 2020 +0000 + + [std] Add "implemented" to hyphenation rules + + commit 431818492f83ca3c3a188906ad562ec24d9aa664 + Author: Thomas Köppe + Date: Wed Nov 25 11:56:48 2020 +0000 + + Replace "could" and "might", Clauses 1-15. (#4384) + + commit b2df3252873f18f272fcc6e72649312a19c8b5ad + Author: Thomas Köppe + Date: Wed Nov 25 11:58:22 2020 +0000 + + Replace "could" and "might", Clauses 16-32. (#4386) + + commit 6bf61cfdabec7b1c7c0076c9aacc1ebcabd02b05 + Author: Thomas Köppe + Date: Wed Nov 25 21:54:34 2020 +0000 + + Replace "could" and "might" in Annexes. (#4390) + + commit 2432acacbce559ac6cd3e2878ff68e3b917484ec + Author: Thomas Köppe + Date: Mon Dec 14 12:36:20 2020 +0000 + + [basic.lookup.unqual] Fix placement of cross reference + + commit 15987c3025f9b87121f20b4706e6fafe00c1bd74 + Author: Dawn Perchik + Date: Thu Nov 19 03:44:50 2020 -0800 + + [ranges] Change "using Parent" declarations to use "maybe-const" after LWG3448 + + commit f73990eb8a63aa2444103a4b7334d8bdd401962f + Author: Jens Maurer + Date: Fri Dec 4 16:31:43 2020 +0100 + + [iterator.requirements.general] Fix indexing around 'valid range'. + + commit 9da9ebf4842358b8aa5212376a637807f097c272 + Author: Jens Maurer + Date: Sun Dec 6 21:40:26 2020 +0100 + + [atomics.syn] Move macro definitions to the global namespace. + + commit 09bdfbde0049fec454b2ec8ccce3622c7e991999 + Author: Jason Cobb + Date: Mon Dec 14 08:17:55 2020 -0500 + + [expr.type.conv] Remove indirection of "specified type" (#4397) + + The resulting type is always unqualified void, and the indirection is unnecessary. + + commit d8707dd332b1eb4c2abd1adf9679665a419abeb5 + Author: Jens Maurer + Date: Mon Dec 14 17:28:48 2020 +0100 + + [diff.cpp03.temp] 'export' was resurrected for modules. (#4316) + + commit 70ae569a8bc9c016fef9f03abf26e5fb4e18b12e + Author: Jens Maurer + Date: Mon Dec 14 17:29:37 2020 +0100 + + [except.spec] Excise undefined term 'instantiation directive'. (#4312) + + commit e0b3fe1abde8b34b5e5fc6371a10ca6fec41f063 + Author: Johel Ernesto Guerrero Peña + Date: Mon Dec 14 12:33:08 2020 -0400 + + [util.smartptr.weak] Remove redundant declaration of 'swap' (#4037) + + The declaration of the non-member function is already present in the header synopsis [memory.syn] and does not need to be repeated in the class synopsis. We generally don't do this for any other free 'swap' function, either. + + commit 29022b485c8ff69a36cd70912b6802d3f341723c + Author: Jonathan Wakely + Date: Mon Dec 14 16:46:09 2020 +0000 + + [time.cal.year.nonmembers] Avoid narrowing conversion (#4184) + + The years::rep type could be a signed integer wider than int. + + commit 2adf4ac572bf8e90f8e6bcab295e977ccdf6e2f0 + Author: MattStephanson <68978048+MattStephanson@users.noreply.github.com> + Date: Mon Dec 14 09:34:17 2020 -0800 + + [time.clock.gps.members] Fix misspelled return type. (#4318) + + The returns specification for `gps_clock::to_utc` says `gps_time` instead of `utc_time`, probably a copy-paste typo from p3. The original proposal, P0355R7, also says `gps_time`, but the intent seems obvious, and the status quo doesn't compile. + + commit c422198deca08a63374a0834880c2e10ca63f8fd + Author: Alisdair Meredith + Date: Wed Mar 25 11:48:56 2020 +0000 + + [expr.sub] Make deprecation of commas in brackets normative. + + Core language deprecations are stated in core wording, and then + cross-referenced from Annex D. All current references to deprecating + this feature are notes, hence there is no normative deprecation. + + This change promotes a note to non-note, normative text. + + commit 3b4b8d3f896aff977d8d8c438dea799f82b9c460 + Author: Jens Maurer + Date: Mon Dec 14 18:57:37 2020 +0100 + + Move punctuation to before the footnote mark. (#4402) + + Also add a programmatic check to catch ill-placed footnote marks in the future. + + commit 305443c9d521d26f4b0fcd5d0e6e36fd998d131b + Author: Christopher Di Bella + Date: Mon Dec 16 10:42:17 2019 +0000 + + [range.istream] Rename expos-only member 'object_' to 'value_'. + + The latter name is used everywhere else, the former was only used in + the four instances renamed by this change. + + commit d8ef9845fe9dcf950f397704714574d983e0a1f4 + Author: Jens Maurer + Date: Tue Nov 3 22:39:28 2020 +0100 + + [thread.req.timing] Capitalize sentences in bullets. + + commit 69e0382cbdf03671ae5cc384f0f85d0694de1531 + Author: Jens Maurer + Date: Tue Nov 3 22:39:53 2020 +0100 + + [class.access.general] Fix list item punctuation. + + commit 4eb65b35e986a9b3911c5ab03b142ecadd555d87 + Author: Jens Maurer + Date: Mon Dec 14 22:23:27 2020 +0100 + + [stmt.return] Remove unhelpful example. (#4309) + + Also split subsequent text up into two new numbered paragraphs. + + commit 93c32455b5c8449f39d69e60773a923f593575f7 + Author: Jens Maurer + Date: Mon Dec 14 22:12:41 2020 +0100 + + [dcl.constexpr] Remove use of 'identifier label'. + + The definition of the term was removed by + P1787R6 Declarations and where to find them. + + commit dfb01cdf6c902a811c5fe523e2f6caa53f16e94d + Author: Jonathan Wakely + Date: Tue Nov 10 20:51:52 2020 +0000 + + [syncstream.syncbuf.cons] Remove bogus rdbuf() calls + + You don't call rdbuf() to get to the streambuf, this type is the streambuf. + + commit 06630ddedd7fb7fa101d1c36188328ff0b54f5e6 + Author: Jens Maurer + Date: Fri Oct 30 15:04:18 2020 +0100 + + [class.access.base] Clarify 'direct member' for access checks. + + commit 9f894e73d4ae8eeff6a2eedc48ac7877047b9f30 + Author: Johel Ernesto Guerrero Peña + Date: Tue Dec 15 12:26:53 2020 -0400 + + [func.wrap.func] Remove redundant declarations of swap and op== (#4411) + + The declarations of the non-member functions swap and operator== + are already present in the header synopsis [functional.syn] and do not + need to be repeated in the class synopsis. diff --git a/papers/n4886.html b/papers/n4886.html new file mode 100644 index 0000000000..e76448aad3 --- /dev/null +++ b/papers/n4886.html @@ -0,0 +1,605 @@ +N4886 +

N4886 Editors' Report -- Programming Languages -- C++

+ +

2021-03-17
+Thomas Köppe (editor, Google DeepMind)
+Jens Maurer (co-editor)
+Dawn Perchik (co-editor, Bright Side Computing, LLC)
+Richard Smith (co-editor, Google Inc)
+<cxxeditor@gmail.com>

+ +

Acknowledgements

+ +

Many thanks to Casey Carter, Davis Herring, and Jonathan Wakely +for checking the correctness of several editorial changes.

+ +

Thanks to all those who have submitted editorial +issues +and to those who have provided pull requests with fixes, and to +Johel Ernesto Guerrero Peña in particular for many valuable contributions.

+ +

New papers

+ +
    +
  • N4885 is the +current working draft for C++23. It replaces +N4878.
  • +
  • N4886 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group polls

+ +

CWG poll 1: Accept as Defect Reports the the following issues (all issues +resolved by +P1787R6 (Declarations and where to find them), +adopted at the November, 2020 meeting): 36, 110, 138, 191, 255, 271, 279, 338, 360, 386, 399, 405, 418, 536, 554, 562, 563, 600, 607, 852, 952, 1028, 1200, 1252, 1291, 1478, 1500, 1616, 1729, 1771, 1818, 1820, 1821, 1822, 1828, 1829, 1835, 1837, 1839, 1841, 1884, 1894, 1896, 1898, 1900, 1907, 1908, 1936, 2007, 2009, 2058, 2062, 2065, 2070, 2165, 2199, 2213, 2331, 2370, 2396, 2413

+ +

This poll did not result in any modifications to the Working Draft. It only +updates the status of the affected CWG issues. The Working Draft had already be +updated by the application of P1787R6 after the previous meeting.

+ +

CWG poll 2: Accept as Defect Reports all issues in P2313R0 (Core Language Working Group "tentatively ready" Issues for the February, 2021 meeting) and apply the proposed resolutions to the C++ working paper.

+ +

CWG poll 3: Apply the changes in P1102R2 (Down with ()!) to the C++ working paper.

+ +

Library working group polls

+ +

LWG poll 1: Apply the changes for all Tentatively Ready issues in +P2315R0 (C++ Standard Library Issues to be moved in Virtual Plenary, Feb. 2021) +to the C++ working paper.

+ +

LWG poll 2: Apply the changes in P2259R1 (Repairing input range adaptors and counted_iterator) to the C++ working paper.

+ +

LWG poll 3: Apply the changes in P2212R2 (Relax Requirements for time_point::clock) to the C++ working paper.

+ +

LWG poll 4: Apply the changes in P2162R2 (Inheriting from std::variant) to the C++ working paper.

+ +

LWG poll 5: Apply the changes in P2160R1 (Locks lock lockables) to the C++ working paper.

+ +

LWG poll 6: Apply the changes in P2017R1 (Conditionally borrowed ranges) to the C++ working paper.

+ +

LWG poll 7: Apply the changes in P1682R2 (std::to_underlying for enumerations) to the C++ working paper.

+ +

LWG poll 8 did not have consensus.

+ +

Editorial fixes

+ +

Changes to motions

+ +
    +
  • Polls LWG-1, LWG-3502 and LWG 2, P2259R1: Both the issue resolution of +LWG-3502 and the wording of +P2259R1 +add wording in [24.7.16.3, range.elements.iterator] immediately after the +synopsis of class template elements_view::iterator. The +wording of P2259R1, which provides general definitions, was inserted before +the wording of LWG-3502, which adds a member specification.

  • +
  • Poll LWG-4, P2162R2: A sentence that introduced a list was reworded very +slightly to end in a colon.

  • +
  • Poll LWG-5, P2160R1: A sentence was turned into a bulleted list for +clarity, and the logical composition ("and" vs "or") was clarified.

  • +
+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4878 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 7dec24a3adcda671751140407f91d0802142013b
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Dec 18 20:16:07 2020 +0800
+
+    [stacktrace.entry.overview] Italicize 'implementation-defined' in code block (#4421)
+
+commit e93b1868df751014c4f21c6b265823dcc7e51c69
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Dec 18 20:24:10 2020 +0800
+
+    [basic.lookup.qual.general] Add \tcode around N::B<0> (#4422)
+
+commit bc7bfc8480fa1056e8a4bc1de9e841f82e662531
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Sat Dec 26 17:30:41 2020 +0100
+
+    [stacktrace.syn] Add header index entry for <stacktrace>. (#4434)
+
+commit adaa5cb85cb950f0d09f3ac7eff239576a6a6bcc
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Dec 28 15:05:09 2020 -0400
+
+    [temp.explicit] Typo fix: remove extraneous x (#4439)
+
+commit d4c03ca423220c1f26aa718712ba6083f421e2ce
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Dec 29 19:18:56 2020 -0400
+
+    [system.error.syn] Add dropped word (#4440)
+
+commit a864d2fae82c7a7c7a23121969d4da743c1c25ae
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 18 21:16:31 2020 +0100
+
+    [localization] Reformat LaTeX source code.
+
+    Also add two missing periods and remove one instance
+    of superfluous whitespace.
+
+commit 0162e808fccd74cffe663104f284f08e1efb65d1
+Author: Christof Meerwald <cmeerw@cmeerw.org>
+Date:   Thu Jan 14 19:14:33 2021 +0100
+
+    [over.match.conv] add missing "can" (#4461)
+
+    The word "can" seems to have been accidentally dropped when applying P1787R6.
+
+commit a8e2d0d30cab31a47a238603f9636e1d567fda3e
+Author: Hubert Tong <hubert-reinterpretcast@users.noreply.github.com>
+Date:   Thu Jan 14 13:17:16 2021 -0500
+
+    [expr.prim.req.type] Clarify example comment re: validity of name only (#4457)
+
+    The comment that a class template specialization is required can be
+    taken as meaning that more is required than the validity of the
+    template-id (which is all that the requirement really checks).
+
+    Additionally, the specific implications of the validity requirement is
+    spelled out.
+
+    Co-authored-by: Hubert Tong <hstong@ca.ibm.com>
+
+commit 803511eb0815cee73167c8a85b78ca046fc3e7c6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jan 4 22:15:58 2021 +0100
+
+    [over.match.viable, over.match.best.general] Use math mode, not \textit
+
+commit 7c5edb431df8ef4bc52e5297e5d54bc188967b8c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jan 14 19:23:50 2021 +0100
+
+    [fs.op.funcs] Qualify declarator-id with sub-namespace (#4459)
+
+commit 82821f2ef3e408b2a2e6b61b8de2342695b0dc42
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jan 4 21:39:47 2021 +0100
+
+    [thread.condition.general] Fix style of quotation marks
+
+commit da00c98ed9f4052e0205ce9079fa6a9dc527bc8b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jan 3 22:16:08 2021 +0100
+
+    [lib] Ensure non-member swap is declared in the header synopsis only
+
+commit f5380e66f3e60953388189c98472517344777be0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jan 14 23:30:51 2021 +0100
+
+    [ranges] Improve concept index (#4456)
+
+commit 134d5f048a28a533e1ec45c45a289f1976b62232
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jan 3 22:37:01 2021 +0100
+
+    [lib] Use 'specialization' instead of 'instance'
+
+commit 836cc23f44e1c5b44376e75f2964f78f0f8b2a9b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jan 15 13:10:45 2021 +0100
+
+    [concepts.equality] Turn 'e.g.' into a proper example (#4442)
+
+commit d35605c14368a3418a999ca6aaf31627a79e14fb
+Author: Hubert Tong <hstong@ca.ibm.com>
+Date:   Sat Jan 2 22:21:44 2021 -0500
+
+    [over.built] Correct note re: "hiding" to match over.match.oper/3
+
+    The note in [over.built] uses "hidden" to describe how built-in
+    candidates are removed from consideration; however, this is not
+    hiding in the sense of name lookup. This PR removes the bad
+    terminology and also corrects the note to defer to the normative
+    text regarding the conditions upon user-written candidates that
+    suppress built-in candidates.
+
+commit 7b197155b61c6ddd63386f915adbfb59258de89c
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri Jan 15 09:40:58 2021 -0400
+
+    [range.iota.iterator,range.iota.sentinel] Add missing requires-clauses on out-of-class member definitions (#4426)
+
+    These additional clauses were accidentally omitted from LWG3292, but should have been part of that issue's resolution.
+
+commit f81e3a820461cd5917448d9ec2519bdd0e6adb91
+Author: frederick-vs-ja <de34@live.cn>
+Date:   Thu Jan 28 05:14:25 2021 +0800
+
+    [stacktrace.basic.overview] Add missing "namespace std {" (#4469)
+
+commit afd12f1de36eb0b47292c179d573ee797611d359
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Jan 30 15:53:02 2021 -0400
+
+    [iterator.concept.winc] Index implementation-defined integer-class type (#4470)
+
+    Also fix a typo.
+
+commit 1aee0cad91184b6f4d4938ba0e8597e0fc644342
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Feb 1 07:04:38 2021 -0400
+
+    [lib] Change 'expression inside noexcept' to 'exception specification' (#4105)
+
+    * [lib] 'expression inside noexcept' -> 'exception specification'
+
+commit 4030cfc62ea51a02d884f170d92c4d0149977c02
+Author: lam-work-group <77063444+lam-work-group@users.noreply.github.com>
+Date:   Tue Jan 26 15:30:41 2021 +0800
+
+    [stacktrace.basic.cmp] Update 'lexicographical_compare_3way'
+
+    P1614R2 changed the name to 'lexicographical_compare_three_way'.
+
+commit be7b0a691b5414996fd0531e15a556a49fc982b6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jan 3 21:19:24 2021 +0100
+
+    [index] Add missing implementation-defined types
+
+commit e429dfc01ed44cb3dd5f6095c74a759aebdb00c4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Dec 27 23:41:52 2020 +0100
+
+    [library.general] Adjust order according to recent clause reorganizations.
+
+commit 81a911dfb70f0d2f0450592ca49ebd05056e86e1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Dec 30 22:17:24 2020 +0100
+
+    [range.dangling] Split up overly long sentence.
+
+commit 22789a0312a773c7ec77dd6a6b9c1f39a3a4634e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 4 17:50:26 2021 +0100
+
+    [format.arg] Fix return type of visit_format_arg
+
+    It was specified as 'see below', pointing nowhere.
+    Use 'decltype(auto)', congruent with the Effects item.
+
+commit 065df74900d3bd2e1dbdec105de4e3742e059eda
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Feb 15 06:17:20 2021 -0400
+
+    [README] Update requirements for "Getting Started" on Arch Linux (#4496)
+
+commit 0a107ed35ef44becc00dea9329f6a7da6e0be98a
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Feb 15 06:21:34 2021 -0400
+
+    [func.bind.front] Use a more conventional introduction (#4488)
+
+commit 3510342f18537f4b1feac191ec6e7fce649f5014
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Feb 15 11:23:05 2021 +0100
+
+    [stmt.pre] Excise undefined term 'contained' (#4485)
+
+commit 80c5fdf17341121464360e953039bd03a9aa3a0f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Feb 5 21:41:05 2021 +0100
+
+    [dcl.init.general] Fix misapplied term 'block variable'
+
+    Block-scope externs are in view here, but those are not
+    block variables, because their target scope is an
+    enclosing namespace scope.
+
+commit 7620db718df1ff82c2468b75f3449ced8ad7b716
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Feb 5 22:02:04 2021 +0100
+
+    [lib] Use 'tm', not 'struct tm'
+
+    Using the elaborated-type-specifier implies that this type
+    is declared in namespace 'std', which might not be true.
+
+commit 5494117ea39b36ce3e590025943a8ff48e78b4d3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 18 17:39:13 2021 +0100
+
+    [container.requirements] Use bulleted lists to introduce identifiers
+
+commit 70da127291269dbda3f1cad7cb34936cf0bdbcf1
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Mon Feb 22 05:26:52 2021 -0500
+
+    [vector.bool] Remove an extra closing parenthesis (#4501)
+
+commit 825255f7c3be12b4807c6df4c1183632d973cf53
+Author: Marek Kurdej <mkurdej@users.noreply.github.com>
+Date:   Mon Feb 22 19:58:47 2021 +0100
+
+    [stdatomic.h.syn] Add semicolons in using-declarations (#4502)
+
+commit cddc112f2b4baa4ce8cc97c60aa04276fd86afc5
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Feb 23 12:08:32 2021 -0800
+
+    [range.iota.iterator,range.iota.sentinel] Fix markup around \libconcept (#4503)
+
+    ...so it doesn't appear in the rendered text.
+
+commit 14952c5e7f742f89c233bc13be05f4825d54db17
+Author: Dawn Perchik <dawn@brightsidecomputing.com>
+Date:   Thu Feb 25 03:08:34 2021 -0800
+
+    [std] Fixes for library concepts that should be \libconcept'd.
+
+commit 1f854d8f83e4eb7d672aa224aabd882e1a70241d
+Author: Christopher Di Bella <cjdb@google.com>
+Date:   Mon Mar 1 10:30:31 2021 -0800
+
+    [optional.ctor] Add missing \tcode around 'true' (#4534)
+
+commit 066bb6b3acd61761cccb639b191429b95271dbb8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 3 19:56:30 2020 +0100
+
+    [cpp.import] Clarify header units as the source of macro definitions.
+
+commit e8240fbde651d690f2e01b5770494e3d9189dca6
+Author: MattStephanson <68978048+MattStephanson@users.noreply.github.com>
+Date:   Sun Mar 7 00:29:30 2021 -0800
+
+    [time.syn] add constexpr to leap_second comparisons (#4539)
+
+commit 2fdafbee15266047133d714e031468be47affe95
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri Mar 12 15:29:26 2021 -0800
+
+    [ranges.syn] Don't constrain specializations of enable_borrowed_range (#4519)
+
+    These constraints redundantly repeat the constraints from the template we're partially specializing for. This isn't incorrect, but it is unnecessary, adds opportunities for editorial errors, and is inconsistent with how other partial specializations of templates for constrained types are specified.
+
+commit dfbc9e657ade9674274b6b234ee28f57a7259136
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 30 09:07:03 2020 +0100
+
+    [conv.rank] Avoid 'shall' for plain descriptions.
+
+commit ebdeb7e99223639d24934b7f00be315e1d9288b7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jan 3 20:58:05 2021 +0100
+
+    [floatfield.manip] Rephrase note about ios_base::hex
+
+commit ce7e6bfaef0e2350e90e5c26154c9cfa59900c4f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jan 4 00:12:38 2021 +0100
+
+    [range.split.outer] Clarify scope of exposition-only 'current'
+
+commit 55c36ec3684a02cb39b232bc34b4a7d22c0a874b
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Dec 28 02:23:27 2020 -0400
+
+    [unord.hash] Remove redundant wording
+
+commit f6d7b014f5b50850ccd3fd31127917ad44309634
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Feb 6 22:04:39 2021 +0100
+
+    [temp.expl.spec] Use 'reachable from', not 'declared before'
+
+    With modules, 'declared before' no longer makes sense.
+
+commit ce0db1e1515aedee533a53145d76d9e5495f6f00
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Mar 15 14:00:53 2021 +0100
+
+    [cmp.alg] Clarify that ill-formed CPO invocations are SFINAE-friendly (#4494)
+
+commit 6dbc76a0935998443d0a28b962d86649c56b27f4
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri Jan 29 15:40:10 2021 -0400
+
+    [lib] Index all uses of public concepts
+
+commit 0b3d8ed6e8a70bedeb0ca161f1a6121cb769266b
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Mon Mar 15 21:15:17 2021 +0800
+
+    [stacktrace.entry.query] Fix description of `source_line` (#4481)
+
+    This fixes a misapplication of P0881R7.
+
+commit fab6f7f0d05b081cf183d1d56811f101ba6c89e6
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Mon Mar 15 23:45:41 2021 +0300
+
+    [dcl.fct] Integrate return type requirements from [expr.call] and simplify them (#4113)
+
+    There is a general prohibition against arrays of function type in [dcl.array].
+    There is no need to highlight some specific permitted types; it is sufficient
+    to state the general rule.
+
+commit 793eb7be096f76dcdf71dde1238ad24ed1c9e13e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Mar 15 22:53:55 2021 +0100
+
+    [dcl.pre] Reorder paragraphs (#4462)
+
+    Group discussion of simple-declaration and
+    move other kinds of declarations to the end.
+
+commit e66bf8fa69e2d0e7c5314a7720cdd9e9e63421db
+Author: Hubert Tong <hstong@ca.ibm.com>
+Date:   Mon Apr 20 17:50:13 2020 -0400
+
+    [dcl.fct.def.delete] Make terms cover semantic deletedness
+
+    The definition of "deleted definition" in [dcl.fct.def.delete] is not
+    written in the form of a definition and neither is the definition of
+    "deleted function". Most problematically, these definitions encompass
+    only the syntactic case of explicitly deleting a function but the terms
+    are used where semantic deletedness is meant.
+
+    Applying the syntactic interpretation of the definition could lead to
+    the conclusion that the following is ill-formed:
+    ```cpp
+    struct A { ~A() = delete; };
+    struct B {
+      A a;
+      virtual ~B() = default;
+    };
+    struct C : B { virtual ~C() = delete; };
+    ```
+
+    This patch changes the definitions to cover semantic deletion.
+
+    **Drafting notes:**
+
+    - It appears that uses of "deleted definition" in the text is usually
+      refer to physical definitions (but not necessarily to explicit
+      deletions).
+    - The increased verbosity is somewhat necessary to meet the ideal that
+      uses of a term may be replaced with the definition of the term with
+      minimal adjustments.
+
+commit 44e3c7fb3e88e45738926d652ed6a78c1df6619b
+Author: Casey Carter <cacarter@microsoft.com>
+Date:   Tue Mar 16 13:44:19 2021 -0700
+
+    [range.split.inner] Clarify paragraph 1 (#4545)
+
+    ... to avoid confusion about what it means for a name that is not present to denote a type.
+
diff --git a/papers/n4886.md b/papers/n4886.md new file mode 100644 index 0000000000..8683e5a2a5 --- /dev/null +++ b/papers/n4886.md @@ -0,0 +1,480 @@ +# N4886 Editors' Report -- Programming Languages -- C++ + +2021-03-17 +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) +`` + +## Acknowledgements + +Many thanks to Casey Carter, Davis Herring, and Jonathan Wakely +for checking the correctness of several editorial changes. + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes, and to +Johel Ernesto Guerrero Peña in particular for many valuable contributions. + +## New papers + + * [N4885](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4885.pdf) is the + current working draft for C++23. It replaces + [N4878](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4878.pdf). + * N4886 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group polls + +CWG poll 1: Accept as Defect Reports the the following issues (all issues +resolved by +[P1787R6 (Declarations and where to find them)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html), +adopted at the November, 2020 meeting): [36](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#36), [110](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#110), [138](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#138), [191](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#191), [255](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#255), [271](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#271), [279](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#279), [338](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#338), [360](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#360), [386](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#386), [399](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#399), [405](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#405), [418](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#418), [536](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#536), [554](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#554), [562](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#562), [563](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#563), [600](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#600), [607](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#607), [852](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#852), [952](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#952), [1028](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1028), [1200](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1200), [1252](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1252), [1291](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1291), [1478](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1478), [1500](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1500), [1616](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1616), [1729](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1729), [1771](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1771), [1818](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1818), [1820](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1820), [1821](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1821), [1822](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1822), [1828](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1828), [1829](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1829), [1835](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1835), [1837](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1837), [1839](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1839), [1841](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1841), [1884](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1884), [1894](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1894), [1896](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1896), [1898](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1898), [1900](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1900), [1907](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1907), [1908](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1908), [1936](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1936), [2007](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2007), [2009](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2009), [2058](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2058), [2062](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2062), [2065](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2065), [2070](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2070), [2165](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2165), [2199](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2199), [2213](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2213), [2331](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2331), [2370](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2370), [2396](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2396), [2413](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2413) + +This poll did not result in any modifications to the Working Draft. It only +updates the status of the affected CWG issues. The Working Draft had already be +updated by the application of P1787R6 after the previous meeting. + +CWG poll 2: Accept as Defect Reports all issues in [P2313R0 (Core Language Working Group "tentatively ready" Issues for the February, 2021 meeting)](https://wiki.edg.com/pub/Wg21virtual2021-02/StrawPolls/p2313r0.html) and apply the proposed resolutions to the C++ working paper. + +CWG poll 3: Apply the changes in [P1102R2 (Down with `()`!)](http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1102r2.html) to the C++ working paper. + +### Library working group polls + +LWG poll 1: Apply the changes for all Tentatively Ready issues in +[P2315R0 (C++ Standard Library Issues to be moved in Virtual Plenary, Feb. 2021)](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2315r0.html) +to the C++ working paper. + +LWG poll 2: Apply the changes in [P2259R1 (Repairing input range adaptors and `counted_iterator`)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2259r1.html) to the C++ working paper. + +LWG poll 3: Apply the changes in [P2212R2 (Relax Requirements for `time_point::clock`)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2212r2.html) to the C++ working paper. + +LWG poll 4: Apply the changes in [P2162R2 (Inheriting from `std::variant`)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2162r2.html) to the C++ working paper. + +LWG poll 5: Apply the changes in [P2160R1 (Locks lock lockables)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2160r1.html) to the C++ working paper. + +LWG poll 6: Apply the changes in [P2017R1 (Conditionally borrowed ranges)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2017r1.html) to the C++ working paper. + +LWG poll 7: Apply the changes in [P1682R2 (`std::to_underlying` for enumerations)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1682r2.html) to the C++ working paper. + +LWG poll 8 did not have consensus. + + +## Editorial fixes + +### Changes to motions + +* **Polls LWG-1, LWG-3502 and LWG 2, P2259R1:** Both the issue resolution of + [LWG-3502](https://cplusplus.github.io/LWG/issue3502) and the wording of + [P2259R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2259r1.html) + add wording in [24.7.16.3, range.elements.iterator] immediately after the + synopsis of class template elements_view::iterator. The + wording of P2259R1, which provides general definitions, was inserted before + the wording of LWG-3502, which adds a member specification. + +* **Poll LWG-4, P2162R2:** A sentence that introduced a list was reworded very + slightly to end in a colon. + +* **Poll LWG-5, P2160R1:** A sentence was turned into a bulleted list for + clarity, and the logical composition ("and" vs "or") was clarified. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4878 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/n4878...n4885). + + commit 7dec24a3adcda671751140407f91d0802142013b + Author: S. B. Tam + Date: Fri Dec 18 20:16:07 2020 +0800 + + [stacktrace.entry.overview] Italicize 'implementation-defined' in code block (#4421) + + commit e93b1868df751014c4f21c6b265823dcc7e51c69 + Author: S. B. Tam + Date: Fri Dec 18 20:24:10 2020 +0800 + + [basic.lookup.qual.general] Add \tcode around N::B<0> (#4422) + + commit bc7bfc8480fa1056e8a4bc1de9e841f82e662531 + Author: Eelis + Date: Sat Dec 26 17:30:41 2020 +0100 + + [stacktrace.syn] Add header index entry for . (#4434) + + commit adaa5cb85cb950f0d09f3ac7eff239576a6a6bcc + Author: Johel Ernesto Guerrero Peña + Date: Mon Dec 28 15:05:09 2020 -0400 + + [temp.explicit] Typo fix: remove extraneous x (#4439) + + commit d4c03ca423220c1f26aa718712ba6083f421e2ce + Author: Johel Ernesto Guerrero Peña + Date: Tue Dec 29 19:18:56 2020 -0400 + + [system.error.syn] Add dropped word (#4440) + + commit a864d2fae82c7a7c7a23121969d4da743c1c25ae + Author: Jens Maurer + Date: Fri Dec 18 21:16:31 2020 +0100 + + [localization] Reformat LaTeX source code. + + Also add two missing periods and remove one instance + of superfluous whitespace. + + commit 0162e808fccd74cffe663104f284f08e1efb65d1 + Author: Christof Meerwald + Date: Thu Jan 14 19:14:33 2021 +0100 + + [over.match.conv] add missing "can" (#4461) + + The word "can" seems to have been accidentally dropped when applying P1787R6. + + commit a8e2d0d30cab31a47a238603f9636e1d567fda3e + Author: Hubert Tong + Date: Thu Jan 14 13:17:16 2021 -0500 + + [expr.prim.req.type] Clarify example comment re: validity of name only (#4457) + + The comment that a class template specialization is required can be + taken as meaning that more is required than the validity of the + template-id (which is all that the requirement really checks). + + Additionally, the specific implications of the validity requirement is + spelled out. + + Co-authored-by: Hubert Tong + + commit 803511eb0815cee73167c8a85b78ca046fc3e7c6 + Author: Jens Maurer + Date: Mon Jan 4 22:15:58 2021 +0100 + + [over.match.viable, over.match.best.general] Use math mode, not \textit + + commit 7c5edb431df8ef4bc52e5297e5d54bc188967b8c + Author: Jens Maurer + Date: Thu Jan 14 19:23:50 2021 +0100 + + [fs.op.funcs] Qualify declarator-id with sub-namespace (#4459) + + commit 82821f2ef3e408b2a2e6b61b8de2342695b0dc42 + Author: Jens Maurer + Date: Mon Jan 4 21:39:47 2021 +0100 + + [thread.condition.general] Fix style of quotation marks + + commit da00c98ed9f4052e0205ce9079fa6a9dc527bc8b + Author: Jens Maurer + Date: Sun Jan 3 22:16:08 2021 +0100 + + [lib] Ensure non-member swap is declared in the header synopsis only + + commit f5380e66f3e60953388189c98472517344777be0 + Author: Jens Maurer + Date: Thu Jan 14 23:30:51 2021 +0100 + + [ranges] Improve concept index (#4456) + + commit 134d5f048a28a533e1ec45c45a289f1976b62232 + Author: Jens Maurer + Date: Sun Jan 3 22:37:01 2021 +0100 + + [lib] Use 'specialization' instead of 'instance' + + commit 836cc23f44e1c5b44376e75f2964f78f0f8b2a9b + Author: Jens Maurer + Date: Fri Jan 15 13:10:45 2021 +0100 + + [concepts.equality] Turn 'e.g.' into a proper example (#4442) + + commit d35605c14368a3418a999ca6aaf31627a79e14fb + Author: Hubert Tong + Date: Sat Jan 2 22:21:44 2021 -0500 + + [over.built] Correct note re: "hiding" to match over.match.oper/3 + + The note in [over.built] uses "hidden" to describe how built-in + candidates are removed from consideration; however, this is not + hiding in the sense of name lookup. This PR removes the bad + terminology and also corrects the note to defer to the normative + text regarding the conditions upon user-written candidates that + suppress built-in candidates. + + commit 7b197155b61c6ddd63386f915adbfb59258de89c + Author: Johel Ernesto Guerrero Peña + Date: Fri Jan 15 09:40:58 2021 -0400 + + [range.iota.iterator,range.iota.sentinel] Add missing requires-clauses on out-of-class member definitions (#4426) + + These additional clauses were accidentally omitted from LWG3292, but should have been part of that issue's resolution. + + commit f81e3a820461cd5917448d9ec2519bdd0e6adb91 + Author: frederick-vs-ja + Date: Thu Jan 28 05:14:25 2021 +0800 + + [stacktrace.basic.overview] Add missing "namespace std {" (#4469) + + commit afd12f1de36eb0b47292c179d573ee797611d359 + Author: Johel Ernesto Guerrero Peña + Date: Sat Jan 30 15:53:02 2021 -0400 + + [iterator.concept.winc] Index implementation-defined integer-class type (#4470) + + Also fix a typo. + + commit 1aee0cad91184b6f4d4938ba0e8597e0fc644342 + Author: Johel Ernesto Guerrero Peña + Date: Mon Feb 1 07:04:38 2021 -0400 + + [lib] Change 'expression inside noexcept' to 'exception specification' (#4105) + + * [lib] 'expression inside noexcept' -> 'exception specification' + + commit 4030cfc62ea51a02d884f170d92c4d0149977c02 + Author: lam-work-group <77063444+lam-work-group@users.noreply.github.com> + Date: Tue Jan 26 15:30:41 2021 +0800 + + [stacktrace.basic.cmp] Update 'lexicographical_compare_3way' + + P1614R2 changed the name to 'lexicographical_compare_three_way'. + + commit be7b0a691b5414996fd0531e15a556a49fc982b6 + Author: Jens Maurer + Date: Sun Jan 3 21:19:24 2021 +0100 + + [index] Add missing implementation-defined types + + commit e429dfc01ed44cb3dd5f6095c74a759aebdb00c4 + Author: Jens Maurer + Date: Sun Dec 27 23:41:52 2020 +0100 + + [library.general] Adjust order according to recent clause reorganizations. + + commit 81a911dfb70f0d2f0450592ca49ebd05056e86e1 + Author: Jens Maurer + Date: Wed Dec 30 22:17:24 2020 +0100 + + [range.dangling] Split up overly long sentence. + + commit 22789a0312a773c7ec77dd6a6b9c1f39a3a4634e + Author: Jens Maurer + Date: Thu Feb 4 17:50:26 2021 +0100 + + [format.arg] Fix return type of visit_format_arg + + It was specified as 'see below', pointing nowhere. + Use 'decltype(auto)', congruent with the Effects item. + + commit 065df74900d3bd2e1dbdec105de4e3742e059eda + Author: Johel Ernesto Guerrero Peña + Date: Mon Feb 15 06:17:20 2021 -0400 + + [README] Update requirements for "Getting Started" on Arch Linux (#4496) + + commit 0a107ed35ef44becc00dea9329f6a7da6e0be98a + Author: Johel Ernesto Guerrero Peña + Date: Mon Feb 15 06:21:34 2021 -0400 + + [func.bind.front] Use a more conventional introduction (#4488) + + commit 3510342f18537f4b1feac191ec6e7fce649f5014 + Author: Jens Maurer + Date: Mon Feb 15 11:23:05 2021 +0100 + + [stmt.pre] Excise undefined term 'contained' (#4485) + + commit 80c5fdf17341121464360e953039bd03a9aa3a0f + Author: Jens Maurer + Date: Fri Feb 5 21:41:05 2021 +0100 + + [dcl.init.general] Fix misapplied term 'block variable' + + Block-scope externs are in view here, but those are not + block variables, because their target scope is an + enclosing namespace scope. + + commit 7620db718df1ff82c2468b75f3449ced8ad7b716 + Author: Jens Maurer + Date: Fri Feb 5 22:02:04 2021 +0100 + + [lib] Use 'tm', not 'struct tm' + + Using the elaborated-type-specifier implies that this type + is declared in namespace 'std', which might not be true. + + commit 5494117ea39b36ce3e590025943a8ff48e78b4d3 + Author: Jens Maurer + Date: Thu Feb 18 17:39:13 2021 +0100 + + [container.requirements] Use bulleted lists to introduce identifiers + + commit 70da127291269dbda3f1cad7cb34936cf0bdbcf1 + Author: Arthur O'Dwyer + Date: Mon Feb 22 05:26:52 2021 -0500 + + [vector.bool] Remove an extra closing parenthesis (#4501) + + commit 825255f7c3be12b4807c6df4c1183632d973cf53 + Author: Marek Kurdej + Date: Mon Feb 22 19:58:47 2021 +0100 + + [stdatomic.h.syn] Add semicolons in using-declarations (#4502) + + commit cddc112f2b4baa4ce8cc97c60aa04276fd86afc5 + Author: Casey Carter + Date: Tue Feb 23 12:08:32 2021 -0800 + + [range.iota.iterator,range.iota.sentinel] Fix markup around \libconcept (#4503) + + ...so it doesn't appear in the rendered text. + + commit 14952c5e7f742f89c233bc13be05f4825d54db17 + Author: Dawn Perchik + Date: Thu Feb 25 03:08:34 2021 -0800 + + [std] Fixes for library concepts that should be \libconcept'd. + + commit 1f854d8f83e4eb7d672aa224aabd882e1a70241d + Author: Christopher Di Bella + Date: Mon Mar 1 10:30:31 2021 -0800 + + [optional.ctor] Add missing \tcode around 'true' (#4534) + + commit 066bb6b3acd61761cccb639b191429b95271dbb8 + Author: Jens Maurer + Date: Thu Dec 3 19:56:30 2020 +0100 + + [cpp.import] Clarify header units as the source of macro definitions. + + commit e8240fbde651d690f2e01b5770494e3d9189dca6 + Author: MattStephanson <68978048+MattStephanson@users.noreply.github.com> + Date: Sun Mar 7 00:29:30 2021 -0800 + + [time.syn] add constexpr to leap_second comparisons (#4539) + + commit 2fdafbee15266047133d714e031468be47affe95 + Author: Casey Carter + Date: Fri Mar 12 15:29:26 2021 -0800 + + [ranges.syn] Don't constrain specializations of enable_borrowed_range (#4519) + + These constraints redundantly repeat the constraints from the template we're partially specializing for. This isn't incorrect, but it is unnecessary, adds opportunities for editorial errors, and is inconsistent with how other partial specializations of templates for constrained types are specified. + + commit dfbc9e657ade9674274b6b234ee28f57a7259136 + Author: Jens Maurer + Date: Fri Oct 30 09:07:03 2020 +0100 + + [conv.rank] Avoid 'shall' for plain descriptions. + + commit ebdeb7e99223639d24934b7f00be315e1d9288b7 + Author: Jens Maurer + Date: Sun Jan 3 20:58:05 2021 +0100 + + [floatfield.manip] Rephrase note about ios_base::hex + + commit ce7e6bfaef0e2350e90e5c26154c9cfa59900c4f + Author: Jens Maurer + Date: Mon Jan 4 00:12:38 2021 +0100 + + [range.split.outer] Clarify scope of exposition-only 'current' + + commit 55c36ec3684a02cb39b232bc34b4a7d22c0a874b + Author: Johel Ernesto Guerrero Peña + Date: Mon Dec 28 02:23:27 2020 -0400 + + [unord.hash] Remove redundant wording + + commit f6d7b014f5b50850ccd3fd31127917ad44309634 + Author: Jens Maurer + Date: Sat Feb 6 22:04:39 2021 +0100 + + [temp.expl.spec] Use 'reachable from', not 'declared before' + + With modules, 'declared before' no longer makes sense. + + commit ce0db1e1515aedee533a53145d76d9e5495f6f00 + Author: Jens Maurer + Date: Mon Mar 15 14:00:53 2021 +0100 + + [cmp.alg] Clarify that ill-formed CPO invocations are SFINAE-friendly (#4494) + + commit 6dbc76a0935998443d0a28b962d86649c56b27f4 + Author: Johel Ernesto Guerrero Peña + Date: Fri Jan 29 15:40:10 2021 -0400 + + [lib] Index all uses of public concepts + + commit 0b3d8ed6e8a70bedeb0ca161f1a6121cb769266b + Author: S. B. Tam + Date: Mon Mar 15 21:15:17 2021 +0800 + + [stacktrace.entry.query] Fix description of `source_line` (#4481) + + This fixes a misapplication of P0881R7. + + commit fab6f7f0d05b081cf183d1d56811f101ba6c89e6 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Mon Mar 15 23:45:41 2021 +0300 + + [dcl.fct] Integrate return type requirements from [expr.call] and simplify them (#4113) + + There is a general prohibition against arrays of function type in [dcl.array]. + There is no need to highlight some specific permitted types; it is sufficient + to state the general rule. + + commit 793eb7be096f76dcdf71dde1238ad24ed1c9e13e + Author: Jens Maurer + Date: Mon Mar 15 22:53:55 2021 +0100 + + [dcl.pre] Reorder paragraphs (#4462) + + Group discussion of simple-declaration and + move other kinds of declarations to the end. + + commit e66bf8fa69e2d0e7c5314a7720cdd9e9e63421db + Author: Hubert Tong + Date: Mon Apr 20 17:50:13 2020 -0400 + + [dcl.fct.def.delete] Make terms cover semantic deletedness + + The definition of "deleted definition" in [dcl.fct.def.delete] is not + written in the form of a definition and neither is the definition of + "deleted function". Most problematically, these definitions encompass + only the syntactic case of explicitly deleting a function but the terms + are used where semantic deletedness is meant. + + Applying the syntactic interpretation of the definition could lead to + the conclusion that the following is ill-formed: + ```cpp + struct A { ~A() = delete; }; + struct B { + A a; + virtual ~B() = default; + }; + struct C : B { virtual ~C() = delete; }; + ``` + + This patch changes the definitions to cover semantic deletion. + + **Drafting notes:** + + - It appears that uses of "deleted definition" in the text is usually + refer to physical definitions (but not necessarily to explicit + deletions). + - The increased verbosity is somewhat necessary to meet the ideal that + uses of a term may be replaced with the definition of the term with + minimal adjustments. + + commit 44e3c7fb3e88e45738926d652ed6a78c1df6619b + Author: Casey Carter + Date: Tue Mar 16 13:44:19 2021 -0700 + + [range.split.inner] Clarify paragraph 1 (#4545) + + ... to avoid confusion about what it means for a name that is not present to denote a type. + diff --git a/papers/n4893.html b/papers/n4893.html new file mode 100644 index 0000000000..4199ee04d2 --- /dev/null +++ b/papers/n4893.html @@ -0,0 +1,625 @@ + + + +N4893 + + +

N4893 Editors' Report -- Programming Languages -- C++

+ +

Date: 2021-06-18

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

Thanks to all those who have submitted editorial +issues +and to those who have provided pull requests with fixes, and special thanks to +Johel Ernesto Guerrero Peña for providing in-depth review of most of the draft +motion applications.

+ +

New papers

+ +
    +
  • N4892 is the +current working draft for C++23. It replaces +N4885.
  • +
  • N4893 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group polls

+ +

CWG poll 1: Accept as Defect Reports all issues in P2386R0 +(Core Language Working Group “ready” Issues for the June, 2021 +meeting) and apply the proposed resolutions to the C++ working paper.

+ +

CWG poll 2: Apply the changes in P1938R3 +(if consteval) to the C++ working paper.

+ +

CWG poll 3: Apply the changes in P2186R2 +(Removing Garbage Collection Support) to the C++ working paper.

+ +

CWG poll 4: Accept P1949R7 +(C++ Identifier Syntax using Unicode Standard Annex 31) as a Defect Report and +apply the changes therein to the C++ working paper.

+ +

CWG poll 5: Accept P2156R1 +(Allow Duplicate Attributes) as a Defect Report and apply the changes therein to +the C++ working paper.

+ +

CWG poll 6: Apply the changes in P1401R5 +(Narrowing contextual conversions to bool) to the C++ working paper.

+ +

CWG poll 7: Apply the changes in P2223R2 +(Trimming whitespaces before line splicing) to the C++ working paper.

+ +

CWG poll 8: Apply the changes in P1847R4 +(Make declaration order layout mandated) to the C++ working paper.

+ +

CWG poll 9: Apply the changes in P2201R1 +(Mixed string literal concatenation) to the C++ working paper.

+ +

Library working group polls

+ +

LWG polls 1 and 2 appertain to the Concurrency TS, not the C++ working paper.

+ +

LWG poll 3: Apply the changes for all Tentatively Ready issues in P2385R0 +(C++ Standard Library Issues to be moved in Virtual Plenary, June 2021) to the +C++ working paper.

+ +

LWG poll 4: Apply the changes in P1132R7 +P1132R8 +(out_ptr - a scalable output pointer abstraction) to the C++ working +paper. See below for a change of paper.

+ +

LWG poll 5: Apply the changes in P1328R1 +(Making std::type_info::operator== constexpr) to the C++ working paper.

+ +

LWG poll 6: Apply the changes in P0448R4 +(A strstream replacement using span as buffer) to the C++ working paper.

+ +

LWG poll 7: Apply the changes in P1425R4 +(Iterators pair constructors for stack and queue) to the C++ working paper.

+ +

LWG poll 8: Apply the changes in P1518R2 +(Stop overconstraining allocators in container deduction guides) to the C++ +working paper.

+ +

LWG poll 9: Apply the changes in P0401R6 +(Providing size feedback in the Allocator interface) to the C++ working paper.

+ +

LWG poll 10: Apply the changes in P1659R3 +(starts_with and ends_with) to the C++ working paper.

+ +

LWG poll 11: Apply the changes in P1951R1 +(Default Arguments for pair's Forwarding Constructor) to the C++ working +paper.

+ +

LWG poll 12: Apply the changes in P1989R2 +(Range constructor for std::string_view 2: Constrain Harder) to the C++ +working paper.

+ +

LWG poll 13: Apply the changes in P2136R3 +(invoke_r) to the C++ working paper.

+ +

LWG poll 14: Apply the changes in P2166R1 +(A Proposal to Prohibit std::basic_string and std::basic_string_view +construction from nullptr) to the C++ working paper.

+ +

Note: The remaining changes are to be considered defects against C++20.

+ +

LWG poll 15: Apply the changes in P2231R1 +(Missing constexpr in std::optional and std::variant) to the C++ working +paper, as a defect report for C++20.

+ +

LWG poll 16: Apply the changes in P2216R3 +(std::format improvements) to the C++ working paper, as a defect report for +C++20.

+ +

LWG poll 17: Apply the changes in P2281R1 +(Clarifying range adaptor objects) to the C++ working paper. This resolves LWG +issues 3509 and 3510.

+ +

LWG poll 18: Apply the changes in P2328R1 +(join_view should join all views of ranges) to the C++ working paper, as a +defect report for C++20.

+ +

LWG poll 19: Apply the changes in P2325R3 +(Views should not be required to be default constructible) to the C++ working +paper, as a defect report for C++20.

+ +

LWG poll 20: Apply the changes in P2210R2 +(Superior String Splitting) to the C++ working paper, as a defect report for +C++20.

+ +

LWG poll 21: Apply the changes in P2367R0 +(Remove misuses of list-initialization from Clause 24) to the C++ working paper, +as a defect report for C++20.

+ +

Editorial fixes

+ +

Changes to motions

+ +
    +
  • Poll CWG-3: A few further minor mentions and references to pointer safety +have also been removed, as has the Annex C entry.

  • +
  • Poll CWG-4: References to URLs have been reworded very slightly to be +consistent with existing references (“available from:” instead of +“available at”). Subclause headings in the new Annex have been +changed from title case to sentence case. This is also the first motion create +a new Annex C entry, so the new Annex C section for C++20 has been created as +part of this change.

  • +
  • Poll LWG-4: An updated paper P1132R8 containing several editorial +corrections had been produced prior to the meeting, but the motions list had +inadvertently not been updated. It was made clear to WG21 that P1132R8 was +being polled instead of the obsolete revision P1132R7; the R8 revision has +been applied to the working paper.

  • +
  • Poll LWG-12: During review, it was identified that an erroneous R should +have said remove_reference_t<R>. This has been corrected, with LWG's +awareness and consent.

  • +
  • Poll LWG-16: The resolution of LWG +3539 that was adopted as part of LWG Poll-3 has been applied to the new +wording of this poll as well, adding std::move as appropriate.

  • +
  • Poll LWG-19: The wording incorporates changes that were contingent on the +adoption of LWG Poll-18.

  • +
  • Poll LWG-20: The resolution of LWG +3533 that was adopted as part of LWG Poll-3 has been applied to the new +wording of this poll as well, changing the type and constraints of base as +appropriate.

  • +
  • Poll LWG-21: The wording incorporates additional changes to the new +wording introduced by LWG Poll-20.

  • +
+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4885 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 7faee4ca019296fd2572df324dcae70ac495e6e4
+Author: cor3ntin <corentinjabot@gmail.com>
+Date:   Sat Apr 10 10:45:20 2021 +0200
+
+    [std] Spell "whitespace" consistently (#4557)
+
+    Unify the spellings "whitespace", white-space", and "white space"
+    by using "whitespace" consistently.
+
+commit 34d0392e2f32ea19aebab4919a525a3a9679594f
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Fri Apr 16 20:39:04 2021 +0300
+
+    [intro.object] Turn non-normative wording into a Note (#4490)
+
+    Remove incorrect wording.
+
+commit f9dac664a11e438ea0dd803f3e5af5675e9fce0a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Apr 2 12:09:52 2021 +0200
+
+    [ranges.syn] Add primary templates for tuple-like protocol
+
+    The primary templates tuple_size and tuple_element
+    are partially specialized, and should be declared
+    before doing so.
+
+commit 7f7700143accb1447e193ed8f64b4ebe5efab215
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 27 14:10:47 2021 +0100
+
+    [except.spec] Clarify potentially-throwing functions
+
+    Expressions are potentially-throwing; functions have a
+    potentially-throwing exception specification.
+
+commit a1d8bc1e81ba0b1570c53879bad41536648ae916
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 26 23:03:53 2021 +0100
+
+    [format.context] Rephrase recommended practice
+
+commit 5e3a688fb6ffd88c099e54172899c08364a7dada
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 19 08:54:57 2021 +0100
+
+    [except.ctor] Remove false claim about automatic objects
+
+    CWG1774 clarified that partially-constructed objects may not be of
+    automatic storage duration. CWG2256 re-introduced that false
+    claim.
+
+commit a912904092fcf3af0bdc17c394971f07a899e7d9
+Author: Vlad Serebrennikov <brainvlad@gmail.com>
+Date:   Fri Apr 30 19:27:56 2021 +0300
+
+    [lex.string] Change "string-literal" to "string literal object" (#4549)
+
+commit e6e47706cb21496031dddaffdece2c5ff5f5e960
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun May 2 12:17:40 2021 +0200
+
+    [template.bitset.general,bitset.members] Use injected-class-name
+
+commit 95ff48305153edf3af4b136eff48f93ea68867d0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun May 2 12:21:17 2021 +0200
+
+    [bitset.operators] Add missing template-head for operator functions
+
+commit eeeb27394f8fd4c9cf38d3071338de17759c859e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun May 2 16:43:22 2021 +0200
+
+    [forward.list] Rename stable label from [forwardlist]
+
+    This makes the labels consistent.
+
+commit 7e0beb7c3aacbd53fee0450196a12d2b8fdd6f5d
+Author: morinmorin <mimomorin@gmail.com>
+Date:   Wed May 19 04:26:19 2021 +0900
+
+    [tuple.elem] Replace "member variables" with "non-static data members" (#4602)
+
+commit fc0e8902effe4cb195bb05eb62311a9eb0aea384
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Thu May 20 15:21:09 2021 -0500
+
+    [range.elements.sentinel] Correct return type of operator- (#4603)
+
+    This is a missed edit from LWG3406.
+
+commit 6fbc8df1b99e49a015bdc976a83044be0cc1344f
+Author: birbacher <frank.birbacher@gmail.com>
+Date:   Fri May 21 18:28:01 2021 +0200
+
+    [vector.bool] Remove top-level const from parameter declaration (#4608)
+
+commit 046c4d349ab4f0630d586b5143c2d313ec820dac
+Author: Jason Cobb <jason.e.cobb@gmail.com>
+Date:   Fri May 21 14:24:26 2021 -0400
+
+    [expr.static.cast] fix wording for static_cast from pointer to base to pointer to derived (#4605)
+
+commit 7789f707ec229fe16329fa890e28bd14eb85bd18
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri May 21 12:09:35 2021 -0700
+
+    [vector.bool] reference has multiple assignment operators (#4607)
+
+commit ab87501552f7ed46b542543d0e8536cc7f52d4bb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Feb 5 22:17:12 2021 +0100
+
+    [defns.well.formed] Fix definition of 'well-formed'
+
+commit 9b76d32e926b98cee1e9aa9556c660b4fd23c47b
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue May 25 14:59:51 2021 +0100
+
+    [list.ops] Fix name of parameter in list::unique effects
+
+commit b7c06451fd87eea847613e83ca5316b2a4d072fb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat May 29 08:53:46 2021 +0200
+
+    [temp.over.link] Add missing \grammarterm marker (#4609)
+
+commit d006a0db172f63fb4a07704bad3b2237f990e4f2
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Oct 8 10:17:43 2020 +0100
+
+    [rand.eng.sub] drop no-op modulo operation
+
+    The e() mod 2^32 operation is a no-op, because e.max() < 2^32.
+
+commit 337c7dbd0a3680ae146db21e1735433e53b6657e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 5 00:25:11 2020 +0100
+
+    [expr] Use 'qualification-combined' and 'qualification-decomposition'
+
+    The previous names 'cv-combined' and 'cv-decomposition' are
+    no longer adequate since a qualification conversion can now
+    convert to an array of unknown bounds.
+
+commit 1bc43817ce3caef3ed68cbc92046e2bc2738e335
+Author: Stephan T. Lavavej <stl@nuwen.net>
+Date:   Sat May 29 02:59:05 2021 -0700
+
+    [time.clock.cast.sys],[time.clock.cast.utc] Use Duration2 for clarity. (#4565)
+
+    [time.clock.cast.sys],[time.clock.cast.utc] Use Duration2 for clarity.
+
+commit 4a2546a1857f7b55eab395589893bdd0999956b2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Apr 21 23:23:30 2021 +0200
+
+    [expr.await] Clarify rethrowing exceptions from await-suspend
+
+commit 72855b062397efdbd30ec5d8c88317d19e27776b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Apr 2 12:23:30 2021 +0200
+
+    [dcl.init.aggr] An initializer list is brace-enclosed
+
+    Do not claim that a designated-initializer-list or
+    an initializer-list is an initializer list.
+
+commit 93d7a96979ff071b76dc211fd4625654b94e8a67
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jan 14 12:20:20 2021 +0100
+
+    [basic.lookup.unqual] Add examples for conversion-function-ids
+
+commit 890b339661891896ee60d28f19be79ecda4d6296
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Mar 27 13:16:52 2021 +0100
+
+    [namespace.def.general] Clarify inline namespaces
+
+    Highlight 'innermost enclosing' namespace.
+
+commit d6d36b48e5c5b8a63e4b93c2f75aa4f9f1e4862b
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Sat May 29 19:26:10 2021 -0500
+
+    [range.elements.overview] Correct example
+
+commit b0a253cc6ba0e7f556f5afefab94f7cc1d1e5ced
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jun 1 12:56:45 2021 +0100
+
+    [expr.const.cast] Fix punctuation placement.
+
+commit caf7428fd6c807f30538042cf9bf1b27b8772b01
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 3 09:53:27 2021 +0200
+
+    [ranges] Rename 'not-same-as' to 'different-from'.
+
+    'not-same-as' is not quite equivalent to 'not same_as'.
+
+commit fb3bea889899c5ea5c0f70b12fc72129f7d1692a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jun 1 22:39:52 2021 +0200
+
+    [expr] Add cross-references for 'local entity'.
+
+    A local entity is not any entity that is local, so add
+    cross-references for clarification.
+
+commit 77d389ffccb7c7ba294834d3196a5bccf25d28e0
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon Jun 7 12:53:22 2021 -0500
+
+    [ranges] Use views::meow in examples instead of meow_view
+
+commit e03d76cb5067598a92105ad7c4841a3d18e5b5d0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 11 22:42:33 2021 +0200
+
+    [fs.path.native.obs] Remove bogus note.
+
+commit 20b924987e59d087af7b28df33490d34466f688c
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jun 4 12:32:04 2021 +0100
+
+    [range.prim.data] Use ranges::begin(t) not ranges::begin(E)
+
+    This is consistent with the typo fixes for ranges::size done in
+    aa9c660a835540117123617a13b0ba1ab6dd801e as part of #3752.
+
+commit e9e2acb4cdff00236aa750c717e1951c655797df
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 17 22:40:23 2021 +0200
+
+    [format.syn] Remove extraneous commas in vformat_to declarations (#4705)
+
+commit d3fbad184abd1c327dd2dd097cd3caa17ada48af
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Apr 2 21:55:37 2021 +0200
+
+    [basic.stc.static] Rephrase the definition of 'static storage duration'
+
+    This clarifies and centralizes the definition and
+    also avoids the undefined term 'local variable'.
+
+commit b6e0848db7a72560a7bfc84f16bd23abf6aab2d6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 4 00:15:46 2021 +0200
+
+    [class.pre] Fix incorrect comment in example
+
+commit 1e889e06856a17f48e32a03a4272502dd67e1035
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 18 19:07:50 2021 +0200
+
+    [temp.variadic] Rearrange description of pack expansion (#4543)
+
+commit 94340ede298a23927523ee28c1c04090416eb20d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jun 18 15:00:48 2021 +0100
+
+    [basic.string.general], [string.view.template.general] remove constexpr
+
+    There is no reason to declare a deleted function constexpr.
+
+commit 472e865817e17620ae4c88fef10e2983884b9f77
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jun 18 22:26:14 2021 +0100
+
+    [range.utility.helper] Add missing '='
+
+commit 421a2e258e2848016df92939f5a1cfa865c7f795
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jun 18 23:06:52 2021 +0100
+
+    [range.join.iterator] Add missing \tcode
+
diff --git a/papers/n4893.md b/papers/n4893.md new file mode 100644 index 0000000000..613dafaab0 --- /dev/null +++ b/papers/n4893.md @@ -0,0 +1,493 @@ +# N4893 Editors' Report -- Programming Languages -- C++ + +Date: 2021-06-18 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes, and special thanks to +Johel Ernesto Guerrero Peña for providing in-depth review of most of the draft +motion applications. + +## New papers + + * [N4892](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4892.pdf) is the + current working draft for C++23. It replaces + [N4885](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4885.pdf). + * N4893 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group polls + +CWG poll 1: Accept as Defect Reports all issues in P2386R0 +(Core Language Working Group “ready” Issues for the June, 2021 +meeting) and apply the proposed resolutions to the C++ working paper. + +CWG poll 2: Apply the changes in P1938R3 +(`if consteval`) to the C++ working paper. + +CWG poll 3: Apply the changes in P2186R2 +(Removing Garbage Collection Support) to the C++ working paper. + +CWG poll 4: Accept P1949R7 +(C++ Identifier Syntax using Unicode Standard Annex 31) as a Defect Report and +apply the changes therein to the C++ working paper. + +CWG poll 5: Accept P2156R1 +(Allow Duplicate Attributes) as a Defect Report and apply the changes therein to +the C++ working paper. + +CWG poll 6: Apply the changes in P1401R5 +(Narrowing contextual conversions to bool) to the C++ working paper. + +CWG poll 7: Apply the changes in P2223R2 +(Trimming whitespaces before line splicing) to the C++ working paper. + +CWG poll 8: Apply the changes in P1847R4 +(Make declaration order layout mandated) to the C++ working paper. + +CWG poll 9: Apply the changes in P2201R1 +(Mixed string literal concatenation) to the C++ working paper. + +### Library working group polls + +LWG polls 1 and 2 appertain to the Concurrency TS, not the C++ working paper. + +LWG poll 3: Apply the changes for all Tentatively Ready issues in P2385R0 +(C++ Standard Library Issues to be moved in Virtual Plenary, June 2021) to the +C++ working paper. + +LWG poll 4: Apply the changes in P1132R7 +P1132R8 +(`out_ptr` - a scalable output pointer abstraction) to the C++ working +paper. *See below for a change of paper.* + +LWG poll 5: Apply the changes in P1328R1 +(Making `std::type_info::operator==` constexpr) to the C++ working paper. + +LWG poll 6: Apply the changes in P0448R4 +(A `strstream` replacement using `span` as buffer) to the C++ working paper. + +LWG poll 7: Apply the changes in P1425R4 +(Iterators pair constructors for `stack` and `queue`) to the C++ working paper. + +LWG poll 8: Apply the changes in P1518R2 +(Stop overconstraining allocators in container deduction guides) to the C++ +working paper. + +LWG poll 9: Apply the changes in P0401R6 +(Providing size feedback in the Allocator interface) to the C++ working paper. + +LWG poll 10: Apply the changes in P1659R3 +(`starts_with` and `ends_with`) to the C++ working paper. + +LWG poll 11: Apply the changes in P1951R1 +(Default Arguments for `pair`'s Forwarding Constructor) to the C++ working +paper. + +LWG poll 12: Apply the changes in P1989R2 +(Range constructor for `std::string_view` 2: Constrain Harder) to the C++ +working paper. + +LWG poll 13: Apply the changes in P2136R3 +(`invoke_r`) to the C++ working paper. + +LWG poll 14: Apply the changes in P2166R1 +(A Proposal to Prohibit `std::basic_string` and `std::basic_string_view` +construction from `nullptr`) to the C++ working paper. + +**Note:** The remaining changes are to be considered defects against C++20. + +LWG poll 15: Apply the changes in P2231R1 +(Missing `constexpr` in `std::optional` and `std::variant`) to the C++ working +paper, as a defect report for C++20. + +LWG poll 16: Apply the changes in P2216R3 +(`std::format` improvements) to the C++ working paper, as a defect report for +C++20. + +LWG poll 17: Apply the changes in P2281R1 +(Clarifying range adaptor objects) to the C++ working paper. This resolves LWG +issues 3509 and 3510. + +LWG poll 18: Apply the changes in P2328R1 +(`join_view` should join all views of ranges) to the C++ working paper, as a +defect report for C++20. + +LWG poll 19: Apply the changes in P2325R3 +(Views should not be required to be default constructible) to the C++ working +paper, as a defect report for C++20. + +LWG poll 20: Apply the changes in P2210R2 +(Superior String Splitting) to the C++ working paper, as a defect report for +C++20. + +LWG poll 21: Apply the changes in P2367R0 +(Remove misuses of list-initialization from Clause 24) to the C++ working paper, +as a defect report for C++20. + +## Editorial fixes + +### Changes to motions + +* **Poll CWG-3:** A few further minor mentions and references to pointer safety + have also been removed, as has the Annex C entry. + +* **Poll CWG-4:** References to URLs have been reworded very slightly to be + consistent with existing references (“available from:” instead of + “available at”). Subclause headings in the new Annex have been + changed from title case to sentence case. This is also the first motion create + a new Annex C entry, so the new Annex C section for C++20 has been created as + part of this change. + +* **Poll LWG-4:** An updated paper P1132R8 containing several editorial + corrections had been produced prior to the meeting, but the motions list had + inadvertently not been updated. It was made clear to WG21 that P1132R8 was + being polled instead of the obsolete revision P1132R7; the R8 revision has + been applied to the working paper. + +* **Poll LWG-12:** During review, it was identified that an erroneous `R` should + have said `remove_reference_t`. This has been corrected, with LWG's + awareness and consent. + +* **Poll LWG-16:** The resolution of LWG + 3539 that was adopted as part of LWG Poll-3 has been applied to the new + wording of this poll as well, adding `std::move` as appropriate. + +* **Poll LWG-19:** The wording incorporates changes that were contingent on the + adoption of LWG Poll-18. + +* **Poll LWG-20:** The resolution of LWG + 3533 that was adopted as part of LWG Poll-3 has been applied to the new + wording of this poll as well, changing the type and constraints of `base` as + appropriate. + +* **Poll LWG-21:** The wording incorporates additional changes to the new + wording introduced by LWG Poll-20. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4885 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/n4885...n4892). + + commit 7faee4ca019296fd2572df324dcae70ac495e6e4 + Author: cor3ntin + Date: Sat Apr 10 10:45:20 2021 +0200 + + [std] Spell "whitespace" consistently (#4557) + + Unify the spellings "whitespace", white-space", and "white space" + by using "whitespace" consistently. + + commit 34d0392e2f32ea19aebab4919a525a3a9679594f + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Fri Apr 16 20:39:04 2021 +0300 + + [intro.object] Turn non-normative wording into a Note (#4490) + + Remove incorrect wording. + + commit f9dac664a11e438ea0dd803f3e5af5675e9fce0a + Author: Jens Maurer + Date: Fri Apr 2 12:09:52 2021 +0200 + + [ranges.syn] Add primary templates for tuple-like protocol + + The primary templates tuple_size and tuple_element + are partially specialized, and should be declared + before doing so. + + commit 7f7700143accb1447e193ed8f64b4ebe5efab215 + Author: Jens Maurer + Date: Sat Mar 27 14:10:47 2021 +0100 + + [except.spec] Clarify potentially-throwing functions + + Expressions are potentially-throwing; functions have a + potentially-throwing exception specification. + + commit a1d8bc1e81ba0b1570c53879bad41536648ae916 + Author: Jens Maurer + Date: Fri Mar 26 23:03:53 2021 +0100 + + [format.context] Rephrase recommended practice + + commit 5e3a688fb6ffd88c099e54172899c08364a7dada + Author: Jens Maurer + Date: Fri Mar 19 08:54:57 2021 +0100 + + [except.ctor] Remove false claim about automatic objects + + CWG1774 clarified that partially-constructed objects may not be of + automatic storage duration. CWG2256 re-introduced that false + claim. + + commit a912904092fcf3af0bdc17c394971f07a899e7d9 + Author: Vlad Serebrennikov + Date: Fri Apr 30 19:27:56 2021 +0300 + + [lex.string] Change "string-literal" to "string literal object" (#4549) + + commit e6e47706cb21496031dddaffdece2c5ff5f5e960 + Author: Jens Maurer + Date: Sun May 2 12:17:40 2021 +0200 + + [template.bitset.general,bitset.members] Use injected-class-name + + commit 95ff48305153edf3af4b136eff48f93ea68867d0 + Author: Jens Maurer + Date: Sun May 2 12:21:17 2021 +0200 + + [bitset.operators] Add missing template-head for operator functions + + commit eeeb27394f8fd4c9cf38d3071338de17759c859e + Author: Jens Maurer + Date: Sun May 2 16:43:22 2021 +0200 + + [forward.list] Rename stable label from [forwardlist] + + This makes the labels consistent. + + commit 7e0beb7c3aacbd53fee0450196a12d2b8fdd6f5d + Author: morinmorin + Date: Wed May 19 04:26:19 2021 +0900 + + [tuple.elem] Replace "member variables" with "non-static data members" (#4602) + + commit fc0e8902effe4cb195bb05eb62311a9eb0aea384 + Author: timsong-cpp + Date: Thu May 20 15:21:09 2021 -0500 + + [range.elements.sentinel] Correct return type of operator- (#4603) + + This is a missed edit from LWG3406. + + commit 6fbc8df1b99e49a015bdc976a83044be0cc1344f + Author: birbacher + Date: Fri May 21 18:28:01 2021 +0200 + + [vector.bool] Remove top-level const from parameter declaration (#4608) + + commit 046c4d349ab4f0630d586b5143c2d313ec820dac + Author: Jason Cobb + Date: Fri May 21 14:24:26 2021 -0400 + + [expr.static.cast] fix wording for static_cast from pointer to base to pointer to derived (#4605) + + commit 7789f707ec229fe16329fa890e28bd14eb85bd18 + Author: Casey Carter + Date: Fri May 21 12:09:35 2021 -0700 + + [vector.bool] reference has multiple assignment operators (#4607) + + commit ab87501552f7ed46b542543d0e8536cc7f52d4bb + Author: Jens Maurer + Date: Fri Feb 5 22:17:12 2021 +0100 + + [defns.well.formed] Fix definition of 'well-formed' + + commit 9b76d32e926b98cee1e9aa9556c660b4fd23c47b + Author: Jonathan Wakely + Date: Tue May 25 14:59:51 2021 +0100 + + [list.ops] Fix name of parameter in list::unique effects + + commit b7c06451fd87eea847613e83ca5316b2a4d072fb + Author: Jens Maurer + Date: Sat May 29 08:53:46 2021 +0200 + + [temp.over.link] Add missing \grammarterm marker (#4609) + + commit d006a0db172f63fb4a07704bad3b2237f990e4f2 + Author: Jonathan Wakely + Date: Thu Oct 8 10:17:43 2020 +0100 + + [rand.eng.sub] drop no-op modulo operation + + The e() mod 2^32 operation is a no-op, because e.max() < 2^32. + + commit 337c7dbd0a3680ae146db21e1735433e53b6657e + Author: Jens Maurer + Date: Thu Nov 5 00:25:11 2020 +0100 + + [expr] Use 'qualification-combined' and 'qualification-decomposition' + + The previous names 'cv-combined' and 'cv-decomposition' are + no longer adequate since a qualification conversion can now + convert to an array of unknown bounds. + + commit 1bc43817ce3caef3ed68cbc92046e2bc2738e335 + Author: Stephan T. Lavavej + Date: Sat May 29 02:59:05 2021 -0700 + + [time.clock.cast.sys],[time.clock.cast.utc] Use Duration2 for clarity. (#4565) + + [time.clock.cast.sys],[time.clock.cast.utc] Use Duration2 for clarity. + + commit 4a2546a1857f7b55eab395589893bdd0999956b2 + Author: Jens Maurer + Date: Wed Apr 21 23:23:30 2021 +0200 + + [expr.await] Clarify rethrowing exceptions from await-suspend + + commit 72855b062397efdbd30ec5d8c88317d19e27776b + Author: Jens Maurer + Date: Fri Apr 2 12:23:30 2021 +0200 + + [dcl.init.aggr] An initializer list is brace-enclosed + + Do not claim that a designated-initializer-list or + an initializer-list is an initializer list. + + commit 93d7a96979ff071b76dc211fd4625654b94e8a67 + Author: Jens Maurer + Date: Thu Jan 14 12:20:20 2021 +0100 + + [basic.lookup.unqual] Add examples for conversion-function-ids + + commit 890b339661891896ee60d28f19be79ecda4d6296 + Author: Jens Maurer + Date: Sat Mar 27 13:16:52 2021 +0100 + + [namespace.def.general] Clarify inline namespaces + + Highlight 'innermost enclosing' namespace. + + commit d6d36b48e5c5b8a63e4b93c2f75aa4f9f1e4862b + Author: timsong-cpp + Date: Sat May 29 19:26:10 2021 -0500 + + [range.elements.overview] Correct example + + commit b0a253cc6ba0e7f556f5afefab94f7cc1d1e5ced + Author: Thomas Köppe + Date: Tue Jun 1 12:56:45 2021 +0100 + + [expr.const.cast] Fix punctuation placement. + + commit caf7428fd6c807f30538042cf9bf1b27b8772b01 + Author: Jens Maurer + Date: Thu Jun 3 09:53:27 2021 +0200 + + [ranges] Rename 'not-same-as' to 'different-from'. + + 'not-same-as' is not quite equivalent to 'not same_as'. + + commit fb3bea889899c5ea5c0f70b12fc72129f7d1692a + Author: Jens Maurer + Date: Tue Jun 1 22:39:52 2021 +0200 + + [expr] Add cross-references for 'local entity'. + + A local entity is not any entity that is local, so add + cross-references for clarification. + + commit 77d389ffccb7c7ba294834d3196a5bccf25d28e0 + Author: timsong-cpp + Date: Mon Jun 7 12:53:22 2021 -0500 + + [ranges] Use views::meow in examples instead of meow_view + + commit e03d76cb5067598a92105ad7c4841a3d18e5b5d0 + Author: Jens Maurer + Date: Fri Jun 11 22:42:33 2021 +0200 + + [fs.path.native.obs] Remove bogus note. + + commit 20b924987e59d087af7b28df33490d34466f688c + Author: Jonathan Wakely + Date: Fri Jun 4 12:32:04 2021 +0100 + + [range.prim.data] Use ranges::begin(t) not ranges::begin(E) + + This is consistent with the typo fixes for ranges::size done in + aa9c660a835540117123617a13b0ba1ab6dd801e as part of #3752. + + commit e9e2acb4cdff00236aa750c717e1951c655797df + Author: Jens Maurer + Date: Thu Jun 17 22:40:23 2021 +0200 + + [format.syn] Remove extraneous commas in vformat_to declarations (#4705) + + commit d3fbad184abd1c327dd2dd097cd3caa17ada48af + Author: Jens Maurer + Date: Fri Apr 2 21:55:37 2021 +0200 + + [basic.stc.static] Rephrase the definition of 'static storage duration' + + This clarifies and centralizes the definition and + also avoids the undefined term 'local variable'. + + commit b6e0848db7a72560a7bfc84f16bd23abf6aab2d6 + Author: Jens Maurer + Date: Fri Jun 4 00:15:46 2021 +0200 + + [class.pre] Fix incorrect comment in example + + commit 1e889e06856a17f48e32a03a4272502dd67e1035 + Author: Jens Maurer + Date: Fri Jun 18 19:07:50 2021 +0200 + + [temp.variadic] Rearrange description of pack expansion (#4543) + + commit 94340ede298a23927523ee28c1c04090416eb20d + Author: Jonathan Wakely + Date: Fri Jun 18 15:00:48 2021 +0100 + + [basic.string.general], [string.view.template.general] remove constexpr + + There is no reason to declare a deleted function constexpr. + + commit 472e865817e17620ae4c88fef10e2983884b9f77 + Author: Thomas Köppe + Date: Fri Jun 18 22:26:14 2021 +0100 + + [range.utility.helper] Add missing '=' + + commit 421a2e258e2848016df92939f5a1cfa865c7f795 + Author: Thomas Köppe + Date: Fri Jun 18 23:06:52 2021 +0100 + + [range.join.iterator] Add missing \tcode diff --git a/papers/n4902.html b/papers/n4902.html new file mode 100644 index 0000000000..cbd94aa9d8 --- /dev/null +++ b/papers/n4902.html @@ -0,0 +1,1065 @@ + + + + + + N4902 + + +

N4902 Editors’ Report – Programming Languages – C++

+ +

Date: 2021-10-22

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

Thanks to all those who have submitted editorial +issues +and to those who have provided pull requests with fixes, and special thanks to +Johel Ernesto Guerrero Peña for providing in-depth review of most of the draft +motion applications.

+ +

New papers

+ +
    +
  • N4901 is the +current working draft for C++23. It replaces +N4892.
  • +
  • N4902 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group polls

+ +

CWG poll 1: Accept as Defect Reports all issues except issue 1726 in +P2462R0 +(Core Language Working Group "ready" Issues for the October, 2021 meeting) and +apply the proposed resolutions to the C++ working paper.

+ +

CWG poll 2: Apply the changes in +P2242R3 +(Non-literal variables (and labels and gotos) in constexpr functions) to the C++ +working paper.

+ +

CWG poll 3: Apply the changes in +P0847R7 +(Deducing this) to the C++ working paper.

+ +

CWG poll 4: Apply the changes in +P2316R2 +(Consistent character literal encoding) to the C++ working paper.

+ +

CWG poll 5: Apply the changes in +P2334R1 +(Add support for preprocessing directives elifdef and elifndef) to the C++ +working paper.

+ +

CWG poll 6: Apply the changes in +P2246R1 +(Character encoding of diagnostic text) to the C++ working paper.

+ +

CWG poll 7: Apply the changes in +P2360R0 +(Extend init-statement to allow alias-declaration) to the C++ working paper.

+ +

CWG poll 8: Accept +P2036R3 +(Change scope of lambda trailing-return-type) as a Defect Report and apply the +changes therein to the C++ working paper.

+ +

CWG poll 9: Apply the changes in +P2128R6 +(Multidimensional subscript operator) to the C++ working paper.

+ +

CWG poll 10: Apply the changes in +P2314R4 +(Character sets and encodings) to the C++ working paper.

+ +

CWG poll 11 does not affect the Working Draft.

+ +

Library working group polls

+ +

Poll 1 contains resolutions of library issues. Polls 2–5 are intended as +defect reports against C++20. Polls 6–19 apply purely to the Working +Draft.

+ +

LWG poll 1: Apply the changes for all Tentatively Ready issues in +P2450R0 +(C++ Standard Library Issues to be moved in Virtual Plenary, Oct. 2021) to the +C++ working paper.

+ +

LWG poll 2: Apply the changes in +P2372R3 +(Fixing locale handling in chrono formatters) to the C++ working paper, as a +Defect Report for C++20.

+ +

LWG poll 3: Apply the changes in +P2415R2 +(What is a view?) to the C++ working paper, as a Defect Report for C++20.

+ +

LWG poll 4: Apply the changes in +P2418R2 +(Add support for std::generator-like types to std::format) to the C++ +working paper, as a Defect Report for C++20.

+ +

LWG poll 5: Apply the changes in +P2432R1 +(fix istream_view) to the C++ working paper, as a Defect Report for C++20.

+ +

LWG poll 6: Apply the changes in +P0288R9 +(move_only_function) to the C++ working paper.

+ +

LWG poll 7: Apply the changes in +P0798R8 +(Monadic operations for std::optional) to the C++ working paper.

+ +

LWG poll 8: Apply the changes in +P0849R8 +(auto(x): decay-copy in the language) to the C++ working paper.

+ +

LWG poll 9: Apply the changes in +P1072R10 +(basic_string::resize_and_overwrite) to the C++ working paper.

+ +

LWG poll 10: Apply the changes in +P1147R1 +(Printing volatile Pointers) to the C++ working paper.

+ +

LWG poll 11: Apply the changes in +P1272R4 +(Byteswapping for fun&&nuf) to the C++ working paper.

+ +

LWG poll 12: Apply the changes in +P1675R2 +(rethrow_exception must be allowed to copy) to the C++ working paper.

+ +

LWG poll 13: Apply the changes in +P2077R3 +(Heterogeneous erasure overloads for associative containers) to the C++ working +paper.

+ +

LWG poll 14: Apply the changes in +P2251R1 +(Require span & basic_string_view to be Trivially Copyable) to the C++ +working paper.

+ +

LWG poll 15: Apply the changes in +P2301R1 +(Add a pmr alias for std::stacktrace) to the C++ working paper.

+ +

LWG poll 16: Apply the changes in +P2321R2 +(zip) to the C++ working paper.

+ +

LWG poll 17: Apply the changes in +P2340R1 +(Clarifying the status of the “C headers”) to the C++ working paper.

+ +

LWG poll 18: Apply the changes in +P2393R1 +(Cleaning up integer-class types) to the C++ working paper.

+ +

LWG poll 19: Apply the changes in +P2401R0 +(Add a conditional noexcept specification to std::exchange) to the C++ working +paper.

+ +

Editorial fixes

+ +

Changes to motions

+ +
    +
  • Poll CWG-8: The wording was adjusted in a minor way to integrate with the +new wording from CWG Poll 3, +P0847R7.

  • +
  • Poll CWG-9: The original text to be edited by this motion had been changed +by CWG Poll 3, +P0847R7, +but the new wording from this motion was retained in its entirety.

  • +
  • Poll CWG-10: The original text had already been modified by CWG Poll 4, +P2316R2, +and by the earlier paper +P2201R1; +the new changes were integrated.

  • +
  • Poll LWG-2: A redundant Returns: element was removed that was subsumed +by a new Effects: element. The sentence structure around a list was improved +by a later change.

  • +
  • Poll LWG-3: A note was moved out from mid-sentence within list to the end +of the list.

  • +
  • Poll LWG-6: Several minor corrections and editorial changes were applied +to improve clarity.

  • +
  • Poll LWG-8: The specification was subsequently simplified by reusing the +term “placeholder type deduction”

  • +
  • Poll LWG-16: Several minor corrections and editorial changes were applied +to improve clarity. In two cases, the original decay-copy was replaced +with auto.

  • +
  • Poll LWG-17: An additional claim in Annex C ([diff.mods.to.headers]) that +the C headers were deprecated has been deleted.

  • +
+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4885 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 e125ca7c66725801da118fa936e1444b22f8fb23
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Tue Apr 6 19:33:07 2021 +0300
+
+    [basic.types.general] Do not mention pointers
+
+commit c2b7ea1b8bf9a8ca9f332b4e4055928772425daa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun May 30 20:31:16 2021 +0200
+
+    [expr.rel] Clarify function pointer comparisons
+
+commit 6091e264374349c12aa775cd66e5f062d9c7b9e4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jun 21 16:36:10 2021 +0100
+
+    [unord.req.general] Replace inappropriate "shall be" with "is".
+
+commit a7ff942fc3d57d35a276ca4aab70f62368466d80
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jun 21 16:38:43 2021 +0100
+
+    [util.smartptr.shared.const] Replace inappropriate "shall"s.
+
+commit 7d7ddcd4b6cfdc68de25ae360103edfc457081c7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 19 09:29:20 2021 +0200
+
+    [temp.variadic] Clarify template parameter packs not introduced by pack expansions.
+
+commit 0ab7d5603fcaa7f0783e26428d69c1e677612511
+Author: cor3ntin <corentinjabot@gmail.com>
+Date:   Tue Jun 22 12:03:26 2021 +0200
+
+    [range.split.overview] Improve string splitting example
+
+    With the adoption of P1989R2, `string_view` is constructible from
+    `subrange`. We can use that to simplify the example of string splitting.
+
+    From  pull request #4714.
+
+commit 031526001191d3f5c20dd9b8b14584d98e6ad692
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Feb 5 22:33:34 2021 +0100
+
+    [basic.start.dynamic] Clarify note about templated variables
+
+commit 09744a2c2abe5095a44840f5c9d27fde3650625c
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Mon Oct 19 13:47:13 2020 +0200
+
+    [input.output.general] Delete note containing [fig:iostreams.streampos].
+
+    Also add a note to [iostreams.limits.pos] to replace the removed figure.
+
+    Fixes #4246.
+
+commit bec4ff5d87b4d258e4d40aae11197ea223689bb0
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Oct 19 14:55:09 2020 +0100
+
+    [stream.types] Move subclause near the start of [iostreams]
+
+    Correct footnote about how uses of streamsize relate to C.
+
+commit b1bb8281bfd32593acb9f355930f18fd19875854
+Author: burblebee <dawn@brightsidecomputing.com>
+Date:   Tue Jun 22 07:21:22 2021 -0700
+
+    [dcl.fct] Clarify in example which declarations refer to which (#4287)
+
+    Co-authored-by: Dawn Perchik <dperchik@embarcadero.com>
+
+commit dd99020d1cb8276df29994da35cf45c174c28bb7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 5 22:46:22 2020 +0100
+
+    [dcl.type.auto.deduct] Clarify initializer for placeholder type deduction.
+
+commit 54743884b5a3a486aa3cf16bdf04481f2c3dcfed
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jun 22 22:07:01 2021 +0100
+
+    [iterator.operations, range.iter.op.distance] Reword "get to".
+
+    It was previously not explicitly stated that input iterators would
+    actually be incremented (which invalidates copies). The new wording is
+    more explicit about how the distance is measured, and in doing so
+    calls out more explicitly that input iterators are indeed incremented.
+
+commit 753c8339e5bb43010d49f57f7020fdc59d899c93
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jun 24 17:57:48 2021 +0100
+
+    [format] Use \exposid{,nc} for format-arg-store, not \placeholder
+
+commit 85525b1bd58421e4507705f96ee67f217aee4e9e
+Author: Krystian Stasiowski <sdkrystian@gmail.com>
+Date:   Mon Mar 16 19:16:30 2020 -0400
+
+    [dcl.dcl] Improve note regarding nodeclspec-function-declarations
+
+commit 5fdd7f71e4ba24778943889f658e3ed0620c08b9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Jun 19 11:04:30 2021 +0100
+
+    [basic.stc.dynamic.general, class, namespace.udecl] Fix ranged index entries
+
+commit 628ded4b8e6cd4b7297f9e04a394f200423ab2d7
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sat Jun 26 21:11:29 2021 +0800
+
+    [range.split.iterator] Add missing braces in 'Effects' clause (#4721)
+
+commit 44c522011a71e66ca9dc86e1c7e5e33ca7e430f5
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri Jul 2 15:48:35 2021 -0400
+
+    [allocator.uses.construction] Add missing closing parentheses (#4729)
+
+    The parentheses were erroneously omitted from
+    9ffd955ed17b8482c0b491d3590f3d3986650e7c during the application of LWG3527.
+
+commit 45578ff558206090ebcc06e8b7d2f028add1efb6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jul 5 15:26:50 2021 +0200
+
+    [time.clock.cast.{sys,utc}] Shorten introdution of `Duration2` (#4734)
+
+commit 52d9b8e0318d3bbf7efaea422f47a3ccb5c07381
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri Jul 9 16:25:52 2021 -0400
+
+    [func.require, func.wrap.func.inv] Use defined term "target object" (#4739)
+
+commit 4bb0543c314c7b302b185245e18e6e0e577b1d72
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 7 23:23:44 2021 +0200
+
+    [thread] Fix and add cross-references in header synopses
+
+commit 1744e9eb44122b1b2772a162ecfb77a9f5406875
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jul 18 21:51:00 2021 +0200
+
+    [bit.count] Add missing paragraph number
+
+commit dff9c52d9b8ecb3029edf43b102e74429c321979
+Author: hewill <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Jul 21 18:34:53 2021 +0800
+
+    [variant.variant.general] Fix typo in "constexpr" (#4765)
+
+commit d6f4d5e9b9186a1bde38dae86013e6cd980f83c0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 21 12:37:50 2021 +0200
+
+    [expr.delete] Replace 'denote' with 'pointed to'. (#4762)
+
+    This change also introduces a name for the pointed-to object,
+    which removes the erstwhile ambiguous antecedent for 'its'.
+
+commit 560c5c80de9090ebefa5c98dfbe6079da359a810
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jul 18 21:42:49 2021 +0200
+
+    [expr.static.cast] Admit integral promotion for cast to enumeration type
+
+commit d8a89d19b9faeed94c5f6b34788621c3ae10abaf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jul 9 22:12:36 2021 +0200
+
+    [basic.compound] Use quoted-string designation for pointer types
+
+commit 5d544aeb48fdbdc9529b9eb7c77f13c10fa4bc6b
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Wed Jul 21 05:47:53 2021 -0500
+
+    [range.nonprop.cache] Clarify emplace-deref for prvalues. (#4732)
+
+    A new note explains that `emplace-deref` requires implementations to
+    avoid materialization of the result of `*i` before the initialization.
+    This is implied by the normatively expressed requirement in terms of
+    an invented initialization of a variable, but is easily overlooked.
+
+commit f4e83097149490c7ff999588ca2cf36d01cbb791
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jun 24 20:01:16 2021 +0100
+
+    [ostream.formatted.reqmts],[ostream.unformatted] "that object" not "this object"
+
+    Avoid saying "this object" when not talking about `*this`.
+
+commit 6847238dcfa2079bc0c70348a5fd34c07f28fe5c
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jun 25 09:58:33 2021 +0100
+
+    [input.streams.general],[output.streams.general] describe contents more accurately
+
+    Class templates are not types. Function templates are not function signatures.
+
+commit 711aa64c2625570b865ce5f88edde0b1e5863a1e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jul 3 00:02:53 2021 +0200
+
+    [std] Harmonize 'reference binds to an expression' phrasing
+
+commit 5465744691ae7d3fad1b9bd3d0e3c1abb90c9c63
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Jul 21 12:13:55 2021 +0100
+
+    [meta.member] Clarify is_corresponding_member semantics
+
+    The definition of 'common initial sequence' in [class.mem] only applies
+    to standard-layout struct types, which excludes unions. There is no
+    reason to define is_corresponding_member in terms of standard-layout
+    types (which includes unions and scalars and arrays of such types) when
+    the common initial sequence is only meaningful for standard-layout
+    structs.
+
+commit 27c1be4dc652449215246c807464605c095eb12e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 14 22:45:03 2020 +0100
+
+    [std] Use grammar typedef-name instead of 'typedef name'.
+
+    The former includes names introduced by alias-declarations,
+    the latter (arguably) does not.
+
+commit a6267a3e89ed19e0d0839a4a98aa44de3eed1536
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 14 23:03:11 2020 +0100
+
+    [dcl.typedef] Properly define 'typedef name for linkage purposes'.
+
+commit 3fb7f67287ff01b7b74f0767fdd0f9d7bd1209df
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Jul 22 18:06:57 2021 -0700
+
+    [span.streams.overview] Fix typo in "these" (#4769)
+
+commit 2a23be97d65776c1a1b4da454bc19ddc5420122c
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Jul 27 15:27:49 2021 -0400
+
+    [allocator.requirements.general] Fix typo in table's note (#4782)
+
+commit 7ce2694926c5a835169635fc916297af803ed4ad
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 27 21:24:51 2021 +0200
+
+    [basic.types.general] Fix comment in example
+
+commit 2a587c1570ab19bed81f9095f54eeec0d319f4ce
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Jul 27 11:28:05 2021 -0400
+
+    [tuple.creation] Remove unused introductory notation
+
+commit 7df2b916044b3b47cd708ed1488f1d2fd5f70886
+Author: stbergmann <sbergman@redhat.com>
+Date:   Tue Aug 3 17:27:34 2021 +0200
+
+    [std] Use $...$ around negative numbers, for proper minus signs (#4790)
+
+commit a4e40b0ada8a15b601566af3f96bf89314e7ef60
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Aug 12 07:50:22 2021 -0700
+
+    [spanbuf.virtuals] Add missing "override" (#4795)
+
+    ... to the declaration of `setbuf` to agree with the class synopsis.
+
+commit b02a8de26b2a19a153516a350b79c55ded8ce5f2
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Aug 17 17:23:32 2021 -0400
+
+    [range.iota.view] Mark exposition-only concepts as such (#4818)
+
+commit ffb5fd38560371bf38757cc8ba75130e7f17398d
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Wed Aug 18 09:41:42 2021 -0400
+
+    [range.dangling] Use "auto" parameter type (#4817)
+
+commit 2f24840565c363d554f99bf74e6e4255a07891c8
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Wed Aug 18 16:27:55 2021 -0400
+
+    [coroutine.traits.primary] Separate parameters by spaces
+
+commit 39399f5f6f2e48d50101769180dea3219679ef60
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 19 22:19:43 2021 +0200
+
+    [cmath.syn] Add 'lerp' to list of differences vs. C (#4806)
+
+commit deec10b978bb05e12b1ad5f586f3e8b21e590306
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Thu Aug 19 21:13:31 2021 -0500
+
+    [iostream.format] Use the injected-class-name throughout
+
+    Also remove ill-formed default template arguments in the definition
+    of sentry and spell out the return type of arithmetic inserters and
+    extractors.
+
+commit f66f72a92c5c9ce108f8b7ceadcafc4c70adae83
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Aug 27 15:50:57 2021 +0100
+
+    [range.istream.view] Repeat default template argument in synopsis (#4836)
+
+commit 2aab403e7e14d3d166006c2e96160a430de5d4e7
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Aug 31 06:30:38 2021 -0400
+
+    [temp.spec.general] Format grammar terms (#4849)
+
+commit d299b77828e86d1ac26ac2ccc081e01b5a22ce4b
+Author: plazum <34277374+plazum@users.noreply.github.com>
+Date:   Thu Sep 2 13:58:34 2021 +0800
+
+    [forward] Fix typo in example 2 in paragraph 6 (#4858)
+
+    Duplicate declaration of sp1. Change it to sp2 just as that in example 1 above.
+
+commit b5582e513b0c79c439a6d25ec3702a63488f35ba
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Sep 6 07:49:51 2021 -0400
+
+    [basic] Reference more specific subclause [expr.context] (#4866)
+
+commit 462b7d4cd325dec7fa6e44bda2a8da0954affa20
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Wed Sep 8 18:54:28 2021 +0300
+
+    [expr.const] Fix reference to integer overflow (#4880)
+
+commit d13ed92b0afe1ca7da4e3783cb4964e43533d3c4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Aug 14 12:32:28 2021 +0200
+
+    [basic.lookup.unqual] Clarify 'unqualified name'
+
+commit 01818364b75784bf19f2618b4f27afbde72caad2
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Thu Sep 9 11:31:03 2021 -0400
+
+    [expr.typeid] Fix reference to header synopsis (#4883)
+
+commit 598d39c6a8da4c657b20cc8b2c002a8b8f286cb8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 3 15:27:55 2021 +0200
+
+    [basic.string.general] Adjust declaration of basic_string::npos
+
+    Use constexpr and an explicit conversion to size_type,
+    for consistency with basic_string_view.
+
+commit 28aa519b3834a9be0f2c93bc3ab1c60e9305fedf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Sep 4 12:23:35 2021 +0200
+
+    [expr.ass] Clarify type of assignment-expression
+
+    An expression has a type and a value category.
+    This particular compound-expression was missing the
+    specification of its (result) type.
+
+commit d6fa2a9a7e52b78b8881a387b64dc1b880bc6ea6
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Sep 13 10:21:47 2021 -0400
+
+    [intro.abstract] Fix reference to point to .general subclause (#4892)
+
+commit 9c018aa764fc1c6f856ffce1e61e80c889a44c6a
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Sep 13 10:22:19 2021 -0400
+
+    [basic.life] Use Oxford comma (#4896)
+
+commit e2e875c3eb1384a70e817f36ca615f8b877f172b
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Sep 13 10:22:59 2021 -0400
+
+    [basic] Reference [basic.types.general] where appropriate (#4895)
+
+commit e29850e886e5626ca09910224c60c3dd340a8937
+Author: Richard Smith <richard-github@metafoo.co.uk>
+Date:   Wed Sep 15 12:24:58 2021 -0700
+
+    [dcl.spec.auto.general] The placeholder type -> A placeholder type (#4909)
+
+    "The placeholder type" gives the wrong impression that we're talking
+    about the case from the previous paragraph. We're not; this is parallel
+    to the previous paragraph so should use parallel wording.
+
+commit dc5a7d695b35870650b363b65ef5ae7498abda10
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Sep 16 20:27:04 2021 +0100
+
+    [dcl.init.general] break p7 into two paragraphs (#4912)
+
+commit 5fdfe684b3aa0ab3579160be5cd1ff723879a0aa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 17 16:31:21 2021 +0200
+
+    [conv.rank] Avoid hinting that 'bool' be a standard integer type. (#4209)
+
+commit ed65b084e8b82af888d43a6dcad9661ddce21820
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 17 16:32:48 2021 +0200
+
+    [stmt.return,dcl.fct.def.coroutine] Avoid use of 'glvalue result' (#4803)
+
+commit b6037fce86b3a64c56ba82ed687802b745083436
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 17 16:34:34 2021 +0200
+
+    [expr.typeid] Require class type to be complete in all cases (#4827)
+
+commit 6e20d2fdbaaad47ec1f89e2ed0b2e823668acfbc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Sep 18 07:44:53 2021 +0200
+
+    [facet.num.get.virtuals] Fix singular/plural mismatch
+
+commit 584923b8c4a19cb026f51db3ebf4006c387b1e41
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri Sep 24 06:53:48 2021 -0700
+
+    [fstream.syn] Fix grammar
+
+    "are only be provided" is not a valid english verb phrase. I'm not sure if
+    the intent was "are only provided" or "are only to be provided", but I think
+    the first more closely adheres to our style of making existential statements
+    about library implementations.
+
+commit 53b8382f25edcad2adc81c17db8f5a45753f6f8c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 24 00:10:24 2021 +0200
+
+    [dcl.init.aggr] Insert paragraph break to avoid bad \item numbering
+
+commit 75fe60fd58d8cfbb5eb5bd9622004f84e60a0cd9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 24 00:03:43 2021 +0200
+
+    [optional] Replace bool(x) with x.has_value()
+
+commit 97e949e6067255152859dbd1b5825d3b42c6bfbf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Sep 2 15:02:42 2021 +0200
+
+    [expr.delete] Clarify constraints on non-array delete
+
+commit a029b12c7baeaeb671a7ace6f231dfe81dce2236
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Aug 30 22:21:05 2021 +0200
+
+    [expr.delete] Clarify treatment of arrays of classes
+
+commit 296f0ed962958db3f9f61ec1bd23092e7c53fa6e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 24 22:13:40 2021 +0200
+
+    [class.copy.elision] Fix comment in example (#4928)
+
+commit d9bd2a6244375c6189060b511c00867563967436
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Sep 18 08:04:14 2021 +0200
+
+    [class.base.init] Clarify implicitly-defined copy/move constructors
+
+    Those do not have a (grammatical) mem-initializer-list,
+    yet they ignore default member initializers.
+
+commit 1e1cb1269679635ef219bb0c0603a1a0d65d754e
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Thu Sep 9 21:55:20 2021 -0400
+
+    [expr.dynamic.cast] Remove apparent condition
+
+    The preceding paragraph already introduces the
+    "otherwise" branch for the runtime check whose
+    algorithm is explain in this paragraph.
+
+commit 80d937ebc6b00f77046c72236256d5a60781d215
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jul 19 23:51:39 2021 +0200
+
+    [stmt.dcl] Clarify 'active' variables
+
+    They necessarily have automatic storage duration.
+
+commit a054daf2cd58f1868737c5761f2fe9fdb3627f03
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Aug 12 17:03:29 2021 +0200
+
+    [dcl.init.ref] Avoid 'value of the expression'
+
+    when the properties of the expression are still relevant.
+    Also avoid "result of the conversion".
+
+commit 166af4d9e8587268564e78e1412e269ccd7170fc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jul 17 22:48:37 2021 +0200
+
+    [expr.new] Clarify result type and value category
+
+    Also move the relevant text to after the syntactic constraints.
+
+commit 7a2e73da0357be63d760fb44311653c55fbac57b
+Author: Barry Revzin <barry.revzin@gmail.com>
+Date:   Sat Sep 25 14:51:52 2021 -0500
+
+    [swappable.requirements] Change "Requires" to "Preconditions" (#4886)
+
+commit 8114ccdb0ef3b0e308c54aa9a3757e9d6c09528b
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Sep 25 16:14:47 2021 -0400
+
+    [func.search] Fix inconsistencies between boyer_moore searchers (#4873)
+
+commit 3a97ba6e50e4acc2bb42b09c57f986b0eadd38e1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Sep 27 11:31:09 2021 +0200
+
+    [lib] Rename exposition-only 'no-throw-' concepts to 'nothrow-' (#4942)
+
+    for consistency with nothrow_constructible.
+
+commit 668c82a2eed560c27c1205b0fe03b818bf11487c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Sep 27 21:52:58 2021 +0200
+
+    [range.dangling] Use ranges::subrange in example (#4946)
+
+commit 17dc5f664da476831c5d6138e9f0cc15ddb6e0bc
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Sep 29 16:37:20 2021 +0100
+
+    [customization.point.object] fix grammar (#4950)
+
+commit b6f5885aa049d9064dab53092cd68425d100fa82
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Sep 30 08:52:38 2021 +0200
+
+    [tuple.apply] Move exposition-only functions to namespace std (#4951)
+
+    and remove superfluous std:: qualification.
+
+commit d82328101bcc70d7cc75929cc185b8f2206561f8
+Author: Erich Keane <erich.keane@intel.com>
+Date:   Sun Oct 3 06:29:18 2021 -0700
+
+    [expr.prim.id.general] Add missing semicolon in example (#4956)
+
+commit 2360a5960c6edd072e1370bb81f2797f3e80f16c
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sun Oct 3 09:42:57 2021 -0400
+
+    [stmt.pre] Remove stray cross-reference (#4959)
+
+commit 35577f575883adc8c5b80dee22b6c131240bdec1
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Oct 19 17:16:31 2021 -0400
+
+    [range.lazy.split.outer.value] Fix indexed outer class name
+
+commit 91ab4b4f5ebea4c84304faa4efd9bd86095c0ac0
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Wed Oct 20 17:40:16 2021 -0400
+
+    [lex.{phases,charset,string}] Fix minor misapplications of P2314R4 (#5040)
+
+    Corrects a grammar term plural form, adds missing "R" for raw string literal,
+    and deletes a paragraph that was missed in the main commit
+    (3505e2ab3fcdf562b3fa3cb76dc417ecaef09648) and adjust index entries.
+
+commit 7d886537b0e2a66aa9778efedf160d43d2a27205
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Wed Oct 20 16:42:52 2021 -0500
+
+    [range.join.view] Remove duplicative condition (#4957)
+
+    This function is constrained on `is_reference_v<range_reference_t<const V>>` already,
+    so checking it again in the `if constexpr` has no effect.
+
+commit ef2bbe887b4caf15ffdfc4d7ba4a1cca0650b5ac
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 3 15:39:35 2021 +0200
+
+    [support.types.layout] Avoid implementation guidance in a note
+
+    Turn it into a "recommended practice" section.
+
+commit c2439d348fba54eed22e0a9803f3bca512803b0e
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Sep 25 19:07:09 2021 -0400
+
+    [headers] Fix note about importing library headers
+
+    Importable library headers are not module units,
+    because they do not have a module-declaration.
+
+commit e49d044c278a0911a98e9f6d912a3e196b5ebb2f
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Thu Oct 21 02:32:58 2021 +0300
+
+    [expr.delete] Remove "result" from expression (#4740)
+
+commit b2264247505861345c6d297d673209b06c67737f
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Wed Oct 20 19:14:12 2021 -0500
+
+    [move.iterator] Use the template parameter directly in declaration of base()
+
+commit 21d7303990d31e8d38738d82d5a4b94fd5801b9e
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Thu Oct 21 05:27:51 2021 -0500
+
+    [utilities, range.nonprop.cache] Simplify direct-non-list-initalization phrasing (#5042)
+
+    Fixes #5038.
+
+commit cb39ab5883d9c1e74a2841bcdf06b6523ca6228d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 15 12:47:35 2021 +0200
+
+    [dcl.type.auto.deduct, expr.type.conv] Rearrange description of 'auto' deduction
+
+    This change moves the fact that 'the type shall be auto' from
+    [expr.type.conv] to [dcl.type.auto.deduct], and thus avoids repeating
+    the mechanism of placeholder deduction.
+
+commit 4bffacc223a5b294be3a2bedc13cfa650fbfd653
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 21 12:51:56 2021 +0200
+
+    [std] Fix cross-references to 'unevaluated operand' (#4941)
+
+    This change adds a new label to the desired paragraph, updates existing references
+    to refer to the new label, and adds new references to occurrences of "unevaluated
+    operand" that previously did not have one.
+
+commit 49eab1d6898e4c39b4e26b9943ab6af99da486e5
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Oct 19 11:08:35 2021 +0100
+
+    [diff.cpp20.utilities] Improve clarity of long sentence.
+
+    Repeating the "that" pronoun makes it easier to tell where each part
+    of the sentence belongs.
+
+commit e72874655094916c118488e867d117c65fb9e754
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Oct 21 12:53:41 2021 +0100
+
+    [container.requirements] Improve punctuation of list items.
+
+    It is still odd to have semicolons in the middle of the first list,
+    but at least this change makes the overall punctuation somewhat more correct.
+
+commit ed7cb023d0e172987b6d55f639380cf848f1db50
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 21 15:09:22 2021 +0200
+
+    [basic.def.odr] Introduce label 'term.odr.use' and refer to it
+
+    instead of referring to 'basic.def.odr'.  The latter breaks if we
+    ever move the definition of 'odr-use', e.g. to a subclause.
+
+commit 23b36a4af0f95038aca34a471b845a5760a13ec5
+Author: Géry Ogam <gery.ogam@gmail.com>
+Date:   Thu Oct 21 18:58:42 2021 +0200
+
+    [basic.life] Remove a partial repetition of the end-of-lifetime rules (#4894)
+
+commit f009b5d7e1eeef39d64b999abfb772ef3ecf15c9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 21 21:41:48 2021 +0200
+
+    [vector.cons] Use math formatting for 'N' for consistency
+
+commit 1acfef5c47862676c5d1401399dd3112f73a161d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 21 21:32:19 2021 +0200
+
+    [string.io] Rephrase sentry conversion
+
+commit d2ce09da710b47d7135757a9bff26bfa4e557fef
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 21 22:32:34 2021 +0200
+
+    [system.error.syn,locale.facet] Replace 'automatic' by 'implicit' conversion
+
+commit b25fb2ea70ff6fb564a247dfc95438e7e90608e4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 22 00:18:21 2021 +0200
+
+    [lex.ccon] Clarify antecedent for 'it'
+
+commit a45f88084ff4ae301bbded86107ab540082387f1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 22 00:14:55 2021 +0200
+
+    [time.format] Avoid non-sentence in bulleted list
+
+commit 12c32b999f85c5b7e3f8f14d7c287d47492533d2
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Oct 22 11:08:35 2021 +0100
+
+    [expr.await] Remove hyphen from "re-thrown" (#5062)
+
+commit 65ec10addf80f6682395904ede48d7a1b5e732ec
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Oct 22 18:08:06 2021 +0100
+
+    [range.view] Move note outside of list.
+
diff --git a/papers/n4902.md b/papers/n4902.md new file mode 100644 index 0000000000..6bba837136 --- /dev/null +++ b/papers/n4902.md @@ -0,0 +1,932 @@ +# N4902 Editors' Report -- Programming Languages -- C++ + +Date: 2021-10-22 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes, and special thanks to +Johel Ernesto Guerrero Peña for providing in-depth review of most of the draft +motion applications. + +## New papers + + * [N4901](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4901.pdf) is the + current working draft for C++23. It replaces + [N4892](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4892.pdf). + * N4902 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group polls + +CWG poll 1: Accept as Defect Reports all issues _except issue 1726_ in +[P2462R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2462r0.html) +(Core Language Working Group "ready" Issues for the October, 2021 meeting) and +apply the proposed resolutions to the C++ working paper. + +CWG poll 2: Apply the changes in +[P2242R3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2242r3.html) +(Non-literal variables (and labels and gotos) in constexpr functions) to the C++ +working paper. + +CWG poll 3: Apply the changes in +[P0847R7](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html) +(Deducing `this`) to the C++ working paper. + +CWG poll 4: Apply the changes in +[P2316R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2316r2.pdf) +(Consistent character literal encoding) to the C++ working paper. + +CWG poll 5: Apply the changes in +[P2334R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2334r1.pdf) +(Add support for preprocessing directives `elifdef` and `elifndef`) to the C++ +working paper. + +CWG poll 6: Apply the changes in +[P2246R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2246r1.pdf) +(Character encoding of diagnostic text) to the C++ working paper. + +CWG poll 7: Apply the changes in +[P2360R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2360r0.html) +(Extend init-statement to allow alias-declaration) to the C++ working paper. + +CWG poll 8: Accept +[P2036R3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2036r3.html) +(Change scope of lambda trailing-return-type) as a Defect Report and apply the +changes therein to the C++ working paper. + +CWG poll 9: Apply the changes in +[P2128R6](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2128r6.pdf) +(Multidimensional subscript operator) to the C++ working paper. + +CWG poll 10: Apply the changes in +[P2314R4](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2314r4.html) +(Character sets and encodings) to the C++ working paper. + +CWG poll 11 does not affect the Working Draft. + +### Library working group polls + +Poll 1 contains resolutions of library issues. Polls 2–5 are intended as +defect reports against C++20. Polls 6–19 apply purely to the Working +Draft. + +LWG poll 1: Apply the changes for all Tentatively Ready issues in +[P2450R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2450r0.html) +(C++ Standard Library Issues to be moved in Virtual Plenary, Oct. 2021) to the +C++ working paper. + +LWG poll 2: Apply the changes in +[P2372R3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2372r3.html) +(Fixing locale handling in chrono formatters) to the C++ working paper, as a +Defect Report for C++20. + +LWG poll 3: Apply the changes in +[P2415R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2415r2.html) +(What is a view?) to the C++ working paper, as a Defect Report for C++20. + +LWG poll 4: Apply the changes in +[P2418R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2418r2.html) +(Add support for `std::generator`-like types to `std::format`) to the C++ +working paper, as a Defect Report for C++20. + +LWG poll 5: Apply the changes in +[P2432R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2432r1.pdf) +(fix `istream_view`) to the C++ working paper, as a Defect Report for C++20. + +LWG poll 6: Apply the changes in +[P0288R9](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0288r9.html) +(`move_only_function`) to the C++ working paper. + +LWG poll 7: Apply the changes in +[P0798R8](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0798r8.html) +(Monadic operations for `std::optional`) to the C++ working paper. + +LWG poll 8: Apply the changes in +[P0849R8](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0849r8.html) +(`auto(x)`: decay-copy in the language) to the C++ working paper. + +LWG poll 9: Apply the changes in +[P1072R10](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1072r10.html) +(`basic_string::resize_and_overwrite`) to the C++ working paper. + +LWG poll 10: Apply the changes in +[P1147R1](https://wiki.edg.com/pub/Wg21virtual2021-10/StrawPolls/P1147R1.html) +(Printing volatile Pointers) to the C++ working paper. + +LWG poll 11: Apply the changes in +[P1272R4](https://wiki.edg.com/pub/Wg21virtual2021-10/StrawPolls/P1272R4.html) +(Byteswapping for fun&&nuf) to the C++ working paper. + +LWG poll 12: Apply the changes in +[P1675R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1675r2.pdf) +(`rethrow_exception` must be allowed to copy) to the C++ working paper. + +LWG poll 13: Apply the changes in +[P2077R3](https://wiki.edg.com/pub/Wg21virtual2021-10/StrawPolls/P2077R3.html) +(Heterogeneous erasure overloads for associative containers) to the C++ working +paper. + +LWG poll 14: Apply the changes in +[P2251R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2251r1.pdf) +(Require `span` & `basic_string_view` to be Trivially Copyable) to the C++ +working paper. + +LWG poll 15: Apply the changes in +[P2301R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2301r1.html) +(Add a pmr alias for `std::stacktrace`) to the C++ working paper. + +LWG poll 16: Apply the changes in +[P2321R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2321r2.html) +(`zip`) to the C++ working paper. + +LWG poll 17: Apply the changes in +[P2340R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2340r1.html) +(Clarifying the status of the “C headers”) to the C++ working paper. + +LWG poll 18: Apply the changes in +[P2393R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2393r1.html) +(Cleaning up integer-class types) to the C++ working paper. + +LWG poll 19: Apply the changes in +[P2401R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2401r0.html) +(Add a conditional noexcept specification to std::exchange) to the C++ working +paper. + +## Editorial fixes + +### Changes to motions + +* **Poll CWG-8:** The wording was adjusted in a minor way to integrate with the + new wording from CWG Poll 3, + [P0847R7](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html). + +* **Poll CWG-9:** The original text to be edited by this motion had been changed + by CWG Poll 3, + [P0847R7](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html), + but the new wording from this motion was retained in its entirety. + +* **Poll CWG-10:** The original text had already been modified by CWG Poll 4, + [P2316R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2316r2.pdf), + and by the earlier paper + [P2201R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2201r1.html); + the new changes were integrated. + +* **Poll LWG-2:** A redundant _Returns:_ element was removed that was subsumed + by a new _Effects:_ element. The sentence structure around a list was improved + by a later change. + +* **Poll LWG-3:** A note was moved out from mid-sentence within list to the end + of the list. + +* **Poll LWG-6:** Several minor corrections and editorial changes were applied + to improve clarity. + +* **Poll LWG-8:** The specification was subsequently simplified by reusing the + term “placeholder type deduction” + +* **Poll LWG-16:** Several minor corrections and editorial changes were applied + to improve clarity. In two cases, the original _`decay-copy`_ was replaced + with `auto`. + +* **Poll LWG-17:** An additional claim in Annex C ([diff.mods.to.headers]) that + the C headers were deprecated has been deleted. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4885 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/n4892...n4901). + + commit e125ca7c66725801da118fa936e1444b22f8fb23 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Tue Apr 6 19:33:07 2021 +0300 + + [basic.types.general] Do not mention pointers + + commit c2b7ea1b8bf9a8ca9f332b4e4055928772425daa + Author: Jens Maurer + Date: Sun May 30 20:31:16 2021 +0200 + + [expr.rel] Clarify function pointer comparisons + + commit 6091e264374349c12aa775cd66e5f062d9c7b9e4 + Author: Thomas Köppe + Date: Mon Jun 21 16:36:10 2021 +0100 + + [unord.req.general] Replace inappropriate "shall be" with "is". + + commit a7ff942fc3d57d35a276ca4aab70f62368466d80 + Author: Thomas Köppe + Date: Mon Jun 21 16:38:43 2021 +0100 + + [util.smartptr.shared.const] Replace inappropriate "shall"s. + + commit 7d7ddcd4b6cfdc68de25ae360103edfc457081c7 + Author: Jens Maurer + Date: Sat Jun 19 09:29:20 2021 +0200 + + [temp.variadic] Clarify template parameter packs not introduced by pack expansions. + + commit 0ab7d5603fcaa7f0783e26428d69c1e677612511 + Author: cor3ntin + Date: Tue Jun 22 12:03:26 2021 +0200 + + [range.split.overview] Improve string splitting example + + With the adoption of P1989R2, `string_view` is constructible from + `subrange`. We can use that to simplify the example of string splitting. + + From pull request #4714. + + commit 031526001191d3f5c20dd9b8b14584d98e6ad692 + Author: Jens Maurer + Date: Fri Feb 5 22:33:34 2021 +0100 + + [basic.start.dynamic] Clarify note about templated variables + + commit 09744a2c2abe5095a44840f5c9d27fde3650625c + Author: Eelis van der Weegen + Date: Mon Oct 19 13:47:13 2020 +0200 + + [input.output.general] Delete note containing [fig:iostreams.streampos]. + + Also add a note to [iostreams.limits.pos] to replace the removed figure. + + Fixes #4246. + + commit bec4ff5d87b4d258e4d40aae11197ea223689bb0 + Author: Jonathan Wakely + Date: Mon Oct 19 14:55:09 2020 +0100 + + [stream.types] Move subclause near the start of [iostreams] + + Correct footnote about how uses of streamsize relate to C. + + commit b1bb8281bfd32593acb9f355930f18fd19875854 + Author: burblebee + Date: Tue Jun 22 07:21:22 2021 -0700 + + [dcl.fct] Clarify in example which declarations refer to which (#4287) + + Co-authored-by: Dawn Perchik + + commit dd99020d1cb8276df29994da35cf45c174c28bb7 + Author: Jens Maurer + Date: Thu Nov 5 22:46:22 2020 +0100 + + [dcl.type.auto.deduct] Clarify initializer for placeholder type deduction. + + commit 54743884b5a3a486aa3cf16bdf04481f2c3dcfed + Author: Thomas Köppe + Date: Tue Jun 22 22:07:01 2021 +0100 + + [iterator.operations, range.iter.op.distance] Reword "get to". + + It was previously not explicitly stated that input iterators would + actually be incremented (which invalidates copies). The new wording is + more explicit about how the distance is measured, and in doing so + calls out more explicitly that input iterators are indeed incremented. + + commit 753c8339e5bb43010d49f57f7020fdc59d899c93 + Author: Thomas Köppe + Date: Thu Jun 24 17:57:48 2021 +0100 + + [format] Use \exposid{,nc} for format-arg-store, not \placeholder + + commit 85525b1bd58421e4507705f96ee67f217aee4e9e + Author: Krystian Stasiowski + Date: Mon Mar 16 19:16:30 2020 -0400 + + [dcl.dcl] Improve note regarding nodeclspec-function-declarations + + commit 5fdd7f71e4ba24778943889f658e3ed0620c08b9 + Author: Thomas Köppe + Date: Sat Jun 19 11:04:30 2021 +0100 + + [basic.stc.dynamic.general, class, namespace.udecl] Fix ranged index entries + + commit 628ded4b8e6cd4b7297f9e04a394f200423ab2d7 + Author: S. B. Tam + Date: Sat Jun 26 21:11:29 2021 +0800 + + [range.split.iterator] Add missing braces in 'Effects' clause (#4721) + + commit 44c522011a71e66ca9dc86e1c7e5e33ca7e430f5 + Author: Johel Ernesto Guerrero Peña + Date: Fri Jul 2 15:48:35 2021 -0400 + + [allocator.uses.construction] Add missing closing parentheses (#4729) + + The parentheses were erroneously omitted from + 9ffd955ed17b8482c0b491d3590f3d3986650e7c during the application of LWG3527. + + commit 45578ff558206090ebcc06e8b7d2f028add1efb6 + Author: Jens Maurer + Date: Mon Jul 5 15:26:50 2021 +0200 + + [time.clock.cast.{sys,utc}] Shorten introdution of `Duration2` (#4734) + + commit 52d9b8e0318d3bbf7efaea422f47a3ccb5c07381 + Author: Johel Ernesto Guerrero Peña + Date: Fri Jul 9 16:25:52 2021 -0400 + + [func.require, func.wrap.func.inv] Use defined term "target object" (#4739) + + commit 4bb0543c314c7b302b185245e18e6e0e577b1d72 + Author: Jens Maurer + Date: Wed Jul 7 23:23:44 2021 +0200 + + [thread] Fix and add cross-references in header synopses + + commit 1744e9eb44122b1b2772a162ecfb77a9f5406875 + Author: Jens Maurer + Date: Sun Jul 18 21:51:00 2021 +0200 + + [bit.count] Add missing paragraph number + + commit dff9c52d9b8ecb3029edf43b102e74429c321979 + Author: hewill <67143766+hewillk@users.noreply.github.com> + Date: Wed Jul 21 18:34:53 2021 +0800 + + [variant.variant.general] Fix typo in "constexpr" (#4765) + + commit d6f4d5e9b9186a1bde38dae86013e6cd980f83c0 + Author: Jens Maurer + Date: Wed Jul 21 12:37:50 2021 +0200 + + [expr.delete] Replace 'denote' with 'pointed to'. (#4762) + + This change also introduces a name for the pointed-to object, + which removes the erstwhile ambiguous antecedent for 'its'. + + commit 560c5c80de9090ebefa5c98dfbe6079da359a810 + Author: Jens Maurer + Date: Sun Jul 18 21:42:49 2021 +0200 + + [expr.static.cast] Admit integral promotion for cast to enumeration type + + commit d8a89d19b9faeed94c5f6b34788621c3ae10abaf + Author: Jens Maurer + Date: Fri Jul 9 22:12:36 2021 +0200 + + [basic.compound] Use quoted-string designation for pointer types + + commit 5d544aeb48fdbdc9529b9eb7c77f13c10fa4bc6b + Author: timsong-cpp + Date: Wed Jul 21 05:47:53 2021 -0500 + + [range.nonprop.cache] Clarify emplace-deref for prvalues. (#4732) + + A new note explains that `emplace-deref` requires implementations to + avoid materialization of the result of `*i` before the initialization. + This is implied by the normatively expressed requirement in terms of + an invented initialization of a variable, but is easily overlooked. + + commit f4e83097149490c7ff999588ca2cf36d01cbb791 + Author: Jonathan Wakely + Date: Thu Jun 24 20:01:16 2021 +0100 + + [ostream.formatted.reqmts],[ostream.unformatted] "that object" not "this object" + + Avoid saying "this object" when not talking about `*this`. + + commit 6847238dcfa2079bc0c70348a5fd34c07f28fe5c + Author: Jonathan Wakely + Date: Fri Jun 25 09:58:33 2021 +0100 + + [input.streams.general],[output.streams.general] describe contents more accurately + + Class templates are not types. Function templates are not function signatures. + + commit 711aa64c2625570b865ce5f88edde0b1e5863a1e + Author: Jens Maurer + Date: Sat Jul 3 00:02:53 2021 +0200 + + [std] Harmonize 'reference binds to an expression' phrasing + + commit 5465744691ae7d3fad1b9bd3d0e3c1abb90c9c63 + Author: Jonathan Wakely + Date: Wed Jul 21 12:13:55 2021 +0100 + + [meta.member] Clarify is_corresponding_member semantics + + The definition of 'common initial sequence' in [class.mem] only applies + to standard-layout struct types, which excludes unions. There is no + reason to define is_corresponding_member in terms of standard-layout + types (which includes unions and scalars and arrays of such types) when + the common initial sequence is only meaningful for standard-layout + structs. + + commit 27c1be4dc652449215246c807464605c095eb12e + Author: Jens Maurer + Date: Mon Dec 14 22:45:03 2020 +0100 + + [std] Use grammar typedef-name instead of 'typedef name'. + + The former includes names introduced by alias-declarations, + the latter (arguably) does not. + + commit a6267a3e89ed19e0d0839a4a98aa44de3eed1536 + Author: Jens Maurer + Date: Mon Dec 14 23:03:11 2020 +0100 + + [dcl.typedef] Properly define 'typedef name for linkage purposes'. + + commit 3fb7f67287ff01b7b74f0767fdd0f9d7bd1209df + Author: Casey Carter + Date: Thu Jul 22 18:06:57 2021 -0700 + + [span.streams.overview] Fix typo in "these" (#4769) + + commit 2a23be97d65776c1a1b4da454bc19ddc5420122c + Author: Johel Ernesto Guerrero Peña + Date: Tue Jul 27 15:27:49 2021 -0400 + + [allocator.requirements.general] Fix typo in table's note (#4782) + + commit 7ce2694926c5a835169635fc916297af803ed4ad + Author: Jens Maurer + Date: Tue Jul 27 21:24:51 2021 +0200 + + [basic.types.general] Fix comment in example + + commit 2a587c1570ab19bed81f9095f54eeec0d319f4ce + Author: Johel Ernesto Guerrero Peña + Date: Tue Jul 27 11:28:05 2021 -0400 + + [tuple.creation] Remove unused introductory notation + + commit 7df2b916044b3b47cd708ed1488f1d2fd5f70886 + Author: stbergmann + Date: Tue Aug 3 17:27:34 2021 +0200 + + [std] Use $...$ around negative numbers, for proper minus signs (#4790) + + commit a4e40b0ada8a15b601566af3f96bf89314e7ef60 + Author: Casey Carter + Date: Thu Aug 12 07:50:22 2021 -0700 + + [spanbuf.virtuals] Add missing "override" (#4795) + + ... to the declaration of `setbuf` to agree with the class synopsis. + + commit b02a8de26b2a19a153516a350b79c55ded8ce5f2 + Author: Johel Ernesto Guerrero Peña + Date: Tue Aug 17 17:23:32 2021 -0400 + + [range.iota.view] Mark exposition-only concepts as such (#4818) + + commit ffb5fd38560371bf38757cc8ba75130e7f17398d + Author: Johel Ernesto Guerrero Peña + Date: Wed Aug 18 09:41:42 2021 -0400 + + [range.dangling] Use "auto" parameter type (#4817) + + commit 2f24840565c363d554f99bf74e6e4255a07891c8 + Author: Johel Ernesto Guerrero Peña + Date: Wed Aug 18 16:27:55 2021 -0400 + + [coroutine.traits.primary] Separate parameters by spaces + + commit 39399f5f6f2e48d50101769180dea3219679ef60 + Author: Jens Maurer + Date: Thu Aug 19 22:19:43 2021 +0200 + + [cmath.syn] Add 'lerp' to list of differences vs. C (#4806) + + commit deec10b978bb05e12b1ad5f586f3e8b21e590306 + Author: timsong-cpp + Date: Thu Aug 19 21:13:31 2021 -0500 + + [iostream.format] Use the injected-class-name throughout + + Also remove ill-formed default template arguments in the definition + of sentry and spell out the return type of arithmetic inserters and + extractors. + + commit f66f72a92c5c9ce108f8b7ceadcafc4c70adae83 + Author: Jonathan Wakely + Date: Fri Aug 27 15:50:57 2021 +0100 + + [range.istream.view] Repeat default template argument in synopsis (#4836) + + commit 2aab403e7e14d3d166006c2e96160a430de5d4e7 + Author: Johel Ernesto Guerrero Peña + Date: Tue Aug 31 06:30:38 2021 -0400 + + [temp.spec.general] Format grammar terms (#4849) + + commit d299b77828e86d1ac26ac2ccc081e01b5a22ce4b + Author: plazum <34277374+plazum@users.noreply.github.com> + Date: Thu Sep 2 13:58:34 2021 +0800 + + [forward] Fix typo in example 2 in paragraph 6 (#4858) + + Duplicate declaration of sp1. Change it to sp2 just as that in example 1 above. + + commit b5582e513b0c79c439a6d25ec3702a63488f35ba + Author: Johel Ernesto Guerrero Peña + Date: Mon Sep 6 07:49:51 2021 -0400 + + [basic] Reference more specific subclause [expr.context] (#4866) + + commit 462b7d4cd325dec7fa6e44bda2a8da0954affa20 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Wed Sep 8 18:54:28 2021 +0300 + + [expr.const] Fix reference to integer overflow (#4880) + + commit d13ed92b0afe1ca7da4e3783cb4964e43533d3c4 + Author: Jens Maurer + Date: Sat Aug 14 12:32:28 2021 +0200 + + [basic.lookup.unqual] Clarify 'unqualified name' + + commit 01818364b75784bf19f2618b4f27afbde72caad2 + Author: Johel Ernesto Guerrero Peña + Date: Thu Sep 9 11:31:03 2021 -0400 + + [expr.typeid] Fix reference to header synopsis (#4883) + + commit 598d39c6a8da4c657b20cc8b2c002a8b8f286cb8 + Author: Jens Maurer + Date: Fri Sep 3 15:27:55 2021 +0200 + + [basic.string.general] Adjust declaration of basic_string::npos + + Use constexpr and an explicit conversion to size_type, + for consistency with basic_string_view. + + commit 28aa519b3834a9be0f2c93bc3ab1c60e9305fedf + Author: Jens Maurer + Date: Sat Sep 4 12:23:35 2021 +0200 + + [expr.ass] Clarify type of assignment-expression + + An expression has a type and a value category. + This particular compound-expression was missing the + specification of its (result) type. + + commit d6fa2a9a7e52b78b8881a387b64dc1b880bc6ea6 + Author: Johel Ernesto Guerrero Peña + Date: Mon Sep 13 10:21:47 2021 -0400 + + [intro.abstract] Fix reference to point to .general subclause (#4892) + + commit 9c018aa764fc1c6f856ffce1e61e80c889a44c6a + Author: Johel Ernesto Guerrero Peña + Date: Mon Sep 13 10:22:19 2021 -0400 + + [basic.life] Use Oxford comma (#4896) + + commit e2e875c3eb1384a70e817f36ca615f8b877f172b + Author: Johel Ernesto Guerrero Peña + Date: Mon Sep 13 10:22:59 2021 -0400 + + [basic] Reference [basic.types.general] where appropriate (#4895) + + commit e29850e886e5626ca09910224c60c3dd340a8937 + Author: Richard Smith + Date: Wed Sep 15 12:24:58 2021 -0700 + + [dcl.spec.auto.general] The placeholder type -> A placeholder type (#4909) + + "The placeholder type" gives the wrong impression that we're talking + about the case from the previous paragraph. We're not; this is parallel + to the previous paragraph so should use parallel wording. + + commit dc5a7d695b35870650b363b65ef5ae7498abda10 + Author: Jonathan Wakely + Date: Thu Sep 16 20:27:04 2021 +0100 + + [dcl.init.general] break p7 into two paragraphs (#4912) + + commit 5fdfe684b3aa0ab3579160be5cd1ff723879a0aa + Author: Jens Maurer + Date: Fri Sep 17 16:31:21 2021 +0200 + + [conv.rank] Avoid hinting that 'bool' be a standard integer type. (#4209) + + commit ed65b084e8b82af888d43a6dcad9661ddce21820 + Author: Jens Maurer + Date: Fri Sep 17 16:32:48 2021 +0200 + + [stmt.return,dcl.fct.def.coroutine] Avoid use of 'glvalue result' (#4803) + + commit b6037fce86b3a64c56ba82ed687802b745083436 + Author: Jens Maurer + Date: Fri Sep 17 16:34:34 2021 +0200 + + [expr.typeid] Require class type to be complete in all cases (#4827) + + commit 6e20d2fdbaaad47ec1f89e2ed0b2e823668acfbc + Author: Jens Maurer + Date: Sat Sep 18 07:44:53 2021 +0200 + + [facet.num.get.virtuals] Fix singular/plural mismatch + + commit 584923b8c4a19cb026f51db3ebf4006c387b1e41 + Author: Casey Carter + Date: Fri Sep 24 06:53:48 2021 -0700 + + [fstream.syn] Fix grammar + + "are only be provided" is not a valid english verb phrase. I'm not sure if + the intent was "are only provided" or "are only to be provided", but I think + the first more closely adheres to our style of making existential statements + about library implementations. + + commit 53b8382f25edcad2adc81c17db8f5a45753f6f8c + Author: Jens Maurer + Date: Fri Sep 24 00:10:24 2021 +0200 + + [dcl.init.aggr] Insert paragraph break to avoid bad \item numbering + + commit 75fe60fd58d8cfbb5eb5bd9622004f84e60a0cd9 + Author: Jens Maurer + Date: Fri Sep 24 00:03:43 2021 +0200 + + [optional] Replace bool(x) with x.has_value() + + commit 97e949e6067255152859dbd1b5825d3b42c6bfbf + Author: Jens Maurer + Date: Thu Sep 2 15:02:42 2021 +0200 + + [expr.delete] Clarify constraints on non-array delete + + commit a029b12c7baeaeb671a7ace6f231dfe81dce2236 + Author: Jens Maurer + Date: Mon Aug 30 22:21:05 2021 +0200 + + [expr.delete] Clarify treatment of arrays of classes + + commit 296f0ed962958db3f9f61ec1bd23092e7c53fa6e + Author: Jens Maurer + Date: Fri Sep 24 22:13:40 2021 +0200 + + [class.copy.elision] Fix comment in example (#4928) + + commit d9bd2a6244375c6189060b511c00867563967436 + Author: Jens Maurer + Date: Sat Sep 18 08:04:14 2021 +0200 + + [class.base.init] Clarify implicitly-defined copy/move constructors + + Those do not have a (grammatical) mem-initializer-list, + yet they ignore default member initializers. + + commit 1e1cb1269679635ef219bb0c0603a1a0d65d754e + Author: Johel Ernesto Guerrero Peña + Date: Thu Sep 9 21:55:20 2021 -0400 + + [expr.dynamic.cast] Remove apparent condition + + The preceding paragraph already introduces the + "otherwise" branch for the runtime check whose + algorithm is explain in this paragraph. + + commit 80d937ebc6b00f77046c72236256d5a60781d215 + Author: Jens Maurer + Date: Mon Jul 19 23:51:39 2021 +0200 + + [stmt.dcl] Clarify 'active' variables + + They necessarily have automatic storage duration. + + commit a054daf2cd58f1868737c5761f2fe9fdb3627f03 + Author: Jens Maurer + Date: Thu Aug 12 17:03:29 2021 +0200 + + [dcl.init.ref] Avoid 'value of the expression' + + when the properties of the expression are still relevant. + Also avoid "result of the conversion". + + commit 166af4d9e8587268564e78e1412e269ccd7170fc + Author: Jens Maurer + Date: Sat Jul 17 22:48:37 2021 +0200 + + [expr.new] Clarify result type and value category + + Also move the relevant text to after the syntactic constraints. + + commit 7a2e73da0357be63d760fb44311653c55fbac57b + Author: Barry Revzin + Date: Sat Sep 25 14:51:52 2021 -0500 + + [swappable.requirements] Change "Requires" to "Preconditions" (#4886) + + commit 8114ccdb0ef3b0e308c54aa9a3757e9d6c09528b + Author: Johel Ernesto Guerrero Peña + Date: Sat Sep 25 16:14:47 2021 -0400 + + [func.search] Fix inconsistencies between boyer_moore searchers (#4873) + + commit 3a97ba6e50e4acc2bb42b09c57f986b0eadd38e1 + Author: Jens Maurer + Date: Mon Sep 27 11:31:09 2021 +0200 + + [lib] Rename exposition-only 'no-throw-' concepts to 'nothrow-' (#4942) + + for consistency with nothrow_constructible. + + commit 668c82a2eed560c27c1205b0fe03b818bf11487c + Author: Jens Maurer + Date: Mon Sep 27 21:52:58 2021 +0200 + + [range.dangling] Use ranges::subrange in example (#4946) + + commit 17dc5f664da476831c5d6138e9f0cc15ddb6e0bc + Author: Jonathan Wakely + Date: Wed Sep 29 16:37:20 2021 +0100 + + [customization.point.object] fix grammar (#4950) + + commit b6f5885aa049d9064dab53092cd68425d100fa82 + Author: Jens Maurer + Date: Thu Sep 30 08:52:38 2021 +0200 + + [tuple.apply] Move exposition-only functions to namespace std (#4951) + + and remove superfluous std:: qualification. + + commit d82328101bcc70d7cc75929cc185b8f2206561f8 + Author: Erich Keane + Date: Sun Oct 3 06:29:18 2021 -0700 + + [expr.prim.id.general] Add missing semicolon in example (#4956) + + commit 2360a5960c6edd072e1370bb81f2797f3e80f16c + Author: Johel Ernesto Guerrero Peña + Date: Sun Oct 3 09:42:57 2021 -0400 + + [stmt.pre] Remove stray cross-reference (#4959) + + commit 35577f575883adc8c5b80dee22b6c131240bdec1 + Author: Johel Ernesto Guerrero Peña + Date: Tue Oct 19 17:16:31 2021 -0400 + + [range.lazy.split.outer.value] Fix indexed outer class name + + commit 91ab4b4f5ebea4c84304faa4efd9bd86095c0ac0 + Author: Johel Ernesto Guerrero Peña + Date: Wed Oct 20 17:40:16 2021 -0400 + + [lex.{phases,charset,string}] Fix minor misapplications of P2314R4 (#5040) + + Corrects a grammar term plural form, adds missing "R" for raw string literal, + and deletes a paragraph that was missed in the main commit + (3505e2ab3fcdf562b3fa3cb76dc417ecaef09648) and adjust index entries. + + commit 7d886537b0e2a66aa9778efedf160d43d2a27205 + Author: timsong-cpp + Date: Wed Oct 20 16:42:52 2021 -0500 + + [range.join.view] Remove duplicative condition (#4957) + + This function is constrained on `is_reference_v>` already, + so checking it again in the `if constexpr` has no effect. + + commit ef2bbe887b4caf15ffdfc4d7ba4a1cca0650b5ac + Author: Jens Maurer + Date: Sun Oct 3 15:39:35 2021 +0200 + + [support.types.layout] Avoid implementation guidance in a note + + Turn it into a "recommended practice" section. + + commit c2439d348fba54eed22e0a9803f3bca512803b0e + Author: Johel Ernesto Guerrero Peña + Date: Sat Sep 25 19:07:09 2021 -0400 + + [headers] Fix note about importing library headers + + Importable library headers are not module units, + because they do not have a module-declaration. + + commit e49d044c278a0911a98e9f6d912a3e196b5ebb2f + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Thu Oct 21 02:32:58 2021 +0300 + + [expr.delete] Remove "result" from expression (#4740) + + commit b2264247505861345c6d297d673209b06c67737f + Author: timsong-cpp + Date: Wed Oct 20 19:14:12 2021 -0500 + + [move.iterator] Use the template parameter directly in declaration of base() + + commit 21d7303990d31e8d38738d82d5a4b94fd5801b9e + Author: timsong-cpp + Date: Thu Oct 21 05:27:51 2021 -0500 + + [utilities, range.nonprop.cache] Simplify direct-non-list-initalization phrasing (#5042) + + Fixes #5038. + + commit cb39ab5883d9c1e74a2841bcdf06b6523ca6228d + Author: Jens Maurer + Date: Fri Oct 15 12:47:35 2021 +0200 + + [dcl.type.auto.deduct, expr.type.conv] Rearrange description of 'auto' deduction + + This change moves the fact that 'the type shall be auto' from + [expr.type.conv] to [dcl.type.auto.deduct], and thus avoids repeating + the mechanism of placeholder deduction. + + commit 4bffacc223a5b294be3a2bedc13cfa650fbfd653 + Author: Jens Maurer + Date: Thu Oct 21 12:51:56 2021 +0200 + + [std] Fix cross-references to 'unevaluated operand' (#4941) + + This change adds a new label to the desired paragraph, updates existing references + to refer to the new label, and adds new references to occurrences of "unevaluated + operand" that previously did not have one. + + commit 49eab1d6898e4c39b4e26b9943ab6af99da486e5 + Author: Thomas Köppe + Date: Tue Oct 19 11:08:35 2021 +0100 + + [diff.cpp20.utilities] Improve clarity of long sentence. + + Repeating the "that" pronoun makes it easier to tell where each part + of the sentence belongs. + + commit e72874655094916c118488e867d117c65fb9e754 + Author: Thomas Köppe + Date: Thu Oct 21 12:53:41 2021 +0100 + + [container.requirements] Improve punctuation of list items. + + It is still odd to have semicolons in the middle of the first list, + but at least this change makes the overall punctuation somewhat more correct. + + commit ed7cb023d0e172987b6d55f639380cf848f1db50 + Author: Jens Maurer + Date: Thu Oct 21 15:09:22 2021 +0200 + + [basic.def.odr] Introduce label 'term.odr.use' and refer to it + + instead of referring to 'basic.def.odr'. The latter breaks if we + ever move the definition of 'odr-use', e.g. to a subclause. + + commit 23b36a4af0f95038aca34a471b845a5760a13ec5 + Author: Géry Ogam + Date: Thu Oct 21 18:58:42 2021 +0200 + + [basic.life] Remove a partial repetition of the end-of-lifetime rules (#4894) + + commit f009b5d7e1eeef39d64b999abfb772ef3ecf15c9 + Author: Jens Maurer + Date: Thu Oct 21 21:41:48 2021 +0200 + + [vector.cons] Use math formatting for 'N' for consistency + + commit 1acfef5c47862676c5d1401399dd3112f73a161d + Author: Jens Maurer + Date: Thu Oct 21 21:32:19 2021 +0200 + + [string.io] Rephrase sentry conversion + + commit d2ce09da710b47d7135757a9bff26bfa4e557fef + Author: Jens Maurer + Date: Thu Oct 21 22:32:34 2021 +0200 + + [system.error.syn,locale.facet] Replace 'automatic' by 'implicit' conversion + + commit b25fb2ea70ff6fb564a247dfc95438e7e90608e4 + Author: Jens Maurer + Date: Fri Oct 22 00:18:21 2021 +0200 + + [lex.ccon] Clarify antecedent for 'it' + + commit a45f88084ff4ae301bbded86107ab540082387f1 + Author: Jens Maurer + Date: Fri Oct 22 00:14:55 2021 +0200 + + [time.format] Avoid non-sentence in bulleted list + + commit 12c32b999f85c5b7e3f8f14d7c287d47492533d2 + Author: Jonathan Wakely + Date: Fri Oct 22 11:08:35 2021 +0100 + + [expr.await] Remove hyphen from "re-thrown" (#5062) + + commit 65ec10addf80f6682395904ede48d7a1b5e732ec + Author: Thomas Köppe + Date: Fri Oct 22 18:08:06 2021 +0100 + + [range.view] Move note outside of list. diff --git a/papers/n4911.html b/papers/n4911.html new file mode 100644 index 0000000000..11b62cf3a1 --- /dev/null +++ b/papers/n4911.html @@ -0,0 +1,1027 @@ + + + + + +N4911 + + +

N4911 Editors' Report -- Programming Languages -- C++

+ +

Date: 2022-03-17

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

Thanks to all those who have submitted editorial +issues +and to those who have provided pull requests with fixes, and special thanks to +Johel Ernesto Guerrero Peña for providing in-depth review of most of the draft +motion applications.

+ +

New papers

+ +
    +
  • N4910 is the +current working draft for C++23. It replaces +N4901.
  • +
  • N4911 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group polls

+ +

CWG poll 1: Accept as Defect Reports all issues except issue 2502 in +P2533R0 +(Core Language Working Group "ready" Issues for the February, 2022 meeting) and +apply the proposed resolutions for all of the issues to the C++ working paper.

+ +

CWG poll 2: Apply the changes in +P2173R1 +(Attributes on Lambda-Expressions) to the C++ Working Paper.

+ +

CWG poll 3: Apply the changes in +P2493R0 +(Missing feature test macros for C++20 core papers) to the C++ Working Paper.

+ +

Library working group polls

+ +

LWG poll 1: Apply the changes for all Tentatively Ready issues in +P2531R0 (C++ +Standard Library Issues to be moved in Virtual Plenary, Feb. 2022) to the C++ +working paper.

+ +

LWG poll 2: Apply the changes in +P0323R12 +(std::expected) to the C++ working paper.

+ +

LWG poll 3: Apply the changes in +P0533R9 +(constexpr for <cmath> and <cstdlib>) to the C++ working paper.

+ +

LWG poll 4: Apply the changes in +P0627R6 +(Function to mark unreachable code) to the C++ working paper.

+ +

LWG poll 5: Apply the changes in +P1206R7 +(ranges::to: A function to convert any range to a container) to the C++ working +paper.

+ +

LWG poll 6: Apply the changes in +P1413R3 +(Deprecate std::aligned_storage and std::aligned_union) to the C++ working +paper.

+ +

LWG poll 7: Apply the changes in +P2255R2 (A +type trait to detect reference binding to temporary) to the C++ working paper.

+ +

LWG poll 8: Apply the changes in +P2273R3 +(Making std::unique_ptr constexpr) to the C++ working paper.

+ +

LWG poll 9: Apply the changes in +P2387R3 +(Pipe support for user-defined range adaptors) to the C++ working paper.

+ +

LWG poll 10: Apply the changes in +P2440R1 +(ranges::iota, ranges::shift_left and ranges::shift_right) to the C++ +working paper.

+ +

LWG poll 11: Apply the changes in +P2441R2 +(views::join_with) to the C++ working paper.

+ +

LWG poll 12: Apply the changes in +P2442R1 +(Windowing range adaptors: views::chunk and views::slide) to the C++ working +paper.

+ +

LWG poll 13: Apply the changes in +P2443R1 +(views::chunk_by) to the C++ working paper.

+ +

Editorial changes

+ +

Notes on motions

+ +
    +
  • Poll CWG-2: The wording was adjusted to integrate with the new wording +from issue +CWG-2509 +to use the new term lambda-specifier-seq instead of the original +decl-specifier-seq.

  • +
  • Poll LWG-1: Issue +LWG-3616 +was skipped, since it had already been applied +editorially.

  • +
  • Poll LWG-8: The wording was integrated with the resolution of +LWG-3632.

  • +
+ +

Clause reorganization

+ +

We rearranged several clauses and subclauses. Over the years, the original +clause structure had been becoming less appropriate for the growing amount of +content, and we hope that the new structure is more suitable to the current (and +anticipated future) content.

+ +
    +
  • New top-level clause "Memory management library [mem]", after [diagnostics]. +This clause contains <memory>, memory parts of <cstdlib>, smart pointers, +memory resources, and scoped allocators, previously part of [utilities].

  • +
  • The "Metaprogramming library [meta]" subclause from [utilities] is now a +new top-level clause, in between [mem] and [utilities]. We expect future +reflection material to be added to this clause.

  • +
  • The "Atomic operations [atomics]" clause has been integrated into the +top-level [thread] clause, which has been renamed to "Concurrency support +library [thread]".

  • +
  • "Bit manipulation [bit]" has been moved to the end of the [utilities] clause.

  • +
  • "Stacktrace [stacktrace]" has been moved to the end of the [diagnostics] clause.

  • +
  • "String view classes [string.view]" has been moved to immediately before +[string.classes].

  • +
  • "Allocation and deallocation functions [class.free]" has been moved to +immediately before [class.nest].

  • +
+ +

We are aiming to not change the top-level clause structure more than once per +standard publication cycle. We have had suggestions to create a new top-level +clause "Text" for text-related content (such as locales and regular expressions, +but also anticipating new material). We have not yet reached consensus, and we +will probably perform that reorganization during the C++26 cycle.

+ +

Requirements tables

+ +

We have begun replacing the large requirements tables in the library with more +conventional paragraphs, as described in editorial paper +P2416R2. +Each requirement is now presented in a style similar to that of function +declarations, followed by as many specification elements as appropriate. A new +"Result:" element has been added to capture the type of a type requirement, +and the type and value category of an expression requirement.

+ +

We have applied these changes to the container, allocator, and regular +expression trait requirements.

+ +

Term labels

+ +

We have started introducing explicit LaTeX labels for defined terms, and we have +updated cross references to refer to those term labels instead of the label of +the subclause that contains the term. This does not change the presentation of +the reference, but makes it less likely that cross references are invalidated by +moving text around.

+ +

In the future, we might extend this to turn the use of a term into a hyperlink +to the page on which the term's definition appears.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4901 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 04e0ea7074c9b0d0ca939821ce0f575c589df6b7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 21 23:52:55 2021 +0200
+
+    [pairs.pair] Use T1/T2, not first_type/second_type
+
+commit ed6e1b5da5d13449cf27c878c60e90892289f98a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 23 01:20:31 2021 +0200
+
+    [index] Fix dangling 'see' references
+
+    Also update the automatic check script to prevent
+    further occurrences.
+
+commit 3d1424716844aef59891d770709e19d83b5bea35
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 24 22:05:40 2021 +0200
+
+    [ranges] Remove \expos markers for nested types (#4829)
+
+    An \expos marker should appear only on the first
+    declaration of a name.
+
+commit 741c20794fdc7aec28afcd9e6c52d6d184d2845c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Oct 26 16:36:39 2021 +0200
+
+    [class.copy.assign] Fix phrasing in note to avoid 'could'. (#4418)
+
+commit f3ab334c789ac89d2f6baf501d60716278cb8fa3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jul 4 23:30:42 2021 +0200
+
+    [contents] Add special lookup treatment for swap
+
+commit 280684c7824b6b7f62c003b909ccf3703d82681b
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Nov 8 07:19:14 2021 -0400
+
+    [defs] Update introduction to match ISO Directives (#5096)
+
+    Reference: https://www.iso.org/sites/directives/current/part2/index.xhtml#_idTextAnchor218
+
+commit 1567c481e3ca3c52f80e4a33db0f913ce1392c4d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Nov 9 09:31:08 2021 +0000
+
+    [intro.refs] Update dated reference to previous POSIX standard
+
+    Fixes #5098
+
+commit c8ec4ab45f58e3a16d8dcb12bd660dd2cf6e936a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 23 17:22:38 2021 +0100
+
+    [refwrap.general] Add cross-references to the class synopsis (#5122)
+
+    Also rename [refwrap.const], because it does not specify
+    any destructors.
+
+commit b4bf594c81865f892bae81342ffb67c8ca8adb74
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 23 17:24:35 2021 +0100
+
+    [smartptr] Rework subclause nesting (#5119)
+
+commit d0cb462d511e5c9bf1ae7403c275f7c1ccf2543d
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sat Nov 20 02:16:40 2021 +0800
+
+    [range.adjacent.overview] Fix multi-character in example
+
+commit 26f6a1f7573ea54ed93b4e90d0e487fe39d44b87
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 13 10:01:36 2021 +0100
+
+    [dcl.typedef] Add explanation for lookup failure in example
+
+commit c63e5e836e8dbe0ae6c7ebc1b2a1b1534d37a220
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 10 23:40:48 2021 +0100
+
+    [input.output] Fix headings of 'assign and swap' subclauses
+
+commit d2699e5de0c10085df309074d2dfbc57d5bc86bb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Oct 27 21:20:02 2021 +0200
+
+    [std] Replace 'OK:' in code comments with 'OK,'
+
+    In contrast to errors, which use a colon, an OK comment
+    is not followed by any unique reason why the code is
+    well-formed, but by a subjective highlighting of a fact.
+
+commit 5e3f1ad0ceb89feb2977a0531422bcbe9ab8fba7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Oct 26 21:49:15 2021 +0200
+
+    [stdatomic.h.syn] Fix missing \expos
+
+    and augment the autmatic checks accordingly.
+
+commit 16e60c63ad14f3f3fc9132a8443421a15ebec8fc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 9 13:09:27 2021 +0100
+
+    [locale.time.get] Replace 'ISO/IEC 9945' with 'POSIX'
+
+    We introduce POSIX as an alias for ISO/IEC 9945, and we use 'POSIX'
+    everywhere else.
+
+commit 31c32e035770797eedc69f150c3a3484bbe828a5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 9 17:54:18 2021 +0100
+
+    [locale.time.get.virtuals] Use 'conversion specification'
+
+    POSIX does not define the term 'conversion directive'.
+
+commit fbab3f13719c34affdb7b712aed7f6d2313570d7
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Tue Nov 23 20:03:13 2021 +0300
+
+    [defns.access, basic.lval] Clarify what can be accessed and how (#4777)
+
+commit 5475bdab828b3585a21172945303ccebbcefb516
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Oct 21 22:11:07 2021 +0200
+
+    [c.mb.wcs] mbrtoc8 stores code units, not characters
+
+commit ba4bb3ee56b94b63d0d1e5914a136a04b1620052
+Author: mordante <koraq@xs4all.nl>
+Date:   Tue Nov 23 18:13:22 2021 +0100
+
+    [format.functions] Add "std::move" around "out" (#5069)
+
+    This fixes a misapplication of the resolution of LWG 3539.
+
+commit 0d0ec1a1393b3baae564234007c94b80da9bab48
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 23 18:15:55 2021 +0100
+
+    [func.wrap.{func.general, move.class}] Remove 'first-class object' (#5067)
+
+    The term is undefined and does not improve the specification.
+
+commit d27c3b388befadc4c35aac1d12f0ba8581f14a5f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Nov 12 14:29:00 2021 +0000
+
+    [spanstream.ctor] Fix base class name in effects
+
+commit c1935504da840995b1bb60eba536cb12bca5ae71
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Tue Nov 23 11:51:37 2021 -0600
+
+    [basic.start.main] Remove redundant phrase (#5083)
+
+commit 70eb0406596b4f4e3d97ed50b3fd6d93b3032d18
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 25 23:57:58 2021 +0200
+
+    [basic.start.main] Avoid implementation guidance in a note
+
+commit ac8d6611a739c64eda4a7062f2cb83f770cd8a53
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 25 23:58:08 2021 +0200
+
+    [dcl.link] Avoid implementation guidance in a note
+
+commit 2ad67aefe350017c4e9403ba2015af683813787f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 6 22:08:47 2021 +0100
+
+    [lex] Remove Unicode character name abbreviations
+
+    They are not part of the character name or alias.
+    The presentation in ISO 10646 is misleading, though.
+
+commit 29c89b16e92cd03a76eb2a19866e683a7bb7ac80
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 6 22:15:05 2021 +0100
+
+    [lex] Rename U+0007 BELL to ALERT
+
+    The former is ambiguous with U+1F514 BELL.
+    The ALERT alias is defined in UCD NameAliases.txt.
+
+commit 408623b7d8f0efd77403d1d0142d9bd59d1cfe55
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 4 11:19:54 2021 +0100
+
+    [associative.reqmts.general] Fix typo: 'kx', not 'rx' (#5136)
+
+commit f03473cd1e32691c105260e65dd534960cf9db21
+Author: Neven Sajko <nsajko@gmail.com>
+Date:   Sun Dec 5 21:19:00 2021 +0100
+
+    [over.sub] Fix typo: change oeprator to operator (#5140)
+
+commit c69a35501174f5ab5d3f13f12186cc9b1fcd40dd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 14 11:24:04 2021 +0100
+
+    [range.access] Fix cross-references for 'array' (#5147)
+
+    Also introduce a label 'term.array.type' in [dcl.array].
+
+commit 7a09dddd036359a10cf10b8e7d80c8edd8c76817
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 16 19:39:18 2021 +0100
+
+    [basic.fundamental] Excise normative requirements on std::numeric_limits (#5105)
+
+commit c2617432eac3313abd2134a26e2d8a1d925dfd15
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Dec 16 23:53:17 2021 -0800
+
+    [depr.default.allocator] Index allocator::is_always_equal here (#5152)
+
+    LWG3170 deprecated `allocator::is_always_equal`. We moved it to Annex D, but left the index entry behind.
+
+commit 28effaea15ef697f5a64fba47b9c095c9fbfe82a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Dec 19 22:16:18 2021 +0100
+
+    [ptr.align,re.regiter.incr] Replace 'compiler' with 'implementation'
+
+commit 575b9a99062de34cc44bc45aeb459f32aa12b98f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Dec 19 22:19:19 2021 +0100
+
+    [smartptr.adapt] Emphasize that casting might not always be viable
+
+commit 9ba8e0329a0f5db15544c31c514ff44e0003f08f
+Author: frederick-vs-ja <de34@live.cn>
+Date:   Tue Jan 11 23:29:26 2022 +0800
+
+    [pairs.pair] Add missing _v for type traits (#5196)
+
+commit dae6769d9767e2e47f2fe451d9c796dd07d0ae29
+Author: zhihaoy <43971430+zhihaoy@users.noreply.github.com>
+Date:   Thu Jan 13 14:03:25 2022 -0800
+
+    [func.memfn] Correct target object by fixing typo (#5202)
+
+commit 5f830f97829965cf791dfe6eef6b84d6283712be
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 24 22:04:55 2021 +0100
+
+    [lib] Add 'namespace std' wrappings around class definitions
+
+    Those were missing in a few places, notably [rand].
+
+    Also add an automated check.
+
+commit 1031a409dfacb84b9871b16502c73e15249160eb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Nov 19 23:02:19 2021 +0100
+
+    [chrono.syn] Use nested namespace definitions for clarity
+
+commit dad631ac4bd30e7ab6de5a888f77ed2b5b44c17d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Nov 6 09:39:55 2021 +0100
+
+    [except.throw,except.handle] Move lvalue specification for copies
+
+commit c6e5eea4f11efec62a4718acd4eb17fb99fd4899
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 25 23:41:31 2021 +0200
+
+    [expr.prim.req.general] Change requirement-seq to right-recursive
+
+    consistent with the specification of other -seq non-terminals.
+
+commit 872fce6effc603735c9717981807eb6bb8b4f838
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Dec 4 11:33:32 2021 +0100
+
+    [associative.reqmts.general] Fix confusing local use of 'r'
+
+commit 3d1bf58b74860fc1e86cd1cf536b7022b90d688d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jan 7 20:26:15 2022 +0100
+
+    [temp.res.general] Clarify binding of names
+
+commit 4123264d22c7617d828083c9ad954b5541934621
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Oct 25 18:15:14 2021 +0200
+
+    [temp.constr.atomic] Fix phrasing in note
+
+commit 26ce304780d79bba03a791b2f4299f083f021238
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 14 09:25:41 2021 +0100
+
+    [dcl.meaning.general] Clarify correspondence for block-scope friends
+
+commit 3c19e315dbb05a2c22b8f5b075af39a7572cdaa1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 23 11:18:17 2021 +0100
+
+    [meta.rel] Avoid undefined term 'void types'
+
+commit 90d178d022c7d597629853ebc70262489e49d5e9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jan 14 19:46:15 2022 +0100
+
+    [class.default.ctor] Fix implicit invocation of default constructor  (#4026)
+
+    Initialization is fully specified in [dcl.init],
+    so turn the list of default-initialization cases
+    into a note and shorten it appropriately.
+
+commit e1bfc25c56c7ab303241f980fa00d7ae402e1f5c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jul 5 23:51:41 2021 +0200
+
+    [stmt.return,class.{ctor,dtor}] Clarify no return operand
+
+    Highlight that constructors and destructors do not have a
+    return type and thus a return statement within a constructor
+    or destructor cannot have an operand.
+
+commit b345505b88b376d547220254fd858840efbfb937
+Author: Chuanqi Xu <yedeng.yd@linux.alibaba.com>
+Date:   Fri Jan 14 10:10:11 2022 +0800
+
+    [temp.param] Delete outdated wording at p15
+
+    The wording at [temp.param]/15 says:
+    > A template-parameter shall not be given default arguments by two
+    > different declarations if one is reachable from the other.
+
+    But it is conflicted with [basic.def.odr]/13:
+    > There can be more than one definition of a
+    > ...
+    >       default template argument
+    > ...
+    > in a program provided that each definition appears in a different
+    > translation unit and the definitions satisfy the [same-meaning
+    > criteria of the ODR].
+
+    [temp.param] should be deleted otherwise we couldn't modularize a real
+    project.
+
+commit fc9818bcdaa08f65c8d99f7df70b418810c36893
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jan 15 09:43:55 2022 +0100
+
+    [util.smartptr.atomic] Add cross-reference to <memory> header (#5207)
+
+commit 5c59ede65b362afb418bda3cf82123ae2ca2553c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 23 11:36:39 2021 +0100
+
+    [locale.ctype.virtuals] Clarify do_widen parameter
+
+commit cec2d218209abf2979a3c7fabc9970d8677b9e63
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 23 12:53:01 2021 +0100
+
+    [diff.stmt] Properly refer to function return types
+
+    Also annotate the 'void' and 'int' keywords.
+
+commit ba9124e62ea85c922d501dfc52bc4d44c85933bd
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jan 21 15:57:58 2022 +0000
+
+    [util.smartptr.atomic.general] Fix cross-reference to shared_ptr (#5222)
+
+commit 3cb2ee9d67360612e6361aa26d1805c8ed30c6e6
+Author: Chuanqi Xu <68680648+ChuanqiXu9@users.noreply.github.com>
+Date:   Sat Jan 22 17:43:22 2022 +0800
+
+    [temp.dep.general] add trailing 'or' (#5186)
+
+commit 4e2dbd25fa137f12c8fa6b960bc2db45be994414
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jan 22 13:38:10 2022 +0100
+
+    [class.free] Move into [class.mem]
+
+    The class-specific allocation and deallocation functions,
+    whose declaration properties are specified in this section,
+    are class member functions.
+
+commit 7987ef93488842bbdbbd6e4de996f463939fe0e8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jan 22 13:45:23 2022 +0100
+
+    [class.free] Change subclause heading and add indexing
+
+    Rename the heading to "Allocation and deallocation functions",
+    which is more appropriate for the contents of the subclause.
+
+commit 07db0b3182495339b00221bba41549913e0a6a0e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jan 22 14:35:11 2022 +0100
+
+    [stacktrace] Move into [diagnostics]
+
+commit 0df02c99d04dd0e0d29ea520904ea64f69ea6c36
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jan 20 19:42:09 2022 +0100
+
+    [class.mem.general] Add cross-reference for 'layout-compatible type'
+
+commit 2e5976f894d821e442a6f98c3e235381f8067570
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jan 20 19:36:15 2022 +0100
+
+    [stmt.return] Clarify flowing off the end of a function
+
+commit 88541f7ad5de85389adb0e88f295091d29f00030
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jan 25 23:12:55 2022 +0100
+
+    [range.req.general] Remove incorrect normative duplication for 'view' (#5235)
+
+commit 0539c5e2cdf7605c5704eb2b63916b6c5c3b9539
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 18 13:42:57 2021 +0100
+
+    [macros,structure.specifications] Add 'Result' element
+
+commit 408a22b1b58207de4af28d59afd20156e715e35f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jan 7 23:48:43 2021 +0100
+
+    [re.req] Replace requirements table with \itemdescr
+
+commit 93ff092d1cd2b335f372b9546365b3d495caf2d8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 14 20:05:03 2021 +0100
+
+    [container.requirements] Replace requirements tables with \itemdescr
+
+    and adjust cross-references to container requirements tables
+    throughout the standard library.
+
+commit 4b1a735f393aa5c864d0a5aba45514aec63f5a90
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 27 11:26:39 2021 +0200
+
+    [container.requirements] Omit redundant specification
+
+    where "Effects: Equivalent to" wording is used.
+
+commit d37470de0392f032d96c85610c947918269532a9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 20 00:09:56 2022 +0100
+
+    [lex.name] Rephrase note to avoid upper/lower-case
+
+commit efd0cab6f2d11f29f205c15672108f6e20de6010
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 20 14:28:36 2022 +0100
+
+    [lib] Add missing \pnum before descriptive elements
+
+    Also fix the ineffective check script by rewriting the
+    check in straightforward awk.
+
+commit ff92c80b70b9cd887512f96e5d5525c20550d12f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 6 09:52:01 2022 +0100
+
+    [iterator.concept.winc] Remove duplicate paragraph
+
+    This fixes a bad merge between P2393R1 Cleaning up integer-class types
+    and P2321R2 zip.
+
+commit a4dfa1f0c46152d3a3399bc32a60fcf11edd4a5d
+Author: Chuanqi Xu <68680648+ChuanqiXu9@users.noreply.github.com>
+Date:   Mon Feb 21 07:18:41 2022 +0800
+
+    [module.interface] Add adjective 'exported' (#5290)
+
+    It was clear in context that "the declaration" is exported, but
+    it is easier to understand if we restate "an exported declaration".
+
+commit 90ef396f088a4e1730a3f73f3db44d9ad8b872b7
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Feb 1 13:58:38 2022 +0000
+
+    [fs.class.directory.iterator.general] Fix grammar
+
+commit 1155c4a361c446eee4602b7fd2e82eba7a4f8c4f
+Author: languagelawyer <language.lawyer@gmail.com>
+Date:   Sat Jan 22 23:27:49 2022 +0300
+
+    [temp.res] Move a note outside itemize environment
+
+commit 44c79f59de6c4ea179bacc698272d713e696b117
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jan 29 09:37:59 2022 +0100
+
+    [derivation] Remove 'basic integral type' from footnote
+
+    Also switch footnote to note.
+
+commit 785b0a84e7b0f8108b5140f33494ceff3d0bd282
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 23 11:40:48 2021 +0100
+
+    [diff.expr] Replace 'will' with present tense
+
+    Also annotate the 'void' keyword.
+
+commit 97a72e1c4f1616f2163d34deafea010d68099a7c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Dec 5 21:22:48 2021 +0100
+
+    [temp.local] Fix type-name interpretation of injected-class-name
+
+commit a8e63922a5f049ab2c58a33117913688b8dc096a
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Feb 21 20:27:01 2022 +0800
+
+    [container.gen.reqmts] Replace "Value:" with "Returns:" (#5256)
+
+commit d267cde4fcc2c13ef87170d68f94f1ae6e499c23
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Feb 21 13:51:45 2022 +0100
+
+    [over.best.ics] Clarify phrasing around user-defined conversion sequence (#5086)
+
+    This replaces the use of "with" that is popular in mathematical writing
+    with a more common construction.
+
+commit 7424b45d8470b8765cdf3b25bcfd9a9a89c0c936
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jan 3 22:24:23 2022 +0100
+
+    [expr] Cleanup for 'discarded-value expression'
+
+commit b5ce71b34217f9d974e96cc366984cbd5f4b71e6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Dec 17 20:31:57 2021 +0100
+
+    [atomics] Harmonize references to atomics operations tables
+
+commit ef78018c8d61d79dc9cddc5f4b2d00a7929964fa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jan 21 23:01:25 2022 +0100
+
+    [std] Replace hyphen with period in labels
+
+    and add a check.
+
+commit 58ea575dd9b4a410dcf457b3357bef4a720e1608
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jan 13 23:21:05 2022 +0100
+
+    [function.objects,ranges] Introduce labels for call wrappers
+
+    In particular, 'term.perfect.forwarding.call.wrapper'
+    and 'term.simple.call.wrapper', and refer to them.
+
+commit 0c53beacef2289e4cc4fabbdff99eb3b6c7ae4ad
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jul 5 23:16:20 2021 +0200
+
+    [unique.ptr.single] Rephrase destruction
+
+commit 03b9040814ecd548f2de18668df0655ef7b37efb
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Tue Feb 22 09:39:37 2022 +0800
+
+    [version.syn] Remove mention of nonexistent header `<priority_queue>`
+
+commit 97430e8f867f5b97f79c8064c32dd1bde117198a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Nov 22 22:20:16 2021 +0100
+
+    [allocator.adaptor.members] Fix select_on_container_copy_construction
+
+    The description was confusing objects and types.
+
+commit 2cd31adb2033b4ae82339ef270bc058128cbd199
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 23 22:38:13 2022 +0100
+
+    [bit] Move into [utilities]
+
+commit e3532fd233355f93558f6a53d14b72e16a1f1ed2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 23 22:44:52 2022 +0100
+
+    [memory] Create new clause
+
+    and move [memory], [smartptr], [mem.res], and [allocator.adaptor]
+    from [utilities] into the new clause.
+
+commit cb7b98d46c4603ccc485fe826fb4363cb2c039bf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 23 22:48:10 2022 +0100
+
+    [comparisons.three.way,func.search] Add namespace around class definition
+
+commit 1daeb8e44b659c5cdf7133df68def1264c8b5774
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 23 22:54:01 2022 +0100
+
+    Move [string.view] to before [string.classes]
+
+commit 724e83e4d0cd82737952711d31505872188269ab
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 23 23:01:35 2022 +0100
+
+    [meta] Create new clause
+
+    and move [intseq], [meta], and [ratio] from [utilities] into the
+    new clause.
+
+commit af8334b94be2df5bf009ef7381460f56e6224c44
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 23 23:06:45 2022 +0100
+
+    [meta] Adjust cross-references
+
+commit d74c2170a9f4c928519461d7742293af2d141852
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 23 23:19:51 2022 +0100
+
+    Move [atomics] into [thread]
+
+    Rename [thread] to 'Concurrency support library'.
+
+commit 888602381e6c4e5fc886a7e575a95c905998b487
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Feb 24 11:35:19 2022 +0800
+
+    [headers] List <expected>
+
+commit aa2c64589cf2a784e9c551a2a54df59b880613d3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Feb 24 15:09:08 2022 +0100
+
+    [thread] Rename to 'Concurrency support library'
+
+    Missed update with commit d74c2170a9f4c928519461d7742293af2d141852.
+
+commit 000d4c091a244b3bf81470c6c6a4f2f35c3ec602
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Feb 25 01:14:48 2022 +0800
+
+    [range.chunk.outer.value] Add missing private specifier
+
+commit 2901f3f6c00060e6c0a368efd28fd50ba07350f1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Feb 25 23:38:49 2022 +0100
+
+    [diff.cpp20.library] Add subclause, highlighting new headers
+
+commit 1c88b6bdafb2eb128e7da05815f3b30fa52d3710
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Feb 27 21:23:40 2022 +0800
+
+    [range.slide.overview] Fix bad quotation marks for string-literal (#5326)
+
+commit dd346dcbd723ae27d6a2c2a74aad8a17a62ea687
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Mar 6 00:18:57 2022 +0100
+
+    [expr.const] Add cross-reference for construct_at
+
+commit 8679960561e6f18ca533915626cdd5ecd349bcf4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 27 22:22:30 2022 +0100
+
+    [allocator.requirements.general] Replace table for descriptive variables
+
+commit 0befc0e9f7e1df2451fa115b9ff12dbd8d384c5d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Feb 27 23:59:42 2022 +0100
+
+    [allocator.requirements.general] Dismantle requirements table
+
+commit 4e4aa46276d1542b2f0ff66ebd0f66df8ba0d785
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Feb 28 00:17:47 2022 +0100
+
+    [lib] Fix cross-references to replaced table cpp17.allocator
+
+commit 2d8e11333fe4e188a940bc5c4e1a2f33b139ee3b
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Feb 21 14:49:31 2022 -0400
+
+    [array.overview] Don't mention swap as an exception
+
+    The container requirements already describe this behavior,
+    so from the POV of this subclause, there's no exception.
+
+commit 65e74383deb8bcc0cab8e813b6360e9b1e8f6b10
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Feb 21 14:52:15 2022 -0400
+
+    [array.overview] Mention condition of exception
+
diff --git a/papers/n4911.md b/papers/n4911.md new file mode 100644 index 0000000000..35188804ab --- /dev/null +++ b/papers/n4911.md @@ -0,0 +1,892 @@ +# N4911 Editors' Report -- Programming Languages -- C++ + +Date: 2022-03-17 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes, and special thanks to +Johel Ernesto Guerrero Peña for providing in-depth review of most of the draft +motion applications. + +## New papers + + * [N4910](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf) is the + current working draft for C++23. It replaces + [N4901](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4901.pdf). + * N4911 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group polls + +CWG poll 1: Accept as Defect Reports all issues _except issue 2502_ in +[P2533R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2533r0.html) +(Core Language Working Group "ready" Issues for the February, 2022 meeting) and +apply the proposed resolutions for all of the issues to the C++ working paper. + +CWG poll 2: Apply the changes in +[P2173R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2173r1.pdf) +(Attributes on Lambda-Expressions) to the C++ Working Paper. + +CWG poll 3: Apply the changes in +[P2493R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2493r0.html) +(Missing feature test macros for C++20 core papers) to the C++ Working Paper. + +### Library working group polls + +LWG poll 1: Apply the changes for all Tentatively Ready issues in +[P2531R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2531r0.html) (C++ +Standard Library Issues to be moved in Virtual Plenary, Feb. 2022) to the C++ +working paper. + +LWG poll 2: Apply the changes in +[P0323R12](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0323r12.html) +(`std::expected`) to the C++ working paper. + +LWG poll 3: Apply the changes in +[P0533R9](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0533r9.pdf) +(constexpr for `` and ``) to the C++ working paper. + +LWG poll 4: Apply the changes in +[P0627R6](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0627r6.pdf) +(Function to mark unreachable code) to the C++ working paper. + +LWG poll 5: Apply the changes in +[P1206R7](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1206r7.pdf) +(ranges::to: A function to convert any range to a container) to the C++ working +paper. + +LWG poll 6: Apply the changes in +[P1413R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1413r3.pdf) +(Deprecate `std::aligned_storage` and `std::aligned_union`) to the C++ working +paper. + +LWG poll 7: Apply the changes in +[P2255R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2255r2.html) (A +type trait to detect reference binding to temporary) to the C++ working paper. + +LWG poll 8: Apply the changes in +[P2273R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2273r3.pdf) +(Making `std::unique_ptr` constexpr) to the C++ working paper. + +LWG poll 9: Apply the changes in +[P2387R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2387r3.html) +(Pipe support for user-defined range adaptors) to the C++ working paper. + +LWG poll 10: Apply the changes in +[P2440R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2440r1.html) +(`ranges::iota`, `ranges::shift_left` and `ranges::shift_right`) to the C++ +working paper. + +LWG poll 11: Apply the changes in +[P2441R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2441r2.html) +(`views::join_with`) to the C++ working paper. + +LWG poll 12: Apply the changes in +[P2442R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2442r1.html) +(Windowing range adaptors: `views::chunk` and `views::slide`) to the C++ working +paper. + +LWG poll 13: Apply the changes in +[P2443R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2443r1.html) +(`views::chunk_by`) to the C++ working paper. + +## Editorial changes + +### Notes on motions + +* **Poll CWG-2:** The wording was adjusted to integrate with the new wording + from issue + [CWG-2509](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2533r0.html#2509) + to use the new term _lambda-specifier-seq_ instead of the original + _decl-specifier-seq_. + +* **Poll LWG-1:** Issue + [LWG-3616](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2531r0.html#3616) + was skipped, since it had already been [applied + editorially](https://github.com/cplusplus/draft/commit/8753efabbbfec8371a82de1af60337fa6a6b6dc2). + +* **Poll LWG-8:** The wording was integrated with the resolution of + [LWG-3632](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2531r0.html#3632). + +### Clause reorganization + +We rearranged several clauses and subclauses. Over the years, the original +clause structure had been becoming less appropriate for the growing amount of +content, and we hope that the new structure is more suitable to the current (and +anticipated future) content. + +* New top-level clause "Memory management library [mem]", after [diagnostics]. + This clause contains ``, memory parts of ``, smart pointers, + memory resources, and scoped allocators, previously part of [utilities]. + +* The "Metaprogramming library [meta]" subclause from [utilities] is now a + new top-level clause, in between [mem] and [utilities]. We expect future + reflection material to be added to this clause. + +* The "Atomic operations [atomics]" clause has been integrated into the + top-level [thread] clause, which has been renamed to "Concurrency support + library [thread]". + +* "Bit manipulation [bit]" has been moved to the end of the [utilities] clause. + +* "Stacktrace [stacktrace]" has been moved to the end of the [diagnostics] clause. + +* "String view classes [string.view]" has been moved to immediately before + [string.classes]. + +* "Allocation and deallocation functions [class.free]" has been moved to + immediately before [class.nest]. + +We are aiming to not change the top-level clause structure more than once per +standard publication cycle. We have had suggestions to create a new top-level +clause "Text" for text-related content (such as locales and regular expressions, +but also anticipating new material). We have not yet reached consensus, and we +will probably perform that reorganization during the C++26 cycle. + +### Requirements tables + +We have begun replacing the large requirements tables in the library with more +conventional paragraphs, as described in editorial paper +[P2416R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2416r2.pdf). +Each requirement is now presented in a style similar to that of function +declarations, followed by as many specification elements as appropriate. A new +"_Result_:" element has been added to capture the type of a type requirement, +and the type and value category of an expression requirement. + +We have applied these changes to the container, allocator, and regular +expression trait requirements. + +### Term labels + +We have started introducing explicit LaTeX labels for defined terms, and we have +updated cross references to refer to those term labels instead of the label of +the subclause that contains the term. This does not change the presentation of +the reference, but makes it less likely that cross references are invalidated by +moving text around. + +In the future, we might extend this to turn the use of a term into a hyperlink +to the page on which the term's definition appears. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4901 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/n4901...n4910). + + commit 04e0ea7074c9b0d0ca939821ce0f575c589df6b7 + Author: Jens Maurer + Date: Thu Oct 21 23:52:55 2021 +0200 + + [pairs.pair] Use T1/T2, not first_type/second_type + + commit ed6e1b5da5d13449cf27c878c60e90892289f98a + Author: Jens Maurer + Date: Sat Oct 23 01:20:31 2021 +0200 + + [index] Fix dangling 'see' references + + Also update the automatic check script to prevent + further occurrences. + + commit 3d1424716844aef59891d770709e19d83b5bea35 + Author: Jens Maurer + Date: Sun Oct 24 22:05:40 2021 +0200 + + [ranges] Remove \expos markers for nested types (#4829) + + An \expos marker should appear only on the first + declaration of a name. + + commit 741c20794fdc7aec28afcd9e6c52d6d184d2845c + Author: Jens Maurer + Date: Tue Oct 26 16:36:39 2021 +0200 + + [class.copy.assign] Fix phrasing in note to avoid 'could'. (#4418) + + commit f3ab334c789ac89d2f6baf501d60716278cb8fa3 + Author: Jens Maurer + Date: Sun Jul 4 23:30:42 2021 +0200 + + [contents] Add special lookup treatment for swap + + commit 280684c7824b6b7f62c003b909ccf3703d82681b + Author: Johel Ernesto Guerrero Peña + Date: Mon Nov 8 07:19:14 2021 -0400 + + [defs] Update introduction to match ISO Directives (#5096) + + Reference: https://www.iso.org/sites/directives/current/part2/index.xhtml#_idTextAnchor218 + + commit 1567c481e3ca3c52f80e4a33db0f913ce1392c4d + Author: Jonathan Wakely + Date: Tue Nov 9 09:31:08 2021 +0000 + + [intro.refs] Update dated reference to previous POSIX standard + + Fixes #5098 + + commit c8ec4ab45f58e3a16d8dcb12bd660dd2cf6e936a + Author: Jens Maurer + Date: Tue Nov 23 17:22:38 2021 +0100 + + [refwrap.general] Add cross-references to the class synopsis (#5122) + + Also rename [refwrap.const], because it does not specify + any destructors. + + commit b4bf594c81865f892bae81342ffb67c8ca8adb74 + Author: Jens Maurer + Date: Tue Nov 23 17:24:35 2021 +0100 + + [smartptr] Rework subclause nesting (#5119) + + commit d0cb462d511e5c9bf1ae7403c275f7c1ccf2543d + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sat Nov 20 02:16:40 2021 +0800 + + [range.adjacent.overview] Fix multi-character in example + + commit 26f6a1f7573ea54ed93b4e90d0e487fe39d44b87 + Author: Jens Maurer + Date: Sat Nov 13 10:01:36 2021 +0100 + + [dcl.typedef] Add explanation for lookup failure in example + + commit c63e5e836e8dbe0ae6c7ebc1b2a1b1534d37a220 + Author: Jens Maurer + Date: Wed Nov 10 23:40:48 2021 +0100 + + [input.output] Fix headings of 'assign and swap' subclauses + + commit d2699e5de0c10085df309074d2dfbc57d5bc86bb + Author: Jens Maurer + Date: Wed Oct 27 21:20:02 2021 +0200 + + [std] Replace 'OK:' in code comments with 'OK,' + + In contrast to errors, which use a colon, an OK comment + is not followed by any unique reason why the code is + well-formed, but by a subjective highlighting of a fact. + + commit 5e3f1ad0ceb89feb2977a0531422bcbe9ab8fba7 + Author: Jens Maurer + Date: Tue Oct 26 21:49:15 2021 +0200 + + [stdatomic.h.syn] Fix missing \expos + + and augment the autmatic checks accordingly. + + commit 16e60c63ad14f3f3fc9132a8443421a15ebec8fc + Author: Jens Maurer + Date: Tue Nov 9 13:09:27 2021 +0100 + + [locale.time.get] Replace 'ISO/IEC 9945' with 'POSIX' + + We introduce POSIX as an alias for ISO/IEC 9945, and we use 'POSIX' + everywhere else. + + commit 31c32e035770797eedc69f150c3a3484bbe828a5 + Author: Jens Maurer + Date: Tue Nov 9 17:54:18 2021 +0100 + + [locale.time.get.virtuals] Use 'conversion specification' + + POSIX does not define the term 'conversion directive'. + + commit fbab3f13719c34affdb7b712aed7f6d2313570d7 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Tue Nov 23 20:03:13 2021 +0300 + + [defns.access, basic.lval] Clarify what can be accessed and how (#4777) + + commit 5475bdab828b3585a21172945303ccebbcefb516 + Author: Jens Maurer + Date: Thu Oct 21 22:11:07 2021 +0200 + + [c.mb.wcs] mbrtoc8 stores code units, not characters + + commit ba4bb3ee56b94b63d0d1e5914a136a04b1620052 + Author: mordante + Date: Tue Nov 23 18:13:22 2021 +0100 + + [format.functions] Add "std::move" around "out" (#5069) + + This fixes a misapplication of the resolution of LWG 3539. + + commit 0d0ec1a1393b3baae564234007c94b80da9bab48 + Author: Jens Maurer + Date: Tue Nov 23 18:15:55 2021 +0100 + + [func.wrap.{func.general, move.class}] Remove 'first-class object' (#5067) + + The term is undefined and does not improve the specification. + + commit d27c3b388befadc4c35aac1d12f0ba8581f14a5f + Author: Jonathan Wakely + Date: Fri Nov 12 14:29:00 2021 +0000 + + [spanstream.ctor] Fix base class name in effects + + commit c1935504da840995b1bb60eba536cb12bca5ae71 + Author: timsong-cpp + Date: Tue Nov 23 11:51:37 2021 -0600 + + [basic.start.main] Remove redundant phrase (#5083) + + commit 70eb0406596b4f4e3d97ed50b3fd6d93b3032d18 + Author: Jens Maurer + Date: Mon Oct 25 23:57:58 2021 +0200 + + [basic.start.main] Avoid implementation guidance in a note + + commit ac8d6611a739c64eda4a7062f2cb83f770cd8a53 + Author: Jens Maurer + Date: Mon Oct 25 23:58:08 2021 +0200 + + [dcl.link] Avoid implementation guidance in a note + + commit 2ad67aefe350017c4e9403ba2015af683813787f + Author: Jens Maurer + Date: Sat Nov 6 22:08:47 2021 +0100 + + [lex] Remove Unicode character name abbreviations + + They are not part of the character name or alias. + The presentation in ISO 10646 is misleading, though. + + commit 29c89b16e92cd03a76eb2a19866e683a7bb7ac80 + Author: Jens Maurer + Date: Sat Nov 6 22:15:05 2021 +0100 + + [lex] Rename U+0007 BELL to ALERT + + The former is ambiguous with U+1F514 BELL. + The ALERT alias is defined in UCD NameAliases.txt. + + commit 408623b7d8f0efd77403d1d0142d9bd59d1cfe55 + Author: Jens Maurer + Date: Sat Dec 4 11:19:54 2021 +0100 + + [associative.reqmts.general] Fix typo: 'kx', not 'rx' (#5136) + + commit f03473cd1e32691c105260e65dd534960cf9db21 + Author: Neven Sajko + Date: Sun Dec 5 21:19:00 2021 +0100 + + [over.sub] Fix typo: change oeprator to operator (#5140) + + commit c69a35501174f5ab5d3f13f12186cc9b1fcd40dd + Author: Jens Maurer + Date: Tue Dec 14 11:24:04 2021 +0100 + + [range.access] Fix cross-references for 'array' (#5147) + + Also introduce a label 'term.array.type' in [dcl.array]. + + commit 7a09dddd036359a10cf10b8e7d80c8edd8c76817 + Author: Jens Maurer + Date: Thu Dec 16 19:39:18 2021 +0100 + + [basic.fundamental] Excise normative requirements on std::numeric_limits (#5105) + + commit c2617432eac3313abd2134a26e2d8a1d925dfd15 + Author: Casey Carter + Date: Thu Dec 16 23:53:17 2021 -0800 + + [depr.default.allocator] Index allocator::is_always_equal here (#5152) + + LWG3170 deprecated `allocator::is_always_equal`. We moved it to Annex D, but left the index entry behind. + + commit 28effaea15ef697f5a64fba47b9c095c9fbfe82a + Author: Jens Maurer + Date: Sun Dec 19 22:16:18 2021 +0100 + + [ptr.align,re.regiter.incr] Replace 'compiler' with 'implementation' + + commit 575b9a99062de34cc44bc45aeb459f32aa12b98f + Author: Jens Maurer + Date: Sun Dec 19 22:19:19 2021 +0100 + + [smartptr.adapt] Emphasize that casting might not always be viable + + commit 9ba8e0329a0f5db15544c31c514ff44e0003f08f + Author: frederick-vs-ja + Date: Tue Jan 11 23:29:26 2022 +0800 + + [pairs.pair] Add missing _v for type traits (#5196) + + commit dae6769d9767e2e47f2fe451d9c796dd07d0ae29 + Author: zhihaoy <43971430+zhihaoy@users.noreply.github.com> + Date: Thu Jan 13 14:03:25 2022 -0800 + + [func.memfn] Correct target object by fixing typo (#5202) + + commit 5f830f97829965cf791dfe6eef6b84d6283712be + Author: Jens Maurer + Date: Wed Nov 24 22:04:55 2021 +0100 + + [lib] Add 'namespace std' wrappings around class definitions + + Those were missing in a few places, notably [rand]. + + Also add an automated check. + + commit 1031a409dfacb84b9871b16502c73e15249160eb + Author: Jens Maurer + Date: Fri Nov 19 23:02:19 2021 +0100 + + [chrono.syn] Use nested namespace definitions for clarity + + commit dad631ac4bd30e7ab6de5a888f77ed2b5b44c17d + Author: Jens Maurer + Date: Sat Nov 6 09:39:55 2021 +0100 + + [except.throw,except.handle] Move lvalue specification for copies + + commit c6e5eea4f11efec62a4718acd4eb17fb99fd4899 + Author: Jens Maurer + Date: Mon Oct 25 23:41:31 2021 +0200 + + [expr.prim.req.general] Change requirement-seq to right-recursive + + consistent with the specification of other -seq non-terminals. + + commit 872fce6effc603735c9717981807eb6bb8b4f838 + Author: Jens Maurer + Date: Sat Dec 4 11:33:32 2021 +0100 + + [associative.reqmts.general] Fix confusing local use of 'r' + + commit 3d1bf58b74860fc1e86cd1cf536b7022b90d688d + Author: Jens Maurer + Date: Fri Jan 7 20:26:15 2022 +0100 + + [temp.res.general] Clarify binding of names + + commit 4123264d22c7617d828083c9ad954b5541934621 + Author: Jens Maurer + Date: Mon Oct 25 18:15:14 2021 +0200 + + [temp.constr.atomic] Fix phrasing in note + + commit 26ce304780d79bba03a791b2f4299f083f021238 + Author: Jens Maurer + Date: Tue Dec 14 09:25:41 2021 +0100 + + [dcl.meaning.general] Clarify correspondence for block-scope friends + + commit 3c19e315dbb05a2c22b8f5b075af39a7572cdaa1 + Author: Jens Maurer + Date: Thu Dec 23 11:18:17 2021 +0100 + + [meta.rel] Avoid undefined term 'void types' + + commit 90d178d022c7d597629853ebc70262489e49d5e9 + Author: Jens Maurer + Date: Fri Jan 14 19:46:15 2022 +0100 + + [class.default.ctor] Fix implicit invocation of default constructor (#4026) + + Initialization is fully specified in [dcl.init], + so turn the list of default-initialization cases + into a note and shorten it appropriately. + + commit e1bfc25c56c7ab303241f980fa00d7ae402e1f5c + Author: Jens Maurer + Date: Mon Jul 5 23:51:41 2021 +0200 + + [stmt.return,class.{ctor,dtor}] Clarify no return operand + + Highlight that constructors and destructors do not have a + return type and thus a return statement within a constructor + or destructor cannot have an operand. + + commit b345505b88b376d547220254fd858840efbfb937 + Author: Chuanqi Xu + Date: Fri Jan 14 10:10:11 2022 +0800 + + [temp.param] Delete outdated wording at p15 + + The wording at [temp.param]/15 says: + > A template-parameter shall not be given default arguments by two + > different declarations if one is reachable from the other. + + But it is conflicted with [basic.def.odr]/13: + > There can be more than one definition of a + > ... + > default template argument + > ... + > in a program provided that each definition appears in a different + > translation unit and the definitions satisfy the [same-meaning + > criteria of the ODR]. + + [temp.param] should be deleted otherwise we couldn't modularize a real + project. + + commit fc9818bcdaa08f65c8d99f7df70b418810c36893 + Author: Jens Maurer + Date: Sat Jan 15 09:43:55 2022 +0100 + + [util.smartptr.atomic] Add cross-reference to header (#5207) + + commit 5c59ede65b362afb418bda3cf82123ae2ca2553c + Author: Jens Maurer + Date: Thu Dec 23 11:36:39 2021 +0100 + + [locale.ctype.virtuals] Clarify do_widen parameter + + commit cec2d218209abf2979a3c7fabc9970d8677b9e63 + Author: Jens Maurer + Date: Thu Dec 23 12:53:01 2021 +0100 + + [diff.stmt] Properly refer to function return types + + Also annotate the 'void' and 'int' keywords. + + commit ba9124e62ea85c922d501dfc52bc4d44c85933bd + Author: Jonathan Wakely + Date: Fri Jan 21 15:57:58 2022 +0000 + + [util.smartptr.atomic.general] Fix cross-reference to shared_ptr (#5222) + + commit 3cb2ee9d67360612e6361aa26d1805c8ed30c6e6 + Author: Chuanqi Xu <68680648+ChuanqiXu9@users.noreply.github.com> + Date: Sat Jan 22 17:43:22 2022 +0800 + + [temp.dep.general] add trailing 'or' (#5186) + + commit 4e2dbd25fa137f12c8fa6b960bc2db45be994414 + Author: Jens Maurer + Date: Sat Jan 22 13:38:10 2022 +0100 + + [class.free] Move into [class.mem] + + The class-specific allocation and deallocation functions, + whose declaration properties are specified in this section, + are class member functions. + + commit 7987ef93488842bbdbbd6e4de996f463939fe0e8 + Author: Jens Maurer + Date: Sat Jan 22 13:45:23 2022 +0100 + + [class.free] Change subclause heading and add indexing + + Rename the heading to "Allocation and deallocation functions", + which is more appropriate for the contents of the subclause. + + commit 07db0b3182495339b00221bba41549913e0a6a0e + Author: Jens Maurer + Date: Sat Jan 22 14:35:11 2022 +0100 + + [stacktrace] Move into [diagnostics] + + commit 0df02c99d04dd0e0d29ea520904ea64f69ea6c36 + Author: Jens Maurer + Date: Thu Jan 20 19:42:09 2022 +0100 + + [class.mem.general] Add cross-reference for 'layout-compatible type' + + commit 2e5976f894d821e442a6f98c3e235381f8067570 + Author: Jens Maurer + Date: Thu Jan 20 19:36:15 2022 +0100 + + [stmt.return] Clarify flowing off the end of a function + + commit 88541f7ad5de85389adb0e88f295091d29f00030 + Author: Jens Maurer + Date: Tue Jan 25 23:12:55 2022 +0100 + + [range.req.general] Remove incorrect normative duplication for 'view' (#5235) + + commit 0539c5e2cdf7605c5704eb2b63916b6c5c3b9539 + Author: Jens Maurer + Date: Thu Feb 18 13:42:57 2021 +0100 + + [macros,structure.specifications] Add 'Result' element + + commit 408a22b1b58207de4af28d59afd20156e715e35f + Author: Jens Maurer + Date: Thu Jan 7 23:48:43 2021 +0100 + + [re.req] Replace requirements table with \itemdescr + + commit 93ff092d1cd2b335f372b9546365b3d495caf2d8 + Author: Jens Maurer + Date: Sun Nov 14 20:05:03 2021 +0100 + + [container.requirements] Replace requirements tables with \itemdescr + + and adjust cross-references to container requirements tables + throughout the standard library. + + commit 4b1a735f393aa5c864d0a5aba45514aec63f5a90 + Author: Jens Maurer + Date: Sun Jun 27 11:26:39 2021 +0200 + + [container.requirements] Omit redundant specification + + where "Effects: Equivalent to" wording is used. + + commit d37470de0392f032d96c85610c947918269532a9 + Author: Jens Maurer + Date: Sun Feb 20 00:09:56 2022 +0100 + + [lex.name] Rephrase note to avoid upper/lower-case + + commit efd0cab6f2d11f29f205c15672108f6e20de6010 + Author: Jens Maurer + Date: Sun Feb 20 14:28:36 2022 +0100 + + [lib] Add missing \pnum before descriptive elements + + Also fix the ineffective check script by rewriting the + check in straightforward awk. + + commit ff92c80b70b9cd887512f96e5d5525c20550d12f + Author: Jens Maurer + Date: Sun Feb 6 09:52:01 2022 +0100 + + [iterator.concept.winc] Remove duplicate paragraph + + This fixes a bad merge between P2393R1 Cleaning up integer-class types + and P2321R2 zip. + + commit a4dfa1f0c46152d3a3399bc32a60fcf11edd4a5d + Author: Chuanqi Xu <68680648+ChuanqiXu9@users.noreply.github.com> + Date: Mon Feb 21 07:18:41 2022 +0800 + + [module.interface] Add adjective 'exported' (#5290) + + It was clear in context that "the declaration" is exported, but + it is easier to understand if we restate "an exported declaration". + + commit 90ef396f088a4e1730a3f73f3db44d9ad8b872b7 + Author: Jonathan Wakely + Date: Tue Feb 1 13:58:38 2022 +0000 + + [fs.class.directory.iterator.general] Fix grammar + + commit 1155c4a361c446eee4602b7fd2e82eba7a4f8c4f + Author: languagelawyer + Date: Sat Jan 22 23:27:49 2022 +0300 + + [temp.res] Move a note outside itemize environment + + commit 44c79f59de6c4ea179bacc698272d713e696b117 + Author: Jens Maurer + Date: Sat Jan 29 09:37:59 2022 +0100 + + [derivation] Remove 'basic integral type' from footnote + + Also switch footnote to note. + + commit 785b0a84e7b0f8108b5140f33494ceff3d0bd282 + Author: Jens Maurer + Date: Thu Dec 23 11:40:48 2021 +0100 + + [diff.expr] Replace 'will' with present tense + + Also annotate the 'void' keyword. + + commit 97a72e1c4f1616f2163d34deafea010d68099a7c + Author: Jens Maurer + Date: Sun Dec 5 21:22:48 2021 +0100 + + [temp.local] Fix type-name interpretation of injected-class-name + + commit a8e63922a5f049ab2c58a33117913688b8dc096a + Author: A. Jiang + Date: Mon Feb 21 20:27:01 2022 +0800 + + [container.gen.reqmts] Replace "Value:" with "Returns:" (#5256) + + commit d267cde4fcc2c13ef87170d68f94f1ae6e499c23 + Author: Jens Maurer + Date: Mon Feb 21 13:51:45 2022 +0100 + + [over.best.ics] Clarify phrasing around user-defined conversion sequence (#5086) + + This replaces the use of "with" that is popular in mathematical writing + with a more common construction. + + commit 7424b45d8470b8765cdf3b25bcfd9a9a89c0c936 + Author: Jens Maurer + Date: Mon Jan 3 22:24:23 2022 +0100 + + [expr] Cleanup for 'discarded-value expression' + + commit b5ce71b34217f9d974e96cc366984cbd5f4b71e6 + Author: Jens Maurer + Date: Fri Dec 17 20:31:57 2021 +0100 + + [atomics] Harmonize references to atomics operations tables + + commit ef78018c8d61d79dc9cddc5f4b2d00a7929964fa + Author: Jens Maurer + Date: Fri Jan 21 23:01:25 2022 +0100 + + [std] Replace hyphen with period in labels + + and add a check. + + commit 58ea575dd9b4a410dcf457b3357bef4a720e1608 + Author: Jens Maurer + Date: Thu Jan 13 23:21:05 2022 +0100 + + [function.objects,ranges] Introduce labels for call wrappers + + In particular, 'term.perfect.forwarding.call.wrapper' + and 'term.simple.call.wrapper', and refer to them. + + commit 0c53beacef2289e4cc4fabbdff99eb3b6c7ae4ad + Author: Jens Maurer + Date: Mon Jul 5 23:16:20 2021 +0200 + + [unique.ptr.single] Rephrase destruction + + commit 03b9040814ecd548f2de18668df0655ef7b37efb + Author: S. B. Tam + Date: Tue Feb 22 09:39:37 2022 +0800 + + [version.syn] Remove mention of nonexistent header `` + + commit 97430e8f867f5b97f79c8064c32dd1bde117198a + Author: Jens Maurer + Date: Mon Nov 22 22:20:16 2021 +0100 + + [allocator.adaptor.members] Fix select_on_container_copy_construction + + The description was confusing objects and types. + + commit 2cd31adb2033b4ae82339ef270bc058128cbd199 + Author: Jens Maurer + Date: Wed Feb 23 22:38:13 2022 +0100 + + [bit] Move into [utilities] + + commit e3532fd233355f93558f6a53d14b72e16a1f1ed2 + Author: Jens Maurer + Date: Wed Feb 23 22:44:52 2022 +0100 + + [memory] Create new clause + + and move [memory], [smartptr], [mem.res], and [allocator.adaptor] + from [utilities] into the new clause. + + commit cb7b98d46c4603ccc485fe826fb4363cb2c039bf + Author: Jens Maurer + Date: Wed Feb 23 22:48:10 2022 +0100 + + [comparisons.three.way,func.search] Add namespace around class definition + + commit 1daeb8e44b659c5cdf7133df68def1264c8b5774 + Author: Jens Maurer + Date: Wed Feb 23 22:54:01 2022 +0100 + + Move [string.view] to before [string.classes] + + commit 724e83e4d0cd82737952711d31505872188269ab + Author: Jens Maurer + Date: Wed Feb 23 23:01:35 2022 +0100 + + [meta] Create new clause + + and move [intseq], [meta], and [ratio] from [utilities] into the + new clause. + + commit af8334b94be2df5bf009ef7381460f56e6224c44 + Author: Jens Maurer + Date: Wed Feb 23 23:06:45 2022 +0100 + + [meta] Adjust cross-references + + commit d74c2170a9f4c928519461d7742293af2d141852 + Author: Jens Maurer + Date: Wed Feb 23 23:19:51 2022 +0100 + + Move [atomics] into [thread] + + Rename [thread] to 'Concurrency support library'. + + commit 888602381e6c4e5fc886a7e575a95c905998b487 + Author: A. Jiang + Date: Thu Feb 24 11:35:19 2022 +0800 + + [headers] List + + commit aa2c64589cf2a784e9c551a2a54df59b880613d3 + Author: Jens Maurer + Date: Thu Feb 24 15:09:08 2022 +0100 + + [thread] Rename to 'Concurrency support library' + + Missed update with commit d74c2170a9f4c928519461d7742293af2d141852. + + commit 000d4c091a244b3bf81470c6c6a4f2f35c3ec602 + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Fri Feb 25 01:14:48 2022 +0800 + + [range.chunk.outer.value] Add missing private specifier + + commit 2901f3f6c00060e6c0a368efd28fd50ba07350f1 + Author: Jens Maurer + Date: Fri Feb 25 23:38:49 2022 +0100 + + [diff.cpp20.library] Add subclause, highlighting new headers + + commit 1c88b6bdafb2eb128e7da05815f3b30fa52d3710 + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Sun Feb 27 21:23:40 2022 +0800 + + [range.slide.overview] Fix bad quotation marks for string-literal (#5326) + + commit dd346dcbd723ae27d6a2c2a74aad8a17a62ea687 + Author: Jens Maurer + Date: Sun Mar 6 00:18:57 2022 +0100 + + [expr.const] Add cross-reference for construct_at + + commit 8679960561e6f18ca533915626cdd5ecd349bcf4 + Author: Jens Maurer + Date: Sun Feb 27 22:22:30 2022 +0100 + + [allocator.requirements.general] Replace table for descriptive variables + + commit 0befc0e9f7e1df2451fa115b9ff12dbd8d384c5d + Author: Jens Maurer + Date: Sun Feb 27 23:59:42 2022 +0100 + + [allocator.requirements.general] Dismantle requirements table + + commit 4e4aa46276d1542b2f0ff66ebd0f66df8ba0d785 + Author: Jens Maurer + Date: Mon Feb 28 00:17:47 2022 +0100 + + [lib] Fix cross-references to replaced table cpp17.allocator + + commit 2d8e11333fe4e188a940bc5c4e1a2f33b139ee3b + Author: Johel Ernesto Guerrero Peña + Date: Mon Feb 21 14:49:31 2022 -0400 + + [array.overview] Don't mention swap as an exception + + The container requirements already describe this behavior, + so from the POV of this subclause, there's no exception. + + commit 65e74383deb8bcc0cab8e813b6360e9b1e8f6b10 + Author: Johel Ernesto Guerrero Peña + Date: Mon Feb 21 14:52:15 2022 -0400 + + [array.overview] Mention condition of exception diff --git a/papers/n4918.html b/papers/n4918.html new file mode 100644 index 0000000000..a21471cc39 --- /dev/null +++ b/papers/n4918.html @@ -0,0 +1,2007 @@ + + + + + +N4918 + + +

N4918 Editors’ Report:
Programming Languages — C++

+ +

Date: 2022-09-06

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

Thanks to all those who have submitted editorial +issues +and to those who have provided pull requests with fixes, and special thanks to +Johel Ernesto Guerrero Peña for providing in-depth review of most of the draft +motion applications, and to Hewill Kang for spotting and sending corrections for +many editorial issues.

+ +

New papers

+ +
    +
  • N4917 is the +current working draft for C++23. It replaces +N4910.
  • +
  • N4918 is this Editors' Report.
  • +
  • N4919 is the C++23 Committee Draft.
  • +
+ +

Motions incorporated into working draft

+ +

Core working group polls

+ +

CWG poll 1: Accept as Defect Reports all issues except 2507 and 2586 in +P2622R0 +(Core Language Working Group "ready" Issues for the July, 2022 meeting) and +apply their proposed resolutions to the C++ Working Paper.

+ +

CWG poll 2: Apply the proposed resolution of issues 2507 and 2586 in +P2622R0 +(Core Language Working Group "ready" Issues for the July, 2022 meeting) to the +C++ Working Paper.

+ +

CWG poll 3: Accept as a Defect Report and apply the changes in +P2468R2 +(The Equality Operator You Are Looking For) to the C++ Working Paper.

+ +

CWG poll 4: Accept as a Defect Report and apply the changes in +P2327R1 +(De-deprecating volatile compound operations) to the C++ Working Paper.

+ +

CWG poll 5: Apply the changes in +P2437R1 +(Support for #warning) to the C++ Working Paper.

+ +

CWG poll 6: Apply the changes in +P2362R3 +(Remove non-encodable wide character literals and multicharacter wide character +literals) to the C++ Working Paper.

+ +

CWG poll 7: Apply the changes in +P2324R2 +(Labels at the end of compound statements (C compatibility)) to the C++ Working +Paper.

+ +

CWG poll 8: Apply the changes in +P2290R3 +(Delimited escape sequences) to the C++ Working Paper.

+ +

CWG poll 9: Apply the changes in +P2448R2 +(Relaxing some constexpr restrictions) to the C++ Working Paper.

+ +

CWG poll 10: Apply the changes in +P2266R3 +(Simpler implicit move) to the C++ Working Paper.

+ +

CWG poll 11: Apply the changes in +P2071R2 +(Named universal character escapes) to the C++ Working Paper.

+ +

CWG poll 12: Apply the changes in +P1169R4 +(static operator()) to the C++ Working Paper.

+ +

CWG poll 13: Accept as a Defect Report and apply the changes in +P2280R4 +(Using unknown pointers and references in constant expressions) to the C++ +Working Paper.

+ +

CWG poll 14: Apply the changes in +P1467R9 +(Extended floating-point types and standard names) to the C++ Working Paper.

+ +

CWG poll 15: Accept as a Defect Report +P2493R0 +(Missing feature test macros for C++20 core papers). (The paper was already +adopted at the February, 2022 meeting, and no changes to the Working Paper +result from it now.)

+ +

CWG poll 16: Apply the changes in +P2582R1 +(Wording for class template argument deduction from inherited constructors) to +the C++ Working Paper.

+ +

CWG poll 17: Apply the changes in +P1774R8 +(Portable assumptions) to the C++ Working Paper.

+ +

CWG poll 18: Apply the changes in +P2295R6 +(Support for UTF-8 as a portable source file encoding) to the C++ Working Paper.

+ +

CWG poll 19: Accept as a Defect Report and apply the changes in +P2513R3 +(char8_t Compatibility and Portability Fix) to the C++ Working Paper.

+ +

CWG poll 20: Accept as a Defect Report and apply the changes in +P2460R2 +(Relax requirements on wchar_t to match existing practices) to the C++ Working +Paper.

+ +

CWG poll 21: Accept as a Defect Report and apply the changes in +P2579R0 +(Mitigation strategies for P2036 "Changing scope for lambda +trailing-return-type") to the C++ Working Paper.

+ +

Library working group polls

+ +

LWG poll 1: Apply the changes for all Ready issues in +P2618R0 (C++ +Standard Library Issues to be moved in Virtual Plenary, Jul. 2022) to the C++ +working paper.

+ +

LWG poll 2: Apply the changes in +P0009R18 +(MDSPAN) to the C++ working paper.

+ +

LWG poll 3: Apply the changes in +P2599R2 +(index_type & size_type in mdspan) to the C++ working paper.

+ +

LWG poll 4: Apply the changes in +P2604R0 +(mdspan: rename pointer and contiguous) to the C++ working paper.

+ +

LWG poll 5: Apply the changes in +P2613R1 (Add +the missing empty to mdspan) to the C++ working paper.

+ +

LWG poll 6: Apply the changes in +P0429R9 (A +Standard flat_map) to the C++ working paper.

+ +

LWG poll 7: Apply the changes in +P1222R4 (A +Standard flat_set) to the C++ working paper.

+ +

LWG poll 8: Apply the changes in +P1223R5 +(find_last) to the C++ working paper.

+ +

LWG poll 9: Apply the changes in +P1642R11 +(Freestanding Library: Easy [utilities], [ranges], and [iterators]) to the C++ +working paper.

+ +

LWG poll 10: Apply the changes in +P1899R3 +(stride_view) to the C++ working paper.

+ +

LWG poll 11: Apply the changes in +P2093R14 +(Formatted output) to the C++ working paper.

+ +

LWG poll 12: Apply the changes in +P2165R4 +(Compatibility between tuple, pair and tuple-like objects) to the C++ +working paper.

+ +

LWG poll 13: Apply the changes in +P2278R4 +(cbegin should always return a constant iterator) to the C++ working paper.

+ +

LWG poll 14: Apply the changes in +P2286R8 +(Formatting Ranges) to the C++ working paper.

+ +

LWG poll 15: Apply the changes in +P2291R3 (Add +Constexpr Modifiers to Functions to_chars and from_chars for Integral Types +in <charconv> Header) to the C++ working paper.

+ +

LWG poll 16: Apply the changes in +P2302R4 +(std::ranges::contains) to the C++ working paper.

+ +

LWG poll 17: Apply the changes in +P2322R6 +(ranges::fold) to the C++ working paper.

+ +

LWG poll 18: Apply the changes in +P2374R4 +(views::cartesian_product) to the C++ working paper.

+ +

LWG poll 19: Apply the changes in +P2540R1 +(Empty Product for certain Views) to the C++ working paper.

+ +

LWG poll 20: Apply the changes in +P2404R3 +(Move-only types for equality_comparable_with, totally_ordered_with, and +three_way_comparable_with) to the C++ working paper.

+ +

LWG poll 21: Apply the changes in +P2408R5 +(Ranges iterators as inputs to non-Ranges algorithms) to the C++ working paper.

+ +

LWG poll 22: Apply the changes in +P2417R2 (A +more constexpr bitset) to the C++ working paper.

+ +

LWG poll 23: Apply the changes in +P2419R2 +(Clarify handling of encodings in localized formatting of chrono types) to the +C++ working paper.

+ +

LWG poll 24: Apply the changes in +P2438R2 +(std::string::substr() &&) to the C++ working paper.

+ +

LWG poll 25: Apply the changes in +P2446R2 +(views::as_rvalue) to the C++ working paper.

+ +

LWG poll 26: Apply the changes in +P2465R3 +(Standard Library Modules std and std.compat) to the C++ working paper.

+ +

LWG poll 27: Apply the changes in +P2445R1 +(std::forward_like) to the C++ working paper.

+ +

LWG poll 28: Apply the changes in +P2467R1 +(Support exclusive mode for fstreams) to the C++ working paper.

+ +

LWG poll 29: Apply the changes in +P2474R2 +(views::repeat) to the C++ working paper.

+ +

LWG poll 30: Apply the changes in +P2494R2 +(Relaxing range adaptors to allow for move only types) to the C++ working paper.

+ +

LWG poll 31: Apply the changes in +P2499R0 +(string_view range constructor should be explicit) to the C++ working paper.

+ +

LWG poll 32: Apply the changes in +P2502R2 +(std::generator: Synchronous Coroutine Generator for Ranges) to the C++ working +paper.

+ +

LWG poll 33: Apply the changes in +P2508R1 +(Exposing std::basic-format-string<charT, Args...>) +to the C++ working paper.

+ +

LWG poll 34: Apply the changes in +P2517R1 (Add +a conditional noexcept specification to std::apply) to the C++ working paper.

+ +

LWG poll 35: Apply the changes in +P2520R0 +(move_iterator<T*> should be a random access iterator) to the C++ working +paper.

+ +

LWG poll 36: Apply the changes in +P2549R1 +(std::unexpected<E> should have error() as member accessor) to the C++ +working paper.

+ +

LWG poll 37: Apply the changes in +P2585R1 +(Improving default container formatting) to the C++ working paper.

+ +

LWG poll 38: Apply the changes in +P2590R2 +(Explicit lifetime management) to the C++ working paper.

+ +

Editorial changes

+ +

Notes on motions

+ +
    +
  • Poll CWG-9: The wording was based on an old draft, and has been adjusted +to integrate with the current draft: an additional example that was added by +P2242R3 +has also been deleted.

  • +
  • Polls CWG-12 and LWG-1: The wording from issue +LWG-3617 +has been integrated with the wording of, and guided by advice from, +P1169R4.

  • +
  • Poll LWG-2: Several minor changes were made to this long paper +P0009R18, +"mdspan": The expression sizeof...(OtherSizeTypes) was given the name N +in a few places to simplify the presentation; the phrase "for all rank index +r" was changed to "for every rank index r", notes have been reworded to +avoid the modal verb "may".

  • +
  • Polls LWG-8 and LWG-1: The macro ATOMIC_FLAG_INIT from +LWG-3659 +has also been marked "freestanding".

  • +
  • Poll LWG-14: Range formatting is also specified for the new "flat" +container adaptors, as requested by +P2286R8.

  • +
  • Poll LWG-29: Minor errors in +P2474R2 +("views::repeat") have been corrected.

  • +
  • Poll LWG-33: The changes have also been applied to new wording from +LWG-11.

  • +
  • Poll LWG-34: The changes have been integrated with the earlier changes +from LWG-12 +(P2165R4, +"Compatibility between tuple and tuple-like objects").

  • +
  • Polls LWG-14, -23, -33, -37: All four papers ask to update the +__cpp_lib_format feature test macro. This has since been discussed and found +unsatisfactory, but a resolution will only be applied editorially in the next +working draft.

  • +
+ +

Noteworthy editorial changes

+ +
    +
  • We introduced the new term "control-flow-limited statement" in [stmt.label] +to refer to a statement into which one cannot jump from the outside, which is +used for constexpr if, consteval if, and try and catch blocks.

  • +
  • Additional subclauses have been introduced where needed to ensure that there +is only one class synopsis along with its member specifications per subclause, +so as to not be ambiguous. Apart from modifying the current motions, this +affects [vector.bool].

  • +
  • Extraneous subclauses were removed, and their contents flattened, from the +erstwhile [expected.un.object].

  • +
  • Old wording for container adapters that used to say "other kinds of sequence +containers that the user defines" has been replaced with "other program-defined +sequence containers", since we now need this phrase in two places, and the term +"program-defined" was only introduced recently.

  • +
  • Further rewordings have been made to avoid the use of the "might" and "could" +modal verbs in notes.

  • +
+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4910 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 fb8135e5ec22acd26cb0dcb1bface21eee118895
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Mar 6 20:22:18 2022 +0800
+
+    [range.utility.conv.general] Add missing template parameter to container-inserter
+
+commit b7c1f9a77eac8dfeb4cb2e92bd3b2a57d05c298a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 25 09:37:42 2022 +0100
+
+    [spanbuf] Fix template name in subclause heading (#5365)
+
+commit cdca862605ae315e2d7a1ca7c7c1b011651944d2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 25 10:44:58 2022 +0100
+
+    [span.streams] Move non-member swaps to header synopsis (#5366)
+
+commit 478b8f8807e5b4561874842aa24a132558682f00
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Mar 31 19:34:03 2022 +0800
+
+    [alg.min.max] Consistently specify ranges::minmax_element with minmax_element_result (#5376)
+
+    LWG3180 was incompletely applied with commit e33be08f8ca49a9a139aa81b7a1ba9787d85f4fc.
+
+commit c92196bc67e252f06907c6de44173ce7157d71df
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Apr 1 13:38:03 2022 +0200
+
+    [memory.syn] Add missing closing bracket for attribute
+
+commit 1d2d223ab9fee202b67b31b32b85f44e3f9dc187
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Mar 24 02:13:51 2022 +0800
+
+    [range.adjacent.transform.iterator] Fix wrong template parameter in adjacent_transform_view::iterator
+
+commit 4813f202b3e2f6d0062967b9fd96ca54b91c7b65
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Mar 30 08:29:55 2022 +0200
+
+    [stacktrace.syn] Add '#include <compare>'
+
+    LWG3330 added #include <compare> to all header files
+    where a three-way comparison operator was declared,
+    but missed this one.
+
+commit d9040a775aa528f0576453532f3cb5058a6e6f24
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Apr 6 20:03:39 2022 +0800
+
+    [allocator.requirements.general] Specify all member types with typename (#5386)
+
+commit 2bfa7c4cc96203e03763816cf310e54e5b8940bb
+Author: Daniel Krügler <daniel.kruegler@gmail.com>
+Date:   Fri Apr 15 21:26:27 2022 +0200
+
+    [temp.constr.normal] Add missing semicolon in example (#5395)
+
+commit a8dbfc63227bf596dcf72a31c9fef4af8af9e592
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Apr 20 14:41:22 2022 +0100
+
+    [depr.tuple,depr.variant] Use struct class-key consistently (#5402)
+
+commit 4fc805d949bfc99ee6cfcf666123eb982fc4c465
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Apr 21 09:27:57 2022 +0200
+
+    [expr.prim.lambda.general] Clarify deduced lambda return type
+
+commit 5fb0fd092782f57e8395841470c92176412a10a3
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 24 09:29:07 2022 +0000
+
+    [expected.un.object.general] Reorder constructors in synopsis
+
+    This matches the order in [expected.un.ctor].
+
+commit 8e7a9b9fbf2f7a7dfa913a77068b6a6d3488e521
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 24 09:36:55 2022 +0000
+
+    [expected.un.object] Remove unnecessary subclause nesting
+
+    All the other class templates in <expected> are at the rSec3 level, but
+    std::unexpected is below a mostly useless rSec3 [expected.unexpected].
+    This subclause has two children, [expected.un.general] which is a single
+    sentence, and [expected.un.object] which defines the class template and
+    its members. If we merge the single sentence from [expected.un.general]
+    into the same subclause as the class synopsis then we can get remove the
+    unnecessary nesting. As a nice side effect, this also gets rid of
+    "object" in the [expected.un.object] stable name, which doesn't really
+    make sense in context.
+
+commit 3372ed0572fd8aa59ed9e59432cd8f593868be49
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Apr 25 13:24:24 2022 -0700
+
+    [range.utility.conv.general] Strike extraneous semicolon (#5414)
+
+commit 4b7deb009c4dfbbe8f2c879f764be446f94957b2
+Author: xmh0511 <970252187@qq.com>
+Date:   Tue Apr 26 04:26:19 2022 +0800
+
+    [lex.ccon] Fix typo in character name for U+0027 (#5412)
+
+commit 93de6031da2ef99b402e18ee8941fd6c7b554ce4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Apr 26 14:14:02 2022 +0200
+
+    [string.view.deduct] Move to immediately after [string.view.cons] (#5397)
+
+commit 41bc0c2ab38c32638685ef9a5068e06abbfc07f3
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Apr 26 20:16:26 2022 +0800
+
+    [expected] Add missing noexcept for expected::error() (#5381)
+
+commit b075835f134e4956fe27eaa5323655137aff3d45
+Author: Hui <65944694+huixie90@users.noreply.github.com>
+Date:   Tue Apr 26 18:56:30 2022 +0100
+
+    [iterator.concept.readable] Remove obsolete note (#5408)
+
+    The note was obsoleted by P1878R1.
+
+commit eed51157b2011478eb40254fbf191f2dd5fca7ca
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Tue May 3 15:26:39 2022 +0800
+
+    [expected.object.general] Remove explicit keyword for copy/move constructors (#5380)
+
+commit d23b318949c0a74c6f93f50afb1375ba9eb7aefd
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 4 00:50:55 2022 +0100
+
+    [stringbuf.virtuals] add "override" to setbuf
+
+commit fbe06e9076db0116e395e969f4cb921e45ae964a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 4 00:51:45 2022 +0100
+
+    [adjacent.difference] fix grammar typo
+
+commit bb8729f3cba593b963031bb25a1a4f12e12ad4fb
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 4 00:52:40 2022 +0100
+
+    [streambuf.virt.get] fix grammar typo
+
+commit 6fa045bf939eeff4dcea56e1a84ab7e1aac69f78
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 4 01:12:12 2022 +0100
+
+    [thread.lock.unique.cons] Use nullptr for null pointer constant
+
+commit f6791f7f9346c007921fec0b406a9edcbf667951
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 4 11:55:03 2022 +0200
+
+    [syncstream.osyncstream.cons] Fix use of parameter name (#5445)
+
+commit 74ad79739e2a13022bc6a33ff2e32efe59a47578
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 4 11:55:45 2022 +0200
+
+    [thread.sema.cnt] Add missing parentheses on function call expression (#5443)
+
+commit 8147026d04fe8fb44ed439cea950b5dab136c04c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 4 11:56:14 2022 +0200
+
+    [cons.slice] Add copy constructor for 'slice' to synopsis (#5444)
+
+commit fb379c19180d1e26b2b8146d547bcc84c59a0da5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed May 4 11:56:50 2022 +0200
+
+    [over.match.best.general] Fix typo in example (#5446)
+
+commit 81e506da21960bc70c271f775673a311ec957f6b
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed May 4 02:59:27 2022 -0700
+
+    [ranges.syn] remove trailing `-> see below` return type from three `to` overloads (#5419)
+
+    Since there is actually no return type specification to see below in [range.utility.conv].
+
+commit 11d886b5c6062ec7291469514eb07424811e4f65
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Tue Apr 26 17:39:39 2022 +0300
+
+    [class.access] Remove dangling Note
+
+    Invalidated by P1847R4
+
+commit 5032e88247bafb5c44dcd4d8ac2ffe3f8bff1bd9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Apr 23 22:15:46 2022 +0200
+
+    [associative] Add "i.e." in front of explanation
+
+commit 445d18255713e183df2819e565aa5faa7f85bb1d
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Apr 1 22:46:44 2022 +0800
+
+    [range.utility.conv.general] Add missing constexpr for container-inserter
+
+commit 64969e2057ef55b7ac3db8e23c37547edff5c8cf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 13:14:25 2022 +0200
+
+    [intro.memory] Fix missing semicolon in example
+
+commit dcf0f144f72e8116c59c188c5057a6ca8a7615d3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 13:35:33 2022 +0200
+
+    [intro.progress] Fix grammar typo
+
+commit 8c743eacc4b8609650d690b774f855507bd0846f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 13:41:54 2022 +0200
+
+    [expr.prim.lambda.general] Fix missing capture-default in example
+
+commit 359b8f41027c970bbbc63f1319a890adaa338f6f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 16:59:35 2022 +0200
+
+    [expr.await] Fix English grammar in string-literal in example
+
+commit 117b352d584cac601c22c63328355658271a6f17
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:05:50 2022 +0200
+
+    [expr.xor] Fix grammar typo
+
+commit 980aded4060cb408c053b0ee4620a71f3b6b73c6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:06:01 2022 +0200
+
+    [expr.or] Fix grammar typo
+
+commit edb43d00ec4f5e98d45c03408b5d0be6b0484c27
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:09:06 2022 +0200
+
+    [expr.yield] Fix typos in examples
+
+commit 451d8b95bd4c04bf89a5915eb973f837873c432b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:20:11 2022 +0200
+
+    [dcl.fct.default] Fix grammar typo in comment in example
+
+commit cd2690e9ace12f901acce1c1e9157f5cbbf06b24
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:21:32 2022 +0200
+
+    [dcl.init.aggr] Fix grammar typo in example
+
+commit cbc1a36376f32e9d31d5276ba44d8237d0632c37
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:24:29 2022 +0200
+
+    [dcl.fct.def.coroutine] Fix grammar typo
+
+commit d7be2ebee9dd3df849cf87bed768f9bb9f8684f8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:27:11 2022 +0200
+
+    [class.copy.ctor] Fix grammar typo
+
+commit 4284e8c31673912ae92bc210bb39aa4b05f0ed86
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:31:25 2022 +0200
+
+    [class.expl.init] Fix grammar typo
+
+commit 6c0d1411779d9e2c3e9a59d10b09605b6e5f1482
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 17:35:00 2022 +0200
+
+    [class.base.init] Fix grammar typo in note
+
+commit 40483ba8cff2165cd81dd75718559037af3ecaa8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 22:43:03 2022 +0200
+
+    [over.match.class.deduct] Fix syntax error in example
+
+commit 04cb8da6485b09592008c82eb330125fbf1034cd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu May 5 23:15:42 2022 +0200
+
+    [temp.decls.general] Fix missing comma
+
+commit e6633adbb2f3a6590cd75a000b377c8736c65094
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 6 00:17:50 2022 +0200
+
+    [temp.deduct.type] Fix grammar typo
+
+commit 1386c5b2cf41b713a12f526077eb578b68bacb9b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 6 00:19:23 2022 +0200
+
+    [temp.over] Fix grammar typos
+
+commit 21dc6d863a5acb0c3e5ec008bddb1c02b3dcd29a
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Thu May 19 11:23:47 2022 +0800
+
+    [range.join.view] Simplify range_reference_t<V> to InnerRng
+
+    I think this is a reasonable simplification and also makes it consistent with join_with_view.
+
+commit 2101d81b42bfcb7ab2227617a5ebe86e0b5733e8
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon May 23 04:39:15 2022 -0700
+
+    [expected.object.ctor] Use the injected-class-name to refer to the current instantiation (#5485)
+
+    ... as is conventional in library wording.
+
+commit 31be778d39b144fe867e24d80481786ad012661e
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun May 29 04:51:06 2022 +0800
+
+    [ranges] Remove redundant "exposition only" comments in \itemdecl (#5499)
+
+commit aff22aca63d0fb4b183cf073de8abfd4b9bb22bd
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Jun 10 00:24:11 2022 +0800
+
+    [range.istream.view] Add reference for basic_istream_view::iterator (#5514)
+
+commit 10a20b22491f1ff39a47847a68c9e4a648754d10
+Author: Mathias Stearn <redbeard0531@gmail.com>
+Date:   Thu Jun 9 18:52:42 2022 +0200
+
+    [res.on.functions] Use regular "behavior is undefined" words of power (#5513)
+
+commit 4bfa5ddf04586b6df76e0f44e4cde8b59f4a0401
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Jun 9 09:56:29 2022 -0700
+
+    [range.istream.iterator] basic_istream_view::iterator is not a class template (#5515)
+
+commit f73087971183d1daa992ad5165946609a77d39ff
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 12 16:18:19 2022 +0200
+
+    [func.wrap.move.ctor] Fix typo naming template parameter packs (#5517)
+
+commit 8d3f43888013437a2870877f00f017860b083df4
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Jun 11 17:34:09 2022 -0400
+
+    [range.adjacent.iterator] Use correct descriptive element
+
+commit d86e1ef9ef8514e570fdbbc5038f71e272dbb008
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Jun 12 03:11:07 2022 +0800
+
+    [ranges.syn] Fix the constraints order of slide_view
+
+commit c4a46fb7343c591f8844c2615ec25cfe8021656a
+Author: hewillk <67143766+hewillk@users.noreply.github.com>
+Date:   Sat May 21 20:39:59 2022 +0800
+
+    [move.iter.cons] Add missing Returns
+
+commit 45498df90fa8fa6ffb4de7341c65a2924de9879c
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Jun 16 04:57:27 2022 +0800
+
+    [range.join.with.sentinel] Add missing curly brace (#5530)
+
+commit d78d53f96d076f66a8af4ca7e71ae48e1d0596be
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 13:52:29 2022 +0200
+
+    [allocator.adaptor.syn] Fix typo in comment in header synopsis
+
+commit 01f16bc99a6a89e69b7a6ec5ae8bfe307ec5299a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 17:33:52 2022 +0200
+
+    [functional.syn,func.search.default] Fix name of template parameter
+
+commit 0678f9986b2c1f75e55d596f63876979433522d4
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 17:43:07 2022 +0200
+
+    [meta.rel] Add parentheses for consistency
+
+    Parentheses are used for is_pointer_interconvertible_base_of.
+
+commit c8a496c62d973305cd6eb5a23d80f169062335fc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 17:51:57 2022 +0200
+
+    [string.view.general] Add missing template-argument-list
+
+commit 70d07925ad874144f2dae4359f5a17c6cada1cdb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 17:55:30 2022 +0200
+
+    [forward.list.modifiers] Fix misspelled parameter name
+
+commit 66fd28de5c730a271bcf631f8452048c0e709232
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 17:56:48 2022 +0200
+
+    [set.cons] Fix grammar typo
+
+commit de6b0e70ffe2da0a0f91ce434863202f78c9e029
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 16 18:00:21 2022 +0200
+
+    [unord.map.overview] Fix presentation of member types
+
+commit 5be153e248d9e741c841ff3ab6c2e3714ecba24b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:14:19 2022 +0200
+
+    [unord.set.overview] Fix presentation of member types
+
+commit 633178f3fd48a784a96a6610f6b12c10700603c0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:15:22 2022 +0200
+
+    [unord.multiset.overview] Fix presentation of member types
+
+commit 5ae534c0c522cf661d3e94c58f54c7d37cf7905a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:18:34 2022 +0200
+
+    [random.access.iterators] Add semicolon at end of statement
+
+commit f60caf420b5210f0ad284999a1e471d50c424856
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:21:11 2022 +0200
+
+    [range.req.general] Fix grammar typo
+
+commit 75436ee3dd005cf13153ee05c9174a3a3df0054d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:32:31 2022 +0200
+
+    [range.take.view] Replace 'struct' with 'class' for consistency
+
+commit 8738cac27de2d66addf735f4fc2b370b73bb9ecc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:33:59 2022 +0200
+
+    [range.take.while.overview] Highlight use of ranges::begin
+
+commit 51cad172464c89cc14fff19d87d6bba6bc68f61d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:38:54 2022 +0200
+
+    [algorithms.requirements] Add commas for readability
+
+commit 5096e87c6c882ae2aff40c3558db7c2ec95ff4a8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:39:08 2022 +0200
+
+    [algorithms.requirements] Add hyphen for non-copied
+
+commit 63f3e4030497e43f39ff89ec0171f89a11dfc0a7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 17 08:41:53 2022 +0200
+
+    [alg.equal] Add missing period
+
+commit 736c755c70be70d5fb75e71f2c212c3c633ddc34
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Jun 23 14:26:40 2022 -0700
+
+    [priqueue.overview] Add misssing `>` to deduction guide (#5535)
+
+commit 3bf6ac52ddd619ae925d32ebb68a90a5bec0c115
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 24 15:50:30 2022 +0200
+
+    [class.prop] Clarify definition of implicit-lifetime class (#5319)
+
+commit 314fa9e2c16bcdaba33febddf2992b3e26c02212
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Jul 13 01:54:20 2022 +0800
+
+    [sequence.reqmts] Add ranges namespace qualifier for range concepts (#5563)
+
+commit 433b7af41ef02b8656c3153ab6ebb1c1c616f5b3
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Jul 13 23:40:21 2022 +0800
+
+    [range.take.overview] Fix punctuation (#5564)
+
+commit f6cb84439e8094ec7c67c708d1cc0ddef59262ec
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Jul 26 23:09:38 2022 +0800
+
+    [ranges.syn] Add \ref for `ref_view` (#5652)
+
+commit c816ae797e36daa466c287f3eff445aa87d8bfeb
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Jul 29 03:11:43 2022 +0800
+
+    [istreambuf.iterator.general] Add \ref for proxy (#5669)
+
+commit d59a4f3392fd1cf87af4ba128518fb4c00cbf77c
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Jul 29 03:13:33 2022 +0800
+
+    [algorithm.syn,bitset.syn,rand.synopsis,valarray.syn] Add \ref for header (#5666)
+
+commit 78b91e849b270423ec3296f7f95666078531e032
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sat Jul 30 05:13:40 2022 +0800
+
+    [range.join.with.overview,range.split.overview] use qualified name in examples (#5683)
+
+commit e24445344d26e3d9a3ad92b939b8c034daa47eb4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Aug 14 20:53:03 2022 +0100
+
+    [mdspan.*] Replace remaining "pointer"s with "data_handle_type".
+
+    These edits are part of LWG Motion 4 (P2604R0) but were accidentally omitted.
+
+commit 762480c9317759ffd6db76f7fef27744776e081d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Aug 17 11:41:51 2022 +0100
+
+    [ranges] Remove now-unused exposition-only "tuple-or-pair".
+
+    Also fix one missed replacement of "tuple-or-pair" with "tuple" as
+    instructed by LWG-Motion 12 (P2165R4, "tuple-like objects").
+
+commit b832e2702df41ebe79ddd9d159ac71e68e9b772a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Aug 14 22:26:15 2022 +0100
+
+    [container.reqmnts] Remove stray `{}`
+
+commit f09e7c5164d6dbc43e4a160aa4676725a83f488d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Aug 17 15:03:41 2022 +0100
+
+    [expr.spaceship, fs.path.generic, temp.inst] Use em-dash for parentheticals, not en-dash.
+
+    We are using em-dashes elsewhere already.
+
+commit 5dd17bf20e46a2964131ec208b6ed31cc659c400
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Aug 17 23:18:35 2022 +0100
+
+    [ranges] Add missing requirement on itemdecl, and fix spacing
+
+commit bb1145f751e2de491873aac5a42faf0a6931c218
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 12 12:03:55 2022 +0100
+
+    [mdspan.{overview,extents.ctor}] Increase reuse of definitions
+
+commit e97f917d3fd39d7fb2421105d8e45cb73bd24a1e
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Thu Aug 18 18:42:15 2022 +0200
+
+    [range.zip.transform.view] Fix typo: mmove_constructible.
+
+commit f440cfa4e3ebf139b5acec3735e90d4acf5785e6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 18 15:25:55 2022 +0100
+
+    [ranges.syn] Add missing "freestanding" comment for as_rvalue.
+
+commit 999005ab72ca0078b3361979584007dd9d991fac
+Author: Yihe Li <winmikedows@hotmail.com>
+Date:   Fri Aug 5 08:49:10 2022 +0800
+
+    [strings.general] Add <string> header to "String classes" row
+
+commit 1fbf5f8b683802849cfc8bb57fef3f48a61bd242
+Author: Yihe Li <winmikedows@hotmail.com>
+Date:   Fri Aug 5 08:49:40 2022 +0800
+
+    [thread.general] Remove non-existent header
+
+commit 0d7d1d70641a773f67b08f4de44e53f00e3b352d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 24 15:40:43 2022 +0200
+
+    [temp.inst] Clarify referent of 'declaration'
+
+commit 99bc532e3c9440defd761985d2329da064b7f9f9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 23 23:17:13 2022 +0200
+
+    [module.private.frag] Remove misleading example and broaden note
+
+commit 596137c054407d4d5f2ccf327bd5d3e2a8b4fef5
+Author: A. Jiang <de34@live.cn>
+Date:   Tue May 17 09:49:27 2022 +0800
+
+    [mem.poly.allocator.class.general] Clarify polymorphic_allocator<void> etc.
+
+commit 193cfc17cbb73e7e6c65d1e596ef9c1a035c7811
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Nov 5 19:58:41 2021 +0100
+
+    [diff.dcl] Discuss 'alignas' placement restrictions
+
+commit 8b2d70502c379b96ddb9d6eb97d5aafcc1d4765c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Nov 5 20:00:00 2021 +0100
+
+    [diff.dcl] Remove 'implicit int' discussion
+
+    C99 has removed implicit int.
+
+commit f91c425a8fe6f0dd826bd399a5bc82796aec8180
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Mar 4 21:20:21 2022 +0100
+
+    [diff.expr] Remove 'implicit function declaration' discussion
+
+    C99 has removed implicit function declarations.
+
+commit b208eb4da5a97cf800f2822318fd487f332d82ad
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 06:22:04 2019 +0000
+
+    [meta.trans.other] Use "denotes" in decay, enable_if and conditional
+
+commit 769e15bd0559a8ff572d2c508f2cce0227229a39
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:04:02 2019 +0000
+
+    [meta.unary.prop.query] Use "is an array type" not "names an array type"
+
+commit 3d010460fc4159b6f99d430a3cf0eb0ff30d0053
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:05:09 2019 +0000
+
+    [meta.trans.ref] Use "is a referenceable type" and "denotes the type"
+
+commit 66cb97967adb501ff352b6e69815b4db10e095bf
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:06:14 2019 +0000
+
+    [meta.trans.sign] Use "is a ... type" and "denotes the type"
+
+commit 485192fb3872c1da42d6cc0ff89230ecb7760c9c
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:06:46 2019 +0000
+
+    [meta.trans.arr] Use "is a type" not "names a type"
+
+    Also use "denotes" instead of "names" for member typedefs.
+
+commit e2d032255ad0f346144659ba43d3eb184163c8bb
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:07:15 2019 +0000
+
+    [meta.trans.ptr] Use "is a referenceable type" not "names ..."
+
+commit 2c9482a15375291528e8742dc7972450c9597d96
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:09:00 2019 +0000
+
+    [meta.trans.other] Use "denotes"
+
+commit c51087e82583b589481f03d4dad2190a569ce857
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Feb 22 07:16:14 2019 +0000
+
+    [meta.trans.cv] use "denotes" in specification of member typedefs
+
+commit 935ec9e8f13d41bc09f8a27a917008ddf2724a29
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Apr 23 10:33:16 2019 +0100
+
+    [refwrap.unwrapref] Use "denotes" for member typedef
+
+commit e412ba9b687e4cdd8ed7546b3ec44122b6baabc5
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Apr 22 18:20:59 2022 +0100
+
+    [depr.meta.types] use "denotes" for member typedefs
+
+commit 887c0330bdd2e4b504854a5c9d34621e5d10a3d2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Nov 27 21:27:28 2018 +0100
+
+    [cmp.categories] Replace 'operator admits' phrasing.
+
+commit 1e3e4180ee26e06abe6eeb648537b36baa92c5b7
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Aug 19 01:33:25 2022 +0800
+
+    [range.as.const.view] Add missing angle bracket (#5745)
+
+commit d732538953bab8ccdbe4388cfb39b8542a01dc65
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Thu Jul 21 10:09:09 2022 -0400
+
+    [map.cons,multimap.cons,multiset.cons,set.cons,associative.reqmts.general] "sorted with respect to `comp`"
+
+    https://cplusplus.github.io/LWG/issue3713
+    LWG3713 points out that we temporarily lost the term of art
+    "sorted with respect to `comp`," and brings back a definition
+    for it. However, several places in the existing draft never
+    actually used that term of art in the first place. Fix them
+    up so that they do.
+
+commit 4db1d62426ef9a9cd8689585d43da38dd3731696
+Author: A. Jiang <de34@live.cn>
+Date:   Fri Aug 19 01:36:40 2022 +0800
+
+    [allocator.requirements.general] Use newer style for SimpleAllocator
+
+commit a458849089b29e3dfc5f9736799c1c6403223f8f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 12 16:11:08 2022 +0200
+
+    [thread.lock.unique.locking] Fix function call expressions
+
+commit dd4ecf3d19bf8a04899324fc72c690880a328a64
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 13 21:51:13 2022 +0200
+
+    [stacktrace.basic.nonmem] Add missing \pnum before \recommended
+
+    Also augment check script
+
+commit fe24762404f5ac7bbd6f139a44dbfa42663ec796
+Author: Barry Revzin <barry.revzin@gmail.com>
+Date:   Thu Aug 18 16:03:10 2022 -0500
+
+    [stmt.pre] List "compound-statement" explicitly as part of a selection statement
+
+    This clarifies the substatements of `if consteval` (which has a compound-statement).
+
+commit 2940703c7ee125ce8194f668683ff5b0bbd7791b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jan 2 21:46:02 2022 +0100
+
+    [core] Replace 'enumerated type' with 'enumeration'
+
+    The term "enumerated type" is defined in [enumerated.types]
+    for use in the standard library, and is not synonymous with
+    "enumeration type".
+
+commit a27e5a6ac3a0fc9cb8474b87b92734a923d495c0
+Author: Hubert Tong <hubert-reinterpretcast@users.noreply.github.com>
+Date:   Fri Aug 19 10:36:20 2022 -0400
+
+    [stmt.label, except.pre] Use new wording "control-flow-limited" statement (#5413)
+
+    A new term of art (control-flow-limited statement) is introduced in [stmt.label]
+    to express the restrictions on control flow into a statement (namely jumping to labels).
+    Both [stmt.if] and [except.pre] are updated to use the new term.
+
+    This rewords "shall not be used to" avoiding question of actual "use": the "shall not be
+    used to" phrasing may be taken to refer only in cases where the actual use occurs
+    or is the primary intent. Instead, the intended restriction can be written in terms
+    of static properties of the constructs so restricted in the style of [stmt.if].
+
+commit 5aa000973bba1ce10ce0f4ca6a3bec61bcea2061
+Author: Jason Merrill <jason@redhat.com>
+Date:   Fri Aug 19 10:47:42 2022 -0400
+
+    [lex.charset] Add missing hyphens
+
+    In P2071R2 and NameAliases.txt, 0+008E is named SINGLE-SHIFT-2, but it went
+    into the draft as "single shift-2", losing the hyphen between the words.
+
+commit 8275c19b3fa9e7cb09f84049ebd6207aceb7ca80
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 19 17:29:40 2022 +0100
+
+    [range.cartesian.view] Fix definition of cartesian-product-is-common
+
+    The original wording seems to have been a copy-paste error.
+
+commit 4117a1fc1aeb307d6b15c8aba8a54925fb1b4faf
+Author: Mark de Wever <koraq@xs4all.nl>
+Date:   Fri Aug 19 18:37:58 2022 +0200
+
+    [format.string.escaped] Fix invalid examples
+
+    While implementing new features introduced by P2286R8 Formatting Ranges
+    I noticed some issues in the examples. These issues are in the paper
+    too.
+
+    For s3 the alternative would be to adjust the output instead of the
+    input.
+
+commit 2d548b2ec835510685cf2fcb175f7645aa798d72
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 19 09:35:25 2022 +0100
+
+    [dcl.fct.def.default] Elaborate on the difference of two declarations
+
+    This makes it clear that T_1 and T_2 may differ because of the present
+    rule for the purposes of the blanket statement "other than as allowed
+    by the preceding rules" futher below.
+
+commit d2ad0017c5584825fce1cbf741c160e4bd6108b3
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Aug 21 01:22:25 2022 +0800
+
+    [range.chunk.overview,range.slide.overview] Use maths, not code style for N/M (#5500)
+
+commit 1277923e3ac7a35a3713823b5782b57b86f956ed
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Aug 21 01:35:35 2022 +0800
+
+    [range.chunk] Fix subclause headings (#5516)
+
+commit 2f228c5cad223a5c8d686d91b054ee3bd2d2a123
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Aug 21 05:01:17 2022 +0800
+
+    [range.as.rvalue.view] Fix accidentally swapped concepts in template head
+
+    Also fixes the whitespace style around the opening brace.
+
+commit 22133b42b1a20d542a8f4d18cc425e8c875e567b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Aug 20 22:04:26 2022 +0100
+
+    [complex.members] Remove stray "template<class T>" from constructor
+
+    This peculiar presentation had previously worked in conjuction with
+    a subclause on "explicit specializations", but since those explicit
+    specializations have been removed by P1467R9, the template head does
+    not serve any useful purpose any longer.
+
+commit fee56834fb55355d617a88fe764f9fb20d92c329
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Aug 20 22:35:28 2022 +0100
+
+    [expr.prim.lambda.capture] Add cross reference to [basic.scope.lambda]
+
+    Suggested by CD review feedback.
+
+commit 6f70f82eead9ddc10830aedb99286d0db54725ad
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Aug 22 02:11:57 2022 +0800
+
+    [range.repeat.view] Fix typo (#5765)
+
+commit 89df45a30a48f30d2ab367490b47c2c0a87f4aa6
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Aug 22 01:51:41 2022 +0800
+
+    [ranges.cartesian.iterator] Fix typo
+
+commit 35aa22acdf080fc5886d715a965aadd36de28c27
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Aug 21 01:55:27 2022 +0100
+
+    [expr.prim.id.unqual] Fix parameter name in example ("y", not "z")
+
+    The misspelling was a misapplication of the motion paper P2579R0.
+
+    Also harmonize the local use of whitespace.
+
+commit 2841712fc15f831481d7bd39e084c213596ccfec
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Aug 20 23:49:21 2022 +0100
+
+    [vector.syn, vector.bool] Add subclause structure.
+
+    After the addition of the formatting-related specialization, the
+    original subclause contained several class template synopses without
+    any intervening separation. The header synopsis is rearranged to
+    follow the document order.
+
+commit 259b8d5d1beeaccf793783679ff4956e84774ea4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:03:46 2022 +0100
+
+    [alg.sorting.general] Make "comp" part of the defined term
+
+    Suggested by CD review feedback.
+
+commit c2aee77b6413fe8ce09bf816d1e239fa2b93f4a9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:14:49 2022 +0100
+
+    [mdspan.overview] Extend the definition to "size of a MD index space"
+
+    Previously, only "size" was the defined term, but P0009R18 asks for
+    the entire phrase to be the defined term.
+
+    Suggested by CD review feedback.
+
+commit ac27094ee2f367faf32a37008f476d57b19fd999
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:29:15 2022 +0100
+
+    [mdspan.extents.expo] Add "exposition-only" comments to itemdecls
+
+    Suggested by CD review feedback.
+
+commit cce4e845272506ad2e0d732d78bce1dcfd02b7c7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:34:32 2022 +0100
+
+    [mdspan.extents.ctor] Consistently use "r" as a maths variable, not code.
+
+    Suggested by CD review feedback.
+
+commit a284ab6c16f387f95adb85e02ad9c07cf36b08a3
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:43:14 2022 +0100
+
+    [mdspan.layout.{reqmts,right.ctor}] Consistently use maths, not code
+
+    Suggested by CD review feedback.
+
+commit 62d024620d93fc08611ce9e931fef95c9e064d03
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:52:22 2022 +0100
+
+    [mdspan.accessor.reqmts] Replace "pointer" with "data_handle_type".
+
+    This edit was part of LWG Motion 4 (P2604R0) but was accidentally omitted.
+
+commit 9369f4c7f116244193c7c2ed12ecc4a625790776
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 00:56:57 2022 +0100
+
+    [mdspan.layout.stride.expo] Replace "SizeType" with "IndexType".
+
+    This edit was part of LWG Motion 3 (P2599R2) but was accidentally omitted.
+
+commit fd7c919c681630425a48fd01b4c36c631c910303
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 01:01:14 2022 +0100
+
+    [mdspan.layout.stride.{ctor,obs}] Add cross references to [mdspan.layout.policy.reqmts]
+
+    Suggested by CD review feedback.
+
+commit d0c287b45c5b7ec1d5cfffed2eeeed2e2682ed3b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 09:59:57 2022 +0100
+
+    [flat.multi*] Fix typo ("mutli" => "multi")
+
+commit 06cbf011ea876313132b51f3699b23f942f91123
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 10:13:01 2022 +0100
+
+    [containers] Add cross references to "erasure" subclauses
+
+    In associative containers, the comment in the synopsis is augmented
+    with the name of the class template, since each header contains two
+    class templates (unique and multi).
+
+    Also fixes some index entry spellings.
+
+commit 3b1461021cb81fbbccd27494ecd60de7daf958b8
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Aug 22 17:56:54 2022 +0800
+
+    [range.adaptor.tuple] Fix tuple helper parameter name clash (#5769)
+
+    The code as presented originally was ill-formed.
+
+commit 90c2cfb1fb8e5cb4781a2d8affdc8856279ca09a
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Aug 22 09:32:17 2022 +0800
+
+    [range.repeat.iterator] repeat_view::iterator is not a class template
+
+commit 4762e1b6fa3bcaf4fdc080e2160ab4e9e96f77b6
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Aug 22 15:32:10 2022 +0800
+
+    Fix preconditions for start_lifetime_as_array(p, n)
+
+    "n > 0 is true" can't be in "Mandates:", and it's in "Preconditions:" according to P2590R2.
+
+commit 28f49c965a394c573fa927792f082a182d422029
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Aug 22 19:29:40 2022 +0800
+
+    [range.as.const.view] Fix order of constraints in class synopsis (#5760)
+
+    The header and the class synopses used different orderings in P2446R0,
+    and the ordering from the header synopsis is the desired one.
+
+commit 03d73772246ec6e9fa0becb983be6dc08189d8b1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 12:23:51 2022 +0100
+
+    [flat.*] Harmonize wording "supports the ... operations but not ..."
+
+commit 9934675dd673bfa8e073bd3c2187575b47e6ea44
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 13:48:45 2022 +0100
+
+    [flat.set.defn] Fix name of function parameter ("rg", not "range")
+
+commit faa173c296bfc3547e6f20af63329ac0e1a024be
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 14:06:39 2022 +0100
+
+    [flat.multiset.ctor] Add missing parameter name "cont"
+
+commit 96fce7b5259e1bfe1688cc60df2d6b2ecf3e7cd1
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 11:49:41 2022 +0100
+
+    [flat.*.{syn,erasure}] Change return type of erase_if to member size_type
+
+    All other containers and container adapters use the member size_type,
+    and the flat maps already did so in the item specification, but not in
+    the synopsis.
+
+    The current wording follows the approved proposals, but this change
+    seems like an improvement.
+
+    Suggested by CD review feedback.
+
+commit 7f11031bf6e41515a8779bdbfe741f4f9bbdfccc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Aug 20 21:14:55 2022 +0100
+
+    [diff] Uniform style for examples
+
+    For C++ differences, examples are always preceded by the phrase "For
+    example:", do not use the usual [Example n: ... -- end example] style,
+    and always appear in the "Effects on original feature" paragraph.
+
+    For differences with C, a different set of styles is used (examples
+    being part of paragraphs such as "Change" and "Rationale"), and that
+    subclause remains unchanged by this commit.
+
+commit d4280f38ddd489aecd8fb0da17a41f577db42e2a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Aug 20 23:11:39 2022 +0100
+
+    [memory.syn] Add missing "// freestanding" comment to "destroy"
+
+    The comment was supposed to be added by P1642R11, but was accidentally
+    omitted.
+
+commit 47b0e73cc1e8d2ea344afedf60e07ec80df118f4
+Author: mordante <koraq@xs4all.nl>
+Date:   Mon Aug 22 17:48:36 2022 +0200
+
+    [format.string.std] Reorder std-format-spec field descriptions. (#5246)
+
+    Moves the wording describing the zero-padding before the description of
+    the width; matching the order of the fields in the std-format-spec.
+
+    The original order was introduced in the initial <format> paper P0645R10 "Text Formatting".
+    Since both fields had one paragraph of description, it wasn't too noticeable. P1868R2 "🦄 width:
+    clarifying units of width and precision in std::format" expanded the wording of the width.
+    Now it's not so easy to find the description of the zero-padding field.
+
+commit 517290b26fa8391d3b77d43ca8c271bb92695db7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 17:06:34 2022 +0100
+
+    [range.cartesian.view] Further fixing of cartesian-product-is-common
+
+    The first fix in 8275c19b3fa9e7cb09f84049ebd6207aceb7ca80 was
+    incorrect. Only Const needs to be dropped (which was an error
+    in the paper), but ignoring Vs... is intentional.
+
+commit 101e7205882495cec1a944c7f6190b08bd131543
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Aug 22 17:23:46 2022 +0100
+
+    [ranges] Add missing closing delimiters
+
+commit 17be256d2431f66842479bf7ab2e92f30fff3060
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 21:39:06 2022 +0200
+
+    [alg.partitions] Indicate base of logarithm outside big-oh notation
+
+commit c6e83c4dba380b235be59b21db6c54bdffcb997d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 21:39:59 2022 +0200
+
+    [set.difference] Fix grammar typo
+
+commit 68e365415c707038f8af6c76f0f6f4cd3a4ce407
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 21:44:05 2022 +0200
+
+    [uninitialized.move] Fix typos in parameter names
+
+commit c3c6761111cff26e0e742e4d14b5d9e0bd28c4aa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 22:53:51 2022 +0200
+
+    [rand.adapt.disc] Remove superfluous trailing semicolon
+
+commit 65c9e5bcb3068a1172a66a7507d26a93adae7981
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 22:55:17 2022 +0200
+
+    [rand.adapt.ibits] Remove superfluous trailing semicolon
+
+commit 6ede23707505a18cdbb558108d635a0b21a1eeb0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 22:55:47 2022 +0200
+
+    [rand.adapt.shuf] Remove superfluous trailing semicolon
+
+commit 5e44bc70b72b64e03e0d09564b2eaf45938a7752
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 18 22:58:11 2022 +0200
+
+    [valarray.members] Fix bad reference to argument
+
+commit 43b2bce231b04c1ccf7dc4bfd20e13f29c0e9c6c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:29:54 2022 +0200
+
+    [time.duration.io] Fix grammar typo
+
+commit 6e9b678f03a1a4fa8218152596a1952c209d1f27
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:32:40 2022 +0200
+
+    [time.cal.year.members] Fix erroneous qualified-id
+
+commit f0ab64a1dcb5bac1249ff67e838a7f899efeb586
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:39:48 2022 +0200
+
+    [locale.codecvt.general] Remove extra space before template-argument-list
+
+commit bbb7552af35266accf98ae718912579527ee11b8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:41:58 2022 +0200
+
+    [locale.collate.general] Fix grammar typo
+
+commit 324dfd448ec5b632fc922015414cd206920b5842
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:45:29 2022 +0200
+
+    [ios.base.storage] Fix grammar typo
+
+commit fc53c9ede41d4992dc64f556bc32febb28ad0e1e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:45:58 2022 +0200
+
+    [fpos] Fix typo in exposition-only member
+
+commit 47273ceb655716f62fc1c9fe00a317b44c221267
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:47:05 2022 +0200
+
+    [fpos.operations] Fix name of type trait
+
+commit 04d7e61e9deaf2481d144e2c0a7d2478cff58764
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 19 21:49:00 2022 +0200
+
+    [streambuf.cons] Fix grammar typo
+
+commit f055ba09397bd479317a92c315e5a074f7c2e474
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Apr 17 11:19:04 2022 +0200
+
+    [atomics.syn] Move namespace-scope memory_order_* variables here
+
+commit f400d80927fd580f99f5f2d94c3d07eaa47373d0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Apr 17 11:23:54 2022 +0200
+
+    [ranges.syn] Move namespace-scope declarations for get(subrange) here
+
+commit e9434db227e8b3113a477dcdd0c6c14ffe2c14b8
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 18:56:41 2022 +0100
+
+    [tuple.creation] Add missing semi-colon to example
+
+commit 25bb0a278e8141613f2c813c50a74428e3da7b8b
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 18:58:39 2022 +0100
+
+    [util.smartptr.shared.obs], [util.smartptr.shared.create] use nullptr for null pointer constant
+
+commit 7a4324c21e4f66af801bc7e7fc78b94119253301
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 21:52:22 2022 +0100
+
+    [char.traits.require] use nullptr for null pointer constant
+
+commit b3b64b35ce456a7e54476b9a00185323b68fcd6d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:01:22 2022 +0100
+
+    [unord.req.general] Use "constant" not "const"
+
+commit a421a3029418651b9734ae786c9b89b72b08b42d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:09:00 2022 +0100
+
+    [unord.multimap.overview] Fix presentation of member types
+
+    As already done in de6b0e70ffe2da0a0f91ce434863202f78c9e029 for unordered_map.
+
+commit a758844278a818fd8ccbd33a6ca0460b31616d74
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:33:04 2022 +0100
+
+    [range.elements.view] fix class-key for iterator and sentinel
+
+commit 44b146eda750e453ee3d52587c2accab4be6c74d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:35:18 2022 +0100
+
+    [range.elements.iterator] remove stray semi-colon
+
+commit 3a51f3e858e14abc0623f8823e0d2c883c27a4e4
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:45:30 2022 +0100
+
+    [complex.ops] use character literal for single character
+
+commit 678907e6d8af62cab9429b7065be69c36ffa2592
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:46:43 2022 +0100
+
+    [rand.req.dist] fix grammar typo
+
+commit 698be9d6b09517dc1323ca99fc4bb84ec62fae9e
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 22:56:42 2022 +0100
+
+    [cons.slice], [gslice.cons] remove undeclared/undocumented copy constructor signatures
+
+commit 1cda1f9d2ac5d8caa81e793ce3f95364aba1fb6b
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Aug 22 23:01:23 2022 +0100
+
+    [template.mask.array.overview], [template.indirect.array.overview] fix itemdecl typos
+
+commit f3ddcf79a971f488b3acf0e52ca6ea9689af7fd7
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Aug 23 19:58:08 2022 +0800
+
+    [ranges.cartesian.iterator] Fix typo "reference_t" => "range_reference_t" (#5777)
+
+commit 227c3b249f0f52484920400b861717649895e6cc
+Author: cor3ntin <corentinjabot@gmail.com>
+Date:   Tue Aug 23 14:00:44 2022 +0200
+
+    [range.adjacent.overview] Use tuple in example, not pair (#5779)
+
+    adjacent_view always yields tuples, but the example was written as if it yielded a std::pair.
+
+commit c0c0d75402b1dc33f0cba971c898dc2ac7bfaa06
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Aug 23 20:00:49 2022 +0800
+
+    [range.cartesian.view] Add missing angle brackets for cartesian-is-sized-sentinel
+
+commit c777f930668fe23ab287ff765463d3b3731696eb
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Aug 23 21:45:23 2022 +0800
+
+    [range.zip, ranges.cartesian.iterator] Simplify `maybe-const<true, Views>` to `const Views` (#5778)
+
+    The type `maybe-const<Const, Views>` only appears after `Const &&`
+    in these cases, so that only the case where `Const` is `true` matters.
+
+commit eca39f43798d7a58fdd482232c60b6db428b656f
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Aug 24 01:57:58 2022 +0800
+
+    [tuple.syn, tuple.like] Fix template head formatting (#5784)
+
+commit 356fb7ff88b63d956b1109c72c5e3bf424f6ba29
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Aug 24 01:58:17 2022 +0800
+
+    [algorithm.syn] Fix template head formatting (#5786)
+
+commit 6ccb959c7a8c10fc5fa7dd469c64f3c992e7e7ee
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Aug 23 20:10:44 2022 +0800
+
+    [range.zip.overview] Use tuple in example, not pair
+
+commit 8404284d8b7ac6ff2725a33d5e33410d1ea3b470
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Aug 23 23:10:39 2022 +0800
+
+    [range.drop.overview, range.take.overview] Fixed unformatted (void)F, decay-copy(E)
+
+commit 6e2b23594abd64c9ba50934654c68bd174c7ab91
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Aug 24 18:49:21 2022 +0800
+
+    [format.range.fmtstr] Add ranges namespace qualifier (#5788)
+
+    The range concept is named outside of the `ranges` namespace.
+
+commit 301f0cdcb547f54b1d39163550a5869a0c6b073f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 02:28:09 2022 +0100
+
+    [coroutine.syn] Move "all freestanding" comment to the top
+
+commit e38650de03741a87d6c625ce93974946f46f5caa
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 02:41:49 2022 +0100
+
+    [tuple.like] Remove extraneous "std::" qualification.
+
+commit 3da6b0e8798681144b676b3b4180301f8f7c8f2c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 10:55:25 2022 +0100
+
+    [const.iterators.{alias,iterators}] Add "exposition only" comments
+
+    Suggested by CD review feedback.
+
+commit 5dd0216a477391fbce339e22f169136420472979
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 11:12:24 2022 +0100
+
+    [range.refinements] Fix template argument name ("T", not "R")
+
+commit 347ded018d09d2a226e3ab42665d1a13b25d489a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 11:27:38 2022 +0100
+
+    [vector.bool.pspc] Reinstate redundant "inline", as per paper
+
+    The "inline" was removed editorially in
+    2141dab25c7f6d186d662e0ebe916efcd56843ae, but CD review has requested
+    we retain it.
+
+commit 79ab62930d2538e1ef668c6a1b50e8d7027ebedc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Aug 25 11:34:57 2022 +0100
+
+    [format.string.escaped] Fix typos in "APOSTROPHE"
+
+commit 426ce8a7ec2232aebaaf76bf2f5e4a69a500cef6
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Aug 25 19:31:57 2022 +0800
+
+    [ranges] Tweak some examples (#5791)
+
+    Removes redundant `std::` qualifications and uses `views::meow` instead of `meow_view`.
+
+commit 4ed7fcf6b725207ac307a6d1411ad2aa4ed55c8f
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Aug 26 04:36:08 2022 +0800
+
+    [containers] Add `std::` for `forward`/`move` (#5793)
+
+commit aec46d1970a8869db0d178c436545b0e40968425
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Aug 26 04:43:03 2022 +0800
+
+    [move.sentinel] Remove extraneous "std" qualification in example (#5792)
+
+commit ed18148b1d514c0aea12d99b1ec3a56d4a834266
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Aug 26 15:00:12 2022 +0800
+
+    [util.smartptr.shared.create] Add std:: qualification for forward
+
+commit eb703517cd6c79f56df12c5dca359121efbef4ee
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 26 14:39:39 2022 +0100
+
+    [range.move.wrap] Fix constraint (move, not copy-constructible)
+
+    This was accidentally omitted from previous changes requested by P2494R2.
+
+commit 2a600822d08332a8350e3a093212bdc7f8a82e2b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 26 15:06:06 2022 +0100
+
+    [format.range.fmtdef] Add "exposition only" comments
+
+commit 9d71b7d3b0aac1f179fc3973b0ff1624b00b07ce
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 26 15:26:39 2022 +0100
+
+    [obj.lifetime] Add cross-reference pointing at basic.types.general
+
+    Suggested by CD review feedback.
+
+commit 9eb92bf36b19381a534273ad98e296dfeb7a0fc9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Aug 29 22:45:41 2022 +0200
+
+    [flat.set.modifiers] Remove stray 'return' in Effects clause
+
+commit 69177109f387d3958ffea237c9b0419e4d2aa49c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Sep 2 23:44:14 2022 +0100
+
+    [expr.ass] Fix typo, "~" should be "^".
+
+    This was a misapplication of P2327R1 in 0aebf5cacded1b64cf089dbc7a0504fbb9f50aa6.
+
+commit e6e17d5e136934f113d6e0a8bde4c227459a9d47
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Sep 3 02:10:27 2022 +0100
+
+    [diff.cpp20.{dcl,expr}] Fix subclause order to match main document
+
+commit 853747c5d8130880b96a39ab940c343aa7530d71
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Sep 3 15:02:00 2022 +0100
+
+    [basic.fundamental] Use correct number; "are", not "is".
+
+commit 07e02a80fe890dcb6e84182a5697046f1bd4c630
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Aug 29 22:23:54 2022 +0200
+
+    [expected.object.assign] Add missing 'Returns: *this'
+
+commit 06dcf0556631382ecdc420c22c66366168c226b4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:01:12 2022 +0100
+
+    [mdspan.layout.left.overview] Reorder "explicit" and "constexpr"
+
+    The standard ordering is "constexpr explicit", not the other way
+    round. The paper P0009R18 contains a non-standard style, and other
+    instances had already been fixed. Only this one seems to have been
+    missed previously.
+
+commit e651f145df7c587ea810aca754e680bb27ea8481
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:08:42 2022 +0100
+
+    [mdspan.layout.{left,right}.overview] Replace "see below" with condition
+
+    The condition is spelled out in the item descriptions already, and the
+    class synopses seem to simply have been inconsistent with that in the
+    incoming paper P0009R18. Since the "see below"s are never referenced
+    explicitly, we just replace them with the actual conditions, which is
+    also how the surrounding members are presented.
+
+commit 1765844a9382e1f3415bbbdcd12eaa09a6b1f827
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:25:52 2022 +0100
+
+    [mdspan.layout.stride.expo] Move "otherwise" from trailing to leading
+
+    We have a mild preference for the leading position.
+
+commit c02512ecf3f15fb0f29dc602eb153bc7dabd643d
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:53:01 2022 +0100
+
+    [mdspan.layout.stride.obs] Add missing parentheses
+
+commit 9897c566ec3ecd6f25078a3dd10ce34c17e812e7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:54:19 2022 +0100
+
+    [mdspan.accessor.default.members] Fix typo in "equivalent"
+
+commit 3b6163d1a3b1f5cc2be49d6ff0eb6b3889b552df
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 13:58:09 2022 +0100
+
+    [flat.map.syn] Add missing "namespace std {"
+
+commit c164add6cdac73cae85649ba2172de43c3d8ed5b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 14:02:11 2022 +0100
+
+    [flat.map.modifiers] Typo: "range" should be "rg"
+
+commit 1b427b20fecbc95b98d2380e0ddae71b71c1f657
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Sep 4 14:06:53 2022 +0100
+
+    [flat.{,multi}set.ctor] Add missing "explicit" in itemdecls
+
+commit 8f153df9c66c33f100ec7a4d7998dfaf6a7aa8da
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 26 02:43:37 2020 +0000
+
+    [basic, except, diff] Rewordings to avoid "might" and "could"
+
+ + diff --git a/papers/n4918.md b/papers/n4918.md new file mode 100644 index 0000000000..550414f120 --- /dev/null +++ b/papers/n4918.md @@ -0,0 +1,1874 @@ +# N4918 Editors' Report -- Programming Languages -- C++ + +Date: 2022-09-06 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes, and special thanks to +Johel Ernesto Guerrero Peña for providing in-depth review of most of the draft +motion applications, and to Hewill Kang for spotting and sending corrections for +many editorial issues. + +## New papers + + * [N4917](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4917.pdf) is the + current working draft for C++23. It replaces + [N4910](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf). + * N4918 is this Editors' Report. + * N4919 is the C++23 Committee Draft. + +## Motions incorporated into working draft + +### Core working group polls + +CWG poll 1: Accept as Defect Reports all issues except 2507 and 2586 in +[P2622R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2622r0.html) +(Core Language Working Group "ready" Issues for the July, 2022 meeting) and +apply their proposed resolutions to the C++ Working Paper. + +CWG poll 2: Apply the proposed resolution of issues 2507 and 2586 in +[P2622R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2622r0.html) +(Core Language Working Group "ready" Issues for the July, 2022 meeting) to the +C++ Working Paper. + +CWG poll 3: Accept as a Defect Report and apply the changes in +[P2468R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2468r2.html) +(The Equality Operator You Are Looking For) to the C++ Working Paper. + +CWG poll 4: Accept as a Defect Report and apply the changes in +[P2327R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2327r1.pdf) +(De-deprecating volatile compound operations) to the C++ Working Paper. + +CWG poll 5: Apply the changes in +[P2437R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2437r1.pdf) +(Support for `#warning`) to the C++ Working Paper. + +CWG poll 6: Apply the changes in +[P2362R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2362r3.pdf) +(Remove non-encodable wide character literals and multicharacter wide character +literals) to the C++ Working Paper. + +CWG poll 7: Apply the changes in +[P2324R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2324r2.pdf) +(Labels at the end of compound statements (C compatibility)) to the C++ Working +Paper. + +CWG poll 8: Apply the changes in +[P2290R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2290r3.pdf) +(Delimited escape sequences) to the C++ Working Paper. + +CWG poll 9: Apply the changes in +[P2448R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2448r2.html) +(Relaxing some `constexpr` restrictions) to the C++ Working Paper. + +CWG poll 10: Apply the changes in +[P2266R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2266r3.html) +(Simpler implicit move) to the C++ Working Paper. + +CWG poll 11: Apply the changes in +[P2071R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2071r2.html) +(Named universal character escapes) to the C++ Working Paper. + +CWG poll 12: Apply the changes in +[P1169R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1169r4.html) +(static `operator()`) to the C++ Working Paper. + +CWG poll 13: Accept as a Defect Report and apply the changes in +[P2280R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2280r4.html) +(Using unknown pointers and references in constant expressions) to the C++ +Working Paper. + +CWG poll 14: Apply the changes in +[P1467R9](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html) +(Extended floating-point types and standard names) to the C++ Working Paper. + +CWG poll 15: Accept as a Defect Report +[P2493R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2493r0.html) +(Missing feature test macros for C++20 core papers). (The paper was already +adopted at the February, 2022 meeting, and no changes to the Working Paper +result from it now.) + +CWG poll 16: Apply the changes in +[P2582R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2582r1.pdf) +(Wording for class template argument deduction from inherited constructors) to +the C++ Working Paper. + +CWG poll 17: Apply the changes in +[P1774R8](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1774r8.pdf) +(Portable assumptions) to the C++ Working Paper. + +CWG poll 18: Apply the changes in +[P2295R6](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2295r6.pdf) +(Support for UTF-8 as a portable source file encoding) to the C++ Working Paper. + +CWG poll 19: Accept as a Defect Report and apply the changes in +[P2513R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2513r3.html) +(`char8_t` Compatibility and Portability Fix) to the C++ Working Paper. + +CWG poll 20: Accept as a Defect Report and apply the changes in +[P2460R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2460r2.pdf) +(Relax requirements on `wchar_t` to match existing practices) to the C++ Working +Paper. + +CWG poll 21: Accept as a Defect Report and apply the changes in +[P2579R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2579r0.pdf) +(Mitigation strategies for P2036 "Changing scope for lambda +trailing-return-type") to the C++ Working Paper. + +### Library working group polls + +LWG poll 1: Apply the changes for all Ready issues in +[P2618R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2618r0.html) (C++ +Standard Library Issues to be moved in Virtual Plenary, Jul. 2022) to the C++ +working paper. + +LWG poll 2: Apply the changes in +[P0009R18](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0009r18.html) +(MDSPAN) to the C++ working paper. + +LWG poll 3: Apply the changes in +[P2599R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2599r2.pdf) +(`index_type` & `size_type` in `mdspan`) to the C++ working paper. + +LWG poll 4: Apply the changes in +[P2604R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2604r0.html) +(`mdspan`: rename `pointer` and `contiguous`) to the C++ working paper. + +LWG poll 5: Apply the changes in +[P2613R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2613r1.html) (Add +the missing `empty` to `mdspan`) to the C++ working paper. + +LWG poll 6: Apply the changes in +[P0429R9](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0429r9.pdf) (A +Standard `flat_map`) to the C++ working paper. + +LWG poll 7: Apply the changes in +[P1222R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1222r4.pdf) (A +Standard `flat_set`) to the C++ working paper. + +LWG poll 8: Apply the changes in +[P1223R5](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1223r5.pdf) +(`find_last`) to the C++ working paper. + +LWG poll 9: Apply the changes in +[P1642R11](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1642r11.html) +(Freestanding Library: Easy [utilities], [ranges], and [iterators]) to the C++ +working paper. + +LWG poll 10: Apply the changes in +[P1899R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1899r3.html) +(`stride_view`) to the C++ working paper. + +LWG poll 11: Apply the changes in +[P2093R14](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2093r14.html) +(Formatted output) to the C++ working paper. + +LWG poll 12: Apply the changes in +[P2165R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2165r4.pdf) +(Compatibility between `tuple`, `pair` and _tuple-like_ objects) to the C++ +working paper. + +LWG poll 13: Apply the changes in +[P2278R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2278r4.html) +(`cbegin` should always return a constant iterator) to the C++ working paper. + +LWG poll 14: Apply the changes in +[P2286R8](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2286r8.html) +(Formatting Ranges) to the C++ working paper. + +LWG poll 15: Apply the changes in +[P2291R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2291r3.pdf) (Add +Constexpr Modifiers to Functions `to_chars` and `from_chars` for Integral Types +in `` Header) to the C++ working paper. + +LWG poll 16: Apply the changes in +[P2302R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2302r4.html) +(`std::ranges::contains`) to the C++ working paper. + +LWG poll 17: Apply the changes in +[P2322R6](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2322r6.html) +(`ranges::fold`) to the C++ working paper. + +LWG poll 18: Apply the changes in +[P2374R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2374r4.html) +(`views::cartesian_product`) to the C++ working paper. + +LWG poll 19: Apply the changes in +[P2540R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2540r1.html) +(Empty Product for certain Views) to the C++ working paper. + +LWG poll 20: Apply the changes in +[P2404R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2404r3.pdf) +(Move-only types for `equality_comparable_with`, `totally_ordered_with`, and +`three_way_comparable_with`) to the C++ working paper. + +LWG poll 21: Apply the changes in +[P2408R5](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2408r5.html) +(Ranges iterators as inputs to non-Ranges algorithms) to the C++ working paper. + +LWG poll 22: Apply the changes in +[P2417R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2417r2.pdf) (A +more constexpr bitset) to the C++ working paper. + +LWG poll 23: Apply the changes in +[P2419R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2419r2.html) +(Clarify handling of encodings in localized formatting of chrono types) to the +C++ working paper. + +LWG poll 24: Apply the changes in +[P2438R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2438r2.html) +(`std::string::substr() &&`) to the C++ working paper. + +LWG poll 25: Apply the changes in +[P2446R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2446r2.html) +(`views::as_rvalue`) to the C++ working paper. + +LWG poll 26: Apply the changes in +[P2465R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2465r3.pdf) +(Standard Library Modules `std` and `std.compat`) to the C++ working paper. + +LWG poll 27: Apply the changes in +[P2445R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2445r1.pdf) +(`std::forward_like`) to the C++ working paper. + +LWG poll 28: Apply the changes in +[P2467R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2467r1.html) +(Support exclusive mode for fstreams) to the C++ working paper. + +LWG poll 29: Apply the changes in +[P2474R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2474r2.html) +(`views::repeat`) to the C++ working paper. + +LWG poll 30: Apply the changes in +[P2494R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2494r2.html) +(Relaxing range adaptors to allow for move only types) to the C++ working paper. + +LWG poll 31: Apply the changes in +[P2499R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2499r0.html) +(`string_view` range constructor should be `explicit`) to the C++ working paper. + +LWG poll 32: Apply the changes in +[P2502R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2502r2.pdf) +(`std::generator`: Synchronous Coroutine Generator for Ranges) to the C++ working +paper. + +LWG poll 33: Apply the changes in +[P2508R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2508r1.html) +(Exposing std::basic-format-string<charT, Args...>) +to the C++ working paper. + +LWG poll 34: Apply the changes in +[P2517R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2517r1.html) (Add +a conditional `noexcept` specification to `std::apply`) to the C++ working paper. + +LWG poll 35: Apply the changes in +[P2520R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2520r0.html) +(`move_iterator` should be a random access iterator) to the C++ working +paper. + +LWG poll 36: Apply the changes in +[P2549R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2549r1.html) +(`std::unexpected` should have `error()` as member accessor) to the C++ +working paper. + +LWG poll 37: Apply the changes in +[P2585R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2585r1.html) +(Improving default container formatting) to the C++ working paper. + +LWG poll 38: Apply the changes in +[P2590R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2590r2.pdf) +(Explicit lifetime management) to the C++ working paper. + +## Editorial changes + +### Notes on motions + +* **Poll CWG-9:** The wording was based on an old draft, and has been adjusted + to integrate with the current draft: an additional example that was added by + [P2242R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2242r3.html) + has also been deleted. + +* **Polls CWG-12 and LWG-1:** The wording from issue + [LWG-3617](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2618r0.html#3617) + has been integrated with the wording of, and guided by advice from, + [P1169R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1169r4.html). + +* **Poll LWG-2:** Several minor changes were made to this long paper + [P0009R18](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0009r18.html), + "`mdspan`": The expression `sizeof...(OtherSizeTypes)` was given the name `N` + in a few places to simplify the presentation; the phrase "for all rank index + `r`" was changed to "for every rank index `r`", notes have been reworded to + avoid the modal verb "may". + +* **Polls LWG-8 and LWG-1:** The macro `ATOMIC_FLAG_INIT` from + [LWG-3659](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2618r0.html#3659) + has also been marked "freestanding". + +* **Poll LWG-14:** Range formatting is also specified for the new "flat" + container adaptors, as requested by + [P2286R8](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2286r8.html). + +* **Poll LWG-29:** Minor errors in + [P2474R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2474r2.html) + ("`views::repeat`") have been corrected. + +* **Poll LWG-33:** The changes have also been applied to new wording from + LWG-11. + +* **Poll LWG-34:** The changes have been integrated with the earlier changes + from LWG-12 + ([P2165R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2165r4.pdf), + "Compatibility between `tuple` and tuple-like objects"). + +* **Polls LWG-14, -23, -33, -37:** All four papers ask to update the + `__cpp_lib_format` feature test macro. This has since been discussed and found + unsatisfactory, but a resolution will only be applied editorially in the next + working draft. + +### Noteworthy editorial changes + +* We introduced the new term "_control-flow-limited_ statement" in [stmt.label] + to refer to a statement into which one cannot jump from the outside, which is + used for constexpr if, consteval if, and try and catch blocks. + +* Additional subclauses have been introduced where needed to ensure that there + is only one class synopsis along with its member specifications per subclause, + so as to not be ambiguous. Apart from modifying the current motions, this + affects [vector.bool]. + +* Extraneous subclauses were removed, and their contents flattened, from the + erstwhile [expected.un.object]. + +* Old wording for container adapters that used to say "other kinds of sequence + containers that the user defines" has been replaced with "other program-defined + sequence containers", since we now need this phrase in two places, and the term + "program-defined" was only introduced recently. + +* Further rewordings have been made to avoid the use of the "might" and "could" + modal verbs in notes. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4910 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/n4910...n4917). + + commit fb8135e5ec22acd26cb0dcb1bface21eee118895 + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Sun Mar 6 20:22:18 2022 +0800 + + [range.utility.conv.general] Add missing template parameter to container-inserter + + commit b7c1f9a77eac8dfeb4cb2e92bd3b2a57d05c298a + Author: Jens Maurer + Date: Fri Mar 25 09:37:42 2022 +0100 + + [spanbuf] Fix template name in subclause heading (#5365) + + commit cdca862605ae315e2d7a1ca7c7c1b011651944d2 + Author: Jens Maurer + Date: Fri Mar 25 10:44:58 2022 +0100 + + [span.streams] Move non-member swaps to header synopsis (#5366) + + commit 478b8f8807e5b4561874842aa24a132558682f00 + Author: A. Jiang + Date: Thu Mar 31 19:34:03 2022 +0800 + + [alg.min.max] Consistently specify ranges::minmax_element with minmax_element_result (#5376) + + LWG3180 was incompletely applied with commit e33be08f8ca49a9a139aa81b7a1ba9787d85f4fc. + + commit c92196bc67e252f06907c6de44173ce7157d71df + Author: Jens Maurer + Date: Fri Apr 1 13:38:03 2022 +0200 + + [memory.syn] Add missing closing bracket for attribute + + commit 1d2d223ab9fee202b67b31b32b85f44e3f9dc187 + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Thu Mar 24 02:13:51 2022 +0800 + + [range.adjacent.transform.iterator] Fix wrong template parameter in adjacent_transform_view::iterator + + commit 4813f202b3e2f6d0062967b9fd96ca54b91c7b65 + Author: Jens Maurer + Date: Wed Mar 30 08:29:55 2022 +0200 + + [stacktrace.syn] Add '#include ' + + LWG3330 added #include to all header files + where a three-way comparison operator was declared, + but missed this one. + + commit d9040a775aa528f0576453532f3cb5058a6e6f24 + Author: A. Jiang + Date: Wed Apr 6 20:03:39 2022 +0800 + + [allocator.requirements.general] Specify all member types with typename (#5386) + + commit 2bfa7c4cc96203e03763816cf310e54e5b8940bb + Author: Daniel Krügler + Date: Fri Apr 15 21:26:27 2022 +0200 + + [temp.constr.normal] Add missing semicolon in example (#5395) + + commit a8dbfc63227bf596dcf72a31c9fef4af8af9e592 + Author: Jonathan Wakely + Date: Wed Apr 20 14:41:22 2022 +0100 + + [depr.tuple,depr.variant] Use struct class-key consistently (#5402) + + commit 4fc805d949bfc99ee6cfcf666123eb982fc4c465 + Author: Jens Maurer + Date: Thu Apr 21 09:27:57 2022 +0200 + + [expr.prim.lambda.general] Clarify deduced lambda return type + + commit 5fb0fd092782f57e8395841470c92176412a10a3 + Author: Jonathan Wakely + Date: Thu Mar 24 09:29:07 2022 +0000 + + [expected.un.object.general] Reorder constructors in synopsis + + This matches the order in [expected.un.ctor]. + + commit 8e7a9b9fbf2f7a7dfa913a77068b6a6d3488e521 + Author: Jonathan Wakely + Date: Thu Mar 24 09:36:55 2022 +0000 + + [expected.un.object] Remove unnecessary subclause nesting + + All the other class templates in are at the rSec3 level, but + std::unexpected is below a mostly useless rSec3 [expected.unexpected]. + This subclause has two children, [expected.un.general] which is a single + sentence, and [expected.un.object] which defines the class template and + its members. If we merge the single sentence from [expected.un.general] + into the same subclause as the class synopsis then we can get remove the + unnecessary nesting. As a nice side effect, this also gets rid of + "object" in the [expected.un.object] stable name, which doesn't really + make sense in context. + + commit 3372ed0572fd8aa59ed9e59432cd8f593868be49 + Author: Casey Carter + Date: Mon Apr 25 13:24:24 2022 -0700 + + [range.utility.conv.general] Strike extraneous semicolon (#5414) + + commit 4b7deb009c4dfbbe8f2c879f764be446f94957b2 + Author: xmh0511 <970252187@qq.com> + Date: Tue Apr 26 04:26:19 2022 +0800 + + [lex.ccon] Fix typo in character name for U+0027 (#5412) + + commit 93de6031da2ef99b402e18ee8941fd6c7b554ce4 + Author: Jens Maurer + Date: Tue Apr 26 14:14:02 2022 +0200 + + [string.view.deduct] Move to immediately after [string.view.cons] (#5397) + + commit 41bc0c2ab38c32638685ef9a5068e06abbfc07f3 + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Tue Apr 26 20:16:26 2022 +0800 + + [expected] Add missing noexcept for expected::error() (#5381) + + commit b075835f134e4956fe27eaa5323655137aff3d45 + Author: Hui <65944694+huixie90@users.noreply.github.com> + Date: Tue Apr 26 18:56:30 2022 +0100 + + [iterator.concept.readable] Remove obsolete note (#5408) + + The note was obsoleted by P1878R1. + + commit eed51157b2011478eb40254fbf191f2dd5fca7ca + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Tue May 3 15:26:39 2022 +0800 + + [expected.object.general] Remove explicit keyword for copy/move constructors (#5380) + + commit d23b318949c0a74c6f93f50afb1375ba9eb7aefd + Author: Jonathan Wakely + Date: Wed May 4 00:50:55 2022 +0100 + + [stringbuf.virtuals] add "override" to setbuf + + commit fbe06e9076db0116e395e969f4cb921e45ae964a + Author: Jonathan Wakely + Date: Wed May 4 00:51:45 2022 +0100 + + [adjacent.difference] fix grammar typo + + commit bb8729f3cba593b963031bb25a1a4f12e12ad4fb + Author: Jonathan Wakely + Date: Wed May 4 00:52:40 2022 +0100 + + [streambuf.virt.get] fix grammar typo + + commit 6fa045bf939eeff4dcea56e1a84ab7e1aac69f78 + Author: Jonathan Wakely + Date: Wed May 4 01:12:12 2022 +0100 + + [thread.lock.unique.cons] Use nullptr for null pointer constant + + commit f6791f7f9346c007921fec0b406a9edcbf667951 + Author: Jens Maurer + Date: Wed May 4 11:55:03 2022 +0200 + + [syncstream.osyncstream.cons] Fix use of parameter name (#5445) + + commit 74ad79739e2a13022bc6a33ff2e32efe59a47578 + Author: Jens Maurer + Date: Wed May 4 11:55:45 2022 +0200 + + [thread.sema.cnt] Add missing parentheses on function call expression (#5443) + + commit 8147026d04fe8fb44ed439cea950b5dab136c04c + Author: Jens Maurer + Date: Wed May 4 11:56:14 2022 +0200 + + [cons.slice] Add copy constructor for 'slice' to synopsis (#5444) + + commit fb379c19180d1e26b2b8146d547bcc84c59a0da5 + Author: Jens Maurer + Date: Wed May 4 11:56:50 2022 +0200 + + [over.match.best.general] Fix typo in example (#5446) + + commit 81e506da21960bc70c271f775673a311ec957f6b + Author: Casey Carter + Date: Wed May 4 02:59:27 2022 -0700 + + [ranges.syn] remove trailing `-> see below` return type from three `to` overloads (#5419) + + Since there is actually no return type specification to see below in [range.utility.conv]. + + commit 11d886b5c6062ec7291469514eb07424811e4f65 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Tue Apr 26 17:39:39 2022 +0300 + + [class.access] Remove dangling Note + + Invalidated by P1847R4 + + commit 5032e88247bafb5c44dcd4d8ac2ffe3f8bff1bd9 + Author: Jens Maurer + Date: Sat Apr 23 22:15:46 2022 +0200 + + [associative] Add "i.e." in front of explanation + + commit 445d18255713e183df2819e565aa5faa7f85bb1d + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Fri Apr 1 22:46:44 2022 +0800 + + [range.utility.conv.general] Add missing constexpr for container-inserter + + commit 64969e2057ef55b7ac3db8e23c37547edff5c8cf + Author: Jens Maurer + Date: Thu May 5 13:14:25 2022 +0200 + + [intro.memory] Fix missing semicolon in example + + commit dcf0f144f72e8116c59c188c5057a6ca8a7615d3 + Author: Jens Maurer + Date: Thu May 5 13:35:33 2022 +0200 + + [intro.progress] Fix grammar typo + + commit 8c743eacc4b8609650d690b774f855507bd0846f + Author: Jens Maurer + Date: Thu May 5 13:41:54 2022 +0200 + + [expr.prim.lambda.general] Fix missing capture-default in example + + commit 359b8f41027c970bbbc63f1319a890adaa338f6f + Author: Jens Maurer + Date: Thu May 5 16:59:35 2022 +0200 + + [expr.await] Fix English grammar in string-literal in example + + commit 117b352d584cac601c22c63328355658271a6f17 + Author: Jens Maurer + Date: Thu May 5 17:05:50 2022 +0200 + + [expr.xor] Fix grammar typo + + commit 980aded4060cb408c053b0ee4620a71f3b6b73c6 + Author: Jens Maurer + Date: Thu May 5 17:06:01 2022 +0200 + + [expr.or] Fix grammar typo + + commit edb43d00ec4f5e98d45c03408b5d0be6b0484c27 + Author: Jens Maurer + Date: Thu May 5 17:09:06 2022 +0200 + + [expr.yield] Fix typos in examples + + commit 451d8b95bd4c04bf89a5915eb973f837873c432b + Author: Jens Maurer + Date: Thu May 5 17:20:11 2022 +0200 + + [dcl.fct.default] Fix grammar typo in comment in example + + commit cd2690e9ace12f901acce1c1e9157f5cbbf06b24 + Author: Jens Maurer + Date: Thu May 5 17:21:32 2022 +0200 + + [dcl.init.aggr] Fix grammar typo in example + + commit cbc1a36376f32e9d31d5276ba44d8237d0632c37 + Author: Jens Maurer + Date: Thu May 5 17:24:29 2022 +0200 + + [dcl.fct.def.coroutine] Fix grammar typo + + commit d7be2ebee9dd3df849cf87bed768f9bb9f8684f8 + Author: Jens Maurer + Date: Thu May 5 17:27:11 2022 +0200 + + [class.copy.ctor] Fix grammar typo + + commit 4284e8c31673912ae92bc210bb39aa4b05f0ed86 + Author: Jens Maurer + Date: Thu May 5 17:31:25 2022 +0200 + + [class.expl.init] Fix grammar typo + + commit 6c0d1411779d9e2c3e9a59d10b09605b6e5f1482 + Author: Jens Maurer + Date: Thu May 5 17:35:00 2022 +0200 + + [class.base.init] Fix grammar typo in note + + commit 40483ba8cff2165cd81dd75718559037af3ecaa8 + Author: Jens Maurer + Date: Thu May 5 22:43:03 2022 +0200 + + [over.match.class.deduct] Fix syntax error in example + + commit 04cb8da6485b09592008c82eb330125fbf1034cd + Author: Jens Maurer + Date: Thu May 5 23:15:42 2022 +0200 + + [temp.decls.general] Fix missing comma + + commit e6633adbb2f3a6590cd75a000b377c8736c65094 + Author: Jens Maurer + Date: Fri May 6 00:17:50 2022 +0200 + + [temp.deduct.type] Fix grammar typo + + commit 1386c5b2cf41b713a12f526077eb578b68bacb9b + Author: Jens Maurer + Date: Fri May 6 00:19:23 2022 +0200 + + [temp.over] Fix grammar typos + + commit 21dc6d863a5acb0c3e5ec008bddb1c02b3dcd29a + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Thu May 19 11:23:47 2022 +0800 + + [range.join.view] Simplify range_reference_t to InnerRng + + I think this is a reasonable simplification and also makes it consistent with join_with_view. + + commit 2101d81b42bfcb7ab2227617a5ebe86e0b5733e8 + Author: Casey Carter + Date: Mon May 23 04:39:15 2022 -0700 + + [expected.object.ctor] Use the injected-class-name to refer to the current instantiation (#5485) + + ... as is conventional in library wording. + + commit 31be778d39b144fe867e24d80481786ad012661e + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun May 29 04:51:06 2022 +0800 + + [ranges] Remove redundant "exposition only" comments in \itemdecl (#5499) + + commit aff22aca63d0fb4b183cf073de8abfd4b9bb22bd + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Jun 10 00:24:11 2022 +0800 + + [range.istream.view] Add reference for basic_istream_view::iterator (#5514) + + commit 10a20b22491f1ff39a47847a68c9e4a648754d10 + Author: Mathias Stearn + Date: Thu Jun 9 18:52:42 2022 +0200 + + [res.on.functions] Use regular "behavior is undefined" words of power (#5513) + + commit 4bfa5ddf04586b6df76e0f44e4cde8b59f4a0401 + Author: Casey Carter + Date: Thu Jun 9 09:56:29 2022 -0700 + + [range.istream.iterator] basic_istream_view::iterator is not a class template (#5515) + + commit f73087971183d1daa992ad5165946609a77d39ff + Author: Jens Maurer + Date: Sun Jun 12 16:18:19 2022 +0200 + + [func.wrap.move.ctor] Fix typo naming template parameter packs (#5517) + + commit 8d3f43888013437a2870877f00f017860b083df4 + Author: Johel Ernesto Guerrero Peña + Date: Sat Jun 11 17:34:09 2022 -0400 + + [range.adjacent.iterator] Use correct descriptive element + + commit d86e1ef9ef8514e570fdbbc5038f71e272dbb008 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Jun 12 03:11:07 2022 +0800 + + [ranges.syn] Fix the constraints order of slide_view + + commit c4a46fb7343c591f8844c2615ec25cfe8021656a + Author: hewillk <67143766+hewillk@users.noreply.github.com> + Date: Sat May 21 20:39:59 2022 +0800 + + [move.iter.cons] Add missing Returns + + commit 45498df90fa8fa6ffb4de7341c65a2924de9879c + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Thu Jun 16 04:57:27 2022 +0800 + + [range.join.with.sentinel] Add missing curly brace (#5530) + + commit d78d53f96d076f66a8af4ca7e71ae48e1d0596be + Author: Jens Maurer + Date: Thu Jun 16 13:52:29 2022 +0200 + + [allocator.adaptor.syn] Fix typo in comment in header synopsis + + commit 01f16bc99a6a89e69b7a6ec5ae8bfe307ec5299a + Author: Jens Maurer + Date: Thu Jun 16 17:33:52 2022 +0200 + + [functional.syn,func.search.default] Fix name of template parameter + + commit 0678f9986b2c1f75e55d596f63876979433522d4 + Author: Jens Maurer + Date: Thu Jun 16 17:43:07 2022 +0200 + + [meta.rel] Add parentheses for consistency + + Parentheses are used for is_pointer_interconvertible_base_of. + + commit c8a496c62d973305cd6eb5a23d80f169062335fc + Author: Jens Maurer + Date: Thu Jun 16 17:51:57 2022 +0200 + + [string.view.general] Add missing template-argument-list + + commit 70d07925ad874144f2dae4359f5a17c6cada1cdb + Author: Jens Maurer + Date: Thu Jun 16 17:55:30 2022 +0200 + + [forward.list.modifiers] Fix misspelled parameter name + + commit 66fd28de5c730a271bcf631f8452048c0e709232 + Author: Jens Maurer + Date: Thu Jun 16 17:56:48 2022 +0200 + + [set.cons] Fix grammar typo + + commit de6b0e70ffe2da0a0f91ce434863202f78c9e029 + Author: Jens Maurer + Date: Thu Jun 16 18:00:21 2022 +0200 + + [unord.map.overview] Fix presentation of member types + + commit 5be153e248d9e741c841ff3ab6c2e3714ecba24b + Author: Jens Maurer + Date: Fri Jun 17 08:14:19 2022 +0200 + + [unord.set.overview] Fix presentation of member types + + commit 633178f3fd48a784a96a6610f6b12c10700603c0 + Author: Jens Maurer + Date: Fri Jun 17 08:15:22 2022 +0200 + + [unord.multiset.overview] Fix presentation of member types + + commit 5ae534c0c522cf661d3e94c58f54c7d37cf7905a + Author: Jens Maurer + Date: Fri Jun 17 08:18:34 2022 +0200 + + [random.access.iterators] Add semicolon at end of statement + + commit f60caf420b5210f0ad284999a1e471d50c424856 + Author: Jens Maurer + Date: Fri Jun 17 08:21:11 2022 +0200 + + [range.req.general] Fix grammar typo + + commit 75436ee3dd005cf13153ee05c9174a3a3df0054d + Author: Jens Maurer + Date: Fri Jun 17 08:32:31 2022 +0200 + + [range.take.view] Replace 'struct' with 'class' for consistency + + commit 8738cac27de2d66addf735f4fc2b370b73bb9ecc + Author: Jens Maurer + Date: Fri Jun 17 08:33:59 2022 +0200 + + [range.take.while.overview] Highlight use of ranges::begin + + commit 51cad172464c89cc14fff19d87d6bba6bc68f61d + Author: Jens Maurer + Date: Fri Jun 17 08:38:54 2022 +0200 + + [algorithms.requirements] Add commas for readability + + commit 5096e87c6c882ae2aff40c3558db7c2ec95ff4a8 + Author: Jens Maurer + Date: Fri Jun 17 08:39:08 2022 +0200 + + [algorithms.requirements] Add hyphen for non-copied + + commit 63f3e4030497e43f39ff89ec0171f89a11dfc0a7 + Author: Jens Maurer + Date: Fri Jun 17 08:41:53 2022 +0200 + + [alg.equal] Add missing period + + commit 736c755c70be70d5fb75e71f2c212c3c633ddc34 + Author: Casey Carter + Date: Thu Jun 23 14:26:40 2022 -0700 + + [priqueue.overview] Add misssing `>` to deduction guide (#5535) + + commit 3bf6ac52ddd619ae925d32ebb68a90a5bec0c115 + Author: Jens Maurer + Date: Fri Jun 24 15:50:30 2022 +0200 + + [class.prop] Clarify definition of implicit-lifetime class (#5319) + + commit 314fa9e2c16bcdaba33febddf2992b3e26c02212 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Jul 13 01:54:20 2022 +0800 + + [sequence.reqmts] Add ranges namespace qualifier for range concepts (#5563) + + commit 433b7af41ef02b8656c3153ab6ebb1c1c616f5b3 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Jul 13 23:40:21 2022 +0800 + + [range.take.overview] Fix punctuation (#5564) + + commit f6cb84439e8094ec7c67c708d1cc0ddef59262ec + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Jul 26 23:09:38 2022 +0800 + + [ranges.syn] Add \ref for `ref_view` (#5652) + + commit c816ae797e36daa466c287f3eff445aa87d8bfeb + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Jul 29 03:11:43 2022 +0800 + + [istreambuf.iterator.general] Add \ref for proxy (#5669) + + commit d59a4f3392fd1cf87af4ba128518fb4c00cbf77c + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Jul 29 03:13:33 2022 +0800 + + [algorithm.syn,bitset.syn,rand.synopsis,valarray.syn] Add \ref for header (#5666) + + commit 78b91e849b270423ec3296f7f95666078531e032 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sat Jul 30 05:13:40 2022 +0800 + + [range.join.with.overview,range.split.overview] use qualified name in examples (#5683) + + commit e24445344d26e3d9a3ad92b939b8c034daa47eb4 + Author: Thomas Köppe + Date: Sun Aug 14 20:53:03 2022 +0100 + + [mdspan.*] Replace remaining "pointer"s with "data_handle_type". + + These edits are part of LWG Motion 4 (P2604R0) but were accidentally omitted. + + commit 762480c9317759ffd6db76f7fef27744776e081d + Author: Thomas Köppe + Date: Wed Aug 17 11:41:51 2022 +0100 + + [ranges] Remove now-unused exposition-only "tuple-or-pair". + + Also fix one missed replacement of "tuple-or-pair" with "tuple" as + instructed by LWG-Motion 12 (P2165R4, "tuple-like objects"). + + commit b832e2702df41ebe79ddd9d159ac71e68e9b772a + Author: Thomas Köppe + Date: Sun Aug 14 22:26:15 2022 +0100 + + [container.reqmnts] Remove stray `{}` + + commit f09e7c5164d6dbc43e4a160aa4676725a83f488d + Author: Thomas Köppe + Date: Wed Aug 17 15:03:41 2022 +0100 + + [expr.spaceship, fs.path.generic, temp.inst] Use em-dash for parentheticals, not en-dash. + + We are using em-dashes elsewhere already. + + commit 5dd17bf20e46a2964131ec208b6ed31cc659c400 + Author: Thomas Köppe + Date: Wed Aug 17 23:18:35 2022 +0100 + + [ranges] Add missing requirement on itemdecl, and fix spacing + + commit bb1145f751e2de491873aac5a42faf0a6931c218 + Author: Thomas Köppe + Date: Fri Aug 12 12:03:55 2022 +0100 + + [mdspan.{overview,extents.ctor}] Increase reuse of definitions + + commit e97f917d3fd39d7fb2421105d8e45cb73bd24a1e + Author: Eelis van der Weegen + Date: Thu Aug 18 18:42:15 2022 +0200 + + [range.zip.transform.view] Fix typo: mmove_constructible. + + commit f440cfa4e3ebf139b5acec3735e90d4acf5785e6 + Author: Thomas Köppe + Date: Thu Aug 18 15:25:55 2022 +0100 + + [ranges.syn] Add missing "freestanding" comment for as_rvalue. + + commit 999005ab72ca0078b3361979584007dd9d991fac + Author: Yihe Li + Date: Fri Aug 5 08:49:10 2022 +0800 + + [strings.general] Add header to "String classes" row + + commit 1fbf5f8b683802849cfc8bb57fef3f48a61bd242 + Author: Yihe Li + Date: Fri Aug 5 08:49:40 2022 +0800 + + [thread.general] Remove non-existent header + + commit 0d7d1d70641a773f67b08f4de44e53f00e3b352d + Author: Jens Maurer + Date: Fri Jun 24 15:40:43 2022 +0200 + + [temp.inst] Clarify referent of 'declaration' + + commit 99bc532e3c9440defd761985d2329da064b7f9f9 + Author: Jens Maurer + Date: Thu Jun 23 23:17:13 2022 +0200 + + [module.private.frag] Remove misleading example and broaden note + + commit 596137c054407d4d5f2ccf327bd5d3e2a8b4fef5 + Author: A. Jiang + Date: Tue May 17 09:49:27 2022 +0800 + + [mem.poly.allocator.class.general] Clarify polymorphic_allocator etc. + + commit 193cfc17cbb73e7e6c65d1e596ef9c1a035c7811 + Author: Jens Maurer + Date: Fri Nov 5 19:58:41 2021 +0100 + + [diff.dcl] Discuss 'alignas' placement restrictions + + commit 8b2d70502c379b96ddb9d6eb97d5aafcc1d4765c + Author: Jens Maurer + Date: Fri Nov 5 20:00:00 2021 +0100 + + [diff.dcl] Remove 'implicit int' discussion + + C99 has removed implicit int. + + commit f91c425a8fe6f0dd826bd399a5bc82796aec8180 + Author: Jens Maurer + Date: Fri Mar 4 21:20:21 2022 +0100 + + [diff.expr] Remove 'implicit function declaration' discussion + + C99 has removed implicit function declarations. + + commit b208eb4da5a97cf800f2822318fd487f332d82ad + Author: Jonathan Wakely + Date: Fri Feb 22 06:22:04 2019 +0000 + + [meta.trans.other] Use "denotes" in decay, enable_if and conditional + + commit 769e15bd0559a8ff572d2c508f2cce0227229a39 + Author: Jonathan Wakely + Date: Fri Feb 22 07:04:02 2019 +0000 + + [meta.unary.prop.query] Use "is an array type" not "names an array type" + + commit 3d010460fc4159b6f99d430a3cf0eb0ff30d0053 + Author: Jonathan Wakely + Date: Fri Feb 22 07:05:09 2019 +0000 + + [meta.trans.ref] Use "is a referenceable type" and "denotes the type" + + commit 66cb97967adb501ff352b6e69815b4db10e095bf + Author: Jonathan Wakely + Date: Fri Feb 22 07:06:14 2019 +0000 + + [meta.trans.sign] Use "is a ... type" and "denotes the type" + + commit 485192fb3872c1da42d6cc0ff89230ecb7760c9c + Author: Jonathan Wakely + Date: Fri Feb 22 07:06:46 2019 +0000 + + [meta.trans.arr] Use "is a type" not "names a type" + + Also use "denotes" instead of "names" for member typedefs. + + commit e2d032255ad0f346144659ba43d3eb184163c8bb + Author: Jonathan Wakely + Date: Fri Feb 22 07:07:15 2019 +0000 + + [meta.trans.ptr] Use "is a referenceable type" not "names ..." + + commit 2c9482a15375291528e8742dc7972450c9597d96 + Author: Jonathan Wakely + Date: Fri Feb 22 07:09:00 2019 +0000 + + [meta.trans.other] Use "denotes" + + commit c51087e82583b589481f03d4dad2190a569ce857 + Author: Jonathan Wakely + Date: Fri Feb 22 07:16:14 2019 +0000 + + [meta.trans.cv] use "denotes" in specification of member typedefs + + commit 935ec9e8f13d41bc09f8a27a917008ddf2724a29 + Author: Jonathan Wakely + Date: Tue Apr 23 10:33:16 2019 +0100 + + [refwrap.unwrapref] Use "denotes" for member typedef + + commit e412ba9b687e4cdd8ed7546b3ec44122b6baabc5 + Author: Jonathan Wakely + Date: Fri Apr 22 18:20:59 2022 +0100 + + [depr.meta.types] use "denotes" for member typedefs + + commit 887c0330bdd2e4b504854a5c9d34621e5d10a3d2 + Author: Jens Maurer + Date: Tue Nov 27 21:27:28 2018 +0100 + + [cmp.categories] Replace 'operator admits' phrasing. + + commit 1e3e4180ee26e06abe6eeb648537b36baa92c5b7 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Aug 19 01:33:25 2022 +0800 + + [range.as.const.view] Add missing angle bracket (#5745) + + commit d732538953bab8ccdbe4388cfb39b8542a01dc65 + Author: Arthur O'Dwyer + Date: Thu Jul 21 10:09:09 2022 -0400 + + [map.cons,multimap.cons,multiset.cons,set.cons,associative.reqmts.general] "sorted with respect to `comp`" + + https://cplusplus.github.io/LWG/issue3713 + LWG3713 points out that we temporarily lost the term of art + "sorted with respect to `comp`," and brings back a definition + for it. However, several places in the existing draft never + actually used that term of art in the first place. Fix them + up so that they do. + + commit 4db1d62426ef9a9cd8689585d43da38dd3731696 + Author: A. Jiang + Date: Fri Aug 19 01:36:40 2022 +0800 + + [allocator.requirements.general] Use newer style for SimpleAllocator + + commit a458849089b29e3dfc5f9736799c1c6403223f8f + Author: Jens Maurer + Date: Sun Jun 12 16:11:08 2022 +0200 + + [thread.lock.unique.locking] Fix function call expressions + + commit dd4ecf3d19bf8a04899324fc72c690880a328a64 + Author: Jens Maurer + Date: Fri May 13 21:51:13 2022 +0200 + + [stacktrace.basic.nonmem] Add missing \pnum before \recommended + + Also augment check script + + commit fe24762404f5ac7bbd6f139a44dbfa42663ec796 + Author: Barry Revzin + Date: Thu Aug 18 16:03:10 2022 -0500 + + [stmt.pre] List "compound-statement" explicitly as part of a selection statement + + This clarifies the substatements of `if consteval` (which has a compound-statement). + + commit 2940703c7ee125ce8194f668683ff5b0bbd7791b + Author: Jens Maurer + Date: Sun Jan 2 21:46:02 2022 +0100 + + [core] Replace 'enumerated type' with 'enumeration' + + The term "enumerated type" is defined in [enumerated.types] + for use in the standard library, and is not synonymous with + "enumeration type". + + commit a27e5a6ac3a0fc9cb8474b87b92734a923d495c0 + Author: Hubert Tong + Date: Fri Aug 19 10:36:20 2022 -0400 + + [stmt.label, except.pre] Use new wording "control-flow-limited" statement (#5413) + + A new term of art (control-flow-limited statement) is introduced in [stmt.label] + to express the restrictions on control flow into a statement (namely jumping to labels). + Both [stmt.if] and [except.pre] are updated to use the new term. + + This rewords "shall not be used to" avoiding question of actual "use": the "shall not be + used to" phrasing may be taken to refer only in cases where the actual use occurs + or is the primary intent. Instead, the intended restriction can be written in terms + of static properties of the constructs so restricted in the style of [stmt.if]. + + commit 5aa000973bba1ce10ce0f4ca6a3bec61bcea2061 + Author: Jason Merrill + Date: Fri Aug 19 10:47:42 2022 -0400 + + [lex.charset] Add missing hyphens + + In P2071R2 and NameAliases.txt, 0+008E is named SINGLE-SHIFT-2, but it went + into the draft as "single shift-2", losing the hyphen between the words. + + commit 8275c19b3fa9e7cb09f84049ebd6207aceb7ca80 + Author: Thomas Köppe + Date: Fri Aug 19 17:29:40 2022 +0100 + + [range.cartesian.view] Fix definition of cartesian-product-is-common + + The original wording seems to have been a copy-paste error. + + commit 4117a1fc1aeb307d6b15c8aba8a54925fb1b4faf + Author: Mark de Wever + Date: Fri Aug 19 18:37:58 2022 +0200 + + [format.string.escaped] Fix invalid examples + + While implementing new features introduced by P2286R8 Formatting Ranges + I noticed some issues in the examples. These issues are in the paper + too. + + For s3 the alternative would be to adjust the output instead of the + input. + + commit 2d548b2ec835510685cf2fcb175f7645aa798d72 + Author: Thomas Köppe + Date: Fri Aug 19 09:35:25 2022 +0100 + + [dcl.fct.def.default] Elaborate on the difference of two declarations + + This makes it clear that T_1 and T_2 may differ because of the present + rule for the purposes of the blanket statement "other than as allowed + by the preceding rules" futher below. + + commit d2ad0017c5584825fce1cbf741c160e4bd6108b3 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Aug 21 01:22:25 2022 +0800 + + [range.chunk.overview,range.slide.overview] Use maths, not code style for N/M (#5500) + + commit 1277923e3ac7a35a3713823b5782b57b86f956ed + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Aug 21 01:35:35 2022 +0800 + + [range.chunk] Fix subclause headings (#5516) + + commit 2f228c5cad223a5c8d686d91b054ee3bd2d2a123 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Aug 21 05:01:17 2022 +0800 + + [range.as.rvalue.view] Fix accidentally swapped concepts in template head + + Also fixes the whitespace style around the opening brace. + + commit 22133b42b1a20d542a8f4d18cc425e8c875e567b + Author: Thomas Köppe + Date: Sat Aug 20 22:04:26 2022 +0100 + + [complex.members] Remove stray "template" from constructor + + This peculiar presentation had previously worked in conjuction with + a subclause on "explicit specializations", but since those explicit + specializations have been removed by P1467R9, the template head does + not serve any useful purpose any longer. + + commit fee56834fb55355d617a88fe764f9fb20d92c329 + Author: Thomas Köppe + Date: Sat Aug 20 22:35:28 2022 +0100 + + [expr.prim.lambda.capture] Add cross reference to [basic.scope.lambda] + + Suggested by CD review feedback. + + commit 6f70f82eead9ddc10830aedb99286d0db54725ad + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Aug 22 02:11:57 2022 +0800 + + [range.repeat.view] Fix typo (#5765) + + commit 89df45a30a48f30d2ab367490b47c2c0a87f4aa6 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Aug 22 01:51:41 2022 +0800 + + [ranges.cartesian.iterator] Fix typo + + commit 35aa22acdf080fc5886d715a965aadd36de28c27 + Author: Thomas Köppe + Date: Sun Aug 21 01:55:27 2022 +0100 + + [expr.prim.id.unqual] Fix parameter name in example ("y", not "z") + + The misspelling was a misapplication of the motion paper P2579R0. + + Also harmonize the local use of whitespace. + + commit 2841712fc15f831481d7bd39e084c213596ccfec + Author: Thomas Köppe + Date: Sat Aug 20 23:49:21 2022 +0100 + + [vector.syn, vector.bool] Add subclause structure. + + After the addition of the formatting-related specialization, the + original subclause contained several class template synopses without + any intervening separation. The header synopsis is rearranged to + follow the document order. + + commit 259b8d5d1beeaccf793783679ff4956e84774ea4 + Author: Thomas Köppe + Date: Mon Aug 22 00:03:46 2022 +0100 + + [alg.sorting.general] Make "comp" part of the defined term + + Suggested by CD review feedback. + + commit c2aee77b6413fe8ce09bf816d1e239fa2b93f4a9 + Author: Thomas Köppe + Date: Mon Aug 22 00:14:49 2022 +0100 + + [mdspan.overview] Extend the definition to "size of a MD index space" + + Previously, only "size" was the defined term, but P0009R18 asks for + the entire phrase to be the defined term. + + Suggested by CD review feedback. + + commit ac27094ee2f367faf32a37008f476d57b19fd999 + Author: Thomas Köppe + Date: Mon Aug 22 00:29:15 2022 +0100 + + [mdspan.extents.expo] Add "exposition-only" comments to itemdecls + + Suggested by CD review feedback. + + commit cce4e845272506ad2e0d732d78bce1dcfd02b7c7 + Author: Thomas Köppe + Date: Mon Aug 22 00:34:32 2022 +0100 + + [mdspan.extents.ctor] Consistently use "r" as a maths variable, not code. + + Suggested by CD review feedback. + + commit a284ab6c16f387f95adb85e02ad9c07cf36b08a3 + Author: Thomas Köppe + Date: Mon Aug 22 00:43:14 2022 +0100 + + [mdspan.layout.{reqmts,right.ctor}] Consistently use maths, not code + + Suggested by CD review feedback. + + commit 62d024620d93fc08611ce9e931fef95c9e064d03 + Author: Thomas Köppe + Date: Mon Aug 22 00:52:22 2022 +0100 + + [mdspan.accessor.reqmts] Replace "pointer" with "data_handle_type". + + This edit was part of LWG Motion 4 (P2604R0) but was accidentally omitted. + + commit 9369f4c7f116244193c7c2ed12ecc4a625790776 + Author: Thomas Köppe + Date: Mon Aug 22 00:56:57 2022 +0100 + + [mdspan.layout.stride.expo] Replace "SizeType" with "IndexType". + + This edit was part of LWG Motion 3 (P2599R2) but was accidentally omitted. + + commit fd7c919c681630425a48fd01b4c36c631c910303 + Author: Thomas Köppe + Date: Mon Aug 22 01:01:14 2022 +0100 + + [mdspan.layout.stride.{ctor,obs}] Add cross references to [mdspan.layout.policy.reqmts] + + Suggested by CD review feedback. + + commit d0c287b45c5b7ec1d5cfffed2eeeed2e2682ed3b + Author: Thomas Köppe + Date: Mon Aug 22 09:59:57 2022 +0100 + + [flat.multi*] Fix typo ("mutli" => "multi") + + commit 06cbf011ea876313132b51f3699b23f942f91123 + Author: Thomas Köppe + Date: Mon Aug 22 10:13:01 2022 +0100 + + [containers] Add cross references to "erasure" subclauses + + In associative containers, the comment in the synopsis is augmented + with the name of the class template, since each header contains two + class templates (unique and multi). + + Also fixes some index entry spellings. + + commit 3b1461021cb81fbbccd27494ecd60de7daf958b8 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Aug 22 17:56:54 2022 +0800 + + [range.adaptor.tuple] Fix tuple helper parameter name clash (#5769) + + The code as presented originally was ill-formed. + + commit 90c2cfb1fb8e5cb4781a2d8affdc8856279ca09a + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Aug 22 09:32:17 2022 +0800 + + [range.repeat.iterator] repeat_view::iterator is not a class template + + commit 4762e1b6fa3bcaf4fdc080e2160ab4e9e96f77b6 + Author: A. Jiang + Date: Mon Aug 22 15:32:10 2022 +0800 + + Fix preconditions for start_lifetime_as_array(p, n) + + "n > 0 is true" can't be in "Mandates:", and it's in "Preconditions:" according to P2590R2. + + commit 28f49c965a394c573fa927792f082a182d422029 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Aug 22 19:29:40 2022 +0800 + + [range.as.const.view] Fix order of constraints in class synopsis (#5760) + + The header and the class synopses used different orderings in P2446R0, + and the ordering from the header synopsis is the desired one. + + commit 03d73772246ec6e9fa0becb983be6dc08189d8b1 + Author: Thomas Köppe + Date: Mon Aug 22 12:23:51 2022 +0100 + + [flat.*] Harmonize wording "supports the ... operations but not ..." + + commit 9934675dd673bfa8e073bd3c2187575b47e6ea44 + Author: Thomas Köppe + Date: Mon Aug 22 13:48:45 2022 +0100 + + [flat.set.defn] Fix name of function parameter ("rg", not "range") + + commit faa173c296bfc3547e6f20af63329ac0e1a024be + Author: Thomas Köppe + Date: Mon Aug 22 14:06:39 2022 +0100 + + [flat.multiset.ctor] Add missing parameter name "cont" + + commit 96fce7b5259e1bfe1688cc60df2d6b2ecf3e7cd1 + Author: Thomas Köppe + Date: Mon Aug 22 11:49:41 2022 +0100 + + [flat.*.{syn,erasure}] Change return type of erase_if to member size_type + + All other containers and container adapters use the member size_type, + and the flat maps already did so in the item specification, but not in + the synopsis. + + The current wording follows the approved proposals, but this change + seems like an improvement. + + Suggested by CD review feedback. + + commit 7f11031bf6e41515a8779bdbfe741f4f9bbdfccc + Author: Thomas Köppe + Date: Sat Aug 20 21:14:55 2022 +0100 + + [diff] Uniform style for examples + + For C++ differences, examples are always preceded by the phrase "For + example:", do not use the usual [Example n: ... -- end example] style, + and always appear in the "Effects on original feature" paragraph. + + For differences with C, a different set of styles is used (examples + being part of paragraphs such as "Change" and "Rationale"), and that + subclause remains unchanged by this commit. + + commit d4280f38ddd489aecd8fb0da17a41f577db42e2a + Author: Thomas Köppe + Date: Sat Aug 20 23:11:39 2022 +0100 + + [memory.syn] Add missing "// freestanding" comment to "destroy" + + The comment was supposed to be added by P1642R11, but was accidentally + omitted. + + commit 47b0e73cc1e8d2ea344afedf60e07ec80df118f4 + Author: mordante + Date: Mon Aug 22 17:48:36 2022 +0200 + + [format.string.std] Reorder std-format-spec field descriptions. (#5246) + + Moves the wording describing the zero-padding before the description of + the width; matching the order of the fields in the std-format-spec. + + The original order was introduced in the initial paper P0645R10 "Text Formatting". + Since both fields had one paragraph of description, it wasn't too noticeable. P1868R2 "🦄 width: + clarifying units of width and precision in std::format" expanded the wording of the width. + Now it's not so easy to find the description of the zero-padding field. + + commit 517290b26fa8391d3b77d43ca8c271bb92695db7 + Author: Thomas Köppe + Date: Mon Aug 22 17:06:34 2022 +0100 + + [range.cartesian.view] Further fixing of cartesian-product-is-common + + The first fix in 8275c19b3fa9e7cb09f84049ebd6207aceb7ca80 was + incorrect. Only Const needs to be dropped (which was an error + in the paper), but ignoring Vs... is intentional. + + commit 101e7205882495cec1a944c7f6190b08bd131543 + Author: Thomas Köppe + Date: Mon Aug 22 17:23:46 2022 +0100 + + [ranges] Add missing closing delimiters + + commit 17be256d2431f66842479bf7ab2e92f30fff3060 + Author: Jens Maurer + Date: Sat Jun 18 21:39:06 2022 +0200 + + [alg.partitions] Indicate base of logarithm outside big-oh notation + + commit c6e83c4dba380b235be59b21db6c54bdffcb997d + Author: Jens Maurer + Date: Sat Jun 18 21:39:59 2022 +0200 + + [set.difference] Fix grammar typo + + commit 68e365415c707038f8af6c76f0f6f4cd3a4ce407 + Author: Jens Maurer + Date: Sat Jun 18 21:44:05 2022 +0200 + + [uninitialized.move] Fix typos in parameter names + + commit c3c6761111cff26e0e742e4d14b5d9e0bd28c4aa + Author: Jens Maurer + Date: Sat Jun 18 22:53:51 2022 +0200 + + [rand.adapt.disc] Remove superfluous trailing semicolon + + commit 65c9e5bcb3068a1172a66a7507d26a93adae7981 + Author: Jens Maurer + Date: Sat Jun 18 22:55:17 2022 +0200 + + [rand.adapt.ibits] Remove superfluous trailing semicolon + + commit 6ede23707505a18cdbb558108d635a0b21a1eeb0 + Author: Jens Maurer + Date: Sat Jun 18 22:55:47 2022 +0200 + + [rand.adapt.shuf] Remove superfluous trailing semicolon + + commit 5e44bc70b72b64e03e0d09564b2eaf45938a7752 + Author: Jens Maurer + Date: Sat Jun 18 22:58:11 2022 +0200 + + [valarray.members] Fix bad reference to argument + + commit 43b2bce231b04c1ccf7dc4bfd20e13f29c0e9c6c + Author: Jens Maurer + Date: Sun Jun 19 21:29:54 2022 +0200 + + [time.duration.io] Fix grammar typo + + commit 6e9b678f03a1a4fa8218152596a1952c209d1f27 + Author: Jens Maurer + Date: Sun Jun 19 21:32:40 2022 +0200 + + [time.cal.year.members] Fix erroneous qualified-id + + commit f0ab64a1dcb5bac1249ff67e838a7f899efeb586 + Author: Jens Maurer + Date: Sun Jun 19 21:39:48 2022 +0200 + + [locale.codecvt.general] Remove extra space before template-argument-list + + commit bbb7552af35266accf98ae718912579527ee11b8 + Author: Jens Maurer + Date: Sun Jun 19 21:41:58 2022 +0200 + + [locale.collate.general] Fix grammar typo + + commit 324dfd448ec5b632fc922015414cd206920b5842 + Author: Jens Maurer + Date: Sun Jun 19 21:45:29 2022 +0200 + + [ios.base.storage] Fix grammar typo + + commit fc53c9ede41d4992dc64f556bc32febb28ad0e1e + Author: Jens Maurer + Date: Sun Jun 19 21:45:58 2022 +0200 + + [fpos] Fix typo in exposition-only member + + commit 47273ceb655716f62fc1c9fe00a317b44c221267 + Author: Jens Maurer + Date: Sun Jun 19 21:47:05 2022 +0200 + + [fpos.operations] Fix name of type trait + + commit 04d7e61e9deaf2481d144e2c0a7d2478cff58764 + Author: Jens Maurer + Date: Sun Jun 19 21:49:00 2022 +0200 + + [streambuf.cons] Fix grammar typo + + commit f055ba09397bd479317a92c315e5a074f7c2e474 + Author: Jens Maurer + Date: Sun Apr 17 11:19:04 2022 +0200 + + [atomics.syn] Move namespace-scope memory_order_* variables here + + commit f400d80927fd580f99f5f2d94c3d07eaa47373d0 + Author: Jens Maurer + Date: Sun Apr 17 11:23:54 2022 +0200 + + [ranges.syn] Move namespace-scope declarations for get(subrange) here + + commit e9434db227e8b3113a477dcdd0c6c14ffe2c14b8 + Author: Jonathan Wakely + Date: Mon Aug 22 18:56:41 2022 +0100 + + [tuple.creation] Add missing semi-colon to example + + commit 25bb0a278e8141613f2c813c50a74428e3da7b8b + Author: Jonathan Wakely + Date: Mon Aug 22 18:58:39 2022 +0100 + + [util.smartptr.shared.obs], [util.smartptr.shared.create] use nullptr for null pointer constant + + commit 7a4324c21e4f66af801bc7e7fc78b94119253301 + Author: Jonathan Wakely + Date: Mon Aug 22 21:52:22 2022 +0100 + + [char.traits.require] use nullptr for null pointer constant + + commit b3b64b35ce456a7e54476b9a00185323b68fcd6d + Author: Jonathan Wakely + Date: Mon Aug 22 22:01:22 2022 +0100 + + [unord.req.general] Use "constant" not "const" + + commit a421a3029418651b9734ae786c9b89b72b08b42d + Author: Jonathan Wakely + Date: Mon Aug 22 22:09:00 2022 +0100 + + [unord.multimap.overview] Fix presentation of member types + + As already done in de6b0e70ffe2da0a0f91ce434863202f78c9e029 for unordered_map. + + commit a758844278a818fd8ccbd33a6ca0460b31616d74 + Author: Jonathan Wakely + Date: Mon Aug 22 22:33:04 2022 +0100 + + [range.elements.view] fix class-key for iterator and sentinel + + commit 44b146eda750e453ee3d52587c2accab4be6c74d + Author: Jonathan Wakely + Date: Mon Aug 22 22:35:18 2022 +0100 + + [range.elements.iterator] remove stray semi-colon + + commit 3a51f3e858e14abc0623f8823e0d2c883c27a4e4 + Author: Jonathan Wakely + Date: Mon Aug 22 22:45:30 2022 +0100 + + [complex.ops] use character literal for single character + + commit 678907e6d8af62cab9429b7065be69c36ffa2592 + Author: Jonathan Wakely + Date: Mon Aug 22 22:46:43 2022 +0100 + + [rand.req.dist] fix grammar typo + + commit 698be9d6b09517dc1323ca99fc4bb84ec62fae9e + Author: Jonathan Wakely + Date: Mon Aug 22 22:56:42 2022 +0100 + + [cons.slice], [gslice.cons] remove undeclared/undocumented copy constructor signatures + + commit 1cda1f9d2ac5d8caa81e793ce3f95364aba1fb6b + Author: Jonathan Wakely + Date: Mon Aug 22 23:01:23 2022 +0100 + + [template.mask.array.overview], [template.indirect.array.overview] fix itemdecl typos + + commit f3ddcf79a971f488b3acf0e52ca6ea9689af7fd7 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Aug 23 19:58:08 2022 +0800 + + [ranges.cartesian.iterator] Fix typo "reference_t" => "range_reference_t" (#5777) + + commit 227c3b249f0f52484920400b861717649895e6cc + Author: cor3ntin + Date: Tue Aug 23 14:00:44 2022 +0200 + + [range.adjacent.overview] Use tuple in example, not pair (#5779) + + adjacent_view always yields tuples, but the example was written as if it yielded a std::pair. + + commit c0c0d75402b1dc33f0cba971c898dc2ac7bfaa06 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Aug 23 20:00:49 2022 +0800 + + [range.cartesian.view] Add missing angle brackets for cartesian-is-sized-sentinel + + commit c777f930668fe23ab287ff765463d3b3731696eb + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Aug 23 21:45:23 2022 +0800 + + [range.zip, ranges.cartesian.iterator] Simplify `maybe-const` to `const Views` (#5778) + + The type `maybe-const` only appears after `Const &&` + in these cases, so that only the case where `Const` is `true` matters. + + commit eca39f43798d7a58fdd482232c60b6db428b656f + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Aug 24 01:57:58 2022 +0800 + + [tuple.syn, tuple.like] Fix template head formatting (#5784) + + commit 356fb7ff88b63d956b1109c72c5e3bf424f6ba29 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Aug 24 01:58:17 2022 +0800 + + [algorithm.syn] Fix template head formatting (#5786) + + commit 6ccb959c7a8c10fc5fa7dd469c64f3c992e7e7ee + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Aug 23 20:10:44 2022 +0800 + + [range.zip.overview] Use tuple in example, not pair + + commit 8404284d8b7ac6ff2725a33d5e33410d1ea3b470 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Aug 23 23:10:39 2022 +0800 + + [range.drop.overview, range.take.overview] Fixed unformatted (void)F, decay-copy(E) + + commit 6e2b23594abd64c9ba50934654c68bd174c7ab91 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Aug 24 18:49:21 2022 +0800 + + [format.range.fmtstr] Add ranges namespace qualifier (#5788) + + The range concept is named outside of the `ranges` namespace. + + commit 301f0cdcb547f54b1d39163550a5869a0c6b073f + Author: Thomas Köppe + Date: Thu Aug 25 02:28:09 2022 +0100 + + [coroutine.syn] Move "all freestanding" comment to the top + + commit e38650de03741a87d6c625ce93974946f46f5caa + Author: Thomas Köppe + Date: Thu Aug 25 02:41:49 2022 +0100 + + [tuple.like] Remove extraneous "std::" qualification. + + commit 3da6b0e8798681144b676b3b4180301f8f7c8f2c + Author: Thomas Köppe + Date: Thu Aug 25 10:55:25 2022 +0100 + + [const.iterators.{alias,iterators}] Add "exposition only" comments + + Suggested by CD review feedback. + + commit 5dd0216a477391fbce339e22f169136420472979 + Author: Thomas Köppe + Date: Thu Aug 25 11:12:24 2022 +0100 + + [range.refinements] Fix template argument name ("T", not "R") + + commit 347ded018d09d2a226e3ab42665d1a13b25d489a + Author: Thomas Köppe + Date: Thu Aug 25 11:27:38 2022 +0100 + + [vector.bool.pspc] Reinstate redundant "inline", as per paper + + The "inline" was removed editorially in + 2141dab25c7f6d186d662e0ebe916efcd56843ae, but CD review has requested + we retain it. + + commit 79ab62930d2538e1ef668c6a1b50e8d7027ebedc + Author: Thomas Köppe + Date: Thu Aug 25 11:34:57 2022 +0100 + + [format.string.escaped] Fix typos in "APOSTROPHE" + + commit 426ce8a7ec2232aebaaf76bf2f5e4a69a500cef6 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Thu Aug 25 19:31:57 2022 +0800 + + [ranges] Tweak some examples (#5791) + + Removes redundant `std::` qualifications and uses `views::meow` instead of `meow_view`. + + commit 4ed7fcf6b725207ac307a6d1411ad2aa4ed55c8f + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Aug 26 04:36:08 2022 +0800 + + [containers] Add `std::` for `forward`/`move` (#5793) + + commit aec46d1970a8869db0d178c436545b0e40968425 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Aug 26 04:43:03 2022 +0800 + + [move.sentinel] Remove extraneous "std" qualification in example (#5792) + + commit ed18148b1d514c0aea12d99b1ec3a56d4a834266 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Aug 26 15:00:12 2022 +0800 + + [util.smartptr.shared.create] Add std:: qualification for forward + + commit eb703517cd6c79f56df12c5dca359121efbef4ee + Author: Thomas Köppe + Date: Fri Aug 26 14:39:39 2022 +0100 + + [range.move.wrap] Fix constraint (move, not copy-constructible) + + This was accidentally omitted from previous changes requested by P2494R2. + + commit 2a600822d08332a8350e3a093212bdc7f8a82e2b + Author: Thomas Köppe + Date: Fri Aug 26 15:06:06 2022 +0100 + + [format.range.fmtdef] Add "exposition only" comments + + commit 9d71b7d3b0aac1f179fc3973b0ff1624b00b07ce + Author: Thomas Köppe + Date: Fri Aug 26 15:26:39 2022 +0100 + + [obj.lifetime] Add cross-reference pointing at basic.types.general + + Suggested by CD review feedback. + + commit 9eb92bf36b19381a534273ad98e296dfeb7a0fc9 + Author: Jens Maurer + Date: Mon Aug 29 22:45:41 2022 +0200 + + [flat.set.modifiers] Remove stray 'return' in Effects clause + + commit 69177109f387d3958ffea237c9b0419e4d2aa49c + Author: Thomas Köppe + Date: Fri Sep 2 23:44:14 2022 +0100 + + [expr.ass] Fix typo, "~" should be "^". + + This was a misapplication of P2327R1 in 0aebf5cacded1b64cf089dbc7a0504fbb9f50aa6. + + commit e6e17d5e136934f113d6e0a8bde4c227459a9d47 + Author: Thomas Köppe + Date: Sat Sep 3 02:10:27 2022 +0100 + + [diff.cpp20.{dcl,expr}] Fix subclause order to match main document + + commit 853747c5d8130880b96a39ab940c343aa7530d71 + Author: Thomas Köppe + Date: Sat Sep 3 15:02:00 2022 +0100 + + [basic.fundamental] Use correct number; "are", not "is". + + commit 07e02a80fe890dcb6e84182a5697046f1bd4c630 + Author: Jens Maurer + Date: Mon Aug 29 22:23:54 2022 +0200 + + [expected.object.assign] Add missing 'Returns: *this' + + commit 06dcf0556631382ecdc420c22c66366168c226b4 + Author: Thomas Köppe + Date: Sun Sep 4 13:01:12 2022 +0100 + + [mdspan.layout.left.overview] Reorder "explicit" and "constexpr" + + The standard ordering is "constexpr explicit", not the other way + round. The paper P0009R18 contains a non-standard style, and other + instances had already been fixed. Only this one seems to have been + missed previously. + + commit e651f145df7c587ea810aca754e680bb27ea8481 + Author: Thomas Köppe + Date: Sun Sep 4 13:08:42 2022 +0100 + + [mdspan.layout.{left,right}.overview] Replace "see below" with condition + + The condition is spelled out in the item descriptions already, and the + class synopses seem to simply have been inconsistent with that in the + incoming paper P0009R18. Since the "see below"s are never referenced + explicitly, we just replace them with the actual conditions, which is + also how the surrounding members are presented. + + commit 1765844a9382e1f3415bbbdcd12eaa09a6b1f827 + Author: Thomas Köppe + Date: Sun Sep 4 13:25:52 2022 +0100 + + [mdspan.layout.stride.expo] Move "otherwise" from trailing to leading + + We have a mild preference for the leading position. + + commit c02512ecf3f15fb0f29dc602eb153bc7dabd643d + Author: Thomas Köppe + Date: Sun Sep 4 13:53:01 2022 +0100 + + [mdspan.layout.stride.obs] Add missing parentheses + + commit 9897c566ec3ecd6f25078a3dd10ce34c17e812e7 + Author: Thomas Köppe + Date: Sun Sep 4 13:54:19 2022 +0100 + + [mdspan.accessor.default.members] Fix typo in "equivalent" + + commit 3b6163d1a3b1f5cc2be49d6ff0eb6b3889b552df + Author: Thomas Köppe + Date: Sun Sep 4 13:58:09 2022 +0100 + + [flat.map.syn] Add missing "namespace std {" + + commit c164add6cdac73cae85649ba2172de43c3d8ed5b + Author: Thomas Köppe + Date: Sun Sep 4 14:02:11 2022 +0100 + + [flat.map.modifiers] Typo: "range" should be "rg" + + commit 1b427b20fecbc95b98d2380e0ddae71b71c1f657 + Author: Thomas Köppe + Date: Sun Sep 4 14:06:53 2022 +0100 + + [flat.{,multi}set.ctor] Add missing "explicit" in itemdecls + + commit 8f153df9c66c33f100ec7a4d7998dfaf6a7aa8da + Author: Thomas Köppe + Date: Thu Nov 26 02:43:37 2020 +0000 + + [basic, except, diff] Rewordings to avoid "might" and "could" diff --git a/papers/n4929.html b/papers/n4929.html new file mode 100644 index 0000000000..9d0ae5c6b6 --- /dev/null +++ b/papers/n4929.html @@ -0,0 +1,1017 @@ + + + + + +N4929 + + +

N4929 Editors' Report -- Programming Languages -- C++

+ +

Date: 2022-12-18

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

Thanks to all those who have submitted editorial +issues +and to those who have provided pull requests with fixes. +Thank you also to Dan Raviv and Robert Leahy for drafting motion applications, +and special thanks to Johel Ernesto Guerrero Peña for providing in-depth review +of many of the draft motion applications.

+ +

New papers

+ +
    +
  • N4928 is the +current working draft for C++23. It replaces +N4917.
  • +
  • N4929 is this Editors' Report.
  • +
+ +

National body comments on the Committee Draft

+ +

N4919 is the C++23 Committee Draft. It received 137 comments from national bodies. +The working group's responses to the issues so far is noted below.

+ +

Editorial comments

+ +

The following 11 national body comments are editorial in nature, and fixes for +them have been applied.

+ +
    +
  • FR 008: Accepted; fixed by 6a1c5050c21ac26fcb2b5b187a0de867713568dc.
  • +
  • FR 027: Accepted; fixed by b2fa70faa783827cd38b819409e94da2523333f2. +New subclauses "contiguous access" and "mulitidimensional access" have been added +to organize the content for span and mdspan.
  • +
  • US 029: Accepted with modifications; fixed by 6c51392a3d1c3c928ef1c20c19e8efe6efed7dc1. +This issue had already been fixed editorially prior to the NB comments.
  • +
  • US 034: Accepted; fixed by 3e825f144f2aa8668c9a1a94066b43799e08a6e7.
  • +
  • CA 062: Accepted with modifications; fixed by d829eac310981e688a15b28622a2f048d23eed65. +A second erroneous comment with the same problem has also been corrected in the same way.
  • +
  • US 100: Accepted; fixed by 92de5996625efcb070f99681acd2e39efc206ee2.
  • +
  • US 119: Accepted with modifications; fixed by 24e046896029a11f2cb78fd6db21482fb0d4be66. +We removed the colon after "equivalent to" and the semicolon after "throw", +and connected the next sentence with a comma.
  • +
  • US 120: Accepted; fixed by 3f47d2565f26a9144e8076641ee55bf7be79f896.
  • +
  • GB 129: Accepted with modifications; fixed by fb0df97e7d7c2c75bbdf7164c33b0796024ff6d3. +Reviewed by LWG and considered editorial.
  • +
  • GB 136: Accepted; fixed by e0bab4b7f2d8afe5d3939aa49fe6de4fd5e638c6.
  • +
  • GB 137: Accepted; fixed by 9512e41e30cf24a8e93e8c8568ff1b5c14398cc6 and 0783dde32073b02b369c7c3893f4f496a83e3658.
  • +
+ +

Non-editorial comments

+ +
    +
  • FR 004: Partially fixed by P1264R2 (LWG poll 12).
  • +
  • FR 005: Fixed by CWG2631 (CWG poll 4).
  • +
  • FR 009: Duplicate of GB 093
  • +
  • FR 019: Duplicate of US 123
  • +
  • US 028: Fixed by CWG2640 (CWG poll 4).
  • +
  • US 030: Fixed by CWG2639 (CWG poll 4).
  • +
  • US 033: Fixed by CWG2242 (CWG poll 3).
  • +
  • DE 038: Fixed by P2718R0 (CWG poll 12).
  • +
  • US 039: Fixed by CWG2643 (CWG poll 3).
  • +
  • US 042: Fixed by CWG2644 (CWG poll 3).
  • +
  • US 044: Fixed by CWG2645 (CWG poll 3).
  • +
  • US 045: Fixed by CWG2654 (CWG poll 5).
  • +
  • US 045: Fixed by CWG2654 (CWG poll 5).
  • +
  • DE 046: Fixed by P2564R3 (CWG poll 9).
  • +
  • US 047: Fixed by CWG2647 (CWG poll 3).
  • +
  • GB 048: Fixed by P2647R1 (CWG poll 8).
  • +
  • GB 051: Fixed by CWG2653 (CWG poll 4).
  • +
  • US 052: Fixed by CWG2646 (CWG poll 3).
  • +
  • CA 054: Fixed by CWG2621 (CWG poll 3).
  • +
  • GB 055: Fixed by CWG2538 (CWG poll 6).
  • +
  • GB 059: Fixed by P2615R1 (CWG poll 11).
  • +
  • US 061: Fixed by P2706R0 (CWG poll 10).
  • +
  • CA 063: Fixed by CWG2648 (CWG poll 3).
  • +
  • CA 064: Fixed by CWG2649 (CWG poll 3).
  • +
  • CA 065: Fixed by P2589R1 (CWG poll 7).
  • +
  • US 068: Fixed by CWG2650 (CWG poll 3).
  • +
  • US 069: Fixed by CWG2651 (CWG poll 3).
  • +
  • GB 070: Fixed by CWG2615 (CWG poll 4).
  • +
  • US 071: Fixed by CWG2652 (CWG poll 4).
  • +
  • US 073: Fixed by P2167R3 (LWG poll 10).
  • +
  • GB 074: Fixed by LWG3818 (LWG poll 8).
  • +
  • GB 075: Fixed by LWG3753 (LWG poll 8).
  • +
  • GB 085: Fixed by LWG3814 (LWG poll 8).
  • +
  • GB 090: Fixed by LWG3823 (LWG poll 8).
  • +
  • US 091: Duplicate of GB 093
  • +
  • US 092: Duplicate of GB 093
  • +
  • GB 093: Fixed by P2505R5 (LWG poll 13).
  • +
  • GB 095: Fixed by LWG3824 (LWG poll 8).
  • +
  • GB 101: Fixed by LWG3817 (LWG poll 8).
  • +
  • US 103: Fixed by LWG3816 (LWG poll 8).
  • +
  • US 109: Partially fixed by LWG3717 + and LWG3737 (LWG poll 8).
  • +
  • GB 110: Fixed by LWG3814 (LWG poll 8).
  • +
  • US 111: Fixed by P2602R2 (LWG poll 9).
  • +
  • US 118: Fixed by LWG3826 (LWG poll 8).
  • +
  • US 123: Fixed by P2539R4 (LWG poll 11).
  • +
  • US 124: Duplicate of US 123
  • +
  • US 125: Fixed by LWG3822 (LWG poll 8).
  • +
  • GB 130: Partially fixed by LWG3814 (LWG poll 8).
  • +
  • US 132: Fixed by CWG2636 (CWG poll 3).
  • +
+ +

Motions incorporated into working draft

+ +

Notes

+ +
    +
  • CWG issue 2602 was withdrawn from the motions. Even though it is part of +P2709R0, +it has not been applied.
  • +
  • CWG issue 2642 (in +P2710R0, +polled in CWG poll 3) was discovered to be incorrect after the WG21 meeting; +CWG has requested that the issue not be applied and reverted to the working +group for further discussion. It has not been applied.
  • +
+ +

Core working group polls

+ +

CWG poll 1: Accept as Defect Reports all issues except 2635 and 2602 in P2709R0 (Core Language Working Group "ready" Issues for the November, 2022 meeting) and apply their proposed resolutions to the C++ Working Paper.

+ +

CWG poll 2: Accept as a Defect Report issue 2635 (Constrained structured bindings) in P2709R0 (Core Language Working Group "ready" Issues for the November, 2022 meeting) and apply its proposed resolution to the C++ Working Paper.

+ +

CWG poll 3: Accept as Defect Reports all issues except 2615, 2639, 2640, 2652, 2653, 2654, and 2538 in P2710R0 (Core Language Working Group NB comment resolutions for the November, 2022 meeting) and apply their proposed resolution to the C++ Working Paper, resolving the NB comments as indicated.

+ +

CWG poll 4: Apply the proposed resolutions of issues 2615, 2639, 2640, 2652, and 2653 in P2710R0 (Core Language Working Group NB comment resolutions for the November, 2022 meeting) to the C++ Working Paper, resolving the NB comments as indicated.

+ +

CWG poll 5: Accept as a Defect Report issue 2654 (Un-deprecation of compound volatile assignments) in P2710R0 (Core Language Working Group NB comment resolutions for the November, 2022 meeting) and apply its proposed resolution to the C++ Working Paper, resolving NB comment US 16-045.

+ +

CWG poll 6: Accept as a Defect Report issue 2538 (Can standard attributes be syntactically ignored?) in P2710R0 (Core Language Working Group NB comment resolutions for the November, 2022 meeting) and apply its proposed resolution to the C++ Working Paper, resolving NB comment GB-055.

+ +

CWG poll 7: Apply the changes in P2589R1 (static operator[]) to the C++ Working Paper, resolving NB comment CA-065.

+ +

CWG poll 8: Accept as a Defect Report and apply the changes in P2647R1 (Permitting static constexpr variables in constexpr functions) to the C++ Working Paper, resolving NB comment GB-048.

+ +

CWG poll 9: Accept as a Defect Report and apply the changes in P2564R3 (consteval needs to propagate up) to the C++ Working Paper, resolving NB comment DE-046.

+ +

CWG poll 10: Accept as a Defect Report and apply the changes in P2706R0 (Redundant specification for defaulted functions) to the C++ Working Paper, resolving NB comment US 26-061.

+ +

CWG poll 11: Accept as a Defect Report and apply the changes in P2615R1 (Meaningful exports) to the C++ Working Paper, resolving NB comment GB-059.

+ +

CWG poll 12: Apply the changes in P2718R0 (Wording for P2644R1 Fix for Range-based for Loop) to the C++ Working Paper, resolving NB comment DE-038.

+ +

Library working group polls

+ +

Polls 1–6 do not concern the C++ Working Paper.

+ +

LWG poll 7: Apply the changes for all Ready and Tentatively Ready issues in P2703R0 (C++ Standard Library Ready Issues to be moved in Kona, Nov. 2022) to the C++ working paper.

+ +

LWG poll 8: Apply the changes for all Immediate issues in P2704R0 (C++ Standard Library Immediate Issues to be moved in Kona, Nov. 2022) to the C++ working paper.

+ +

LWG poll 9: Apply the changes in P2602R2 (Poison Pills are Too Toxic) to the C++ working paper. This addresses ballot comment US 49-111.

+ +

LWG poll 10: Apply the changes in P2167R3 (Improved Proposed Wording for LWG 2114 (contextually convertible to bool)) to the C++ working paper. This addresses ballot comment US 32-073.

+ +

LWG poll 11: Apply the changes in P2539R4 (Should the output of std::print to a terminal be synchronized with the underlying stream?) to the C++ working paper. This addresses ballot comment US 58-123 (and duplicates US 59-124 and FR-001-019).

+ +

LWG poll 12: Apply the changes in P1264R2 (Revising the wording of stream input operations) to the C++ working paper. This partially addresses ballot comment FR-018-004.

+ +

LWG poll 13: Apply the changes in P2505R5 (Monadic Functions for std::expected) to the C++ working paper. This addresses ballot comments GB-093, US 36-091, US 35-092, and FR-011-009.

+ +

LWG poll 14: Apply the changes in P2696R0 (Introduce Cpp17Swappable as additional convenience requirements) to the C++ working paper.

+ +

Noteworthy editorial changes

+ +
    +
  • There were no noteworthy changes to the wording of the approved papers.
  • +
  • A new subclause "Arithmetic types" was added. The new subclause contains +both "integer types" (<cstdint>) and the new "extended floating-point +types" (<stdfloat>). Previously, the newly added <stdfloat> synopsis +was somewhat disconnected and out of context.
  • +
+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4917 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 7772de4408db8122431169156ea230803cb6bf56
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Sep 6 19:47:21 2022 +0100
+
+    [headers] Reflow table after header additions
+
+commit 3231e8115e93a24806694c36f1eb2d709fe78f4f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 12 15:49:22 2022 +0200
+
+    [basic.align] Recommend alignment-specifier instead of deprecated library facility
+
+commit 37d46b0d41d014febacd9ffe684eb0cf11a5c364
+Author: Chuanqi Xu <yedeng.yd@linux.alibaba.com>
+Date:   Tue Jun 7 16:19:08 2022 +0800
+
+    [module.reach] Remove redundant module implementation unit declaration
+
+commit 4e2297b8d2543062edf347ec13341a8356f59605
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Sep 9 04:12:51 2022 +0800
+
+    [thread.stoptoken.syn] "class template", not just "class"; fix spacing (#5799)
+
+commit 20452e91b30d0a299a03d937f443a81537dc03f2
+Author: xmh0511 <970252187@qq.com>
+Date:   Fri Sep 9 04:54:01 2022 +0800
+
+    [basic.def.odr] A variable is "named by" an expression (#5534)
+
+    The previous wording, a variable "whose name appears
+    as [an] expression", is less precise and not well-defined.
+
+commit 7260f30c74eaf670b3f3d33a7571f6c055930cd7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jan 21 23:27:34 2022 +0100
+
+    [basic.life] Add cross-reference for union member lifetime
+
+commit ba51a5375fa3099e4a85594f2e67d48bc11ec448
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Mar 20 11:58:33 2017 +0000
+
+    [rand.req.seedseq] Rephrase in terms of const types not values
+
+commit 88e574edc674e85911ea1a5b4e87c07457d97bf1
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Mar 20 12:23:12 2017 +0000
+
+    [container.requirements] Rephrase in terms of const types not values
+
+commit 547987d9d203bb7f1f18297ca438ccb18d8fe612
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Sep 14 14:39:16 2022 +0800
+
+    [range.chunk.view.input, range.slide.view] Remove unused name in the deduction guide
+
+commit c774ac4a072efd41e478d72ad57a3dae8b0946ff
+Author: Mathias Stearn <redbeard0531@gmail.com>
+Date:   Fri Sep 16 17:46:10 2022 +0200
+
+    [basic.life] Change "complete const object" to "const, complete object" (#5818)
+
+    "Complete object" is a defined term (https://eel.is/c++draft/basic#def:complete_object).
+    Putting "const" in the middle of that leaves it ambiguous whether we are referring to
+    a const-qualified "complete object", or to a complete const object with some other meaning
+    of "complete" (such as "with a complete type").
+
+commit 787ea7683982ed58b1a8bf7bbfb7c77f8d227dce
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 16 21:24:15 2022 +0200
+
+    [diagnostics] Remove 'shall', use 'recommended practice'
+
+commit 9a005c04b91ffa9b92e6a57a03419091f365bc9b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 16 21:57:46 2022 +0200
+
+    [func.bind.isplace] Add cross-reference to [func.bind.place]
+
+commit 7bd72a7671d9bee0eed11578e325460bcf7fa5a1
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 16 22:09:23 2022 +0200
+
+    [vector.bool.pspc] Index vector<bool>::reference
+
+commit f68d6428f27d5cd722e713262d8986489484ae02
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Sep 16 22:18:36 2022 +0200
+
+    [over.best.ics.general] Split long paragraph
+
+commit 1383e97e21d6d10ac210344d66ab715cfc0f747a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Sep 15 15:38:58 2022 +0100
+
+    [ranges.syn] Make get overloads freestanding
+
+    These were moved to the synopsis after the P1642 changes to mark nearly
+    everything in the synopsis freestanding, so they were not marked.
+
+commit c70087afe980f9ec339f088babde575e04e185d7
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Sat Sep 17 02:29:45 2022 +0500
+
+    [expr.add] Move note, add example (#4778)
+
+    The original note wasn't quite in the right place.
+    It is moved and made more concrete.
+
+    In the original place of the note we now put
+    a more immediately relevant example.
+
+commit 6000c29e5b9547bf457f4461fd538670144ad88c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Sep 17 10:05:19 2022 +0200
+
+    [format.string.std] Clarify location of 0x prefix for pointers
+
+commit 718873b512d0687143bbfa00e18edfb0a8b164ce
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Sep 17 08:56:36 2022 +0200
+
+    [expr.prim.lambda.capture] Cross-reference [basic.def.odr] for 'odr-usable'
+
+commit 6a98fd8c1f9ea79961b78f731637ba9fe9d52218
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Sep 17 09:05:57 2022 +0200
+
+    [thread.thread.this] Clarify this_thread::get_id
+
+commit 90c4ba5624a655af5c5d8b11c1137d552f3e0a60
+Author: Casey Carter <Casey@Carter.net>
+Date:   Sun Sep 18 14:55:55 2022 -0700
+
+    [headers] Order `<type_traits>` before `<typeindex>` in the header table
+
+    Fixes #5853.
+
+commit 16f92154ce99a5fef26c53c464e8b14ad5b78d79
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Sep 20 05:37:31 2022 +0800
+
+    [c.math.hypot3] Fix mis-transcribed parameter type (#5852)
+
+    The paper P1467R9 says that the third parameter of `hypot` should be
+    `_floating-point-type_`, but it was erroneously transcribed as `double`.
+
+commit db26a63222f10cec871656958b3e296e529df67e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Sep 21 22:18:51 2022 +0100
+
+    [support, etc.] New subclause "Arithmetic types". (#5851)
+
+    The new subclause contains both "integer types" (<cstdint>)
+    and "extended floating-point types" (<stdfloat>).
+
+    Previously, the newly added <stdfloat> synopsis was somewhat
+    disconnected and out of context.
+
+    This change removes the stable labels [cstdint] and [cstdint.general].
+
+commit d462173b5afdc8506d85e5395f2be19311895f2d
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Sep 19 20:42:44 2022 -0700
+
+    [mdspan.extents.cons] Correct spelling of "dynamic-extents"
+
+commit 14a10ef0948f4709cd1114c489b8e4b919ba7cbc
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Sep 22 05:20:44 2022 +0800
+
+    [unord.general, container.adaptors.general] Fix list of exposition-only alias templates (#5840)
+
+commit aab149233f76df37979d777ffd2b3151c52d48a9
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Sep 22 10:51:46 2022 +0100
+
+    [template.bitset] reorder synopsis and member descriptions
+
+    Group shifts together and use same order for synopsis and detailed
+    descriptions.
+
+    Also remove the unnecessary "for b[i];" comments explaining what
+    operator[] does, and add a comment introducing the group containing
+    count(), size() etc.
+
+commit 63e4a76f780c925a13efeb06955252d7c37ed4ef
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Sep 22 09:30:14 2022 +0800
+
+    [range.as.const.overview] Remove unnecessary ranges namespace qualification
+
+commit 179436adbe60c277fa6512352ee27e26f192bf2b
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Fri Sep 23 12:45:09 2022 -0400
+
+    [utility.arg.requirements] Present identifiers as itemization (#5856)
+
+    Lists providing the key for names used throughout a subclause are difficult
+    to follow when buried as a single sentence in a paragraph. This change updates
+    the key to tables 29-36 in [utility.arg.requirements] to a bulleted list
+    following the examples set elsewhere.
+
+    Each key is now consistently introduced with the word "denotes", following
+    the precedent set by similar bullet lists.
+
+    It is not at all coincidental that this also resolves pagination issues
+    at the end of the page, so that the floating tables to not float into the
+    middle of a sentence in the following section.
+
+commit 24d54e30506a62ef41cf4bd0132fbdba45bb6dda
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Sep 27 11:56:32 2022 +0100
+
+    [futures.task.members] Add missing explicit to packaged_task ctor
+
+commit 842424bd228b79876437a1a9393f20f00033476a
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Sep 28 16:39:59 2022 +0800
+
+    [futures.task.members] Correct capitalization
+
+commit d3ddc0906638bb30b5a3ce0f4033148e9a8ed1ff
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Sep 29 15:49:06 2022 +0800
+
+    [container.rev.reqmts] Correct capitalization
+
+commit a7f17181ef5b59ad728b421a83975209406fa037
+Author: Daniel Krügler <daniel.kruegler@gmail.com>
+Date:   Mon Oct 3 17:59:20 2022 +0200
+
+    [sequence.reqmts] Use "lvalues of type T are swappable" (#5878)
+
+commit dd6c7f4012489325bdd65a40cd121b3d25008b0e
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Oct 4 04:41:26 2022 +0800
+
+    [associative.reqmts.general] Fix typo in namespace name (#5881)
+
+commit 42c7b3fb3a3cb11bc1af418cfdd395ecf314aa43
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Oct 4 13:08:17 2022 +0100
+
+    [intro.defs] Update hyperlink according to SC22 requirements
+
+commit 05019b35890b79374fac180a9a9ff9e7cf8d7595
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Oct 4 15:19:01 2022 +0100
+
+    Foreword placeholder
+
+commit b0fab58d4f2b12defdaf7c3ddfb2ddcd1f30e1b5
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Oct 5 11:27:23 2022 +0100
+
+    [temp.local] Fix typo in "inject-class-name" (#5889)
+
+commit f6c5d4512d4b32d63d66669555ab976b315d439c
+Author: mordante <koraq@xs4all.nl>
+Date:   Mon Oct 10 17:50:51 2022 +0200
+
+    [format.string.escaped] Fix example of invalid code unit (#5890)
+
+    Example 5 should only have one invalid code unit. The second code unit is a valid code point.
+
+    This issue was already in the paper P2286R8 "Formatting Ranges".
+
+commit 5f26c516a659cdf3f0ea007cf6c90c690cccc3b6
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Tue Oct 11 04:36:08 2022 +0200
+
+    [bibliography] Remove stray closing parenthesis.
+
+commit 6c51392a3d1c3c928ef1c20c19e8efe6efed7dc1
+Author: Corentin Jabot <corentinjabot@gmail.com>
+Date:   Wed Oct 19 22:29:09 2022 +0200
+
+    [intro.defs] Move the definition of "multibyte character" to library
+
+    This address the US-2 NB comment as per the direction voted on
+    by SG-16.
+
+    No use of "multibyte character" remains before [multibyte.strings].
+
+commit 33e56641d63c5993d288082cf264a733464ff75c
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Tue Oct 25 17:48:03 2022 -0400
+
+    [stack.syn, queue.syn] Add xref comments to class synopses (#5913)
+
+commit 90aa7729b9a926622581354284ecf294a56e410b
+Author: Will Hawkins <8715530+hawkinsw@users.noreply.github.com>
+Date:   Tue Nov 1 04:37:52 2022 -0400
+
+    [range.dangling] Replace "tag type" with just "type" (#5922)
+
+    The extra word "tag" was not adding any value and was potentially,
+    confusing; e.g. the "dangling" type is not like, say, an iterator tag
+    that would be used for overload resolution.
+
+commit fd998c52af2dc6b9c73098fdbd5a22444a358448
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Tue Nov 1 10:45:53 2022 -0400
+
+    [flat.set] [flat.multiset] Use value_type, not key_type
+
+    For consistency with the other `set`, `unordered_set` containers.
+    `key_type` is a synonym for `value_type`, and there's no reason
+    the flat containers need to depart from existing practice here.
+
+commit 48ecaaec300de4a8176c116408cac915142166ce
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Mon Nov 7 14:02:40 2022 -0500
+
+    [flat.multiset.modifiers] Fix typo in "multiset" (#5927)
+
+commit 45d9a5ba5aee1e3c4da8938e12376b36a7147d63
+Author: Eric41293 <eric41293@comcast.net>
+Date:   Mon Nov 7 11:11:58 2022 -0800
+
+    [climits.syn] Correct note about types of macros (#5926)
+
+    This note was added apparently as a response to LWG 416. However, there may have been a misunderstanding of the C standard, and in fact only the macros for `{signed,unsigned,} char` and `{signed,unsigned} int` have a different type.
+
+commit f41cd00273e6ee7ff1a29446b21f230c28bf1a9f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Nov 7 20:59:54 2022 +0000
+
+    [time.clock.system.nonmembers, time.zone.zonedtime.nonmembers] Add <charT> to STATICALLY-WIDEN (#5934)
+
+commit ef7d0e234722d2ef8b4ec069b6f929dc083d8dc7
+Author: Ed Catmur <edward.catmur@mavensecurities.com>
+Date:   Tue Sep 20 18:12:45 2022 +0100
+
+    [meta, thread] Add or amend references to func.{require,invoke}
+
+commit 0d5c9b9310b2f6c6c4259665e1e680936babdc3d
+Author: Eric41293 <eric41293@comcast.net>
+Date:   Mon Nov 7 15:54:55 2022 -0800
+
+    [meta.type.synop] Capitalize NTTP name (#5921)
+
+commit 0959b5c200a6f2b543e2d656850917b8d788767c
+Author: Hui <65944694+huixie90@users.noreply.github.com>
+Date:   Tue Nov 8 00:49:15 2022 +0000
+
+    [range.drop.while.overview] Use string_view rather than string literal (#5897)
+
+    The string literal would have been treated as a `const char*`, which is not a range.
+
+commit 720c3ae24a68fda02a6372eda13ec3f9c6a1a39b
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Nov 8 02:01:34 2022 +0000
+
+    [time.format] Use basic_ostringstream<charT> instead of ostringstream (#5932)
+
+commit 8739d316f2a55c633963b26b748681ff16498887
+Author: Marc Mutz <94039187+marcmutz@users.noreply.github.com>
+Date:   Tue Nov 8 03:05:45 2022 +0100
+
+    [meta.const.eval] Add is_constant_evaluated to index of library names (#5898)
+
+    Previously, only its feature-test macro was listed there.
+
+commit 4c442cf93f03a44ec1f6a93875043a3aca7c5b9b
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Nov 7 23:38:36 2022 -0400
+
+    [class.union.general] Attach example to its note (#5882)
+
+commit 65c494b9a4a5a4fab500733441c04e50a787d318
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Nov 8 15:51:21 2022 +0800
+
+    [mdspan.extents.expo] Remove redundant "// exposition only" (#5907)
+
+commit b766881dda1d0201d98710b11efda3491a84b4f2
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Tue Nov 8 13:15:07 2022 +0500
+
+    [dcl.init.list] Specify the type of the prvalue (#5919)
+
+commit 6e035b52e28e95211a39ffb552851499432b2c6e
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Tue Nov 8 15:30:29 2022 -0400
+
+    [ratio.ratio] Use symbol "sgn" for the signum function (#5925)
+
+commit 89269f8e548b993b239f2c0f5ecc071ee7f54c9a
+Author: Blackteahamburger <blackteahamburger@outlook.com>
+Date:   Wed Nov 9 04:12:59 2022 +0800
+
+    [dcl.link] Add missing restriction to language linkage application (#5892)
+
+    A language linkage specification should only apply to entities that do in fact have language linkage.
+
+commit ea77b2fa83ddac0c52c1b505ff666328a2a8f558
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Nov 9 00:34:26 2022 +0100
+
+    [temp.deduct.general] Fix typo in comment in example
+
+commit 0c196ec375993000547e8913abb4c4ce703144cb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 10 15:32:56 2022 +0100
+
+    [temp.deduct.conv] Remove misleading paragraph break
+
+commit 0cd0c33f648d1304160e6dcb1856affd71b3ebbb
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri Nov 11 18:35:53 2022 -0800
+
+    [mdspan.extents.cons] "constexpr" should precede "explicit"
+
+    In library function declarations, the `constexpr` specifier always precedes the `explicit` specifier per our standing style guide.
+
+commit 608c152dbae69d335d7238cdd5d178e048e2a1fd
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Nov 14 10:48:18 2022 -0800
+
+    [vector.bool.pspc] Replace `constexpr static` with `static constexpr`
+
+    As preferred by our style guide.
+
+commit d829eac310981e688a15b28622a2f048d23eed65
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 10 07:43:32 2022 +0000
+
+    [class.inhctor.init] Fix explanation of "error:" in example
+
+    The correct explanation is that classes `B1` and `D1` do not have
+    default constructors, not that they have deleted default constructors.
+
+    Fixes NB CA 062 (C++23 CD).
+
+commit 6a1c5050c21ac26fcb2b5b187a0de867713568dc
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 8 23:35:00 2022 +0000
+
+    [diff.cpp20.library] Add missing new headers
+
+    Fixes NB FR 008 (C++23 CD).
+
+commit b2fa70faa783827cd38b819409e94da2523333f2
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 9 18:50:56 2022 +0000
+
+    [views] Subclauses for contiguous and multidimensional access
+
+    This organises the material for <span> and <mdspan> into separate
+    subclauses, rather than having all constituent parts being siblings in
+    the same subclause. Even though we now have some subclauses six levels
+    deep, this seems like an improvement. As a drive-by, this allows us to
+    move a subclause on a non-member span helper function up one level,
+    where it is more appropriate.
+
+    Fixes NB FR 027 (C++23 CD).
+
+commit e0bab4b7f2d8afe5d3939aa49fe6de4fd5e638c6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Nov 10 02:16:11 2022 +0000
+
+    [concepts index] Describe exposition-only concepts
+
+    Fixes NB GB 136 (C++23 CD).
+
+commit 9512e41e30cf24a8e93e8c8568ff1b5c14398cc6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 19:31:11 2022 +0000
+
+    [general, library index] Describe exposition-only entities
+
+    Partially fixes NB GB 137 (C++23 CD).
+
+commit 0783dde32073b02b369c7c3893f4f496a83e3658
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Nov 11 19:33:33 2022 +0000
+
+    [func.wrap.move.ctor] Move private expos member to general index
+
+    The private, exposition-only data member is not useful in the library
+    index. However, there seems no reason to not show it in the general
+    index, so we move the index entry from the library index to the
+    general index.
+
+    Partially fixes NB GB 137 (C++23 CD).
+
+commit 3e825f144f2aa8668c9a1a94066b43799e08a6e7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 8 21:31:30 2022 +0000
+
+    [basic.scope.scope] Fix indentation in example
+
+    Fixes NB US 034 (C++23 CD).
+
+commit 92de5996625efcb070f99681acd2e39efc206ee2
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 8 23:24:35 2022 +0000
+
+    [unord.req.general] Fix garbled end of sentence
+
+    This was an editorial mistake introduced by the transformation of the
+    requirement tables into regular paragraphs.
+
+    Fixes NB US 100 (C++23 CD).
+
+commit 24e046896029a11f2cb78fd6db21482fb0d4be66
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 8 21:02:31 2022 +0000
+
+    [coro.generator.promise] Use "equivalent to `throw`, ..."
+
+    Our style guide says that "equivalent to <expression>" is the
+    appropriate style for an expression of type `void`, which is the case
+    for `throw`. This avoids the awkward situation of having "equivalent
+    to: `throws;`" appear in the middle of a paragraph without proper
+    terminal punctuation.
+
+    Fixes NB US 119 (C++23 CD).
+
+commit 3f47d2565f26a9144e8076641ee55bf7be79f896
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 8 21:27:56 2022 +0000
+
+    [coro.generator.promise] Remove unused name "x"
+
+    Fixes NB US 120 (C++23 CD).
+
+commit fb0df97e7d7c2c75bbdf7164c33b0796024ff6d3
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Nov 17 08:44:05 2022 +0000
+
+    [atomics] Replace integral and floating-point placeholders (#5939)
+
+    Fixes NB GB 129 (C++23 CD).
+
+commit 0bb57d5ebffa7170fbc80724f55a6ac2a82f2e83
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Nov 25 14:56:24 2022 +0800
+
+    [format.arg] Add std:: for forward
+
+commit c88fb46327d87d78d571b7e1076e1916eaf7e310
+Author: Dawn Perchik <dawn@brightsidecomputing.com>
+Date:   Tue Nov 15 07:46:41 2022 -0800
+
+    [expr.unary.op] Say "the ~ operator" consistently, remove "unary"
+
+    We are currently using the term "unary complement operator" to refer
+    to the "~" operator without ever giving it that name. This change
+    removes the use of that undefined term.
+
+commit bef02b89464fe6f4be3926d62defc92986ae4532
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Nov 22 16:28:42 2022 +0000
+
+    [expr.unary.op] Notes naming unary ops as {ones',two's} complement
+
+    The terms "one's complement" and "two's complement" are well-known,
+    and it is useful to associate them with these operators.
+
+commit 020a312b2aa513a992e488d82db55fd0cd4fa025
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 16 17:48:12 2022 +0000
+
+    [fs.rec.dir.itr.nonmembers] "for" is a keyword in "range-based for"
+
+commit cee095e75a97fb88a7053e360b3bc06d36a6b687
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Fri Dec 16 06:51:26 2022 +0700
+
+    [depr.conversions.string] remove redundent respecification (#6004)
+
+    There are several typedef names defined precisely in the deprecated code conversion
+    facets classes that are redundantly respecified in text. Nowhere else in the library
+    does this; any specified typedef names are _see below_ definitions, not repeats of
+    the class definition. Needless redundancy is always a risk of divergence, however
+    small, so remove the respecification in text form.
+
+commit 1bb52db31be002f04ea5977f9900ba4174c7155e
+Author: Anoop Rana <93918384+ranaanoop@users.noreply.github.com>
+Date:   Fri Dec 16 05:23:57 2022 +0530
+
+    [concepts.object] Change "built-in" to "fundamental" types (#6012)
+
+commit ce1cc3b011099b6228b18dad937911c6ea67d309
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sun Dec 11 17:03:41 2022 -0400
+
+    [expr.const] Remove redundant "ill-formed" in "error" comment
+
+commit 5d43f0137776fa112d0ffd6ba0e34df34a4cb820
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Dec 13 12:52:00 2022 +0000
+
+    [time.zone.leap.members] update note about leap seconds
+
+commit fd20d4ea9f3ea8653b17169aad61eec843b71718
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Nov 23 14:45:43 2022 +0000
+
+    [time.zone.zonedtime.overview] Rename parameters to match later definitions
+
+commit 137728f0830824c6058648a846376eec80e5cab3
+Author: Michael Florian Hava <mfh@live.at>
+Date:   Fri Dec 16 02:10:55 2022 +0100
+
+    [coro.generator.promise] Fix template parameters (#6009)
+
+    Some of the template parameters of `yield_value` were inconsistent,
+    and the synopsis contained an outright typo. This change uses `R2`
+    consistently since the parameter is a reference.
+
+commit 5d6099c3df78922ee5b5f1d1c42a5c762d246df0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Dec 15 23:31:26 2022 +0000
+
+    [formatter.requirements] Remove one level of list nesting
+
+commit 9e41a1c27de2f676badacbe0c1aac783063b7cd6
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Nov 16 19:43:58 2022 +0000
+
+    [time.clock.req] Make list item end with comma, not full stop.
+
+    Also reformat the itemization source to be more edit-friendly.
+
+commit 5ef31f3fc1531d9e6e923cb57bf6e5ecec59ed4e
+Author: languagelawyer <language.lawyer@gmail.com>
+Date:   Thu Jun 25 10:54:17 2020 +0300
+
+    [expr.unary.op] Fix usage of "result"
+
+commit 8c60752c7eb28e1ff1cc9e088d7836957356f559
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Apr 26 10:18:11 2022 +0100
+
+    [optional.ctor], [expected.object.ctor] Add converts-from-any-cvref
+
+commit 405b46f50ce6c7458e94db7b4528fc267e2b67c3
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sat Dec 17 00:14:51 2022 +0800
+
+    [mdspan.mdspan.overview] Add default template arguments for mdspan (#6018)
+
+    We usually restate the default template arguments in the class synopsis,
+    so that the information is in one place and one does not need to also refer
+    to the header synopsis.
+
+commit ae88bb581d32f1939987c0a834fe3f6011a9d003
+Author: frederick-vs-ja <de34@live.cn>
+Date:   Fri Dec 16 21:25:31 2022 +0800
+
+    [range.repeat] Change `W`/`WArgs` to `T`/`TArgs`
+
+commit 0a1f1e147c75ce9220de3488103ca880b6b8e49f
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 16 17:19:08 2022 +0000
+
+    [concept.copyconstructible] Avoid "possibly \tcode{const}"
+
+    A small rewrite avoids the phrase "possibly \tcode{const}",
+    which we would like to remove entirely in favour of just
+    "possibly const".
+
+commit f058decdf9c7dea0461f723df72f5093f5e92b11
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Dec 16 17:31:47 2022 +0000
+
+    Replace "possibly \tcode{const}" with "possibly const"
+
+    The "const" here is not syntax, but just normal text.
+    This is similar to "inline" and "public", which have
+    previously been cleaned up similarly.
+
+commit 9ac55553459e15c84db6d8072c93787d41ef7ccf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 4 00:29:30 2021 +0200
+
+    [lib] Drop 'inline' from 'inline constexpr' variable templates.
+
+    Since CWG2387, constexpr variable templates have external linkage.
+
+ + diff --git a/papers/n4929.md b/papers/n4929.md new file mode 100644 index 0000000000..36adf1e8d4 --- /dev/null +++ b/papers/n4929.md @@ -0,0 +1,868 @@ +# N4929 Editors' Report -- Programming Languages -- C++ + +Date: 2022-12-18 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. +Thank you also to Dan Raviv and Robert Leahy for drafting motion applications, +and special thanks to Johel Ernesto Guerrero Peña for providing in-depth review +of many of the draft motion applications. + +## New papers + + * [N4928](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4928.pdf) is the + current working draft for C++23. It replaces + [N4917](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4917.pdf). + * N4929 is this Editors' Report. + +## National body comments on the Committee Draft + +N4919 is the C++23 Committee Draft. It received 137 comments from national bodies. +The working group's responses to the issues so far is noted below. + +### Editorial comments + +The following 11 national body comments are editorial in nature, and fixes for +them have been applied. + + * **FR 008:** Accepted; fixed by 6a1c5050c21ac26fcb2b5b187a0de867713568dc. + * **FR 027:** Accepted; fixed by b2fa70faa783827cd38b819409e94da2523333f2. + New subclauses "contiguous access" and "mulitidimensional access" have been added + to organize the content for `span` and `mdspan`. + * **US 029:** Accepted with modifications; fixed by 6c51392a3d1c3c928ef1c20c19e8efe6efed7dc1. + This issue had already been fixed editorially prior to the NB comments. + * **US 034:** Accepted; fixed by 3e825f144f2aa8668c9a1a94066b43799e08a6e7. + * **CA 062:** Accepted with modifications; fixed by d829eac310981e688a15b28622a2f048d23eed65. + A second erroneous comment with the same problem has also been corrected in the same way. + * **US 100:** Accepted; fixed by 92de5996625efcb070f99681acd2e39efc206ee2. + * **US 119:** Accepted with modifications; fixed by 24e046896029a11f2cb78fd6db21482fb0d4be66. + We removed the colon after "equivalent to" and the semicolon after "throw", + and connected the next sentence with a comma. + * **US 120:** Accepted; fixed by 3f47d2565f26a9144e8076641ee55bf7be79f896. + * **GB 129:** Accepted with modifications; fixed by fb0df97e7d7c2c75bbdf7164c33b0796024ff6d3. + Reviewed by LWG and considered editorial. + * **GB 136:** Accepted; fixed by e0bab4b7f2d8afe5d3939aa49fe6de4fd5e638c6. + * **GB 137:** Accepted; fixed by 9512e41e30cf24a8e93e8c8568ff1b5c14398cc6 and 0783dde32073b02b369c7c3893f4f496a83e3658. + +### Non-editorial comments + +* **FR 004:** Partially fixed by [P1264R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1264r2.pdf) (LWG poll 12). +* **FR 005:** Fixed by [CWG2631](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2631) (CWG poll 4). +* **FR 009:** Duplicate of GB 093 +* **FR 019:** Duplicate of US 123 +* **US 028:** Fixed by [CWG2640](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2640) (CWG poll 4). +* **US 030:** Fixed by [CWG2639](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2639) (CWG poll 4). +* **US 033:** Fixed by [CWG2242](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2242) (CWG poll 3). +* **DE 038:** Fixed by [P2718R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2718r0.html) (CWG poll 12). +* **US 039:** Fixed by [CWG2643](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2643) (CWG poll 3). +* **US 042:** Fixed by [CWG2644](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2644) (CWG poll 3). +* **US 044:** Fixed by [CWG2645](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2645) (CWG poll 3). +* **US 045:** Fixed by [CWG2654](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2654) (CWG poll 5). +* **US 045:** Fixed by [CWG2654](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2654) (CWG poll 5). +* **DE 046:** Fixed by [P2564R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2564r3.html) (CWG poll 9). +* **US 047:** Fixed by [CWG2647](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2647) (CWG poll 3). +* **GB 048:** Fixed by [P2647R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2647r1.html) (CWG poll 8). +* **GB 051:** Fixed by [CWG2653](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2653) (CWG poll 4). +* **US 052:** Fixed by [CWG2646](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2646) (CWG poll 3). +* **CA 054:** Fixed by [CWG2621](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2621) (CWG poll 3). +* **GB 055:** Fixed by [CWG2538](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2538) (CWG poll 6). +* **GB 059:** Fixed by [P2615R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2615r1.html) (CWG poll 11). +* **US 061:** Fixed by [P2706R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2706r0.html) (CWG poll 10). +* **CA 063:** Fixed by [CWG2648](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2648) (CWG poll 3). +* **CA 064:** Fixed by [CWG2649](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2649) (CWG poll 3). +* **CA 065:** Fixed by [P2589R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2589r1.pdf) (CWG poll 7). +* **US 068:** Fixed by [CWG2650](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2650) (CWG poll 3). +* **US 069:** Fixed by [CWG2651](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2651) (CWG poll 3). +* **GB 070:** Fixed by [CWG2615](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2615) (CWG poll 4). +* **US 071:** Fixed by [CWG2652](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2652) (CWG poll 4). +* **US 073:** Fixed by [P2167R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2167r3.html) (LWG poll 10). +* **GB 074:** Fixed by [LWG3818](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3818) (LWG poll 8). +* **GB 075:** Fixed by [LWG3753](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3753) (LWG poll 8). +* **GB 085:** Fixed by [LWG3814](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3814) (LWG poll 8). +* **GB 090:** Fixed by [LWG3823](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3823) (LWG poll 8). +* **US 091:** Duplicate of GB 093 +* **US 092:** Duplicate of GB 093 +* **GB 093:** Fixed by [P2505R5](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2505r5.html) (LWG poll 13). +* **GB 095:** Fixed by [LWG3824](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3824) (LWG poll 8). +* **GB 101:** Fixed by [LWG3817](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3817) (LWG poll 8). +* **US 103:** Fixed by [LWG3816](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3816) (LWG poll 8). +* **US 109:** Partially fixed by [LWG3717](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3717) + and [LWG3737](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3737) (LWG poll 8). +* **GB 110:** Fixed by [LWG3814](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3814) (LWG poll 8). +* **US 111:** Fixed by [P2602R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2602r2.html) (LWG poll 9). +* **US 118:** Fixed by [LWG3826](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3826) (LWG poll 8). +* **US 123:** Fixed by [P2539R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2539r4.html) (LWG poll 11). +* **US 124:** Duplicate of US 123 +* **US 125:** Fixed by [LWG3822](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3822) (LWG poll 8). +* **GB 130:** Partially fixed by [LWG3814](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html#3814) (LWG poll 8). +* **US 132:** Fixed by [CWG2636](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2636) (CWG poll 3). + +## Motions incorporated into working draft + +### Notes + + * CWG issue 2602 was withdrawn from the motions. Even though it is part of + [P2709R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2709r0.html), + it has not been applied. + * CWG issue 2642 (in + [P2710R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html#2642), + polled in CWG poll 3) was discovered to be incorrect after the WG21 meeting; + CWG has requested that the issue not be applied and reverted to the working + group for further discussion. It has not been applied. + +### Core working group polls + +CWG poll 1: Accept as Defect Reports all issues except 2635 and 2602 in [P2709R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2709r0.html) (Core Language Working Group "ready" Issues for the November, 2022 meeting) and apply their proposed resolutions to the C++ Working Paper. + +CWG poll 2: Accept as a Defect Report issue 2635 (Constrained structured bindings) in [P2709R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2709r0.html) (Core Language Working Group "ready" Issues for the November, 2022 meeting) and apply its proposed resolution to the C++ Working Paper. + +CWG poll 3: Accept as Defect Reports all issues except 2615, 2639, 2640, 2652, 2653, 2654, and 2538 in [P2710R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html) (Core Language Working Group NB comment resolutions for the November, 2022 meeting) and apply their proposed resolution to the C++ Working Paper, resolving the NB comments as indicated. + +CWG poll 4: Apply the proposed resolutions of issues 2615, 2639, 2640, 2652, and 2653 in [P2710R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html) (Core Language Working Group NB comment resolutions for the November, 2022 meeting) to the C++ Working Paper, resolving the NB comments as indicated. + +CWG poll 5: Accept as a Defect Report issue 2654 (Un-deprecation of compound volatile assignments) in [P2710R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html) (Core Language Working Group NB comment resolutions for the November, 2022 meeting) and apply its proposed resolution to the C++ Working Paper, resolving NB comment US 16-045. + +CWG poll 6: Accept as a Defect Report issue 2538 (Can standard attributes be syntactically ignored?) in [P2710R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2710r0.html) (Core Language Working Group NB comment resolutions for the November, 2022 meeting) and apply its proposed resolution to the C++ Working Paper, resolving NB comment GB-055. + +CWG poll 7: Apply the changes in [P2589R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2589r1.pdf) (`static operator[]`) to the C++ Working Paper, resolving NB comment CA-065. + +CWG poll 8: Accept as a Defect Report and apply the changes in [P2647R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2647r1.html) (Permitting static constexpr variables in constexpr functions) to the C++ Working Paper, resolving NB comment GB-048. + +CWG poll 9: Accept as a Defect Report and apply the changes in [P2564R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2564r3.html) (`consteval` needs to propagate up) to the C++ Working Paper, resolving NB comment DE-046. + +CWG poll 10: Accept as a Defect Report and apply the changes in [P2706R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2706r0.html) (Redundant specification for defaulted functions) to the C++ Working Paper, resolving NB comment US 26-061. + +CWG poll 11: Accept as a Defect Report and apply the changes in [P2615R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2615r1.html) (Meaningful exports) to the C++ Working Paper, resolving NB comment GB-059. + +CWG poll 12: Apply the changes in [P2718R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2718r0.html) (Wording for P2644R1 Fix for Range-based `for` Loop) to the C++ Working Paper, resolving NB comment DE-038. + +### Library working group polls + +Polls 1–6 do not concern the C++ Working Paper. + +LWG poll 7: Apply the changes for all Ready and Tentatively Ready issues in [P2703R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2703r0.html) (C++ Standard Library Ready Issues to be moved in Kona, Nov. 2022) to the C++ working paper. + +LWG poll 8: Apply the changes for all Immediate issues in [P2704R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2704r0.html) (C++ Standard Library Immediate Issues to be moved in Kona, Nov. 2022) to the C++ working paper. + +LWG poll 9: Apply the changes in [P2602R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2602r2.html) (Poison Pills are Too Toxic) to the C++ working paper. This addresses ballot comment US 49-111. + +LWG poll 10: Apply the changes in [P2167R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2167r3.html) (Improved Proposed Wording for LWG 2114 (contextually convertible to `bool`)) to the C++ working paper. This addresses ballot comment US 32-073. + +LWG poll 11: Apply the changes in [P2539R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2539r4.html) (Should the output of `std::print` to a terminal be synchronized with the underlying stream?) to the C++ working paper. This addresses ballot comment US 58-123 (and duplicates US 59-124 and FR-001-019). + +LWG poll 12: Apply the changes in [P1264R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1264r2.pdf) (Revising the wording of stream input operations) to the C++ working paper. This partially addresses ballot comment FR-018-004. + +LWG poll 13: Apply the changes in [P2505R5](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2505r5.html) (Monadic Functions for `std::expected`) to the C++ working paper. This addresses ballot comments GB-093, US 36-091, US 35-092, and FR-011-009. + +LWG poll 14: Apply the changes in [P2696R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2696r0.html) (Introduce _Cpp17Swappable_ as additional convenience requirements) to the C++ working paper. + +### Noteworthy editorial changes + +* There were no noteworthy changes to the wording of the approved papers. +* A new subclause "Arithmetic types" was added. The new subclause contains + both "integer types" (``) and the new "extended floating-point + types" (``). Previously, the newly added `` synopsis + was somewhat disconnected and out of context. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4917 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/n4917...n4928). + + commit 7772de4408db8122431169156ea230803cb6bf56 + Author: Thomas Köppe + Date: Tue Sep 6 19:47:21 2022 +0100 + + [headers] Reflow table after header additions + + commit 3231e8115e93a24806694c36f1eb2d709fe78f4f + Author: Jens Maurer + Date: Sun Jun 12 15:49:22 2022 +0200 + + [basic.align] Recommend alignment-specifier instead of deprecated library facility + + commit 37d46b0d41d014febacd9ffe684eb0cf11a5c364 + Author: Chuanqi Xu + Date: Tue Jun 7 16:19:08 2022 +0800 + + [module.reach] Remove redundant module implementation unit declaration + + commit 4e2297b8d2543062edf347ec13341a8356f59605 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Sep 9 04:12:51 2022 +0800 + + [thread.stoptoken.syn] "class template", not just "class"; fix spacing (#5799) + + commit 20452e91b30d0a299a03d937f443a81537dc03f2 + Author: xmh0511 <970252187@qq.com> + Date: Fri Sep 9 04:54:01 2022 +0800 + + [basic.def.odr] A variable is "named by" an expression (#5534) + + The previous wording, a variable "whose name appears + as [an] expression", is less precise and not well-defined. + + commit 7260f30c74eaf670b3f3d33a7571f6c055930cd7 + Author: Jens Maurer + Date: Fri Jan 21 23:27:34 2022 +0100 + + [basic.life] Add cross-reference for union member lifetime + + commit ba51a5375fa3099e4a85594f2e67d48bc11ec448 + Author: Jonathan Wakely + Date: Mon Mar 20 11:58:33 2017 +0000 + + [rand.req.seedseq] Rephrase in terms of const types not values + + commit 88e574edc674e85911ea1a5b4e87c07457d97bf1 + Author: Jonathan Wakely + Date: Mon Mar 20 12:23:12 2017 +0000 + + [container.requirements] Rephrase in terms of const types not values + + commit 547987d9d203bb7f1f18297ca438ccb18d8fe612 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Sep 14 14:39:16 2022 +0800 + + [range.chunk.view.input, range.slide.view] Remove unused name in the deduction guide + + commit c774ac4a072efd41e478d72ad57a3dae8b0946ff + Author: Mathias Stearn + Date: Fri Sep 16 17:46:10 2022 +0200 + + [basic.life] Change "complete const object" to "const, complete object" (#5818) + + "Complete object" is a defined term (https://eel.is/c++draft/basic#def:complete_object). + Putting "const" in the middle of that leaves it ambiguous whether we are referring to + a const-qualified "complete object", or to a complete const object with some other meaning + of "complete" (such as "with a complete type"). + + commit 787ea7683982ed58b1a8bf7bbfb7c77f8d227dce + Author: Jens Maurer + Date: Fri Sep 16 21:24:15 2022 +0200 + + [diagnostics] Remove 'shall', use 'recommended practice' + + commit 9a005c04b91ffa9b92e6a57a03419091f365bc9b + Author: Jens Maurer + Date: Fri Sep 16 21:57:46 2022 +0200 + + [func.bind.isplace] Add cross-reference to [func.bind.place] + + commit 7bd72a7671d9bee0eed11578e325460bcf7fa5a1 + Author: Jens Maurer + Date: Fri Sep 16 22:09:23 2022 +0200 + + [vector.bool.pspc] Index vector::reference + + commit f68d6428f27d5cd722e713262d8986489484ae02 + Author: Jens Maurer + Date: Fri Sep 16 22:18:36 2022 +0200 + + [over.best.ics.general] Split long paragraph + + commit 1383e97e21d6d10ac210344d66ab715cfc0f747a + Author: Jonathan Wakely + Date: Thu Sep 15 15:38:58 2022 +0100 + + [ranges.syn] Make get overloads freestanding + + These were moved to the synopsis after the P1642 changes to mark nearly + everything in the synopsis freestanding, so they were not marked. + + commit c70087afe980f9ec339f088babde575e04e185d7 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Sat Sep 17 02:29:45 2022 +0500 + + [expr.add] Move note, add example (#4778) + + The original note wasn't quite in the right place. + It is moved and made more concrete. + + In the original place of the note we now put + a more immediately relevant example. + + commit 6000c29e5b9547bf457f4461fd538670144ad88c + Author: Jens Maurer + Date: Sat Sep 17 10:05:19 2022 +0200 + + [format.string.std] Clarify location of 0x prefix for pointers + + commit 718873b512d0687143bbfa00e18edfb0a8b164ce + Author: Jens Maurer + Date: Sat Sep 17 08:56:36 2022 +0200 + + [expr.prim.lambda.capture] Cross-reference [basic.def.odr] for 'odr-usable' + + commit 6a98fd8c1f9ea79961b78f731637ba9fe9d52218 + Author: Jens Maurer + Date: Sat Sep 17 09:05:57 2022 +0200 + + [thread.thread.this] Clarify this_thread::get_id + + commit 90c4ba5624a655af5c5d8b11c1137d552f3e0a60 + Author: Casey Carter + Date: Sun Sep 18 14:55:55 2022 -0700 + + [headers] Order `` before `` in the header table + + Fixes #5853. + + commit 16f92154ce99a5fef26c53c464e8b14ad5b78d79 + Author: A. Jiang + Date: Tue Sep 20 05:37:31 2022 +0800 + + [c.math.hypot3] Fix mis-transcribed parameter type (#5852) + + The paper P1467R9 says that the third parameter of `hypot` should be + `_floating-point-type_`, but it was erroneously transcribed as `double`. + + commit db26a63222f10cec871656958b3e296e529df67e + Author: Thomas Köppe + Date: Wed Sep 21 22:18:51 2022 +0100 + + [support, etc.] New subclause "Arithmetic types". (#5851) + + The new subclause contains both "integer types" () + and "extended floating-point types" (). + + Previously, the newly added synopsis was somewhat + disconnected and out of context. + + This change removes the stable labels [cstdint] and [cstdint.general]. + + commit d462173b5afdc8506d85e5395f2be19311895f2d + Author: Casey Carter + Date: Mon Sep 19 20:42:44 2022 -0700 + + [mdspan.extents.cons] Correct spelling of "dynamic-extents" + + commit 14a10ef0948f4709cd1114c489b8e4b919ba7cbc + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Thu Sep 22 05:20:44 2022 +0800 + + [unord.general, container.adaptors.general] Fix list of exposition-only alias templates (#5840) + + commit aab149233f76df37979d777ffd2b3151c52d48a9 + Author: Jonathan Wakely + Date: Thu Sep 22 10:51:46 2022 +0100 + + [template.bitset] reorder synopsis and member descriptions + + Group shifts together and use same order for synopsis and detailed + descriptions. + + Also remove the unnecessary "for b[i];" comments explaining what + operator[] does, and add a comment introducing the group containing + count(), size() etc. + + commit 63e4a76f780c925a13efeb06955252d7c37ed4ef + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Thu Sep 22 09:30:14 2022 +0800 + + [range.as.const.overview] Remove unnecessary ranges namespace qualification + + commit 179436adbe60c277fa6512352ee27e26f192bf2b + Author: Alisdair Meredith + Date: Fri Sep 23 12:45:09 2022 -0400 + + [utility.arg.requirements] Present identifiers as itemization (#5856) + + Lists providing the key for names used throughout a subclause are difficult + to follow when buried as a single sentence in a paragraph. This change updates + the key to tables 29-36 in [utility.arg.requirements] to a bulleted list + following the examples set elsewhere. + + Each key is now consistently introduced with the word "denotes", following + the precedent set by similar bullet lists. + + It is not at all coincidental that this also resolves pagination issues + at the end of the page, so that the floating tables to not float into the + middle of a sentence in the following section. + + commit 24d54e30506a62ef41cf4bd0132fbdba45bb6dda + Author: Jonathan Wakely + Date: Tue Sep 27 11:56:32 2022 +0100 + + [futures.task.members] Add missing explicit to packaged_task ctor + + commit 842424bd228b79876437a1a9393f20f00033476a + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Sep 28 16:39:59 2022 +0800 + + [futures.task.members] Correct capitalization + + commit d3ddc0906638bb30b5a3ce0f4033148e9a8ed1ff + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Thu Sep 29 15:49:06 2022 +0800 + + [container.rev.reqmts] Correct capitalization + + commit a7f17181ef5b59ad728b421a83975209406fa037 + Author: Daniel Krügler + Date: Mon Oct 3 17:59:20 2022 +0200 + + [sequence.reqmts] Use "lvalues of type T are swappable" (#5878) + + commit dd6c7f4012489325bdd65a40cd121b3d25008b0e + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Oct 4 04:41:26 2022 +0800 + + [associative.reqmts.general] Fix typo in namespace name (#5881) + + commit 42c7b3fb3a3cb11bc1af418cfdd395ecf314aa43 + Author: Thomas Köppe + Date: Tue Oct 4 13:08:17 2022 +0100 + + [intro.defs] Update hyperlink according to SC22 requirements + + commit 05019b35890b79374fac180a9a9ff9e7cf8d7595 + Author: Thomas Köppe + Date: Tue Oct 4 15:19:01 2022 +0100 + + Foreword placeholder + + commit b0fab58d4f2b12defdaf7c3ddfb2ddcd1f30e1b5 + Author: Jonathan Wakely + Date: Wed Oct 5 11:27:23 2022 +0100 + + [temp.local] Fix typo in "inject-class-name" (#5889) + + commit f6c5d4512d4b32d63d66669555ab976b315d439c + Author: mordante + Date: Mon Oct 10 17:50:51 2022 +0200 + + [format.string.escaped] Fix example of invalid code unit (#5890) + + Example 5 should only have one invalid code unit. The second code unit is a valid code point. + + This issue was already in the paper P2286R8 "Formatting Ranges". + + commit 5f26c516a659cdf3f0ea007cf6c90c690cccc3b6 + Author: Eelis van der Weegen + Date: Tue Oct 11 04:36:08 2022 +0200 + + [bibliography] Remove stray closing parenthesis. + + commit 6c51392a3d1c3c928ef1c20c19e8efe6efed7dc1 + Author: Corentin Jabot + Date: Wed Oct 19 22:29:09 2022 +0200 + + [intro.defs] Move the definition of "multibyte character" to library + + This address the US-2 NB comment as per the direction voted on + by SG-16. + + No use of "multibyte character" remains before [multibyte.strings]. + + commit 33e56641d63c5993d288082cf264a733464ff75c + Author: Arthur O'Dwyer + Date: Tue Oct 25 17:48:03 2022 -0400 + + [stack.syn, queue.syn] Add xref comments to class synopses (#5913) + + commit 90aa7729b9a926622581354284ecf294a56e410b + Author: Will Hawkins <8715530+hawkinsw@users.noreply.github.com> + Date: Tue Nov 1 04:37:52 2022 -0400 + + [range.dangling] Replace "tag type" with just "type" (#5922) + + The extra word "tag" was not adding any value and was potentially, + confusing; e.g. the "dangling" type is not like, say, an iterator tag + that would be used for overload resolution. + + commit fd998c52af2dc6b9c73098fdbd5a22444a358448 + Author: Arthur O'Dwyer + Date: Tue Nov 1 10:45:53 2022 -0400 + + [flat.set] [flat.multiset] Use value_type, not key_type + + For consistency with the other `set`, `unordered_set` containers. + `key_type` is a synonym for `value_type`, and there's no reason + the flat containers need to depart from existing practice here. + + commit 48ecaaec300de4a8176c116408cac915142166ce + Author: Arthur O'Dwyer + Date: Mon Nov 7 14:02:40 2022 -0500 + + [flat.multiset.modifiers] Fix typo in "multiset" (#5927) + + commit 45d9a5ba5aee1e3c4da8938e12376b36a7147d63 + Author: Eric41293 + Date: Mon Nov 7 11:11:58 2022 -0800 + + [climits.syn] Correct note about types of macros (#5926) + + This note was added apparently as a response to LWG 416. However, there may have been a misunderstanding of the C standard, and in fact only the macros for `{signed,unsigned,} char` and `{signed,unsigned} int` have a different type. + + commit f41cd00273e6ee7ff1a29446b21f230c28bf1a9f + Author: Jonathan Wakely + Date: Mon Nov 7 20:59:54 2022 +0000 + + [time.clock.system.nonmembers, time.zone.zonedtime.nonmembers] Add to STATICALLY-WIDEN (#5934) + + commit ef7d0e234722d2ef8b4ec069b6f929dc083d8dc7 + Author: Ed Catmur + Date: Tue Sep 20 18:12:45 2022 +0100 + + [meta, thread] Add or amend references to func.{require,invoke} + + commit 0d5c9b9310b2f6c6c4259665e1e680936babdc3d + Author: Eric41293 + Date: Mon Nov 7 15:54:55 2022 -0800 + + [meta.type.synop] Capitalize NTTP name (#5921) + + commit 0959b5c200a6f2b543e2d656850917b8d788767c + Author: Hui <65944694+huixie90@users.noreply.github.com> + Date: Tue Nov 8 00:49:15 2022 +0000 + + [range.drop.while.overview] Use string_view rather than string literal (#5897) + + The string literal would have been treated as a `const char*`, which is not a range. + + commit 720c3ae24a68fda02a6372eda13ec3f9c6a1a39b + Author: Jonathan Wakely + Date: Tue Nov 8 02:01:34 2022 +0000 + + [time.format] Use basic_ostringstream instead of ostringstream (#5932) + + commit 8739d316f2a55c633963b26b748681ff16498887 + Author: Marc Mutz <94039187+marcmutz@users.noreply.github.com> + Date: Tue Nov 8 03:05:45 2022 +0100 + + [meta.const.eval] Add is_constant_evaluated to index of library names (#5898) + + Previously, only its feature-test macro was listed there. + + commit 4c442cf93f03a44ec1f6a93875043a3aca7c5b9b + Author: Johel Ernesto Guerrero Peña + Date: Mon Nov 7 23:38:36 2022 -0400 + + [class.union.general] Attach example to its note (#5882) + + commit 65c494b9a4a5a4fab500733441c04e50a787d318 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Nov 8 15:51:21 2022 +0800 + + [mdspan.extents.expo] Remove redundant "// exposition only" (#5907) + + commit b766881dda1d0201d98710b11efda3491a84b4f2 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Tue Nov 8 13:15:07 2022 +0500 + + [dcl.init.list] Specify the type of the prvalue (#5919) + + commit 6e035b52e28e95211a39ffb552851499432b2c6e + Author: Johel Ernesto Guerrero Peña + Date: Tue Nov 8 15:30:29 2022 -0400 + + [ratio.ratio] Use symbol "sgn" for the signum function (#5925) + + commit 89269f8e548b993b239f2c0f5ecc071ee7f54c9a + Author: Blackteahamburger + Date: Wed Nov 9 04:12:59 2022 +0800 + + [dcl.link] Add missing restriction to language linkage application (#5892) + + A language linkage specification should only apply to entities that do in fact have language linkage. + + commit ea77b2fa83ddac0c52c1b505ff666328a2a8f558 + Author: Jens Maurer + Date: Wed Nov 9 00:34:26 2022 +0100 + + [temp.deduct.general] Fix typo in comment in example + + commit 0c196ec375993000547e8913abb4c4ce703144cb + Author: Jens Maurer + Date: Thu Nov 10 15:32:56 2022 +0100 + + [temp.deduct.conv] Remove misleading paragraph break + + commit 0cd0c33f648d1304160e6dcb1856affd71b3ebbb + Author: Casey Carter + Date: Fri Nov 11 18:35:53 2022 -0800 + + [mdspan.extents.cons] "constexpr" should precede "explicit" + + In library function declarations, the `constexpr` specifier always precedes the `explicit` specifier per our standing style guide. + + commit 608c152dbae69d335d7238cdd5d178e048e2a1fd + Author: Casey Carter + Date: Mon Nov 14 10:48:18 2022 -0800 + + [vector.bool.pspc] Replace `constexpr static` with `static constexpr` + + As preferred by our style guide. + + commit d829eac310981e688a15b28622a2f048d23eed65 + Author: Thomas Köppe + Date: Thu Nov 10 07:43:32 2022 +0000 + + [class.inhctor.init] Fix explanation of "error:" in example + + The correct explanation is that classes `B1` and `D1` do not have + default constructors, not that they have deleted default constructors. + + Fixes NB CA 062 (C++23 CD). + + commit 6a1c5050c21ac26fcb2b5b187a0de867713568dc + Author: Thomas Köppe + Date: Tue Nov 8 23:35:00 2022 +0000 + + [diff.cpp20.library] Add missing new headers + + Fixes NB FR 008 (C++23 CD). + + commit b2fa70faa783827cd38b819409e94da2523333f2 + Author: Thomas Köppe + Date: Wed Nov 9 18:50:56 2022 +0000 + + [views] Subclauses for contiguous and multidimensional access + + This organises the material for and into separate + subclauses, rather than having all constituent parts being siblings in + the same subclause. Even though we now have some subclauses six levels + deep, this seems like an improvement. As a drive-by, this allows us to + move a subclause on a non-member span helper function up one level, + where it is more appropriate. + + Fixes NB FR 027 (C++23 CD). + + commit e0bab4b7f2d8afe5d3939aa49fe6de4fd5e638c6 + Author: Thomas Köppe + Date: Thu Nov 10 02:16:11 2022 +0000 + + [concepts index] Describe exposition-only concepts + + Fixes NB GB 136 (C++23 CD). + + commit 9512e41e30cf24a8e93e8c8568ff1b5c14398cc6 + Author: Thomas Köppe + Date: Fri Nov 11 19:31:11 2022 +0000 + + [general, library index] Describe exposition-only entities + + Partially fixes NB GB 137 (C++23 CD). + + commit 0783dde32073b02b369c7c3893f4f496a83e3658 + Author: Thomas Köppe + Date: Fri Nov 11 19:33:33 2022 +0000 + + [func.wrap.move.ctor] Move private expos member to general index + + The private, exposition-only data member is not useful in the library + index. However, there seems no reason to not show it in the general + index, so we move the index entry from the library index to the + general index. + + Partially fixes NB GB 137 (C++23 CD). + + commit 3e825f144f2aa8668c9a1a94066b43799e08a6e7 + Author: Thomas Köppe + Date: Tue Nov 8 21:31:30 2022 +0000 + + [basic.scope.scope] Fix indentation in example + + Fixes NB US 034 (C++23 CD). + + commit 92de5996625efcb070f99681acd2e39efc206ee2 + Author: Thomas Köppe + Date: Tue Nov 8 23:24:35 2022 +0000 + + [unord.req.general] Fix garbled end of sentence + + This was an editorial mistake introduced by the transformation of the + requirement tables into regular paragraphs. + + Fixes NB US 100 (C++23 CD). + + commit 24e046896029a11f2cb78fd6db21482fb0d4be66 + Author: Thomas Köppe + Date: Tue Nov 8 21:02:31 2022 +0000 + + [coro.generator.promise] Use "equivalent to `throw`, ..." + + Our style guide says that "equivalent to " is the + appropriate style for an expression of type `void`, which is the case + for `throw`. This avoids the awkward situation of having "equivalent + to: `throws;`" appear in the middle of a paragraph without proper + terminal punctuation. + + Fixes NB US 119 (C++23 CD). + + commit 3f47d2565f26a9144e8076641ee55bf7be79f896 + Author: Thomas Köppe + Date: Tue Nov 8 21:27:56 2022 +0000 + + [coro.generator.promise] Remove unused name "x" + + Fixes NB US 120 (C++23 CD). + + commit fb0df97e7d7c2c75bbdf7164c33b0796024ff6d3 + Author: Jonathan Wakely + Date: Thu Nov 17 08:44:05 2022 +0000 + + [atomics] Replace integral and floating-point placeholders (#5939) + + Fixes NB GB 129 (C++23 CD). + + commit 0bb57d5ebffa7170fbc80724f55a6ac2a82f2e83 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Nov 25 14:56:24 2022 +0800 + + [format.arg] Add std:: for forward + + commit c88fb46327d87d78d571b7e1076e1916eaf7e310 + Author: Dawn Perchik + Date: Tue Nov 15 07:46:41 2022 -0800 + + [expr.unary.op] Say "the ~ operator" consistently, remove "unary" + + We are currently using the term "unary complement operator" to refer + to the "~" operator without ever giving it that name. This change + removes the use of that undefined term. + + commit bef02b89464fe6f4be3926d62defc92986ae4532 + Author: Thomas Köppe + Date: Tue Nov 22 16:28:42 2022 +0000 + + [expr.unary.op] Notes naming unary ops as {ones',two's} complement + + The terms "one's complement" and "two's complement" are well-known, + and it is useful to associate them with these operators. + + commit 020a312b2aa513a992e488d82db55fd0cd4fa025 + Author: Thomas Köppe + Date: Wed Nov 16 17:48:12 2022 +0000 + + [fs.rec.dir.itr.nonmembers] "for" is a keyword in "range-based for" + + commit cee095e75a97fb88a7053e360b3bc06d36a6b687 + Author: Alisdair Meredith + Date: Fri Dec 16 06:51:26 2022 +0700 + + [depr.conversions.string] remove redundent respecification (#6004) + + There are several typedef names defined precisely in the deprecated code conversion + facets classes that are redundantly respecified in text. Nowhere else in the library + does this; any specified typedef names are _see below_ definitions, not repeats of + the class definition. Needless redundancy is always a risk of divergence, however + small, so remove the respecification in text form. + + commit 1bb52db31be002f04ea5977f9900ba4174c7155e + Author: Anoop Rana <93918384+ranaanoop@users.noreply.github.com> + Date: Fri Dec 16 05:23:57 2022 +0530 + + [concepts.object] Change "built-in" to "fundamental" types (#6012) + + commit ce1cc3b011099b6228b18dad937911c6ea67d309 + Author: Johel Ernesto Guerrero Peña + Date: Sun Dec 11 17:03:41 2022 -0400 + + [expr.const] Remove redundant "ill-formed" in "error" comment + + commit 5d43f0137776fa112d0ffd6ba0e34df34a4cb820 + Author: Jonathan Wakely + Date: Tue Dec 13 12:52:00 2022 +0000 + + [time.zone.leap.members] update note about leap seconds + + commit fd20d4ea9f3ea8653b17169aad61eec843b71718 + Author: Jonathan Wakely + Date: Wed Nov 23 14:45:43 2022 +0000 + + [time.zone.zonedtime.overview] Rename parameters to match later definitions + + commit 137728f0830824c6058648a846376eec80e5cab3 + Author: Michael Florian Hava + Date: Fri Dec 16 02:10:55 2022 +0100 + + [coro.generator.promise] Fix template parameters (#6009) + + Some of the template parameters of `yield_value` were inconsistent, + and the synopsis contained an outright typo. This change uses `R2` + consistently since the parameter is a reference. + + commit 5d6099c3df78922ee5b5f1d1c42a5c762d246df0 + Author: Thomas Köppe + Date: Thu Dec 15 23:31:26 2022 +0000 + + [formatter.requirements] Remove one level of list nesting + + commit 9e41a1c27de2f676badacbe0c1aac783063b7cd6 + Author: Thomas Köppe + Date: Wed Nov 16 19:43:58 2022 +0000 + + [time.clock.req] Make list item end with comma, not full stop. + + Also reformat the itemization source to be more edit-friendly. + + commit 5ef31f3fc1531d9e6e923cb57bf6e5ecec59ed4e + Author: languagelawyer + Date: Thu Jun 25 10:54:17 2020 +0300 + + [expr.unary.op] Fix usage of "result" + + commit 8c60752c7eb28e1ff1cc9e088d7836957356f559 + Author: Jonathan Wakely + Date: Tue Apr 26 10:18:11 2022 +0100 + + [optional.ctor], [expected.object.ctor] Add converts-from-any-cvref + + commit 405b46f50ce6c7458e94db7b4528fc267e2b67c3 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sat Dec 17 00:14:51 2022 +0800 + + [mdspan.mdspan.overview] Add default template arguments for mdspan (#6018) + + We usually restate the default template arguments in the class synopsis, + so that the information is in one place and one does not need to also refer + to the header synopsis. + + commit ae88bb581d32f1939987c0a834fe3f6011a9d003 + Author: frederick-vs-ja + Date: Fri Dec 16 21:25:31 2022 +0800 + + [range.repeat] Change `W`/`WArgs` to `T`/`TArgs` + + commit 0a1f1e147c75ce9220de3488103ca880b6b8e49f + Author: Thomas Köppe + Date: Fri Dec 16 17:19:08 2022 +0000 + + [concept.copyconstructible] Avoid "possibly \tcode{const}" + + A small rewrite avoids the phrase "possibly \tcode{const}", + which we would like to remove entirely in favour of just + "possibly const". + + commit f058decdf9c7dea0461f723df72f5093f5e92b11 + Author: Thomas Köppe + Date: Fri Dec 16 17:31:47 2022 +0000 + + Replace "possibly \tcode{const}" with "possibly const" + + The "const" here is not syntax, but just normal text. + This is similar to "inline" and "public", which have + previously been cleaned up similarly. + + commit 9ac55553459e15c84db6d8072c93787d41ef7ccf + Author: Jens Maurer + Date: Fri Jun 4 00:29:30 2021 +0200 + + [lib] Drop 'inline' from 'inline constexpr' variable templates. + + Since CWG2387, constexpr variable templates have external linkage. diff --git a/papers/n4945.html b/papers/n4945.html new file mode 100644 index 0000000000..7ead1e9a9d --- /dev/null +++ b/papers/n4945.html @@ -0,0 +1,635 @@ + + + + + +N4945 + + +

N4945 Editors' Report -- Programming Languages -- C++

+ +

Date: 2023-03-22

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

Thanks to all those who have submitted editorial +issues +and to those who have provided pull requests with fixes. +Thank you also to Robert Leahy for drafting motion applications, +and special thanks to Johel Ernesto Guerrero Peña for providing in-depth review +of many of the draft motion applications.

+ +

New papers

+ +
    +
  • N4944 is the +current working draft for C++23. It replaces +N4928.
  • +
  • N4945 is this Editors' Report.
  • +
+ +

National body comments on the Committee Draft

+ +

N4919 is the C++23 Committee Draft. It received 137 comments from national bodies. +The first set of responses to all 11 editorial comments and to 49 non-editorial comments +was incorporated into the previous working draft, N4928; see the +previous Editors' Report +for details. The present working draft contains the final set of responses, +to 26 non-editorial comments, as noted below.

+ +

Non-editorial comments

+ +
    +
  • FR 012: Fixed by P2675R1 (LWG poll 10)
  • +
  • FR 013: Fixed by P2736R2 (CWG poll 8)
  • +
  • FR 021: Fixed by P2164R9 (LWG poll 6)
  • +
  • FR 023: Fixed by P2693R1 (LWG poll 12)
  • +
  • US 035: Fixed by CWG2642 (CWG poll 1)
  • +
  • US 036: Fixed by P2788R0 (CWG poll 9)
  • +
  • DE 038: Fixed by CWG2659 (CWG poll 6)
  • +
  • CA 076: Fixed by LWG3871 (LWG poll 3)
  • +
  • US 077: Fixed by P2652R2 (LWG poll 16)
  • +
  • DE 079: Fixed by P2614R2 (LWG poll 18)
  • +
  • GB 080: Fixed by LWG3828 (LWG poll 3)
  • +
  • GB 081: Fixed by LWG3827 (LWG poll 3)
  • +
  • GB 082: Fixed by LWG3827 (LWG poll 3)
  • +
  • GB 084: Fixed by LWG3869 (LWG poll 3)
  • +
  • CA 086: Fixed by P2679R2 (LWG poll 13)
  • +
  • GB 089: Fixed by P2674R1 (LWG poll 14)
  • +
  • US 098: Fixed by P2713R1 (LWG poll 9)
  • +
  • US 099: Fixed by P2609R3 (LWG poll 8)
  • +
  • US 108: Duplicate of FR 021
  • +
  • US 116: Fixed by P2787R1 (LWG poll 17)
  • +
  • GB 121: Fixed by LWG3870 (LWG poll 3)
  • +
  • US 126: Fixed by P2770R0 (LWG poll 5)
  • +
  • US 131: Fixed by P2588R3 (LWG poll 19)
  • +
  • FR 133: Duplicate of FR 013
  • +
  • FR 134: Duplicate of US 098
  • +
  • DE 135: Duplicate of US 131
  • +
+ +

Motions incorporated into working draft

+ +

Notes on motions

+ +
    +
  • CWG Poll 7 does not modify the C++ Working Paper.
  • +
  • For CWG Poll 4, the proposed wording of CWG 2521 +erroneously used the non-existing grammar production pp-token, +which was fixed to preprocessing-token.
  • +
  • For CWG Poll 8, a change of "character classes" to "character properties" +missing from P2736R2 +was applied.
  • +
  • CWG Poll 8, LWG Polls 9 and 11 all affect Unicode-related wording. While the +wording for the latter two was given relative to the status quo ante, the +actual wording has been adjusted to incorporate the changes from the CWG poll. +Moreover, we now always use the phrase "UAX #N of the Unicode Standard".
  • +
  • For LWG Poll 2, issue LWG 3821, +the new overload was marked as "freestanding" to match the surrounding interface; +this was not in the proposed wording.
  • +
  • For LWG Poll 6, an unused and erroneous default argument "pos = 0" was removed.
  • +
  • For LWG Poll 16, the wording has been reconciled with the changes from issue +LWG 3775 +that was applied after the previous meeting.
  • +
+ +

Core working group polls

+ +

CWG Poll 1: Accept as a Defect Report and apply the proposed resolution of all issues +except issues 2518, 2521, 2659, 2674, 2678, and 2691 in P2796R0 +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper.

+ +

CWG Poll 2: Apply the proposed resolution of issues 2674 and 2691 +in P2796R0 +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper.

+ +

CWG Poll 3: Accept as a Defect Report and apply the proposed resolution of issue 2518 (Conformance requirements and #error/#warning) +in P2796R0 +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper.

+ +

CWG Poll 4: Accept as a Defect Report and apply the proposed resolution of issue 2521 (User-defined literals and reserved identifiers) +in P2796R0 +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper.

+ +

CWG Poll 5: Accept as a Defect Report and apply the proposed resolution of issue 2678 +(std::source_location::current is unimplementable) in P2796R0 +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper.

+ +

CWG Poll 6: Apply the proposed resolution of issue 2659 (Missing feature-test macro for lifetime extension in range-for loop) +in P2796R0 +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper, resolving NB comment DE 038.

+ +

CWG Poll 7: Specify that P2647R1 +(Permitting static constexpr variables in constexpr functions) (applied in November, 2022) is no longer a Defect Report.

+ +

CWG Poll 8: Apply the changes in P2736R2 (Referencing The Unicode Standard) +to the C++ Working Paper, resolving NB comments FR 133 and FR 013.

+ +

CWG Poll 9: Accept as a Defect Report and apply the changes in P2788R0 +(Linkage for modular constants) to the C++ Working Paper, resolving NB comment US 036.

+ +

CWG Poll 10: Apply the changes in P2797R0 +(Proposed resolution for CWG2692 Static and explicit object member functions with the same parameter-type-lists) to the C++ Working Paper.

+ +

Library working group polls

+ +

Poll 1 does not concern the C++ Working Paper.

+ +

LWG Poll 2: Apply the changes for all Ready and Tentatively Ready issues in P2789R0 +(C++ Standard Library Issues to be moved in Issaquah, Feb. 2023) to the C++ working paper.

+ +

LWG Poll 3: Apply the changes for all Immediate issues except 3441 in P2790R0 +(C++ Standard Library Immediate Issues to be moved in Issaquah, Feb. 2023) to the C++ working paper.

+ +

LWG Poll 4: Apply the changes for the Immediate issue 3441 in P2790R0 +(C++ Standard Library Immediate Issues to be moved in Issaquah, Feb. 2023) to the C++ working paper.

+ +

LWG Poll 5: Apply the changes in P2770R0 +(Stashing stashing iterators for proper flattening) to the C++ working paper. This addresses ballot comment US 126.

+ +

LWG Poll 6: Apply the changes in P2164R9 +(views::enumerate) to the C++ working paper. This addresses ballot comments FR 021 and US 108.

+ +

LWG Poll 7: Apply the changes in P2711R1 +(Making multi-param constructors of views explicit) to the C++ working paper.

+ +

LWG Poll 8: Apply the changes in P2609R3 +(Relaxing Ranges Just A Smidge) to the C++ working paper. This addresses ballot comment US 099.

+ +

LWG Poll 9: Apply the changes in P2713R1 +(Escaping improvements in std::format) to the C++ working paper. This addresses ballot comments US 098 and FR 134.

+ +

LWG Poll 10: Apply the changes in P2675R1 +(format's width estimation is too approximate and not forward compatible) to the C++ working paper. This addresses ballot comment FR 012.

+ +

LWG Poll 11: Apply the changes in P2572R1 +(std::format fill character allowances) to the C++ working paper.

+ +

LWG Poll 12: Apply the changes in P2693R1 +(Formatting thread::id and stacktrace) to the C++ working paper. This addresses ballot comment FR 023.

+ +

LWG Poll 13: Apply the changes in P2679R2 +(Fixing std::start_lifetime_as for arrays) to the C++ working paper. This addresses ballot comment CA 086.

+ +

LWG Poll 14: Apply the changes in P2674R1 +(A trait for implicit lifetime types) to the C++ working paper. This addresses ballot comment GB 089.

+ +

LWG Poll 15: Apply the changes in P2655R3 +(common_reference_t of reference_wrapper Should Be a Reference Type) to the C++ working paper.

+ +

LWG Poll 16: Apply the changes in P2652R2 +(Disallow User Specialization of allocator_traits) to the C++ working paper. This addresses ballot comment US 077.

+ +

LWG Poll 17: Apply the changes in P2787R1 +(pmr::generator - Promise Types are not Values) to the C++ working paper. This addresses ballot comment US 116.

+ +

LWG Poll 18: Apply the changes in P2614R2 +(Deprecate numeric_limits::has_denorm) to the C++ working paper. This addresses ballot comment DE 079.

+ +

LWG Poll 19: Apply the changes in P2588R3 +(barrier's phase completion guarantees) to the C++ working paper. This addresses ballot comment DE 135 and US 131.

+ +

LWG Poll 20: Apply the changes in P2763R1 +(layout_stride static extents default constructor fix) to the C++ working paper.

+ +

Noteworthy editorial changes

+ +
    +
  • In the container requirements, the presentation of "contiguous container" has +been reordered for a better logical progression, which was made possible by +the earlier dissolution of the requirements tables.
  • +
+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4928 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 538ed7470087a1304ec9c04db8b00de1d4f40d03
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Dec 18 21:19:08 2022 +0000
+
+    [lex.ccon] Add xref to lex.charset, where encodings are defined
+
+commit ffd3141ffd278f86209845282548e6e5d9ed21eb
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Dec 19 00:02:24 2022 +0000
+
+    [lex.string] Add xref to lex.charset, where encodings are defined
+
+commit 13fa11859e144ecba44807746cd376c0b33f571f
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Dec 29 02:01:37 2022 +0800
+
+    [range.single.view] Remove duplicate semicolon (#6040)
+
+commit b98b620ec72c67423169782aa197dd0008900154
+Author: Eric41293 <eric41293@comcast.net>
+Date:   Wed Dec 28 11:07:01 2022 -0700
+
+    [format.string.std] Fixing grammatical error (#6037)
+
+commit c8e334d0632b5e49e7333002ebeb04c58754f2d1
+Author: zhihaoy <43971430+zhihaoy@users.noreply.github.com>
+Date:   Thu Jan 5 02:40:02 2023 -0800
+
+    [bitwise.operations.not] missing parameter name
+
+commit 0c9dd96bbfc421a0feabcbc2b6850cd369ed181f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jan 17 23:16:33 2023 +0100
+
+    [over.over] Missed edit for P0847R7
+
+    P0847R7 (Deducing this) was approved at the October, 2021 meeting
+    and applied with commit ee5117e100bbe9b7adb3510b2d7bb6d4d150f810,
+    missing this change.
+
+commit 2228f1c619fcd19c61ae6a4378f03f6ee938e55a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jan 16 12:11:47 2023 +0000
+
+    [unord.map.overview] Remove stray template-head on non-template
+
+commit b9d35e813c007f3514015017e1ce09d936b5e2cc
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Jan 23 01:43:54 2023 +0800
+
+    [reverse.iter.conv] Remove unclear explicit comments
+
+    I don't know what explicit refers to here, it seems to be more appropriate to remove.
+    People who disagree with me are also welcome.
+
+commit b5d9d4f5c5a14a059a8af75428707a0fc14b4c12
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Jan 24 17:20:59 2023 +0800
+
+    [move.sentinel] Use "std::move" in example for correctness (#6043)
+
+commit a009995257307b1ed8894718b70c917f4c25094b
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Jan 26 02:06:35 2023 +0800
+
+    [iterator.synopsis] Fix inconsistent template constraint
+
+commit 388eff69768d3ba97c095de98e9972685f2e3579
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jan 27 14:30:39 2023 +0100
+
+    [version.syn] Fix value of __cpp_lib_constexpr_bitset
+
+    Paper P2417R2 was approved in July 2022, but commit
+    75518ffdc476cbc239918466588d963fc97a8013 did not set
+    the feature-test to the approriate value.
+
+commit 9020f7480b2cd0f3c0857b93cab4dbcf44a24edc
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Feb 5 23:30:36 2023 +0800
+
+    [format.range.fmtmap] Fix undefined type name
+
+commit a096b08e6a2ee5544fd753aefd9469673e4864dd
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Jan 31 10:53:18 2023 +0800
+
+    [const.iterators.iterator] Add \expos comment for concept
+
+commit 9ce105b48e34c0e08947ac073694faa6600716ec
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Feb 10 14:52:42 2023 +0800
+
+    [iostream.cons] Add std:: qualified for move
+
+commit 6d836080a380d0f828de30e6449985b5b503d874
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Mar 6 18:28:32 2023 +0000
+
+    [dcl.pre] Add missing markup that makes "fails" a definition.
+
+    This change was missed from the application of CWG2518.
+
+    Also fixes the indexing of "static_assert" (which is a keyword, not a
+    grammar production).
+
+commit 9357ba63abeb27152ac7d03db4ba9a274cf2f922
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Sun Feb 26 19:52:46 2023 -0600
+
+    [expected.object.eq] Fix typo
+
+commit 586f4ed7fbafeee5b91fcb6c2950008dfffbeec0
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Mar 7 10:34:50 2023 -0500
+
+    [cpp.pre] Fix grammar for #elifdef
+
+    This fix is editorial as it corrects a mis-application of the original
+    paper, https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2334r1.pdf.
+
+    Note that the corresponding use of this grammar in [cpp.cond]p13
+    assumes the correct grammar, making the intent equally clear.
+
+commit 64ef8b32a5b3ac60e8ac1f28ccb008c704cc25f4
+Author: Barry Revzin <barry.revzin@gmail.com>
+Date:   Sun Mar 12 10:11:24 2023 -0500
+
+    [expr.prim.req.compound] Move compound requirement example from inner to outer bullet (#6159)
+
+    Example 1 from [expr.prim.req.compound] is currently attached to the
+    inner bullet point, but should be attached to the outer one.
+
+commit 5a974f72f43928258a6264155f8932bebb3fea30
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Mar 12 23:17:02 2023 +0800
+
+    [util.smartptr.atomic.general] Simplify example code (#6077)
+
+    Removes the redundant explicit construction of the return value,
+    and uses an explicit return type instead of "auto" for clarity.
+
+commit 1912644b1bf60e0c8fc8d53ccbee0488244b1fd3
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Mar 13 00:02:02 2023 +0800
+
+    [specialized.algorithms.general] Remove possibly wrong note (#6157)
+
+commit 40cfc37319ae4e6204a2237ad6e143fac6911df6
+Author: Blackteahamburger <blackteahamburger@outlook.com>
+Date:   Mon Mar 13 02:23:01 2023 +0800
+
+    [allocator.requirements.general] Fix SimpleAllocator example (#6152)
+
+    The example now meets the requirements and is minimal.
+    Previously, some == comparisons that should work were ambiguous.
+
+commit f131b37fbf412bf2b69690914c2030b3ad702e55
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sun Mar 12 14:27:09 2023 -0400
+
+    [library.general,tab:thread.summary] Update references to renamed Clause (#6149)
+
+commit 71c72b23250d4e3f8c960c345721ba5e6a52f3c1
+Author: Giuseppe D'Angelo <dangelog@users.noreply.github.com>
+Date:   Sun Mar 12 23:29:23 2023 +0100
+
+    [range.split] Fix invalid conversion in example (#6041)
+
+    Replaces an illegal implicit conversion from a range to string_view
+    in the example with an explicit one.
+
+    After P2499R0, it is no longer possible to implicitly construct a
+    string_view from a range (like the ones produced by views::split).
+
+commit b1f3246af2a6af4f2b81be9b296feb08ad40962b
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 2 12:58:40 2023 +0000
+
+    Consistent comma after e.g. and i.e. (again)
+
+commit 29c0c3d61be7875e9be08a19d7612a7a2c628ef6
+Author: Alex Riegler <53669754+alexriegler@users.noreply.github.com>
+Date:   Sun Mar 12 19:59:06 2023 -0500
+
+    [tab:iostreams.summary] Add missing header in summary table (#6079)
+
+    Also reorder the headers into order of appearance,
+    which is how the "C library files" headers are ordered.
+
+commit 16dfc43257e15582d7461280b2c896c471e6e431
+Author: Mark de Wever <koraq@xs4all.nl>
+Date:   Mon Mar 13 02:06:04 2023 +0100
+
+    [time.syn] Use "ymwd" parameter name consistently (#6029)
+
+commit 6298c4b6ad03946ea5a547d375762d5f029cf195
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Mar 7 22:23:05 2023 -0500
+
+    [depr.template.template] Add cross-ref to core language
+
+    Add a cross reference to the core language paragraph that
+    contains the deprecation notice, [temp.names] (p6).
+
+commit d9f8705de8aaa61112250d211e7891e91b411dbe
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sat Dec 31 00:57:08 2022 +0800
+
+    [range.take.overview, range.drop.overview] Remove redundant ranges:: qualifier
+
+commit dcac5eaf993a190a1bb1335217779bd9ef13a38e
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Mar 14 10:46:30 2023 -0400
+
+    [span.iterators] Fix cross-reference to container iterators (#6183)
+
+    The current cross-reference is to [containers.requirements], which
+    is the whole containers requirements clause, including not just
+    general containers, but also allocator-aware, reversible, sequence,
+    associative, and unodered associative containers.  It seems very
+    unlikely that the cross-reference expects to be the intersection
+    of all of those.
+
+    Rather, the reference seems to intend just the [containers.reqmts]
+    subclause, which adds just two useful constraints: random access
+    iterators should support the 3-way comparison operator, and the
+    interoperabiity of container iterators and const_iterators.
+
+commit 39c1510d443b647c46de3e84d49a21d442154795
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Mar 14 16:12:22 2023 +0100
+
+    [stmt] Fix cross-references for condition
+
+commit 22a3b44cd6d5b0017cb57d8767d9dfc2094735c8
+Author: morinmorin <mimomorin@gmail.com>
+Date:   Wed Mar 15 01:45:28 2023 +0900
+
+    [projected, alg.req.ind.{move, copy}, range.as.rvalue.overview] Article "an", not "a" (#6186)
+
+    The subsequent identifier is naturally pronounced with a leading vowel.
+
+commit ae8ec6f016e0efcb37104a96f0b0677b850fdd0f
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Mar 16 11:13:43 2023 -0400
+
+    [container.reqmts] Fix cross-references to contiguous container
+
+    This edit deserves describing in detail, to establish that it
+    is purely editorial.
+
+    As part of the mission to clean up tables in the standard,
+    the general container requirements were split into 5 more
+    focused leaf nodes.  Due to its location in the original
+    text, the definition for a contiguous container fell into
+    the subclause for reversible containers, to which it is
+    entirely unrelated.  There is no requirement that a
+    contiguous container be reversible, only that it has the
+    correct category for its iterators.
+
+    Meanwhile, all 3 of the existing cross-references point
+    to the wrong leaf node, that simply provides a key to
+    the identifiers used throughout the specification of this
+    clause.
+
+    The fix has two parts.  First move the definition of
+    contiguous container, and a container with special
+    iterators, into the [container.reqmts] clause where it
+    best belongs.  This move is appended to the end so that
+    there can be no ambiguity that any existing text could
+    be confused with requirements only on contiguous
+    containers after the edit.  The other part is to fix up
+    the three cross-references to point to [container.reqmts]
+    rather than its sibling that has no information on
+    contiguous containers.
+
+    A grep of the .tex source files confirms that these
+    three references (array,basic_string, and vector) are
+    the only current uses of contiguous container, even
+    though basic_stacktrace would also meet the requirements.
+
+commit f24d86dcb1d597dc65cd10e56e80d23e331a9f1b
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Mar 18 20:41:27 2023 -0400
+
+    [range.subrange.general, range.adaptors] Use "present only if" (#6146)
+
+ + diff --git a/papers/n4945.md b/papers/n4945.md new file mode 100644 index 0000000000..2be432983d --- /dev/null +++ b/papers/n4945.md @@ -0,0 +1,488 @@ +# N4945 Editors' Report -- Programming Languages -- C++ + +Date: 2023-03-22 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. +Thank you also to Robert Leahy for drafting motion applications, +and special thanks to Johel Ernesto Guerrero Peña for providing in-depth review +of many of the draft motion applications. + +## New papers + + * [N4944](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4944.pdf) is the + current working draft for C++23. It replaces + [N4928](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4928.pdf). + * N4945 is this Editors' Report. + +## National body comments on the Committee Draft + +N4919 is the C++23 Committee Draft. It received 137 comments from national bodies. +The first set of responses to all 11 editorial comments and to 49 non-editorial comments +was incorporated into the previous working draft, N4928; see the +[previous Editors' Report](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4929.html) +for details. The present working draft contains the final set of responses, +to 26 non-editorial comments, as noted below. + +### Non-editorial comments + +* **FR 012:** Fixed by [P2675R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2675r1.pdf) (LWG poll 10) +* **FR 013:** Fixed by [P2736R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2736r2.pdf) (CWG poll 8) +* **FR 021:** Fixed by [P2164R9](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2164r9.pdf) (LWG poll 6) +* **FR 023:** Fixed by [P2693R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2693r1.pdf) (LWG poll 12) +* **US 035:** Fixed by [CWG2642](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2796r0.html#2642) (CWG poll 1) +* **US 036:** Fixed by [P2788R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2788r0.html) (CWG poll 9) +* **DE 038:** Fixed by [CWG2659](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2796r0.html#2659) (CWG poll 6) +* **CA 076**: Fixed by [LWG3871](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2790r0.html#3871) (LWG poll 3) +* **US 077:** Fixed by [P2652R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2652r2.html) (LWG poll 16) +* **DE 079:** Fixed by [P2614R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2614r2.pdf) (LWG poll 18) +* **GB 080**: Fixed by [LWG3828](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2790r0.html#3828) (LWG poll 3) +* **GB 081**: Fixed by [LWG3827](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2790r0.html#3827) (LWG poll 3) +* **GB 082**: Fixed by [LWG3827](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2790r0.html#3827) (LWG poll 3) +* **GB 084**: Fixed by [LWG3869](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2790r0.html#3869) (LWG poll 3) +* **CA 086:** Fixed by [P2679R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2679r2.html) (LWG poll 13) +* **GB 089:** Fixed by [P2674R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2674r1.pdf) (LWG poll 14) +* **US 098:** Fixed by [P2713R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2713r1.html) (LWG poll 9) +* **US 099:** Fixed by [P2609R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2609r3.html) (LWG poll 8) +* **US 108:** Duplicate of FR 021 +* **US 116:** Fixed by [P2787R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2787r1.pdf) (LWG poll 17) +* **GB 121**: Fixed by [LWG3870](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2790r0.html#3870) (LWG poll 3) +* **US 126:** Fixed by [P2770R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2770r0.html) (LWG poll 5) +* **US 131:** Fixed by [P2588R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2588r3.html) (LWG poll 19) +* **FR 133:** Duplicate of FR 013 +* **FR 134:** Duplicate of US 098 +* **DE 135:** Duplicate of US 131 + +## Motions incorporated into working draft + +### Notes on motions + +* CWG Poll 7 does not modify the C++ Working Paper. +* For CWG Poll 4, the proposed wording of [CWG 2521](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2796r0.html#2521) + erroneously used the non-existing grammar production *pp-token*, + which was fixed to *preprocessing-token*. +* For CWG Poll 8, a change of "character classes" to "character properties" + missing from [P2736R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2736r2.pdf) + was applied. +* CWG Poll 8, LWG Polls 9 and 11 all affect Unicode-related wording. While the + wording for the latter two was given relative to the status quo ante, the + actual wording has been adjusted to incorporate the changes from the CWG poll. + Moreover, we now always use the phrase "UAX #N of the Unicode Standard". +* For LWG Poll 2, issue [LWG 3821](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2789r0.html#3821), + the new overload was marked as "freestanding" to match the surrounding interface; + this was not in the proposed wording. +* For LWG Poll 6, an unused and erroneous default argument "`pos = 0`" was removed. +* For LWG Poll 16, the wording has been reconciled with the changes from issue + [LWG 3775](https://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2703r0.html#3775) + that was applied after the previous meeting. + +### Core working group polls + +CWG Poll 1: Accept as a Defect Report and apply the proposed resolution of all issues +except issues 2518, 2521, 2659, 2674, 2678, and 2691 in [P2796R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2796r0.html) +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper. + +CWG Poll 2: Apply the proposed resolution of issues 2674 and 2691 +in [P2796R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2796r0.html) +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper. + +CWG Poll 3: Accept as a Defect Report and apply the proposed resolution of issue 2518 (Conformance requirements and `#error`/`#warning`) +in [P2796R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2796r0.html) +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper. + +CWG Poll 4: Accept as a Defect Report and apply the proposed resolution of issue 2521 (User-defined literals and reserved identifiers) +in [P2796R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2796r0.html) +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper. + +CWG Poll 5: Accept as a Defect Report and apply the proposed resolution of issue 2678 +(`std::source_location::current` is unimplementable) in [P2796R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2796r0.html) +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper. + +CWG Poll 6: Apply the proposed resolution of issue 2659 (Missing feature-test macro for lifetime extension in range-for loop) +in [P2796R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2796r0.html) +(Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper, resolving NB comment DE 038. + +CWG Poll 7: Specify that [P2647R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2647r1.html) +(Permitting static constexpr variables in constexpr functions) (applied in November, 2022) is no longer a Defect Report. + +CWG Poll 8: Apply the changes in [P2736R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2736r2.pdf) (Referencing The Unicode Standard) +to the C++ Working Paper, resolving NB comments FR 133 and FR 013. + +CWG Poll 9: Accept as a Defect Report and apply the changes in [P2788R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2788r0.html) +(Linkage for modular constants) to the C++ Working Paper, resolving NB comment US 036. + +CWG Poll 10: Apply the changes in [P2797R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2797r0.html) +(Proposed resolution for CWG2692 Static and explicit object member functions with the same parameter-type-lists) to the C++ Working Paper. + +### Library working group polls + +Poll 1 does not concern the C++ Working Paper. + +LWG Poll 2: Apply the changes for all Ready and Tentatively Ready issues in [P2789R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2789r0.html) +(C++ Standard Library Issues to be moved in Issaquah, Feb. 2023) to the C++ working paper. + +LWG Poll 3: Apply the changes for all Immediate issues except 3441 in [P2790R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2790r0.html) +(C++ Standard Library Immediate Issues to be moved in Issaquah, Feb. 2023) to the C++ working paper. + +LWG Poll 4: Apply the changes for the Immediate issue 3441 in [P2790R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2790r0.html) +(C++ Standard Library Immediate Issues to be moved in Issaquah, Feb. 2023) to the C++ working paper. + +LWG Poll 5: Apply the changes in [P2770R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2770r0.html) +(Stashing stashing iterators for proper flattening) to the C++ working paper. This addresses ballot comment US 126. + +LWG Poll 6: Apply the changes in [P2164R9](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2164r9.pdf) +(`views::enumerate`) to the C++ working paper. This addresses ballot comments FR 021 and US 108. + +LWG Poll 7: Apply the changes in [P2711R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2711r1.html) +(Making multi-param constructors of views explicit) to the C++ working paper. + +LWG Poll 8: Apply the changes in [P2609R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2609r3.html) +(Relaxing Ranges Just A Smidge) to the C++ working paper. This addresses ballot comment US 099. + +LWG Poll 9: Apply the changes in [P2713R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2713r1.html) +(Escaping improvements in `std::format`) to the C++ working paper. This addresses ballot comments US 098 and FR 134. + +LWG Poll 10: Apply the changes in [P2675R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2675r1.pdf) +(`format`'s width estimation is too approximate and not forward compatible) to the C++ working paper. This addresses ballot comment FR 012. + +LWG Poll 11: Apply the changes in [P2572R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2572r1.html) +(`std::format` fill character allowances) to the C++ working paper. + +LWG Poll 12: Apply the changes in [P2693R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2693r1.pdf) +(Formatting `thread::id` and `stacktrace`) to the C++ working paper. This addresses ballot comment FR 023. + +LWG Poll 13: Apply the changes in [P2679R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2679r2.html) +(Fixing `std::start_lifetime_as` for arrays) to the C++ working paper. This addresses ballot comment CA 086. + +LWG Poll 14: Apply the changes in [P2674R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2674r1.pdf) +(A trait for implicit lifetime types) to the C++ working paper. This addresses ballot comment GB 089. + +LWG Poll 15: Apply the changes in [P2655R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2655r3.html) +(`common_reference_t` of `reference_wrapper` Should Be a Reference Type) to the C++ working paper. + +LWG Poll 16: Apply the changes in [P2652R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2652r2.html) +(Disallow User Specialization of `allocator_traits`) to the C++ working paper. This addresses ballot comment US 077. + +LWG Poll 17: Apply the changes in [P2787R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2787r1.pdf) +(`pmr::generator` - Promise Types are not Values) to the C++ working paper. This addresses ballot comment US 116. + +LWG Poll 18: Apply the changes in [P2614R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2614r2.pdf) +(Deprecate `numeric_limits::has_denorm`) to the C++ working paper. This addresses ballot comment DE 079. + +LWG Poll 19: Apply the changes in [P2588R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2588r3.html) +(`barrier`'s phase completion guarantees) to the C++ working paper. This addresses ballot comment DE 135 and US 131. + +LWG Poll 20: Apply the changes in [P2763R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2763r1.html) +(`layout_stride` static extents default constructor fix) to the C++ working paper. + +### Noteworthy editorial changes + +* In the container requirements, the presentation of "contiguous container" has + been reordered for a better logical progression, which was made possible by + the earlier dissolution of the requirements tables. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4928 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/n4928...n4944). + + commit 538ed7470087a1304ec9c04db8b00de1d4f40d03 + Author: Thomas Köppe + Date: Sun Dec 18 21:19:08 2022 +0000 + + [lex.ccon] Add xref to lex.charset, where encodings are defined + + commit ffd3141ffd278f86209845282548e6e5d9ed21eb + Author: Thomas Köppe + Date: Mon Dec 19 00:02:24 2022 +0000 + + [lex.string] Add xref to lex.charset, where encodings are defined + + commit 13fa11859e144ecba44807746cd376c0b33f571f + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Thu Dec 29 02:01:37 2022 +0800 + + [range.single.view] Remove duplicate semicolon (#6040) + + commit b98b620ec72c67423169782aa197dd0008900154 + Author: Eric41293 + Date: Wed Dec 28 11:07:01 2022 -0700 + + [format.string.std] Fixing grammatical error (#6037) + + commit c8e334d0632b5e49e7333002ebeb04c58754f2d1 + Author: zhihaoy <43971430+zhihaoy@users.noreply.github.com> + Date: Thu Jan 5 02:40:02 2023 -0800 + + [bitwise.operations.not] missing parameter name + + commit 0c9dd96bbfc421a0feabcbc2b6850cd369ed181f + Author: Jens Maurer + Date: Tue Jan 17 23:16:33 2023 +0100 + + [over.over] Missed edit for P0847R7 + + P0847R7 (Deducing this) was approved at the October, 2021 meeting + and applied with commit ee5117e100bbe9b7adb3510b2d7bb6d4d150f810, + missing this change. + + commit 2228f1c619fcd19c61ae6a4378f03f6ee938e55a + Author: Jonathan Wakely + Date: Mon Jan 16 12:11:47 2023 +0000 + + [unord.map.overview] Remove stray template-head on non-template + + commit b9d35e813c007f3514015017e1ce09d936b5e2cc + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Jan 23 01:43:54 2023 +0800 + + [reverse.iter.conv] Remove unclear explicit comments + + I don't know what explicit refers to here, it seems to be more appropriate to remove. + People who disagree with me are also welcome. + + commit b5d9d4f5c5a14a059a8af75428707a0fc14b4c12 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Jan 24 17:20:59 2023 +0800 + + [move.sentinel] Use "std::move" in example for correctness (#6043) + + commit a009995257307b1ed8894718b70c917f4c25094b + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Thu Jan 26 02:06:35 2023 +0800 + + [iterator.synopsis] Fix inconsistent template constraint + + commit 388eff69768d3ba97c095de98e9972685f2e3579 + Author: Jens Maurer + Date: Fri Jan 27 14:30:39 2023 +0100 + + [version.syn] Fix value of __cpp_lib_constexpr_bitset + + Paper P2417R2 was approved in July 2022, but commit + 75518ffdc476cbc239918466588d963fc97a8013 did not set + the feature-test to the approriate value. + + commit 9020f7480b2cd0f3c0857b93cab4dbcf44a24edc + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Feb 5 23:30:36 2023 +0800 + + [format.range.fmtmap] Fix undefined type name + + commit a096b08e6a2ee5544fd753aefd9469673e4864dd + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Jan 31 10:53:18 2023 +0800 + + [const.iterators.iterator] Add \expos comment for concept + + commit 9ce105b48e34c0e08947ac073694faa6600716ec + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Feb 10 14:52:42 2023 +0800 + + [iostream.cons] Add std:: qualified for move + + commit 6d836080a380d0f828de30e6449985b5b503d874 + Author: Thomas Köppe + Date: Mon Mar 6 18:28:32 2023 +0000 + + [dcl.pre] Add missing markup that makes "fails" a definition. + + This change was missed from the application of CWG2518. + + Also fixes the indexing of "static_assert" (which is a keyword, not a + grammar production). + + commit 9357ba63abeb27152ac7d03db4ba9a274cf2f922 + Author: timsong-cpp + Date: Sun Feb 26 19:52:46 2023 -0600 + + [expected.object.eq] Fix typo + + commit 586f4ed7fbafeee5b91fcb6c2950008dfffbeec0 + Author: Alisdair Meredith + Date: Tue Mar 7 10:34:50 2023 -0500 + + [cpp.pre] Fix grammar for #elifdef + + This fix is editorial as it corrects a mis-application of the original + paper, https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2334r1.pdf. + + Note that the corresponding use of this grammar in [cpp.cond]p13 + assumes the correct grammar, making the intent equally clear. + + commit 64ef8b32a5b3ac60e8ac1f28ccb008c704cc25f4 + Author: Barry Revzin + Date: Sun Mar 12 10:11:24 2023 -0500 + + [expr.prim.req.compound] Move compound requirement example from inner to outer bullet (#6159) + + Example 1 from [expr.prim.req.compound] is currently attached to the + inner bullet point, but should be attached to the outer one. + + commit 5a974f72f43928258a6264155f8932bebb3fea30 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Mar 12 23:17:02 2023 +0800 + + [util.smartptr.atomic.general] Simplify example code (#6077) + + Removes the redundant explicit construction of the return value, + and uses an explicit return type instead of "auto" for clarity. + + commit 1912644b1bf60e0c8fc8d53ccbee0488244b1fd3 + Author: A. Jiang + Date: Mon Mar 13 00:02:02 2023 +0800 + + [specialized.algorithms.general] Remove possibly wrong note (#6157) + + commit 40cfc37319ae4e6204a2237ad6e143fac6911df6 + Author: Blackteahamburger + Date: Mon Mar 13 02:23:01 2023 +0800 + + [allocator.requirements.general] Fix SimpleAllocator example (#6152) + + The example now meets the requirements and is minimal. + Previously, some == comparisons that should work were ambiguous. + + commit f131b37fbf412bf2b69690914c2030b3ad702e55 + Author: Johel Ernesto Guerrero Peña + Date: Sun Mar 12 14:27:09 2023 -0400 + + [library.general,tab:thread.summary] Update references to renamed Clause (#6149) + + commit 71c72b23250d4e3f8c960c345721ba5e6a52f3c1 + Author: Giuseppe D'Angelo + Date: Sun Mar 12 23:29:23 2023 +0100 + + [range.split] Fix invalid conversion in example (#6041) + + Replaces an illegal implicit conversion from a range to string_view + in the example with an explicit one. + + After P2499R0, it is no longer possible to implicitly construct a + string_view from a range (like the ones produced by views::split). + + commit b1f3246af2a6af4f2b81be9b296feb08ad40962b + Author: Jonathan Wakely + Date: Thu Mar 2 12:58:40 2023 +0000 + + Consistent comma after e.g. and i.e. (again) + + commit 29c0c3d61be7875e9be08a19d7612a7a2c628ef6 + Author: Alex Riegler <53669754+alexriegler@users.noreply.github.com> + Date: Sun Mar 12 19:59:06 2023 -0500 + + [tab:iostreams.summary] Add missing header in summary table (#6079) + + Also reorder the headers into order of appearance, + which is how the "C library files" headers are ordered. + + commit 16dfc43257e15582d7461280b2c896c471e6e431 + Author: Mark de Wever + Date: Mon Mar 13 02:06:04 2023 +0100 + + [time.syn] Use "ymwd" parameter name consistently (#6029) + + commit 6298c4b6ad03946ea5a547d375762d5f029cf195 + Author: Alisdair Meredith + Date: Tue Mar 7 22:23:05 2023 -0500 + + [depr.template.template] Add cross-ref to core language + + Add a cross reference to the core language paragraph that + contains the deprecation notice, [temp.names] (p6). + + commit d9f8705de8aaa61112250d211e7891e91b411dbe + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sat Dec 31 00:57:08 2022 +0800 + + [range.take.overview, range.drop.overview] Remove redundant ranges:: qualifier + + commit dcac5eaf993a190a1bb1335217779bd9ef13a38e + Author: Alisdair Meredith + Date: Tue Mar 14 10:46:30 2023 -0400 + + [span.iterators] Fix cross-reference to container iterators (#6183) + + The current cross-reference is to [containers.requirements], which + is the whole containers requirements clause, including not just + general containers, but also allocator-aware, reversible, sequence, + associative, and unodered associative containers. It seems very + unlikely that the cross-reference expects to be the intersection + of all of those. + + Rather, the reference seems to intend just the [containers.reqmts] + subclause, which adds just two useful constraints: random access + iterators should support the 3-way comparison operator, and the + interoperabiity of container iterators and const_iterators. + + commit 39c1510d443b647c46de3e84d49a21d442154795 + Author: Jens Maurer + Date: Tue Mar 14 16:12:22 2023 +0100 + + [stmt] Fix cross-references for condition + + commit 22a3b44cd6d5b0017cb57d8767d9dfc2094735c8 + Author: morinmorin + Date: Wed Mar 15 01:45:28 2023 +0900 + + [projected, alg.req.ind.{move, copy}, range.as.rvalue.overview] Article "an", not "a" (#6186) + + The subsequent identifier is naturally pronounced with a leading vowel. + + commit ae8ec6f016e0efcb37104a96f0b0677b850fdd0f + Author: Alisdair Meredith + Date: Thu Mar 16 11:13:43 2023 -0400 + + [container.reqmts] Fix cross-references to contiguous container + + This edit deserves describing in detail, to establish that it + is purely editorial. + + As part of the mission to clean up tables in the standard, + the general container requirements were split into 5 more + focused leaf nodes. Due to its location in the original + text, the definition for a contiguous container fell into + the subclause for reversible containers, to which it is + entirely unrelated. There is no requirement that a + contiguous container be reversible, only that it has the + correct category for its iterators. + + Meanwhile, all 3 of the existing cross-references point + to the wrong leaf node, that simply provides a key to + the identifiers used throughout the specification of this + clause. + + The fix has two parts. First move the definition of + contiguous container, and a container with special + iterators, into the [container.reqmts] clause where it + best belongs. This move is appended to the end so that + there can be no ambiguity that any existing text could + be confused with requirements only on contiguous + containers after the edit. The other part is to fix up + the three cross-references to point to [container.reqmts] + rather than its sibling that has no information on + contiguous containers. + + A grep of the .tex source files confirms that these + three references (array,basic_string, and vector) are + the only current uses of contiguous container, even + though basic_stacktrace would also meet the requirements. + + commit f24d86dcb1d597dc65cd10e56e80d23e331a9f1b + Author: Johel Ernesto Guerrero Peña + Date: Sat Mar 18 20:41:27 2023 -0400 + + [range.subrange.general, range.adaptors] Use "present only if" (#6146) diff --git a/papers/n4951.html b/papers/n4951.html new file mode 100644 index 0000000000..ab5636e4d9 --- /dev/null +++ b/papers/n4951.html @@ -0,0 +1,447 @@ + + + + + +N4951 + + +

N4951 Editors’ Report:
Programming Languages — C++

+ +

Date: 2023-05-10

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

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

+ +

New papers

+ +
    +
  • N4950 is the +current and final working draft for C++23. It replaces +N4944, and it +forms the basis of the Draft International Standard for C++23.
  • +
  • N4951 is this Editors' Report.
  • +
  • The next working draft will be for C++26.
  • +
+ +

Editorial changes

+ +

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

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4944 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 b8512a1c292adee71c1145d3c61e32d48dcb8daa
+Author: morinmorin <mimomorin@gmail.com>
+Date:   Wed Mar 15 01:45:28 2023 +0900
+
+    [container.requirements.general] Move exposition-only concept
+
+    The exposition-only concept container-compatible-range is defined
+    in the subclause for allocator-aware containers, that does not
+    actually use it.  This requirement is used throughout the subclause
+    for a variety of contains, so relocate the definition into the
+    leading subclause that provides a key to definitions used throughout
+    the containers subclauses.
+
+commit 6e7fd98b684a92405934de981abf01414a67ddbd
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Mar 23 14:21:22 2023 +0000
+
+    [version.syn] bump value of __cpp_lib_allocate_at_least
+
+    This is requested for the Tentatively Ready LWG issue 3887.
+
+    Fixes #6202
+
+commit a0403a9407e6520b6bbf0e818d9db8ac1282f4e1
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sat Mar 11 20:40:30 2023 +0000
+
+    [module.interface] Fix outdated example
+
+commit 2c7e87d447d65684c74890074999c60bb45712ab
+Author: Christian Trott <crtrott@sandia.gov>
+Date:   Fri Mar 24 09:32:22 2023 -0700
+
+    [mdspan.layout.left.cons] extents() should be other.extents() (#6069)
+
+    The precondition was erroneously referring to the not yet
+    constructed extents instead of other.extents().
+
+    Note that the extents of the to be constructed layout will be
+    initialized with other.extents - i.e. after construction they will
+    return the same value for the fwd-prod-of-extents etc.
+
+commit 1b0fe66324f2d5e7861397d7f537243833418cde
+Author: Jakub Mazurkiewicz <mazkuba3@gmail.com>
+Date:   Fri Mar 24 17:33:09 2023 +0100
+
+    [range.cartesian.view] Add missing views:: qualifier (#6059)
+
+commit 562af663363337848bcb34a8f5ba37641fb0560e
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Mar 27 17:06:50 2023 -0400
+
+    [over.literal] Cross-reference deprecated grammar (#6209)
+
+    The core convention is to retain deprecated wording in the
+    core clauses, but always make a reference to Annex D
+    where a feature, or parts of a feature, are deprecated.
+
+commit ac47f9cb768760f0abd7a57cbf3074ad5eebf011
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Mar 27 17:09:44 2023 -0400
+
+    [container.reqmts] Move requirements to the right place (#6199)
+
+    As part of the replacement of the container requirements tables with text,
+    several paragraphs of general container requirements were buried
+    in the new subsections for more specific requirements such as
+    reversible containers or allocator-aware containers.
+
+    This seems to have happened when general container requirements
+    followed one of the container requirements tables that are now expressed
+    as text. This change carefully restores text to the general container requirements
+    clause, in the original order they appeared in C++20.
+
+commit bb65fc8e22b8e056cfbeb45ba65c6f37bf355182
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Mar 28 21:04:20 2023 +0200
+
+    [dcl.decl.general] Fix cross-references
+
+    "templated function" is defined in [temp.pre], but avoid having
+    two cross-references to the same place in the same paragraph by
+    dropping the cross-reference for the definition of the grammar
+    non-terminal "requires-clause".
+
+commit 8c99598b60f0a059b37c7e1fd82480aaf32169a5
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Mar 29 10:47:27 2023 +0100
+
+    [class.member.lookup] Also change "N" to "M" in note.
+
+    This change should have been part of the resolution of CWG2642 (via
+    CWG Motion 1), but was accidentally omitted there.
+
+commit 8e2d6ee92f372d9526c01a8fb601da9921c94b2a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Mar 29 16:08:57 2023 +0100
+
+    [stacktrace.format] Use full typename "basic_stacktrace<Allocator>".
+
+commit 70b2f7b6bf0d7fe3d87d9438459f766fdd83b08c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Mar 29 17:31:24 2023 +0100
+
+    [indirectcallable.indirectinvocable] Remove stray "&".
+
+    This was an error in the application of P2609R3.
+
+commit 08581e85636794384029de729a641975bb13260c
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Sun Apr 16 05:18:24 2023 -0400
+
+    [alg.unique] fix typo: namepace -> namespace
+
+commit 1a2e97de0517bb9ee1715a9664fa2861fa025cda
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Apr 17 14:31:05 2023 +0800
+
+    [range.repeat.iterator] Remove redundant period (#6234)
+
+commit 44ff7aa92ba7f716abe96c29876b2ea145a22c66
+Author: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
+Date:   Fri Apr 21 18:56:31 2023 +0330
+
+    [check.yml] update version of "upload" action (#6231)
+
+    Update the `actions/upload-artifact` action to version 3.
+
+commit 413b147b0f48ea87606e0b7fbc107c8316b98fc3
+Author: Detlef Riekenberg <wine.dev@web.de>
+Date:   Thu Apr 27 04:00:32 2023 +0200
+
+    [compliance, headers.cpp.fs] Fix subclause name for cstddef (#6227)
+
+commit 82ecf4355a016847ffcf778abfcf1fe96d02fc79
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Sun Apr 30 07:56:10 2023 -0400
+
+    [flat.map.modifiers] Fix erroneous "try_emplace_hint" (#6238)
+
+    The hint-taking operation is instead an overload of try_emplace.
+
+commit 9568c66abd12eadd696b9f16bb4884908e2aad66
+Author: Daniel Krügler <daniel.kruegler@gmail.com>
+Date:   Sun Apr 30 13:57:23 2023 +0200
+
+    [ranges] Remove "inline" from variable templates (#6218)
+
+commit bdd25a63a8a84a1183ebc125dac132d0572f67fd
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sun Apr 30 08:02:42 2023 -0400
+
+    [iterator.concept.winc] Improve implementation-defined text (#6228)
+
+commit 057da6c79e35cc4cdebaa5a6096738f273c6c2e8
+Author: tocic <tocic@protonmail.ch>
+Date:   Wed Sep 28 13:14:14 2022 +0300
+
+    [back, macros] Fix inconsistent hyphenation of "cross-reference"
+
+commit d1e109e43d7625f4a4ebb6a045fc68a275fca611
+Author: tocic <tocic@protonmail.ch>
+Date:   Wed Sep 28 13:19:36 2022 +0300
+
+    [std] Fix inconsistent hyphenation of "multidimensional"
+
+commit bf9edb92183b34421dd6e02474f2ac943fd7cea3
+Author: tocic <tocic@protonmail.ch>
+Date:   Fri Apr 7 13:56:59 2023 +0300
+
+    [diff.cpp17.temp] Fix inconsistent hyphenation of "well-formed"
+
+commit 62cd54aedecb8bf152e80b1aced64d80e0b8bff6
+Author: tocic <tocic@protonmail.ch>
+Date:   Fri Apr 7 13:57:28 2023 +0300
+
+    [diff.cpp17.depr] Fix inconsistent hyphenation of "well-defined"
+
+commit 57ad77984fd2e07c90b1bb8ca34125452688031a
+Author: tocic <tocic@protonmail.ch>
+Date:   Fri Apr 7 13:51:09 2023 +0300
+
+    [fs.path.type.cvt] Fix inconsistent hyphenation of "error-prone"
+
+commit e16a651b7d6f490e9ffe003c9ca382970c478c1d
+Author: tocic <tocic@protonmail.ch>
+Date:   Fri Apr 7 13:45:39 2023 +0300
+
+    [filesystems] Fix inconsistent hyphenation of "subdirectory"
+
+commit f52423c2a4d60d0ad653a3c8e2895037df016db0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 30 14:07:51 2023 +0100
+
+    [format.string.std] Clarify how an integer is interpreted
+
+commit 62d7d5a2e51d63d676cc93bfe69d4d55ea635983
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 30 14:15:35 2023 +0100
+
+    [class.{default,copy}.ctor] Use new term "constexpr-suitable".
+
+    As of CWG2602 (ce7d8b0360e1509de6f7fd073d0a091238b1326f), the term
+    "constexpr-suitable" replaces the previous phrase "satisfy the
+    requirements for a constexpr function".
+
+commit 696ddeb2b28b48efaffa93b881ff667d85d0a457
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 30 14:22:32 2023 +0100
+
+    [time.duration.general] Use new term "constexpr-suitable".
+
+commit 79aef51943810dcf14654490fb6101bbc9e4a0f9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Apr 30 14:23:05 2023 +0100
+
+    [pairs.pair, variant.ctor, tuple.cnstr] Use new term "constexpr-suitable".
+
+commit b6903b6fe23d06e23191e672ae287f0de0de472c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon May 1 09:47:08 2023 +0200
+
+    [cpp.predefined] Add __cpp_auto_cast
+
+commit 8f946881355fbbe031a325168078b2925e029bba
+Author: xmh0511 <970252187@qq.com>
+Date:   Tue May 2 01:31:02 2023 +0800
+
+    [temp.variadic] Change "init-capture pack" to "init-capture pack declaration"
+
+commit b81e4be37c5f7a4d374546a72bfc82c96601aee2
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri May 5 12:01:05 2023 +0100
+
+    [container.alloc.reqmts] Fix incorrect change of \mandates to \expects
+
+    This was incorrectly changed from a \mandates to an \expects when
+    93ff092d1cd2b335f372b9546365b3d495caf2d8 replaced the requirements
+    tables.
+
+commit 7003252f4db8b388dd097790b374ffed3be1ff56
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Sun May 7 16:27:19 2023 -0400
+
+    [flat.map.cons] Close an angle bracket (#6245)
+
+commit e7492cef7f930089e009913bff6ac30f41d6165e
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat May 6 02:47:07 2023 +0100
+
+    [format] Fix presentation of whitespace; use \caret
+
+commit f8f5b8b564a785297a43b6b823b521e5adc79fb9
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Mon May 8 14:30:31 2023 -0400
+
+    [flat.map.modifiers] "Arg..." should be "Args..." (#6249)
+
+commit 02545c761c7f6c9e336c6badf8660b2baf4ac627
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Tue May 9 13:25:42 2023 -0400
+
+    [flat.set.modifiers] `(first, last)` should be `rg` (#6246)
+
+    Restore consistency with [flat.map.modifiers]/13, which already uses `ranges::distance(rg)`.
+
+ + diff --git a/papers/n4951.md b/papers/n4951.md new file mode 100644 index 0000000000..01e7a0651d --- /dev/null +++ b/papers/n4951.md @@ -0,0 +1,306 @@ +# N4951 Editors' Report -- Programming Languages -- C++ + +Date: 2023-05-10 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4950](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4950.pdf) is the + current and final working draft for C++23. It replaces + [N4944](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4944.pdf), and it + forms the basis of the Draft International Standard for C++23. + * N4951 is this Editors' Report. + * The next working draft will be for C++26. + +### Editorial changes + +There have not been any motions from WG21 since the last working draft. This +revision incorporates all the changes requested by the editorial review +committee in preparation of the Draft International Standard (DIS) ballot, +as well as other editorial changes. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4944 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/n4944...n4950). + + commit b8512a1c292adee71c1145d3c61e32d48dcb8daa + Author: morinmorin + Date: Wed Mar 15 01:45:28 2023 +0900 + + [container.requirements.general] Move exposition-only concept + + The exposition-only concept container-compatible-range is defined + in the subclause for allocator-aware containers, that does not + actually use it. This requirement is used throughout the subclause + for a variety of contains, so relocate the definition into the + leading subclause that provides a key to definitions used throughout + the containers subclauses. + + commit 6e7fd98b684a92405934de981abf01414a67ddbd + Author: Jonathan Wakely + Date: Thu Mar 23 14:21:22 2023 +0000 + + [version.syn] bump value of __cpp_lib_allocate_at_least + + This is requested for the Tentatively Ready LWG issue 3887. + + Fixes #6202 + + commit a0403a9407e6520b6bbf0e818d9db8ac1282f4e1 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sat Mar 11 20:40:30 2023 +0000 + + [module.interface] Fix outdated example + + commit 2c7e87d447d65684c74890074999c60bb45712ab + Author: Christian Trott + Date: Fri Mar 24 09:32:22 2023 -0700 + + [mdspan.layout.left.cons] extents() should be other.extents() (#6069) + + The precondition was erroneously referring to the not yet + constructed extents instead of other.extents(). + + Note that the extents of the to be constructed layout will be + initialized with other.extents - i.e. after construction they will + return the same value for the fwd-prod-of-extents etc. + + commit 1b0fe66324f2d5e7861397d7f537243833418cde + Author: Jakub Mazurkiewicz + Date: Fri Mar 24 17:33:09 2023 +0100 + + [range.cartesian.view] Add missing views:: qualifier (#6059) + + commit 562af663363337848bcb34a8f5ba37641fb0560e + Author: Alisdair Meredith + Date: Mon Mar 27 17:06:50 2023 -0400 + + [over.literal] Cross-reference deprecated grammar (#6209) + + The core convention is to retain deprecated wording in the + core clauses, but always make a reference to Annex D + where a feature, or parts of a feature, are deprecated. + + commit ac47f9cb768760f0abd7a57cbf3074ad5eebf011 + Author: Alisdair Meredith + Date: Mon Mar 27 17:09:44 2023 -0400 + + [container.reqmts] Move requirements to the right place (#6199) + + As part of the replacement of the container requirements tables with text, + several paragraphs of general container requirements were buried + in the new subsections for more specific requirements such as + reversible containers or allocator-aware containers. + + This seems to have happened when general container requirements + followed one of the container requirements tables that are now expressed + as text. This change carefully restores text to the general container requirements + clause, in the original order they appeared in C++20. + + commit bb65fc8e22b8e056cfbeb45ba65c6f37bf355182 + Author: Jens Maurer + Date: Tue Mar 28 21:04:20 2023 +0200 + + [dcl.decl.general] Fix cross-references + + "templated function" is defined in [temp.pre], but avoid having + two cross-references to the same place in the same paragraph by + dropping the cross-reference for the definition of the grammar + non-terminal "requires-clause". + + commit 8c99598b60f0a059b37c7e1fd82480aaf32169a5 + Author: Thomas Köppe + Date: Wed Mar 29 10:47:27 2023 +0100 + + [class.member.lookup] Also change "N" to "M" in note. + + This change should have been part of the resolution of CWG2642 (via + CWG Motion 1), but was accidentally omitted there. + + commit 8e2d6ee92f372d9526c01a8fb601da9921c94b2a + Author: Thomas Köppe + Date: Wed Mar 29 16:08:57 2023 +0100 + + [stacktrace.format] Use full typename "basic_stacktrace". + + commit 70b2f7b6bf0d7fe3d87d9438459f766fdd83b08c + Author: Thomas Köppe + Date: Wed Mar 29 17:31:24 2023 +0100 + + [indirectcallable.indirectinvocable] Remove stray "&". + + This was an error in the application of P2609R3. + + commit 08581e85636794384029de729a641975bb13260c + Author: Arthur O'Dwyer + Date: Sun Apr 16 05:18:24 2023 -0400 + + [alg.unique] fix typo: namepace -> namespace + + commit 1a2e97de0517bb9ee1715a9664fa2861fa025cda + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Apr 17 14:31:05 2023 +0800 + + [range.repeat.iterator] Remove redundant period (#6234) + + commit 44ff7aa92ba7f716abe96c29876b2ea145a22c66 + Author: Mohammed Keyvanzadeh + Date: Fri Apr 21 18:56:31 2023 +0330 + + [check.yml] update version of "upload" action (#6231) + + Update the `actions/upload-artifact` action to version 3. + + commit 413b147b0f48ea87606e0b7fbc107c8316b98fc3 + Author: Detlef Riekenberg + Date: Thu Apr 27 04:00:32 2023 +0200 + + [compliance, headers.cpp.fs] Fix subclause name for cstddef (#6227) + + commit 82ecf4355a016847ffcf778abfcf1fe96d02fc79 + Author: Arthur O'Dwyer + Date: Sun Apr 30 07:56:10 2023 -0400 + + [flat.map.modifiers] Fix erroneous "try_emplace_hint" (#6238) + + The hint-taking operation is instead an overload of try_emplace. + + commit 9568c66abd12eadd696b9f16bb4884908e2aad66 + Author: Daniel Krügler + Date: Sun Apr 30 13:57:23 2023 +0200 + + [ranges] Remove "inline" from variable templates (#6218) + + commit bdd25a63a8a84a1183ebc125dac132d0572f67fd + Author: Alisdair Meredith + Date: Sun Apr 30 08:02:42 2023 -0400 + + [iterator.concept.winc] Improve implementation-defined text (#6228) + + commit 057da6c79e35cc4cdebaa5a6096738f273c6c2e8 + Author: tocic + Date: Wed Sep 28 13:14:14 2022 +0300 + + [back, macros] Fix inconsistent hyphenation of "cross-reference" + + commit d1e109e43d7625f4a4ebb6a045fc68a275fca611 + Author: tocic + Date: Wed Sep 28 13:19:36 2022 +0300 + + [std] Fix inconsistent hyphenation of "multidimensional" + + commit bf9edb92183b34421dd6e02474f2ac943fd7cea3 + Author: tocic + Date: Fri Apr 7 13:56:59 2023 +0300 + + [diff.cpp17.temp] Fix inconsistent hyphenation of "well-formed" + + commit 62cd54aedecb8bf152e80b1aced64d80e0b8bff6 + Author: tocic + Date: Fri Apr 7 13:57:28 2023 +0300 + + [diff.cpp17.depr] Fix inconsistent hyphenation of "well-defined" + + commit 57ad77984fd2e07c90b1bb8ca34125452688031a + Author: tocic + Date: Fri Apr 7 13:51:09 2023 +0300 + + [fs.path.type.cvt] Fix inconsistent hyphenation of "error-prone" + + commit e16a651b7d6f490e9ffe003c9ca382970c478c1d + Author: tocic + Date: Fri Apr 7 13:45:39 2023 +0300 + + [filesystems] Fix inconsistent hyphenation of "subdirectory" + + commit f52423c2a4d60d0ad653a3c8e2895037df016db0 + Author: Thomas Köppe + Date: Sun Apr 30 14:07:51 2023 +0100 + + [format.string.std] Clarify how an integer is interpreted + + commit 62d7d5a2e51d63d676cc93bfe69d4d55ea635983 + Author: Thomas Köppe + Date: Sun Apr 30 14:15:35 2023 +0100 + + [class.{default,copy}.ctor] Use new term "constexpr-suitable". + + As of CWG2602 (ce7d8b0360e1509de6f7fd073d0a091238b1326f), the term + "constexpr-suitable" replaces the previous phrase "satisfy the + requirements for a constexpr function". + + commit 696ddeb2b28b48efaffa93b881ff667d85d0a457 + Author: Thomas Köppe + Date: Sun Apr 30 14:22:32 2023 +0100 + + [time.duration.general] Use new term "constexpr-suitable". + + commit 79aef51943810dcf14654490fb6101bbc9e4a0f9 + Author: Thomas Köppe + Date: Sun Apr 30 14:23:05 2023 +0100 + + [pairs.pair, variant.ctor, tuple.cnstr] Use new term "constexpr-suitable". + + commit b6903b6fe23d06e23191e672ae287f0de0de472c + Author: Jens Maurer + Date: Mon May 1 09:47:08 2023 +0200 + + [cpp.predefined] Add __cpp_auto_cast + + commit 8f946881355fbbe031a325168078b2925e029bba + Author: xmh0511 <970252187@qq.com> + Date: Tue May 2 01:31:02 2023 +0800 + + [temp.variadic] Change "init-capture pack" to "init-capture pack declaration" + + commit b81e4be37c5f7a4d374546a72bfc82c96601aee2 + Author: Jonathan Wakely + Date: Fri May 5 12:01:05 2023 +0100 + + [container.alloc.reqmts] Fix incorrect change of \mandates to \expects + + This was incorrectly changed from a \mandates to an \expects when + 93ff092d1cd2b335f372b9546365b3d495caf2d8 replaced the requirements + tables. + + commit 7003252f4db8b388dd097790b374ffed3be1ff56 + Author: Arthur O'Dwyer + Date: Sun May 7 16:27:19 2023 -0400 + + [flat.map.cons] Close an angle bracket (#6245) + + commit e7492cef7f930089e009913bff6ac30f41d6165e + Author: Thomas Köppe + Date: Sat May 6 02:47:07 2023 +0100 + + [format] Fix presentation of whitespace; use \caret + + commit f8f5b8b564a785297a43b6b823b521e5adc79fb9 + Author: Arthur O'Dwyer + Date: Mon May 8 14:30:31 2023 -0400 + + [flat.map.modifiers] "Arg..." should be "Args..." (#6249) + + commit 02545c761c7f6c9e336c6badf8660b2baf4ac627 + Author: Arthur O'Dwyer + Date: Tue May 9 13:25:42 2023 -0400 + + [flat.set.modifiers] `(first, last)` should be `rg` (#6246) + + Restore consistency with [flat.map.modifiers]/13, which already uses `ranges::distance(rg)`. diff --git a/papers/n4959.html b/papers/n4959.html new file mode 100644 index 0000000000..958923da9f --- /dev/null +++ b/papers/n4959.html @@ -0,0 +1,698 @@ + + + + + +N4959 + + +

N4959 Editors' Report -- Programming Languages -- C++

+ +

Date: 2023-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 +and to those who have provided pull requests with fixes, +and special thanks to Johel Ernesto Guerrero Peña for providing in-depth review +of many of the draft motion applications.

+ +

New papers

+ +
    +
  • N4958 is the +current working draft for C++26. It replaces +N4950.
  • +
  • N4959 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Notes on motions

+ +

All motions were applied cleanly. In a small number of cases, the approved +wording was based on an older draft and needed reconciliation with intervening +changes, but it was clear how to do this.

+ +
    +
  • The wording for P1854R4 +("Making non-encodable string literals ill-formed", CWG Poll 3) +has been reconciled with previous changes from +P2314R4 +("Character sets and encodings").
  • +
  • For P0792R14 +("function_ref: a type-erased callable reference", LWG Poll 18), +among some minor fixes for correctness and consistency, +exposition-only members have been added explicitly to the class synopsis, +which had only been mentioned in the descriptive text in the approved wording.
  • +
  • The feature test macro __cpp_lib_format has been modified three times, as follows: +
      +
    • 202304L by +P2510R3 +("Formatting pointers", LWG Poll 10)
    • +
    • 202305L by +P2757R3 +("Type checking format args", LWG Poll 20)
    • +
    • 202306L by +P2637R3 +("Member visit", LWG Poll 21)
    • +
  • +
  • The feature test macro for +P2641R4 +("Checking if a union alternative is active", LWG Poll 22) +has been renamed from __cpp_lib_within_lifetime to __cpp_lib_is_within_lifetime, +which seems more appropriate and follows existing practice.
  • +
  • For P2630R4 +(submdspan, LWG Poll 29), numerous minor editorial corrections and improvements +have been applied; see the full commit log for details.
  • +
+ +

Core working group polls

+ +

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

+ +

CWG Poll 2: Accept as a Defect Report and apply the changes in +P2621R2 +(UB? In my Lexer?) to the C++26 Working Paper.

+ +

CWG Poll 3: Accept as a Defect Report and apply the changes in +P1854R4 +(Making non-encodable string literals ill-formed) to the C++26 Working Paper.

+ +

CWG Poll 4: Apply the changes in P2361R6 +(Unevaluated strings) to the C++26 Working Paper.

+ +

CWG Poll 5: Apply the changes in P2558R2 +(Add @, $, and ` to the basic character set) to the C++26 Working Paper.

+ +

CWG Poll 6: Apply the changes in P2738R1 +(constexpr cast from void*: towards constexpr type-erasure) to the C++26 Working Paper.

+ +

CWG Poll 7: Accept as a Defect Report and apply the changes in +P2915R0 +(Proposed resolution for CWG1223) to the C++26 Working Paper.

+ +

CWG Poll 8: Accept as a Defect Report and apply the changes in +P2552R3 +(On the ignorability of standard attributes) to the C++26 Working Paper.

+ +

CWG Poll 9: Accept as a Defect Report and apply the changes in +P2752R3 +(Static storage for braced initializers) to the C++26 Working Paper.

+ +

CWG Poll 10: Apply the changes in P2741R3 +(User-generated static_assert messages) to the C++26 Working Paper.

+ +

CWG Poll 11: Apply the changes in P2169R4 +(A nice placeholder with no name) to the C++26 Working Paper.

+ +

Library working group polls

+ +

LWG Poll 1: Apply the changes for all Tentatively Ready issues in +P2910R0 +(C++ Standard Library Issues to be moved in Varna, Jun. 2023) to the C++ working paper.

+ +

LWG Poll 2: Apply the changes in P2497R0 +(Testing for success or failure of <charconv> functions) to the C++ working paper.

+ +

LWG Poll 3: Apply the changes in P2592R3 +(Hashing support for std::chrono value classes) to the C++ working paper.

+ +

LWG Poll 4: Apply the changes in P2587R3 +(to_string or not to_string) to the C++ working paper.

+ +

LWG Poll 5: Apply the changes in P2562R1 +(constexpr Stable Sorting) to the C++ working paper.

+ +

LWG Poll 6: Apply the changes in P2545R4 +(Read-Copy Update (RCU)) to the C++ working paper.

+ +

LWG Poll 7: Apply the changes in P2530R3 +(Hazard Pointers for C++26) to the C++ working paper.

+ +

LWG Poll 8: Apply the changes in P2538R1 +(ADL-proof std::projected) to the C++ working paper.

+ +

LWG Poll 9: Apply the changes in P2495R3 +(Interfacing stringstreams with string_view) to the C++ working paper.

+ +

LWG Poll 10: Apply the changes in P2510R3 +(Formatting pointers) to the C++ working paper.

+ +

LWG Poll 11: Apply the changes in P2198R7 +(Freestanding Feature-Test Macros and Implementation-Defined Extensions) to the C++ working paper.

+ +

LWG Poll 12: Apply the changes in P2338R4 +(Freestanding Library: Character primitives and the C library) to the C++ working paper.

+ +

LWG Poll 13: Apply the changes in P2013R5 +(Freestanding Language: Optional ::operator new) to the C++ working paper.

+ +

LWG Poll 14: Apply the changes in P0493R4 +(Atomic maximum/minimum) to the C++ working paper.

+ +

LWG Poll 15: Apply the changes in P2363R5 +(Extending associative containers with the remaining heterogeneous overloads) to the C++ working paper.

+ +

LWG Poll 16: Apply the changes in P1901R2 +(Enabling the Use of weak_ptr as Keys in Unordered Associative Containers) to the C++ working paper.

+ +

LWG Poll 17: Apply the changes in P1885R12 +(Naming Text Encodings to Demystify Them) to the C++ working paper.

+ +

LWG Poll 18: Apply the changes in P0792R14 +(function_ref: a type-erased callable reference) to the C++ working paper.

+ +

LWG Poll 19: Apply the changes in P2874R2 +(Mandating Annex D) to the C++ working paper.

+ +

LWG Poll 20: Apply the changes in P2757R3 +(Type checking format args) to the C++ working paper.

+ +

LWG Poll 21: Apply the changes in P2637R3 +(Member visit) to the C++ working paper.

+ +

LWG Poll 22: Apply the changes in P2641R4 +(Checking if a union alternative is active) to the C++ working paper.

+ +

LWG Poll 23: Apply the changes in P1759R6 +(Native handles and file streams) to the C++ working paper.

+ +

LWG Poll 24: Apply the changes in P2697R1 +(Interfacing bitset with string_view) to the C++ working paper.

+ +

LWG Poll 25: Apply the changes in P1383R2 +(More constexpr for <cmath> and <complex>) to the C++ working paper.

+ +

LWG Poll 26: Apply the changes in P2734R0 +(Adding the new 2022 SI prefixes) to the C++ working paper.

+ +

LWG Poll 27: Apply the changes in P2548R6 +(copyable_function) to the C++ working paper.

+ +

LWG Poll 28: Apply the changes in P2714R1 +(Bind front and back to NTTP callables) to the C++ working paper.

+ +

LWG Poll 29: Apply the changes in P2630R4 +(submdspan) to the C++ working paper.

+ +

Editorial changes

+ +

Noteworthy changes

+ +

Some Unicode examples of the new formatting facilities had been missing from the +last few working drafts (but are present in the C++23 DIS) because they needed +some bespoke handling. This has now been integrated into the main branch, and +the examples now appear correctly in the working draft. (The examples are +generated with LuaTeX. As a side effect, the typeface used in existing diagrams +has been changed to match the one used for the main body text. We have also +explored switching the typesetting engine for the main document from eTeX to +LuaTeX. This is possible in principle, but results in slightly lower typographic +quality at the moment, so we are holding off on this and will revisit this +change in the future.)

+ +

The title of the working draft has been changed to "Working Draft, Programming +Languages — C++", to match the official title of the standard more closely.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4950 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 abb81facf56f82a7487b3f64ae337ce2802c4bf3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 12 09:38:16 2023 +0200
+
+    [intro.execution] Fix bad function call in example
+
+commit 42f21d84fb374b11d44c0b367bda649636128b6a
+Author: Andrew Rogers <adr26__github@nunsway.co.uk>
+Date:   Wed Apr 19 01:03:57 2023 +0100
+
+    [dcl.init.aggr] Add missing apostrophe
+
+commit 4514233a48954d0fd0669236cc986640e33feb04
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Fri May 12 23:14:43 2023 +0200
+
+    [basic.compound] Fix cross-reference for 'incomplete type' (#6210)
+
+commit 4fac9f97a2c25d39a01f75cf198d0783bfa8deda
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue May 16 17:01:51 2023 +0100
+
+    [strings], [unord.req.general], [stringbuf.members]: Fix xrefs to [container.requirements.general]
+
+    All the references for "qualifies as an input iterator" and "qualifies
+    as an allocator" are supposed to be to [container.reqmts] p69 which
+    begins:
+
+    > The behavior of certain container member functions and deduction
+    > guides depends on whether types qualify as input iterators or
+    > allocators.
+
+    The reference in [string.require] for obtaining an allocator should be
+    to [container.reqmts] p64.
+
+    The reference in [string.require] Note 2 should be to
+    [container.requirements.pre] p3.
+
+    Fixes #6184
+
+commit 1be4801ac1f90aca9a8f5804a48e8bcd082f5bb9
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Jun 1 20:57:05 2023 +0200
+
+    [lib] Refer to exposition-only function templates as templates, not functions (#6265)
+
+     * [tuple.apply]/1, /4
+     * [expected.object.assign]/1
+     * [iterator.cust.swap]/2
+     * [specialized.algorithms.general]/3
+
+commit c0685a584ea51d3e47381478a750729da3202b37
+Author: Géry Ogam <gery.ogam@gmail.com>
+Date:   Tue Jun 13 18:21:59 2023 +0200
+
+    [basic.lval] Reword the misused term ‘classifications’ (#4913)
+
+commit ae4cba4dc8ee2437f39a451268ad6bc924076da0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jun 20 13:29:38 2023 +0100
+
+    [cover-wd] A more appropriate title, and better line spacing
+
+commit 7e7afe0965e4e16ff651167212ea05ed9c0ef788
+Author: Eisenwave <me@eisenwave.net>
+Date:   Thu Jul 6 12:45:54 2023 +0200
+
+    [expr.mul] Add missing commas (#6366)
+
+commit 384d36a0d30e6a8050e23f7193db40fb56ff4f06
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jul 6 20:45:10 2023 +0100
+
+    [filebuf.virtuals] fix "if width if less than zero" typo
+
+commit 964015779245341d64d93bbd0d1e11f050b32e70
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Mon Jul 10 18:53:10 2023 +0800
+
+    [time.duration.cons] Fix duplicate definition in example (#6372)
+
+commit e6c2f8fb0d5ad6cda3e2d3da63bd5d5e434635b4
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jul 18 23:16:59 2023 +0100
+
+    [diff.cpp23.expr] Fix environment ("example" should be "codeblock")
+
+commit 2109f579cc6749d19ddf9cf892e8aec4762ba344
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 21 16:21:54 2023 +0100
+
+    [locale.general] Add cross-references to class synopsis
+
+commit c2e05a4080e8c79bcc9971054ca6fb6ae9b3e722
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 21 17:05:10 2023 +0100
+
+    [functional.syn] Tweak cross-references in class synopsis
+
+commit 8334cc876d29595f0f2796a6de42acae937d8377
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 21 23:29:54 2023 +0100
+
+    [functional.syn, func.wrap.move] Hyphenate "move-only wrapper"
+
+commit 7fb62d5f50bfbfc159df4ca0af932ee82d26bc41
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jul 21 18:13:28 2023 +0100
+
+    [version.syn] Rename smart_pointer_owner_equality to smart_ptr_owner_equality
+
+    For consistency: the use of "ptr" is already prevailing.
+
+commit 56a6b7fe068726ace9196366c968cc679653cc04
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed May 17 23:27:22 2023 +0800
+
+    <ranges> Add missing colon for the Effects: Equivalent to return format
+
+commit a34d2e08bda9b1314ecec1b608745a88a678d664
+Author: vasama <git@vasama.org>
+Date:   Wed Jun 7 11:01:02 2023 +0300
+
+    [expr.pre] Clarify note on pointer subtraction
+
+commit 96f695aea7589a62e5ebb55a18a40f985f7d89ce
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Jun 13 09:18:01 2023 +0300
+
+    [basic.def.odr] Restructure requirements in p14-p15
+
+commit ebba9f316ddd8c120608447b00ea32bf3926a18d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sun Jul 23 02:29:17 2023 +0100
+
+    [func.wrap.func.general, func.wrap.move.class] Remove redundant declaration (#6273)
+
+    We don't need to repeat the declarations of the incomplete primary
+    template, they are already present in the <functional> synopsis.
+
+commit e6bd946d953b76e908a8e853d93834572c125d59
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jul 14 13:31:47 2023 -0700
+
+    [basic.scope.scope] Avoid hard-to-read except...unless construction.
+
+    Factor out a name for the "unless" condition to avoid the double-negative.
+
+commit 3769c701daf9ae38f8db054670106abca7c03d32
+Author: Roger Orr <rogero@howzatt.co.uk>
+Date:   Tue Jul 18 23:54:34 2023 +0100
+
+    [dcl.ambig.res] fix double declaration of 'y' in example
+
+commit 0bf51a3bc5c24b070265412c32e53a0060d73eef
+Author: Christian Trott <crtrott@sandia.gov>
+Date:   Sat Jul 22 19:33:41 2023 -0600
+
+    [mdspan.layout.stride.cons] Fix missed rename of template parameter (#6385)
+
+    "LayoutStrideMapping" should say "StridedLayoutMapping".
+
+commit f8feaa6e5bc8e6d28e00c06a3de305f80f395913
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Fri Jul 21 11:43:39 2023 +0200
+
+    [version.syn] Fix header references.
+
+commit 872bda08678d1aeecfc555f26920cec28a2ad497
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Jun 1 14:59:00 2023 +0000
+
+    [basic.stc.dynamic.allocation] Remove redundant 'address of' from a note
+
+commit 880531fad125c4b806300151ddcb961a7f44a181
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Sat Jul 22 21:49:38 2023 -0400
+
+    [flat.{,multi}{map,set}.cons]: zip_view should be views::zip (#6373)
+
+    We don't expect to use CTAD on `ranges::zip_view(args...)`;
+    what we expect is `views::zip`.
+
+commit a417ade53722d944481baac575292874c1bcc79a
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Jul 22 21:50:37 2023 -0400
+
+    [range.enumerate.overview] Add cross reference to [range.adaptor.object] (#6219)
+
+commit 7f100cc67b0bb263e2f438238e87555347ae45c0
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Jul 23 17:50:27 2023 +0800
+
+    [input.output] Fix the "Effects: Equivalent to" format (#6402)
+
+commit 9334219bd95a85e86b20c8a712397f9f23f0f7a8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jul 23 06:59:28 2023 +0200
+
+    [class.copy.assign] Remove note obsoleted by CWG2586
+
+commit 503b4b261061bdd2481e1e4f1153481a0a75ecee
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jul 23 08:29:10 2023 +0200
+
+    [dcl.fct.def.default] Highlight different references in defaulted assignments
+
+commit a567088b0ab8ca62f0ff5a7b4746337ac3f6df9b
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 24 12:45:57 2023 +0100
+
+    [assets] Move separate assets into "assets" subdirectory
+
+commit 7e2cc3ba6a30a693a96bbc37c4d8428d92ce1fa8
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Aug 19 17:03:37 2022 +0100
+
+    [assets] Unicode examples
+
+commit 589af92ce99b91444a3e6155cb64f8009918e885
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Aug 28 02:09:47 2022 +0100
+
+    [format.string.{std,escaped}, macros] Add missing examples
+
+commit f61a2c8a847e846ba1167c876b0fc1532ab433d7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Jul 24 21:27:00 2023 +0100
+
+    [format.string.escape] Fix mis{sing,escaped} braces
+
+    This was an oversight in the application of
+    https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2713r0.html
+    in e38ea31d46ca2964c4f9169f049e2f15e2cd5957.
+
+commit 3b2a8ee11725eb485df89dec40a7e0fc965debb2
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Fri Jul 21 12:46:48 2023 -0400
+
+    [func.wrap.ref.class] change deduction guide to match its detailed specifications
+
+commit d5160c6ff6c09fc0c52b5b11676c03ff179f4554
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Jul 23 02:51:25 2023 +0100
+
+    [mdspan.submdspan.extents] Factor out common result expression
+
+commit 84cf8ef63a479a3fda05a219dd26ab4b8c6a8e32
+Author: Jakub Mazurkiewicz <mazkuba3@gmail.com>
+Date:   Tue Jul 25 01:06:49 2023 +0200
+
+    [mdspan.mdspan.cons] `OtherIndexType` is not a parameter pack; missing _v (#6263)
+
+commit a636f553369825bc37ac0d95c171a00c526af499
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Jul 24 16:16:14 2023 +0000
+
+    [intro.object] Fix cross-references for library implicit object creation
+
+commit d09a77e09a5210c50994b89d999f3cbdfcc9a436
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed May 17 18:51:00 2023 +0100
+
+    [re.results.general, string.cons] Fix references to container reqmts
+
+    [re.results.general] should refer to [container.alloc.reqmts] for an
+    allocator-aware container, [strings.cons] should refer to sequence
+    container requirements.
+
+commit dd32b7eeb21e0ca8be7aae1996814a2ffda0ed83
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu May 18 12:54:12 2023 +0100
+
+    [container.gen.reqmts] Adjust subclause names and stable tags
+
+    There are no more cross-references to [container.gen.reqmts] or
+    [container.requirements.general], so this doesn't affect anything else.
+
+commit a0e6740cda724c192ea14979e2fa92e9f38cf242
+Author: Janet Cobb <git@randomcat.org>
+Date:   Mon Jul 24 12:09:44 2023 -0400
+
+    [basic.fundamental] Clarify that table of minimum integral type widths applies only to standard integral types
+
+commit 3a2586ccb4112f32f08643f7fcafab0b6b7956e2
+Author: Joshua Berne <berne@notadragon.com>
+Date:   Fri Jul 28 15:31:51 2023 -0400
+
+    [dcl.attr.grammar] Fix typo "appeartain" -> "appertain" (#6420)
+
+commit 00b4bb25e7b881cc53dca91dd44ef87c9696b19c
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Aug 13 22:35:57 2023 +0200
+
+    [over.ics.list] Fix missing std:: in example (#6453)
+
+commit cf7d5820d2ab8352d96462c647b735dc575cc1cb
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Aug 15 00:12:21 2023 +0200
+
+    [depr.static.constexpr] Cross-reference core clauses for deprecated feature (#6448)
+
+commit 1353359777de653346dd05ed117bba3627b6c7ca
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jan 24 18:51:02 2023 +0100
+
+    [class.mem.general] Clarify class completeness
+
+commit 77d1b66193d5324b121979474d0e35645bbcfb1c
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Aug 1 13:39:55 2023 +0800
+
+    [memory.syn] Remove redundant freestanding mark for members
+
+    Making `allocator_arg_t` shown like `from_range_t` in [ranges.syn].
+
+commit bf304328b603d96b9da5dc38dfeb04057c67cc53
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Aug 1 13:42:07 2023 +0800
+
+    [ranges.syn] Remove redundant freestanding mark for members
+
+commit d347b328e058bb4b357a2b7b4733c923fca6fd98
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Tue Aug 15 00:42:54 2023 +0200
+
+    [temp.over] itemize parts of long paragraph (#6443)
+
+commit e34a8e15e1de7eab0980af328765957c6118fc04
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Tue Aug 15 00:45:43 2023 +0200
+
+    [meta.unary.prop] itemize long sentence (#6436)
+
+ + diff --git a/papers/n4959.md b/papers/n4959.md new file mode 100644 index 0000000000..a1f6effec6 --- /dev/null +++ b/papers/n4959.md @@ -0,0 +1,553 @@ +# N4959 Editors' Report -- Programming Languages -- C++ + +Date: 2023-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) +and to those who have provided pull requests with fixes, +and special thanks to Johel Ernesto Guerrero Peña for providing in-depth review +of many of the draft motion applications. + +## New papers + + * [N4958](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4958.pdf) is the + current working draft for C++26. It replaces + [N4950](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4950.pdf). + * N4959 is this Editors' Report. + +## Motions incorporated into working draft + +### Notes on motions + +All motions were applied cleanly. In a small number of cases, the approved +wording was based on an older draft and needed reconciliation with intervening +changes, but it was clear how to do this. + +* The wording for [P1854R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1854r4.pdf) + ("Making non-encodable string literals ill-formed", CWG Poll 3) + has been reconciled with previous changes from + [P2314R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2314r4.html) + ("Character sets and encodings"). +* For [P0792R14](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0792r14.html) + ("`function_ref`: a type-erased callable reference", LWG Poll 18), + among some minor fixes for correctness and consistency, + exposition-only members have been added explicitly to the class synopsis, + which had only been mentioned in the descriptive text in the approved wording. +* The feature test macro `__cpp_lib_format` has been modified three times, as follows: + * `202304L` by + [P2510R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2510r3.pdf) + ("Formatting pointers", LWG Poll 10) + * `202305L` by + [P2757R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2757r3.html) + ("Type checking format args", LWG Poll 20) + * `202306L` by + [P2637R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2637r3.html) + ("Member `visit`", LWG Poll 21) +* The feature test macro for + [P2641R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2641r4.html) + ("Checking if a union alternative is active", LWG Poll 22) + has been renamed from `__cpp_lib_within_lifetime` to `__cpp_lib_is_within_lifetime`, + which seems more appropriate and follows existing practice. +* For [P2630R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2630r4.html) + (`submdspan`, LWG Poll 29), numerous minor editorial corrections and improvements + have been applied; see the full commit log for details. + +### Core working group polls + +CWG Poll 1: Accept as Defect Reports and apply the proposed resolutions of all issues in +[P2922R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2922r0.html) +(Core Language Working Group "ready" Issues for the June, 2023 meeting) to the C++ Working Paper. + +CWG Poll 2: Accept as a Defect Report and apply the changes in +[P2621R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2621r2.pdf) +(UB? In my Lexer?) to the C++26 Working Paper. + +CWG Poll 3: Accept as a Defect Report and apply the changes in +[P1854R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1854r4.pdf) +(Making non-encodable string literals ill-formed) to the C++26 Working Paper. + +CWG Poll 4: Apply the changes in [P2361R6](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2361r6.pdf) +(Unevaluated strings) to the C++26 Working Paper. + +CWG Poll 5: Apply the changes in [P2558R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2558r2.html) +(Add `@`, `$`, and ` to the basic character set) to the C++26 Working Paper. + +CWG Poll 6: Apply the changes in [P2738R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2738r1.pdf) +(constexpr cast from `void*`: towards constexpr type-erasure) to the C++26 Working Paper. + +CWG Poll 7: Accept as a Defect Report and apply the changes in +[P2915R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2915r0.pdf) +(Proposed resolution for CWG1223) to the C++26 Working Paper. + +CWG Poll 8: Accept as a Defect Report and apply the changes in +[P2552R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2552r3.pdf) +(On the ignorability of standard attributes) to the C++26 Working Paper. + +CWG Poll 9: Accept as a Defect Report and apply the changes in +[P2752R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2752r3.html) +(Static storage for braced initializers) to the C++26 Working Paper. + +CWG Poll 10: Apply the changes in [P2741R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2741r3.pdf) +(User-generated `static_assert` messages) to the C++26 Working Paper. + +CWG Poll 11: Apply the changes in [P2169R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2169r4.pdf) +(A nice placeholder with no name) to the C++26 Working Paper. + +### Library working group polls + +LWG Poll 1: Apply the changes for all Tentatively Ready issues in +[P2910R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2910r0.html) +(C++ Standard Library Issues to be moved in Varna, Jun. 2023) to the C++ working paper. + +LWG Poll 2: Apply the changes in [P2497R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2497r0.html) +(Testing for success or failure of `` functions) to the C++ working paper. + +LWG Poll 3: Apply the changes in [P2592R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2592r3.html) +(Hashing support for `std::chrono` value classes) to the C++ working paper. + +LWG Poll 4: Apply the changes in [P2587R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2587r3.html) +(`to_string` or not `to_string`) to the C++ working paper. + +LWG Poll 5: Apply the changes in [P2562R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2562r1.pdf) +(`constexpr` Stable Sorting) to the C++ working paper. + +LWG Poll 6: Apply the changes in [P2545R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf) +(Read-Copy Update (RCU)) to the C++ working paper. + +LWG Poll 7: Apply the changes in [P2530R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2530r3.pdf) +(Hazard Pointers for C++26) to the C++ working paper. + +LWG Poll 8: Apply the changes in [P2538R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2538r1.html) +(ADL-proof `std::projected`) to the C++ working paper. + +LWG Poll 9: Apply the changes in [P2495R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2495r3.pdf) +(Interfacing stringstreams with `string_view`) to the C++ working paper. + +LWG Poll 10: Apply the changes in [P2510R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2510r3.pdf) +(Formatting pointers) to the C++ working paper. + +LWG Poll 11: Apply the changes in [P2198R7](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2198r7.html) +(Freestanding Feature-Test Macros and Implementation-Defined Extensions) to the C++ working paper. + +LWG Poll 12: Apply the changes in [P2338R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2338r4.html) +(Freestanding Library: Character primitives and the C library) to the C++ working paper. + +LWG Poll 13: Apply the changes in [P2013R5](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2013r5.html) +(Freestanding Language: Optional `::operator new`) to the C++ working paper. + +LWG Poll 14: Apply the changes in [P0493R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0493r4.pdf) +(Atomic maximum/minimum) to the C++ working paper. + +LWG Poll 15: Apply the changes in [P2363R5](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2363r5.html) +(Extending associative containers with the remaining heterogeneous overloads) to the C++ working paper. + +LWG Poll 16: Apply the changes in [P1901R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1901r2.html) +(Enabling the Use of `weak_ptr` as Keys in Unordered Associative Containers) to the C++ working paper. + +LWG Poll 17: Apply the changes in [P1885R12](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1885r12.pdf) +(Naming Text Encodings to Demystify Them) to the C++ working paper. + +LWG Poll 18: Apply the changes in [P0792R14](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0792r14.html) +(`function_ref`: a type-erased callable reference) to the C++ working paper. + +LWG Poll 19: Apply the changes in [P2874R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2874r2.pdf) +(Mandating Annex D) to the C++ working paper. + +LWG Poll 20: Apply the changes in [P2757R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2757r3.html) +(Type checking format args) to the C++ working paper. + +LWG Poll 21: Apply the changes in [P2637R3](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2637r3.html) +(Member `visit`) to the C++ working paper. + +LWG Poll 22: Apply the changes in [P2641R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2641r4.html) +(Checking if a union alternative is active) to the C++ working paper. + +LWG Poll 23: Apply the changes in [P1759R6](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1759r6.html) +(Native handles and file streams) to the C++ working paper. + +LWG Poll 24: Apply the changes in [P2697R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2697r1.pdf) +(Interfacing `bitset` with `string_view`) to the C++ working paper. + +LWG Poll 25: Apply the changes in [P1383R2](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1383r2.pdf) +(More `constexpr` for `` and ``) to the C++ working paper. + +LWG Poll 26: Apply the changes in [P2734R0](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2734r0.pdf) +(Adding the new 2022 SI prefixes) to the C++ working paper. + +LWG Poll 27: Apply the changes in [P2548R6](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2548r6.pdf) +(`copyable_function`) to the C++ working paper. + +LWG Poll 28: Apply the changes in [P2714R1](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2714r1.html) +(Bind front and back to NTTP callables) to the C++ working paper. + +LWG Poll 29: Apply the changes in [P2630R4](http://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2630r4.html) +(`submdspan`) to the C++ working paper. + +## Editorial changes + +### Noteworthy changes + +Some Unicode examples of the new formatting facilities had been missing from the +last few working drafts (but are present in the C++23 DIS) because they needed +some bespoke handling. This has now been integrated into the main branch, and +the examples now appear correctly in the working draft. (The examples are +generated with LuaTeX. As a side effect, the typeface used in existing diagrams +has been changed to match the one used for the main body text. We have also +explored switching the typesetting engine for the main document from eTeX to +LuaTeX. This is possible in principle, but results in slightly lower typographic +quality at the moment, so we are holding off on this and will revisit this +change in the future.) + +The title of the working draft has been changed to "Working Draft, Programming +Languages — C++", to match the official title of the standard more closely. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4950 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/n4950...n4958). + + commit abb81facf56f82a7487b3f64ae337ce2802c4bf3 + Author: Jens Maurer + Date: Fri May 12 09:38:16 2023 +0200 + + [intro.execution] Fix bad function call in example + + commit 42f21d84fb374b11d44c0b367bda649636128b6a + Author: Andrew Rogers + Date: Wed Apr 19 01:03:57 2023 +0100 + + [dcl.init.aggr] Add missing apostrophe + + commit 4514233a48954d0fd0669236cc986640e33feb04 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Fri May 12 23:14:43 2023 +0200 + + [basic.compound] Fix cross-reference for 'incomplete type' (#6210) + + commit 4fac9f97a2c25d39a01f75cf198d0783bfa8deda + Author: Jonathan Wakely + Date: Tue May 16 17:01:51 2023 +0100 + + [strings], [unord.req.general], [stringbuf.members]: Fix xrefs to [container.requirements.general] + + All the references for "qualifies as an input iterator" and "qualifies + as an allocator" are supposed to be to [container.reqmts] p69 which + begins: + + > The behavior of certain container member functions and deduction + > guides depends on whether types qualify as input iterators or + > allocators. + + The reference in [string.require] for obtaining an allocator should be + to [container.reqmts] p64. + + The reference in [string.require] Note 2 should be to + [container.requirements.pre] p3. + + Fixes #6184 + + commit 1be4801ac1f90aca9a8f5804a48e8bcd082f5bb9 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Jun 1 20:57:05 2023 +0200 + + [lib] Refer to exposition-only function templates as templates, not functions (#6265) + + * [tuple.apply]/1, /4 + * [expected.object.assign]/1 + * [iterator.cust.swap]/2 + * [specialized.algorithms.general]/3 + + commit c0685a584ea51d3e47381478a750729da3202b37 + Author: Géry Ogam + Date: Tue Jun 13 18:21:59 2023 +0200 + + [basic.lval] Reword the misused term ‘classifications’ (#4913) + + commit ae4cba4dc8ee2437f39a451268ad6bc924076da0 + Author: Thomas Köppe + Date: Tue Jun 20 13:29:38 2023 +0100 + + [cover-wd] A more appropriate title, and better line spacing + + commit 7e7afe0965e4e16ff651167212ea05ed9c0ef788 + Author: Eisenwave + Date: Thu Jul 6 12:45:54 2023 +0200 + + [expr.mul] Add missing commas (#6366) + + commit 384d36a0d30e6a8050e23f7193db40fb56ff4f06 + Author: Jonathan Wakely + Date: Thu Jul 6 20:45:10 2023 +0100 + + [filebuf.virtuals] fix "if width if less than zero" typo + + commit 964015779245341d64d93bbd0d1e11f050b32e70 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Mon Jul 10 18:53:10 2023 +0800 + + [time.duration.cons] Fix duplicate definition in example (#6372) + + commit e6c2f8fb0d5ad6cda3e2d3da63bd5d5e434635b4 + Author: Thomas Köppe + Date: Tue Jul 18 23:16:59 2023 +0100 + + [diff.cpp23.expr] Fix environment ("example" should be "codeblock") + + commit 2109f579cc6749d19ddf9cf892e8aec4762ba344 + Author: Thomas Köppe + Date: Fri Jul 21 16:21:54 2023 +0100 + + [locale.general] Add cross-references to class synopsis + + commit c2e05a4080e8c79bcc9971054ca6fb6ae9b3e722 + Author: Thomas Köppe + Date: Fri Jul 21 17:05:10 2023 +0100 + + [functional.syn] Tweak cross-references in class synopsis + + commit 8334cc876d29595f0f2796a6de42acae937d8377 + Author: Thomas Köppe + Date: Fri Jul 21 23:29:54 2023 +0100 + + [functional.syn, func.wrap.move] Hyphenate "move-only wrapper" + + commit 7fb62d5f50bfbfc159df4ca0af932ee82d26bc41 + Author: Thomas Köppe + Date: Fri Jul 21 18:13:28 2023 +0100 + + [version.syn] Rename smart_pointer_owner_equality to smart_ptr_owner_equality + + For consistency: the use of "ptr" is already prevailing. + + commit 56a6b7fe068726ace9196366c968cc679653cc04 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed May 17 23:27:22 2023 +0800 + + Add missing colon for the Effects: Equivalent to return format + + commit a34d2e08bda9b1314ecec1b608745a88a678d664 + Author: vasama + Date: Wed Jun 7 11:01:02 2023 +0300 + + [expr.pre] Clarify note on pointer subtraction + + commit 96f695aea7589a62e5ebb55a18a40f985f7d89ce + Author: Thomas Köppe + Date: Tue Jun 13 09:18:01 2023 +0300 + + [basic.def.odr] Restructure requirements in p14-p15 + + commit ebba9f316ddd8c120608447b00ea32bf3926a18d + Author: Jonathan Wakely + Date: Sun Jul 23 02:29:17 2023 +0100 + + [func.wrap.func.general, func.wrap.move.class] Remove redundant declaration (#6273) + + We don't need to repeat the declarations of the incomplete primary + template, they are already present in the synopsis. + + commit e6bd946d953b76e908a8e853d93834572c125d59 + Author: Richard Smith + Date: Fri Jul 14 13:31:47 2023 -0700 + + [basic.scope.scope] Avoid hard-to-read except...unless construction. + + Factor out a name for the "unless" condition to avoid the double-negative. + + commit 3769c701daf9ae38f8db054670106abca7c03d32 + Author: Roger Orr + Date: Tue Jul 18 23:54:34 2023 +0100 + + [dcl.ambig.res] fix double declaration of 'y' in example + + commit 0bf51a3bc5c24b070265412c32e53a0060d73eef + Author: Christian Trott + Date: Sat Jul 22 19:33:41 2023 -0600 + + [mdspan.layout.stride.cons] Fix missed rename of template parameter (#6385) + + "LayoutStrideMapping" should say "StridedLayoutMapping". + + commit f8feaa6e5bc8e6d28e00c06a3de305f80f395913 + Author: Eelis van der Weegen + Date: Fri Jul 21 11:43:39 2023 +0200 + + [version.syn] Fix header references. + + commit 872bda08678d1aeecfc555f26920cec28a2ad497 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Jun 1 14:59:00 2023 +0000 + + [basic.stc.dynamic.allocation] Remove redundant 'address of' from a note + + commit 880531fad125c4b806300151ddcb961a7f44a181 + Author: Arthur O'Dwyer + Date: Sat Jul 22 21:49:38 2023 -0400 + + [flat.{,multi}{map,set}.cons]: zip_view should be views::zip (#6373) + + We don't expect to use CTAD on `ranges::zip_view(args...)`; + what we expect is `views::zip`. + + commit a417ade53722d944481baac575292874c1bcc79a + Author: Johel Ernesto Guerrero Peña + Date: Sat Jul 22 21:50:37 2023 -0400 + + [range.enumerate.overview] Add cross reference to [range.adaptor.object] (#6219) + + commit 7f100cc67b0bb263e2f438238e87555347ae45c0 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Jul 23 17:50:27 2023 +0800 + + [input.output] Fix the "Effects: Equivalent to" format (#6402) + + commit 9334219bd95a85e86b20c8a712397f9f23f0f7a8 + Author: Jens Maurer + Date: Sun Jul 23 06:59:28 2023 +0200 + + [class.copy.assign] Remove note obsoleted by CWG2586 + + commit 503b4b261061bdd2481e1e4f1153481a0a75ecee + Author: Jens Maurer + Date: Sun Jul 23 08:29:10 2023 +0200 + + [dcl.fct.def.default] Highlight different references in defaulted assignments + + commit a567088b0ab8ca62f0ff5a7b4746337ac3f6df9b + Author: Thomas Köppe + Date: Mon Jul 24 12:45:57 2023 +0100 + + [assets] Move separate assets into "assets" subdirectory + + commit 7e2cc3ba6a30a693a96bbc37c4d8428d92ce1fa8 + Author: Thomas Köppe + Date: Fri Aug 19 17:03:37 2022 +0100 + + [assets] Unicode examples + + commit 589af92ce99b91444a3e6155cb64f8009918e885 + Author: Thomas Köppe + Date: Sun Aug 28 02:09:47 2022 +0100 + + [format.string.{std,escaped}, macros] Add missing examples + + commit f61a2c8a847e846ba1167c876b0fc1532ab433d7 + Author: Thomas Köppe + Date: Mon Jul 24 21:27:00 2023 +0100 + + [format.string.escape] Fix mis{sing,escaped} braces + + This was an oversight in the application of + https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2713r0.html + in e38ea31d46ca2964c4f9169f049e2f15e2cd5957. + + commit 3b2a8ee11725eb485df89dec40a7e0fc965debb2 + Author: Johel Ernesto Guerrero Peña + Date: Fri Jul 21 12:46:48 2023 -0400 + + [func.wrap.ref.class] change deduction guide to match its detailed specifications + + commit d5160c6ff6c09fc0c52b5b11676c03ff179f4554 + Author: Thomas Köppe + Date: Sun Jul 23 02:51:25 2023 +0100 + + [mdspan.submdspan.extents] Factor out common result expression + + commit 84cf8ef63a479a3fda05a219dd26ab4b8c6a8e32 + Author: Jakub Mazurkiewicz + Date: Tue Jul 25 01:06:49 2023 +0200 + + [mdspan.mdspan.cons] `OtherIndexType` is not a parameter pack; missing _v (#6263) + + commit a636f553369825bc37ac0d95c171a00c526af499 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Jul 24 16:16:14 2023 +0000 + + [intro.object] Fix cross-references for library implicit object creation + + commit d09a77e09a5210c50994b89d999f3cbdfcc9a436 + Author: Jonathan Wakely + Date: Wed May 17 18:51:00 2023 +0100 + + [re.results.general, string.cons] Fix references to container reqmts + + [re.results.general] should refer to [container.alloc.reqmts] for an + allocator-aware container, [strings.cons] should refer to sequence + container requirements. + + commit dd32b7eeb21e0ca8be7aae1996814a2ffda0ed83 + Author: Jonathan Wakely + Date: Thu May 18 12:54:12 2023 +0100 + + [container.gen.reqmts] Adjust subclause names and stable tags + + There are no more cross-references to [container.gen.reqmts] or + [container.requirements.general], so this doesn't affect anything else. + + commit a0e6740cda724c192ea14979e2fa92e9f38cf242 + Author: Janet Cobb + Date: Mon Jul 24 12:09:44 2023 -0400 + + [basic.fundamental] Clarify that table of minimum integral type widths applies only to standard integral types + + commit 3a2586ccb4112f32f08643f7fcafab0b6b7956e2 + Author: Joshua Berne + Date: Fri Jul 28 15:31:51 2023 -0400 + + [dcl.attr.grammar] Fix typo "appeartain" -> "appertain" (#6420) + + commit 00b4bb25e7b881cc53dca91dd44ef87c9696b19c + Author: Jan Schultke + Date: Sun Aug 13 22:35:57 2023 +0200 + + [over.ics.list] Fix missing std:: in example (#6453) + + commit cf7d5820d2ab8352d96462c647b735dc575cc1cb + Author: Alisdair Meredith + Date: Tue Aug 15 00:12:21 2023 +0200 + + [depr.static.constexpr] Cross-reference core clauses for deprecated feature (#6448) + + commit 1353359777de653346dd05ed117bba3627b6c7ca + Author: Jens Maurer + Date: Tue Jan 24 18:51:02 2023 +0100 + + [class.mem.general] Clarify class completeness + + commit 77d1b66193d5324b121979474d0e35645bbcfb1c + Author: A. Jiang + Date: Tue Aug 1 13:39:55 2023 +0800 + + [memory.syn] Remove redundant freestanding mark for members + + Making `allocator_arg_t` shown like `from_range_t` in [ranges.syn]. + + commit bf304328b603d96b9da5dc38dfeb04057c67cc53 + Author: A. Jiang + Date: Tue Aug 1 13:42:07 2023 +0800 + + [ranges.syn] Remove redundant freestanding mark for members + + commit d347b328e058bb4b357a2b7b4733c923fca6fd98 + Author: Jan Schultke + Date: Tue Aug 15 00:42:54 2023 +0200 + + [temp.over] itemize parts of long paragraph (#6443) + + commit e34a8e15e1de7eab0980af328765957c6118fc04 + Author: Jan Schultke + Date: Tue Aug 15 00:45:43 2023 +0200 + + [meta.unary.prop] itemize long sentence (#6436) diff --git a/papers/n4965.html b/papers/n4965.html new file mode 100644 index 0000000000..de693b4372 --- /dev/null +++ b/papers/n4965.html @@ -0,0 +1,658 @@ + + + + + +N4965 + + +

N4965 Editors’ Report — Programming Languages — C++

+ +

Date: 2023-10-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 + and to those who have provided pull requests with fixes.

+ +

New papers

+ +
    +
  • N4964 is the +current working draft for C++26. It replaces +N4958.
  • +
  • N4965 is this Editors' Report.
  • +
+ +

Comments on the Draft International Standard

+ +

This report includes a snapshot of our dispositions on the Draft International Standard (DIS) +ballot comments for C++23 from national bodies and the ISO secretariat. Some of them only apply +to the published standard document and not the working draft, and the corresponding edits do not +appear in the working draft commit history. All comments on the ballot were editorial.

+ +
    +
  • ISO/CS 01: Accepted. We added references to the tables.
  • +
  • ISO/CS 02: in progress
  • +
  • ISO/CS 03: Accepted. We are now referring to a specific element, and keeping the dated reference.
  • +
  • ISO/CS 04: Accepted.
  • +
  • ISO/CS 05: Rejected: We do not understand the justification "Since there is no specific element referenced this reference shall be undated." The Drafting Directives seem to make a clear case for when undated (10.4) and dated (10.5) references are appropriate, and we firmly fall into the case where an undated reference is inappropriate ("if it will be possible to use all future changes of the referenced document" is defintely not the case). Reference to a specific element does not seem to be required in order to permit the use of a dated reference. Even the House Style seems to permit dated references when necessary: "When referring to the whole document, use an undated document number unless it is necessary that the user refers to a specific edition".
  • +
  • ISO/CS 06: Rejected: Moot by comment 05.
  • +
  • ISO/CS 07: Rejected: Moot by comment 05.
  • +
  • ISO/CS 08: Accepted. We reworded the reference to the Unicode standard to make the normative nature more obvious.
  • +
  • ISO/CS 09: Accepted.
  • +
  • ISO/CS 10: Rejected: We find domains valuable here, since the terms often sound like plain English words, but have rather domain-specific meaning, and the domain establishes important context to aid understandability.
  • +
  • ISO/CS 11: Accepted with modifications: four unused definitions are removed. The remaining term, "unspecified behavior" is retained, since it captures a variety of patterns which are not lexically spelled "behavior" but are neatly covered by this umbrella term.
  • +
  • ISO/CS 12: Accepted with modifications: we have italicized the cross-references. However, for the formal grammar terms that we display in italic sans font, please see the discussion on comment 32.
  • +
  • ISO/CS 13: Rejected: The token "CE" is not an acronym, but a meta variable (like "x" or "y". It is typeset distinctly. The name is evocative of its use.
  • +
  • ISO/CS 14: Accepted.
  • +
  • ISO/CS 15: Accepted.
  • +
  • ISO/CS 16: Rejected: The wording is correct as written. However, this is also mooted by comment 11, which deletes the wording in question.
  • +
  • ISO/CS 17: Accepted.
  • +
  • ISO/CS 18: Accepted.
  • +
  • ISO/CS 19: Accepted.
  • +
  • CA 20: n/a, comment was filed erroneously
  • +
  • JP 21: Accepted. We added an example.
  • +
  • JP 22: Rejected: No consensus for change; any attributes of a lambda-declarator are considered to be attached to the synthesized function call operator or operator template (i.e. the member function of the closure type), not the closure type itself.
  • +
  • JP 23: Accepted with modifications: The example is written as intended. The comments in the example have been amended to clarify the exposition.
  • +
  • JP 24: Accepted.
  • +
  • JP 25: Accepted.
  • +
  • JP 26: Rejected: No concensus for change; the example deliberately introduces a facility to aid comprehension.
  • +
  • JP 27: Rejected: No concensus for change; the example deliberately introduces a facility to aid comprehension.
  • +
  • JP 28: Rejected: No concensus for change; the example deliberately introduces a facility to aid comprehension.
  • +
  • ISO/CS 29: Accepted.
  • +
  • ISO/CS 30: Accepted. We added a note that refers to the annex.
  • +
  • ISO/CS 31: Accepted. We had previously used foreword wording from an older document.
  • +
  • ISO/CS 32: Rejected (to be discussed), along with comment 12.
  • +
  • ISO/CS 33: Rejected: We have an approved SC22 ballot to permit the use of paragraph numbers. (We also have a proposal for the JDMT to add such a permission to the Drafting Directives.)
  • +
  • ISO/CS 34: Accepted. Reworded to clarify.
  • +
  • ISO/CS 35: Accepted.
  • +
  • ISO/CS 36: Accepted the notes and tables captioning changes. Rejected the UK English spelling: The document defines many terms that must be spelled the same way by conforming implementations and by users of those implementations, and these terms use US English spelling. It would be confusing for the document text to use UK English spelling when describing these terms. (This is the same disposition as for a similar comment on the DIS ballot of 14882:2017.)
  • +
  • ISO/CS 37: in progress
  • +
  • ISO/CS 38: Accepted with modifications: We will review the presentation of cross-references in Clause 3. However, the use of italics in Clause 3 is not a regular "emphasis/definition" in body font, but rather a grammar production, which we typeset distinctly. Please also see the discussion regarding comment 32.
  • +
  • ISO/CS 39: in progress
  • +
  • ISO/CS 40: Accepted. The logic that processed the notes was erroneous and failed to handle subclauses with more than 9 notes; this has been fixed.
  • +
+ +

Editorial changes

+ +

There have not been any motions from WG21 since the last working draft. This +revision incorporates all the changes resulting from the DIS ballot comments for +C++23, in as far as they apply to the current working draft, as well as other +editorial changes.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4958 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 a4b1ffd9e65188ae19c29dffd2db42cb1558cee2
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Tue Aug 15 01:18:00 2023 +0200
+
+    [except.terminate] add comma after introductory phrase (#6446)
+
+commit aa8a5315136feb1af9084a2a914ba19cd8758a74
+Author: Salvage <29021710+Saalvage@users.noreply.github.com>
+Date:   Sun May 28 18:59:26 2023 +0200
+
+    [flat.multiset.defn] Fix minor errors and inconsistencies
+
+    [flat.set.defn] and [flat.multiset.defn] are now formatted identically.
+    Additionally removed erroenous template parameters in two deduction guides.
+
+commit d3ac7d4c1c74df5d5b375f4c0260345be18b0b0b
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Wed Aug 16 16:21:40 2023 +0200
+
+    [conv.ptr, conv.mem] Remove redundant text on null pointer comparisons (#6411)
+
+commit b55ad4cb65b53bb6b6e60064938537f07d63bfb3
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Aug 17 00:32:21 2023 +0200
+
+    [algorithms.parallel.defns] New paragraph for example (#6447)
+
+    Making the example a sibling to the preceding paragraph
+    rather than part of it resets its list numbering, which is less
+    confusing than continuing numbering.
+
+commit be07cd4e87c693fb9749c1e5e7c07ee0cf9e0084
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Aug 2 01:28:29 2023 +0800
+
+    [diagnostics] Exposition-only formatting for members
+
+commit 7b7dedba78c8ae860db78feb3149acdf34ebb551
+Author: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+Date:   Thu Aug 17 21:04:37 2023 +0200
+
+    [time.general] Add a reference to time.hash in the summary
+
+    [time.general] has a library summary with references to the various
+    subclauses; [time.hash] was missing, add it.
+
+commit 1e9e54ef536870ea01e6b016e4219e57df0c099b
+Author: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+Date:   Thu Aug 17 21:07:27 2023 +0200
+
+    [time.hash] Fix a typo in the code for zoned_time
+
+    The `m` was supposed to be a `,` to separate the template arguments.
+
+commit a272b7cd04dc0be488250a0c6aaead160e778774
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Aug 18 12:11:24 2023 +0800
+
+    [iterator.concept.readable] Add missing \expos for indirectly-readable-impl
+
+    Also adjust horizontal whitespace in related comments.
+
+commit 846dc84ac222e5f4a26373899a2cbd683f83991c
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Aug 20 16:56:55 2023 +0200
+
+    [diff.cpp20.utilities] Hyphenate bit-fields (#6481)
+
+commit 433baff775b00c2b72d0d81d792c24617c2ace06
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Aug 20 20:56:34 2023 +0200
+
+    [tuple.swap] Improve 'call x with y' wording (#6478)
+
+commit 1c22d62180901069128b21daa2773d40566bd983
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Mon Aug 21 08:31:10 2023 +0200
+
+    [lex.phases] Add cross-reference to [cpp.include] (#6485)
+
+commit a54e71ed55a590214f2f33f4b1b900263a5f0b0d
+Author: Eelis van der Weegen <eelis@eelis.net>
+Date:   Fri Aug 25 18:05:32 2023 +0200
+
+    [rand.device] Remove stray \textit.
+
+    Fixes #6513.
+
+commit 9a0b5d767ed6ef038adc129856c0c0623f552abe
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Mon Aug 28 14:51:28 2023 +0200
+
+    [vector.data],[array.members] Clarify boolean condition (#6526)
+
+commit 8845a3778dbbd078c83a66ac09ae07e6357ec3e5
+Author: Eisenwave <me@eisenwave.net>
+Date:   Mon Aug 28 15:33:11 2023 +0200
+
+    [expr.call] add further forward references
+
+commit 837d6c979124200f1e06bc582079a60767c2756b
+Author: Daniel Krügler <daniel.kruegler@gmail.com>
+Date:   Sat Aug 26 18:35:55 2023 +0200
+
+    [atomics] Reword preconditions on memory_order values in a positive form
+
+commit 55b87300ce414fc5aa761838f217a957c797e9bf
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Aug 29 13:12:09 2023 +0100
+
+    [format.string.std] Fix example
+
+commit 61c089e934c1df406580eeb488dd5cee0900a7b1
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Jul 29 01:36:15 2023 +0800
+
+    [intro.object] Fix alignment in example
+
+    Makes the storage in the example properly aligned,
+    and explicitly states size assumption.
+
+commit 90d56dbe810e707d90322a3d16256e122e915eca
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Aug 19 15:51:27 2023 +0200
+
+    [expr.sizeof] turn identifier into a grammarterm
+
+commit f52ffc9054913f3f9a4c5dc6973f6c5c3e7f1096
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Aug 30 08:56:33 2023 +0200
+
+    [class.access.general] Fix improper \keyword{private} (#6532)
+
+commit d02a12a70c53974442f3e3ca4a75227783ea39d7
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Aug 30 19:54:36 2023 +0200
+
+    [lex.string] Mark "narrow string literal" as a definition (#6533)
+
+commit 31154dccdbe33aadb91d43cc03884f2d1aa5dbc0
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sat Sep 2 09:08:17 2023 +0200
+
+    [class.local] Add comma after introductory phrase (#6545)
+
+commit f9d08b09ffd8f68a32cbb480d54ab517e425d519
+Author: Joshua Berne <berne@notadragon.com>
+Date:   Sat Sep 2 12:56:57 2023 -0400
+
+    [diff.cpp20.thread] Add hyphen for "ill-formed" (#6550)
+
+commit 9130806ceb4a9476153eb7544b4509b713cce3e0
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Aug 30 14:01:06 2023 +0200
+
+    [fs.path.member] fix empty() == true
+
+commit ae4ae54b293c28d782902b955af8abae5229fc6d
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Aug 30 14:01:49 2023 +0200
+
+    [fs.path.modifiers] fix empty() == true
+
+commit ab4185710a64b303e6d302ac43c543849d79c5a8
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Aug 30 14:06:30 2023 +0200
+
+    [fs.filesystem.error.members] fix missing 'is true'
+
+commit 86b18720b37dadefe6c753ac2aec478b8f87593d
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Sep 5 16:19:25 2023 -0400
+
+    [basic.types.general] Apply Oxford comma consistently (#6554)
+
+commit 16c8ce5db2173a098a91e552dcfa3544c67e544f
+Author: Eelis <github.com@contacts.eelis.net>
+Date:   Fri Sep 8 08:05:36 2023 +0200
+
+    [mdspan.submdspan.extents] Format equations as math (#6530)
+
+commit 3bdb5e7b2b947ecd9fbb42029899ec098b51c51c
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Sep 13 00:24:17 2023 -0700
+
+    [mdspan.layout.stride.cons] Fix cross-reference (#6565)
+
+commit 536653b854e293af569156864ea6aa407c90e011
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Sep 11 10:36:39 2023 -0700
+
+    [mdspan.extents.cons] require conversions to index_type to be nonnegative
+
+    "nonnegative" is meaningless for a value of some arbitrary type which we've only required to be convertible to the integral type `index_type`, so this wording clearly intends to constrain the result of the conversion.
+
+commit 5c7841b1530dc02dbf7feacd5e154b777632dc36
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Sep 11 16:56:47 2023 -0700
+
+    [mdspan.layout.stride.cons] Convert to integral type before comparing to 0
+
+    `s[i]` is an lvalue of a type that we can only convert to `index_type`; clearly the wording intends that the result of the conversion should be `> 0`.
+
+commit 24659bd716808538fb7066103a396e785e4f0099
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Sep 11 16:59:56 2023 -0700
+
+    [mdspan.layout.stride.expo] Convert to integral type to perform math
+
+    [mdspan.layout.stride.cons] uses either a span or array of a type which we can only convert to `index_type` as the second argument to the exposition-only `REQUIRED-SPAN-SIZE`. We must perform that conversion before doing math with the result.
+
+commit 81c3897d34ccd32d4ccdbe3c74091ba1db458533
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Oct 4 00:22:33 2023 +0800
+
+    [const.iterators.ops] Add missing \pnum and replace returns with effects (#6581)
+
+commit 34cf81ebc821377eb3969002e4669bf5e08f479f
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Wed Oct 4 02:59:42 2023 +0800
+
+    [common.iter.const] Add missing period for Returns (#6584)
+
+commit 22537613dd844670ee9fb9d5afcf19f89c26fd26
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Sep 26 07:21:52 2023 +0200
+
+    [temp.over.link] Fix phrasing and cross-reference introduced by P1787R6
+
+commit 1398617dfd99dd3383e801abee6ce58629439f3a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Oct 4 17:48:32 2023 +0200
+
+    [tab:headers.cpp] Add <hazard_pointer> (#6586)
+
+commit 78635c91ac910e9c0953e1784eec648a214eb5ad
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Oct 4 14:44:18 2023 -0700
+
+    [string.cons] Remove erroneous paragraph break (#6587)
+
+commit a2e820424e089806191a40d43df2360906902d86
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Sep 19 13:36:52 2023 +0100
+
+    [range.utility.conv.to] Add terminating condition for first bullet
+
+    We currently fail to say what happens if the first bullet is true, but
+    then none of its sub-bullets is true.
+
+commit 9369ba13509cd5d2c9e862b7ad02f109c204a585
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Sep 19 16:19:50 2023 +0100
+
+    [version.syn] Put feature test macros in alphabetical order
+
+commit 1430209dbf6edda0827207166770c4d964cf0598
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 6 15:53:39 2023 +0200
+
+    [time.format] Make reference to ISO 8601 more precise
+
+    Fixes ISO/CS 003 (C++23 DIS).
+
+commit 7ed9cbfef44d15b798af83223f5d3b62927652a5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 6 15:14:44 2023 +0200
+
+    [intro.refs] Fix title of ISO/IEC 9899:2018
+
+    Fixes ISO/CS 004 (C++23 DIS).
+
+commit 258290ecc9d6e4d615b29173fd520df1f66a3292
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 6 01:21:01 2023 +0200
+
+    [annex] Fix table numbering in annexes
+
+    Fixes ISO/CS 029 (C++23 DIS).
+
+commit c39f5b014540820b4ea2061805a92c417e43ca0d
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 6 14:59:03 2023 +0200
+
+    [lex.name] Add cross-reference to Annex E
+
+    Fixes ISO/CS 030 (C++23 DIS).
+
+commit b5d6409bf5132d653bc13a3ce8f76c556d5d6fc9
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 7 22:50:53 2023 +0200
+
+    [defns.component] Remove unwarranted italics
+
+    Fixes ISO/CS 018 (C++23 DIS).
+
+commit 722bd4f167badc5bb5dddde9b0d00f91c2ef1644
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 6 13:24:16 2023 +0200
+
+    [util.smartptr.shared.cmp] Fix missing right parenthesis
+
+    Fixes NB JP 025 (C++23 DIS).
+
+commit 24b090f5c63bf99d4cdcea8989d885f2d23c00e7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Oct 6 13:20:03 2023 +0200
+
+    [unique.ptr.runtime.modifiers] Fix placement of 'constexpr'
+
+    Fixes NB JP 024 (C++23 DIS).
+
+commit 400521547f60196f6dfa7857bdcc907698991df8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 7 11:11:15 2023 +0200
+
+    [expr.const] Amend comments in example
+
+    Fixes NB JP 023 (C++23 DIS).
+
+commit 812e64a65699bb01203fbedcc7d9d5ea004a5007
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 7 22:32:16 2023 +0200
+
+    [expr.prim.lambda.general] Add example for parsing ambiguity
+
+    Fixes NB JP 021 (C++23 DIS).
+
+commit bd7f9a9e640bfcd204cabecf1cc4953b7138554e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Oct 7 10:38:29 2023 +0200
+
+    [intro.scope] Clarify 'they'
+
+    Fixes ISO/CS 034 (C++23 DIS).
+
+commit dc597fa561a795c100a36f46376d6ddd0cf93a31
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Oct 9 12:02:19 2023 -0400
+
+    [expr.prim.lambda.closure] Insert an extra \pnum (#6594)
+
+commit d81c17120e5a527f779b965ba8fd1ce66cfc24ef
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Oct 9 12:03:25 2023 -0400
+
+    [obj.lifetime] Dehyphenate trivially-copyable (#6592)
+
+commit d29b1fc1c22018b1a83cee910ebdbb4520d2c960
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 8 09:52:42 2023 +0200
+
+    [lex.charset] Add reference to the Unicode Standard
+
+commit e128de19470877fbf8f0335b8c0e2a1700f2e320
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 8 11:52:06 2023 +0200
+
+    [lex.charset] Clarify normative reference to Unicode for UTF-x
+
+    Fixes ISO/CS 008 (C++23 DIS).
+
+commit 4d603c640dd47c71f84bbce55416302efab8b298
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Oct 10 23:55:22 2023 +0100
+
+    [intro.defs] Remove inappropriate paragraph.
+
+    Only specific, fixed wording is allowed in Clause 3.
+
+    Fixes ISO/CS 009 (C++23 DIS).
+
+commit 7d4fa2432b58a2ef6a2062812ec00ccde4443acf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Oct 11 01:04:35 2023 +0200
+
+    [intro.defs] Remove unused definitions
+
+    The terms "arbitrary-positional stream", "repositional stream",
+    and "iostream class templates" are removed.
+
+    Fixes ISO/CS 011 and ISO/CS 16 (C++23 DIS).
+
+commit 4c76193e3d310ea5a18679ab86a54074fe1635e9
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 11 00:14:53 2023 +0100
+
+    [defns.impl.limits] Use singular
+
+    Fixes ISO/CS 015 (C++23 DIS).
+
+commit f672ecf38d2aec6ccf184d1a36bc4e83809afab0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 11 00:46:29 2023 +0100
+
+    [std] Replace "C Standard" with "ISO/IEC 9899:2018".
+
+    Fixes ISO/CS 035 (C++23 DIS).
+
+commit 2d6182932954732f71a28d90ec1f1b23838ccc67
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Oct 11 01:13:46 2023 +0100
+
+    [intro.{r,d}efs] Make "C standard library" a defined term
+
+    Partially fixes ISO/CS-002 (C++23 DIS).
+
+commit 4676f765f696774807688c3adfdc2eb03905a827
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Oct 8 12:30:18 2023 +0200
+
+    [type.traits] Add references to tables
+
+    Fixes ISO/CS 001 (C++23 DIS).
+
+commit 583391e28f34d6e0a17f67f77e04ba4f924c1d13
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Oct 14 20:42:50 2023 +0100
+
+    [intro.defs, dcl.init.list] Move definition of direct-non-list-init
+
+    Partially fixes ISO/CS-11 (C++23 DIS).
+
+commit 4a8e84ede8a927a7ebe7fa16a086041db437d57c
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sat Oct 14 20:58:52 2023 +0100
+
+    [xrefdelta] Remove mention of removals that are now already in C++23
+
+ + diff --git a/papers/n4965.md b/papers/n4965.md new file mode 100644 index 0000000000..fabff56da6 --- /dev/null +++ b/papers/n4965.md @@ -0,0 +1,515 @@ +# N4965 Editors' Report -- Programming Languages -- C++ + +Date: 2023-10-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) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4964](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4964.pdf) is the + current working draft for C++26. It replaces + [N4958](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4958.pdf). + * N4965 is this Editors' Report. + +## Comments on the Draft International Standard + +This report includes a snapshot of our dispositions on the Draft International Standard (DIS) +ballot comments for C++23 from national bodies and the ISO secretariat. Some of them only apply +to the published standard document and not the working draft, and the corresponding edits do not +appear in the working draft commit history. All comments on the ballot were editorial. + +* **ISO/CS 01:** Accepted. We added references to the tables. +* **ISO/CS 02:** _in progress_ +* **ISO/CS 03:** Accepted. We are now referring to a specific element, and keeping the dated reference. +* **ISO/CS 04:** Accepted. +* **ISO/CS 05:** Rejected: We do not understand the justification "Since there is no specific element referenced this reference shall be undated." The Drafting Directives seem to make a clear case for when undated (10.4) and dated (10.5) references are appropriate, and we firmly fall into the case where an undated reference is inappropriate ("if it will be possible to use all future changes of the referenced document" is defintely not the case). Reference to a specific element does not seem to be required in order to permit the use of a dated reference. Even the House Style seems to permit dated references when necessary: "When referring to the whole document, use an undated document number unless it is necessary that the user refers to a specific edition". +* **ISO/CS 06:** Rejected: Moot by comment 05. +* **ISO/CS 07:** Rejected: Moot by comment 05. +* **ISO/CS 08:** Accepted. We reworded the reference to the Unicode standard to make the normative nature more obvious. +* **ISO/CS 09:** Accepted. +* **ISO/CS 10:** Rejected: We find domains valuable here, since the terms often sound like plain English words, but have rather domain-specific meaning, and the domain establishes important context to aid understandability. +* **ISO/CS 11:** Accepted with modifications: four unused definitions are removed. The remaining term, "unspecified behavior" is retained, since it captures a variety of patterns which are not lexically spelled "behavior" but are neatly covered by this umbrella term. +* **ISO/CS 12:** Accepted with modifications: we have italicized the cross-references. However, for the formal grammar terms that we display in italic sans font, please see the discussion on comment 32. +* **ISO/CS 13:** Rejected: The token "CE" is not an acronym, but a meta variable (like "x" or "y". It is typeset distinctly. The name is evocative of its use. +* **ISO/CS 14:** Accepted. +* **ISO/CS 15:** Accepted. +* **ISO/CS 16:** Rejected: The wording is correct as written. However, this is also mooted by comment 11, which deletes the wording in question. +* **ISO/CS 17:** Accepted. +* **ISO/CS 18:** Accepted. +* **ISO/CS 19:** Accepted. +* **CA 20:** n/a, comment was filed erroneously +* **JP 21:** Accepted. We added an example. +* **JP 22:** Rejected: No consensus for change; any attributes of a lambda-declarator are considered to be attached to the synthesized function call operator or operator template (i.e. the member function of the closure type), not the closure type itself. +* **JP 23:** Accepted with modifications: The example is written as intended. The comments in the example have been amended to clarify the exposition. +* **JP 24:** Accepted. +* **JP 25:** Accepted. +* **JP 26:** Rejected: No concensus for change; the example deliberately introduces a facility to aid comprehension. +* **JP 27:** Rejected: No concensus for change; the example deliberately introduces a facility to aid comprehension. +* **JP 28:** Rejected: No concensus for change; the example deliberately introduces a facility to aid comprehension. +* **ISO/CS 29:** Accepted. +* **ISO/CS 30:** Accepted. We added a note that refers to the annex. +* **ISO/CS 31:** Accepted. We had previously used foreword wording from an older document. +* **ISO/CS 32:** Rejected (to be discussed), along with comment 12. +* **ISO/CS 33:** Rejected: We have an approved SC22 ballot to permit the use of paragraph numbers. (We also have a proposal for the JDMT to add such a permission to the Drafting Directives.) +* **ISO/CS 34:** Accepted. Reworded to clarify. +* **ISO/CS 35:** Accepted. +* **ISO/CS 36:** Accepted the notes and tables captioning changes. Rejected the UK English spelling: The document defines many terms that must be spelled the same way by conforming implementations and by users of those implementations, and these terms use US English spelling. It would be confusing for the document text to use UK English spelling when describing these terms. (This is the same disposition as for a similar comment on the DIS ballot of 14882:2017.) +* **ISO/CS 37:** _in progress_ +* **ISO/CS 38:** Accepted with modifications: We will review the presentation of cross-references in Clause 3. However, the use of italics in Clause 3 is not a regular "emphasis/definition" in body font, but rather a grammar production, which we typeset distinctly. Please also see the discussion regarding comment 32. +* **ISO/CS 39:** _in progress_ +* **ISO/CS 40:** Accepted. The logic that processed the notes was erroneous and failed to handle subclauses with more than 9 notes; this has been fixed. + +## Editorial changes + +There have not been any motions from WG21 since the last working draft. This +revision incorporates all the changes resulting from the DIS ballot comments for +C++23, in as far as they apply to the current working draft, as well as other +editorial changes. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4958 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/n4958...n4964). + + commit a4b1ffd9e65188ae19c29dffd2db42cb1558cee2 + Author: Jan Schultke + Date: Tue Aug 15 01:18:00 2023 +0200 + + [except.terminate] add comma after introductory phrase (#6446) + + commit aa8a5315136feb1af9084a2a914ba19cd8758a74 + Author: Salvage <29021710+Saalvage@users.noreply.github.com> + Date: Sun May 28 18:59:26 2023 +0200 + + [flat.multiset.defn] Fix minor errors and inconsistencies + + [flat.set.defn] and [flat.multiset.defn] are now formatted identically. + Additionally removed erroenous template parameters in two deduction guides. + + commit d3ac7d4c1c74df5d5b375f4c0260345be18b0b0b + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Wed Aug 16 16:21:40 2023 +0200 + + [conv.ptr, conv.mem] Remove redundant text on null pointer comparisons (#6411) + + commit b55ad4cb65b53bb6b6e60064938537f07d63bfb3 + Author: Alisdair Meredith + Date: Thu Aug 17 00:32:21 2023 +0200 + + [algorithms.parallel.defns] New paragraph for example (#6447) + + Making the example a sibling to the preceding paragraph + rather than part of it resets its list numbering, which is less + confusing than continuing numbering. + + commit be07cd4e87c693fb9749c1e5e7c07ee0cf9e0084 + Author: A. Jiang + Date: Wed Aug 2 01:28:29 2023 +0800 + + [diagnostics] Exposition-only formatting for members + + commit 7b7dedba78c8ae860db78feb3149acdf34ebb551 + Author: Giuseppe D'Angelo + Date: Thu Aug 17 21:04:37 2023 +0200 + + [time.general] Add a reference to time.hash in the summary + + [time.general] has a library summary with references to the various + subclauses; [time.hash] was missing, add it. + + commit 1e9e54ef536870ea01e6b016e4219e57df0c099b + Author: Giuseppe D'Angelo + Date: Thu Aug 17 21:07:27 2023 +0200 + + [time.hash] Fix a typo in the code for zoned_time + + The `m` was supposed to be a `,` to separate the template arguments. + + commit a272b7cd04dc0be488250a0c6aaead160e778774 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Aug 18 12:11:24 2023 +0800 + + [iterator.concept.readable] Add missing \expos for indirectly-readable-impl + + Also adjust horizontal whitespace in related comments. + + commit 846dc84ac222e5f4a26373899a2cbd683f83991c + Author: Jan Schultke + Date: Sun Aug 20 16:56:55 2023 +0200 + + [diff.cpp20.utilities] Hyphenate bit-fields (#6481) + + commit 433baff775b00c2b72d0d81d792c24617c2ace06 + Author: Jan Schultke + Date: Sun Aug 20 20:56:34 2023 +0200 + + [tuple.swap] Improve 'call x with y' wording (#6478) + + commit 1c22d62180901069128b21daa2773d40566bd983 + Author: Jan Schultke + Date: Mon Aug 21 08:31:10 2023 +0200 + + [lex.phases] Add cross-reference to [cpp.include] (#6485) + + commit a54e71ed55a590214f2f33f4b1b900263a5f0b0d + Author: Eelis van der Weegen + Date: Fri Aug 25 18:05:32 2023 +0200 + + [rand.device] Remove stray \textit. + + Fixes #6513. + + commit 9a0b5d767ed6ef038adc129856c0c0623f552abe + Author: Jan Schultke + Date: Mon Aug 28 14:51:28 2023 +0200 + + [vector.data],[array.members] Clarify boolean condition (#6526) + + commit 8845a3778dbbd078c83a66ac09ae07e6357ec3e5 + Author: Eisenwave + Date: Mon Aug 28 15:33:11 2023 +0200 + + [expr.call] add further forward references + + commit 837d6c979124200f1e06bc582079a60767c2756b + Author: Daniel Krügler + Date: Sat Aug 26 18:35:55 2023 +0200 + + [atomics] Reword preconditions on memory_order values in a positive form + + commit 55b87300ce414fc5aa761838f217a957c797e9bf + Author: Thomas Köppe + Date: Tue Aug 29 13:12:09 2023 +0100 + + [format.string.std] Fix example + + commit 61c089e934c1df406580eeb488dd5cee0900a7b1 + Author: A. Jiang + Date: Sat Jul 29 01:36:15 2023 +0800 + + [intro.object] Fix alignment in example + + Makes the storage in the example properly aligned, + and explicitly states size assumption. + + commit 90d56dbe810e707d90322a3d16256e122e915eca + Author: Eisenwave + Date: Sat Aug 19 15:51:27 2023 +0200 + + [expr.sizeof] turn identifier into a grammarterm + + commit f52ffc9054913f3f9a4c5dc6973f6c5c3e7f1096 + Author: Jan Schultke + Date: Wed Aug 30 08:56:33 2023 +0200 + + [class.access.general] Fix improper \keyword{private} (#6532) + + commit d02a12a70c53974442f3e3ca4a75227783ea39d7 + Author: Jan Schultke + Date: Wed Aug 30 19:54:36 2023 +0200 + + [lex.string] Mark "narrow string literal" as a definition (#6533) + + commit 31154dccdbe33aadb91d43cc03884f2d1aa5dbc0 + Author: Jan Schultke + Date: Sat Sep 2 09:08:17 2023 +0200 + + [class.local] Add comma after introductory phrase (#6545) + + commit f9d08b09ffd8f68a32cbb480d54ab517e425d519 + Author: Joshua Berne + Date: Sat Sep 2 12:56:57 2023 -0400 + + [diff.cpp20.thread] Add hyphen for "ill-formed" (#6550) + + commit 9130806ceb4a9476153eb7544b4509b713cce3e0 + Author: Eisenwave + Date: Wed Aug 30 14:01:06 2023 +0200 + + [fs.path.member] fix empty() == true + + commit ae4ae54b293c28d782902b955af8abae5229fc6d + Author: Eisenwave + Date: Wed Aug 30 14:01:49 2023 +0200 + + [fs.path.modifiers] fix empty() == true + + commit ab4185710a64b303e6d302ac43c543849d79c5a8 + Author: Eisenwave + Date: Wed Aug 30 14:06:30 2023 +0200 + + [fs.filesystem.error.members] fix missing 'is true' + + commit 86b18720b37dadefe6c753ac2aec478b8f87593d + Author: Alisdair Meredith + Date: Tue Sep 5 16:19:25 2023 -0400 + + [basic.types.general] Apply Oxford comma consistently (#6554) + + commit 16c8ce5db2173a098a91e552dcfa3544c67e544f + Author: Eelis + Date: Fri Sep 8 08:05:36 2023 +0200 + + [mdspan.submdspan.extents] Format equations as math (#6530) + + commit 3bdb5e7b2b947ecd9fbb42029899ec098b51c51c + Author: Casey Carter + Date: Wed Sep 13 00:24:17 2023 -0700 + + [mdspan.layout.stride.cons] Fix cross-reference (#6565) + + commit 536653b854e293af569156864ea6aa407c90e011 + Author: Casey Carter + Date: Mon Sep 11 10:36:39 2023 -0700 + + [mdspan.extents.cons] require conversions to index_type to be nonnegative + + "nonnegative" is meaningless for a value of some arbitrary type which we've only required to be convertible to the integral type `index_type`, so this wording clearly intends to constrain the result of the conversion. + + commit 5c7841b1530dc02dbf7feacd5e154b777632dc36 + Author: Casey Carter + Date: Mon Sep 11 16:56:47 2023 -0700 + + [mdspan.layout.stride.cons] Convert to integral type before comparing to 0 + + `s[i]` is an lvalue of a type that we can only convert to `index_type`; clearly the wording intends that the result of the conversion should be `> 0`. + + commit 24659bd716808538fb7066103a396e785e4f0099 + Author: Casey Carter + Date: Mon Sep 11 16:59:56 2023 -0700 + + [mdspan.layout.stride.expo] Convert to integral type to perform math + + [mdspan.layout.stride.cons] uses either a span or array of a type which we can only convert to `index_type` as the second argument to the exposition-only `REQUIRED-SPAN-SIZE`. We must perform that conversion before doing math with the result. + + commit 81c3897d34ccd32d4ccdbe3c74091ba1db458533 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Oct 4 00:22:33 2023 +0800 + + [const.iterators.ops] Add missing \pnum and replace returns with effects (#6581) + + commit 34cf81ebc821377eb3969002e4669bf5e08f479f + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Wed Oct 4 02:59:42 2023 +0800 + + [common.iter.const] Add missing period for Returns (#6584) + + commit 22537613dd844670ee9fb9d5afcf19f89c26fd26 + Author: Jens Maurer + Date: Tue Sep 26 07:21:52 2023 +0200 + + [temp.over.link] Fix phrasing and cross-reference introduced by P1787R6 + + commit 1398617dfd99dd3383e801abee6ce58629439f3a + Author: Jens Maurer + Date: Wed Oct 4 17:48:32 2023 +0200 + + [tab:headers.cpp] Add (#6586) + + commit 78635c91ac910e9c0953e1784eec648a214eb5ad + Author: Casey Carter + Date: Wed Oct 4 14:44:18 2023 -0700 + + [string.cons] Remove erroneous paragraph break (#6587) + + commit a2e820424e089806191a40d43df2360906902d86 + Author: Jonathan Wakely + Date: Tue Sep 19 13:36:52 2023 +0100 + + [range.utility.conv.to] Add terminating condition for first bullet + + We currently fail to say what happens if the first bullet is true, but + then none of its sub-bullets is true. + + commit 9369ba13509cd5d2c9e862b7ad02f109c204a585 + Author: Jonathan Wakely + Date: Tue Sep 19 16:19:50 2023 +0100 + + [version.syn] Put feature test macros in alphabetical order + + commit 1430209dbf6edda0827207166770c4d964cf0598 + Author: Jens Maurer + Date: Fri Oct 6 15:53:39 2023 +0200 + + [time.format] Make reference to ISO 8601 more precise + + Fixes ISO/CS 003 (C++23 DIS). + + commit 7ed9cbfef44d15b798af83223f5d3b62927652a5 + Author: Jens Maurer + Date: Fri Oct 6 15:14:44 2023 +0200 + + [intro.refs] Fix title of ISO/IEC 9899:2018 + + Fixes ISO/CS 004 (C++23 DIS). + + commit 258290ecc9d6e4d615b29173fd520df1f66a3292 + Author: Jens Maurer + Date: Fri Oct 6 01:21:01 2023 +0200 + + [annex] Fix table numbering in annexes + + Fixes ISO/CS 029 (C++23 DIS). + + commit c39f5b014540820b4ea2061805a92c417e43ca0d + Author: Jens Maurer + Date: Fri Oct 6 14:59:03 2023 +0200 + + [lex.name] Add cross-reference to Annex E + + Fixes ISO/CS 030 (C++23 DIS). + + commit b5d6409bf5132d653bc13a3ce8f76c556d5d6fc9 + Author: Jens Maurer + Date: Sat Oct 7 22:50:53 2023 +0200 + + [defns.component] Remove unwarranted italics + + Fixes ISO/CS 018 (C++23 DIS). + + commit 722bd4f167badc5bb5dddde9b0d00f91c2ef1644 + Author: Jens Maurer + Date: Fri Oct 6 13:24:16 2023 +0200 + + [util.smartptr.shared.cmp] Fix missing right parenthesis + + Fixes NB JP 025 (C++23 DIS). + + commit 24b090f5c63bf99d4cdcea8989d885f2d23c00e7 + Author: Jens Maurer + Date: Fri Oct 6 13:20:03 2023 +0200 + + [unique.ptr.runtime.modifiers] Fix placement of 'constexpr' + + Fixes NB JP 024 (C++23 DIS). + + commit 400521547f60196f6dfa7857bdcc907698991df8 + Author: Jens Maurer + Date: Sat Oct 7 11:11:15 2023 +0200 + + [expr.const] Amend comments in example + + Fixes NB JP 023 (C++23 DIS). + + commit 812e64a65699bb01203fbedcc7d9d5ea004a5007 + Author: Jens Maurer + Date: Sat Oct 7 22:32:16 2023 +0200 + + [expr.prim.lambda.general] Add example for parsing ambiguity + + Fixes NB JP 021 (C++23 DIS). + + commit bd7f9a9e640bfcd204cabecf1cc4953b7138554e + Author: Jens Maurer + Date: Sat Oct 7 10:38:29 2023 +0200 + + [intro.scope] Clarify 'they' + + Fixes ISO/CS 034 (C++23 DIS). + + commit dc597fa561a795c100a36f46376d6ddd0cf93a31 + Author: Alisdair Meredith + Date: Mon Oct 9 12:02:19 2023 -0400 + + [expr.prim.lambda.closure] Insert an extra \pnum (#6594) + + commit d81c17120e5a527f779b965ba8fd1ce66cfc24ef + Author: Alisdair Meredith + Date: Mon Oct 9 12:03:25 2023 -0400 + + [obj.lifetime] Dehyphenate trivially-copyable (#6592) + + commit d29b1fc1c22018b1a83cee910ebdbb4520d2c960 + Author: Jens Maurer + Date: Sun Oct 8 09:52:42 2023 +0200 + + [lex.charset] Add reference to the Unicode Standard + + commit e128de19470877fbf8f0335b8c0e2a1700f2e320 + Author: Jens Maurer + Date: Sun Oct 8 11:52:06 2023 +0200 + + [lex.charset] Clarify normative reference to Unicode for UTF-x + + Fixes ISO/CS 008 (C++23 DIS). + + commit 4d603c640dd47c71f84bbce55416302efab8b298 + Author: Thomas Köppe + Date: Tue Oct 10 23:55:22 2023 +0100 + + [intro.defs] Remove inappropriate paragraph. + + Only specific, fixed wording is allowed in Clause 3. + + Fixes ISO/CS 009 (C++23 DIS). + + commit 7d4fa2432b58a2ef6a2062812ec00ccde4443acf + Author: Jens Maurer + Date: Wed Oct 11 01:04:35 2023 +0200 + + [intro.defs] Remove unused definitions + + The terms "arbitrary-positional stream", "repositional stream", + and "iostream class templates" are removed. + + Fixes ISO/CS 011 and ISO/CS 16 (C++23 DIS). + + commit 4c76193e3d310ea5a18679ab86a54074fe1635e9 + Author: Thomas Köppe + Date: Wed Oct 11 00:14:53 2023 +0100 + + [defns.impl.limits] Use singular + + Fixes ISO/CS 015 (C++23 DIS). + + commit f672ecf38d2aec6ccf184d1a36bc4e83809afab0 + Author: Thomas Köppe + Date: Wed Oct 11 00:46:29 2023 +0100 + + [std] Replace "C Standard" with "ISO/IEC 9899:2018". + + Fixes ISO/CS 035 (C++23 DIS). + + commit 2d6182932954732f71a28d90ec1f1b23838ccc67 + Author: Thomas Köppe + Date: Wed Oct 11 01:13:46 2023 +0100 + + [intro.{r,d}efs] Make "C standard library" a defined term + + Partially fixes ISO/CS-002 (C++23 DIS). + + commit 4676f765f696774807688c3adfdc2eb03905a827 + Author: Jens Maurer + Date: Sun Oct 8 12:30:18 2023 +0200 + + [type.traits] Add references to tables + + Fixes ISO/CS 001 (C++23 DIS). + + commit 583391e28f34d6e0a17f67f77e04ba4f924c1d13 + Author: Thomas Köppe + Date: Sat Oct 14 20:42:50 2023 +0100 + + [intro.defs, dcl.init.list] Move definition of direct-non-list-init + + Partially fixes ISO/CS-11 (C++23 DIS). + + commit 4a8e84ede8a927a7ebe7fa16a086041db437d57c + Author: Thomas Köppe + Date: Sat Oct 14 20:58:52 2023 +0100 + + [xrefdelta] Remove mention of removals that are now already in C++23 diff --git a/papers/n4972.html b/papers/n4972.html new file mode 100644 index 0000000000..61df993043 --- /dev/null +++ b/papers/n4972.html @@ -0,0 +1,846 @@ + + + + + +N4972 + + +

N4972 Editors’ Report:
Programming Languages — C++

+ +

Date: 2023-12-18

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

Thanks to all those who have submitted editorial +issues +and to those who have provided pull requests with fixes, +and special thanks to Johel Ernesto Guerrero Peña for providing in-depth review +of many of the draft motion applications.

+ +

New papers

+ +
    +
  • N4971 is the +current working draft for C++26. It replaces +N4964.
  • +
  • N4972 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Notes on motions

+ +

All motions were applied cleanly, and the following additional changes applied +for the sake of integration:

+ +
    +
  • LWG Polls 1 and 3 both modified [optional.monadic]: +LWG-3973 +changed **this to *val, and +P2407R5 +changed value() to **this. This has been reconciled by changing the +latter to *val, too.
  • +
  • LWG Poll 2 created a freestanding facility (saturation arithmetic) but did +not define a freestanding feature test macro. We added the macro +__cpp_lib_freestanding_numeric, also defined in the <numeric> header.
  • +
+ +

The feature test macro __cpp_lib_span has been modified both LWG Poll 3 and +LWG Poll 10, and is now set to a common, updated value (202311L).

+ +

The linear algebra paper P1673R13 moved by LWG Poll 19 adds a substantial amount +of material, and numerous minor issues were discovered during application, many +of which have been fixed immediately, and some will be addressed in future +editorial work. One particular issue, which is not new and also affects the +random number and special maths functions, is how to relate variables in code +and mathematical variables in a mathematical expression.

+ +

Core working group polls

+ +

CWG Poll 1: Accept as a Defect Report and apply the proposed resolution of all issues in +P3046R0 +(Core Language Working Group "ready" Issues for the November, 2023 meeting) to the C++ Working Paper.

+ +

CWG Poll 2: Accept as a Defect Report and apply the changes in +P2308R1 +(Template parameter initialization) to the C++ Working Paper.

+ +

CWG Poll 3: Apply the changes in +P2662R3 +(Pack Indexing) to the C++ Working Paper.

+ +

CWG Poll 4: Apply the changes in +P2864R2 +(Remove Deprecated Arithmetic Conversion on Enumerations From C++26) to the C++ Working Paper.

+ +

CWG Poll 5 was withdrawn.

+ +

Library working group polls

+ +

LWG Poll 1: Apply the changes for all Ready and Tentatively Ready issues in +P3040R0 +(C++ Standard Library Issues to be moved in Kona, Nov. 2023) to the C++ working paper.

+ +

LWG Poll 2: Apply the changes in +P0543R3 +(Saturation arithmetic) to the C++ working paper.

+ +

LWG Poll 3: Apply the changes in +P2407R5 +(Freestanding Library: Partial Classes) to the C++ working paper.

+ +

LWG Poll 4: Apply the changes in +P2546R5 +(Debugging Support) to the C++ working paper.

+ +

LWG Poll 5: Accept as a Defect Report and apply the changes in +P2905R2 +(Runtime format strings) to the C++ working paper.

+ +

LWG Poll 6: Apply the changes in +P2918R2 +(Runtime format strings II) to the C++ working paper.

+ +

LWG Poll 7: Accept as a Defect Report and apply the changes in +P2909R4 +(Fix formatting of code units as integers (Dude, where's my char?)) to the C++ working paper.

+ +

LWG Poll 8: Apply the changes in +P0952R2 +(A new specification for std::generate_canonical) to the C++ working paper.

+ +

LWG Poll 9: Apply the changes in +P2447R6 +(std::span over an initializer list) to the C++ working paper.

+ +

LWG Poll 10: Apply the changes in +P2821R5 +(span.at()) to the C++ working paper.

+ +

LWG Poll 11: Apply the changes in +P2868R3 +(Remove Deprecated std::allocator Typedef From C++26) to the C++ working paper.

+ +

LWG Poll 12: Apply the changes in +P2870R3 +(Remove basic_string::reserve() From C++26) to the C++ working paper.

+ +

LWG Poll 13: Apply the changes in +P2871R3 +(Remove Deprecated Unicode Conversion Facets from C++26) to the C++ working paper.

+ +

LWG Poll 14: Apply the changes in +P2819R2 +(Add tuple protocol to complex) to the C++ working paper.

+ +

LWG Poll 15: Apply the changes in +P2937R0 +(Freestanding: Remove strtok) to the C++ working paper.

+ +

LWG Poll 16: Apply the changes in +P2833R2 +(Freestanding Library: inout expected span) to the C++ working paper.

+ +

LWG Poll 17: Accept as a Defect Report and apply the changes in +P2836R1 +(std::basic_const_iterator should follow its underlying type's convertibility) to the C++ working paper.

+ +

LWG Poll 18: Apply the changes in +P2264R7 +(Make assert() macro user friendly for C and C++) to the C++ working paper.

+ +

LWG Poll 19: Apply the changes in +P1673R13 +(A free function linear algebra interface based on the BLAS) to the C++ working paper.

+ +

Comments on the Draft International Standard

+ +

This report includes our final dispositions on the Draft International Standard (DIS) +ballot comments for C++23 from national bodies and the ISO secretariat. Some of them only apply +to the published standard document and not the working draft, and the corresponding edits do not +appear in the working draft commit history. All comments on the ballot were editorial.

+ +
    +
  • ISO/CS 01: Accepted. We added references to the tables.
  • +
  • ISO/CS 02: Accepted. We moved the explanations close to their point of use.
  • +
  • ISO/CS 03: Accepted. We are now referring to a specific element, and keeping the dated reference.
  • +
  • ISO/CS 04: Accepted.
  • +
  • ISO/CS 05: Rejected: We do not understand the justification "Since there is no specific element referenced this reference shall be undated." The Drafting Directives seem to make a clear case for when undated (10.4) and dated (10.5) references are appropriate, and we firmly fall into the case where an undated reference is inappropriate ("if it will be possible to use all future changes of the referenced document" is definitely not the case). Reference to a specific element does not seem to be required in order to permit the use of a dated reference. Even the House Style seems to permit dated references when necessary: "When referring to the whole document, use an undated document number unless it is necessary that the user refers to a specific edition".
  • +
  • ISO/CS 06: Rejected: Moot by comment 05.
  • +
  • ISO/CS 07: Rejected: Moot by comment 05.
  • +
  • ISO/CS 08: Accepted. We reworded the reference to the Unicode standard to make the normative nature more obvious.
  • +
  • ISO/CS 09: Accepted.
  • +
  • ISO/CS 10: Rejected: We find domains valuable here, since the terms often sound like plain English words, but have rather domain-specific meaning, and the domain establishes important context to aid understandability.
  • +
  • ISO/CS 11: Accepted with modifications: four unused definitions are removed. The remaining term, "unspecified behavior" is retained, since it captures a variety of patterns which are not lexically spelled "behavior" but are neatly covered by this umbrella term.
  • +
  • ISO/CS 12: Accepted with modifications: we have italicized the cross-references. However, for the formal grammar terms that we display in italic sans font, please see the discussion on comment 32.
  • +
  • ISO/CS 13: Rejected: The token "CE" is not an acronym, but a meta variable (like "x" or "y". It is typeset distinctly. The name is evocative of its use.
  • +
  • ISO/CS 14: Accepted.
  • +
  • ISO/CS 15: Accepted.
  • +
  • ISO/CS 16: Rejected: The wording is correct as written. However, this is also mooted by comment 11, which deletes the wording in question.
  • +
  • ISO/CS 17: Accepted.
  • +
  • ISO/CS 18: Accepted.
  • +
  • ISO/CS 19: Accepted.
  • +
  • CA 20: n/a, comment was filed erroneously
  • +
  • JP 21: Accepted. We added an example.
  • +
  • JP 22: Rejected: No consensus for change; any attributes of a lambda-declarator are considered to be attached to the synthesized function call operator or operator template (i.e. the member function of the closure type), not the closure type itself.
  • +
  • JP 23: Accepted with modifications: The example is written as intended. The comments in the example have been amended to clarify the exposition.
  • +
  • JP 24: Accepted.
  • +
  • JP 25: Accepted.
  • +
  • JP 26: Rejected: No consensus for change; the example deliberately introduces a facility to aid comprehension.
  • +
  • JP 27: Rejected: No consensus for change; the example deliberately introduces a facility to aid comprehension.
  • +
  • JP 28: Rejected: No consensus for change; the example deliberately introduces a facility to aid comprehension.
  • +
  • ISO/CS 29: Accepted.
  • +
  • ISO/CS 30: Accepted. We added a note that refers to the annex.
  • +
  • ISO/CS 31: Accepted. We had previously used foreword wording from an older document.
  • +
  • ISO/CS 32: Rejected, along with comment 12: our document has complex typographic requirements, and we have carefully selected a harmonizing family of typefaces in our document processing system that meets our needs. For example, certain parts of a formal grammar (some of which appear in Clause 3; see comment 12) require typographic distinction to avoid ambiguity. We have discussed this with the ISO secretariat.
  • +
  • ISO/CS 33: Rejected: We have an approved SC22 ballot to permit the use of paragraph numbers. (We also have a proposal for the JDMT to add such a permission to the Drafting Directives.)
  • +
  • ISO/CS 34: Accepted. Reworded to clarify.
  • +
  • ISO/CS 35: Accepted.
  • +
  • ISO/CS 36: Accepted the notes and tables captioning changes. Rejected the UK English spelling: The document defines many terms that must be spelled the same way by conforming implementations and by users of those implementations, and these terms use US English spelling. It would be confusing for the document text to use UK English spelling when describing these terms. (This is the same disposition as for a similar comment on the DIS ballot of 14882:2017.)
  • +
  • ISO/CS 37: Rejected, please see comment 39.
  • +
  • ISO/CS 38: Accepted with modifications: We will review the presentation of cross-references in Clause 3. However, the use of italics in Clause 3 is not a regular "emphasis/definition" in body font, but rather a grammar production, which we typeset distinctly. Please also see the discussion regarding comment 32.
  • +
  • ISO/CS 39: Rejected: For this comment and for comment 37, we have carefully reviewed the permitted verbal constructions. We believe that the notes are the best place for this explanatory, optional information, and the wording as-is accurately describes the consequences of normative requirements for illustrative purposes. We would like to not move this explanatory material into the main text, since that text already contains a complex range of requirements on the C++ language, its implementations, and its users, and our community has been finding our established boundary for what is explanatory note material helpful.
  • +
  • ISO/CS 40: Accepted. The logic that processed the notes was erroneous and failed to handle subclauses with more than 9 notes; this has been fixed.
  • +
+ +

Editorial changes

+ +

Major editorial changes

+ +

A number of editorial changes were made in response to requests from the ISO +secretariat during the publication of C++23. We list just a few noteworthy ones.

+ +
    +
  • There is now a new "Introduction" subclause, which explains our use of +stable labels and some typographic choices. In the future, we would like to +expand the introduction to explain more comprehensively how the Standard is +structured, phrased, and intended to be read.
  • +
  • Table captions are now formatted in bold, and the table number is separated +from the caption by a dash.
  • +
  • Inadmissible text has been removed from Clauses 2 (Normative references) and +3 (Terms and definitions), as those clauses must only contain specific, +fixed wording. The removed text has been moved nearer to the places in the +main text where it is needed.
  • +
  • Definitions in Clause 3 (Terms and definitions) now contain cross references +to one another as appropriate.
  • +
+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4964 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 a27ede64fef7fda551d480e5a1cf1b9a73832574
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Tue Oct 24 20:55:27 2023 +0800
+
+    [span.cons] Add `std::` for `data(arr)` (#6632)
+
+commit 84c526ebbda74553bf935f35f5594b8d5591bce5
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Oct 30 14:22:57 2023 -0700
+
+    [format.formatter.spec] Add missing include to example (#6636)
+
+    The example code refers to `std::string` directly so it should `#include<string>`.
+
+commit 4a6f2e3f4791c44b8c8f32a75d0bebac4a7b6a9e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Nov 2 00:53:04 2023 +0100
+
+    [intro.refs] Move nicknames for standards to relevant subclauses
+
+commit dc6eed02986d9c3c6827c710adb577ba0809f939
+Author: Krystian Stasiowski <sdkrystian@gmail.com>
+Date:   Tue Nov 7 04:32:19 2023 -0500
+
+    [dcl.dcl, over.best.ics, temp.param, class.union.anon] Remove mentions of "storage class" (#3906)
+
+commit 17c09925b2423c596196d3f88a61ff7b4052ef7a
+Author: Krystian Stasiowski <sdkrystian@gmail.com>
+Date:   Tue Nov 7 01:16:28 2023 -0500
+
+    [class.conv.fct] Fix reference to 'ref-qualifier-seq'
+
+commit 90720a35b0c3d65488d9dc9ecea682c271f43d52
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Oct 30 09:34:01 2023 +0800
+
+    [queue.syn] Show `formatter` specializations in the synopsis
+
+commit e43aa89a4882f8080fb10c843cdb25c9740b65c7
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Oct 30 09:36:24 2023 +0800
+
+    [stack.syn] Show the `formatter` specialization in the synopsis
+
+commit 80a8748fd401cfceee804bc96d2bfc518726d2e7
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Thu Oct 12 18:24:21 2023 -0400
+
+    [class.copy.assign] Remove a superfluous note.
+
+    Alternatively we could have added the word "non-object"; or changed
+    it to say "An overloaded assignment operator must be a member function";
+    but it doesn't seem like it needs to be here at all.
+
+commit c9c69dc54052badeb9b80458027371438d886763
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Thu Oct 12 18:58:39 2023 -0400
+
+    [class.copy.assign] Add some missing "non-object"s
+
+commit 2b5fc2936f12f73e975dbb9f34d3790fe0aa708f
+Author: Matt Bentley <mattreecebentley@gmail.com>
+Date:   Wed Nov 8 14:56:22 2023 +1300
+
+    [sequence.reqmts] Remove misleading, oversimplified informative text
+
+commit 11334c71244a046f0c29b01dfd79b35f6fea8cc4
+Author: Eisenwave <me@eisenwave.net>
+Date:   Fri Sep 1 09:29:01 2023 +0200
+
+    [class.copy.elision] improve reference and replace informal term
+
+commit 4feefb62e0419bb52c678389163729959785d44a
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Nov 8 02:59:01 2023 +0100
+
+    [mem.res.pool.options] Change "field" to "member" (#6479)
+
+commit a700e3b87b00d2673b3cded0a61201d09dfc051a
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Wed Nov 8 10:01:46 2023 +0800
+
+     [version.syn] Bump value of __cpp_lib_constexpr_complex (#6421)
+
+    P1383R2 "More constexpr for <cmath> and <complex>" modifies two headers;
+    both __cpp_lib_constexpr_cmath and __cpp_lib_constexpr_complex should be updated.
+
+    This aligns with existing practice in SD6.
+
+commit e9fb04e1c1e67bfb07bf3c61145b9d63a0f0adcf
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Tue Sep 27 15:36:08 2022 -0400
+
+    [dcl.enum] Enumerators don't have "initializers"
+
+commit bc3cb41a36dfff0d2358f4e294be9636590e680e
+Author: Krystian Stasiowski <sdkrystian@gmail.com>
+Date:   Tue Nov 7 21:08:15 2023 -0500
+
+    [dcl.name] Turn informative wording into note (#3964)
+
+commit 82b2ba6f6245e717cb002a9a836117a918aab36a
+Author: Patrick Johnston <gcupcakekid@gmail.com>
+Date:   Wed Nov 8 02:10:58 2023 +0000
+
+    [streambuf.general] Remove incorrect "abstract"
+
+    The referenced class template `basic_streambuf` is not abstract.
+
+commit bbaa4a497e03d944fc38279db4d8c47eed7831d9
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Oct 12 20:51:57 2023 +0200
+
+    [basic.lval] turn reference paragraph into note
+
+commit a03b8b70d6666b67d27c801b68d41683e987e929
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Thu Oct 5 15:27:29 2023 -0400
+
+    [temp.param] Introduce term to xref structural type
+
+    The current cross-references to [temp.param] appear confusing,
+    as the structural type definition is buried a couple of pages
+    below.  Also, this change looks clearer in the source.
+
+commit 71ee18ab8cd9efca0d8afa1f6e639cb02610a52b
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Nov 7 16:18:40 2023 -1000
+
+    [basic.types.general] Introduce term to xref implicit-lifetime type (#6591)
+
+commit 21454c7ebf67a1a723b61c32901a842c684e6b94
+Author: Language Lawyer <language.lawyer@gmail.com>
+Date:   Wed Aug 23 01:35:22 2023 +0500
+
+    [intro.races] Make reading atomic objects nondeterministic
+
+commit df26017a6bfd74d794345ea9313eae1efacbf7c9
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Nov 8 03:31:10 2023 +0100
+
+    [diff.dcl] Replace 'field initializers' with 'member initializers' (#6482)
+
+commit cc69fc0dd6b1a2fdc834bade578acb84cc7d2cfa
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Nov 8 10:54:52 2023 +0800
+
+    [intro.races] Remove inappropriate uses of "shall" (#6457)
+
+commit 60e280391a06b8d27f778a56310b0827109623aa
+Author: Eisenwave <me@eisenwave.net>
+Date:   Thu Aug 31 00:19:24 2023 +0200
+
+    [cmath.syn] fix misaligned parameter lists
+
+commit 646bfb2a060e3c7f490f6c4672ee93a0cbaf6d0d
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Nov 8 05:59:28 2023 -1000
+
+    [container.alloc.reqmts] Better xrefs for allocator-aware containers
+
+    There are now more allocator-aware containers in the standard
+    than when this subclause was first written, so ensure we have
+    call outs to all relevent subclauses.
+
+    The current wording for 'basic_stacktrace' also shows how
+    containers can properly call out the allocator-aware container
+    requirements, now that they have their own, titled subclause.
+
+commit 62e33ca8a0a55764227e6a67c1f554783ffefe40
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Thu Nov 9 00:01:38 2023 +0800
+
+    [time.zone.leap.overview] Fix example (#6383)
+
+commit 07ae51af31587ac533b1b39c95777ecb725dcab0
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Jan 25 18:22:53 2023 +0800
+
+    [expr.prim.req.general] Correct the IFNDR example
+
+commit f3059744c84f561f8ead4c5d117bc1160c43b7e2
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Nov 8 23:52:44 2023 +0000
+
+    [defns.character.container] Improve note to entry (#6644)
+
+commit 8b38857b22f6518a41e506e4c9b2e9a1792a0fbd
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Oct 10 09:40:20 2023 +0800
+
+    [iterator.requirements.general] Clarify non-forward iterator
+
+commit fbb1a6ebbd1f78e644df2dbcb3ce31250410779e
+Author: onihusube <44743040+onihusube@users.noreply.github.com>
+Date:   Fri Nov 10 08:36:12 2023 +0900
+
+    [execpol.unseq] Fix missing \itemdescr (#5931)
+
+commit 10e2799f5d524dd941d424dfd08927c77a6b87f1
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Fri Feb 17 10:47:28 2023 -0500
+
+    [pairs.pair] Consistent wording for assignment
+
+    Apply a consistent pattern to how we specify assigning members in assignment operators.
+
+commit 78300aa38c23f1356dca8e786205e5aaf7769d01
+Author: Barry Revzin <barry.revzin@gmail.com>
+Date:   Thu Nov 9 14:45:17 2023 -1000
+
+    [class.compare] Don't introduce `V` for the return value (#6035)
+
+    In both cases, I'm not sure introducing `V` helps much - just requires name lookup for `V`. If we just say "the return value" in every case, I think that's clearer.
+
+commit 838cb0649b1f4061e960772aee3563cedb20b108
+Author: Michael Florian Hava <mfh@live.at>
+Date:   Thu Nov 9 13:51:58 2023 -1000
+
+    [basic.extended.fp] Replaced usage of 'mantissa' with 'significand'
+    according to SO/IEC/IEEE 60559:2008
+
+commit ce5ef1b5334f1fc756d40e40ec300257b0ff99d9
+Author: Michael Florian Hava <mfh@live.at>
+Date:   Thu Nov 9 13:57:32 2023 -1000
+
+    [numeric.limits.members] Replaced usage of 'mantissa' with 'significand' according to
+    SO/IEC/IEEE 60559:2008
+
+commit 3e1f377a9dc3bece7acd2dddb7237065504db65c
+Author: Brian Bi <bbi5291@gmail.com>
+Date:   Thu Nov 9 16:00:22 2023 -1000
+
+    [macros, styles] Add \hypertarget to headings (#6516)
+
+    This allows forming URLs with a stable label as a fragment and
+    have PDF viewers jump to the corresponding (sub)clause.
+
+    For example: std.pdf#basic.life
+
+commit 60f7bb72cdd36e9d359fa7aea84a5b836079a0ed
+Author: Eisenwave <me@eisenwave.net>
+Date:   Thu Jul 6 13:41:56 2023 +0200
+
+    [namespace.std] convert (a) and (b) notation to items
+
+commit f48f316c42c6cb67058d9f9106852154497b4516
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Fri Nov 10 06:57:17 2023 +0100
+
+    [atomics.order] Use "recommended practice" (#6380)
+
+commit 1ec1d9e6fa98734b3edf20f6c2217a4482f78103
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Fri Nov 10 16:59:21 2023 +0800
+
+    [meta.{unary.prop.query,trans.arr] Use `static_assert` instead of `assert` in example
+
+commit bd8f4540720e52dab9187a62c5598e735aeacfdd
+Author: Eisenwave <me@eisenwave.net>
+Date:   Sat Aug 19 15:57:39 2023 +0200
+
+    [expr.sizeof] use constexpr member in example
+
+commit b1f922a126dcda78acb4bae055843e7a7321fe1d
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Aug 23 13:42:39 2023 +0200
+
+    [basic.def.odr] Fix hyphenation of "{copy,move} assignment"
+
+commit 54e465a17adfcba56a57ff2fefe43ec898725efb
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Aug 23 13:43:46 2023 +0200
+
+    [res.on.arguments] Fix hyphenation of "move assignment"
+
+commit 3c5b5b0c58d0440233d992e1a0791a449936f203
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Aug 23 13:44:40 2023 +0200
+
+    [futures.{unique,shared}.future] Fix hyphenation of "{copy,move} assignment"
+
+commit 9483cb7cf6973689ad563d30778d8da2dff42a8d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Nov 8 22:57:57 2023 +0000
+
+    [string.capacity] Remove parentheses from "reserve()"
+
+    It's very confusing to talk about `reserve()` when describing a call to
+    `reserve(size_type)`, given that the overload `reserve()` also exists.
+
+commit 2a9f28670a0df6e239d9b335bdb014f20f577732
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Jul 24 16:19:01 2023 +0000
+
+    [dcl.meaning.general] Use 'declarator-id' instead of 'name'
+
+commit d8b72f0ceb36b3537ef576ab216d588642e332ab
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Tue Jul 25 18:26:03 2023 +0000
+
+    [module.global.frag] Simplify wording
+
+    Also make variable order consistent across bullets.
+
+commit f0c172c5604b47c3ecc7b64669aad660df403624
+Author: Oliver Rosten <oliver.rosten@gmail.com>
+Date:   Fri Nov 10 18:12:06 2023 +0000
+
+    [algorithms] Change stable label "mismatch" to "alg.mismatch" (#6653)
+
+commit d97603a90d2fcfeec2caf4371ca9e6c8f562842a
+Author: A. Jiang <de34@live.cn>
+Date:   Sat Nov 11 03:21:17 2023 +0800
+
+    [forward.iterators] Use "Cpp17" requirement (#6612)
+
+commit f474227b69d10350999a5fc63503725421a89954
+Author: Geng Cheng <xmcgcg@qq.com>
+Date:   Sat Nov 11 10:25:39 2023 +0800
+
+    [stringstream.general] Add missing template argument "Allocator" (#6560)
+
+commit f5fdfe453e5a1e0370f2cb28bfc2dfeecab6370e
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Nov 8 15:12:16 2023 -1000
+
+    [diff.cpp20.library] Add missing new headers for C++23
+
+commit 38dfe3db0f08bd09a2b445ba82e83f7caae28d94
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Nov 9 11:00:44 2023 +0800
+
+    [dcl.init.ref] Clarify "related type"
+
+    "Related type" is not a term, "reference-related type" is clearer.
+
+commit 979983929bb592c02c9ae3e52f1c676dd5ae06fe
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Nov 14 02:27:01 2023 +0800
+
+    [range.cartesian.view] Don't name unused template parameter (#6177)
+
+commit ecbeb5ad4e4c0ac1d0cdb5e8dd01daab8df8d62e
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Nov 14 14:27:27 2023 -0500
+
+    [diff.cpp23.library] Entry for new headers in C++26 (#6648)
+
+commit eb7f0bcbff2af109643089ef36dfe67040a27f4a
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Nov 13 01:12:50 2023 -1000
+
+    [intro.defs, macros] Add cross-references among definitions
+
+    Fixes ISO/CS 017 (C++23 DIS).
+
+commit 706880e4ed855ae76d503c70adfb0015bbfb3df0
+Author: Lewis Baker <lewissbaker@users.noreply.github.com>
+Date:   Thu Nov 16 10:36:25 2023 +1030
+
+    [allocator.requirements.general] Fix missing ellipsis (#6695)
+
+commit 5c0103c0a656cbcd725780388b0879e992a1b21a
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Nov 16 15:38:47 2023 +0000
+
+    [stacktrace.format], [stacktrace.basic.hash] change rSec3 to rSec2
+
+    These should not be nested below std::basic_stacktrace because they
+    apply to both std::stacktrace_entry and std::basic_stacktrace.
+
+commit a6ad6083ab75901cb41b5bc8d034c0b322433457
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Dec 5 23:42:23 2023 +0000
+
+    [std, styles] Adjust table captions as per ISO request
+
+    ISO has asked for captions to be bold and table numbers to be
+    separated by a dash.
+
+commit f519ea4aa97592703ba5bbe9164242d946723721
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 7 01:00:53 2023 +0100
+
+    [intro.refs, time.format] Update references from ISO 8601:2004 to ISO 8601-1:2019 (#6720)
+
+commit 37956fb3685c2c279bd6b4b701964b20913d0c79
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Dec 6 19:01:29 2023 +0000
+
+    [syntax] Change "italic" to "italic, sans-serif"
+
+    We changed the grammar non-terminal font to sans-serif,
+    so we should update the description.
+
+commit 4eed7a0f1e44c45554f8a210af34fd6e1ea19596
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Dec 7 22:13:35 2023 +0100
+
+    [intro.abstract] Actually use the phrase 'unspecified/undefined behavior'
+
+    Fixes ISO/CS 011 (C++23 DIS).
+
+commit f8a6138da1e431779ac43a893faa32f3f0cad7d0
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Dec 7 12:45:11 2023 +0000
+
+    [intro.defs] Fix introductory text according to ISO rules.
+
+    In principle, "symbols and abbreviated terms" can be listed in a
+    standard, and can be listed in a separate clause or in a combined
+    clause 3 "Terms, definitions, symbols and abbreviated terms", we do
+    not actually need symbol definitions. In any case, the introductory
+    text would never mention "symbols".
+
+commit 9961cd4f16aca645c77d6927526ea71f635a2932
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Dec 7 00:01:48 2023 +0000
+
+    [introduction] A minimal "Introduction" clause
+
+    This clause explains our conventions regarding stable labels and
+    choice of fonts.
+
+commit 9041b27206388fecd03073bb913185ac738c6dca
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Mon Dec 18 00:57:45 2023 +0000
+
+    [optional.monaic] Restore wording effected by LWG3973.
+
+    Both LWG3973 (Motion 1) and P2407R5 (Motion 3) modified this wording:
+    LWG3973 changes "value()" to "*val" to address ADL concerns, and
+    P2407R5 changed "value()" to "**this" to be freestanding. In light of
+    the former, the latter should also use "*val".
+
+    Independently, additional problems have been discovered with LWG3973,
+    but those will be addressed by a future LWG issue.
+
+commit 2b1867a3404562c4261722e0a913cbcbf5a0a476
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Sun Dec 17 23:10:44 2023 +0000
+
+    [version.syn] New feature test macro __cpp_lib_freestanding_numeric
+
+    This macro indicates that freestanding support for "saturation
+    arithmetic" is available, which was added in motion LWG-2 (via
+    P0543R3). This reverts the previous change
+    148e03a16d53ff8cffd219384df37efad5fd386d, which I had made subsequent
+    to motion LWG-3 (P2407R5), on advice of LWG. A separate macro is
+    preferable to mixing both headers under "algorithm".
+
+commit fa54f9e7306b3d0abb21a82b5cc951711c96161f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Wed Dec 13 11:03:18 2023 +0000
+
+    [range.access.general] Use consistent "In addition to being available ..." form
+
+    Elsewhere we say "the header" or "any of the headers", e.g. [meta.trans.other],
+    [tuple.helper], etc.
+
+commit 8c611593555b93a45a13543ad265d8cfaf646932
+Author: Cassio Neri <cassio.neri@gmail.com>
+Date:   Mon Nov 27 19:47:29 2023 +0000
+
+    [expected.general] Fix description of expected<T, E> (issue #6714.)
+
+commit 12565ed5ea083761b25df3c8325989f95fa04898
+Author: Po-yao Chang <poyaoc97@gmail.com>
+Date:   Wed Nov 22 23:02:49 2023 +0800
+
+    [class.eq] Fix the return value of a defaulted == operator function
+
+ + diff --git a/papers/n4972.md b/papers/n4972.md new file mode 100644 index 0000000000..ed66878372 --- /dev/null +++ b/papers/n4972.md @@ -0,0 +1,699 @@ +# N4972 Editors' Report -- Programming Languages -- C++ + +Date: 2023-12-18 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes, +and special thanks to Johel Ernesto Guerrero Peña for providing in-depth review +of many of the draft motion applications. + +## New papers + + * [N4971](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4971.pdf) is the + current working draft for C++26. It replaces + [N4964](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4964.pdf). + * N4972 is this Editors' Report. + +## Motions incorporated into working draft + +### Notes on motions + +All motions were applied cleanly, and the following additional changes applied +for the sake of integration: + +* LWG Polls 1 and 3 both modified [optional.monadic]: + [LWG-3973](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p3040r0.html#3973) + changed `**this` to `*val`, and + [P2407R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2407r5.html) + changed `value()` to `**this`. This has been reconciled by changing the + latter to `*val`, too. +* LWG Poll 2 created a freestanding facility (saturation arithmetic) but did + not define a freestanding feature test macro. We added the macro + `__cpp_lib_freestanding_numeric`, also defined in the `` header. + +The feature test macro `__cpp_lib_span` has been modified both LWG Poll 3 and +LWG Poll 10, and is now set to a common, updated value (`202311L`). + +The linear algebra paper P1673R13 moved by LWG Poll 19 adds a substantial amount +of material, and numerous minor issues were discovered during application, many +of which have been fixed immediately, and some will be addressed in future +editorial work. One particular issue, which is not new and also affects the +random number and special maths functions, is how to relate variables in code +and mathematical variables in a mathematical expression. + +### Core working group polls + +CWG Poll 1: Accept as a Defect Report and apply the proposed resolution of all issues in +[P3046R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p3046r0.html) +(Core Language Working Group "ready" Issues for the November, 2023 meeting) to the C++ Working Paper. + +CWG Poll 2: Accept as a Defect Report and apply the changes in +[P2308R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2308r1.html) +(Template parameter initialization) to the C++ Working Paper. + +CWG Poll 3: Apply the changes in +[P2662R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2662r3.pdf) +(Pack Indexing) to the C++ Working Paper. + +CWG Poll 4: Apply the changes in +[P2864R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2864r2.pdf) +(Remove Deprecated Arithmetic Conversion on Enumerations From C++26) to the C++ Working Paper. + +CWG Poll 5 was withdrawn. + +### Library working group polls + +LWG Poll 1: Apply the changes for all Ready and Tentatively Ready issues in +[P3040R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p3040r0.html) +(C++ Standard Library Issues to be moved in Kona, Nov. 2023) to the C++ working paper. + +LWG Poll 2: Apply the changes in +[P0543R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0543r3.html) +(Saturation arithmetic) to the C++ working paper. + +LWG Poll 3: Apply the changes in +[P2407R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2407r5.html) +(Freestanding Library: Partial Classes) to the C++ working paper. + +LWG Poll 4: Apply the changes in +[P2546R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2546r5.html) +(Debugging Support) to the C++ working paper. + +LWG Poll 5: Accept as a Defect Report and apply the changes in +[P2905R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2905r2.html) +(Runtime format strings) to the C++ working paper. + +LWG Poll 6: Apply the changes in +[P2918R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2918r2.html) +(Runtime format strings II) to the C++ working paper. + +LWG Poll 7: Accept as a Defect Report and apply the changes in +[P2909R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2909r4.html) +(Fix formatting of code units as integers (Dude, where's my char?)) to the C++ working paper. + +LWG Poll 8: Apply the changes in +[P0952R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0952r2.html) +(A new specification for `std::generate_canonical`) to the C++ working paper. + +LWG Poll 9: Apply the changes in +[P2447R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2447r6.html) +(`std::span` over an initializer list) to the C++ working paper. + +LWG Poll 10: Apply the changes in +[P2821R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2821r5.html) +(`span.at()`) to the C++ working paper. + +LWG Poll 11: Apply the changes in +[P2868R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2868r3.pdf) +(Remove Deprecated `std::allocator` Typedef From C++26) to the C++ working paper. + +LWG Poll 12: Apply the changes in +[P2870R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2870r3.pdf) +(Remove `basic_string::reserve()` From C++26) to the C++ working paper. + +LWG Poll 13: Apply the changes in +[P2871R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2871r3.pdf) +(Remove Deprecated Unicode Conversion Facets from C++26) to the C++ working paper. + +LWG Poll 14: Apply the changes in +[P2819R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2819r2.pdf) +(Add tuple protocol to `complex`) to the C++ working paper. + +LWG Poll 15: Apply the changes in +[P2937R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2937r0.html) +(Freestanding: Remove `strtok`) to the C++ working paper. + +LWG Poll 16: Apply the changes in +[P2833R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2833r2.html) +(Freestanding Library: `inout` `expected` `span`) to the C++ working paper. + +LWG Poll 17: Accept as a Defect Report and apply the changes in +[P2836R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2836r1.html) +(`std::basic_const_iterator` should follow its underlying type's convertibility) to the C++ working paper. + +LWG Poll 18: Apply the changes in +[P2264R7](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2264r7.html) +(Make `assert()` macro user friendly for C and C++) to the C++ working paper. + +LWG Poll 19: Apply the changes in +[P1673R13](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1673r13.html) +(A free function linear algebra interface based on the BLAS) to the C++ working paper. + +## Comments on the Draft International Standard + +This report includes our final dispositions on the Draft International Standard (DIS) +ballot comments for C++23 from national bodies and the ISO secretariat. Some of them only apply +to the published standard document and not the working draft, and the corresponding edits do not +appear in the working draft commit history. All comments on the ballot were editorial. + +* **ISO/CS 01:** Accepted. We added references to the tables. +* **ISO/CS 02:** Accepted. We moved the explanations close to their point of use. +* **ISO/CS 03:** Accepted. We are now referring to a specific element, and keeping the dated reference. +* **ISO/CS 04:** Accepted. +* **ISO/CS 05:** Rejected: We do not understand the justification "Since there is no specific element referenced this reference shall be undated." The Drafting Directives seem to make a clear case for when undated (10.4) and dated (10.5) references are appropriate, and we firmly fall into the case where an undated reference is inappropriate ("if it will be possible to use all future changes of the referenced document" is definitely not the case). Reference to a specific element does not seem to be required in order to permit the use of a dated reference. Even the House Style seems to permit dated references when necessary: "When referring to the whole document, use an undated document number unless it is necessary that the user refers to a specific edition". +* **ISO/CS 06:** Rejected: Moot by comment 05. +* **ISO/CS 07:** Rejected: Moot by comment 05. +* **ISO/CS 08:** Accepted. We reworded the reference to the Unicode standard to make the normative nature more obvious. +* **ISO/CS 09:** Accepted. +* **ISO/CS 10:** Rejected: We find domains valuable here, since the terms often sound like plain English words, but have rather domain-specific meaning, and the domain establishes important context to aid understandability. +* **ISO/CS 11:** Accepted with modifications: four unused definitions are removed. The remaining term, "unspecified behavior" is retained, since it captures a variety of patterns which are not lexically spelled "behavior" but are neatly covered by this umbrella term. +* **ISO/CS 12:** Accepted with modifications: we have italicized the cross-references. However, for the formal grammar terms that we display in italic sans font, please see the discussion on comment 32. +* **ISO/CS 13:** Rejected: The token "CE" is not an acronym, but a meta variable (like "x" or "y". It is typeset distinctly. The name is evocative of its use. +* **ISO/CS 14:** Accepted. +* **ISO/CS 15:** Accepted. +* **ISO/CS 16:** Rejected: The wording is correct as written. However, this is also mooted by comment 11, which deletes the wording in question. +* **ISO/CS 17:** Accepted. +* **ISO/CS 18:** Accepted. +* **ISO/CS 19:** Accepted. +* **CA 20:** n/a, comment was filed erroneously +* **JP 21:** Accepted. We added an example. +* **JP 22:** Rejected: No consensus for change; any attributes of a lambda-declarator are considered to be attached to the synthesized function call operator or operator template (i.e. the member function of the closure type), not the closure type itself. +* **JP 23:** Accepted with modifications: The example is written as intended. The comments in the example have been amended to clarify the exposition. +* **JP 24:** Accepted. +* **JP 25:** Accepted. +* **JP 26:** Rejected: No consensus for change; the example deliberately introduces a facility to aid comprehension. +* **JP 27:** Rejected: No consensus for change; the example deliberately introduces a facility to aid comprehension. +* **JP 28:** Rejected: No consensus for change; the example deliberately introduces a facility to aid comprehension. +* **ISO/CS 29:** Accepted. +* **ISO/CS 30:** Accepted. We added a note that refers to the annex. +* **ISO/CS 31:** Accepted. We had previously used foreword wording from an older document. +* **ISO/CS 32:** Rejected, along with comment 12: our document has complex typographic requirements, and we have carefully selected a harmonizing family of typefaces in our document processing system that meets our needs. For example, certain parts of a formal grammar (some of which appear in Clause 3; see comment 12) require typographic distinction to avoid ambiguity. We have discussed this with the ISO secretariat. +* **ISO/CS 33:** Rejected: We have an approved SC22 ballot to permit the use of paragraph numbers. (We also have a proposal for the JDMT to add such a permission to the Drafting Directives.) +* **ISO/CS 34:** Accepted. Reworded to clarify. +* **ISO/CS 35:** Accepted. +* **ISO/CS 36:** Accepted the notes and tables captioning changes. Rejected the UK English spelling: The document defines many terms that must be spelled the same way by conforming implementations and by users of those implementations, and these terms use US English spelling. It would be confusing for the document text to use UK English spelling when describing these terms. (This is the same disposition as for a similar comment on the DIS ballot of 14882:2017.) +* **ISO/CS 37:** Rejected, please see comment 39. +* **ISO/CS 38:** Accepted with modifications: We will review the presentation of cross-references in Clause 3. However, the use of italics in Clause 3 is not a regular "emphasis/definition" in body font, but rather a grammar production, which we typeset distinctly. Please also see the discussion regarding comment 32. +* **ISO/CS 39:** Rejected: For this comment and for comment 37, we have carefully reviewed the permitted verbal constructions. We believe that the notes are the best place for this explanatory, optional information, and the wording as-is accurately describes the consequences of normative requirements for illustrative purposes. We would like to not move this explanatory material into the main text, since that text already contains a complex range of requirements on the C++ language, its implementations, and its users, and our community has been finding our established boundary for what is explanatory note material helpful. +* **ISO/CS 40:** Accepted. The logic that processed the notes was erroneous and failed to handle subclauses with more than 9 notes; this has been fixed. + +## Editorial changes + +### Major editorial changes + +A number of editorial changes were made in response to requests from the ISO +secretariat during the publication of C++23. We list just a few noteworthy ones. + +* There is now a new "Introduction" subclause, which explains our use of + stable labels and some typographic choices. In the future, we would like to + expand the introduction to explain more comprehensively how the Standard is + structured, phrased, and intended to be read. +* Table captions are now formatted in bold, and the table number is separated + from the caption by a dash. +* Inadmissible text has been removed from Clauses 2 (Normative references) and + 3 (Terms and definitions), as those clauses must only contain specific, + fixed wording. The removed text has been moved nearer to the places in the + main text where it is needed. +* Definitions in Clause 3 (Terms and definitions) now contain cross references + to one another as appropriate. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4964 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/n4964...n4971). + + commit a27ede64fef7fda551d480e5a1cf1b9a73832574 + Author: S. B. Tam + Date: Tue Oct 24 20:55:27 2023 +0800 + + [span.cons] Add `std::` for `data(arr)` (#6632) + + commit 84c526ebbda74553bf935f35f5594b8d5591bce5 + Author: Casey Carter + Date: Mon Oct 30 14:22:57 2023 -0700 + + [format.formatter.spec] Add missing include to example (#6636) + + The example code refers to `std::string` directly so it should `#include`. + + commit 4a6f2e3f4791c44b8c8f32a75d0bebac4a7b6a9e + Author: Jens Maurer + Date: Thu Nov 2 00:53:04 2023 +0100 + + [intro.refs] Move nicknames for standards to relevant subclauses + + commit dc6eed02986d9c3c6827c710adb577ba0809f939 + Author: Krystian Stasiowski + Date: Tue Nov 7 04:32:19 2023 -0500 + + [dcl.dcl, over.best.ics, temp.param, class.union.anon] Remove mentions of "storage class" (#3906) + + commit 17c09925b2423c596196d3f88a61ff7b4052ef7a + Author: Krystian Stasiowski + Date: Tue Nov 7 01:16:28 2023 -0500 + + [class.conv.fct] Fix reference to 'ref-qualifier-seq' + + commit 90720a35b0c3d65488d9dc9ecea682c271f43d52 + Author: A. Jiang + Date: Mon Oct 30 09:34:01 2023 +0800 + + [queue.syn] Show `formatter` specializations in the synopsis + + commit e43aa89a4882f8080fb10c843cdb25c9740b65c7 + Author: A. Jiang + Date: Mon Oct 30 09:36:24 2023 +0800 + + [stack.syn] Show the `formatter` specialization in the synopsis + + commit 80a8748fd401cfceee804bc96d2bfc518726d2e7 + Author: Arthur O'Dwyer + Date: Thu Oct 12 18:24:21 2023 -0400 + + [class.copy.assign] Remove a superfluous note. + + Alternatively we could have added the word "non-object"; or changed + it to say "An overloaded assignment operator must be a member function"; + but it doesn't seem like it needs to be here at all. + + commit c9c69dc54052badeb9b80458027371438d886763 + Author: Arthur O'Dwyer + Date: Thu Oct 12 18:58:39 2023 -0400 + + [class.copy.assign] Add some missing "non-object"s + + commit 2b5fc2936f12f73e975dbb9f34d3790fe0aa708f + Author: Matt Bentley + Date: Wed Nov 8 14:56:22 2023 +1300 + + [sequence.reqmts] Remove misleading, oversimplified informative text + + commit 11334c71244a046f0c29b01dfd79b35f6fea8cc4 + Author: Eisenwave + Date: Fri Sep 1 09:29:01 2023 +0200 + + [class.copy.elision] improve reference and replace informal term + + commit 4feefb62e0419bb52c678389163729959785d44a + Author: Jan Schultke + Date: Wed Nov 8 02:59:01 2023 +0100 + + [mem.res.pool.options] Change "field" to "member" (#6479) + + commit a700e3b87b00d2673b3cded0a61201d09dfc051a + Author: S. B. Tam + Date: Wed Nov 8 10:01:46 2023 +0800 + + [version.syn] Bump value of __cpp_lib_constexpr_complex (#6421) + + P1383R2 "More constexpr for and " modifies two headers; + both __cpp_lib_constexpr_cmath and __cpp_lib_constexpr_complex should be updated. + + This aligns with existing practice in SD6. + + commit e9fb04e1c1e67bfb07bf3c61145b9d63a0f0adcf + Author: Arthur O'Dwyer + Date: Tue Sep 27 15:36:08 2022 -0400 + + [dcl.enum] Enumerators don't have "initializers" + + commit bc3cb41a36dfff0d2358f4e294be9636590e680e + Author: Krystian Stasiowski + Date: Tue Nov 7 21:08:15 2023 -0500 + + [dcl.name] Turn informative wording into note (#3964) + + commit 82b2ba6f6245e717cb002a9a836117a918aab36a + Author: Patrick Johnston + Date: Wed Nov 8 02:10:58 2023 +0000 + + [streambuf.general] Remove incorrect "abstract" + + The referenced class template `basic_streambuf` is not abstract. + + commit bbaa4a497e03d944fc38279db4d8c47eed7831d9 + Author: Jan Schultke + Date: Thu Oct 12 20:51:57 2023 +0200 + + [basic.lval] turn reference paragraph into note + + commit a03b8b70d6666b67d27c801b68d41683e987e929 + Author: Alisdair Meredith + Date: Thu Oct 5 15:27:29 2023 -0400 + + [temp.param] Introduce term to xref structural type + + The current cross-references to [temp.param] appear confusing, + as the structural type definition is buried a couple of pages + below. Also, this change looks clearer in the source. + + commit 71ee18ab8cd9efca0d8afa1f6e639cb02610a52b + Author: Alisdair Meredith + Date: Tue Nov 7 16:18:40 2023 -1000 + + [basic.types.general] Introduce term to xref implicit-lifetime type (#6591) + + commit 21454c7ebf67a1a723b61c32901a842c684e6b94 + Author: Language Lawyer + Date: Wed Aug 23 01:35:22 2023 +0500 + + [intro.races] Make reading atomic objects nondeterministic + + commit df26017a6bfd74d794345ea9313eae1efacbf7c9 + Author: Jan Schultke + Date: Wed Nov 8 03:31:10 2023 +0100 + + [diff.dcl] Replace 'field initializers' with 'member initializers' (#6482) + + commit cc69fc0dd6b1a2fdc834bade578acb84cc7d2cfa + Author: A. Jiang + Date: Wed Nov 8 10:54:52 2023 +0800 + + [intro.races] Remove inappropriate uses of "shall" (#6457) + + commit 60e280391a06b8d27f778a56310b0827109623aa + Author: Eisenwave + Date: Thu Aug 31 00:19:24 2023 +0200 + + [cmath.syn] fix misaligned parameter lists + + commit 646bfb2a060e3c7f490f6c4672ee93a0cbaf6d0d + Author: Alisdair Meredith + Date: Wed Nov 8 05:59:28 2023 -1000 + + [container.alloc.reqmts] Better xrefs for allocator-aware containers + + There are now more allocator-aware containers in the standard + than when this subclause was first written, so ensure we have + call outs to all relevent subclauses. + + The current wording for 'basic_stacktrace' also shows how + containers can properly call out the allocator-aware container + requirements, now that they have their own, titled subclause. + + commit 62e33ca8a0a55764227e6a67c1f554783ffefe40 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Thu Nov 9 00:01:38 2023 +0800 + + [time.zone.leap.overview] Fix example (#6383) + + commit 07ae51af31587ac533b1b39c95777ecb725dcab0 + Author: A. Jiang + Date: Wed Jan 25 18:22:53 2023 +0800 + + [expr.prim.req.general] Correct the IFNDR example + + commit f3059744c84f561f8ead4c5d117bc1160c43b7e2 + Author: Jonathan Wakely + Date: Wed Nov 8 23:52:44 2023 +0000 + + [defns.character.container] Improve note to entry (#6644) + + commit 8b38857b22f6518a41e506e4c9b2e9a1792a0fbd + Author: A. Jiang + Date: Tue Oct 10 09:40:20 2023 +0800 + + [iterator.requirements.general] Clarify non-forward iterator + + commit fbb1a6ebbd1f78e644df2dbcb3ce31250410779e + Author: onihusube <44743040+onihusube@users.noreply.github.com> + Date: Fri Nov 10 08:36:12 2023 +0900 + + [execpol.unseq] Fix missing \itemdescr (#5931) + + commit 10e2799f5d524dd941d424dfd08927c77a6b87f1 + Author: Alisdair Meredith + Date: Fri Feb 17 10:47:28 2023 -0500 + + [pairs.pair] Consistent wording for assignment + + Apply a consistent pattern to how we specify assigning members in assignment operators. + + commit 78300aa38c23f1356dca8e786205e5aaf7769d01 + Author: Barry Revzin + Date: Thu Nov 9 14:45:17 2023 -1000 + + [class.compare] Don't introduce `V` for the return value (#6035) + + In both cases, I'm not sure introducing `V` helps much - just requires name lookup for `V`. If we just say "the return value" in every case, I think that's clearer. + + commit 838cb0649b1f4061e960772aee3563cedb20b108 + Author: Michael Florian Hava + Date: Thu Nov 9 13:51:58 2023 -1000 + + [basic.extended.fp] Replaced usage of 'mantissa' with 'significand' + according to SO/IEC/IEEE 60559:2008 + + commit ce5ef1b5334f1fc756d40e40ec300257b0ff99d9 + Author: Michael Florian Hava + Date: Thu Nov 9 13:57:32 2023 -1000 + + [numeric.limits.members] Replaced usage of 'mantissa' with 'significand' according to + SO/IEC/IEEE 60559:2008 + + commit 3e1f377a9dc3bece7acd2dddb7237065504db65c + Author: Brian Bi + Date: Thu Nov 9 16:00:22 2023 -1000 + + [macros, styles] Add \hypertarget to headings (#6516) + + This allows forming URLs with a stable label as a fragment and + have PDF viewers jump to the corresponding (sub)clause. + + For example: std.pdf#basic.life + + commit 60f7bb72cdd36e9d359fa7aea84a5b836079a0ed + Author: Eisenwave + Date: Thu Jul 6 13:41:56 2023 +0200 + + [namespace.std] convert (a) and (b) notation to items + + commit f48f316c42c6cb67058d9f9106852154497b4516 + Author: Jan Schultke + Date: Fri Nov 10 06:57:17 2023 +0100 + + [atomics.order] Use "recommended practice" (#6380) + + commit 1ec1d9e6fa98734b3edf20f6c2217a4482f78103 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Fri Nov 10 16:59:21 2023 +0800 + + [meta.{unary.prop.query,trans.arr] Use `static_assert` instead of `assert` in example + + commit bd8f4540720e52dab9187a62c5598e735aeacfdd + Author: Eisenwave + Date: Sat Aug 19 15:57:39 2023 +0200 + + [expr.sizeof] use constexpr member in example + + commit b1f922a126dcda78acb4bae055843e7a7321fe1d + Author: Eisenwave + Date: Wed Aug 23 13:42:39 2023 +0200 + + [basic.def.odr] Fix hyphenation of "{copy,move} assignment" + + commit 54e465a17adfcba56a57ff2fefe43ec898725efb + Author: Eisenwave + Date: Wed Aug 23 13:43:46 2023 +0200 + + [res.on.arguments] Fix hyphenation of "move assignment" + + commit 3c5b5b0c58d0440233d992e1a0791a449936f203 + Author: Eisenwave + Date: Wed Aug 23 13:44:40 2023 +0200 + + [futures.{unique,shared}.future] Fix hyphenation of "{copy,move} assignment" + + commit 9483cb7cf6973689ad563d30778d8da2dff42a8d + Author: Jonathan Wakely + Date: Wed Nov 8 22:57:57 2023 +0000 + + [string.capacity] Remove parentheses from "reserve()" + + It's very confusing to talk about `reserve()` when describing a call to + `reserve(size_type)`, given that the overload `reserve()` also exists. + + commit 2a9f28670a0df6e239d9b335bdb014f20f577732 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Jul 24 16:19:01 2023 +0000 + + [dcl.meaning.general] Use 'declarator-id' instead of 'name' + + commit d8b72f0ceb36b3537ef576ab216d588642e332ab + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Tue Jul 25 18:26:03 2023 +0000 + + [module.global.frag] Simplify wording + + Also make variable order consistent across bullets. + + commit f0c172c5604b47c3ecc7b64669aad660df403624 + Author: Oliver Rosten + Date: Fri Nov 10 18:12:06 2023 +0000 + + [algorithms] Change stable label "mismatch" to "alg.mismatch" (#6653) + + commit d97603a90d2fcfeec2caf4371ca9e6c8f562842a + Author: A. Jiang + Date: Sat Nov 11 03:21:17 2023 +0800 + + [forward.iterators] Use "Cpp17" requirement (#6612) + + commit f474227b69d10350999a5fc63503725421a89954 + Author: Geng Cheng + Date: Sat Nov 11 10:25:39 2023 +0800 + + [stringstream.general] Add missing template argument "Allocator" (#6560) + + commit f5fdfe453e5a1e0370f2cb28bfc2dfeecab6370e + Author: Alisdair Meredith + Date: Wed Nov 8 15:12:16 2023 -1000 + + [diff.cpp20.library] Add missing new headers for C++23 + + commit 38dfe3db0f08bd09a2b445ba82e83f7caae28d94 + Author: A. Jiang + Date: Thu Nov 9 11:00:44 2023 +0800 + + [dcl.init.ref] Clarify "related type" + + "Related type" is not a term, "reference-related type" is clearer. + + commit 979983929bb592c02c9ae3e52f1c676dd5ae06fe + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Nov 14 02:27:01 2023 +0800 + + [range.cartesian.view] Don't name unused template parameter (#6177) + + commit ecbeb5ad4e4c0ac1d0cdb5e8dd01daab8df8d62e + Author: Alisdair Meredith + Date: Tue Nov 14 14:27:27 2023 -0500 + + [diff.cpp23.library] Entry for new headers in C++26 (#6648) + + commit eb7f0bcbff2af109643089ef36dfe67040a27f4a + Author: Thomas Köppe + Date: Mon Nov 13 01:12:50 2023 -1000 + + [intro.defs, macros] Add cross-references among definitions + + Fixes ISO/CS 017 (C++23 DIS). + + commit 706880e4ed855ae76d503c70adfb0015bbfb3df0 + Author: Lewis Baker + Date: Thu Nov 16 10:36:25 2023 +1030 + + [allocator.requirements.general] Fix missing ellipsis (#6695) + + commit 5c0103c0a656cbcd725780388b0879e992a1b21a + Author: Jonathan Wakely + Date: Thu Nov 16 15:38:47 2023 +0000 + + [stacktrace.format], [stacktrace.basic.hash] change rSec3 to rSec2 + + These should not be nested below std::basic_stacktrace because they + apply to both std::stacktrace_entry and std::basic_stacktrace. + + commit a6ad6083ab75901cb41b5bc8d034c0b322433457 + Author: Thomas Köppe + Date: Tue Dec 5 23:42:23 2023 +0000 + + [std, styles] Adjust table captions as per ISO request + + ISO has asked for captions to be bold and table numbers to be + separated by a dash. + + commit f519ea4aa97592703ba5bbe9164242d946723721 + Author: Jens Maurer + Date: Thu Dec 7 01:00:53 2023 +0100 + + [intro.refs, time.format] Update references from ISO 8601:2004 to ISO 8601-1:2019 (#6720) + + commit 37956fb3685c2c279bd6b4b701964b20913d0c79 + Author: Thomas Köppe + Date: Wed Dec 6 19:01:29 2023 +0000 + + [syntax] Change "italic" to "italic, sans-serif" + + We changed the grammar non-terminal font to sans-serif, + so we should update the description. + + commit 4eed7a0f1e44c45554f8a210af34fd6e1ea19596 + Author: Jens Maurer + Date: Thu Dec 7 22:13:35 2023 +0100 + + [intro.abstract] Actually use the phrase 'unspecified/undefined behavior' + + Fixes ISO/CS 011 (C++23 DIS). + + commit f8a6138da1e431779ac43a893faa32f3f0cad7d0 + Author: Thomas Köppe + Date: Thu Dec 7 12:45:11 2023 +0000 + + [intro.defs] Fix introductory text according to ISO rules. + + In principle, "symbols and abbreviated terms" can be listed in a + standard, and can be listed in a separate clause or in a combined + clause 3 "Terms, definitions, symbols and abbreviated terms", we do + not actually need symbol definitions. In any case, the introductory + text would never mention "symbols". + + commit 9961cd4f16aca645c77d6927526ea71f635a2932 + Author: Thomas Köppe + Date: Thu Dec 7 00:01:48 2023 +0000 + + [introduction] A minimal "Introduction" clause + + This clause explains our conventions regarding stable labels and + choice of fonts. + + commit 9041b27206388fecd03073bb913185ac738c6dca + Author: Thomas Köppe + Date: Mon Dec 18 00:57:45 2023 +0000 + + [optional.monaic] Restore wording effected by LWG3973. + + Both LWG3973 (Motion 1) and P2407R5 (Motion 3) modified this wording: + LWG3973 changes "value()" to "*val" to address ADL concerns, and + P2407R5 changed "value()" to "**this" to be freestanding. In light of + the former, the latter should also use "*val". + + Independently, additional problems have been discovered with LWG3973, + but those will be addressed by a future LWG issue. + + commit 2b1867a3404562c4261722e0a913cbcbf5a0a476 + Author: Thomas Köppe + Date: Sun Dec 17 23:10:44 2023 +0000 + + [version.syn] New feature test macro __cpp_lib_freestanding_numeric + + This macro indicates that freestanding support for "saturation + arithmetic" is available, which was added in motion LWG-2 (via + P0543R3). This reverts the previous change + 148e03a16d53ff8cffd219384df37efad5fd386d, which I had made subsequent + to motion LWG-3 (P2407R5), on advice of LWG. A separate macro is + preferable to mixing both headers under "algorithm". + + commit fa54f9e7306b3d0abb21a82b5cc951711c96161f + Author: Jonathan Wakely + Date: Wed Dec 13 11:03:18 2023 +0000 + + [range.access.general] Use consistent "In addition to being available ..." form + + Elsewhere we say "the header" or "any of the headers", e.g. [meta.trans.other], + [tuple.helper], etc. + + commit 8c611593555b93a45a13543ad265d8cfaf646932 + Author: Cassio Neri + Date: Mon Nov 27 19:47:29 2023 +0000 + + [expected.general] Fix description of expected (issue #6714.) + + commit 12565ed5ea083761b25df3c8325989f95fa04898 + Author: Po-yao Chang + Date: Wed Nov 22 23:02:49 2023 +0800 + + [class.eq] Fix the return value of a defaulted == operator function diff --git a/papers/n4982.html b/papers/n4982.html new file mode 100644 index 0000000000..3f97397fec --- /dev/null +++ b/papers/n4982.html @@ -0,0 +1,613 @@ + + + + + +N4982 + + +

N4982 Editors’ Report:
Programming Languages — C++

+ +

Date: 2024-04-16

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

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

+ +

New papers

+ +
    +
  • N4981 is the +current working draft for C++26. It replaces +N4971.
  • +
  • N4982 is this Editors' Report.
  • +
+ +

Motions incorporated into working draft

+ +

Notes on motions

+ +

All motions were applied cleanly.

+ +

Core working group polls

+ +

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

+ +

CWG Poll 2. Apply the changes in +P2748R5 +(Disallow Binding a Returned Glvalue to a Temporary) to the C++ Working Paper.

+ +

CWG Poll 3. Accept as a Defect Report and apply the changes in P3106R1 (Clarifying rules for brace elision in aggregate initialization) to the C++ Working Paper, resolving core issue 2149.

+ +

CWG Poll 4. Apply the changes in +P0609R3 +(Attributes for Structured Bindings) to the C++ Working Paper.

+ +

CWG Poll 5. Accept as a Defect Report and apply the changes in +P3034R1 +(Module Declarations Shouldn’t be Macros) to the C++ Working Paper.

+ +

CWG Poll 6. Accept as a Defect Report and apply the changes in +P2809R3 +(Trivial infinite loops are not Undefined Behavior) to the C++ Working Paper.

+ +

CWG Poll 7. Apply the changes in +P2795R5 +(Erroneous behaviour for uninitialized reads) to the C++ Working Paper.

+ +

CWG Poll 9. Apply the changes in +P2573R2 +(= delete("should have a reason");) to the C++ Working Paper.

+ +

CWG Poll 10. Apply the changes in +P2893R3 +(Variadic friends) to the C++ Working Paper.

+ +

CWG Poll 8 was withdrawn.

+ +

Library working group polls

+ +

LWG Poll 1: Apply the changes for all Ready and Tentatively Ready issues in +P3180R0 +(C++ Standard Library Ready Issues to be moved in Tokyo, Mar. 2024) to the C++ working paper.

+ +

LWG Poll 2: Apply the changes in +P2875R4 +(Undeprecate polymorphic_allocator::destroy for C++26) to the C++ working paper.

+ +

LWG Poll 3: Apply the changes in +P2867R2 +(Remove Deprecated strstreams From C++26) to the C++ working paper.

+ +

LWG Poll 4: Apply the changes in +P2869R4 +(Remove Deprecated shared_ptr Atomic Access APIs from C++26) to the C++ working paper.

+ +

LWG Poll 5: Apply the changes in +P2872R3 +(Remove wstring_convert From C++26) to the C++ working paper.

+ +

LWG Poll 6: Accept as a Defect Report and apply the changes in +P3107R5 +(Permit an efficient implementation of std::print) to the C++ working paper.

+ +

LWG Poll 7: Apply the changes in +P3142R0 +(Printing Blank Lines with println) to the C++ working paper.

+ +

LWG Poll 8: Apply the changes in +P2845R8 +(Formatting of std::filesystem::path) to the C++ working paper.

+ +

LWG Poll 9: Apply the changes in +P0493R5 +(Atomic minimum/maximum) to the C++ working paper.

+ +

LWG Poll 10: Apply the changes in +P2542R8 +(views::concat) to the C++ working paper.

+ +

LWG Poll 11: Apply the changes in +P2591R5 +(Concatenation of strings and string views) to the C++ working paper.

+ +

LWG Poll 12: Apply the changes in +P2248R8 +(Enabling list-initialization for algorithms) to the C++ working paper.

+ +

LWG Poll 13: Apply the changes in +P2810R4 +(is_debugger_present is_replaceable) to the C++ working paper.

+ +

LWG Poll 14: Apply the changes in +P1068R11 +(Vector API for random number generation) to the C++ working paper.

+ +

LWG Poll 16: Apply the changes in +P2944R3 +(Comparisons for reference_wrapper) to the C++ working paper.

+ +

LWG Poll 17: Apply the changes in +P2642R6 +(Padded mdspan layouts) to the C++ working paper.

+ +

LWG Poll 18: Apply the changes in +P3029R1 +(Better mdspan's CTAD) to the C++ working paper.

+ +

LWG Poll 15 was withdrawn.

+ +

Editorial changes

+ +

Major editorial changes

+ +

There have not been any major editorial changes since the last working draft.

+ +

Minor editorial changes

+ +

A log of editorial fixes made to the working draft since N4971 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 08649a5a81ba91d8597c263b99dc80ed71767940
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Fri Dec 22 11:33:39 2023 +0100
+
+    [stmt.expr] Use \grammarterm for expression (#6469)
+
+commit acb68797051c9a6a5f51e4adb5091b376f1ba13a
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Jan 1 16:23:56 2024 +0100
+
+    [basic.life] Fix indentation in example (#6727)
+
+commit f6692f25130834672ba5a212f739100669abbbe8
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Jan 2 20:21:54 2024 +0100
+
+    [basic.scope.pdecl,basic.types.general] Remove extra whitespace (#6756)
+
+commit 7ddcd43c96589fc13342ac4cee549da75360fde7
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Fri Jan 5 15:41:01 2024 -0500
+
+    [basic.scope.param] Add missing \grammarterm for requires-expression (#6759)
+
+commit 29c0e4882a1ae62e7cd5f8d3fabcb22ae6153219
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 18 17:22:30 2023 +0100
+
+    [std] Remove problematic 'requires' phrases from notes.
+
+    Only specific phrases involving the word "required" are problematic,
+    namely when they appear to establish a normative requirement. They
+    have been reworded, often by replacing "is required" with "needs",
+    sometimes with slightly larger edits.
+
+commit 43fc5a16147e720568b68ecae77f12fa3fb15102
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jan 5 15:32:55 2024 +0000
+
+    [std] Reword "necessary", "permitted", "allowed", "may" in notes.
+
+    This is so that notes do not (inappropriately) state requirements or
+    permissions.
+
+commit 74433025763f83bbccfb001dab8aa084647ffb2f
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Jan 11 19:11:17 2024 +0100
+
+    [basic.def] Fix punctuation (#6766)
+
+commit b67e0b70e88abf65d9b49875133c68d55744b1de
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jan 12 12:53:10 2024 +0000
+
+    [text.encoding.overview] Use same parameter names as detailed description (#6768)
+
+commit bc5a56b6e9cadd030d48066601fc8098382c7469
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Jan 15 11:19:13 2024 -0800
+
+    [exception] Paragraph two is no longer universally true
+
+    We recently added `bad_expected_access<void>` to the Standard Library, which derives from `exception`, but does not have "the following publicly accessible member functions, each of them having a non-throwing exception specification." For clarity, we should point out that this provision is not universal.
+
+commit 2055c2feabee6ec9df24ea07f8451ad33618be45
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Jan 16 09:20:44 2024 +0100
+
+    [zombie.names] Remove superfluous period (#6774)
+
+commit 8410aac1b84ec161b6990441acde53185f958135
+Author: Daniel Krügler <daniel.kruegler@gmail.com>
+Date:   Sun Jan 21 22:39:02 2024 +0100
+
+    [tuple.helper] Paragraph 1 not universally true (#6777)
+
+    [tuple.helper] p1 defines a general requirement that all specializations of `tuple_size`
+    shall meet the *Cpp17UnaryTypeTrait* requirements, but p4 actually defines a
+    special situation where this requirement is not met ("Otherwise, it has no member value").
+    We have the same seemingly contradiction in [depr.tuple] p2. For clarity, we should
+    point out that this provision is not universal.
+
+commit 4fe9190fa05c4fb4e83c1a1ba68aa12aa49542e9
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Sat Jan 27 14:38:55 2024 +0800
+
+    [locale.ctype.members] Add missing parameter name
+
+commit 74f5f61cac56a4eca5389a51754fe7e60e6b7449
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sat Jan 27 11:26:37 2024 +0000
+
+    [tuple.cnstr] Do not use code font for cardinal number 1 (#6785)
+
+commit cb8ff12806b67990665100baaacb9a16040bce8c
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat Jan 27 17:11:23 2024 +0100
+
+    [container.alloc.reqmts] End note with period (#6787)
+
+commit 70b99af0dfcb9cae82bcd97c7b24a2e84edfb2cd
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat Jan 27 18:03:16 2024 +0100
+
+    [class.mem.general,class.mfct.non.static] End note with period (#6778)
+
+commit db80a4612af561e8473fd8fb3724ae9db2c72578
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Feb 5 15:51:03 2024 +0000
+
+    [rand.dist.samp.plinear] Fix copy & paste error in Mandates (#6794)
+
+    This error was present in the incoming P1719R2 paper (Mandating the
+    Standard Library: Clause 26 - Numerics Library), but is obviously bogus.
+    There is no UnaryOperation type in that constructor. The correct
+    requirement is taken from the corresponding constructor in
+    [rand.dist.samp.pconst].
+
+commit e51d5733b1bd1531d6e3b63617d12414a56678c0
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Wed Feb 7 10:37:06 2024 -0500
+
+    [temp.res.general] Grammatical parallelism: remove a stray "a" (#6796)
+
+commit 8238252bcec14f76e97133db32721beaec5c749b
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Feb 8 06:59:10 2024 +0100
+
+    [iterator.concept.winc] Fix typo (#6800)
+
+commit 19caa61068d3f3aa2453e1ba7256536b8464c25c
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Dec 28 10:07:15 2023 +0800
+
+    [mem.res.private] Say `*this` instead of improper  `this`
+
+commit 419190062806ae257e5efe7057551fd626bd9516
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Dec 28 10:08:04 2023 +0800
+
+    [mem.res.monotonic.buffer.mem] Say `*this` instead of improper `this`
+
+commit 6ecda0b20664fc6b8450157e1cd9f0580c32e5e1
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Dec 28 10:09:08 2023 +0800
+
+    [re.traits] Say `*this` instead of improper `this`
+
+commit 9305893dfd250d876edf4555cf96c665e2e71e75
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Feb 15 13:16:33 2024 -0800
+
+    [thread.once.callonce] INVOKE is evaluated, not called (#6810)
+
+commit 3616a40ded794e94181a5405672b1c36f7774684
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Feb 21 19:05:13 2024 +0100
+
+    [temp.pre] Add comma after introductory clause (#6814)
+
+commit 30debb0c5d5dc42fa36864aac76b82f49319ad84
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Feb 21 21:39:56 2024 +0100
+
+    [temp.constr.order] Move index entry to correct paragraph (#6812)
+
+commit fb0277664fd53efea93d95202784f78aea610f31
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Feb 22 20:28:15 2024 +0100
+
+    [semaphore.syn] Add binary_semaphore to index (#6781)
+
+commit 090840673ee58d3c1e8d2844d3c716ee5ce245bc
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Feb 22 20:31:19 2024 +0100
+
+    [format.parse.ctx] Improve readability of paragraphs 12 and 14 (#6815)
+
+commit a5825b1905b06d730a46e64fb5b379f48cbc6e51
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Feb 22 20:33:18 2024 +0100
+
+    [format.parse.ctx] Add comma (#6817)
+
+commit 8c8e05d7ff6cda6329ca898e7a270547a85675d7
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Feb 22 20:35:21 2024 +0100
+
+    [format.parse.ctx] Move non-normative explanations of errors into notes (#6816)
+
+commit 48f90026631638c91b3d8138bed49cd0450380c7
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Feb 28 10:23:51 2024 +0100
+
+    [stmt.while] Add comma after introductory phrase
+
+commit d5ad3794937429b1410071037af9ddfb0aa8c861
+Author: Eisenwave <me@eisenwave.net>
+Date:   Wed Feb 28 10:24:26 2024 +0100
+
+    [stmt.do] Add comma after introductory phrase
+
+commit 78ecd23f22f00be4bffaf806a6747417ce2150a2
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Feb 28 18:06:26 2024 +0100
+
+    [stmt.jump] Add cross-reference to [stmt.dcl] for destruction of local variables (#6829)
+
+commit 66b6b97c8f3969f96e3ca8df1180c18b1c57af8c
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Wed Feb 28 21:50:50 2024 +0100
+
+    [expr.dynamic.cast] Add comma after conditional clause (#6830)
+
+commit 23430d7e605d62f5a4a1769611e3c415d6510b65
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Mar 1 11:06:34 2024 +0100
+
+    [bibliography] Replace HTTP link with HTTPS link (#6831)
+
+commit 20c2851a3c8f480a017cef6602b1b6a4d32bc5e4
+Author: Eisenwave <me@eisenwave.net>
+Date:   Fri Mar 1 16:03:04 2024 +0100
+
+    [time.parse] Hyphenate argument-dependent lookup
+
+commit e0287d17110f86e3724bda5ebe74de249508490f
+Author: Eisenwave <me@eisenwave.net>
+Date:   Fri Mar 1 16:04:02 2024 +0100
+
+    [diff.cpp17.temp] Hyphenate argument-dependent lookup
+
+commit ceff4ea83b511be01a8e1756386ce6a2e06e323c
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Fri Mar 1 18:06:00 2024 +0100
+
+    [headers] Strike incorrect quote of subclause heading (#6832)
+
+commit 9878cfbea12b517d32c5af1bbfa7c8b8c4ff9cab
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Sun Mar 3 08:42:45 2024 +0100
+
+    [handler.functions] Add cross-reference to [intro.races] (#6845)
+
+commit 9ec133c8e51aae98297255563250a2f6656e4636
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Tue Mar 19 15:36:51 2024 +0000
+
+    [time.hash] Fix spelling of 'Cpp17Hash'
+
+commit 2b7cd6e8be2bc8a9ae97da9bf03ae4efa7fe1a9c
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Tue Apr 16 20:03:29 2024 +0800
+
+    [expos.only.entity] Add/fix \expos for exposition-only names (#6924)
+
+commit aa21c812f629975d5d25d4639053482f346751a8
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Tue Apr 16 08:07:44 2024 -0400
+
+    [dcl.type.elab] Move note to separate paragraph
+
+    Also clarify that the next paragraph is talking about any elaborated-type-specifier at all, not just the ones in p4.
+
+commit 397384c90e3ead9f832a3a269335fbfe53328180
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Feb 16 06:51:03 2024 +0100
+
+    [rand.adapt.ibits,rand.dist.pois.poisson] Add namespace std in class template
+
+    [rand.adapt.ibits] 28.5.5.3-4
+    [rand.dist.pois.poisson] 28.5.9.4.1-1
+
+commit fbf3d76683d269a0a5313fb69b5aa483ddd3a18a
+Author: Jan Schultke <me@eisenwave.net>
+Date:   Thu Feb 22 21:41:42 2024 +0100
+
+    [expr.unary.op] remove redundant value category wording
+
+commit 498cd7720bb2e53fb323144f956e67900a054e34
+Author: Daniel Krügler <daniel.kruegler@gmail.com>
+Date:   Sun Feb 4 17:57:38 2024 +0100
+
+    [iterator.requirements.general] Clarify that "constexpr iterator" is a requirement to be met
+
+    [iterator.requirements.general] p16 says "Iterators are called _constexpr iterators_ [..]", but all referencing sections say "meet the constexpr iterator requirements". For clarity, we should reword the definition to make it clear that this is a named requirement.
+
+commit 89cd1467f354a2b9b05ac57ad1f90f483aab22b9
+Author: Hewill Kang <67143766+hewillk@users.noreply.github.com>
+Date:   Sun Jan 28 13:54:17 2024 +0800
+
+    [range.drop.overview] Remove redundant \iref for subrange
+
+    ..which already existed in the previous bullet.
+
+commit bee055de1c5e23ce0b301138998633dc64169b4a
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Nov 23 09:33:39 2023 +0800
+
+    [dcl.init.ref] Change "function lvalue" to "lvalue of function type"
+
+commit ce31d424ba6753be1c87a4cf3face42f89b9e010
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Nov 23 09:36:28 2023 +0800
+
+    [over.ics.ref] Simplify wording by not using "function lvalue"
+
+commit 2a07c133732dcc7ea57aeb32612b15b50837a4df
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Nov 23 09:38:41 2023 +0800
+
+    [over.ics.rank] Change "function lvalue" to "lvalue of function type"
+
+commit 7675c4c1abf1986241e8a20463fd71f2841d3c39
+Author: Eisenwave <me@eisenwave.net>
+Date:   Fri Sep 1 10:27:25 2023 +0200
+
+    [res.on.exception.handling] use grammarterm instead of informal term and add ref
+
+ + diff --git a/papers/n4982.md b/papers/n4982.md new file mode 100644 index 0000000000..92a68b0900 --- /dev/null +++ b/papers/n4982.md @@ -0,0 +1,472 @@ +# N4982 Editors' Report -- Programming Languages -- C++ + +Date: 2024-04-16 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have [submitted editorial +issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue) +and to those who have provided pull requests with fixes. + +## New papers + + * [N4981](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4981.pdf) is the + current working draft for C++26. It replaces + [N4971](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4971.pdf). + * N4982 is this Editors' Report. + +## Motions incorporated into working draft + +### Notes on motions + +All motions were applied cleanly. + +### Core working group polls + +CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues in +[P3196R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3196r0.html) +(Core Language Working Group "ready" Issues for the March, 2024 meeting) to the C++ Working Paper. + +CWG Poll 2. Apply the changes in +[P2748R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2748r5.html) +(Disallow Binding a Returned Glvalue to a Temporary) to the C++ Working Paper. + +CWG Poll 3. Accept as a Defect Report and apply the changes in [P3106R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3106r1.html) (Clarifying rules for brace elision in aggregate initialization) to the C++ Working Paper, resolving core issue 2149. + +CWG Poll 4. Apply the changes in +[P0609R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0609r3.pdf) +(Attributes for Structured Bindings) to the C++ Working Paper. + +CWG Poll 5. Accept as a Defect Report and apply the changes in +[P3034R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3034r1.html) +(Module Declarations Shouldn’t be Macros) to the C++ Working Paper. + +CWG Poll 6. Accept as a Defect Report and apply the changes in +[P2809R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2809r3.html) +(Trivial infinite loops are not Undefined Behavior) to the C++ Working Paper. + +CWG Poll 7. Apply the changes in +[P2795R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2795r5.html) +(Erroneous behaviour for uninitialized reads) to the C++ Working Paper. + +CWG Poll 9. Apply the changes in +[P2573R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2573r2.html) +(`= delete("should have a reason");`) to the C++ Working Paper. + +CWG Poll 10. Apply the changes in +[P2893R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2893r3.html) +(Variadic friends) to the C++ Working Paper. + +CWG Poll 8 was withdrawn. + +### Library working group polls + +LWG Poll 1: Apply the changes for all Ready and Tentatively Ready issues in +[P3180R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3180r0.html) +(C++ Standard Library Ready Issues to be moved in Tokyo, Mar. 2024) to the C++ working paper. + +LWG Poll 2: Apply the changes in +[P2875R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2875r4.pdf) +(Undeprecate `polymorphic_allocator::destroy` for C++26) to the C++ working paper. + +LWG Poll 3: Apply the changes in +[P2867R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2867r2.html) +(Remove Deprecated `strstream`s From C++26) to the C++ working paper. + +LWG Poll 4: Apply the changes in +[P2869R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2869r4.pdf) +(Remove Deprecated `shared_ptr` Atomic Access APIs from C++26) to the C++ working paper. + +LWG Poll 5: Apply the changes in +[P2872R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2872r3.pdf) +(Remove `wstring_convert` From C++26) to the C++ working paper. + +LWG Poll 6: Accept as a Defect Report and apply the changes in +[P3107R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3107r5.html) +(Permit an efficient implementation of `std::print`) to the C++ working paper. + +LWG Poll 7: Apply the changes in +[P3142R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3142r0.pdf) +(Printing Blank Lines with `println`) to the C++ working paper. + +LWG Poll 8: Apply the changes in +[P2845R8](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2845r8.html) +(Formatting of `std::filesystem::path`) to the C++ working paper. + +LWG Poll 9: Apply the changes in +[P0493R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0493r5.pdf) +(Atomic minimum/maximum) to the C++ working paper. + +LWG Poll 10: Apply the changes in +[P2542R8](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2542r8.html) +(`views::concat`) to the C++ working paper. + +LWG Poll 11: Apply the changes in +[P2591R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2591r5.html) +(Concatenation of strings and string views) to the C++ working paper. + +LWG Poll 12: Apply the changes in +[P2248R8](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2248r8.html) +(Enabling list-initialization for algorithms) to the C++ working paper. + +LWG Poll 13: Apply the changes in +[P2810R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2810r4.html) +(`is_debugger_present` `is_replaceable`) to the C++ working paper. + +LWG Poll 14: Apply the changes in +[P1068R11](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p1068r11.html) +(Vector API for random number generation) to the C++ working paper. + +LWG Poll 16: Apply the changes in +[P2944R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2944r3.html) +(Comparisons for `reference_wrapper`) to the C++ working paper. + +LWG Poll 17: Apply the changes in +[P2642R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2642r6.pdf) +(Padded `mdspan` layouts) to the C++ working paper. + +LWG Poll 18: Apply the changes in +[P3029R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3029r1.html) +(Better `mdspan`'s CTAD) to the C++ working paper. + +LWG Poll 15 was withdrawn. + +## Editorial changes + +### Major editorial changes + +There have not been any major editorial changes since the last working draft. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N4971 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/n4971...n4981). + + commit 08649a5a81ba91d8597c263b99dc80ed71767940 + Author: Jan Schultke + Date: Fri Dec 22 11:33:39 2023 +0100 + + [stmt.expr] Use \grammarterm for expression (#6469) + + commit acb68797051c9a6a5f51e4adb5091b376f1ba13a + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Jan 1 16:23:56 2024 +0100 + + [basic.life] Fix indentation in example (#6727) + + commit f6692f25130834672ba5a212f739100669abbbe8 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Jan 2 20:21:54 2024 +0100 + + [basic.scope.pdecl,basic.types.general] Remove extra whitespace (#6756) + + commit 7ddcd43c96589fc13342ac4cee549da75360fde7 + Author: Alisdair Meredith + Date: Fri Jan 5 15:41:01 2024 -0500 + + [basic.scope.param] Add missing \grammarterm for requires-expression (#6759) + + commit 29c0e4882a1ae62e7cd5f8d3fabcb22ae6153219 + Author: Jens Maurer + Date: Mon Dec 18 17:22:30 2023 +0100 + + [std] Remove problematic 'requires' phrases from notes. + + Only specific phrases involving the word "required" are problematic, + namely when they appear to establish a normative requirement. They + have been reworded, often by replacing "is required" with "needs", + sometimes with slightly larger edits. + + commit 43fc5a16147e720568b68ecae77f12fa3fb15102 + Author: Thomas Köppe + Date: Fri Jan 5 15:32:55 2024 +0000 + + [std] Reword "necessary", "permitted", "allowed", "may" in notes. + + This is so that notes do not (inappropriately) state requirements or + permissions. + + commit 74433025763f83bbccfb001dab8aa084647ffb2f + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Jan 11 19:11:17 2024 +0100 + + [basic.def] Fix punctuation (#6766) + + commit b67e0b70e88abf65d9b49875133c68d55744b1de + Author: Jonathan Wakely + Date: Fri Jan 12 12:53:10 2024 +0000 + + [text.encoding.overview] Use same parameter names as detailed description (#6768) + + commit bc5a56b6e9cadd030d48066601fc8098382c7469 + Author: Casey Carter + Date: Mon Jan 15 11:19:13 2024 -0800 + + [exception] Paragraph two is no longer universally true + + We recently added `bad_expected_access` to the Standard Library, which derives from `exception`, but does not have "the following publicly accessible member functions, each of them having a non-throwing exception specification." For clarity, we should point out that this provision is not universal. + + commit 2055c2feabee6ec9df24ea07f8451ad33618be45 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Jan 16 09:20:44 2024 +0100 + + [zombie.names] Remove superfluous period (#6774) + + commit 8410aac1b84ec161b6990441acde53185f958135 + Author: Daniel Krügler + Date: Sun Jan 21 22:39:02 2024 +0100 + + [tuple.helper] Paragraph 1 not universally true (#6777) + + [tuple.helper] p1 defines a general requirement that all specializations of `tuple_size` + shall meet the *Cpp17UnaryTypeTrait* requirements, but p4 actually defines a + special situation where this requirement is not met ("Otherwise, it has no member value"). + We have the same seemingly contradiction in [depr.tuple] p2. For clarity, we should + point out that this provision is not universal. + + commit 4fe9190fa05c4fb4e83c1a1ba68aa12aa49542e9 + Author: S. B. Tam + Date: Sat Jan 27 14:38:55 2024 +0800 + + [locale.ctype.members] Add missing parameter name + + commit 74f5f61cac56a4eca5389a51754fe7e60e6b7449 + Author: Jonathan Wakely + Date: Sat Jan 27 11:26:37 2024 +0000 + + [tuple.cnstr] Do not use code font for cardinal number 1 (#6785) + + commit cb8ff12806b67990665100baaacb9a16040bce8c + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat Jan 27 17:11:23 2024 +0100 + + [container.alloc.reqmts] End note with period (#6787) + + commit 70b99af0dfcb9cae82bcd97c7b24a2e84edfb2cd + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat Jan 27 18:03:16 2024 +0100 + + [class.mem.general,class.mfct.non.static] End note with period (#6778) + + commit db80a4612af561e8473fd8fb3724ae9db2c72578 + Author: Jonathan Wakely + Date: Mon Feb 5 15:51:03 2024 +0000 + + [rand.dist.samp.plinear] Fix copy & paste error in Mandates (#6794) + + This error was present in the incoming P1719R2 paper (Mandating the + Standard Library: Clause 26 - Numerics Library), but is obviously bogus. + There is no UnaryOperation type in that constructor. The correct + requirement is taken from the corresponding constructor in + [rand.dist.samp.pconst]. + + commit e51d5733b1bd1531d6e3b63617d12414a56678c0 + Author: Arthur O'Dwyer + Date: Wed Feb 7 10:37:06 2024 -0500 + + [temp.res.general] Grammatical parallelism: remove a stray "a" (#6796) + + commit 8238252bcec14f76e97133db32721beaec5c749b + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Feb 8 06:59:10 2024 +0100 + + [iterator.concept.winc] Fix typo (#6800) + + commit 19caa61068d3f3aa2453e1ba7256536b8464c25c + Author: A. Jiang + Date: Thu Dec 28 10:07:15 2023 +0800 + + [mem.res.private] Say `*this` instead of improper `this` + + commit 419190062806ae257e5efe7057551fd626bd9516 + Author: A. Jiang + Date: Thu Dec 28 10:08:04 2023 +0800 + + [mem.res.monotonic.buffer.mem] Say `*this` instead of improper `this` + + commit 6ecda0b20664fc6b8450157e1cd9f0580c32e5e1 + Author: A. Jiang + Date: Thu Dec 28 10:09:08 2023 +0800 + + [re.traits] Say `*this` instead of improper `this` + + commit 9305893dfd250d876edf4555cf96c665e2e71e75 + Author: Casey Carter + Date: Thu Feb 15 13:16:33 2024 -0800 + + [thread.once.callonce] INVOKE is evaluated, not called (#6810) + + commit 3616a40ded794e94181a5405672b1c36f7774684 + Author: Jan Schultke + Date: Wed Feb 21 19:05:13 2024 +0100 + + [temp.pre] Add comma after introductory clause (#6814) + + commit 30debb0c5d5dc42fa36864aac76b82f49319ad84 + Author: Jens Maurer + Date: Wed Feb 21 21:39:56 2024 +0100 + + [temp.constr.order] Move index entry to correct paragraph (#6812) + + commit fb0277664fd53efea93d95202784f78aea610f31 + Author: Jan Schultke + Date: Thu Feb 22 20:28:15 2024 +0100 + + [semaphore.syn] Add binary_semaphore to index (#6781) + + commit 090840673ee58d3c1e8d2844d3c716ee5ce245bc + Author: Jan Schultke + Date: Thu Feb 22 20:31:19 2024 +0100 + + [format.parse.ctx] Improve readability of paragraphs 12 and 14 (#6815) + + commit a5825b1905b06d730a46e64fb5b379f48cbc6e51 + Author: Jan Schultke + Date: Thu Feb 22 20:33:18 2024 +0100 + + [format.parse.ctx] Add comma (#6817) + + commit 8c8e05d7ff6cda6329ca898e7a270547a85675d7 + Author: Jan Schultke + Date: Thu Feb 22 20:35:21 2024 +0100 + + [format.parse.ctx] Move non-normative explanations of errors into notes (#6816) + + commit 48f90026631638c91b3d8138bed49cd0450380c7 + Author: Eisenwave + Date: Wed Feb 28 10:23:51 2024 +0100 + + [stmt.while] Add comma after introductory phrase + + commit d5ad3794937429b1410071037af9ddfb0aa8c861 + Author: Eisenwave + Date: Wed Feb 28 10:24:26 2024 +0100 + + [stmt.do] Add comma after introductory phrase + + commit 78ecd23f22f00be4bffaf806a6747417ce2150a2 + Author: Jan Schultke + Date: Wed Feb 28 18:06:26 2024 +0100 + + [stmt.jump] Add cross-reference to [stmt.dcl] for destruction of local variables (#6829) + + commit 66b6b97c8f3969f96e3ca8df1180c18b1c57af8c + Author: Jan Schultke + Date: Wed Feb 28 21:50:50 2024 +0100 + + [expr.dynamic.cast] Add comma after conditional clause (#6830) + + commit 23430d7e605d62f5a4a1769611e3c415d6510b65 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Mar 1 11:06:34 2024 +0100 + + [bibliography] Replace HTTP link with HTTPS link (#6831) + + commit 20c2851a3c8f480a017cef6602b1b6a4d32bc5e4 + Author: Eisenwave + Date: Fri Mar 1 16:03:04 2024 +0100 + + [time.parse] Hyphenate argument-dependent lookup + + commit e0287d17110f86e3724bda5ebe74de249508490f + Author: Eisenwave + Date: Fri Mar 1 16:04:02 2024 +0100 + + [diff.cpp17.temp] Hyphenate argument-dependent lookup + + commit ceff4ea83b511be01a8e1756386ce6a2e06e323c + Author: Jan Schultke + Date: Fri Mar 1 18:06:00 2024 +0100 + + [headers] Strike incorrect quote of subclause heading (#6832) + + commit 9878cfbea12b517d32c5af1bbfa7c8b8c4ff9cab + Author: Jan Schultke + Date: Sun Mar 3 08:42:45 2024 +0100 + + [handler.functions] Add cross-reference to [intro.races] (#6845) + + commit 9ec133c8e51aae98297255563250a2f6656e4636 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Tue Mar 19 15:36:51 2024 +0000 + + [time.hash] Fix spelling of 'Cpp17Hash' + + commit 2b7cd6e8be2bc8a9ae97da9bf03ae4efa7fe1a9c + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Tue Apr 16 20:03:29 2024 +0800 + + [expos.only.entity] Add/fix \expos for exposition-only names (#6924) + + commit aa21c812f629975d5d25d4639053482f346751a8 + Author: Arthur O'Dwyer + Date: Tue Apr 16 08:07:44 2024 -0400 + + [dcl.type.elab] Move note to separate paragraph + + Also clarify that the next paragraph is talking about any elaborated-type-specifier at all, not just the ones in p4. + + commit 397384c90e3ead9f832a3a269335fbfe53328180 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Feb 16 06:51:03 2024 +0100 + + [rand.adapt.ibits,rand.dist.pois.poisson] Add namespace std in class template + + [rand.adapt.ibits] 28.5.5.3-4 + [rand.dist.pois.poisson] 28.5.9.4.1-1 + + commit fbf3d76683d269a0a5313fb69b5aa483ddd3a18a + Author: Jan Schultke + Date: Thu Feb 22 21:41:42 2024 +0100 + + [expr.unary.op] remove redundant value category wording + + commit 498cd7720bb2e53fb323144f956e67900a054e34 + Author: Daniel Krügler + Date: Sun Feb 4 17:57:38 2024 +0100 + + [iterator.requirements.general] Clarify that "constexpr iterator" is a requirement to be met + + [iterator.requirements.general] p16 says "Iterators are called _constexpr iterators_ [..]", but all referencing sections say "meet the constexpr iterator requirements". For clarity, we should reword the definition to make it clear that this is a named requirement. + + commit 89cd1467f354a2b9b05ac57ad1f90f483aab22b9 + Author: Hewill Kang <67143766+hewillk@users.noreply.github.com> + Date: Sun Jan 28 13:54:17 2024 +0800 + + [range.drop.overview] Remove redundant \iref for subrange + + ..which already existed in the previous bullet. + + commit bee055de1c5e23ce0b301138998633dc64169b4a + Author: A. Jiang + Date: Thu Nov 23 09:33:39 2023 +0800 + + [dcl.init.ref] Change "function lvalue" to "lvalue of function type" + + commit ce31d424ba6753be1c87a4cf3face42f89b9e010 + Author: A. Jiang + Date: Thu Nov 23 09:36:28 2023 +0800 + + [over.ics.ref] Simplify wording by not using "function lvalue" + + commit 2a07c133732dcc7ea57aeb32612b15b50837a4df + Author: A. Jiang + Date: Thu Nov 23 09:38:41 2023 +0800 + + [over.ics.rank] Change "function lvalue" to "lvalue of function type" + + commit 7675c4c1abf1986241e8a20463fd71f2841d3c39 + Author: Eisenwave + Date: Fri Sep 1 10:27:25 2023 +0200 + + [res.on.exception.handling] use grammarterm instead of informal term and add ref diff --git a/papers/n4987.html b/papers/n4987.html new file mode 100644 index 0000000000..3099e7e867 --- /dev/null +++ b/papers/n4987.html @@ -0,0 +1,915 @@ + + + + + +N4987 + + +

N4987 Editors’ Report:
Programming Languages — C++

+ +

Date: 2024-07-16

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

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

+ +

New papers

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

Motions incorporated into working draft

+ +

Notes on motions

+ +

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

+ +

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

+ +

Core working group polls

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

CWG Poll 4 did not have consensus.

+ +

Library working group polls

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

Not yet applied:

+ +

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

+ +

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

+ +

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

+ +

Editorial changes

+ +

Major editorial changes

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

Minor editorial changes

+ +

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

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

N4989 Editors’ Report:
Programming Languages — C++

+ +

Date: 2024-08-05

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

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

+ +

New papers

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

Draft approval

+ +

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

+ +

Motions incorporated into working draft

+ +

Notes on motions

+ +

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

+ +

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

+ +

Core working group polls

+ +

Already applied in previous draft.

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

CWG Poll 4 did not have consensus.

+ +

Library working group polls

+ +

Already applied in previous draft.

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

Newly applied in this draft:

+ +

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

+ +

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

+ +

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

+ +

Editorial changes

+ +

Major editorial changes

+ +

There were no major editorial changes.

+ +

Minor editorial changes

+ +

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

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

N4994 Editors’ Report:
Programming Languages — C++

+ +

Date: 2024-10-16

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

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

+ +

New papers

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

Draft approval

+ +

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

+ +

No motions

+ +

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

+ +

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

+ +

Editorial changes

+ +

Major editorial changes

+ +

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

+ +

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

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

The new [text] clause obtains the following contents:

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

Additionally, the following subclauses are moved:

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

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

+ +

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

+ +

Minor editorial changes

+ +

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

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

N5002 Editors’ Report:
Programming Languages — C++

+ +

Date: 2024-12-17

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

Thanks to all those who have submitted editorial +issues +and to those who have provided pull requests with fixes. +Special thanks to Andreas Krug for many timely editorial fixes.

+ +

New papers

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

Motions incorporated into working draft

+ +

Notes on motions

+ +

CWG Poll 9 was retracted.

+ +

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

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

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

  • +
+ +

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

+ +

Core working group polls

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

CWG Poll 9 was retracted.

+ +

Library working group polls

+ +

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

+ +

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

+ +

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

+ +

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

+ +

LWG Poll 5 was sent back (see above).

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

LWG Poll 17 was sent back (see above).

+ +

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

+ +

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

+ +

Editorial changes

+ +

Major editorial changes

+ +

There have not been any major editorial changes.

+ +

Minor editorial changes

+ +

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

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

N5009 Editors’ Report:
Programming Languages — C++

+ +

Date: 2025-03-15

+ +

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

+ +

Email: cxxeditor@gmail.com

+ +

Acknowledgements

+ +

Thanks to all those who have +submitted editorial issues, +to those who have provided pull requests with fixes, +and to everyone who drafted motion applications.

+ +

New papers

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

Motions incorporated into working draft

+ +

Notes on motions

+ +

LWG Poll 2 was retracted.

+ +

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

+ +

Core working group polls

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

Library working group polls

+ +

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

+ +

LWG Poll 2 was retracted.

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

Editorial changes

+ +

Major editorial changes

+ +

There have not been any major editorial changes.

+ +

Minor editorial changes

+ +

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

+ +
commit f3676cb1550f1501236cc65c1dfa2dec957bbdf2
+Author: Mark Hoemmen <mhoemmen@users.noreply.github.com>
+Date:   Tue Dec 17 14:15:10 2024 -0700
+
+    [linalg.conj.conjugated] Remove inappropriate "expression-equivalent" wording (#7497)
+
+    This phrase appears to be copy-pasted from elsewhere, but is not meaningful here.
+
+commit be0a25c9a2f2c1f498b0ff84a33c28adae41863e
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Dec 17 20:31:14 2024 +0100
+
+    [simd.alg] Fix range syntax
+
+commit a18040f05ff6a27e5c6425005ab1b21515ad952c
+Author: Eisenwave <me@eisenwave.net>
+Date:   Fri Nov 1 08:06:28 2024 +0100
+
+    [basic.compound] Update introduction
+
+commit 0131e015c09eca1901d0bfa46744a6c7ab31b00d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Dec 17 21:21:42 2024 +0000
+
+    [linalg.helpers] Rename template parameter for poison pills
+
+    This avoids reusing `T` which is also used for the type of the
+    subexpression E.
+
+    Fixes #7494
+
+commit 04169bac7059322ad8bf32e605a80e57ef30b922
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 17 22:51:01 2024 +0100
+
+    [inplace.vector.overview] Replace residual use of 'trivial type'
+
+commit 9272753d0ecbc1df9d08178793795f06b623a451
+Author: Hewill Kang <hewillk@gmail.com>
+Date:   Tue Nov 19 16:41:00 2024 +0800
+
+    [flat.map.defn, flat.set.defn] Avoid naming the from_range_t tag
+
+commit 85de0af0e0af416f7e73ac096254641c31bf11cc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Dec 17 23:19:21 2024 +0100
+
+    [basic.fundamental] Ensure consistency with [conv.ptr]
+
+commit 561a4d8cde9e434fe206b88489e95b0e5271f469
+Author: Mark Hoemmen <mhoemmen@users.noreply.github.com>
+Date:   Thu Dec 19 14:35:50 2024 -0700
+
+    [bibliography] Fix spelling and formatting (#7507)
+
+    Fix spelling of one author's name.  Add missing commas
+    and extra spaces after a period ending authors' abbreviated
+    first or middle names.
+
+commit 82153790d8904ea82bc57edc8885b02925e85e93
+Author: Mark Hoemmen <mhoemmen@users.noreply.github.com>
+Date:   Thu Dec 19 14:41:02 2024 -0700
+
+    [simd.general, bibliography] Add SIMD acronym explanation and bibliographic reference (#7504)
+
+    To the existing Note at the beginning of [simd.general],
+    add text that unpacks the SIMD acronym and refers to Flynn 1966.
+
+    Add bibliography entry for Flynn 1966, the paper that introduced what
+    later became known as "Flynn's Taxonomy."  This classifies parallel
+    computer hardware as SISD, SIMD, MISD, or MIMD.
+
+commit e1a368bc157f824cee7702e87a2cca1951e60f98
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Dec 19 11:02:38 2024 +0000
+
+    [mdspan.sub] Change to "unit-stride slice for mapping"
+
+    This was the wording requested by LWG and approved in P3355R2, but I
+    mistakenly put P3355R1 in the straw polls.
+
+commit 2d3ac367d8605d7172151726e873daea295a573a
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Dec 20 10:15:46 2024 +0100
+
+    [diff.cpp03.library] Correct \effect to \change
+
+    - Correct \effect to \change.
+    - Add period at end.
+    - Add \tcode for swap.
+
+commit a2429a5944b71e3563dc09730426af43fb4b53e1
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Dec 26 01:37:34 2024 +0000
+
+    [class.expl.init] Fix incorrect note
+
+commit 1411cf56fcb41f9fd000406185f17ef47235d26a
+Author: Bronek Kozicki <brok@incorrekt.com>
+Date:   Wed Jan 1 17:00:14 2025 +0000
+
+    [expected.bad.void] Fix syntax error in bad_expected_access<void> (#7529)
+
+    Introduced by commit 8c997445c176c81a334e77f9344b91abc72b2772
+
+commit a137940ac9c807e3ea809c3ff0b3a863795bf742
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jan 1 22:18:37 2025 +0100
+
+    [filebuf.members,fs.path.req] Fix indefinite article (#7530)
+
+commit d2b48043fcc219b2a141af39dae2eb85934c0847
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jan 2 10:49:14 2025 +0100
+
+    [expr.const] Properly merge P2686R5
+
+    P2686R5 (applied by commit e220906b71df01f09fe60921e8fac39b80558f78)
+    accidentally reverted a change considering erroneous values made by
+    P2795R5.
+
+commit 22937c04da139226c186973eda2cdb79df640b5b
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Thu Jan 2 15:14:06 2025 +0100
+
+    [format.arg] Fix indefinite article (#7536)
+
+commit 75af9f7f8cd816e1908eb2a3917eb7749c11471a
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sat Jan 4 02:18:53 2025 +0700
+
+    [tuple.helper] Remove redundant 'public' in base-specifier of struct (#7539)
+
+commit 6ff55d533f72b7222e022513dcb80982f4e887a0
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Dec 30 16:34:49 2024 +0100
+
+    [lex.icon,depr.locale.category] Remove duplicate 'table' in front of table references
+
+commit 70df8aa8f4a30a7d54a604cbe01ebe13f5973043
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jan 8 13:51:13 2025 +0100
+
+    [linalg.algs.blas2.gemv] Fix singular/plural mismatch (#7546)
+
+commit 0164098f821ae002469c6f23cd03fc66a0a2f7ca
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Jan 9 10:01:36 2025 +0000
+
+    [basic.def.odr] Fix typo and reference the correct subclause
+
+commit 2734ddeb05115f3fddf09c9c15b843083575e9df
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Jan 10 13:13:28 2025 +0100
+
+    [exec.async.ops] Remove stray closing parenthesis (#7555)
+
+commit 77171de904e6008f31717615d5baabf604baeea8
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Fri Jan 10 23:05:58 2025 +0800
+
+    [locale.time.put.members] Remove incorrect footnote (#7553)
+
+commit 6ecd1be67c71001db37883ee45b76cc66ef4101f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jan 13 22:34:47 2025 +0100
+
+    [exec.getcomplsigs] Add missing LaTeX escaping of braces (#7541)
+
+commit 1b1914ed868b0b29e63d0d1e4b872daf07b50740
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Jan 14 14:31:09 2025 +0100
+
+    [simd.traits] Remove stray closing parenthesis (#7563)
+
+commit 0ac6f9d7e94a70b48457f289bcbeb069a4662c28
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jan 15 14:10:57 2025 +0100
+
+    [locale.moneypunct.general] Insert period at end (#7564)
+
+commit 96fad4cf7ff48c8a4ae5442580d55008fb56ca43
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jan 15 10:06:49 2025 -0500
+
+    [inplace.vector.overview] Remove spurious semicolon closing namespace std (#7566)
+
+commit 1c398ffc71845163ca50b712f1edd9e1b2a87772
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri Jan 17 17:11:02 2025 +0000
+
+    [type.info] Remove comments explaining deleted members
+
+    The standard is not a tutorial.
+
+commit 569e2a38cf1aa6d185b4c4d1817d9496ebd087e5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jan 18 09:18:53 2025 +0100
+
+    [exec.snd.expos] Move write-env paragraph into itemdescr (#7571)
+
+commit 93aa7cb89b375280cb2d5f385fb0c5a5874e9243
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sat Jan 18 23:32:20 2025 +0100
+
+    [re.err,re.alg.match,re.tokiter.incr] Add period at end for consistency (#7574)
+
+commit ce5fd62b98d822228f46319f4516e34c492fa257
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jan 22 16:15:57 2025 +0100
+
+    [string.view.io,string.insert] Add period at end of "Returns" (#7579)
+
+commit 5c4823a05b83a67f7550fdcc1476f8000c29514c
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Jan 23 11:31:05 2025 +0800
+
+    [expr.const] Re-apply CWG2909
+
+commit db563eecdfb63cb24f10afb30f001a0bc6213997
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jan 15 07:59:51 2025 -0500
+
+    [lex.phases] Update implementation defined text
+
+    Since C++23 we no longer have physical source files, but rather
+    input files.  Update the two implementation-defined references
+    to the mapping from input file to translation character set
+    using the same phrasing so that they provide the same entry
+    in the index of implementation-defined behavior, just as they
+    did in C++20, before getting out of sync when the terminology
+    changed.
+
+commit a39cca2e9c009766da1e205daf5d7bf8cbdccaa3
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Thu Jan 23 07:28:40 2025 -0500
+
+    [linalg.conj.conjugated] Rearrange to match P3050R3 (#7506)
+
+    This was the wording requested by LWG and approved in P3050R3, but I
+    mistakenly put P3050R2 in the straw polls.
+
+commit 6583c4ac9c2d3bbfb7daac0c79c902a30417c50f
+Author: cor3ntin <corentinjabot@gmail.com>
+Date:   Sat Jan 25 14:11:30 2025 +0100
+
+    [std] Use template-parameter and template parameter more consistently (#7460)
+
+    Try to use template-parameter only when we refer to a
+    grammar construct, and to 'template parameter' everywhere else.
+
+    Adopt the same logic to template-argument/template argument.
+
+    This change might not be  exhaustive.
+
+    The aim is to editorially adopt some of the wording changes
+    made in P2841R5 to ease its review in core.
+
+commit 696dcd809ceed3fc10502161963f8ce13505ec1a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jan 25 21:25:32 2025 +0100
+
+    [format.string.general,format.formatter.spec] Fix unparenthesized cross-references
+
+commit 47cf5a67357543b0d45d0072f42fdd29fa028cca
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Wed Jan 29 09:29:54 2025 +0100
+
+    [alg.rand.generate] Add period at end of "Returns" (#7595)
+
+commit b2b266e7b67eb583c50c34a9eceffe44f72ea2f6
+Author: Ivan Lazarić <ivan.lazaric1@gmail.com>
+Date:   Sat Feb 1 09:56:42 2025 +0100
+
+    [temp.res.general] Fix nesting for \terminal{\opt{...}} (#7599)
+
+commit d51e6bedd991d55b7f7fb7f41e1f08083cfd1b1d
+Author: Eric Niebler <eniebler@boost.org>
+Date:   Mon Feb 3 12:05:48 2025 -0800
+
+    [range.view] Change incorrect uses of "which" to "that" (#7606)
+
+commit 1d49b05d1b48a2daa2a88d854e2367e6648c3cb6
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Mon Feb 3 21:14:45 2025 +0100
+
+    [tuple.assign] Remove incorrect comma at end (#7609)
+
+commit 2e1b856b6187fe9a5c74782948982eefd128ecbf
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Feb 3 16:17:48 2025 -0500
+
+    [diff.cpp.library] Add new C23 headers to list of new headers
+
+commit cae9b2a645d5bb91caffc061325f107605e85a0d
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Tue Feb 4 09:30:49 2025 +0100
+
+    [container.alloc.reqmts,sequence.reqmts] Add period at end (#7614)
+
+commit 003506a2779c519d4929cce75c7adeb1b7a76955
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Jan 1 18:45:19 2025 +0700
+
+    [macros] Add LaTeX macros to index library macros
+
+    The immediate idea is to support using the new macros directly
+    in header synopses when defining each library macro.  This will
+    ensure that no macros are accidentally not indexed.
+
+    A follow-up plan is that this separation of library macros will
+    make it easier to create a separate index of macros, or apply
+    other macro-specific renderings, in the future.  To this end,
+    all indexed uses of a macro, not just those in header files,
+    should be replaced by use of these new macros.  Similarly,
+    these LaTeX macros can be used in-place in regular text to
+    index cross-references where standard library macros are used
+    throughout the standard.
+
+commit d7618b4d20a24b37677b92c2fbd80dcee4565bc3
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Feb 7 09:37:37 2025 +0100
+
+    [diff.lex] Add period at end (#7618)
+
+commit 040ff41df1d0e0e4d31bd6c76f084fbc84239e7f
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Sat Feb 8 07:56:45 2025 +0000
+
+    [fs.op.current.path] Remove note discussing design choices (#7620)
+
+commit dfdc64cbdc842f0f7d2a060440ea907b41ce78e6
+Author: Vlad Serebrennikov <serebrennikov.vladislav@gmail.com>
+Date:   Sun Feb 9 20:12:44 2025 +0400
+
+    [basic.scope.scope] Update the note about special cases (#7594)
+
+commit 8948fd9bd8f799d50fc9cbff34b349b9d59157f1
+Author: André Brand <andre.brand@mailbox.org>
+Date:   Sun Feb 9 17:18:12 2025 +0100
+
+    [temp.mem.enum] Remove instantiation in example [temp.inst] (#7558)
+
+    The example is inconsistent with [temp.inst]p3. Since the implicit instantiation
+    does not contribute to the point of [temp.mem.enum], the inconsistency
+    can be resolved by omitting the instantiation.
+
+commit 0d0ea5582082f85fa707c680634044209c2e343d
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Mon Nov 18 13:47:37 2024 +0000
+
+    [defns.argument] Mention braced-init-list
+
+commit 7566675c778f95ef966c4fea058a895def98e6d1
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Sun Feb 9 11:23:22 2025 -0500
+
+    [lex.phases] Use preprocessing token consistently (#7361)
+
+    Prior to converting preprocessing tokens to tokens in phase 7,
+    all tokens are strictly preprocessing tokens.
+
+commit b9f054b0cba3a36f9c8eff0c190f85996597dc3d
+Author: cor3ntin <corentinjabot@gmail.com>
+Date:   Mon Feb 10 07:47:58 2025 +0100
+
+    [std] Rename "non-type" to "constant" template parameter/argument (#7587)
+
+    Note that not all instances of "non-type" have been mechanically replaced,
+    as [dcl] and [diff] use the term to refer to anything that is not a type
+    in the context of lookup.
+
+commit 45eb50507a1b6477dea6106c3c26654b96feae4a
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Fri Jan 31 14:04:53 2025 -0500
+
+    [cmath.syn] Consolidate std namespaces
+
+    There is no ordering dependency between the two typedefs
+    in namespace std, the macros that follow, and teh next
+    opening of namespace std, so move the two typedefs to
+    avoid repeatedly opening an closing the namespace.
+
+    Note that we could have done this without moving
+    the typedefs as macros are not bound by namespaces,
+    but our convention very sensibly avoids confusing
+    readers by keeping macro definitions outside of
+    namespaces.
+
+commit 5eab5c6b456db2424b04becb791b23dbf4de356a
+Author: Axel Naumann <Axel.Naumann@cern.ch>
+Date:   Mon Jan 27 15:50:24 2025 +0100
+
+    [class.prop] add ref to actual layout spec in [expr.rel]
+
+commit 2f42a31044cc1ec8cf119b0fd595fdcc1d625c59
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Jan 23 11:37:15 2025 +0800
+
+    [util.smartptr.atomic.{shared,weak}] Fix wording for initialization
+
+    By using more conventional "value-initializes".
+
+commit 4e026ec784007b492eb3d904663cfdc4bf905fd3
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Feb 4 11:09:05 2025 +0000
+
+    [fs.op.funcs] Remove empty parens when referring to functions by name
+
+    As per the Specification Style Guidelines.
+
+    https://github.com/cplusplus/draft/wiki/Specification-Style-Guidelines#describing-function-calls
+
+commit 7f00883b8f65307b7e0df0ad2e55182d699d2804
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jan 13 22:33:34 2025 +0100
+
+    [xrefdelta] Restore cross-references since C++17
+
+commit 7fbdb79d99338d9aa91f382760ff6e1cb0353c71
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Oct 1 09:20:10 2024 -0400
+
+    [except.uncaught] Tidy the specification for uncaught exceptions
+
+    Several concurrent fixes.  First include the normative wording
+    that 'uncaught_exceptions' returns the number of uncaught
+    exceptions *on the current thread*.  This wording is present
+    in the core language.
+
+    Then move the core wording for when an exception is uncaught
+    directly into the text that talks about caught and uncaught
+    exceptions.  In the process, turn the reference to into a note,
+    so that there is only one normative specification.
+
+    Finally, remove [except.uncaught] as it is now empty.
+
+commit 70abf300ddbb1074cd16e9a5febe7f7c88bdff3d
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Nov 20 02:07:51 2024 +0100
+
+    [except.special.general] Complete the set of clause 17 references
+
+commit 888b0510da303e367f7421ac34607a158ddfc453
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Tue Jan 21 04:31:34 2025 -0500
+
+    [basic.pre] Defragment specification of names and entities
+
+    The current contents of [basic.pre] jump between specifying
+    different things.  This PR moves all the specification of
+    names to the front, followed by the specification of entities.
+
+    There are two main benefits: (1) the specification for when
+    two names are the same is a list of 4 rules that correspond
+    to the 4 things than can form a name --- the connection is
+    much clearer when the paragraphs are adjacent and the list
+    is sorted to the same order; (2) in this form, even though
+    all the words are the same, the reordering and merging of
+    paragraphs a fit on a single page.  The very last paragraph
+    was forced over a page-break in the original layout.
+
+commit 5be40a6b59527e82b13a29722c623635065759bf
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Tue Feb 11 21:42:20 2025 +0100
+
+    [expr.lval] Update cross reference for "invalid pointer value"
+
+commit 83530f54892686c9ba055434d02dfadc00bbb290
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 3 00:54:57 2023 +0800
+
+    [basic.extended.fp] Use "declared" for typedef-names
+
+commit 1542d983b3f690876720d69a44dff2c5574617b3
+Author: A. Jiang <de34@live.cn>
+Date:   Thu Aug 3 01:00:16 2023 +0800
+
+    [expr.{add,alignof,sizeof}] Use "typedef-name", avoid "defined"
+
+commit 152693b46648ea99493aecedbc8051aa2ab7542f
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Wed Feb 12 17:58:51 2025 +0000
+
+    [temp.param, temp.constr.normal] Use \dotsc for a non-code ellipsis (#7397)
+
+commit 930b8f97b0ab7bd9442bd0faf10f7302da5fc89a
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Wed Feb 12 19:22:47 2025 +0100
+
+    [diff.cpp03.library] Fix cross-reference to restriction on macro names
+
+commit 2cfc175a01d2bff1daf084d5c776017c5c049872
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Thu Feb 13 22:28:24 2025 +0000
+
+    [linalg.general] Remove extraneous dot (#7637)
+
+commit 422ded52d1876578f4eeb3bc30d583a193b94f42
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Fri Feb 14 19:13:02 2025 +0100
+
+    [conv.rank] Fix typo
+
+commit 10468bf63eee8926b84b76a10abb2a7d05b43c02
+Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com>
+Date:   Sun Feb 16 12:13:43 2025 +0100
+
+    [map.overview] Fix punctuation (#7677)
+
+commit a103bf3ea67a731189a8f1453d3e9ab88d589eba
+Author: Alisdair Meredith <alisdairm@me.com>
+Date:   Mon Feb 24 07:46:22 2025 -0500
+
+    [xrefdelta] Consolidate restored entries (#7631)
+
+    Several entries in the restored larger delta referred
+    to stable labels that have since moved again, or have been
+    removed.  This commit updates their cross-references
+    accordingly, or marks them as removed if appropriate.
+
+commit 9854e729ba5ade9a41bf047b6a5fe6f4bbe038e0
+Author: Hubert Tong <hstong@ca.ibm.com>
+Date:   Thu Feb 13 17:01:13 2025 -0500
+
+    [basic.types.general] Change ordering to "non-variant non-static"
+
+    The definition of literal type is the only place where "non-static
+    non-variant data member" is used as opposed to "non-variant non-static
+    data member".
+
+    Change to use the canonical ordering.
+
+commit c31b8f4111dfa9dd598220b9c6f8c1cf9d4a9b34
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Tue Feb 25 09:54:40 2025 +0000
+
+    [support.srcloc.cons] Update xref to [class.mem.general]
+
+    The cross-reference to [class.mem] was referring to a hanging paragraph
+    that was fixed by 2850139be6285ba10a64fb718125a80ca967c631 so we should
+    be referring to [class.mem.general] now.
+
+commit 912e5cab7565be0daa9c0c6d7c178600b3cd38e6
+Author: lprv <100177227+lprv@users.noreply.github.com>
+Date:   Sat Mar 15 20:23:43 2025 +0000
+
+    [functional.{syn,bind.place}] Use \vdots; add missing \placeholder (#7723)
+
+commit 0dda8468be890adf880afddc37e449cbc40607cb
+Author: A. Jiang <de34@live.cn>
+Date:   Sun Mar 16 04:26:10 2025 +0800
+
+    [expr.const] Change "value" to "result object" (of a prvalue) (#6267)
+
+commit 4552a92a01a2d1b032264cd6568a860a5244918b
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Nov 7 22:35:21 2021 +0100
+
+    [lex.string] Clarify size of string-literal
+
+commit ec10aaec4e6daac66b7b28426abcc765494194c9
+Author: Hubert Tong <hubert.reinterpretcast@gmail.com>
+Date:   Sat Mar 15 16:41:54 2025 -0400
+
+    [debugging.utility] Clarify wording in notes
+
+    The previous wording in the notes in `breakpoint` and `is_debugger_present`
+    read as statements of fact about the implementation-defined behaviour.
+    The statements are actually ones of intent.
+
+    The specific claim in `breakpoint` that the debugger resumes execution of the program
+    as if the function was not invoked is confusing considering that the debugger may effect
+    side-effects or cause execution to resume from a different evaluation.
+
+    Instead, the idea is that `breakpoint` is not responsible for causing the translation process
+    to make special accomodations for resumption of execution other than in cases
+    where the debugger was strictly used for observation only.
+
+    In `is_debugger_present`, the functionality ascribed to POSIX by the wording
+    ("ptrace") is not present in POSIX. Update to reference the LSB and to use
+    the corresponding terminology ("tracing process").
+
+    The wording implies a preference to return `true` in case it is unknown
+    whether a debugger is present. Add a critical "only" to fix that.
+
+commit 598910dc970bc0bc840ba797983e9bc131cd826e
+Author: A. Jiang <de34@live.cn>
+Date:   Tue Feb 25 07:51:44 2025 +0800
+
+    [ifstream.members] Remove mistakenly added `@`
+
+commit 4b5a0080230ed74d796a3ee909bdde66e2f2b395
+Author: A. Jiang <de34@live.cn>
+Date:   Wed Aug 7 18:45:41 2024 +0800
+
+    [func.wrap.func] Drop Lvalue-Callable
+
+    Replace its usages with `is_invocable_r_v` and remove an unnecessary index.
+
+commit f9847af90413adb0436aae9f6895b4a2e0e173ec
+Author: A. Jiang <de34@live.cn>
+Date:   Mon Feb 17 11:44:11 2025 +0800
+
+    [containers, strings, algorithms, re] Use \range where appropriate
+
+    Currently, there are several cases where `\tcode{[i, j)}` is used for
+    specifying left-closed right-open intervals, where `\range{i}{j}` is proper.
+
+    Co-authored-by: Eelis van der Weegen <eelis@eelis.net>
+
+commit 73699cf37d247a7c1f3a6879197c730a14666b90
+Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com>
+Date:   Fri Feb 26 02:55:52 2021 +0300
+
+    [class.cdtor] Only objects of scalar type can be accessed
+
+ + diff --git a/papers/n5009.md b/papers/n5009.md new file mode 100644 index 0000000000..2caf3f0571 --- /dev/null +++ b/papers/n5009.md @@ -0,0 +1,753 @@ +# N5009 Editors' Report -- Programming Languages -- C++ + +Date: 2025-03-15 + +Thomas Köppe (editor, Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor, Bright Side Computing, LLC) +Richard Smith (co-editor, Google Inc) + +Email: `cxxeditor@gmail.com` + +## Acknowledgements + +Thanks to all those who have +[submitted editorial issues](https://github.com/cplusplus/draft/wiki/How-to-submit-an-editorial-issue), +to those who have provided pull requests with fixes, +and to everyone who drafted motion applications. + +## New papers + + * [N5008](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5008.pdf) is the + current working draft for C++26. It replaces + [N5001](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/n5001.pdf). + * N5009 is this Editors' Report. + +## Motions incorporated into working draft + +### Notes on motions + +LWG Poll 2 was retracted. + +Library issue [LWG4189](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3615r0.html#4189), +adopted by LWG Poll 1 (P3615R0) had the effect of making most of the content of `` +free-standing by default, with the note that "[m]ost future additions to this header should +have no problem being freestanding, so that is the right default." Absent an explicit +opt-out, the new facilities from LWG Poll 14 +([P2846R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2846r6.html)), +`reserve_hint` and `approximately_sized_range`, are now free-standing as well. + +### Core working group polls + +CWG Poll 1. Accept as Defect Reports and apply the proposed resolutions of all issues in +[P3638R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3638r0.html) +(Core Language Working Group "ready" Issues for the February, 2025 meeting) to the C++ Working Paper. + +CWG Poll 2. Apply the changes in [P3542R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3542r0.html) +(Abolish the term "converting constructor") to the C++ Working Paper. + +CWG Poll 3. Apply the changes in [P3074R7](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3074r7.html) +(trivial unions (was `std::uninitialized`)) to the C++ Working Paper. + +CWG Poll 4. Apply the changes in [P1494R5](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1494r5.html) +(Partial program correctness) to the C++ Working Paper. + +CWG Poll 5. Apply the changes in [P2900R14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2900r14.pdf) +(Contracts for C++) to the C++ Working Paper. + +CWG Poll 6. Apply the changes in [P3475R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3475r2.pdf) +(Defang and deprecate `memory_order::consume`) to the C++ Working Paper. + +CWG Poll 7. Apply the changes in [P2841R7](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2841r7.pdf) +(Concept and variable-template template-parameters) to the C++ Working Paper. + +CWG Poll 8. Apply the changes in [P2786R13](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2786r13.html) +(Trivial Relocatability For C++26) to the C++ Working Paper. + +CWG Poll 9. Apply the changes in [P1967R14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1967r14.html) +(`#embed` - a simple, scannable preprocessor-based resource acquisition method) to the C++ Working Paper. + +### Library working group polls + +LWG Poll 1. Apply the changes for all Tentatively Ready issues in +[P3615R0](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3615r0.html) +(C++ Standard Library Ready Issues to be moved in Hagenberg, Feb. 2025) to the C++ working paper. + +LWG Poll 2 was retracted. + +LWG Poll 3. Apply the changes in [P3137R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3137r3.html) +(`views::to_input`) to the C++ working paper. + +LWG Poll 4. Apply the changes in [P0472R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0472r3.pdf) +(Put `std::monostate` in ``) to the C++ working paper. + +LWG Poll 5. Apply the changes in [P3349R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3349r1.html) +(Converting contiguous iterators to pointers) to the C++ working paper. + +LWG Poll 6. Apply the changes in [P3372R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3372r3.html) +(constexpr containers and adaptors) to the C++ working paper. + +LWG Poll 7. Apply the changes in [P3378R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3378r2.html) +(constexpr exception types) to the C++ working paper. + +LWG Poll 8. Apply the changes in [P3441R2](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3441r2.html) +(Rename `simd_split` to `simd_chunk`) to the C++ working paper. + +LWG Poll 9. Apply the changes in [P3287R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3287r3.pdf) +(Exploration of namespaces for `std::simd`) to the C++ working paper. + +LWG Poll 10. Apply the changes in [P2976R1](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2976r1.html) +(Freestanding Library: algorithm, numeric, and random) to the C++ working paper. + +LWG Poll 11. Apply the changes in [P3430R3](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3430r3.pdf) +(SIMD issues: explicit, unsequenced, identity-element position, and members of disabled SIMD) to the C++ working paper. + +LWG Poll 12. Apply the changes in [P2663R7](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2663r7.html) +(Interleaved complex values support in `std::simd`) to the C++ working paper. + +LWG Poll 13. Apply the changes in [P2933R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2933r4.html) +(Extend `` header function with overloads for `std::simd`) to the C++ working paper. + +LWG Poll 14. Apply the changes in [P2846R6](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2846r6.pdf) +(`reserve_hint`: Eagerly reserving memory for not-quite-sized lazy ranges) to the C++ working paper. + +LWG Poll 15. Apply the changes in [P3471R4](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3471r4.html) +(Standard Library Hardening) to the C++ working paper. + +LWG Poll 16. Apply the changes in [P0447R28](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0447r28.html) +(Introduction of `std::hive` to the standard library) to the C++ working paper. + +LWG Poll 17. Apply the changes in [P3019R14](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3019r14.pdf) +(`indirect` and `polymorphic`: Vocabulary Types for Composite Class Design) to the C++ working paper. + +## Editorial changes + +### Major editorial changes + +There have not been any major editorial changes. + +### Minor editorial changes + +A log of editorial fixes made to the working draft since N5001 is below. This +list excludes changes that do not affect the body text or only affect whitespace +or typeface. For a complete list including such changes (or for the actual +deltas applied by these changes), consult the +[draft sources on GitHub](https://github.com/cplusplus/draft/compare/n5001...n5008). + + commit f3676cb1550f1501236cc65c1dfa2dec957bbdf2 + Author: Mark Hoemmen + Date: Tue Dec 17 14:15:10 2024 -0700 + + [linalg.conj.conjugated] Remove inappropriate "expression-equivalent" wording (#7497) + + This phrase appears to be copy-pasted from elsewhere, but is not meaningful here. + + commit be0a25c9a2f2c1f498b0ff84a33c28adae41863e + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Dec 17 20:31:14 2024 +0100 + + [simd.alg] Fix range syntax + + commit a18040f05ff6a27e5c6425005ab1b21515ad952c + Author: Eisenwave + Date: Fri Nov 1 08:06:28 2024 +0100 + + [basic.compound] Update introduction + + commit 0131e015c09eca1901d0bfa46744a6c7ab31b00d + Author: Jonathan Wakely + Date: Tue Dec 17 21:21:42 2024 +0000 + + [linalg.helpers] Rename template parameter for poison pills + + This avoids reusing `T` which is also used for the type of the + subexpression E. + + Fixes #7494 + + commit 04169bac7059322ad8bf32e605a80e57ef30b922 + Author: Jens Maurer + Date: Tue Dec 17 22:51:01 2024 +0100 + + [inplace.vector.overview] Replace residual use of 'trivial type' + + commit 9272753d0ecbc1df9d08178793795f06b623a451 + Author: Hewill Kang + Date: Tue Nov 19 16:41:00 2024 +0800 + + [flat.map.defn, flat.set.defn] Avoid naming the from_range_t tag + + commit 85de0af0e0af416f7e73ac096254641c31bf11cc + Author: Jens Maurer + Date: Tue Dec 17 23:19:21 2024 +0100 + + [basic.fundamental] Ensure consistency with [conv.ptr] + + commit 561a4d8cde9e434fe206b88489e95b0e5271f469 + Author: Mark Hoemmen + Date: Thu Dec 19 14:35:50 2024 -0700 + + [bibliography] Fix spelling and formatting (#7507) + + Fix spelling of one author's name. Add missing commas + and extra spaces after a period ending authors' abbreviated + first or middle names. + + commit 82153790d8904ea82bc57edc8885b02925e85e93 + Author: Mark Hoemmen + Date: Thu Dec 19 14:41:02 2024 -0700 + + [simd.general, bibliography] Add SIMD acronym explanation and bibliographic reference (#7504) + + To the existing Note at the beginning of [simd.general], + add text that unpacks the SIMD acronym and refers to Flynn 1966. + + Add bibliography entry for Flynn 1966, the paper that introduced what + later became known as "Flynn's Taxonomy." This classifies parallel + computer hardware as SISD, SIMD, MISD, or MIMD. + + commit e1a368bc157f824cee7702e87a2cca1951e60f98 + Author: Jonathan Wakely + Date: Thu Dec 19 11:02:38 2024 +0000 + + [mdspan.sub] Change to "unit-stride slice for mapping" + + This was the wording requested by LWG and approved in P3355R2, but I + mistakenly put P3355R1 in the straw polls. + + commit 2d3ac367d8605d7172151726e873daea295a573a + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Dec 20 10:15:46 2024 +0100 + + [diff.cpp03.library] Correct \effect to \change + + - Correct \effect to \change. + - Add period at end. + - Add \tcode for swap. + + commit a2429a5944b71e3563dc09730426af43fb4b53e1 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Dec 26 01:37:34 2024 +0000 + + [class.expl.init] Fix incorrect note + + commit 1411cf56fcb41f9fd000406185f17ef47235d26a + Author: Bronek Kozicki + Date: Wed Jan 1 17:00:14 2025 +0000 + + [expected.bad.void] Fix syntax error in bad_expected_access (#7529) + + Introduced by commit 8c997445c176c81a334e77f9344b91abc72b2772 + + commit a137940ac9c807e3ea809c3ff0b3a863795bf742 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jan 1 22:18:37 2025 +0100 + + [filebuf.members,fs.path.req] Fix indefinite article (#7530) + + commit d2b48043fcc219b2a141af39dae2eb85934c0847 + Author: Jens Maurer + Date: Thu Jan 2 10:49:14 2025 +0100 + + [expr.const] Properly merge P2686R5 + + P2686R5 (applied by commit e220906b71df01f09fe60921e8fac39b80558f78) + accidentally reverted a change considering erroneous values made by + P2795R5. + + commit 22937c04da139226c186973eda2cdb79df640b5b + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Thu Jan 2 15:14:06 2025 +0100 + + [format.arg] Fix indefinite article (#7536) + + commit 75af9f7f8cd816e1908eb2a3917eb7749c11471a + Author: Alisdair Meredith + Date: Sat Jan 4 02:18:53 2025 +0700 + + [tuple.helper] Remove redundant 'public' in base-specifier of struct (#7539) + + commit 6ff55d533f72b7222e022513dcb80982f4e887a0 + Author: Jens Maurer + Date: Mon Dec 30 16:34:49 2024 +0100 + + [lex.icon,depr.locale.category] Remove duplicate 'table' in front of table references + + commit 70df8aa8f4a30a7d54a604cbe01ebe13f5973043 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jan 8 13:51:13 2025 +0100 + + [linalg.algs.blas2.gemv] Fix singular/plural mismatch (#7546) + + commit 0164098f821ae002469c6f23cd03fc66a0a2f7ca + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Jan 9 10:01:36 2025 +0000 + + [basic.def.odr] Fix typo and reference the correct subclause + + commit 2734ddeb05115f3fddf09c9c15b843083575e9df + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Jan 10 13:13:28 2025 +0100 + + [exec.async.ops] Remove stray closing parenthesis (#7555) + + commit 77171de904e6008f31717615d5baabf604baeea8 + Author: S. B. Tam + Date: Fri Jan 10 23:05:58 2025 +0800 + + [locale.time.put.members] Remove incorrect footnote (#7553) + + commit 6ecd1be67c71001db37883ee45b76cc66ef4101f + Author: Jens Maurer + Date: Mon Jan 13 22:34:47 2025 +0100 + + [exec.getcomplsigs] Add missing LaTeX escaping of braces (#7541) + + commit 1b1914ed868b0b29e63d0d1e4b872daf07b50740 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Jan 14 14:31:09 2025 +0100 + + [simd.traits] Remove stray closing parenthesis (#7563) + + commit 0ac6f9d7e94a70b48457f289bcbeb069a4662c28 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jan 15 14:10:57 2025 +0100 + + [locale.moneypunct.general] Insert period at end (#7564) + + commit 96fad4cf7ff48c8a4ae5442580d55008fb56ca43 + Author: Alisdair Meredith + Date: Wed Jan 15 10:06:49 2025 -0500 + + [inplace.vector.overview] Remove spurious semicolon closing namespace std (#7566) + + commit 1c398ffc71845163ca50b712f1edd9e1b2a87772 + Author: Jonathan Wakely + Date: Fri Jan 17 17:11:02 2025 +0000 + + [type.info] Remove comments explaining deleted members + + The standard is not a tutorial. + + commit 569e2a38cf1aa6d185b4c4d1817d9496ebd087e5 + Author: Jens Maurer + Date: Sat Jan 18 09:18:53 2025 +0100 + + [exec.snd.expos] Move write-env paragraph into itemdescr (#7571) + + commit 93aa7cb89b375280cb2d5f385fb0c5a5874e9243 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sat Jan 18 23:32:20 2025 +0100 + + [re.err,re.alg.match,re.tokiter.incr] Add period at end for consistency (#7574) + + commit ce5fd62b98d822228f46319f4516e34c492fa257 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jan 22 16:15:57 2025 +0100 + + [string.view.io,string.insert] Add period at end of "Returns" (#7579) + + commit 5c4823a05b83a67f7550fdcc1476f8000c29514c + Author: A. Jiang + Date: Thu Jan 23 11:31:05 2025 +0800 + + [expr.const] Re-apply CWG2909 + + commit db563eecdfb63cb24f10afb30f001a0bc6213997 + Author: Alisdair Meredith + Date: Wed Jan 15 07:59:51 2025 -0500 + + [lex.phases] Update implementation defined text + + Since C++23 we no longer have physical source files, but rather + input files. Update the two implementation-defined references + to the mapping from input file to translation character set + using the same phrasing so that they provide the same entry + in the index of implementation-defined behavior, just as they + did in C++20, before getting out of sync when the terminology + changed. + + commit a39cca2e9c009766da1e205daf5d7bf8cbdccaa3 + Author: Jonathan Wakely + Date: Thu Jan 23 07:28:40 2025 -0500 + + [linalg.conj.conjugated] Rearrange to match P3050R3 (#7506) + + This was the wording requested by LWG and approved in P3050R3, but I + mistakenly put P3050R2 in the straw polls. + + commit 6583c4ac9c2d3bbfb7daac0c79c902a30417c50f + Author: cor3ntin + Date: Sat Jan 25 14:11:30 2025 +0100 + + [std] Use template-parameter and template parameter more consistently (#7460) + + Try to use template-parameter only when we refer to a + grammar construct, and to 'template parameter' everywhere else. + + Adopt the same logic to template-argument/template argument. + + This change might not be exhaustive. + + The aim is to editorially adopt some of the wording changes + made in P2841R5 to ease its review in core. + + commit 696dcd809ceed3fc10502161963f8ce13505ec1a + Author: Jens Maurer + Date: Sat Jan 25 21:25:32 2025 +0100 + + [format.string.general,format.formatter.spec] Fix unparenthesized cross-references + + commit 47cf5a67357543b0d45d0072f42fdd29fa028cca + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Wed Jan 29 09:29:54 2025 +0100 + + [alg.rand.generate] Add period at end of "Returns" (#7595) + + commit b2b266e7b67eb583c50c34a9eceffe44f72ea2f6 + Author: Ivan Lazarić + Date: Sat Feb 1 09:56:42 2025 +0100 + + [temp.res.general] Fix nesting for \terminal{\opt{...}} (#7599) + + commit d51e6bedd991d55b7f7fb7f41e1f08083cfd1b1d + Author: Eric Niebler + Date: Mon Feb 3 12:05:48 2025 -0800 + + [range.view] Change incorrect uses of "which" to "that" (#7606) + + commit 1d49b05d1b48a2daa2a88d854e2367e6648c3cb6 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Mon Feb 3 21:14:45 2025 +0100 + + [tuple.assign] Remove incorrect comma at end (#7609) + + commit 2e1b856b6187fe9a5c74782948982eefd128ecbf + Author: Alisdair Meredith + Date: Mon Feb 3 16:17:48 2025 -0500 + + [diff.cpp.library] Add new C23 headers to list of new headers + + commit cae9b2a645d5bb91caffc061325f107605e85a0d + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Tue Feb 4 09:30:49 2025 +0100 + + [container.alloc.reqmts,sequence.reqmts] Add period at end (#7614) + + commit 003506a2779c519d4929cce75c7adeb1b7a76955 + Author: Alisdair Meredith + Date: Wed Jan 1 18:45:19 2025 +0700 + + [macros] Add LaTeX macros to index library macros + + The immediate idea is to support using the new macros directly + in header synopses when defining each library macro. This will + ensure that no macros are accidentally not indexed. + + A follow-up plan is that this separation of library macros will + make it easier to create a separate index of macros, or apply + other macro-specific renderings, in the future. To this end, + all indexed uses of a macro, not just those in header files, + should be replaced by use of these new macros. Similarly, + these LaTeX macros can be used in-place in regular text to + index cross-references where standard library macros are used + throughout the standard. + + commit d7618b4d20a24b37677b92c2fbd80dcee4565bc3 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Feb 7 09:37:37 2025 +0100 + + [diff.lex] Add period at end (#7618) + + commit 040ff41df1d0e0e4d31bd6c76f084fbc84239e7f + Author: Jonathan Wakely + Date: Sat Feb 8 07:56:45 2025 +0000 + + [fs.op.current.path] Remove note discussing design choices (#7620) + + commit dfdc64cbdc842f0f7d2a060440ea907b41ce78e6 + Author: Vlad Serebrennikov + Date: Sun Feb 9 20:12:44 2025 +0400 + + [basic.scope.scope] Update the note about special cases (#7594) + + commit 8948fd9bd8f799d50fc9cbff34b349b9d59157f1 + Author: André Brand + Date: Sun Feb 9 17:18:12 2025 +0100 + + [temp.mem.enum] Remove instantiation in example [temp.inst] (#7558) + + The example is inconsistent with [temp.inst]p3. Since the implicit instantiation + does not contribute to the point of [temp.mem.enum], the inconsistency + can be resolved by omitting the instantiation. + + commit 0d0ea5582082f85fa707c680634044209c2e343d + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Mon Nov 18 13:47:37 2024 +0000 + + [defns.argument] Mention braced-init-list + + commit 7566675c778f95ef966c4fea058a895def98e6d1 + Author: Alisdair Meredith + Date: Sun Feb 9 11:23:22 2025 -0500 + + [lex.phases] Use preprocessing token consistently (#7361) + + Prior to converting preprocessing tokens to tokens in phase 7, + all tokens are strictly preprocessing tokens. + + commit b9f054b0cba3a36f9c8eff0c190f85996597dc3d + Author: cor3ntin + Date: Mon Feb 10 07:47:58 2025 +0100 + + [std] Rename "non-type" to "constant" template parameter/argument (#7587) + + Note that not all instances of "non-type" have been mechanically replaced, + as [dcl] and [diff] use the term to refer to anything that is not a type + in the context of lookup. + + commit 45eb50507a1b6477dea6106c3c26654b96feae4a + Author: Alisdair Meredith + Date: Fri Jan 31 14:04:53 2025 -0500 + + [cmath.syn] Consolidate std namespaces + + There is no ordering dependency between the two typedefs + in namespace std, the macros that follow, and teh next + opening of namespace std, so move the two typedefs to + avoid repeatedly opening an closing the namespace. + + Note that we could have done this without moving + the typedefs as macros are not bound by namespaces, + but our convention very sensibly avoids confusing + readers by keeping macro definitions outside of + namespaces. + + commit 5eab5c6b456db2424b04becb791b23dbf4de356a + Author: Axel Naumann + Date: Mon Jan 27 15:50:24 2025 +0100 + + [class.prop] add ref to actual layout spec in [expr.rel] + + commit 2f42a31044cc1ec8cf119b0fd595fdcc1d625c59 + Author: A. Jiang + Date: Thu Jan 23 11:37:15 2025 +0800 + + [util.smartptr.atomic.{shared,weak}] Fix wording for initialization + + By using more conventional "value-initializes". + + commit 4e026ec784007b492eb3d904663cfdc4bf905fd3 + Author: Jonathan Wakely + Date: Tue Feb 4 11:09:05 2025 +0000 + + [fs.op.funcs] Remove empty parens when referring to functions by name + + As per the Specification Style Guidelines. + + https://github.com/cplusplus/draft/wiki/Specification-Style-Guidelines#describing-function-calls + + commit 7f00883b8f65307b7e0df0ad2e55182d699d2804 + Author: Jens Maurer + Date: Mon Jan 13 22:33:34 2025 +0100 + + [xrefdelta] Restore cross-references since C++17 + + commit 7fbdb79d99338d9aa91f382760ff6e1cb0353c71 + Author: Alisdair Meredith + Date: Tue Oct 1 09:20:10 2024 -0400 + + [except.uncaught] Tidy the specification for uncaught exceptions + + Several concurrent fixes. First include the normative wording + that 'uncaught_exceptions' returns the number of uncaught + exceptions *on the current thread*. This wording is present + in the core language. + + Then move the core wording for when an exception is uncaught + directly into the text that talks about caught and uncaught + exceptions. In the process, turn the reference to into a note, + so that there is only one normative specification. + + Finally, remove [except.uncaught] as it is now empty. + + commit 70abf300ddbb1074cd16e9a5febe7f7c88bdff3d + Author: Alisdair Meredith + Date: Wed Nov 20 02:07:51 2024 +0100 + + [except.special.general] Complete the set of clause 17 references + + commit 888b0510da303e367f7421ac34607a158ddfc453 + Author: Alisdair Meredith + Date: Tue Jan 21 04:31:34 2025 -0500 + + [basic.pre] Defragment specification of names and entities + + The current contents of [basic.pre] jump between specifying + different things. This PR moves all the specification of + names to the front, followed by the specification of entities. + + There are two main benefits: (1) the specification for when + two names are the same is a list of 4 rules that correspond + to the 4 things than can form a name --- the connection is + much clearer when the paragraphs are adjacent and the list + is sorted to the same order; (2) in this form, even though + all the words are the same, the reordering and merging of + paragraphs a fit on a single page. The very last paragraph + was forced over a page-break in the original layout. + + commit 5be40a6b59527e82b13a29722c623635065759bf + Author: Thomas Köppe + Date: Tue Feb 11 21:42:20 2025 +0100 + + [expr.lval] Update cross reference for "invalid pointer value" + + commit 83530f54892686c9ba055434d02dfadc00bbb290 + Author: A. Jiang + Date: Thu Aug 3 00:54:57 2023 +0800 + + [basic.extended.fp] Use "declared" for typedef-names + + commit 1542d983b3f690876720d69a44dff2c5574617b3 + Author: A. Jiang + Date: Thu Aug 3 01:00:16 2023 +0800 + + [expr.{add,alignof,sizeof}] Use "typedef-name", avoid "defined" + + commit 152693b46648ea99493aecedbc8051aa2ab7542f + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Wed Feb 12 17:58:51 2025 +0000 + + [temp.param, temp.constr.normal] Use \dotsc for a non-code ellipsis (#7397) + + commit 930b8f97b0ab7bd9442bd0faf10f7302da5fc89a + Author: Alisdair Meredith + Date: Wed Feb 12 19:22:47 2025 +0100 + + [diff.cpp03.library] Fix cross-reference to restriction on macro names + + commit 2cfc175a01d2bff1daf084d5c776017c5c049872 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Thu Feb 13 22:28:24 2025 +0000 + + [linalg.general] Remove extraneous dot (#7637) + + commit 422ded52d1876578f4eeb3bc30d583a193b94f42 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Fri Feb 14 19:13:02 2025 +0100 + + [conv.rank] Fix typo + + commit 10468bf63eee8926b84b76a10abb2a7d05b43c02 + Author: Andreas Krug <153394595+Andreas-Krug@users.noreply.github.com> + Date: Sun Feb 16 12:13:43 2025 +0100 + + [map.overview] Fix punctuation (#7677) + + commit a103bf3ea67a731189a8f1453d3e9ab88d589eba + Author: Alisdair Meredith + Date: Mon Feb 24 07:46:22 2025 -0500 + + [xrefdelta] Consolidate restored entries (#7631) + + Several entries in the restored larger delta referred + to stable labels that have since moved again, or have been + removed. This commit updates their cross-references + accordingly, or marks them as removed if appropriate. + + commit 9854e729ba5ade9a41bf047b6a5fe6f4bbe038e0 + Author: Hubert Tong + Date: Thu Feb 13 17:01:13 2025 -0500 + + [basic.types.general] Change ordering to "non-variant non-static" + + The definition of literal type is the only place where "non-static + non-variant data member" is used as opposed to "non-variant non-static + data member". + + Change to use the canonical ordering. + + commit c31b8f4111dfa9dd598220b9c6f8c1cf9d4a9b34 + Author: Jonathan Wakely + Date: Tue Feb 25 09:54:40 2025 +0000 + + [support.srcloc.cons] Update xref to [class.mem.general] + + The cross-reference to [class.mem] was referring to a hanging paragraph + that was fixed by 2850139be6285ba10a64fb718125a80ca967c631 so we should + be referring to [class.mem.general] now. + + commit 912e5cab7565be0daa9c0c6d7c178600b3cd38e6 + Author: lprv <100177227+lprv@users.noreply.github.com> + Date: Sat Mar 15 20:23:43 2025 +0000 + + [functional.{syn,bind.place}] Use \vdots; add missing \placeholder (#7723) + + commit 0dda8468be890adf880afddc37e449cbc40607cb + Author: A. Jiang + Date: Sun Mar 16 04:26:10 2025 +0800 + + [expr.const] Change "value" to "result object" (of a prvalue) (#6267) + + commit 4552a92a01a2d1b032264cd6568a860a5244918b + Author: Jens Maurer + Date: Sun Nov 7 22:35:21 2021 +0100 + + [lex.string] Clarify size of string-literal + + commit ec10aaec4e6daac66b7b28426abcc765494194c9 + Author: Hubert Tong + Date: Sat Mar 15 16:41:54 2025 -0400 + + [debugging.utility] Clarify wording in notes + + The previous wording in the notes in `breakpoint` and `is_debugger_present` + read as statements of fact about the implementation-defined behaviour. + The statements are actually ones of intent. + + The specific claim in `breakpoint` that the debugger resumes execution of the program + as if the function was not invoked is confusing considering that the debugger may effect + side-effects or cause execution to resume from a different evaluation. + + Instead, the idea is that `breakpoint` is not responsible for causing the translation process + to make special accomodations for resumption of execution other than in cases + where the debugger was strictly used for observation only. + + In `is_debugger_present`, the functionality ascribed to POSIX by the wording + ("ptrace") is not present in POSIX. Update to reference the LSB and to use + the corresponding terminology ("tracing process"). + + The wording implies a preference to return `true` in case it is unknown + whether a debugger is present. Add a critical "only" to fix that. + + commit 598910dc970bc0bc840ba797983e9bc131cd826e + Author: A. Jiang + Date: Tue Feb 25 07:51:44 2025 +0800 + + [ifstream.members] Remove mistakenly added `@` + + commit 4b5a0080230ed74d796a3ee909bdde66e2f2b395 + Author: A. Jiang + Date: Wed Aug 7 18:45:41 2024 +0800 + + [func.wrap.func] Drop Lvalue-Callable + + Replace its usages with `is_invocable_r_v` and remove an unnecessary index. + + commit f9847af90413adb0436aae9f6895b4a2e0e173ec + Author: A. Jiang + Date: Mon Feb 17 11:44:11 2025 +0800 + + [containers, strings, algorithms, re] Use \range where appropriate + + Currently, there are several cases where `\tcode{[i, j)}` is used for + specifying left-closed right-open intervals, where `\range{i}{j}` is proper. + + Co-authored-by: Eelis van der Weegen + + commit 73699cf37d247a7c1f3a6879197c730a14666b90 + Author: languagelawyer <38548419+languagelawyer@users.noreply.github.com> + Date: Fri Feb 26 02:55:52 2021 +0300 + + [class.cdtor] Only objects of scalar type can be accessed + diff --git a/papers/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/wd-index.md b/papers/wd-index.md new file mode 100644 index 0000000000..8b987792af --- /dev/null +++ b/papers/wd-index.md @@ -0,0 +1,59 @@ +# Index of C++ Working Drafts + + * [N3337](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf) 2012-01 C++ Working Draft + * [N3690](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf) 2013-05 C++ Working Draft + * [N3691](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3691.pdf) 2013-05 C++ Working Draft + * [N3936](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3936.pdf) 2014-03 C++ Working Draft + * [N4140](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4140.pdf) 2014-10 C++ Working Draft + * [N4141](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4141.pdf) 2014-09 C++ Working Draft + * [N4296](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf) 2014-11 C++ Working Draft + * [N4431](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4431.pdf) 2015-04 C++ Working Draft + * [N4527](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4527.pdf) 2015-05 C++ Working Draft + * [N4567](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf) 2015-11 C++ Working Draft + * [N4582](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4582.pdf) 2016-03 C++ Working Draft + * [N4594](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4594.pdf) 2016-05 C++ Working Draft + * [N4604](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4604.pdf) 2016-07 C++ Working Draft + * [N4606](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf) 2016-07 C++ Working Draft + * [N4618](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4618.pdf) 2016-11 C++ Working Draft + * [N4640](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4640.pdf) 2017-02 C++ Working Draft + * [N4659](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf) 2017-03 C++ Working Draft + * [N4687](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4687.pdf) 2017-07 C++ Working Draft + * [N4700](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4700.pdf) 2017-10 C++ Working Draft + * [N4713](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf) 2017-11 C++ Working Draft + * [N4727](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4727.pdf) 2018-02 C++ Working Draft + * [N4741](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4741.pdf) 2018-04 C++ Working Draft + * [N4750](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4750.pdf) 2018-05 C++ Working Draft + * [N4762](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4762.pdf) 2018-07 C++ Working Draft + * [N4778](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4778.pdf) 2018-10 C++ Working Draft + * [N4791](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4791.pdf) 2018-12 C++ Working Draft + * [N4800](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4800.pdf) 2019-01 C++ Working Draft + * [N4810](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4810.pdf) 2019-03 C++ Working Draft + * [N4820](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4820.pdf) 2019-06 C++ Working Draft + * [N4828](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4828.pdf) 2019-08 C++ Working Draft + * [N4830](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4830.pdf) 2019-08 C++ Working Draft + * [N4835](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4835.pdf) 2019-10 C++ Working Draft + * [N4842](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4842.pdf) 2019-11 C++ Working Draft + * [N4849](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdf) 2020-01 C++ Working Draft + * [N4861](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4861.pdf) 2020-04 C++ Working Draft + * [N4868](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4868.pdf) 2020-10 C++ Working Draft + * [N4878](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4878.pdf) 2020-12 C++ Working Draft + * [N4885](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4885.pdf) 2021-03 C++ Working Draft + * [N4892](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4892.pdf) 2021-06 C++ Working Draft + * [N4901](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4901.pdf) 2021-10 C++ Working Draft + * [N4910](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf) 2022-03 C++ Working Draft + * [N4917](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4917.pdf) 2022-07 C++ Working Draft + * [N4928](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4928.pdf) 2022-11 C++ Working Draft + * [N4944](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4944.pdf) 2023-02 C++ Working Draft + * [N4950](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4950.pdf) 2023-05 C++ Working Draft + * [N4958](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4958.pdf) 2023-08 C++ Working Draft + * [N4964](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4964.pdf) 2023-10 C++ Working Draft + * [N4971](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4971.pdf) 2023-12 C++ Working Draft + * [N4981](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4981.pdf) 2024-03 C++ Working Draft + * [N4986](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4986.pdf) 2024-06 C++ Working Draft + * [N4988](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4988.pdf) 2024-08 C++ Working Draft + * [N4993](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n4993.pdf) 2024-10 C++ Working Draft + * [N5001](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/n5001.pdf) 2024-12 C++ Working Draft + * [N5008](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5008.pdf) 2025-03 C++ Working Draft + * [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 diff --git a/source/.gitattributes b/source/.gitattributes new file mode 100644 index 0000000000..ee114b3eae --- /dev/null +++ b/source/.gitattributes @@ -0,0 +1 @@ +*.tex diff=c++draft diff --git a/source/Makefile b/source/Makefile index 03127fb5a9..25fdcf505c 100644 --- a/source/Makefile +++ b/source/Makefile @@ -1,53 +1,41 @@ -### -*- mode: makefile-gmake -*- +FIGURES=$(patsubst %.dot,%.pdf,$(wildcard assets/*.dot)) +EXAMPLES=$(patsubst %.tex,%.pdf,$(wildcard assets/*.tex)) -# Note: If building on Mac OS X, and if you use MacPorts, the following ports -# should be installed: -# -# texlive-latex -# texlive-plain-extra -# texlive-latex-recommended -# texlive-latex-extra -# texlive-fonts-recommended -# texlive-fonts-extra -# texlive-generic-recommended - -FIGURES = $(patsubst %.dot,%.pdf,$(wildcard *.dot)) - -STDPDF = pdflatex std | grep -v "^Overfull" - -default: rebuild +default: full clean: - rm -f *.aux std.pdf *.idx *.ilg *.ind *.log *.lot *.lof *.tmp *.out + rm -f *.aux std.pdf std-gram.ext *.idx *.ilg *.ind *.log *.lot *.lof *.tmp *.out *.glo *.gls *.fls *.fdb* *.toc *.xtr refresh: - $(STDPDF) + pdflatex std -rebuild: - $(STDPDF) - $(STDPDF) - $(STDPDF) +full: + latexmk -pdf std -full: $(FIGURES) grammar xrefs reindex +quiet: + latexmk -pdf std -e '$$max_repeat = 1;' -silent || ( rm std.pdf; latexmk -pdf std -e '$$max_repeat = 4;' ) %.pdf: %.dot - dot -o $@ -Tpdf $< - -grammar: - sh ../tools/makegram - -xrefs: - sh ../tools/makexref - -reindex: - $(STDPDF) - $(STDPDF) - $(STDPDF) - makeindex generalindex - makeindex libraryindex - makeindex grammarindex - makeindex impldefindex - $(STDPDF) - $(STDPDF) - -### Makefile ends here + dot -o $@ -Tpdf $< -Nfontname=NewComputerModernSans10 + +clean-figures: + rm -f $(FIGURES) + +figures: $(FIGURES) + +%.pdf: %.tex + lualatex -output-directory assets $< + +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/access.tex b/source/access.tex deleted file mode 100644 index 816ae62445..0000000000 --- a/source/access.tex +++ /dev/null @@ -1,1018 +0,0 @@ -%!TEX root = std.tex -\rSec0[class.access]{Member access control}% -\indextext{access control|(} - -\indextext{protection|see{access control}} -\indextext{\idxcode{private}|see{access control, \tcode{private}}} -\indextext{\idxcode{protected}|see{access control, \tcode{protected}}} -\indextext{\idxcode{public}|see{access control, \tcode{public}}} - -\pnum -A member of a class can be -\begin{itemize} -\item -\indextext{access control!\idxcode{private}}% -\tcode{private}; -that is, its name can be used only by members and friends -of the class in which it is declared. -\item -\indextext{access control!\idxcode{protected}}% -\tcode{protected}; -that is, its name can be used only by members and friends -of the class in which it is declared, by classes derived from that class, and by their -friends (see~\ref{class.protected}). -\item -\indextext{access control!\idxcode{public}}% -\tcode{public}; -that is, its name can be used anywhere without access restriction. -\end{itemize} - -\pnum -A member of a class can also access all the names to which the class has access. -A local class of a member function may access -the same names that the member function itself may access.\footnote{Access -permissions are thus transitive and cumulative to nested -and local classes.} - -\pnum -\indextext{access control!member name}% -\indextext{default access control|see{access control, default}}% -\indextext{access control!default}% -Members of a class defined with the keyword -\tcode{class} -are -\tcode{private} -by default. -Members of a class defined with the keywords -\tcode{struct} -or -\tcode{union} -are -\tcode{public} -by default. -\enterexample - -\begin{codeblock} -class X { - int a; // \tcode{X::a} is private by default -}; - -struct S { - int a; // \tcode{S::a} is public by default -}; -\end{codeblock} -\exitexample - -\pnum -Access control is applied uniformly to all names, whether the names are -referred to from declarations or expressions. -\enternote -Access control applies to names nominated by -\tcode{friend} -declarations~(\ref{class.friend}) and -\grammarterm{using-declaration}{s}~(\ref{namespace.udecl}). -\exitnote -In the case of overloaded function names, access control is applied to -the function selected by overload resolution. -\enternote -Because access control applies to names, if access control is applied to a -typedef name, only the accessibility of the typedef name itself is considered. -The accessibility of the entity referred to by the typedef is not considered. -For example, - -\begin{codeblock} -class A { - class B { }; -public: - typedef B BB; -}; - -void f() { - A::BB x; // OK, typedef name \tcode{A::BB} is public - A::B y; // access error, \tcode{A::B} is private -} -\end{codeblock} -\exitnote - -\pnum -It should be noted that it is -\term{access} -to members and base classes that is controlled, not their -\term{visibility}. -Names of members are still visible, and implicit conversions to base -classes are still considered, when those members and base classes are -inaccessible. -The interpretation of a given construct is -established without regard to access control. -If the interpretation -established makes use of inaccessible member names or base classes, -the construct is ill-formed. - -\pnum -All access controls in Clause~\ref{class.access} affect the ability to access a class member -name from the declaration of a particular -entity, including parts of the declaration preceding the name of the entity -being declared and, if the entity is a class, the definitions of members of -the class appearing outside the class's \grammarterm{member-specification}{.} -\enternote this access also applies to implicit references to constructors, -conversion functions, and destructors. \exitnote -\enterexample - -\begin{codeblock} -class A { - typedef int I; // private member - I f(); - friend I g(I); - static I x; - template struct Q; - template friend struct R; -protected: - struct B { }; -}; - -A::I A::f() { return 0; } -A::I g(A::I p = A::x); -A::I g(A::I p) { return 0; } -A::I A::x = 0; -template struct A::Q { }; -template struct R { }; - -struct D: A::B, A { }; -\end{codeblock} - -\pnum -Here, all the uses of -\tcode{A::I} -are well-formed because -\tcode{A::f}, -\tcode{A::x}, and \tcode{A::Q} -are members of class -\tcode{A} -and -\tcode{g} -and \tcode{R} are friends of class -\tcode{A}. -This implies, for example, that access checking on the first use of -\tcode{A::I} -must be deferred until it is determined that this use of -\tcode{A::I} -is as the return type of a member of class -\tcode{A}. -Similarly, the use of \tcode{A::B} as a -\grammarterm{base-specifier} is well-formed because \tcode{D} -is derived from \tcode{A}, so checking of \grammarterm{base-specifier}{s} -must be deferred until the entire \grammarterm{base-specifier-list} has been seen. -\exitexample - -\pnum -\indextext{argument!access checking~and default}% -\indextext{access control!default argument}% -The names in a default argument~(\ref{dcl.fct.default}) are -bound at the point of declaration, and access is checked at that -point rather than at any points of use of the default argument. -Access checking for default arguments in function templates and in -member functions of class templates is performed as described in~\ref{temp.inst}. - -\pnum -The names in a default \grammarterm{template-argument}~(\ref{temp.param}) -have their access checked in the context in which they appear rather than at any -points of use of the default \grammarterm{template-argument}. \enterexample -\begin{codeblock} -class B { }; -template class C { -protected: - typedef T TT; -}; - -template -class D : public U { }; - -D >* d; // access error, C::TT is protected -\end{codeblock} -\exitexample - -\rSec1[class.access.spec]{Access specifiers}% -\indextext{access~specifier} - -\pnum -Member declarations can be labeled by an -\grammarterm{access-specifier} -(Clause~\ref{class.derived}): - -\begin{ncbnftab} -access-specifier \terminal{:} member-specification\opt -\end{ncbnftab} - -An -\grammarterm{access-specifier} -specifies the access rules for members following it -until the end of the class or until another -\grammarterm{access-specifier} -is encountered. -\enterexample - -\begin{codeblock} -class X { - int a; // \tcode{X::a} is private by default: \tcode{class} used -public: - int b; // \tcode{X::b} is public - int c; // \tcode{X::c} is public -}; -\end{codeblock} -\exitexample - -\pnum -Any number of access specifiers is allowed and no particular order is required. -\enterexample - -\begin{codeblock} -struct S { - int a; // \tcode{S::a} is public by default: \tcode{struct} used -protected: - int b; // \tcode{S::b} is protected -private: - int c; // \tcode{S::c} is private -public: - int d; // \tcode{S::d} is public -}; -\end{codeblock} -\exitexample - -\pnum -\enternote The effect of access control on the order of allocation -of data members is described in~\ref{class.mem}.\exitnote - -\pnum -When a member is redeclared within its class definition, -the access specified at its redeclaration shall -be the same as at its initial declaration. -\enterexample - -\begin{codeblock} -struct S { - class A; - enum E : int; -private: - class A { }; // error: cannot change access - enum E: int { e0 }; // error: cannot change access -}; -\end{codeblock} -\exitexample - -\pnum -\enternote -In a derived class, the lookup of a base class name will find the -injected-class-name instead of the name of the base class in the scope -in which it was declared. The injected-class-name might be less accessible -than the name of the base class in the scope in which it was declared. -\exitnote - -\enterexample -\begin{codeblock} -class A { }; -class B : private A { }; -class C : public B { - A* p; // error: injected-class-name \tcode{A} is inaccessible - ::A* q; // OK -}; -\end{codeblock} -\exitexample - -\rSec1[class.access.base]{Accessibility of base classes and base class members}% -\indextext{access control!base~class}% -\indextext{access~specifier}% -\indextext{base~class!\idxcode{private}}% -\indextext{base~class!\idxcode{protected}}% -\indextext{base~class!\idxcode{public}} - -\pnum -If a class is declared to be a base class (Clause~\ref{class.derived}) for another class using the -\tcode{public} -access specifier, the -\tcode{public} -members of the base class are accessible as -\tcode{public} -members of the derived class and -\tcode{protected} -members of the base class are accessible as -\tcode{protected} -members of the derived class. -If a class is declared to be a base class for another class using the -\tcode{protected} -access specifier, the -\tcode{public} -and -\tcode{protected} -members of the base class are accessible as -\tcode{protected} -members of the derived class. -If a class is declared to be a base class for another class using the -\tcode{private} -access specifier, the -\tcode{public} -and -\tcode{protected} -members of the base class are accessible as -\tcode{private} -members of the derived class\footnote{As specified previously in Clause~\ref{class.access}, -private members of a base class remain inaccessible even to derived classes -unless -\tcode{friend} -declarations within the base class definition are used to grant access explicitly.}. - -\pnum -In the absence of an -\grammarterm{access-specifier} -for a base class, -\tcode{public} -is assumed when the derived class is -defined with the \grammarterm{class-key} -\tcode{struct} -and -\tcode{private} -is assumed when the class is -defined with the \grammarterm{class-key} -\tcode{class}. -\enterexample - -\begin{codeblock} -class B { /* ... */ }; -class D1 : private B { /* ... */ }; -class D2 : public B { /* ... */ }; -class D3 : B { /* ... */ }; // \tcode{B} private by default -struct D4 : public B { /* ... */ }; -struct D5 : private B { /* ... */ }; -struct D6 : B { /* ... */ }; // \tcode{B} public by default -class D7 : protected B { /* ... */ }; -struct D8 : protected B { /* ... */ }; -\end{codeblock} - -Here -\tcode{B} -is a public base of -\tcode{D2}, -\tcode{D4}, -and -\tcode{D6}, -a private base of -\tcode{D1}, -\tcode{D3}, -and -\tcode{D5}, -and a protected base of -\tcode{D7} -and -\tcode{D8}. -\exitexample - -\pnum -\enternote -A member of a private base class might be inaccessible as an inherited -member name, but accessible directly. -Because of the rules on pointer conversions~(\ref{conv.ptr}) and explicit casts~(\ref{expr.cast}), a conversion from a pointer to a derived class to a pointer -to an inaccessible base class might be ill-formed if an implicit conversion -is used, but well-formed if an explicit cast is used. -For example, - -\begin{codeblock} -class B { -public: - int mi; // non-static member - static int si; // static member -}; -class D : private B { -}; -class DD : public D { - void f(); -}; - -void DD::f() { - mi = 3; // error: \tcode{mi} is private in \tcode{D} - si = 3; // error: \tcode{si} is private in \tcode{D} - ::B b; - b.mi = 3; // OK (\tcode{b.mi} is different from \tcode{this->mi}) - b.si = 3; // OK (\tcode{b.si} is different from \tcode{this->si}) - ::B::si = 3; // OK - ::B* bp1 = this; // error: \tcode{B} is a private base class - ::B* bp2 = (::B*)this; // OK with cast - bp2->mi = 3; // OK: access through a pointer to \tcode{B}. -} -\end{codeblock} -\exitnote - -\pnum -A base class -\tcode{B} -of -\tcode{N} -is -\term{accessible} -at -\term{R}, -if -\begin{itemize} -\item -an invented public member of -\tcode{B} -would be a public member of -\tcode{N}, or -\item -\term{R} -occurs in a member or friend of class -\tcode{N}, -and an invented public member of -\tcode{B} -would be a private or protected member of -\tcode{N}, or -\item -\term{R} -occurs in a member or friend of a class -\tcode{P} -derived from -\tcode{N}, -and an invented public member of -\tcode{B} -would be a private or protected member of -\tcode{P}, or -\item -there exists a class -\tcode{S} -such that -\tcode{B} -is a base class of -\tcode{S} -accessible at -\term{R} -and -\tcode{S} -is a base class of -\tcode{N} -accessible at -\term{R}. -\end{itemize} - -\enterexample -\begin{codeblock} -class B { -public: - int m; -}; - -class S: private B { - friend class N; -}; - -class N: private S { - void f() { - B* p = this; // OK because class \tcode{S} satisfies the fourth condition - // above: \tcode{B} is a base class of \tcode{N} accessible in \tcode{f()} because - // \tcode{B} is an accessible base class of \tcode{S} and \tcode{S} is an accessible - // base class of \tcode{N}. - } -}; -\end{codeblock} -\exitexample - -\pnum -If a base class is accessible, one can implicitly convert a pointer to -a derived class to a pointer to that base class~(\ref{conv.ptr}, \ref{conv.mem}). -\enternote -It follows that -members and friends of a class -\tcode{X} -can implicitly convert an -\tcode{X*} -to a pointer to a private or protected immediate base class of -\tcode{X}. -\exitnote -The access to a member is affected by the class in which the member is -named. -This naming class is the class in which the member name was looked -up and found. -\enternote -This class can be explicit, e.g., when a -\grammarterm{qualified-id} -is used, or implicit, e.g., when a class member access operator~(\ref{expr.ref}) is used (including cases where an implicit -``\tcode{this->}'' -is -added). -If both a class member access operator and a -\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 -\grammarterm{nested-name-specifier} -of the -\grammarterm{qualified-id} -(that is, -\tcode{T}). -\exitnote -A member -\tcode{m} -is accessible at the point -\term{R} -when named in class -\tcode{N} -if -\begin{itemize} -\item -\tcode{m} -as a member of -\tcode{N} -is public, or -\item -\tcode{m} -as a member of -\tcode{N} -is private, and -\term{R} -occurs in a member or friend of class -\tcode{N}, -or -\item -\tcode{m} -as a member of -\tcode{N} -is protected, and -\term{R} -occurs in a member or friend of class -\tcode{N}, -or in a member or friend of a class -\tcode{P} -derived from -\tcode{N}, -where -\tcode{m} -as a member of -\tcode{P} -is public, private, or protected, or -\item -there exists a base class -\tcode{B} -of -\tcode{N} -that is accessible at -\term{R}, -and -\tcode{m} -is accessible at -\term{R} -when named in class -\tcode{B}. -\enterexample - -\begin{codeblock} -class B; -class A { -private: - int i; - friend void f(B*); -}; -class B : public A { }; -void f(B* p) { - p->i = 1; // OK: \tcode{B*} can be implicitly converted to \tcode{A*}, - // and \tcode{f} has access to \tcode{i} in \tcode{A} -} -\end{codeblock} -\exitexample -\end{itemize} - -\pnum -If a class member access operator, including an implicit -``\tcode{this->},'' -is used to access a non-static data member or non-static -member function, the reference is ill-formed if the -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. -\enternote -This requirement is in addition to the requirement that -the member be accessible as named. -\exitnote - -\rSec1[class.friend]{Friends}% -\indextext{friend function!access and}% -\indextext{access control!friend function} - -\pnum -A friend of a class is a function or class that is -given permission to use the private and protected member names from the class. -A class specifies its friends, if any, by way of friend declarations. -Such declarations give special access rights to the friends, but they -do not make the nominated friends members of the befriending class. -\enterexample -the following example illustrates the differences between -members and friends: -\indextext{friend function!member~function~and}% -\indextext{example!friend function}% -\indextext{example!member~function}% - -\begin{codeblock} -class X { - int a; - friend void friend_set(X*, int); -public: - void member_set(int); -}; - -void friend_set(X* p, int i) { p->a = i; } -void X::member_set(int i) { a = i; } - -void f() { - X obj; - friend_set(&obj,10); - obj.member_set(10); -} -\end{codeblock} -\exitexample - -\pnum -\indextext{friend!class access~and}% -Declaring a class to be a friend implies that the names of private and -protected members from the class granting friendship can be accessed in the -\grammarterm{base-specifier}{s} and member declarations of the befriended -class. \enterexample - -\begin{codeblock} -class A { - class B { }; - friend class X; -}; - -struct X : A::B { // OK: \tcode{A::B} accessible to friend - A::B mx; // OK: \tcode{A::B} accessible to member of friend - class Y { - A::B my; // OK: \tcode{A::B} accessible to nested member of friend - }; -}; -\end{codeblock} -\exitexample -\enterexample - -\begin{codeblock} -class X { - enum { a=100 }; - friend class Y; -}; - -class Y { - int v[X::a]; // OK, \tcode{Y} is a friend of \tcode{X} -}; - -class Z { - int v[X::a]; // error: \tcode{X::a} is private -}; -\end{codeblock} -\exitexample - -A class shall not be defined in a friend declaration. \enterexample -\begin{codeblock} -class A { - friend class B { }; // error: cannot define class in friend declaration -}; -\end{codeblock} -\exitexample - -\pnum -A \tcode{friend} declaration that does not declare a function -shall have one of the following forms: - -\begin{ncsimplebnf} -\terminal{friend} elaborated-type-specifier \terminal{;}\br -\terminal{friend} simple-type-specifier \terminal{;}\br -\terminal{friend} typename-specifier \terminal{;} -\end{ncsimplebnf} - -\enternote A \tcode{friend} declaration may be the -\term{declaration} in a \grammarterm{template-declaration} -(Clause~\ref{temp}, \ref{temp.friend}).\exitnote If the -type specifier in a \tcode{friend} declaration designates a (possibly -cv-qualified) class type, that class is declared as a friend; otherwise, the -\tcode{friend} declaration is ignored. \enterexample - -\begin{codeblock} -class C; -typedef C Ct; - -class X1 { - friend C; // OK: \tcode{class C} is a friend -}; - -class X2 { - friend Ct; // OK: \tcode{class C} is a friend - friend D; // error: no type-name \tcode{D} in scope - friend class D; // OK: elaborated-type-specifier declares new class -}; - -template class R { - friend T; -}; - -R rc; // \tcode{class C} is a friend of \tcode{R} -R Ri; // OK: \tcode{"friend int;"} is ignored -\end{codeblock} -\exitexample - -\pnum -\indextext{friend function!linkage~of}% -A function first declared in a friend declaration -has the linkage of the namespace of which it is a member~(\ref{basic.link}). -Otherwise, the function retains its previous linkage~(\ref{dcl.stc}). - -\pnum -\indextext{declaration!overloaded~name~and \tcode{friend}}% -When a -\tcode{friend} -declaration refers to an overloaded name or operator, only the function specified -by the parameter types becomes a friend. -A member function of a class -\tcode{X} -can be a friend of -a class -\tcode{Y}. -\indextext{member function!friend}% -\enterexample - -\begin{codeblock} -class Y { - friend char* X::foo(int); - friend X::X(char); // constructors can be friends - friend X::~X(); // destructors can be friends -}; -\end{codeblock} -\exitexample - -\pnum -\indextext{friend function!inline}% -A function can be defined in a friend declaration of a class if and only if the -class is a non-local class~(\ref{class.local}), the function name is unqualified, -and the function has namespace scope. -\enterexample - -\begin{codeblock} -class M { - friend void f() { } // definition of global \tcode{f}, a friend of \tcode{M}, - // not the definition of a member function -}; -\end{codeblock} -\exitexample - -\pnum -Such a function is implicitly -\tcode{inline}. -A -\tcode{friend} -function defined in a class is in the (lexical) scope of the class in which it is defined. -A friend function defined outside the class is not~(\ref{basic.lookup.unqual}). - -\pnum -No -\grammarterm{storage-class-specifier} -shall appear in the -\grammarterm{decl-specifier-seq} -of a friend declaration. - -\pnum -\indextext{friend!access~specifier~and}% -A name nominated by a friend declaration shall be accessible in the scope of the -class containing the friend declaration. -The meaning of the friend declaration is the same whether the friend declaration -appears in the -\tcode{private}, -\tcode{protected} -or -\tcode{public}~(\ref{class.mem}) -portion of the class -\grammarterm{member-specification}. - -\pnum -\indextext{friend!inheritance~and}% -Friendship is neither inherited nor transitive. -\enterexample - -\begin{codeblock} -class A { - friend class B; - int a; -}; - -class B { - friend class C; -}; - -class C { - void f(A* p) { - p->a++; // error: \tcode{C} is not a friend of \tcode{A} - // despite being a friend of a friend - } -}; - -class D : public B { - void f(A* p) { - p->a++; // error: \tcode{D} is not a friend of \tcode{A} - // despite being derived from a friend - } -}; -\end{codeblock} -\exitexample - -\pnum -\indextext{local~class!friend}% -\indextext{friend!local~class~and}% -If a friend declaration appears in a local class~(\ref{class.local}) and the -name specified is an unqualified name, a prior declaration is looked -up without considering scopes that are outside the innermost enclosing -non-class scope. -For a friend function declaration, if there is no -prior declaration, the program is ill-formed. -For a friend class -declaration, if there is no prior declaration, the class that is -specified belongs to the innermost enclosing non-class scope, but if it is -subsequently referenced, its name is not found by name lookup -until a matching declaration is provided in the innermost enclosing -non-class scope. -\enterexample - -\begin{codeblock} -class X; -void a(); -void f() { - class Y; - extern void b(); - class A { - friend class X; // OK, but \tcode{X} is a local class, not \tcode{::X} - friend class Y; // OK - friend class Z; // OK, introduces local class \tcode{Z} - friend void a(); // error, \tcode{::a} is not considered - friend void b(); // OK - friend void c(); // error - }; - X* px; // OK, but \tcode{::X} is found - Z* pz; // error, no \tcode{Z} is found -} -\end{codeblock} -\exitexample - -\rSec1[class.protected]{Protected member access} -\indextext{access control!\idxcode{protected}}% - -\pnum -An additional access check beyond those described earlier in Clause~\ref{class.access} -is applied when a non-static data member or non-static member function is a -protected member of its naming class~(\ref{class.access.base})\footnote{This -additional check does not apply to other members, -e.g., static data members or enumerator member constants.} -As described earlier, access to a protected member is granted because the -reference occurs in a friend or member of some class \tcode{C}. If the access is -to form a pointer to member~(\ref{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~(\ref{expr.ref}). In this case, the class of the object expression shall be -\tcode{C} or a class derived from \tcode{C}. -\enterexample - -\begin{codeblock} -class B { -protected: - int i; - static int j; -}; - -class D1 : public B { -}; - -class D2 : public B { - friend void fr(B*,D1*,D2*); - void mem(B*,D1*); -}; - -void fr(B* pb, D1* p1, D2* p2) { - pb->i = 1; // ill-formed - p1->i = 2; // ill-formed - 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}) - int B::* pmi_B = &B::i; // ill-formed - int B::* pmi_B2 = &D2::i; // OK (type of \tcode{\&D2::i} is \tcode{int B::*}) - B::j = 5; // OK (because refers to static member) - D2::j = 6; // OK (because refers to static member) -} - -void D2::mem(B* pb, D1* p1) { - pb->i = 1; // ill-formed - p1->i = 2; // ill-formed - i = 3; // OK (access through \tcode{this}) - B::i = 4; // OK (access through \tcode{this}, qualification ignored) - int B::* pmi_B = &B::i; // ill-formed - int B::* pmi_B2 = &D2::i; // OK - j = 5; // OK (because \tcode{j} refers to static member) - B::j = 6; // OK (because \tcode{B::j} refers to static member) -} - -void g(B* pb, D1* p1, D2* p2) { - pb->i = 1; // ill-formed - p1->i = 2; // ill-formed - p2->i = 3; // ill-formed -} -\end{codeblock} -\exitexample - -\rSec1[class.access.virt]{Access to virtual functions}% -\indextext{access control!virtual function} - -\pnum -The access rules (Clause~\ref{class.access}) for a virtual function are determined by its declaration -and are not affected by the rules for a function that later overrides it. -\enterexample - -\begin{codeblock} -class B { -public: - virtual int f(); -}; - -class D : public B { -private: - int f(); -}; - -void f() { - D d; - B* pb = &d; - D* pd = &d; - - pb->f(); // OK: \tcode{B::f()} is public, - // \tcode{D::f()} is invoked - pd->f(); // error: \tcode{D::f()} is private -} -\end{codeblock} -\exitexample - -\pnum -Access is checked at the call point using the type of the expression used -to denote the object for which the member function is called -(\tcode{B*} -in the example above). -The access of the member function in the class in which it was defined -(\tcode{D} -in the example above) is in general not known. - -\rSec1[class.paths]{Multiple access}% -\indextext{access control!multiple access} - -\pnum -If a name can be reached by several paths through a multiple inheritance -graph, the access is that of the path that gives most access. -\enterexample - -\begin{codeblock} -class W { public: void f(); }; -class A : private virtual W { }; -class B : public virtual W { }; -class C : public A, public B { - void f() { W::f(); } // OK -}; -\end{codeblock} - -\pnum -Since -\tcode{W::f()} -is available to -\tcode{C::f()} -along the public path through -\tcode{B}, -access is allowed. -\exitexample - -\rSec1[class.access.nest]{Nested classes}% -\indextext{access control!nested class}% -\indextext{member function!nested class} - -\pnum -A nested class is a member and as such has the same access rights as any other member. -The members of an enclosing class have no special access to members of a nested -class; the usual access rules (Clause~\ref{class.access}) shall be obeyed. -\enterexample -\indextext{example!nested~class definition}% - -\begin{codeblock} -class E { - int x; - class B { }; - - class I { - B b; // OK: \tcode{E::I} can access \tcode{E::B} - int y; - void f(E* p, int i) { - p->x = i; // OK: \tcode{E::I} can access \tcode{E::x} - } - }; - - int g(I* p) { - return p->y; // error: \tcode{I::y} is private - } -}; -\end{codeblock} -\exitexample% -\indextext{access control|)} diff --git a/source/algorithms.tex b/source/algorithms.tex index f657d332e1..8b2f530d4c 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -4,494 +4,3877 @@ \rSec1[algorithms.general]{General} \pnum -This Clause describes components that \Cpp programs may use to perform -algorithmic operations on containers (Clause~\ref{containers}) and other sequences. +This Clause describes components that \Cpp{} programs may use to perform +algorithmic operations on containers\iref{containers} and other sequences. \pnum The following subclauses describe components for -non-modifying sequence operation, -modifying sequence operations, +non-modifying sequence operations, +mutating sequence operations, sorting and related operations, -and algorithms from the ISO C library, -as summarized in Table~\ref{tab:algorithms.summary}. - -\begin{libsumtab}{Algorithms library summary}{tab:algorithms.summary} -\ref{alg.nonmodifying} & Non-modifying sequence operations & \\ -\ref{alg.modifying.operations} & Mutating sequence operations & \tcode{} \\ -\ref{alg.sorting} & Sorting and related operations & \\ \hline -\ref{alg.c.library} & C library algorithms & \tcode{} \\ \hline +and algorithms from the C library, +as summarized in \tref{algorithms.summary}. + +\begin{libsumtab}{Algorithms library summary}{algorithms.summary} +\ref{algorithms.requirements} & Algorithms requirements & \\ +\ref{algorithms.parallel} & Parallel algorithms & \tcode{} \\ \rowsep +\ref{algorithms.results} & Algorithm result types & \tcode{} \\ +\ref{alg.nonmodifying} & Non-modifying sequence operations & \\ +\ref{alg.modifying.operations} & Mutating sequence operations & \\ +\ref{alg.sorting} & Sorting and related operations & \\ \rowsep +\ref{numeric.ops} & Generalized numeric operations & \tcode{} \\ \rowsep +\ref{specialized.algorithms} & Specialized \tcode{} algorithms & \tcode{} \\ \rowsep +\ref{alg.rand} & Specialized \tcode{} algorithms & \tcode{} \\ \rowsep +\ref{alg.c.library} & C library algorithms & \tcode{} \\ \end{libsumtab} -\synopsis{Header \tcode{} synopsis} -\indexlibrary{\idxhdr{algorithm}}% +\rSec1[algorithms.requirements]{Algorithms requirements} +\pnum +All of the algorithms +are separated from the particular implementations of data structures and +are parameterized by iterator types. +Because of this, they can work with program-defined data structures, +as long as these data structures have iterator types +satisfying the assumptions on the algorithms. + +\pnum +The entities defined in the \tcode{std::ranges} namespace in this Clause and +specified as function templates are +algorithm function objects\iref{alg.func.obj}. + +\pnum +For purposes of determining the existence of data races, +algorithms shall not modify objects referenced through an iterator argument +unless the specification requires such modification. + +\pnum +Throughout this Clause, where the template parameters are not constrained, +the names of template parameters are used to express type requirements. +\begin{itemize} +\item + If an algorithm's \Fundescx{Effects} element specifies + that a value pointed to by any iterator passed as an argument is modified, + then the type of that argument shall meet + the requirements of a mutable iterator\iref{iterator.requirements}. +\item + If an algorithm's template parameter is named + \tcode{InputIterator}, + \tcode{InputIterator1}, or + \tcode{Input\-Iterator2}, + the template argument shall meet the + \oldconcept{InputIterator} requirements\iref{input.iterators}. +\item + If an algorithm's template parameter is named + \tcode{OutputIterator}, + \tcode{OutputIterator1}, or + \tcode{Output\-Iterator2}, + the template argument shall meet the + \oldconcept{OutputIterator} requirements\iref{output.iterators}. +\item + If an algorithm's template parameter is named + \tcode{ForwardIterator}, + \tcode{ForwardIterator1}, + \tcode{ForwardItera\-tor2}, or + \tcode{NoThrowForwardIterator}, + the template argument shall meet the + \oldconcept{ForwardIterator} requirements\iref{forward.iterators} + if it is required to be a mutable iterator, or + model \libconcept{forward_iterator}\iref{iterator.concept.forward} otherwise. +\item + If an algorithm's template parameter is named + \tcode{NoThrowForwardIterator}, + the template argument + is also required to have the property that no exceptions are thrown + from increment, assignment, or comparison of, or + indirection through, valid iterators. +\item + If an algorithm's template parameter is named + \tcode{BidirectionalIterator}, + \tcode{Bidirectional\-Iterator1}, or + \tcode{BidirectionalIterator2}, + the template argument shall meet the + \oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators} + if it is required to be a mutable iterator, or model + \libconcept{bidirectional_iterator}\iref{iterator.concept.bidir} otherwise. +\item + If an algorithm's template parameter is named + \tcode{RandomAccessIterator}, + \tcode{Random\-AccessIterator1}, or + \tcode{RandomAccessIterator2}, + the template argument shall meet the + \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} + if it is required to be a mutable iterator, or model + \libconcept{random_access_iterator}\iref{iterator.concept.random.access} otherwise. +\end{itemize} +\begin{note} +These requirements do not affect iterator arguments that are constrained, +for which iterator category and mutability requirements +are expressed explicitly. +\end{note} + +\pnum +Both in-place and copying versions are provided for certain algorithms. +\begin{footnote} +The decision whether to include a copying version was +usually based on complexity considerations. +When the cost of doing the operation dominates the cost of copy, +the copying version is not included. +For example, \tcode{sort_copy} is not included +because the cost of sorting is much more significant, +and users can invoke \tcode{copy} followed by \tcode{sort}. +\end{footnote} +When such a version is provided for \textit{algorithm} it is called +\textit{algorithm\tcode{_copy}}. +Algorithms that take predicates end with the suffix \tcode{_if} +(which follows the suffix \tcode{_copy}). + +\pnum +When not otherwise constrained, the \tcode{Predicate} parameter is used +whenever an algorithm expects a function object\iref{function.objects} that, +when applied to the result of dereferencing the corresponding iterator, +returns a value testable as \tcode{true}. +If an algorithm takes \tcode{Predicate pred} as its argument and +\tcode{first} as its iterator argument with value type \tcode{T}, +the expression \tcode{pred(*first)} shall be well-formed and +the type \tcode{decltype(pred(*first))} shall model +\exposconcept{boolean-testable}\iref{concept.booleantestable}. +The function object \tcode{pred} shall not apply any non-constant function +through its argument. +Given a glvalue \tcode{u} of type (possibly const) \tcode{T} +that designates the same object as \tcode{*first}, +\tcode{pred(u)} shall be a valid expression +that is equal to \tcode{pred(*first)}. + +\pnum +When not otherwise constrained, the \tcode{BinaryPredicate} parameter is used +whenever an algorithm expects a function object that, when applied +to the result of dereferencing two corresponding iterators or +to dereferencing an iterator and type \tcode{T} +when \tcode{T} is part of the signature, +returns a value testable as \tcode{true}. +If an algorithm takes \tcode{BinaryPredicate binary_pred} as its argument and +\tcode{first1} and \tcode{first2} as its iterator arguments +with respective value types \tcode{T1} and \tcode{T2}, +the expression \tcode{binary_pred(*first1, *first2)} shall be well-formed and +the type \tcode{decltype(binary_pred(*first1, *first2))} shall model +\exposconcept{boolean-testable}. +Unless otherwise specified, +\tcode{BinaryPredicate} always takes the first iterator's \tcode{value_type} +as its first argument, that is, in those cases when \tcode{T value} +is part of the signature, +the expression \tcode{binary_pred(*first1, value)} shall be well-formed and +the type \tcode{decltype(binary_pred(*first1, value))} shall model +\exposconcept{boolean-testable}. +\tcode{binary_pred} shall not apply any non-constant function +through any of its arguments. +Given a glvalue \tcode{u} of type (possibly const) \tcode{T1} +that designates the same object as \tcode{*first1}, and +a glvalue \tcode{v} of type (possibly const) \tcode{T2} +that designates the same object as \tcode{*first2}, +\tcode{binary_pred(u, *first2)}, +\tcode{binary_pred(*first1, v)}, and +\tcode{binary_pred(u, v)} +shall each be a valid expression that is equal to +\tcode{binary_pred(*first1, *first2)}, and +\tcode{binary_pred(u, value)} +shall be a valid expression that is equal to +\tcode{binary_pred(*first1, value)}. + +\pnum +The parameters +\tcode{UnaryOperation}, +\tcode{BinaryOperation}, +\tcode{BinaryOperation1}, +and \tcode{BinaryOperation2} +are used +whenever an algorithm expects a function object\iref{function.objects}. + +\pnum +\begin{note} +Unless otherwise specified, algorithms that take function objects as arguments +can copy those function objects freely. +If object identity is important, +a wrapper class that points to a non-copied implementation object +such as \tcode{reference_wrapper}\iref{refwrap}, or some equivalent solution, +can be used. +\end{note} + +\pnum +When the description of an algorithm gives an expression such as +\tcode{*first == value} for a condition, the expression +shall evaluate to either \tcode{true} or \tcode{false} in boolean contexts. + +\pnum +In the description of the algorithms, operator \tcode{+} +is used for some of the iterator categories +for which it does not have to be defined. +In these cases the semantics of \tcode{a + n} are the same as those of +\begin{codeblock} +auto tmp = a; +for (; n < 0; ++n) --tmp; +for (; n > 0; --n) ++tmp; +return tmp; +\end{codeblock} +Similarly, operator \tcode{-} is used +for some combinations of iterators and sentinel types +for which it does not have to be defined. +If \range{a}{b} denotes a range, +the semantics of \tcode{b - a} in these cases are the same as those of +\begin{codeblock} +iter_difference_t n = 0; +for (auto tmp = a; tmp != b; ++tmp) ++n; +return n; +\end{codeblock} +and if \range{b}{a} denotes a range, the same as those of +\begin{codeblock} +iter_difference_t n = 0; +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, +given an iterator \tcode{a} whose difference type is \tcode{D}, and +an expression \tcode{n} of integer-like type other than \cv{} \tcode{D}, +the semantics of \tcode{a + n} and \tcode{a - n} are, respectively, +those of \tcode{a + D(n)} and \tcode{a - D(n)}. + +\pnum +In the description of algorithm return values, +a sentinel value \tcode{s} denoting the end of a range \range{i}{s} +is sometimes returned where an iterator is expected. +In these cases, +the semantics are as if the sentinel is converted into an iterator using +\tcode{ranges::next(i, s)}. + +\pnum +Overloads of algorithms that take \libconcept{range} arguments\iref{range.range} +behave as if they are implemented by +dispatching to the overload in namespace \tcode{ranges} +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::next(ranges::\brk{}begin(r), ranges::end(r))} + if the type of \tcode{r} models \libconcept{forward_range} + and computing \tcode{ranges::next} meets the specified complexity requirements. +\end{itemize} + +\pnum +The well-formedness and behavior of a call to an algorithm with +an explicitly-specified template argument list +is unspecified, except where explicitly stated otherwise. +\begin{note} +Consequently, an implementation can declare an algorithm with +different template parameters than those presented. +\end{note} + +\rSec1[algorithms.parallel]{Parallel algorithms} + +\rSec2[algorithms.parallel.defns]{Preamble} +\pnum +Subclause \ref{algorithms.parallel} describes components that \Cpp{} programs may use +to perform operations on containers and other sequences in parallel. + +\pnum +A \defn{parallel algorithm} is a function template listed in this document +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 +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, 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 invocable objects + to be applied during the execution of the algorithm, + if required by the specification. +\item + Operations on those invocable objects required by the specification. +\begin{note} +See~\ref{algorithms.requirements}. +\end{note} +\end{itemize} +These functions are herein called \defn{element access functions}. + +\pnum +\begin{example} +The \tcode{sort} function may invoke the following element access functions: +\begin{itemize} +\item + Operations of the random-access iterator of the actual template argument + (as per \ref{random.access.iterators}), + as implied by the name of the template parameter \tcode{RandomAccessIterator}. +\item + The \tcode{swap} function on the elements of the sequence + (as per the preconditions specified in \ref{sort}). +\item + The user-provided \tcode{Compare} function object. +\end{itemize} +\end{example} + +\pnum +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 +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 +when those functions are executed by threads of execution +with weakly parallel forward progress guarantees. +\end{note} +\begin{example} +\begin{codeblock} +int x = 0; +std::mutex m; +void f() { + int a[] = {1,2}; + std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) { + std::lock_guard guard(m); // incorrect: \tcode{lock_guard} constructor calls \tcode{m.lock()} + ++x; + }); +} +\end{codeblock} +The above program may result in two consecutive calls to \tcode{m.lock()} +on the same thread of execution (which may deadlock), +because the applications of the function object are not guaranteed +to run on different threads of execution. +\end{example} + +\rSec2[algorithms.parallel.user]{Requirements on user-provided function objects} + +\pnum +Unless otherwise specified, +invocable objects passed into parallel algorithms as objects of a type +denoted by a template parameter named +\tcode{Predicate}, +\tcode{BinaryPredicate}, +\tcode{Compare}, +\tcode{UnaryOperation}, +\tcode{BinaryOperation}, +\tcode{BinaryOperation1}, +\tcode{BinaryOperation2}, +\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, +nor shall they rely on the identity of the provided objects. + +\rSec2[algorithms.parallel.exec]{Effect of execution policies on algorithm execution} + +\pnum +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, +the algorithm will perform no other unsynchronized accesses to that object. +The modifying element access functions are those +which are specified as modifying the object. +\begin{note} +For example, +\tcode{swap}, +\tcode{++}, +\tcode{--}, +\tcode{@=}, and +assignments +modify the object. +For the assignment and \tcode{@=} operators, only the left argument is modified. +\end{note} + +\pnum +Unless otherwise stated, implementations may make arbitrary copies of elements +(with type \tcode{T}) from sequences +where \tcode{is_trivially_copy_constructible_v} +and \tcode{is_trivially_destructible_v} are \tcode{true}. +\begin{note} +This implies that user-supplied function objects cannot rely on +object identity of arguments for such input sequences. +If object identity of the arguments to these function objects +is important, a wrapping iterator +that returns a non-copied implementation object +such as \tcode{reference_wrapper}\iref{refwrap}, +or some equivalent solution, can be used. +\end{note} + +\pnum +The invocations of element access functions in parallel algorithms invoked with +an execution policy object of type \tcode{execution::sequenced_policy} all occur +in the calling thread of execution. +\begin{note} +The invocations are not interleaved; see~\ref{intro.execution}. +\end{note} + +\pnum +The invocations of element access functions in parallel algorithms invoked with +an execution policy object of type \tcode{execution::unsequenced_policy} +are permitted to execute in an unordered fashion +in the calling thread of execution, +unsequenced with respect to one another in the calling thread of execution. +\begin{note} +This means that multiple function object invocations +can be interleaved on a single thread of execution, +which overrides the usual guarantee from \ref{intro.execution} +that function executions do not overlap with one another. +\end{note} +The behavior of a program is undefined if +it invokes a vectorization-unsafe standard library function +from user code +called from an \tcode{execution::unsequenced_policy} algorithm. +\begin{note} +Because \tcode{execution::unsequenced_policy} allows +the execution of element access functions +to be interleaved on a single thread of execution, +blocking synchronization, including the use of mutexes, risks deadlock. +\end{note} + +\pnum +The invocations of element access functions in parallel algorithms invoked with +an execution policy object of type \tcode{execution::parallel_policy} +are permitted to execute either +in the invoking thread of execution or +in a thread of execution implicitly created by the library +to support parallel algorithm execution. +If the threads of execution created by \tcode{thread}\iref{thread.thread.class} +or \tcode{jthread}\iref{thread.jthread.class} +provide concurrent forward progress guarantees\iref{intro.progress}, +then a thread of execution implicitly created by the library will provide +parallel forward progress guarantees; +otherwise, the provided forward progress guarantee is +\impldef{forward progress guarantees for +implicit threads of parallel algorithms (if not defined for \tcode{thread})}. +Any such invocations executing in the same thread of execution +are indeterminately sequenced with respect to each other. +\begin{note} +It is the caller's responsibility to ensure +that the invocation does not introduce data races or deadlocks. +\end{note} +\begin{example} +\begin{codeblock} +int a[] = {0,1}; +std::vector v; +std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) { + v.push_back(i*2+1); // incorrect: data race +}); +\end{codeblock} +The program above has a data race because of the unsynchronized access to the +container \tcode{v}. +\end{example} +\begin{example} +\begin{codeblock} +std::atomic x{0}; +int a[] = {1,2}; +std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) { + x.fetch_add(1, std::memory_order::relaxed); + // spin wait for another iteration to change the value of \tcode{x} + while (x.load(std::memory_order::relaxed) == 1) { } // incorrect: assumes execution order +}); +\end{codeblock} +The above example depends on the order of execution of the iterations, and +will not terminate if both iterations are executed sequentially +on the same thread of execution. +\end{example} +\begin{example} +\begin{codeblock} +int x = 0; +std::mutex m; +int a[] = {1,2}; +std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) { + std::lock_guard guard(m); + ++x; +}); +\end{codeblock} +The above example synchronizes access to object \tcode{x} +ensuring that it is incremented correctly. +\end{example} + +\pnum +The invocations of element access functions in parallel algorithms invoked with +an execution policy object of type \tcode{execution::parallel_unsequenced_policy} are +permitted to execute +in an unordered fashion in unspecified threads of execution, and +unsequenced with respect to one another within each thread of execution. +These threads of execution are +either the invoking thread of execution +or threads of execution implicitly created by the library; +the latter will provide weakly parallel forward progress guarantees. +\begin{note} +This means that multiple function object invocations can be interleaved +on a single thread of execution, +which overrides the usual guarantee from \ref{intro.execution} +that function executions do not overlap with one another. +\end{note} +The behavior of a program is undefined if +it invokes a vectorization-unsafe standard library function +from user code +called from an \tcode{execution::parallel_unsequenced_policy} algorithm. +\begin{note} +Because \tcode{execution::parallel_unsequenced_policy} allows +the execution of element access functions +to be interleaved on a single thread of execution, +blocking synchronization, including the use of mutexes, risks deadlock. +\end{note} + +\pnum +\begin{note} +The semantics of invocation with +\tcode{execution::unsequenced_policy}, +\tcode{execution::parallel_policy}, or +\tcode{execution::parallel_unsequenced_policy} +allow the implementation to fall back to sequential execution +if the system cannot parallelize an algorithm invocation, +e.g., due to lack of resources. +\end{note} + +\pnum +If an invocation of a parallel algorithm uses threads of execution +implicitly created by the library, +then the invoking thread of execution will either +\begin{itemize} +\item + temporarily block + with forward progress guarantee delegation\iref{intro.progress} + on the completion of these library-managed threads of execution, or +\item + eventually execute an element access function; +\end{itemize} +the thread of execution will continue to do so until the algorithm is finished. +\begin{note} +In blocking with forward progress guarantee delegation in this context, +a thread of execution created by the library +is considered to have finished execution +as soon as it has finished the execution +of the particular element access function +that the invoking thread of execution logically depends on. +\end{note} + +\pnum +The semantics of parallel algorithms invoked with an execution policy object of +\impldef{additional execution policies supported by parallel algorithms} type +are \impldef{semantics of parallel algorithms invoked with +imple\-men\-tation-defined execution policies}. + +\rSec2[algorithms.parallel.exceptions]{Parallel algorithm exceptions} + +\pnum +During the execution of a parallel algorithm, +if temporary memory resources are required for parallelization +and none are available, the algorithm throws a \tcode{bad_alloc} exception. + +\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 execution policy. + +\rSec2[algorithms.parallel.overloads]{Parallel algorithm overloads} + +\pnum +Parallel algorithms are algorithm overloads. +Each parallel algorithm overload +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 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 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}'' +and does not specify the number of assignments or swaps, and +\placeholder{expr} is not already expressed with \bigoh{} notation, +the complexity of the algorithm shall be \bigoh{\placeholder{expr}}. + +\pnum +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} + +\rSec3[execpol.general]{General} + +\pnum +Subclause~\ref{execpol} describes classes that are \defn{execution policy} types. An +object of an execution policy type indicates the kinds of parallelism allowed +in the execution of an algorithm and expresses the consequent requirements on +the element access functions. +Execution policy types are declared in header \libheaderref{execution}. +\begin{example} +\begin{codeblock} +using namespace std; +vector v = @\commentellip@; + +// standard sequential sort +sort(v.begin(), v.end()); + +// explicitly sequential sort +sort(execution::seq, v.begin(), v.end()); + +// permitting parallel execution +sort(execution::par, v.begin(), v.end()); + +// permitting vectorization as well +sort(execution::par_unseq, v.begin(), v.end()); +\end{codeblock} +\end{example} +\begin{note} +Implementations can provide additional execution policies +to those described in this document as extensions +to address parallel architectures that require idiosyncratic +parameters for efficient execution. +\end{note} + +\rSec3[execpol.type]{Execution policy type trait} + +\indexlibraryglobal{is_execution_policy}% +\begin{itemdecl} +template struct is_execution_policy; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{is_execution_policy} can be used to detect execution policies for the +purpose of excluding function signatures from otherwise ambiguous overload +resolution participation. + +\pnum +\tcode{is_execution_policy} is a \oldconcept{UnaryTypeTrait} with a +base characteristic of \tcode{true_type} if \tcode{T} is the type of a standard +or \impldef{additional execution policies supported by parallel algorithms} +execution policy, otherwise \tcode{false_type}. + +\begin{note} +This provision reserves the privilege of creating non-standard execution +policies to the library implementation. +\end{note} + +\pnum +The behavior of a program that adds specializations for +\tcode{is_execution_policy} is undefined. +\end{itemdescr} + +\rSec3[execpol.seq]{Sequenced execution policy} + +\indexlibraryglobal{execution::sequenced_policy}% +\begin{itemdecl} +class execution::sequenced_policy { @\unspec@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The class \tcode{execution::sequenced_policy} is an execution policy type used +as a unique type to disambiguate parallel algorithm overloading and require +that a parallel algorithm's execution may not be parallelized. + +\pnum +During the execution of a parallel algorithm with +the \tcode{execution::sequenced_policy} policy, +if the invocation of an element access function exits via an exception, +\tcode{terminate} is invoked\iref{except.terminate}. +\end{itemdescr} + +\rSec3[execpol.par]{Parallel execution policy} + +\indexlibraryglobal{execution::parallel_policy}% +\begin{itemdecl} +class execution::parallel_policy { @\unspec@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The class \tcode{execution::parallel_policy} is an execution policy type used as +a unique type to disambiguate parallel algorithm overloading and indicate that +a parallel algorithm's execution may be parallelized. + +\pnum +During the execution of a parallel algorithm with +the \tcode{execution::parallel_policy} policy, +if the invocation of an element access function exits via an exception, +\tcode{terminate} is invoked\iref{except.terminate}. +\end{itemdescr} + +\rSec3[execpol.parunseq]{Parallel and unsequenced execution policy} + +\indexlibraryglobal{execution::parallel_unsequenced_policy}% +\begin{itemdecl} +class execution::parallel_unsequenced_policy { @\unspec@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The class \tcode{execution::parallel_unsequenced_policy} is an execution policy type +used as a unique type to disambiguate parallel algorithm overloading and +indicate that a parallel algorithm's execution may be parallelized and +vectorized. + +\pnum +During the execution of a parallel algorithm with +the \tcode{execution::parallel_unsequenced_policy} policy, +if the invocation of an element access function exits via an exception, +\tcode{terminate} is invoked\iref{except.terminate}. +\end{itemdescr} + +\rSec3[execpol.unseq]{Unsequenced execution policy} + +\indexlibraryglobal{execution::unsequenced_policy}% +\begin{itemdecl} +class execution::unsequenced_policy { @\unspec@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The class \tcode{unsequenced_policy} is an execution policy type +used as a unique type to disambiguate parallel algorithm overloading and +indicate that a parallel algorithm's execution may be vectorized, +e.g., executed on a single thread using instructions +that operate on multiple data items. + +\pnum +During the execution of a parallel algorithm with +the \tcode{execution::unsequenced_policy} policy, +if the invocation of an element access function exits via an exception, +\tcode{terminate} is invoked\iref{except.terminate}. +\end{itemdescr} + +\rSec3[execpol.objects]{Execution policy objects} + +\indexlibraryglobal{seq}% +\indexlibraryglobal{par}% +\indexlibraryglobal{par_unseq}% +\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@ }; +inline constexpr execution::parallel_unsequenced_policy execution::par_unseq{ @\unspec@ }; +inline constexpr execution::unsequenced_policy execution::unseq{ @\unspec@ }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The header \libheaderref{execution} declares global objects associated with each type of execution policy. +\end{itemdescr} + +\rSec1[algorithm.syn]{Header \tcode{} synopsis} +\indexheader{algorithm}% \begin{codeblock} -#include +// mostly freestanding +#include // see \ref{initializer.list.syn} namespace std { + namespace ranges { + // \ref{algorithms.results}, algorithm result types + template + struct in_fun_result; + + template + struct in_in_result; + + template + struct in_out_result; + + template + struct in_in_out_result; + + template + struct in_out_out_result; + + template + struct min_max_result; - // \ref{alg.nonmodifying}, non-modifying sequence operations: - template - bool all_of(InputIterator first, InputIterator last, Predicate pred); - template - bool any_of(InputIterator first, InputIterator last, Predicate pred); - template - bool none_of(InputIterator first, InputIterator last, Predicate pred); + template + struct in_found_result; + template + struct in_value_result; + + template + struct out_value_result; + } + + // \ref{alg.nonmodifying}, non-modifying sequence operations + // \ref{alg.all.of}, all of + template + constexpr bool all_of(InputIterator first, InputIterator last, Predicate pred); + template + bool all_of(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred); + + namespace ranges { + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr bool all_of(I first, S last, Pred pred, Proj proj = {}); + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred); + + namespace ranges { + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr bool any_of(I first, S last, Pred pred, Proj proj = {}); + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred); + + namespace ranges { + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr bool none_of(I first, S last, Pred pred, Proj proj = {}); + 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 + namespace ranges { + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr bool contains(I first, S last, const T& value, Proj proj = {}); + template<@\libconcept{input_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires + @\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> + requires @\libconcept{indirectly_comparable}@ + constexpr bool contains_subrange(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{forward_range}@ R1, @\libconcept{forward_range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + 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 - Function for_each(InputIterator first, InputIterator last, Function f); - template - InputIterator find(InputIterator first, InputIterator last, - const T& value); + constexpr Function for_each(InputIterator first, InputIterator last, Function f); + template + void for_each(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Function f); + + namespace ranges { + template + 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> + constexpr for_each_result + for_each(I first, S last, Fun f, Proj proj = {}); + template<@\libconcept{input_range}@ R, class Proj = identity, + @\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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, Size n, Function f); + + namespace ranges { + template + 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 + template::value_type> + constexpr InputIterator find(InputIterator first, InputIterator last, + const T& value); + template::value_type> + ForwardIterator find(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + const T& value); template - InputIterator find_if(InputIterator first, InputIterator last, - Predicate pred); + constexpr InputIterator find_if(InputIterator first, InputIterator last, + Predicate pred); + template + ForwardIterator find_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Predicate pred); template - InputIterator find_if_not(InputIterator first, InputIterator last, - Predicate pred); + constexpr InputIterator find_if_not(InputIterator first, InputIterator last, + Predicate pred); + template + ForwardIterator find_if_not(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Predicate pred); + + namespace ranges { + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr I find(I first, S last, const T& value, Proj proj = {}); + template<@\libconcept{input_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{indirect_binary_predicate}@, 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 = {}); + template<@\libconcept{input_range}@ R, class Proj = identity, + @\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 = {}); + template<@\libconcept{input_range}@ R, class Proj = identity, + @\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 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 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 template - ForwardIterator1 + constexpr ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); - template - ForwardIterator1 + template + constexpr ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); + template + ForwardIterator1 + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + namespace ranges { + 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> + requires @\libconcept{indirectly_comparable}@ + constexpr subrange + find_end(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{forward_range}@ R1, @\libconcept{forward_range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + 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 of template - InputIterator + constexpr InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2); - template - InputIterator + template + constexpr InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryPredicate pred); + template + ForwardIterator1 + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + namespace ranges { + template<@\libconcept{input_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> + requires @\libconcept{indirectly_comparable}@ + constexpr I1 find_first_of(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{forward_range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + 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 template - ForwardIterator adjacent_find(ForwardIterator first, - ForwardIterator last); + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last); template - ForwardIterator adjacent_find(ForwardIterator first, - ForwardIterator last, - BinaryPredicate pred); + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); + template + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); - template - typename iterator_traits::difference_type + namespace ranges { + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_binary_predicate}@, + projected> Pred = ranges::equal_to> + constexpr I adjacent_find(I first, S last, Pred pred = {}, + Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_binary_predicate}@, Proj>, + 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 + template::value_type> + constexpr typename iterator_traits::difference_type count(InputIterator first, InputIterator last, const T& value); + template::value_type> + typename iterator_traits::difference_type + count(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, const T& value); template - typename iterator_traits::difference_type + constexpr typename iterator_traits::difference_type count_if(InputIterator first, InputIterator last, Predicate pred); - + template + typename iterator_traits::difference_type + count_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred); + + namespace ranges { + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr iter_difference_t + count(I first, S last, const T& value, Proj proj = {}); + template<@\libconcept{input_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{indirect_binary_predicate}@, 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 + count_if(I first, S last, Pred pred, Proj proj = {}); + template<@\libconcept{input_range}@ R, class Proj = identity, + @\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 template - pair + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); - template - - pair + template + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); - template - pair + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); - - template - - pair + template + constexpr pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); + template + pair + mismatch(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + template + pair + mismatch(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + template + pair + mismatch(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + pair + mismatch(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + namespace ranges { + template + 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> + requires @\libconcept{indirectly_comparable}@ + constexpr mismatch_result + mismatch(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + 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 template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); - template - - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); - + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2); + template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate pred); template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); - - template - - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); + template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred); + template + bool equal(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + template + bool equal(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + template + bool equal(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + bool equal(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); + namespace ranges { + 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> + requires @\libconcept{indirectly_comparable}@ + constexpr bool equal(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + 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 template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); - template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, BinaryPredicate pred); + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + namespace ranges { + template<@\libconcept{forward_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{forward_iterator}@ I2, + @\libconcept{sentinel_for}@ S2, class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_equivalence_relation}@, + projected> Pred = ranges::equal_to> + constexpr bool is_permutation(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{forward_range}@ R1, @\libconcept{forward_range}@ R2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_equivalence_relation}@, Proj1>, + projected, Proj2>> + Pred = ranges::equal_to> + constexpr bool is_permutation(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + } + + // \ref{alg.search}, search template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); + constexpr ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + constexpr ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + template + ForwardIterator1 + search(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + ForwardIterator1 + search(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); - template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); + namespace ranges { + 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> + requires @\libconcept{indirectly_comparable}@ + constexpr subrange + search(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{forward_range}@ R1, @\libconcept{forward_range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + 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> + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value); + template::value_type, class BinaryPredicate> + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value, BinaryPredicate pred); + template::value_type> + ForwardIterator + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Size count, const T& value, + BinaryPredicate pred); - template - ForwardIterator1 search( - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - template - ForwardIterator1 search( - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); - template - ForwardIterator search_n(ForwardIterator first, ForwardIterator last, - Size count, const T& value); - template - - ForwardIterator search_n(ForwardIterator first, ForwardIterator last, - Size count, const T& value, - BinaryPredicate pred); - - // \ref{alg.modifying.operations}, modifying sequence operations: - // \ref{alg.copy}, copy: + namespace ranges { + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, + class Pred = ranges::equal_to, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirectly_comparable}@ + constexpr subrange + search_n(I first, S last, iter_difference_t count, + const T& value, Pred pred = {}, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Pred = ranges::equal_to, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirectly_comparable}@, const T*, Pred, Proj> + 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 + constexpr ForwardIterator + search(ForwardIterator first, ForwardIterator last, const Searcher& searcher); + + namespace ranges { + // \ref{alg.starts.with}, starts 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> + requires @\libconcept{indirectly_comparable}@ + constexpr bool starts_with(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + 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> + requires (@\libconcept{forward_iterator}@ || @\libconcept{sized_sentinel_for}@) && + (@\libconcept{forward_iterator}@ || @\libconcept{sized_sentinel_for}@) && + @\libconcept{indirectly_comparable}@ + constexpr bool ends_with(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires (@\libconcept{forward_range}@ || @\libconcept{sized_range}@) && + (@\libconcept{forward_range}@ || @\libconcept{sized_range}@) && + @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + 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 + F @\exposid{f}@; // \expos + + public: + template requires @\libconcept{invocable}@ + invoke_result_t operator()(T&&, U&&); + }; + + template + concept @\defexposconcept{indirectly-binary-left-foldable-impl}@ = // \expos + @\libconcept{movable}@ && @\libconcept{movable}@ && + @\libconcept{convertible_to}@ && @\libconcept{invocable}@> && + @\libconcept{assignable_from}@>>; + + template + concept @\defexposconcept{indirectly-binary-left-foldable}@ = // \expos + @\libconcept{copy_constructible}@ && @\libconcept{indirectly_readable}@ && + @\libconcept{invocable}@> && + @\libconcept{convertible_to}@>, + decay_t>>> && + @\exposconcept{indirectly-binary-left-foldable-impl}@>>>; + + template + concept @\defexposconcept{indirectly-binary-right-foldable}@ = // \expos + @\exposconcept{indirectly-binary-left-foldable}@<@\exposid{flipped}@, T, I>; + + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class T = iter_value_t, + @\exposconcept{indirectly-binary-left-foldable}@ F> + constexpr auto fold_left(I first, S last, T init, F f); + + template<@\libconcept{input_range}@ R, class T = range_value_t, + @\exposconcept{indirectly-binary-left-foldable}@> F> + constexpr auto fold_left(R&& r, T init, F f); + + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, + @\exposconcept{indirectly-binary-left-foldable}@, I> F> + requires @\libconcept{constructible_from}@, iter_reference_t> + constexpr auto fold_left_first(I first, S last, F f); + + template<@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr auto fold_left_first(R&& r, F f); + + template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class T = iter_value_t, + @\exposconcept{indirectly-binary-right-foldable}@ F> + constexpr auto fold_right(I first, S last, T init, F f); + + template<@\libconcept{bidirectional_range}@ R, class T = range_value_t, + @\exposconcept{indirectly-binary-right-foldable}@> F> + constexpr auto fold_right(R&& r, T init, F f); + + 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); + + template<@\libconcept{bidirectional_range}@ R, + @\exposconcept{indirectly-binary-right-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr auto fold_right_last(R&& r, F f); + + template + using @\libglobal{fold_left_with_iter_result}@ = in_value_result; + template + 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> + constexpr @\seebelow@ fold_left_with_iter(I first, S last, T init, F f); + + template<@\libconcept{input_range}@ R, class T = range_value_t, + @\exposconcept{indirectly-binary-left-foldable}@> F> + constexpr @\seebelow@ fold_left_with_iter(R&& r, T init, F f); + + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, + @\exposconcept{indirectly-binary-left-foldable}@, I> F> + requires @\libconcept{constructible_from}@, iter_reference_t> + constexpr @\seebelow@ fold_left_first_with_iter(I first, S last, F f); + + template<@\libconcept{input_range}@ R, + @\exposconcept{indirectly-binary-left-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr @\seebelow@ fold_left_first_with_iter(R&& r, F f); + } + + // \ref{alg.modifying.operations}, mutating sequence operations + // \ref{alg.copy}, copy template - OutputIterator copy(InputIterator first, InputIterator last, - OutputIterator result); + constexpr OutputIterator copy(InputIterator first, InputIterator last, + OutputIterator result); + template + ForwardIterator2 copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + + namespace ranges { + template + using @\libglobal{copy_result}@ = in_out_result; + + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O> + requires @\libconcept{indirectly_copyable}@ + constexpr copy_result + copy(I first, S last, O result); + template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O> + 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 - OutputIterator copy_n(InputIterator first, Size n, - OutputIterator result); + constexpr OutputIterator copy_n(InputIterator first, Size n, + OutputIterator result); + template + ForwardIterator2 copy_n(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, Size n, + ForwardIterator2 result); + + namespace ranges { + template + 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 - OutputIterator copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); - template - BidirectionalIterator2 copy_backward( - BidirectionalIterator1 first, BidirectionalIterator1 last, - BidirectionalIterator2 result); + constexpr OutputIterator copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); + template + ForwardIterator2 copy_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred); + + namespace ranges { + template + 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> + requires @\libconcept{indirectly_copyable}@ + constexpr copy_if_result + copy_if(I first, S last, O result, Pred pred, Proj proj = {}); + template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + 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 + } - // \ref{alg.move}, move: - template - OutputIterator move(InputIterator first, InputIterator last, - OutputIterator result); template - BidirectionalIterator2 move_backward( - BidirectionalIterator1 first, BidirectionalIterator1 last, - BidirectionalIterator2 result); + constexpr BidirectionalIterator2 + copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, + BidirectionalIterator2 result); + + namespace ranges { + template + 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}@ + constexpr copy_backward_result + copy_backward(I1 first, S1 last, I2 result); + template<@\libconcept{bidirectional_range}@ R, @\libconcept{bidirectional_iterator}@ I> + requires @\libconcept{indirectly_copyable}@, I> + constexpr copy_backward_result, I> + copy_backward(R&& r, I result); + } + + // \ref{alg.move}, move + template + constexpr OutputIterator move(InputIterator first, InputIterator last, + OutputIterator result); + template + ForwardIterator2 move(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + + namespace ranges { + template + using @\libglobal{move_result}@ = in_out_result; + + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O> + requires @\libconcept{indirectly_movable}@ + constexpr move_result + move(I first, S last, O result); + template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O> + 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 + } - // \ref{alg.swap}, swap: + template + constexpr BidirectionalIterator2 + move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, + BidirectionalIterator2 result); + + namespace ranges { + template + 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}@ + constexpr move_backward_result + move_backward(I1 first, S1 last, I2 result); + template<@\libconcept{bidirectional_range}@ R, @\libconcept{bidirectional_iterator}@ I> + requires @\libconcept{indirectly_movable}@, I> + constexpr move_backward_result, I> + move_backward(R&& r, I result); + } + + // \ref{alg.swap}, swap template - ForwardIterator2 swap_ranges(ForwardIterator1 first1, - ForwardIterator1 last1, ForwardIterator2 first2); + constexpr ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + template + ForwardIterator2 swap_ranges(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + + namespace ranges { + template + 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}@ + constexpr swap_ranges_result + swap_ranges(I1 first1, S1 last1, I2 first2, S2 last2); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2> + 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 - void iter_swap(ForwardIterator1 a, ForwardIterator2 b); + constexpr void iter_swap(ForwardIterator1 a, ForwardIterator2 b); + // \ref{alg.transform}, transform template - OutputIterator transform(InputIterator first, InputIterator last, - OutputIterator result, UnaryOperation op); + constexpr OutputIterator + transform(InputIterator first1, InputIterator last1, + OutputIterator result, UnaryOperation op); template - OutputIterator transform(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, OutputIterator result, - BinaryOperation binary_op); - + class BinaryOperation> + constexpr OutputIterator + transform(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, OutputIterator result, + BinaryOperation binary_op); + template + ForwardIterator2 + transform(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 result, UnaryOperation op); + template + ForwardIterator + 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 @\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> + requires @\libconcept{indirectly_writable}@>> + constexpr unary_transform_result + transform(I first1, S last1, O result, F op, Proj proj = {}); + template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, @\libconcept{copy_constructible}@ F, + class Proj = identity> + requires @\libconcept{indirectly_writable}@, Proj>>> + 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 @\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>> + 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>>> + 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 template - void replace(ForwardIterator first, ForwardIterator last, + constexpr void replace(ForwardIterator first, ForwardIterator last, + const T& old_value, const T& new_value); + template::value_type> + void replace(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); - template - void replace_if(ForwardIterator first, ForwardIterator last, + template::value_type> + constexpr void replace_if(ForwardIterator first, ForwardIterator last, + Predicate pred, const T& new_value); + template::value_type> + void replace_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value); - template - OutputIterator replace_copy(InputIterator first, InputIterator last, - OutputIterator result, - const T& old_value, const T& new_value); - template - OutputIterator replace_copy_if(InputIterator first, InputIterator last, - OutputIterator result, - Predicate pred, const T& new_value); - template - void fill(ForwardIterator first, ForwardIterator last, const T& value); - template - OutputIterator fill_n(OutputIterator first, Size n, const T& value); + namespace ranges { + template<@\libconcept{input_iterator}@ I, @\libconcept{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*> + 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 = 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 = 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 = 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 + constexpr OutputIterator replace_copy(InputIterator first, InputIterator last, + OutputIterator result, + const T& old_value, const T& new_value); + template + 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); + template::value_type> + constexpr OutputIterator replace_copy_if(InputIterator first, InputIterator last, + OutputIterator result, + Predicate pred, const T& new_value); + template::value_type> + 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 @\libglobal{replace_copy_result}@ = in_out_result; + + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class O, + class Proj = identity, + class T1 = projected_value_t, class T2 = iter_value_t> + requires @\libconcept{indirectly_copyable}@ && + @\libconcept{indirect_binary_predicate}@, const T1*> && + @\libconcept{output_iterator}@ + constexpr replace_copy_result + replace_copy(I first, S last, O result, const T1& old_value, const T2& new_value, + Proj proj = {}); + template<@\libconcept{input_range}@ R, class O, class Proj = identity, + class T1 = projected_value_t, Proj>, class T2 = iter_value_t> + requires @\libconcept{indirectly_copyable}@, O> && + @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> && + @\libconcept{output_iterator}@ + constexpr replace_copy_result, O> + 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 @\libglobal{replace_copy_if_result}@ = in_out_result; + + 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 + replace_copy_if(I first, S last, O result, Pred pred, const T& new_value, + Proj proj = {}); + template<@\libconcept{input_range}@ R, class O, class T = iter_value_t, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, O> && @\libconcept{output_iterator}@ + 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 + template::value_type> + constexpr void fill(ForwardIterator first, ForwardIterator last, const T& value); + template::value_type> + 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); + template::value_type> + ForwardIterator fill_n(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, Size n, const T& value); + + namespace ranges { + template S, class T = iter_value_t> + requires @\libconcept{output_iterator}@ + constexpr O fill(O first, S last, const T& value); + template> + requires @\libconcept{output_range}@ + constexpr borrowed_iterator_t fill(R&& r, const T& value); + 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 template - void generate(ForwardIterator first, ForwardIterator last, + constexpr void generate(ForwardIterator first, ForwardIterator last, + Generator gen); + template + void generate(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Generator gen); template - OutputIterator generate_n(OutputIterator first, Size n, Generator gen); - - template - ForwardIterator remove(ForwardIterator first, ForwardIterator last, + constexpr OutputIterator generate_n(OutputIterator first, Size n, Generator gen); + template + ForwardIterator generate_n(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, Size n, Generator gen); + + namespace ranges { + template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{sentinel_for}@ S, @\libconcept{copy_constructible}@ F> + requires @\libconcept{invocable}@ && @\libconcept{indirectly_writable}@> + constexpr O generate(O first, S last, F gen); + template + requires @\libconcept{invocable}@ && @\libconcept{output_range}@> + constexpr borrowed_iterator_t generate(R&& r, F gen); + template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{copy_constructible}@ F> + requires @\libconcept{invocable}@ && @\libconcept{indirectly_writable}@> + constexpr O generate_n(O first, iter_difference_t n, F gen); + } + + // \ref{alg.remove}, remove + template::value_type> + constexpr ForwardIterator remove(ForwardIterator first, ForwardIterator last, + const T& value); + template::value_type> + ForwardIterator remove(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, const T& value); template - ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, + constexpr ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, + Predicate pred); + template + ForwardIterator remove_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred); - template - OutputIterator remove_copy(InputIterator first, InputIterator last, - OutputIterator result, const T& value); - template - OutputIterator remove_copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); + namespace ranges { + template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr subrange remove(I first, S last, const T& value, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{permutable}@> && + @\libconcept{indirect_binary_predicate}@, 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 = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + 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> + constexpr OutputIterator + remove_copy(InputIterator first, InputIterator last, + OutputIterator result, const T& value); + template::value_type> + ForwardIterator2 + remove_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, const T& value); + template + constexpr OutputIterator + remove_copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); + template + ForwardIterator2 + remove_copy_if(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred); + + namespace ranges { + template + 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> + requires @\libconcept{indirectly_copyable}@ && + @\libconcept{indirect_binary_predicate}@, const T*> + constexpr remove_copy_result + remove_copy(I first, S last, O result, const T& value, Proj proj = {}); + template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{indirectly_copyable}@, O> && + @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + 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 @\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> + requires @\libconcept{indirectly_copyable}@ + constexpr remove_copy_if_result + remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {}); + template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + 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 template - ForwardIterator unique(ForwardIterator first, ForwardIterator last); + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last); template - ForwardIterator unique(ForwardIterator first, ForwardIterator last, + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); + template + ForwardIterator unique(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + ForwardIterator unique(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, BinaryPredicate pred); + + namespace ranges { + template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_equivalence_relation}@> C = ranges::equal_to> + constexpr subrange unique(I first, S last, C comp = {}, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_equivalence_relation}@, Proj>> C = ranges::equal_to> + 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 - OutputIterator unique_copy(InputIterator first, InputIterator last, - OutputIterator result); + constexpr OutputIterator + unique_copy(InputIterator first, InputIterator last, + OutputIterator result); template - OutputIterator unique_copy(InputIterator first, InputIterator last, - OutputIterator result, BinaryPredicate pred); - + constexpr OutputIterator + unique_copy(InputIterator first, InputIterator last, + OutputIterator result, BinaryPredicate pred); + template + ForwardIterator2 + unique_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + template + ForwardIterator2 + unique_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryPredicate pred); + + namespace ranges { + template + 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> + requires @\libconcept{indirectly_copyable}@ && + (@\libconcept{forward_iterator}@ || + (@\libconcept{input_iterator}@ && @\libconcept{same_as}@, iter_value_t>) || + @\libconcept{indirectly_copyable_storable}@) + constexpr unique_copy_result + unique_copy(I first, S last, O result, C comp = {}, Proj proj = {}); + template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, class Proj = identity, + @\libconcept{indirect_equivalence_relation}@, Proj>> C = ranges::equal_to> + requires @\libconcept{indirectly_copyable}@, O> && + (@\libconcept{forward_iterator}@> || + (@\libconcept{input_iterator}@ && @\libconcept{same_as}@, iter_value_t>) || + @\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 - void reverse(BidirectionalIterator first, BidirectionalIterator last); - template - OutputIterator reverse_copy(BidirectionalIterator first, - BidirectionalIterator last, - OutputIterator result); + constexpr void reverse(BidirectionalIterator first, BidirectionalIterator last); + template + void reverse(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + BidirectionalIterator first, BidirectionalIterator last); + + namespace ranges { + template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S> + requires @\libconcept{permutable}@ + constexpr I reverse(I first, S last); + 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 + constexpr OutputIterator + reverse_copy(BidirectionalIterator first, BidirectionalIterator last, + OutputIterator result); + template + ForwardIterator + reverse_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + BidirectionalIterator first, BidirectionalIterator last, + ForwardIterator result); + + namespace ranges { + template + 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}@ + constexpr reverse_copy_result + reverse_copy(I first, S last, O result); + template<@\libconcept{bidirectional_range}@ R, @\libconcept{weakly_incrementable}@ O> + 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 template - ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, + constexpr ForwardIterator rotate(ForwardIterator first, + ForwardIterator middle, + ForwardIterator last); + template + ForwardIterator rotate(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, + ForwardIterator middle, ForwardIterator last); - template - OutputIterator rotate_copy( - ForwardIterator first, ForwardIterator middle, - ForwardIterator last, OutputIterator result); - // \ref{alg.random.shuffle}, shuffle: - template - void shuffle(RandomAccessIterator first, - RandomAccessIterator last, - UniformRandomNumberGenerator&& g); - - // \ref{alg.partitions}, partitions: - template - bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); + namespace ranges { + template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S> + constexpr subrange rotate(I first, I middle, S last); + 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 - ForwardIterator partition(ForwardIterator first, - ForwardIterator last, - Predicate pred); - template - BidirectionalIterator stable_partition(BidirectionalIterator first, - BidirectionalIterator last, - Predicate pred); - template - pair - partition_copy(InputIterator first, InputIterator last, - OutputIterator1 out_true, OutputIterator2 out_false, - Predicate pred); - template - ForwardIterator partition_point(ForwardIterator first, - ForwardIterator last, - Predicate pred); + template + constexpr OutputIterator + rotate_copy(ForwardIterator first, ForwardIterator middle, + ForwardIterator last, OutputIterator result); + template + ForwardIterator2 + rotate_copy(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 middle, + ForwardIterator1 last, ForwardIterator2 result); + + namespace ranges { + template + 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}@ + constexpr rotate_copy_result + rotate_copy(I first, I middle, S last, O result); + template<@\libconcept{forward_range}@ R, @\libconcept{weakly_incrementable}@ O> + 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 + template + SampleIterator sample(PopulationIterator first, PopulationIterator last, + SampleIterator out, Distance n, + UniformRandomBitGenerator&& g); + + namespace ranges { + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, + @\libconcept{weakly_incrementable}@ O, class Gen> + requires (@\libconcept{forward_iterator}@ || @\libconcept{random_access_iterator}@) && + @\libconcept{indirectly_copyable}@ && + @\libconcept{uniform_random_bit_generator}@> + O sample(I first, S last, O out, iter_difference_t n, Gen&& g); + template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, class Gen> + requires (@\libconcept{forward_range}@ || @\libconcept{random_access_iterator}@) && + @\libconcept{indirectly_copyable}@, O> && + @\libconcept{uniform_random_bit_generator}@> + O sample(R&& r, O out, range_difference_t n, Gen&& g); + } + + // \ref{alg.random.shuffle}, shuffle + template + void shuffle(RandomAccessIterator first, + RandomAccessIterator last, + UniformRandomBitGenerator&& g); + + namespace ranges { + template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Gen> + requires @\libconcept{permutable}@ && + @\libconcept{uniform_random_bit_generator}@> + I shuffle(I first, S last, Gen&& g); + template<@\libconcept{random_access_range}@ R, class Gen> + requires @\libconcept{permutable}@> && + @\libconcept{uniform_random_bit_generator}@> + borrowed_iterator_t shuffle(R&& r, Gen&& g); + } + + // \ref{alg.shift}, shift + template + constexpr ForwardIterator + shift_left(ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); + template + ForwardIterator + shift_left(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); + + namespace ranges { + template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S> + constexpr subrange shift_left(I first, S last, iter_difference_t n); + 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 + } - // \ref{alg.sorting}, sorting and related operations: - // \ref{alg.sort}, sorting: + template + constexpr ForwardIterator + shift_right(ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); + template + ForwardIterator + shift_right(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); + + namespace ranges { + template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S> + constexpr subrange shift_right(I first, S last, iter_difference_t n); + 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 + // \ref{alg.sort}, sorting template - void sort(RandomAccessIterator first, RandomAccessIterator last); + constexpr void sort(RandomAccessIterator first, RandomAccessIterator last); template - void sort(RandomAccessIterator first, RandomAccessIterator last, + constexpr void sort(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + template + void sort(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last); + template + void sort(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last, Compare comp); + namespace ranges { + template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + sort(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + 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 - void stable_sort(RandomAccessIterator first, RandomAccessIterator last); + constexpr void stable_sort(RandomAccessIterator first, RandomAccessIterator last); // hosted template - void stable_sort(RandomAccessIterator first, RandomAccessIterator last, + constexpr void stable_sort(RandomAccessIterator first, RandomAccessIterator last, // hosted + Compare comp); + template + void stable_sort(ExecutionPolicy&& exec, // hosted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last); + template + void stable_sort(ExecutionPolicy&& exec, // hosted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last, Compare comp); + namespace ranges { + 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 = {}); // 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 = {}); // 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 - void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last); + constexpr void partial_sort(RandomAccessIterator first, RandomAccessIterator middle, + RandomAccessIterator last); template - void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, + constexpr void partial_sort(RandomAccessIterator first, RandomAccessIterator middle, + RandomAccessIterator last, Compare comp); + template + void partial_sort(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator middle, + RandomAccessIterator last); + template + void partial_sort(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); + + namespace ranges { + template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + partial_sort(I first, I middle, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + 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 - RandomAccessIterator partial_sort_copy( - InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last); + constexpr RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last); template - RandomAccessIterator partial_sort_copy( - InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last, - Compare comp); + constexpr RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Compare comp); + template + RandomAccessIterator + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Compare comp); + + namespace ranges { + template + 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, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_copyable}@ && @\libconcept{sortable}@ && + @\libconcept{indirect_strict_weak_order}@, projected> + constexpr partial_sort_copy_result + partial_sort_copy(I1 first, S1 last, I2 result_first, S2 result_last, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{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>> + 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 - bool is_sorted(ForwardIterator first, ForwardIterator last); + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last); template - bool is_sorted(ForwardIterator first, ForwardIterator last, + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last, + Compare comp); + template + bool is_sorted(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + bool is_sorted(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Compare comp); + + namespace ranges { + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr bool is_sorted(I first, S last, Comp comp = {}, Proj proj = {}); + 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 - ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last); + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last); template - ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last, - Compare comp); + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last, + Compare comp); + template + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Compare comp); + namespace ranges { + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr I is_sorted_until(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + @\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 - void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last); + constexpr void nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last); template - void nth_element(RandomAccessIterator first, RandomAccessIterator nth, + constexpr void nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last, Compare comp); + template + void nth_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last); + template + void nth_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); - // \ref{alg.binary.search}, binary search: - template - ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, - const T& value); - template - ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); + namespace ranges { + template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + 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 + template::value_type> + constexpr ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, + const T& value); + template::value_type, + class Compare> + constexpr ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); - template - ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, - const T& value); - template - ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); + 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 I lower_bound(I first, S last, const T& value, Comp comp = {}, + Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = + ranges::less> + constexpr borrowed_iterator_t + lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); + } + + template::value_type> + constexpr ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, + const T& value); + template::value_type, + class Compare> + constexpr ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); - template - pair + 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 I upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = + ranges::less> + constexpr borrowed_iterator_t + upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); + } + + template::value_type> + constexpr pair equal_range(ForwardIterator first, ForwardIterator last, const T& value); - template - pair + template::value_type, + class Compare> + constexpr pair equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); - template - bool binary_search(ForwardIterator first, ForwardIterator last, - const T& value); - template - bool binary_search(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); + 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 = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = + ranges::less> + constexpr borrowed_subrange_t + equal_range(R&& r, const T& value, Comp comp = {}, Proj proj = {}); + } + + template::value_type> + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value); + template::value_type, + class Compare> + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); + + 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 bool binary_search(I first, S last, const T& value, Comp comp = {}, + Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = + ranges::less> + constexpr bool binary_search(R&& r, const T& value, Comp comp = {}, + Proj proj = {}); + } + + // \ref{alg.partitions}, partitions + template + constexpr bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); + template + bool is_partitioned(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred); + + namespace ranges { + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr bool is_partitioned(I first, S last, Pred pred, Proj proj = {}); + 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 + constexpr ForwardIterator partition(ForwardIterator first, + ForwardIterator last, + Predicate pred); + template + ForwardIterator partition(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, + ForwardIterator last, + Predicate pred); + + namespace ranges { + template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr subrange + partition(I first, S last, Pred pred, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + 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, // hosted + BidirectionalIterator last, + Predicate pred); + template + BidirectionalIterator stable_partition(ExecutionPolicy&& exec, // hosted, + BidirectionalIterator first, // see \ref{algorithms.parallel.overloads} + BidirectionalIterator last, + Predicate pred); + + namespace ranges { + 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, // 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, // 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 + constexpr pair + partition_copy(InputIterator first, InputIterator last, + OutputIterator1 out_true, OutputIterator2 out_false, + Predicate pred); + template + pair + 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 @\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, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_copyable}@ && @\libconcept{indirectly_copyable}@ + constexpr partition_copy_result + partition_copy(I first, S last, O1 out_true, O2 out_false, Pred pred, + Proj proj = {}); + template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O1, @\libconcept{weakly_incrementable}@ O2, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, O1> && + @\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 + } - // \ref{alg.merge}, merge: + template + constexpr ForwardIterator + partition_point(ForwardIterator first, ForwardIterator last, + Predicate pred); + + namespace ranges { + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr I partition_point(I first, S last, Pred pred, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + constexpr borrowed_iterator_t + partition_point(R&& r, Pred pred, Proj proj = {}); + } + + // \ref{alg.merge}, merge template - OutputIterator merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); + constexpr OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); template - OutputIterator merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + class Compare> + constexpr OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); + template + ForwardIterator + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + + namespace ranges { + template + 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, + class Proj2 = identity> + requires @\libconcept{mergeable}@ + constexpr merge_result + merge(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, O, Comp, Proj1, Proj2> + 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 - void inplace_merge(BidirectionalIterator first, + constexpr void inplace_merge(BidirectionalIterator first, // hosted + BidirectionalIterator middle, + BidirectionalIterator last); + template + constexpr void inplace_merge(BidirectionalIterator first, // hosted + BidirectionalIterator middle, + BidirectionalIterator last, Compare comp); + template + void inplace_merge(ExecutionPolicy&& exec, // hosted, see \ref{algorithms.parallel.overloads} + BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); - template - void inplace_merge(BidirectionalIterator first, + template + void inplace_merge(ExecutionPolicy&& exec, // hosted, see \ref{algorithms.parallel.overloads} + BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); - // \ref{alg.set.operations}, set operations: + namespace ranges { + 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 = {}); // 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 = {}); // 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 template - bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); template - bool includes( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, Compare comp); + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp); + template + bool includes(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + bool includes(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + Compare comp); - template - OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + namespace ranges { + template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, projected> Comp = + ranges::less> + constexpr bool includes(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Proj1 = identity, + class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, Proj1>, + 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 - OutputIterator set_intersection( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - OutputIterator set_intersection( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + constexpr OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); + template + constexpr OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); + template + ForwardIterator + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + + namespace ranges { + template + 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, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + constexpr set_union_result + set_union(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, O, Comp, Proj1, Proj2> + 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 - OutputIterator set_difference( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - OutputIterator set_difference( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + constexpr OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); + template + constexpr OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); + template + ForwardIterator + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + + namespace ranges { + template + 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, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + constexpr set_intersection_result + set_intersection(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, O, Comp, Proj1, Proj2> + 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 - OutputIterator set_symmetric_difference( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - OutputIterator set_symmetric_difference( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); + constexpr OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); + template + constexpr OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); + template + ForwardIterator + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + + namespace ranges { + template + 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, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + constexpr set_difference_result + set_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, O, Comp, Proj1, Proj2> + 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 + } - // \ref{alg.heap.operations}, heap operations: + template + constexpr OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); + template + constexpr OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); + template + ForwardIterator + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + + namespace ranges { + template + 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, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@ + constexpr set_symmetric_difference_result + set_symmetric_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, + Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, O, Comp, Proj1, Proj2> + constexpr set_symmetric_difference_result, + 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 template - void push_heap(RandomAccessIterator first, RandomAccessIterator last); + constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last); template - void push_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); + constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + + namespace ranges { + template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + push_heap(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr borrowed_iterator_t + push_heap(R&& r, Comp comp = {}, Proj proj = {}); + } template - void pop_heap(RandomAccessIterator first, RandomAccessIterator last); + constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last); template - void pop_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); + constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + + namespace ranges { + template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + pop_heap(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr borrowed_iterator_t + pop_heap(R&& r, Comp comp = {}, Proj proj = {}); + } template - void make_heap(RandomAccessIterator first, RandomAccessIterator last); + constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last); template - void make_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); + constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + + namespace ranges { + template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + make_heap(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr borrowed_iterator_t + make_heap(R&& r, Comp comp = {}, Proj proj = {}); + } template - void sort_heap(RandomAccessIterator first, RandomAccessIterator last); + constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last); template - void sort_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); + constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + + namespace ranges { + template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + sort_heap(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr borrowed_iterator_t + sort_heap(R&& r, Comp comp = {}, Proj proj = {}); + } template - bool is_heap(RandomAccessIterator first, RandomAccessIterator last); + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last); template - bool is_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + template + bool is_heap(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last); + template + bool is_heap(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + + namespace ranges { + template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {}); + 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 - RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last); + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last); template - RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + template + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last); + template + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); - // \ref{alg.min.max}, minimum and maximum: + namespace ranges { + template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{random_access_range}@ R, class Proj = identity, + @\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 template constexpr const T& min(const T& a, const T& b); template constexpr const T& min(const T& a, const T& b, Compare comp); @@ -500,6 +3883,25 @@ template constexpr T min(initializer_list t, Compare comp); + namespace ranges { + template> Comp = ranges::less> + constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); + template<@\libconcept{copyable}@ T, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr T min(initializer_list r, Comp comp = {}, Proj proj = {}); + template<@\libconcept{input_range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + 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); template constexpr const T& max(const T& a, const T& b, Compare comp); @@ -508,6 +3910,25 @@ template constexpr T max(initializer_list t, Compare comp); + namespace ranges { + template> Comp = ranges::less> + constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); + template<@\libconcept{copyable}@ T, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr T max(initializer_list r, Comp comp = {}, Proj proj = {}); + template<@\libconcept{input_range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + 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); template constexpr pair minmax(const T& a, const T& b, Compare comp); @@ -516,3480 +3937,10574 @@ template constexpr pair minmax(initializer_list t, Compare comp); + namespace ranges { + template + using @\libglobal{minmax_result}@ = min_max_result; + + template> Comp = ranges::less> + constexpr minmax_result + minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); + template<@\libconcept{copyable}@ T, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr minmax_result + minmax(initializer_list r, Comp comp = {}, Proj proj = {}); + template<@\libconcept{input_range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + 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 - ForwardIterator min_element(ForwardIterator first, ForwardIterator last); + constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last); template - ForwardIterator min_element(ForwardIterator first, ForwardIterator last, + constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last, + Compare comp); + template + ForwardIterator min_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + ForwardIterator min_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Compare comp); + + namespace ranges { + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr I min_element(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + @\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 - ForwardIterator max_element(ForwardIterator first, ForwardIterator last); + constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last); template - ForwardIterator max_element(ForwardIterator first, ForwardIterator last, + constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last, + Compare comp); + template + ForwardIterator max_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + ForwardIterator max_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Compare comp); + + namespace ranges { + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr I max_element(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + @\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 - pair + constexpr pair minmax_element(ForwardIterator first, ForwardIterator last); template - pair + constexpr pair minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); + template + pair + minmax_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + pair + minmax_element(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Compare comp); + + namespace ranges { + template + 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> + constexpr minmax_element_result + minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{forward_range}@ R, class Proj = identity, + @\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 + template + constexpr const T& clamp(const T& v, const T& lo, const T& hi); + template + constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp); + + namespace ranges { + template> Comp = ranges::less> + constexpr const T& + clamp(const T& v, const T& lo, const T& hi, Comp comp = {}, Proj proj = {}); + } + // \ref{alg.lex.comparison}, lexicographical comparison template - bool lexicographical_compare( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); + constexpr bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); template - bool lexicographical_compare( - InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - Compare comp); + constexpr bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp); + template + bool + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + Compare comp); + + namespace ranges { + template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, projected> Comp = + ranges::less> + constexpr bool + lexicographical_compare(I1 first1, S1 last1, I2 first2, S2 last2, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Proj1 = identity, + class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, Proj1>, + projected, Proj2>> Comp = ranges::less> + 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 + template + constexpr auto + lexicographical_compare_three_way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2, + Cmp comp) + -> decltype(comp(*b1, *b2)); + template + constexpr auto + lexicographical_compare_three_way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2); - // \ref{alg.permutation.generators}, permutations: + // \ref{alg.permutation.generators}, permutations template - bool next_permutation(BidirectionalIterator first, - BidirectionalIterator last); + constexpr bool next_permutation(BidirectionalIterator first, + BidirectionalIterator last); template - bool next_permutation(BidirectionalIterator first, - BidirectionalIterator last, Compare comp); + constexpr bool next_permutation(BidirectionalIterator first, + BidirectionalIterator last, Compare comp); + + namespace ranges { + template + using @\libglobal{next_permutation_result}@ = in_found_result; + + template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr next_permutation_result + next_permutation(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{bidirectional_range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr next_permutation_result> + next_permutation(R&& r, Comp comp = {}, Proj proj = {}); + } + template - bool prev_permutation(BidirectionalIterator first, - BidirectionalIterator last); + constexpr bool prev_permutation(BidirectionalIterator first, + BidirectionalIterator last); template - bool prev_permutation(BidirectionalIterator first, - BidirectionalIterator last, Compare comp); + constexpr bool prev_permutation(BidirectionalIterator first, + BidirectionalIterator last, Compare comp); + + namespace ranges { + template + using @\libglobal{prev_permutation_result}@ = in_found_result; + + template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr prev_permutation_result + prev_permutation(I first, S last, Comp comp = {}, Proj proj = {}); + template<@\libconcept{bidirectional_range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr prev_permutation_result> + prev_permutation(R&& r, Comp comp = {}, Proj proj = {}); + } +} +\end{codeblock} + +\rSec1[algorithms.results]{Algorithm result types} + +\pnum +Each of the class templates specified in this subclause +has the template parameters, data members, and special members specified below, +and has no base classes or members other than those specified. + +\begin{codeblock} +namespace std::ranges { + template + 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}@ + constexpr operator in_fun_result() const & { + return {in, fun}; + } + + template + requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ + constexpr operator in_fun_result() && { + return {std::move(in), std::move(fun)}; + } + }; + + template + 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}@ + constexpr operator in_in_result() const & { + return {in1, in2}; + } + + template + requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ + constexpr operator in_in_result() && { + return {std::move(in1), std::move(in2)}; + } + }; + + template + 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}@ + constexpr operator in_out_result() const & { + return {in, out}; + } + + template + requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ + constexpr operator in_out_result() && { + return {std::move(in), std::move(out)}; + } + }; + + template + 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}@ && + @\libconcept{convertible_to}@ && + @\libconcept{convertible_to}@ + constexpr operator in_in_out_result() const & { + return {in1, in2, out}; + } + + template + requires @\libconcept{convertible_to}@ && + @\libconcept{convertible_to}@ && + @\libconcept{convertible_to}@ + constexpr operator in_in_out_result() && { + return {std::move(in1), std::move(in2), std::move(out)}; + } + }; + + template + 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}@ && + @\libconcept{convertible_to}@ && + @\libconcept{convertible_to}@ + constexpr operator in_out_out_result() const & { + return {in, out1, out2}; + } + + template + requires @\libconcept{convertible_to}@ && + @\libconcept{convertible_to}@ && + @\libconcept{convertible_to}@ + constexpr operator in_out_out_result() && { + return {std::move(in), std::move(out1), std::move(out2)}; + } + }; + + template + 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}@ + constexpr operator min_max_result() const & { + return {min, max}; + } + + template + requires @\libconcept{convertible_to}@ + constexpr operator min_max_result() && { + return {std::move(min), std::move(max)}; + } + }; + + template + 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}@ + constexpr operator in_found_result() const & { + return {in, found}; + } + template + requires @\libconcept{convertible_to}@ + constexpr operator in_found_result() && { + return {std::move(in), found}; + } + }; + + template + 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}@ + constexpr operator in_value_result() const & { + return {in, value}; + } + + template + requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ + constexpr operator in_value_result() && { + return {std::move(in), std::move(value)}; + } + }; + + template + 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}@ + constexpr operator out_value_result() const & { + return {out, value}; + } + + template + requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ + constexpr operator out_value_result() && { + return {std::move(out), std::move(value)}; + } + }; } \end{codeblock} +\rSec1[alg.nonmodifying]{Non-modifying sequence operations} + +\rSec2[alg.all.of]{All of} + +\indexlibraryglobal{all_of}% +\begin{itemdecl} +template + constexpr bool all_of(InputIterator first, InputIterator last, Predicate pred); +template + bool all_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + Predicate pred); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr bool ranges::all_of(I first, S last, Pred pred, Proj proj = {}); +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} +\pnum +Let $E$ be: +\begin{itemize} +\item + \tcode{pred(*i)} for the overloads in namespace \tcode{std}; +\item + \tcode{invoke(pred, invoke(proj, *i))} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\returns +\tcode{false} if $E$ is \tcode{false} +for some iterator \tcode{i} in the range \range{first}{last}, and +\tcode{true} otherwise. + +\pnum +\complexity +At most \tcode{last - first} applications of the predicate and any projection. +\end{itemdescr} + +\rSec2[alg.any.of]{Any of} + +\indexlibraryglobal{any_of}% +\begin{itemdecl} +template + constexpr bool any_of(InputIterator first, InputIterator last, Predicate pred); +template + bool any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + Predicate pred); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr bool ranges::any_of(I first, S last, Pred pred, Proj proj = {}); +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} +\pnum +Let $E$ be: +\begin{itemize} +\item + \tcode{pred(*i)} for the overloads in namespace \tcode{std}; +\item + \tcode{invoke(pred, invoke(proj, *i))} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\returns +\tcode{true} if $E$ is \tcode{true} for some iterator \tcode{i} +in the range \range{first}{last}, and \tcode{false} otherwise. + +\pnum +\complexity +At most \tcode{last - first} applications of the predicate +and any projection. +\end{itemdescr} + +\rSec2[alg.none.of]{None of} + +\indexlibraryglobal{none_of}% +\begin{itemdecl} +template + constexpr bool none_of(InputIterator first, InputIterator last, Predicate pred); +template + bool none_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + Predicate pred); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr bool ranges::none_of(I first, S last, Pred pred, Proj proj = {}); +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} +\pnum +Let $E$ be: +\begin{itemize} +\item + \tcode{pred(*i)} for the overloads in namespace \tcode{std}; +\item + \tcode{invoke(pred, invoke(proj, *i))} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\returns +\tcode{false} if $E$ is \tcode{true} +for some iterator \tcode{i} in the range \range{first}{last}, and +\tcode{true} otherwise. + +\pnum +\complexity +At most \tcode{last - first} applications of the predicate and any projection. +\end{itemdescr} + +\rSec2[alg.contains]{Contains} + +\indexlibraryglobal{contains}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr bool ranges::contains(I first, S last, const T& value, Proj proj = {}); +template<@\libconcept{input_range}@ R, class Proj = identity, class T = projected_value_t, Proj>> + requires @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + constexpr bool ranges::contains(R&& r, const T& value, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\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, + @\libconcept{forward_iterator}@ I2, @\libconcept{sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + constexpr bool ranges::contains_subrange(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{forward_range}@ R1, @\libconcept{forward_range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + constexpr bool ranges::contains_subrange(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\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} + +\indexlibraryglobal{for_each}% +\begin{itemdecl} +template + constexpr Function for_each(InputIterator first, InputIterator last, Function f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{Function} meets +the \oldconcept{MoveConstructible} requirements (\tref{cpp17.moveconstructible}). +\begin{note} +\tcode{Function} need not meet the requirements of +\oldconcept{CopyConstructible} (\tref{cpp17.copyconstructible}). +\end{note} + +\pnum +\effects +Applies \tcode{f} to the result of dereferencing +every iterator in the range \range{first}{last}, +starting from \tcode{first} and proceeding to \tcode{last - 1}. +\begin{note} +If the type of \tcode{first} meets the requirements of a mutable iterator, +\tcode{f} can apply non-constant functions through the dereferenced iterator. +\end{note} + +\pnum +\returns +\tcode{f}. + +\pnum +\complexity +Applies \tcode{f} exactly \tcode{last - first} times. + +\pnum +\remarks +If \tcode{f} returns a result, the result is ignored. +\end{itemdescr} + +\indexlibraryglobal{for_each}% +\begin{itemdecl} +template + void for_each(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Function f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{Function} meets the \oldconcept{CopyConstructible} requirements. + +\pnum +\effects +Applies \tcode{f} to the result of dereferencing +every iterator in the range \range{first}{last}. +\begin{note} +If the type of \tcode{first} meets the requirements of a mutable iterator, +\tcode{f} can apply non-constant functions through the dereferenced iterator. +\end{note} + +\pnum +\complexity +Applies \tcode{f} exactly \tcode{last - first} times. + +\pnum +\remarks +If \tcode{f} returns a result, the result is ignored. +Implementations do not have +the freedom granted under \ref{algorithms.parallel.exec} +to make arbitrary copies of elements from the input sequence. + +\pnum +\begin{note} +Does not return a copy of its \tcode{Function} parameter, +since parallelization often does not permit efficient state accumulation. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{for_each}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirectly_unary_invocable}@> Fun> + constexpr ranges::for_each_result + ranges::for_each(I first, S last, Fun f, Proj proj = {}); +template<@\libconcept{input_range}@ R, class Proj = identity, + @\libconcept{indirectly_unary_invocable}@, Proj>> Fun> + constexpr ranges::for_each_result, Fun> + ranges::for_each(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}, +starting from \tcode{first} and proceeding to \tcode{last - 1}. +\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, std::move(f)\}}. + +\pnum +\complexity +Applies \tcode{f} and \tcode{proj} exactly \tcode{last - first} times. + +\pnum +\remarks +If \tcode{f} returns a result, the result is ignored. + +\pnum +\begin{note} +The overloads in namespace \tcode{ranges} require +\tcode{Fun} to model \libconcept{copy_constructible}. +\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 + constexpr InputIterator for_each_n(InputIterator first, Size n, Function f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +The type \tcode{Size} is convertible +to an integral type\iref{conv.integral,class.conv}. + +\pnum +\expects +\tcode{n >= 0} is \tcode{true}. +\tcode{Function} meets the \oldconcept{MoveConstructible} requirements. +\begin{note} +\tcode{Function} need not meet +the requirements of \oldconcept{CopyConstructible}. +\end{note} + +\pnum +\effects +Applies \tcode{f} to the result of dereferencing +every iterator in the range \range{first}{first + n} in order. +\begin{note} +If the type of \tcode{first} meets the requirements of a mutable iterator, +\tcode{f} can apply non-constant functions through the dereferenced iterator. +\end{note} + +\pnum +\returns +\tcode{first + n}. + +\pnum +\remarks +If \tcode{f} returns a result, the result is ignored. +\end{itemdescr} + +\indexlibraryglobal{for_each_n}% +\begin{itemdecl} +template + ForwardIterator for_each_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, + Function f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +The type \tcode{Size} is convertible +to an integral type\iref{conv.integral,class.conv}. + +\pnum +\expects +\tcode{n >= 0} is \tcode{true}. +\tcode{Function} meets the \oldconcept{CopyConstructible} requirements. + +\pnum +\effects +Applies \tcode{f} to the result of dereferencing +every iterator in the range \range{first}{first + n}. +\begin{note} +If the type of \tcode{first} meets the requirements of a mutable iterator, +\tcode{f} can apply non-constant functions through the dereferenced iterator. +\end{note} + +\pnum +\returns +\tcode{first + n}. + +\pnum +\remarks +If \tcode{f} returns a result, the result is ignored. +Implementations do not have +the freedom granted under \ref{algorithms.parallel.exec} +to make arbitrary copies of elements from the input sequence. +\end{itemdescr} + +\indexlibraryglobal{for_each_n}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, class Proj = identity, + @\libconcept{indirectly_unary_invocable}@> Fun> + constexpr ranges::for_each_n_result + ranges::for_each_n(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} in order. +\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, std::move(f)\}}. + +\pnum +\remarks +If \tcode{f} returns a result, the result is ignored. + +\pnum +\begin{note} +The overload in namespace \tcode{ranges} +requires \tcode{Fun} to model \libconcept{copy_constructible}. +\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}% +\indexlibraryglobal{find_if}% +\indexlibraryglobal{find_if_not}% +\begin{itemdecl} +template::value_type> + constexpr InputIterator find(InputIterator first, InputIterator last, + const T& value); +template::value_type> + ForwardIterator find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + const T& value); + +template + constexpr InputIterator find_if(InputIterator first, InputIterator last, + Predicate pred); +template + ForwardIterator find_if(ExecutionPolicy&& exec, 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, + ForwardIterator first, ForwardIterator last, + Predicate pred); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr I ranges::find(I first, S last, const T& value, Proj proj = {}); +template<@\libconcept{input_range}@ R, class Proj = identity, class T = projected_value_t, Proj>> + 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 = {}); +template<@\libconcept{input_range}@ R, class Proj = identity, + @\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 = {}); +template<@\libconcept{input_range}@ R, class Proj = identity, + @\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} +\pnum +Let $E$ be: +\begin{itemize} +\item \tcode{*i == value} for \tcode{find}; +\item \tcode{pred(*i) != false} for \tcode{find_if}; +\item \tcode{pred(*i) == false} for \tcode{find_if_not}; +\item \tcode{bool(invoke(proj, *i) == value)} for \tcode{ranges::find}; +\item \tcode{bool(invoke(pred, invoke(proj, *i)))} for \tcode{ranges::find_if}; +\item \tcode{bool(!invoke(pred, invoke(proj, *i)))} for \tcode{ranges::find_if_not}. +\end{itemize} + +\pnum +\returns +The first iterator \tcode{i} in the range \range{first}{last} +for which $E$ is \tcode{true}. +Returns \tcode{last} if no such iterator is found. + +\pnum +\complexity +At most \tcode{last - first} applications +of the corresponding predicate and any projection. +\end{itemdescr} + +\rSec2[alg.find.last]{Find last} + +\indexlibraryglobal{find_last}% +\begin{itemdecl} +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr subrange ranges::find_last(I first, S last, const T& value, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{indirect_binary_predicate}@, Proj>, const T*> + constexpr borrowed_subrange_t ranges::find_last(R&& r, const T& value, Proj proj = {}); + +template<@\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} +\pnum +Let $E$ be: +\begin{itemize} +\item +\tcode{bool(invoke(proj, *i) == value)} for \tcode{ranges::find_last}; +\item +\tcode{bool(invoke(pred, invoke(proj, *i)))} for \tcode{ranges::find_last_if}; +\item +\tcode{bool(!invoke(pred, invoke(proj, *i)))} for \tcode{ranges::find_last_if_not}. +\end{itemize} + +\pnum +\returns +Let \tcode{i} be the last iterator in the range \range{first}{last} +for which $E$ is \tcode{true}. +Returns \tcode{\{i, last\}}, or +\tcode{\{last, last\}} if no such iterator is found. + +\pnum +\complexity +At most \tcode{last - first} applications of +the corresponding predicate and projection. +\end{itemdescr} + +\rSec2[alg.find.end]{Find end} + +\indexlibraryglobal{find_end}% +\begin{itemdecl} +template + constexpr ForwardIterator1 + find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); +template + ForwardIterator1 + find_end(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + +template + constexpr ForwardIterator1 + find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +template + ForwardIterator1 + find_end(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + +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> + requires @\libconcept{indirectly_comparable}@ + constexpr subrange + ranges::find_end(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{forward_range}@ R1, @\libconcept{forward_range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + 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} +\pnum +Let: +\begin{itemize} +\item + \tcode{pred} be \tcode{equal_to\{\}} + for the overloads with no parameter \tcode{pred}; +\item + $E$ be: + \begin{itemize} + \item + \tcode{pred(*(i + n), *(first2 + n))} + for the overloads in namespace \tcode{std}; + \item + \tcode{invoke(pred, invoke(proj1, *(i + n)), invoke(proj2, *(first2 + n)))} + for the overloads in namespace \tcode{ranges}; + \end{itemize} +\item + \tcode{i} be \tcode{last1} if \range{first2}{last2} is empty, + or if \tcode{(last2 - first2) > (last1 - first1)} is \tcode{true}, + or if there is no iterator + in the range \range{first1}{last1 - (last2 - first2)} + such that for every non-negative integer + \tcode{n < (last2 - first2)}, $E$ is \tcode{true}. + Otherwise \tcode{i} is the last such iterator + in \range{first1}{last1 - (last2 - first2)}. +\end{itemize} + +\pnum +\returns +\begin{itemize} +\item \tcode{i} for the overloads in namespace \tcode{std}. +\item \tcode{\{i, i + (i == last1 ? 0 : last2 - first2)\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +At most +\tcode{(last2 - first2) * (last1 - first1 - (last2 - first2) + 1)} +applications of the corresponding predicate and any projections. +\end{itemdescr} + +\rSec2[alg.find.first.of]{Find first of} + +\indexlibraryglobal{find_first_of}% +\begin{itemdecl} +template + constexpr InputIterator + find_first_of(InputIterator first1, InputIterator last1, + ForwardIterator first2, ForwardIterator last2); +template + ForwardIterator1 + find_first_of(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + +template + constexpr InputIterator + find_first_of(InputIterator first1, InputIterator last1, + ForwardIterator first2, ForwardIterator last2, + BinaryPredicate pred); +template + ForwardIterator1 + find_first_of(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + +template<@\libconcept{input_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> + requires @\libconcept{indirectly_comparable}@ + constexpr I1 ranges::find_first_of(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{forward_range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + constexpr borrowed_iterator_t + 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} +\pnum +Let $E$ be: +\begin{itemize} +\item \tcode{*i == *j} for the overloads with no parameter \tcode{pred}; +\item \tcode{pred(*i, *j) != false} for the overloads with a parameter \tcode{pred} and no parameter \tcode{proj1}; +\item \tcode{bool(invoke(pred, invoke(proj1, *i), invoke(proj2, *j)))} for the overloads with parameters \tcode{pred} and \tcode{proj1}. +\end{itemize} + +\pnum +\effects +Finds an element that matches one of a set of values. + +\pnum +\returns +The first iterator \tcode{i} in the range \range{first1}{last1} +such that for some iterator \tcode{j} in the range \range{first2}{last2} +$E$ holds. +Returns \tcode{last1} +if \range{first2}{last2} is empty or +if no such iterator is found. + +\pnum +\complexity +At most \tcode{(last1 - first1) * (last2 - first2)} applications +of the corresponding predicate and any projections. +\end{itemdescr} + +\rSec2[alg.adjacent.find]{Adjacent find} + +\indexlibraryglobal{adjacent_find}% +\begin{itemdecl} +template + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last); +template + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); + +template + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); +template + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); + +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_binary_predicate}@, + projected> Pred = ranges::equal_to> + constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\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} +\pnum +Let $E$ be: +\begin{itemize} +\setlength{\emergencystretch}{1em} +\item \tcode{*i == *(i + 1)} for the overloads with no parameter \tcode{pred}; +\item \tcode{pred(*i, *(i + 1)) != false} for the overloads with a parameter \tcode{pred} and no parameter \tcode{proj}; +\item \tcode{bool(invoke(pred, invoke(proj, *i), invoke(proj, *(i + 1))))} for the overloads with both parameters \tcode{pred} and \tcode{proj}. +\end{itemize} + +\pnum +\returns +The first iterator \tcode{i} +such that both \tcode{i} and \tcode{i + 1} are in the range \range{first}{last} +for which $E$ holds. +Returns \tcode{last} if no such iterator is found. + +\pnum +\complexity +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 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} + +\indexlibraryglobal{count}% +\indexlibraryglobal{count_if}% +\begin{itemdecl} +template::value_type> + constexpr typename iterator_traits::difference_type + count(InputIterator first, InputIterator last, const T& value); +template::value_type> + typename iterator_traits::difference_type + count(ExecutionPolicy&& exec, + 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, + ForwardIterator first, ForwardIterator last, Predicate pred); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr iter_difference_t + ranges::count(I first, S last, const T& value, Proj proj = {}); +template<@\libconcept{input_range}@ R, class Proj = identity, class T = projected_value_t, Proj>> + 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 + ranges::count_if(I first, S last, Pred pred, Proj proj = {}); +template<@\libconcept{input_range}@ R, class Proj = identity, + @\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} +\pnum +Let $E$ be: +\begin{itemize} +\item + \tcode{*i == value} for the overloads + with no parameter \tcode{pred} or \tcode{proj}; +\item + \tcode{pred(*i) != false} for the overloads + with a parameter \tcode{pred} but no parameter \tcode{proj}; +\item + \tcode{invoke(proj, *i) == value} for the overloads + with a parameter \tcode{proj} but no parameter \tcode{pred}; +\item + \tcode{bool(invoke(pred, invoke(proj, *i)))} for the overloads + with both parameters \tcode{proj} and \tcode{pred}. +\end{itemize} + +\pnum +\effects +Returns the number of iterators \tcode{i} in the range \range{first}{last} +for which $E$ holds. + +\pnum +\complexity +Exactly \tcode{last - first} applications +of the corresponding predicate and any projection. +\end{itemdescr} + +\rSec2[alg.mismatch]{Mismatch} + +\indexlibraryglobal{mismatch}% +\begin{itemdecl} +template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2); +template + pair + mismatch(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + +template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate pred); +template + pair + mismatch(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + +template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); +template + pair + mismatch(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + +template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred); +template + pair + mismatch(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + +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> + requires @\libconcept{indirectly_comparable}@ + constexpr ranges::mismatch_result + ranges::mismatch(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + constexpr ranges::mismatch_result, borrowed_iterator_t> + ranges::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}@ + 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 in namespace \tcode{std} with no parameter \tcode{last2}. + +\pnum +Let $E$ be: +\begin{itemize} +\setlength{\emergencystretch}{1em} +\item + \tcode{!(*(first1 + n) == *(first2 + n))} + for the overloads with no parameter \tcode{pred}; +\item + \tcode{pred(*(first1 + n), *(first2 + n)) == false} + for the overloads with a parameter \tcode{pred} and + no parameter \tcode{proj1}; +\item + \tcode{!invoke(pred, invoke(proj1, *(first1 + n)), invoke(proj2, *(first2 + n)))} + for the overloads with both parameters \tcode{pred} and \tcode{proj1}. +\end{itemize} + +\pnum +Let $N$ be $\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$. + +\pnum +\returns +\tcode{\{ first1 + n, first2 + n \}}, +where \tcode{n} is the smallest integer in \range{0}{$N$} such that $E$ holds, +or $N$ if no such integer exists. + +\pnum +\complexity +At most $N$ applications of the corresponding predicate and any projections. +\end{itemdescr} + +\rSec2[alg.equal]{Equal} + +\indexlibraryglobal{equal}% +\begin{itemdecl} +template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2); +template + bool equal(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + +template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate pred); +template + bool equal(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + +template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); +template + bool equal(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + +template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred); +template + bool equal(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + +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> + requires @\libconcept{indirectly_comparable}@ + constexpr bool ranges::equal(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + 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} +\pnum +Let: +\begin{itemize} +\item + \tcode{last2} be \tcode{first2 + (last1 - first1)} + 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}; +\item + $E$ be: + \begin{itemize} + \setlength{\emergencystretch}{1em} + \item + \tcode{pred(*i, *(first2 + (i - first1)))} + for the overloads with no parameter \tcode{proj1}; + \item + \tcode{invoke(pred, invoke(proj1, *i), invoke(proj2, *(first2 + (i - first1))))} + for the overloads with parameter \tcode{proj1}. + \end{itemize} +\end{itemize} + +\pnum +\returns +If \tcode{last1 - first1 != last2 - first2}, return \tcode{false}. +Otherwise return \tcode{true} +if $E$ holds for every iterator \tcode{i} in the range \range{first1}{last1}. +Otherwise, returns \tcode{false}. + +\pnum +\complexity +If +\begin{itemize} +\item + the types of \tcode{first1}, \tcode{last1}, \tcode{first2}, and \tcode{last2} + meet the + \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} + 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} + and \tcode{last1 - first1 != last2 - first2} + 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 and fourth overloads in namespace \tcode{ranges}, +\end{itemize} +then no applications of the corresponding predicate and each projection; +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} + +\indexlibraryglobal{is_permutation}% +\begin{itemdecl} +template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); +template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); +template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); +template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{last2} be \tcode{first2 + (last1 - first1)} +for the overloads with no parameter named \tcode{last2}, +and let \tcode{pred} be \tcode{equal_to\{\}} +for the overloads with no parameter \tcode{pred}. + +\pnum +\mandates +\tcode{ForwardIterator1} and \tcode{ForwardIterator2} have the same value type. + +\pnum +\expects +The comparison function is an equivalence relation. + +\pnum +\returns +If \tcode{last1 - first1 != last2 - first2}, return \tcode{false}. +Otherwise return \tcode{true} +if there exists a permutation of the elements +in the range \range{first2}{last2}, +beginning with \tcode{ForwardIterator2 begin}, +such that \tcode{equal(first1, last1, begin, pred)} returns \tcode{true}; +otherwise, returns \tcode{false}. + +\pnum +\complexity +No applications of the corresponding predicate +if \tcode{ForwardIterator1} and \tcode{Forward\-Iter\-ator2} +meet the requirements of random access iterators and +\tcode{last1 - first1 != last2 - first2}. +Otherwise, exactly \tcode{last1 - first1} applications +of the corresponding predicate +if \tcode{equal(first1, last1, first2, last2, pred)} would return \tcode{true}; +otherwise, at worst \bigoh{N^2}, where $N$ has the value \tcode{last1 - first1}. +\end{itemdescr} + +\indexlibraryglobal{is_permutation}% +\begin{itemdecl} +template<@\libconcept{forward_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{forward_iterator}@ I2, + @\libconcept{sentinel_for}@ S2, class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_equivalence_relation}@, + projected> Pred = ranges::equal_to> + constexpr bool ranges::is_permutation(I1 first1, S1 last1, I2 first2, S2 last2, + Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{forward_range}@ R1, @\libconcept{forward_range}@ R2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_equivalence_relation}@, Proj1>, + projected, Proj2>> Pred = ranges::equal_to> + constexpr bool ranges::is_permutation(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{last1 - first1 != last2 - first2}, return \tcode{false}. +Otherwise return \tcode{true} if there exists a permutation of the elements +in the range \range{first2}{last2}, bounded by \range{pfirst}{plast}, +such that +\tcode{ranges::equal(first1, last1, pfirst, plast, pred, proj1, proj2)} +returns \tcode{true}; +otherwise, returns \tcode{false}. + +\pnum +\complexity +No applications of the corresponding predicate and projections if +\begin{itemize} +\item +for the first overload, +\begin{itemize} +\item \tcode{S1} and \tcode{I1} model \tcode{\libconcept{sized_sentinel_for}}, +\item \tcode{S2} and \tcode{I2} model \tcode{\libconcept{sized_sentinel_for}}, and +\item \tcode{last1 - first1 != last2 - first2}; +\end{itemize} +\item +for the second overload, +\tcode{R1} and \tcode{R2} each model \libconcept{sized_range}, and +\tcode{ranges::distance(r1) != ranges::distance(r2)}. +\end{itemize} +Otherwise, exactly \tcode{last1 - first1} applications +of the corresponding predicate and projections +if \tcode{ranges::equal(\brk{}first1, last1, first2, last2, pred, proj1, proj2)} +would return \tcode{true}; +otherwise, at worst \bigoh{N^2}, where $N$ has the value \tcode{last1 - first1}. +\end{itemdescr} + +\rSec2[alg.search]{Search} + +\indexlibraryglobal{search}% +\begin{itemdecl} +template + constexpr ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); +template + ForwardIterator1 + search(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + +template + constexpr ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +template + ForwardIterator1 + search(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +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: +\tcode{*(i + n) == *(first2 + n), pred(*(i + n), *(first2 + n)) != false}. +Returns \tcode{first1} if \range{first2}{last2} is empty, +otherwise returns \tcode{last1} if no such iterator is found. + +\pnum +\complexity +At most \tcode{(last1 - first1) * (last2 - first2)} applications +of the corresponding predicate. +\end{itemdescr} + +\indexlibraryglobal{search}% +\begin{itemdecl} +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> + requires @\libconcept{indirectly_comparable}@ + constexpr subrange + ranges::search(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{forward_range}@ R1, @\libconcept{forward_range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + 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} +\pnum +\returns +\begin{itemize} +\item + \tcode{\{i, i + (last2 - first2)\}}, + where \tcode{i} is + 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 +\begin{codeblock} +bool(invoke(pred, invoke(proj1, *(i + n)), invoke(proj2, *(first2 + n)))) +\end{codeblock} + is \tcode{true}. +\item + Returns \tcode{\{last1, last1\}} if no such iterator exists. +\end{itemize} + +\pnum +\complexity +At most \tcode{(last1 - first1) * (last2 - first2)} applications +of the corresponding predicate and projections. +\end{itemdescr} + +\indexlibraryglobal{search_n}% +\begin{itemdecl} +template::value_type> + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value); +template::value_type> + ForwardIterator + search_n(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Size count, const T& value); + +template::value_type, + class BinaryPredicate> + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value, + BinaryPredicate pred); +template::value_type, + class BinaryPredicate> + ForwardIterator + search_n(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Size count, const T& value, + BinaryPredicate pred); +\end{itemdecl} + +\begin{itemdescr} + +\pnum +\mandates +The type \tcode{Size} +is convertible to an integral type\iref{conv.integral,class.conv}. + +\pnum +Let $E$ be \tcode{pred(*(i + n), value) != false} +for the overloads with a parameter \tcode{pred}, +and \tcode{*(i + n) == value} otherwise. + +\pnum +\returns +The first iterator \tcode{i} in the range \crange{first}{last - count} +such that for every non-negative integer \tcode{n} less than \tcode{count} +the condition $E$ is \tcode{true}. +Returns \tcode{last} if no such iterator is found. + +\pnum +\complexity +At most \tcode{last - first} applications of the corresponding predicate. +\end{itemdescr} + +\indexlibraryglobal{search_n}% +\begin{itemdecl} +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, + class Pred = ranges::equal_to, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirectly_comparable}@ + constexpr subrange + ranges::search_n(I first, S last, iter_difference_t count, + const T& value, Pred pred = {}, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Pred = ranges::equal_to, + class Proj = identity, class T = projected_value_t, Proj>> + requires @\libconcept{indirectly_comparable}@, const T*, Pred, Proj> + 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 \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)}. +Returns \tcode{\{last, last\}} if no such iterator is found. + +\pnum +\complexity +At most \tcode{last - first} applications +of the corresponding predicate and projection. +\end{itemdescr} + +\indexlibraryglobal{search}% +\begin{itemdecl} +template + constexpr ForwardIterator + search(ForwardIterator first, ForwardIterator last, const Searcher& searcher); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return searcher(first, last).first;} + +\pnum +\remarks +\tcode{Searcher} need not meet the \oldconcept{CopyConstructible} requirements. +\end{itemdescr} + +\rSec2[alg.starts.with]{Starts with} + +\indexlibraryglobal{starts_with}% +\begin{itemdecl} +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> + requires @\libconcept{indirectly_comparable}@ + constexpr bool ranges::starts_with(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Pred = ranges::equal_to, class Proj1 = identity, + class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + constexpr bool ranges::starts_with(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +ranges::mismatch(std::move(first1), last1, std::move(first2), last2, + pred, proj1, proj2).in2 == last2 +\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}% +\begin{itemdecl} +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> + requires (@\libconcept{forward_iterator}@ || @\libconcept{sized_sentinel_for}@) && + (@\libconcept{forward_iterator}@ || @\libconcept{sized_sentinel_for}@) && + @\libconcept{indirectly_comparable}@ + constexpr bool ranges::ends_with(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::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> + requires (@\libconcept{forward_range}@ || @\libconcept{sized_range}@) && + (@\libconcept{forward_range}@ || @\libconcept{sized_range}@) && + @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + constexpr bool ranges::ends_with(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(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}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class T = iter_value_t, + @\exposconcept{indirectly-binary-left-foldable}@ F> + constexpr auto ranges::fold_left(I first, S last, T init, F f); +template<@\libconcept{input_range}@ R, class T = range_value_t, + @\exposconcept{indirectly-binary-left-foldable}@> F> + constexpr auto ranges::fold_left(R&& r, T init, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +ranges::fold_left_with_iter(std::move(first), last, std::move(init), f).value +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{fold_left_first}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, + @\exposconcept{indirectly-binary-left-foldable}@, I> F> + requires @\libconcept{constructible_from}@, iter_reference_t> + constexpr auto ranges::fold_left_first(I first, S last, F f); +template<@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr auto ranges::fold_left_first(R&& r, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +ranges::fold_left_first_with_iter(std::move(first), last, f).value +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{fold_right}% +\begin{itemdecl} +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class T = iter_value_t, + @\exposconcept{indirectly-binary-right-foldable}@ F> + constexpr auto ranges::fold_right(I first, S last, T init, F f); +template<@\libconcept{bidirectional_range}@ R, class T = range_value_t, + @\exposconcept{indirectly-binary-right-foldable}@> F> + constexpr auto ranges::fold_right(R&& r, T init, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +using U = decay_t, T>>; +if (first == last) + return U(std::move(init)); +I tail = ranges::next(first, last); +U accum = invoke(f, *--tail, std::move(init)); +while (first != tail) + accum = invoke(f, *--tail, std::move(accum)); +return accum; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{fold_right_last}% +\begin{itemdecl} +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 ranges::fold_right_last(I first, S last, F f); +template<@\libconcept{bidirectional_range}@ R, + @\exposconcept{indirectly-binary-right-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr auto ranges::fold_right_last(R&& r, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{U} be +\tcode{decltype(ranges::fold_right(first, last, iter_value_t(*first), f))}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (first == last) + return optional(); +I tail = ranges::prev(ranges::next(first, std::move(last))); +return optional(in_place, + ranges::fold_right(std::move(first), tail, iter_value_t(*tail), std::move(f))); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{fold_left_with_iter}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class T = iter_value_t, + @\exposconcept{indirectly-binary-left-foldable}@ F> + constexpr @\seebelow@ ranges::fold_left_with_iter(I first, S last, T init, F f); +template<@\libconcept{input_range}@ R, class T = range_value_t, + @\exposconcept{indirectly-binary-left-foldable}@> F> + constexpr @\seebelow@ ranges::fold_left_with_iter(R&& r, T init, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{U} be \tcode{decay_t>>}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (first == last) + return {std::move(first), U(std::move(init))}; +U accum = invoke(f, std::move(init), *first); +for (++first; first != last; ++first) + accum = invoke(f, std::move(accum), *first); +return {std::move(first), std::move(accum)}; +\end{codeblock} + +\pnum +\remarks +The return type is +\tcode{fold_left_with_iter_result} for the first overload and +\tcode{fold_left_with_iter_result, U>} +for the second overload. +\end{itemdescr} + +\indexlibraryglobal{fold_left_first_with_iter}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, + @\exposconcept{indirectly-binary-left-foldable}@, I> F> + requires @\libconcept{constructible_from}@, iter_reference_t> + constexpr @\seebelow@ ranges::fold_left_first_with_iter(I first, S last, F f); +template<@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@, iterator_t> F> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr @\seebelow@ ranges::fold_left_first_with_iter(R&& r, F f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{U} be +\begin{codeblock} +decltype(ranges::fold_left(std::move(first), last, iter_value_t(*first), f)) +\end{codeblock} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (first == last) + return {std::move(first), optional()}; +optional init(in_place, *first); +for (++first; first != last; ++first) + *init = invoke(f, std::move(*init), *first); +return {std::move(first), std::move(init)}; +\end{codeblock} + +\pnum +\remarks +The return type is +\tcode{fold_left_first_with_iter_result>} +for the first overload and +\tcode{fold_left_first_with_iter_result, optional>} +for the second overload. +\end{itemdescr} + +\rSec1[alg.modifying.operations]{Mutating sequence operations} + +\rSec2[alg.copy]{Copy} + +\indexlibraryglobal{copy}% +\begin{itemdecl} +template + constexpr OutputIterator copy(InputIterator first, InputIterator last, + OutputIterator result); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O> + requires @\libconcept{indirectly_copyable}@ + constexpr ranges::copy_result ranges::copy(I first, S last, O result); +template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O> + requires @\libconcept{indirectly_copyable}@, O> + constexpr ranges::copy_result, O> ranges::copy(R&& r, O result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $N$ be \tcode{last - first}. + +\pnum +\expects +\tcode{result} is not in the range \range{first}{last}. + +\pnum +\effects +Copies 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$) = *(first + $n$)}. + +\pnum +\returns +\begin{itemize} +\item + \tcode{result + $N$} for the overload in namespace \tcode{std}. +\item + \tcode{\{last, result + $N$\}} for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +Exactly $N$ assignments. +\end{itemdescr} + +\indexlibraryglobal{copy}% +\begin{itemdecl} +template + 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 + $N$} +do not overlap. + +\pnum +\effects +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 +\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 $N$ assignments. +\end{itemdescr} + +\indexlibraryglobal{copy_n}% +\begin{itemdecl} +template + constexpr OutputIterator copy_n(InputIterator first, Size n, + OutputIterator result); +template + ForwardIterator2 copy_n(ExecutionPolicy&& exec, + ForwardIterator1 first, Size n, + ForwardIterator2 result); + +template<@\libconcept{input_iterator}@ I, @\libconcept{weakly_incrementable}@ O> + 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 $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 +The type \tcode{Size} is convertible +to an integral type\iref{conv.integral,class.conv}. + +\pnum +\effects +For each non-negative integer $i < N$, +performs \tcode{*(result + $i$) = *(first + $i$)}. + +\pnum +\returns +\begin{itemize} +\item + \tcode{result + $N$} + for the overloads in namespace \tcode{std}. +\item + \tcode{\{first + $N$, result + $N$\}} + for the overload in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +Exactly $N$ assignments. +\end{itemdescr} + +\indexlibraryglobal{copy_if}% +\begin{itemdecl} +template + constexpr OutputIterator copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); +template + ForwardIterator2 copy_if(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred); + +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}@ + constexpr ranges::copy_if_result + ranges::copy_if(I first, S last, O result, Pred pred, Proj proj = {}); +template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + 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(\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}. +\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} + +\pnum +\expects +The ranges \range{first}{last} and \range{result}{result + $N$} +do not overlap. +\begin{note} +For the parallel algorithm overload 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 the first $N$ elements referred to +by the iterator \tcode{i} in the range \range{first}{last} +for which $E(\tcode{i})$ is \tcode{true} +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}, 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 +At most \tcode{last - first} applications +of the corresponding predicate and any projection. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} + +\indexlibraryglobal{copy_backward}% +\begin{itemdecl} +template + constexpr BidirectionalIterator2 + copy_backward(BidirectionalIterator1 first, + BidirectionalIterator1 last, + BidirectionalIterator2 result); + +template<@\libconcept{bidirectional_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{bidirectional_iterator}@ I2> + requires @\libconcept{indirectly_copyable}@ + constexpr ranges::copy_backward_result + ranges::copy_backward(I1 first, S1 last, I2 result); +template<@\libconcept{bidirectional_range}@ R, @\libconcept{bidirectional_iterator}@ I> + requires @\libconcept{indirectly_copyable}@, I> + constexpr ranges::copy_backward_result, I> + ranges::copy_backward(R&& r, I result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $N$ be \tcode{last - first}. + +\pnum +\expects +\tcode{result} is not in the range \brange{first}{last}. + +\pnum +\effects +Copies elements in the range \range{first}{last} +into the range \range{result - $N$}{result} +starting from \tcode{last - 1} and proceeding to \tcode{first}. +\begin{footnote} +\tcode{copy_backward} can be used instead of \tcode{copy} +when \tcode{last} is in the range \range{result - $N$}{result}. +\end{footnote} +For each positive integer $n \le N$, +performs \tcode{*(result - $n$) = *(last - $n$)}. + +\pnum +\returns +\begin{itemize} +\item + \tcode{result - $N$} + for the overload in namespace \tcode{std}. +\item + \tcode{\{last, result - $N$\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +Exactly $N$ assignments. +\end{itemdescr} + +\rSec2[alg.move]{Move} + +\indexlibrary{\idxcode{move}!algorithm}% +\begin{itemdecl} +template + constexpr OutputIterator move(InputIterator first, InputIterator last, + OutputIterator result); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O> + requires @\libconcept{indirectly_movable}@ + constexpr ranges::move_result + ranges::move(I first, S last, O result); +template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O> + requires @\libconcept{indirectly_movable}@, O> + constexpr ranges::move_result, O> + ranges::move(R&& r, O result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +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} +Let $N$ be \tcode{last - first}. + +\pnum +\expects +\tcode{result} is not in the range \range{first}{last}. + +\pnum +\effects +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(n)$}. + +\pnum +\returns +\begin{itemize} +\item + \tcode{result + $N$} + for the overload in namespace \tcode{std}. +\item + \tcode{\{last, result + $N$\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +Exactly $N$ assignments. +\end{itemdescr} + +\indexlibrary{\idxcode{move}!algorithm}% +\begin{itemdecl} +template + 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 $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 +The ranges \range{first}{last} and \range{result}{result + $N$} +do not overlap. + +\pnum +\effects +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$) = $E(n)$}. + +\pnum +\returns +\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 $N$ assignments. +\end{itemdescr} + +\indexlibraryglobal{move_backward}% +\begin{itemdecl} +template + constexpr BidirectionalIterator2 + move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, + BidirectionalIterator2 result); + +template<@\libconcept{bidirectional_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{bidirectional_iterator}@ I2> + requires @\libconcept{indirectly_movable}@ + constexpr ranges::move_backward_result + ranges::move_backward(I1 first, S1 last, I2 result); +template<@\libconcept{bidirectional_range}@ R, @\libconcept{bidirectional_iterator}@ I> + requires @\libconcept{indirectly_movable}@, I> + constexpr ranges::move_backward_result, I> + ranges::move_backward(R&& r, I result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $E(n)$ be +\begin{itemize} +\item + \tcode{std::move(*(last - $n$))} + for the overload in namespace \tcode{std}; +\item + \tcode{ranges::iter_move(last - $n$)} + for the overloads in namespace \tcode{ranges}. +\end{itemize} +Let $N$ be \tcode{last - first}. + +\pnum +\expects +\tcode{result} is not in the range \brange{first}{last}. + +\pnum +\effects +Moves elements in the range \range{first}{last} +into the range \range{result - $N$}{result} +starting from \tcode{last - 1} and proceeding to \tcode{first}. +\begin{footnote} +\tcode{move_backward} can be used instead of \tcode{move} +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(n)$}. + +\pnum +\returns +\begin{itemize} +\item + \tcode{result - $N$} + for the overload in namespace \tcode{std}. +\item + \tcode{\{last, result - $N$\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +Exactly $N$ assignments. +\end{itemdescr} + +\rSec2[alg.swap]{Swap} + +\indexlibraryglobal{swap_ranges}% +\begin{itemdecl} +template + constexpr ForwardIterator2 + swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); +template + ForwardIterator2 + swap_ranges(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + +template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2> + requires @\libconcept{indirectly_swappable}@ + constexpr ranges::swap_ranges_result + ranges::swap_ranges(I1 first1, S1 last1, I2 first2, S2 last2); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2> + 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} +\pnum +Let: +\begin{itemize} +\item + \tcode{last2} be \tcode{first2 + (last1 - first1)} + 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} + +\pnum +\expects +The two ranges \range{first1}{last1} and \range{first2}{last2} +do not overlap. +For the overloads in namespace \tcode{std}, +\tcode{*(first1 + $n$)} is swappable with\iref{swappable.requirements} +\tcode{*(first2 + $n$)}. + +\pnum +\effects +For each non-negative integer $n < M$ performs: +\begin{itemize} +\item + \tcode{swap(*(first1 + $n$), *(first2 + $n$))} + for the overloads in namespace \tcode{std}; +\item + \tcode{ranges::iter_swap(first1 + $n$, first2 + $n$)} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\returns +\begin{itemize} +\item + \tcode{last2} + for the overloads in namespace \tcode{std}. +\item + \tcode{\{first1 + $M$, first2 + $M$\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +Exactly $M$ swaps. +\end{itemdescr} + +\indexlibraryglobal{iter_swap}% +\begin{itemdecl} +template + constexpr void iter_swap(ForwardIterator1 a, ForwardIterator2 b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{a} and \tcode{b} are dereferenceable. \tcode{*a} is +swappable with\iref{swappable.requirements} \tcode{*b}. + +\pnum +\effects +As if by \tcode{swap(*a, *b)}. +\end{itemdescr} + +\rSec2[alg.transform]{Transform} + +\indexlibraryglobal{transform}% +\begin{itemdecl} +template + constexpr OutputIterator + transform(InputIterator first1, InputIterator last1, + OutputIterator result, UnaryOperation op); +template + ForwardIterator2 + transform(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 result, UnaryOperation op); + +template + constexpr OutputIterator + transform(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, OutputIterator result, + BinaryOperation binary_op); +template + ForwardIterator + transform(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator result, + BinaryOperation binary_op); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O, + @\libconcept{copy_constructible}@ F, class Proj = identity> + requires @\libconcept{indirectly_writable}@>> + constexpr ranges::unary_transform_result + ranges::transform(I first1, S last1, O result, F op, Proj proj = {}); +template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, @\libconcept{copy_constructible}@ F, + class Proj = identity> + 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>> + 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>>> + 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} +\pnum +Let: +\begin{itemize} +\setlength{\emergencystretch}{1em} +\item + \tcode{last2} be \tcode{first2 + (last1 - first1)} + for the overloads in namespace \tcode{std} + with parameter \tcode{first2} + but no parameter \tcode{last2}; +\item + $M$ be \tcode{last1 - first1} for unary transforms, or + $\min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ for binary transforms; +\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})$; +\item + $E(\tcode{i})$ be + \begin{itemize} + \item + \tcode{op(*(first1 + (i - result)))} + for unary transforms defined in namespace \tcode{std}; + \item + \tcode{binary_op(*(first1 + (i - result)), *(first2 + (i - result)))} + for binary transforms defined in namespace \tcode{std}; + \item + \tcode{invoke(op, invoke(proj, *(first1 + (i - result))))} + for unary transforms defined in namespace \tcode{ranges}; + \item + \tcode{invoke(binary_op, invoke(proj1, *(first1 + (i - result))), invoke(proj2,\linebreak *(first2 + (i - result))))} + for binary transforms defined in namespace \tcode{ranges}. + \end{itemize} +\end{itemize} + +\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} +\item \crange{first1}{first1 + $N$}, +\item \crange{first2}{first2 + $N$}, and +\item \crange{result}{result + $N$}. +\begin{footnote} +The use of fully closed ranges is intentional. +\end{footnote} +\end{itemize} + +\pnum +\effects +Assigns through every iterator \tcode{i} +in the range \range{result}{result + $N$} +a new corresponding value equal to $E(\tcode{i})$. + +\pnum +\returns +\begin{itemize} +\item + \tcode{result + $N$} + for the overloads defined in namespace \tcode{std}. +\item + \tcode{\{first1 + $N$, result + $N$\}} + for unary transforms defined in namespace \tcode{ranges}. +\item + \tcode{\{first1 + $N$, first2 + $N$, result + $N$\}} + for binary transforms defined in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +Exactly $N$ applications of \tcode{op} or \tcode{binary_op}, and +any projections. +This requirement also applies to the parallel algorithm overloads. + +\pnum +\remarks +\tcode{result} may be equal to \tcode{first1} or \tcode{first2}. +\end{itemdescr} + +\rSec2[alg.replace]{Replace} + +\indexlibraryglobal{replace}% +\indexlibraryglobal{replace_if}% +\begin{itemdecl} +template::value_type> + constexpr void replace(ForwardIterator first, ForwardIterator last, + const T& old_value, const T& new_value); +template::value_type> + void replace(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + const T& old_value, const T& new_value); + +template::value_type> + constexpr void replace_if(ForwardIterator first, ForwardIterator last, + Predicate pred, const T& new_value); +template::value_type> + void replace_if(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + 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 = 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 = 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 = 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 = 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(\tcode{i})$ be +\begin{itemize} +\item \tcode{bool(*i == old_value)} for \tcode{replace}; +\item \tcode{bool(pred(*i))} for \tcode{replace_if}; +\item \tcode{bool(invoke(proj, *i) == old_value)} for \tcode{ranges::replace}; +\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}. + +\pnum +\effects +Substitutes elements referred by the iterator \tcode{i} +in the range \range{first}{last} with \tcode{new_value}, +when $E(\tcode{i})$ is \tcode{true}. + +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. + +\pnum +\complexity +Exactly \tcode{last - first} applications +of the corresponding predicate and any projection. +\end{itemdescr} + +\indexlibraryglobal{replace_copy}% +\indexlibraryglobal{replace_copy_if}% +\begin{itemdecl} +template + constexpr OutputIterator + replace_copy(InputIterator first, InputIterator last, + OutputIterator result, + const T& old_value, const T& new_value); +template + ForwardIterator2 + replace_copy(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + const T& old_value, const T& new_value); + +template + constexpr OutputIterator + replace_copy_if(InputIterator first, InputIterator last, + OutputIterator result, + Predicate pred, const T& new_value); +template + ForwardIterator2 + replace_copy_if(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + Predicate pred, const T& new_value); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class O, + class Proj = identity, class T1 = projected_value_t, class T2 = iter_value_t> + requires @\libconcept{indirectly_copyable}@ && + @\libconcept{indirect_binary_predicate}@, const T1*> && + @\libconcept{output_iterator}@ + constexpr ranges::replace_copy_result + ranges::replace_copy(I first, S last, O result, const T1& old_value, const T2& new_value, + Proj proj = {}); +template<@\libconcept{input_range}@ R, class O, class Proj = identity, + class T1 = projected_value_t, Proj>, class T2 = iter_value_t> + requires @\libconcept{indirectly_copyable}@, O> && + @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> + && @\libconcept{output_iterator}@ + constexpr ranges::replace_copy_result, O> + 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}@ + constexpr ranges::replace_copy_if_result + ranges::replace_copy_if(I first, S last, O result, Pred pred, const T& new_value, + Proj proj = {}); +template<@\libconcept{input_range}@ R, class O, class T = iter_value_t, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, O> && @\libconcept{output_iterator}@ + 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(\tcode{i})$ be +\begin{itemize} +\item \tcode{bool(*(first + (i - result)) == old_value)} + for \tcode{replace_copy}; +\item \tcode{bool(pred(*(first + (i - result))))} + for \tcode{replace_copy_if}; +\item \tcode{bool(invoke(proj, *(first + (i - result))) == old_value)} + for \tcode{ranges::replace_copy}; +\item \tcode{bool(invoke(pred, invoke(proj, *(first + (i - result)))))} + 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} +are writable\iref{iterator.requirements.general} to \tcode{result}. + +\pnum +\expects +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 + $N$} +a new corresponding value +\begin{itemize} +\item \tcode{new_value} if $E(\tcode{i})$ is \tcode{true} or +\item \tcode{*(first + (i - result))} otherwise. +\end{itemize} + +\pnum +\returns +\begin{itemize} +\item + \tcode{result + $N$} + for the overloads in namespace \tcode{std}. +\item + \tcode{\{first + $N$, result + $N$\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +Exactly $N$ applications +of the corresponding predicate and any projection. +\end{itemdescr} + +\rSec2[alg.fill]{Fill} + +\indexlibraryglobal{fill}% +\indexlibraryglobal{fill_n}% +\begin{itemdecl} +template::value_type> + constexpr void fill(ForwardIterator first, ForwardIterator last, const T& value); +template::value_type> + void fill(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, const T& value); + +template::value_type> + constexpr OutputIterator fill_n(OutputIterator first, Size n, const T& value); +template::value_type> + ForwardIterator fill_n(ExecutionPolicy&& exec, + ForwardIterator first, Size n, const T& value); + +template S, class T = iter_value_t> + requires @\libconcept{output_iterator}@ + constexpr O ranges::fill(O first, S last, const T& value); +template> + requires @\libconcept{output_range}@ + constexpr borrowed_iterator_t ranges::fill(R&& r, const T& value); +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} +\pnum +Let $N$ be $\max(0, \tcode{n})$ for the \tcode{fill_n} algorithms, and +\tcode{last - first} for the \tcode{fill} algorithms. + +\pnum +\mandates +The expression \tcode{value} +is writable\iref{iterator.requirements.general} to the output iterator. +The type \tcode{Size} is convertible +to an integral type\iref{conv.integral,class.conv}. + +\pnum +\effects +Assigns \tcode{value} +through all the iterators in the range \range{first}{first + $N$}. + +\pnum +\returns +\tcode{first + $N$}. + +\pnum +\complexity +Exactly $N$ assignments. +\end{itemdescr} + +\rSec2[alg.generate]{Generate} + +\indexlibraryglobal{generate}% +\indexlibraryglobal{generate_n}% +\begin{itemdecl} +template + constexpr void generate(ForwardIterator first, ForwardIterator last, + Generator gen); +template + void generate(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Generator gen); + +template + constexpr OutputIterator generate_n(OutputIterator first, Size n, Generator gen); +template + ForwardIterator generate_n(ExecutionPolicy&& exec, + ForwardIterator first, Size n, Generator gen); + +template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{sentinel_for}@ S, @\libconcept{copy_constructible}@ F> + requires @\libconcept{invocable}@ && @\libconcept{indirectly_writable}@> + constexpr O ranges::generate(O first, S last, F gen); +template + requires @\libconcept{invocable}@ && @\libconcept{output_range}@> + constexpr borrowed_iterator_t ranges::generate(R&& r, F gen); +template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{copy_constructible}@ F> + requires @\libconcept{invocable}@ && @\libconcept{indirectly_writable}@> + constexpr O ranges::generate_n(O first, iter_difference_t n, F gen); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $N$ be $\max(0, \tcode{n})$ for the \tcode{generate_n} algorithms, and +\tcode{last - first} for the \tcode{generate} algorithms. + +\pnum +\mandates +\tcode{Size} is convertible +to an integral type\iref{conv.integral,class.conv}. + +\pnum +\effects +Assigns the result of successive evaluations of \tcode{gen()} +through each iterator in the range \range{first}{first + $N$}. + +\pnum +\returns +\tcode{first + $N$}. + +\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} + +\indexlibraryglobal{remove}% +\indexlibraryglobal{remove_if}% +\begin{itemdecl} +template::value_type> + constexpr ForwardIterator remove(ForwardIterator first, ForwardIterator last, + const T& value); +template::value_type> + ForwardIterator remove(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + const T& value); + +template + constexpr ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, + Predicate pred); +template + ForwardIterator remove_if(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Predicate pred); + +template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + class T = projected_value_t> + requires @\libconcept{indirect_binary_predicate}@, const T*> + constexpr subrange ranges::remove(I first, S last, const T& value, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{permutable}@> && + @\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 = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + 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(\tcode{i})$ be +\begin{itemize} +\item \tcode{bool(*i == value)} for \tcode{remove}; +\item \tcode{bool(pred(*i))} for \tcode{remove_if}; +\item \tcode{bool(invoke(proj, *i) == value)} for \tcode{ranges::remove}; +\item \tcode{bool(invoke(pred, invoke(proj, *i)))} for \tcode{ranges::remove_if}. +\end{itemize} + +\pnum +\expects +For the algorithms in namespace \tcode{std}, +the type of \tcode{*first} +meets the \oldconcept{MoveAssignable} requirements (\tref{cpp17.moveassignable}). + +\pnum +\effects +Eliminates all the elements referred to by iterator \tcode{i} +in the range \range{first}{last} for which $E(\tcode{i})$ holds. + +\pnum +\returns +Let $j$ be the end of the resulting range. Returns: +\begin{itemize} +\item $j$ for the overloads in namespace \tcode{std}. +\item \tcode{\{$j$, last\}} for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +Exactly \tcode{last - first} applications +of the corresponding predicate and any projection. + +\pnum +\remarks +Stable\iref{algorithm.stable}. + +\pnum +\begin{note} +Each element in the range \range{ret}{last}, +where \tcode{ret} is the returned value, +has a valid but unspecified state, +because the algorithms can eliminate elements +by moving from elements that were originally in that range. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{remove_copy}% +\indexlibraryglobal{remove_copy_if}% +\begin{itemdecl} +template::value_type> + constexpr OutputIterator + remove_copy(InputIterator first, InputIterator last, + OutputIterator result, const T& value); +template::value_type> + ForwardIterator2 + remove_copy(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, const T& value); + +template + constexpr OutputIterator + remove_copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); +template + ForwardIterator2 + remove_copy_if(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O, + class Proj = identity, class T = projected_value_t> + requires @\libconcept{indirectly_copyable}@ && + @\libconcept{indirect_binary_predicate}@, const T*> + constexpr ranges::remove_copy_result + ranges::remove_copy(I first, S last, O result, const T& value, Proj proj = {}); +template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, class Proj = identity, + class T = projected_value_t, Proj>> + requires @\libconcept{indirectly_copyable}@, O> && + @\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}@ + constexpr ranges::remove_copy_if_result + ranges::remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {}); +template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + 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(\tcode{i})$ be +\begin{itemize} +\item \tcode{bool(*i == value)} for \tcode{remove_copy}; +\item \tcode{bool(pred(*i))} for \tcode{remove_copy_if}; +\item \tcode{bool(invoke(proj, *i) == value)} for \tcode{ranges::remove_copy}; +\item \tcode{bool(invoke(pred, invoke(proj, *i)))} for \tcode{ranges::remove_copy_if}. +\end{itemize} + +\pnum +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 +\tcode{*first} is writable\iref{iterator.requirements.general} to \tcode{result}. + +\pnum +\expects +The ranges \range{first}{last} and \range{result}{result + $N$} +do not overlap. +\begin{note} +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 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}, + 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 +At most \tcode{last - first} applications +of the corresponding predicate and any projection. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} + +\rSec2[alg.unique]{Unique} + +\indexlibraryglobal{unique}% +\begin{itemdecl} +template + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last); +template + ForwardIterator unique(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); + +template + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); +template + ForwardIterator unique(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); + +template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_equivalence_relation}@> C = ranges::equal_to> + constexpr subrange ranges::unique(I first, S last, C comp = {}, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_equivalence_relation}@, Proj>> C = ranges::equal_to> + 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(\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}; +\item + \tcode{bool(invoke(comp, invoke(proj, *(i - 1)), invoke(proj, *i)))} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\expects +For the overloads in namespace \tcode{std}, +\tcode{pred} is an equivalence relation and +the type of \tcode{*first} meets +the \oldconcept{MoveAssignable} requirements (\tref{cpp17.moveassignable}). + +\pnum +\effects +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 +Let $j$ be the end of the resulting range. Returns: +\begin{itemize} +\item $j$ for the overloads in namespace \tcode{std}. +\item \tcode{\{$j$, last\}} for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +For nonempty ranges, exactly \tcode{(last - first) - 1} applications +of the corresponding predicate and +no more than twice as many applications of any projection. +\end{itemdescr} + +\indexlibraryglobal{unique_copy}% +\begin{itemdecl} +template + constexpr OutputIterator + unique_copy(InputIterator first, InputIterator last, + OutputIterator result); +template + ForwardIterator2 + unique_copy(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + +template + constexpr OutputIterator + unique_copy(InputIterator first, InputIterator last, + OutputIterator result, BinaryPredicate pred); +template + ForwardIterator2 + unique_copy(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryPredicate pred); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O, class Proj = identity, + @\libconcept{indirect_equivalence_relation}@> C = ranges::equal_to> + requires @\libconcept{indirectly_copyable}@ && + (@\libconcept{forward_iterator}@ || + (@\libconcept{input_iterator}@ && @\libconcept{same_as}@, iter_value_t>) || + @\libconcept{indirectly_copyable_storable}@) + constexpr ranges::unique_copy_result + ranges::unique_copy(I first, S last, O result, C comp = {}, Proj proj = {}); +template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, class Proj = identity, + @\libconcept{indirect_equivalence_relation}@, Proj>> C = ranges::equal_to> + requires @\libconcept{indirectly_copyable}@, O> && + (@\libconcept{forward_iterator}@> || + (@\libconcept{input_iterator}@ && @\libconcept{same_as}@, iter_value_t>) || + @\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(\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}; +\item + \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}. + +\pnum +\expects +\begin{itemize} +\item + The ranges \range{first}{last} and \range{result}{result + $N$} + do not overlap. +\item + For the overloads in namespace \tcode{std}: + \begin{itemize} + \item + The comparison function is an equivalence relation. + \item + For the overloads with no \tcode{ExecutionPolicy}, + let \tcode{T} be the value type of \tcode{InputIterator}. + If \tcode{InputIterator} models + \libconcept{forward_iterator}\iref{iterator.concept.forward}, + then there are no additional requirements for \tcode{T}. + Otherwise, if \tcode{OutputIterator} meets + the \oldconcept{ForwardIterator} requirements and + its value type is the same as \tcode{T}, + then \tcode{T} meets + the \oldconcept{CopyAssignable} (\tref{cpp17.copyassignable}) requirements. + Otherwise, \tcode{T} meets both + the \oldconcept{CopyConstructible} (\tref{cpp17.copyconstructible}) and + \oldconcept{CopyAssignable} requirements. + \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 $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 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 +At most \tcode{last - first - 1} applications +of the corresponding predicate +and no more than twice as many applications of any projection. +\end{itemdescr} + +\rSec2[alg.reverse]{Reverse} + +\indexlibraryglobal{reverse}% +\begin{itemdecl} +template + constexpr void reverse(BidirectionalIterator first, BidirectionalIterator last); +template + void reverse(ExecutionPolicy&& exec, + BidirectionalIterator first, BidirectionalIterator last); + +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S> + requires @\libconcept{permutable}@ + constexpr I ranges::reverse(I first, S last); +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} +\pnum +\expects +For the overloads in namespace \tcode{std}, +\tcode{BidirectionalIterator} meets +the \oldconcept{Value\-Swappable} requirements\iref{swappable.requirements}. + +\pnum +\effects +For each non-negative integer \tcode{i < (last - first) / 2}, +applies \tcode{std::iter_swap}, or +\tcode{ranges::\brk{}iter_swap} for the overloads in namespace \tcode{ranges}, +to all pairs of iterators \tcode{first + i, (last - i) - 1}. + +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. + +\pnum +\complexity +Exactly \tcode{(last - first)/2} swaps. +\end{itemdescr} + +\indexlibraryglobal{reverse_copy}% +\begin{itemdecl} +template + constexpr OutputIterator + reverse_copy(BidirectionalIterator first, BidirectionalIterator last, + OutputIterator result); +template + ForwardIterator + reverse_copy(ExecutionPolicy&& exec, + BidirectionalIterator first, BidirectionalIterator last, + ForwardIterator result); + +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O> + requires @\libconcept{indirectly_copyable}@ + constexpr ranges::reverse_copy_result + ranges::reverse_copy(I first, S last, O result); +template<@\libconcept{bidirectional_range}@ R, @\libconcept{weakly_incrementable}@ O> + requires @\libconcept{indirectly_copyable}@, O> + constexpr ranges::reverse_copy_result, O> + ranges::reverse_copy(R&& r, O result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $N$ be \tcode{last - first}. + +\pnum +\expects +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 every non-negative integer \tcode{i < $N$} +the following assignment takes place: +\tcode{*(result + $N$ - 1 - i) = *(first + i)}. + +\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}. +\end{itemize} + +\pnum +\complexity +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}% +\begin{itemdecl} +template + constexpr ForwardIterator + rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last); +template + ForwardIterator + rotate(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator middle, ForwardIterator last); + +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} +\pnum +\expects +\range{first}{middle} and \range{middle}{last} are valid ranges. +For the overloads in namespace \tcode{std}, +\tcode{ForwardIterator} meets +the \oldconcept{ValueSwappable} requirements\iref{swappable.requirements}, and +the type of \tcode{*first} meets +the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}) requirements. + +\pnum +\effects +For each non-negative integer \tcode{i < (last - first)}, +places the element from the position \tcode{first + i} +into position \tcode{first + (i + (last - middle)) \% (last - first)}. +\begin{note} +This is a left rotate. +\end{note} + +\pnum +\returns +\begin{itemize} +\item + \tcode{first + (last - middle)} + for the overloads in namespace \tcode{std}. +\item + \tcode{\{first + (last - middle), last\}} + for the overload in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +At most \tcode{last - first} swaps. +\end{itemdescr} + +\begin{itemdecl} +template<@\libconcept{forward_range}@ R> + requires @\libconcept{permutable}@> + constexpr borrowed_subrange_t ranges::rotate(R&& r, iterator_t middle); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\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 + constexpr OutputIterator + rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, + OutputIterator result); +template + ForwardIterator2 + rotate_copy(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, + ForwardIterator2 result); + + template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O> + requires @\libconcept{indirectly_copyable}@ + constexpr ranges::rotate_copy_result + ranges::rotate_copy(I first, I middle, S last, O result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $N$ be \tcode{last - first}. + +\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)) \% $N$)}. + +\pnum +\returns +\begin{itemize} +\item + \tcode{result + $N$} for the overloads in namespace \tcode{std}. +\item + \tcode{\{last, result + $N$\}} for the overload in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +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> + constexpr ranges::rotate_copy_result, O> + ranges::rotate_copy(R&& r, iterator_t middle, O result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ranges::rotate_copy(ranges::begin(r), middle, ranges::end(r), std::move(result)); +\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}% +\begin{itemdecl} +template + SampleIterator sample(PopulationIterator first, PopulationIterator last, + SampleIterator out, Distance n, + UniformRandomBitGenerator&& g); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O, class Gen> + requires (@\libconcept{forward_iterator}@ || @\libconcept{random_access_iterator}@) && + @\libconcept{indirectly_copyable}@ && + @\libconcept{uniform_random_bit_generator}@> + O ranges::sample(I first, S last, O out, iter_difference_t n, Gen&& g); +template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O, class Gen> + requires (@\libconcept{forward_range}@ || @\libconcept{random_access_iterator}@) && + @\libconcept{indirectly_copyable}@, O> && + @\libconcept{uniform_random_bit_generator}@> + O ranges::sample(R&& r, O out, range_difference_t n, Gen&& g); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +For the overload in namespace \tcode{std}, +\tcode{Distance} is an integer type and +\tcode{*first} is writable\iref{iterator.requirements.general} to \tcode{out}. + +\pnum +\expects +\tcode{out} is not in the range \range{first}{last}. +For the overload in namespace \tcode{std}: +\begin{itemize} +\item + \tcode{PopulationIterator} meets + the \oldconcept{InputIterator} requirements\iref{input.iterators}. +\item + \tcode{SampleIterator} meets + the \oldconcept{OutputIterator} requirements\iref{output.iterators}. +\item + \tcode{SampleIterator} meets + the \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} + unless \tcode{Pop\-ulat\-ion\-Iter\-ator} + models \libconcept{forward_iterator}\iref{iterator.concept.forward}. +\item + \tcode{remove_reference_t} meets + the requirements of a uniform random bit generator type\iref{rand.req.urng}. +\end{itemize} + +\pnum +\effects +Copies $\min(\tcode{last - first}, \ \tcode{n})$ elements (the \defn{sample}) +from \range{first}{last} (the \defn{population}) to \tcode{out} +such that each possible sample has equal probability of appearance. +\begin{note} +Algorithms that obtain such effects include \term{selection sampling} +and \term{reservoir sampling}. +\end{note} + +\pnum +\returns +The end of the resulting sample range. + +\pnum +\complexity +\bigoh{\tcode{last - first}}. + +\pnum +\remarks +\begin{itemize} +\item + For the overload in namespace \tcode{std}, + stable if and only if \tcode{PopulationIterator} + models \libconcept{forward_iterator}. + For the first overload in namespace \tcode{ranges}, + stable if and only if \tcode{I} models \libconcept{forward_iterator}. +\item + To the extent that the implementation of this function makes use + of random numbers, the object \tcode{g} serves as + the implementation's source of randomness. +\end{itemize} +\end{itemdescr} + +\rSec2[alg.random.shuffle]{Shuffle} + +\indexlibraryglobal{shuffle}% +\begin{itemdecl} +template + void shuffle(RandomAccessIterator first, + RandomAccessIterator last, + UniformRandomBitGenerator&& g); + +template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Gen> + requires @\libconcept{permutable}@ && + @\libconcept{uniform_random_bit_generator}@> + I ranges::shuffle(I first, S last, Gen&& g); +template<@\libconcept{random_access_range}@ R, class Gen> + requires @\libconcept{permutable}@> && + @\libconcept{uniform_random_bit_generator}@> + borrowed_iterator_t ranges::shuffle(R&& r, Gen&& g); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +For the overload in namespace \tcode{std}: +\begin{itemize} +\item + \tcode{RandomAccessIterator} meets + the \oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. +\item + The type \tcode{remove_reference_t} meets + the uniform random bit generator\iref{rand.req.urng} requirements. +\end{itemize} + +\pnum +\effects +Permutes the elements in the range \range{first}{last} +such that each possible permutation of those elements +has equal probability of appearance. + +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. + +\pnum +\complexity +Exactly \tcode{(last - first) - 1} swaps. + +\pnum +\remarks +To the extent that the implementation of this function makes use +of random numbers, the object referenced by \tcode{g} shall serve as +the implementation's source of randomness. +\end{itemdescr} + +\rSec2[alg.shift]{Shift} + +\indexlibraryglobal{shift_left}% +\begin{itemdecl} +template + constexpr ForwardIterator + shift_left(ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); +template + ForwardIterator + shift_left(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); + +template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S> + 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); + +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} +\pnum +\expects +\tcode{n >= 0} is \tcode{true}. +For the overloads in namespace \tcode{std}, +the type of \tcode{*first} meets the \oldconcept{MoveAssignable} requirements. + +\pnum +\effects +If \tcode{n == 0} or \tcode{n >= last - first}, does nothing. +Otherwise, moves the element +from position \tcode{first + n + i} +into position \tcode{first + i} +for each non-negative integer \tcode{i < (last - first) - n}. +For the non-parallel algorithm overloads, +does so in order starting +from \tcode{i = 0} and proceeding to \tcode{i = (last - first) - n - 1}. + +\pnum +\returns +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}. +\item +\tcode{\{first, \exposid{NEW_LAST}\}} +for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +At most \tcode{(last - first) - n} assignments. +\end{itemdescr} + +\indexlibraryglobal{shift_right}% +\begin{itemdecl} +template + constexpr ForwardIterator + shift_right(ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); +template + ForwardIterator + shift_right(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); + +template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S> + constexpr subrange ranges::shift_right(I first, S last, iter_difference_t n); +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} +\pnum +\expects +\tcode{n >= 0} is \tcode{true}. +For the overloads in namespace \tcode{std}, +the type of \tcode{*first} meets the \oldconcept{MoveAssignable} requirements, +and \tcode{ForwardIterator} meets +the \oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators} or +the \oldconcept{ValueSwap\-pable} requirements. + +\pnum +\effects +If \tcode{n == 0} or \tcode{n >= last - first}, does nothing. +Otherwise, moves the element +from position \tcode{first + i} into position \tcode{first + n + i} +for each non-negative integer \tcode{i < (last - first) - n}. +Does so in order starting +from \tcode{i = (last - first) - n - 1} and proceeding to \tcode{i = 0} if +\begin{itemize} +\item +for the non-parallel algorithm overload in namespace \tcode{std}, +\tcode{Forward\-Iterator} meets the \oldconcept{\-Bi\-directional\-Iterator} requirements, +\item +for the non-parallel algorithm overloads in namespace \tcode{ranges}, +\tcode{I} models \libconcept{bidirectional_iterator}. +\end{itemize} + +\pnum +\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}. +\item +\tcode{\{\exposid{NEW_FIRST}, last\}} +for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +At most \tcode{(last - first) - n} assignments or swaps. +\end{itemdescr} + +\rSec1[alg.sorting]{Sorting and related operations} + +\rSec2[alg.sorting.general]{General} + +\pnum +The operations in~\ref{alg.sorting} defined directly in namespace \tcode{std} +have two versions: +one that takes a function object of type \tcode{Compare} and +one that uses an \tcode{operator<}. + +\pnum +\tcode{Compare} is a function object type\iref{function.objects} +that meets the requirements for a template parameter +named \tcode{BinaryPredicate}~\iref{algorithms.requirements}. +The return value of the function call operation +applied to an object of type \tcode{Compare}, +when converted to \tcode{bool}, +yields \tcode{true} +if the first argument of the call is less than the second, and +\tcode{false} otherwise. +\tcode{Compare comp} is used throughout +for algorithms assuming an ordering relation. + +\pnum +For all algorithms that take \tcode{Compare}, +there is a version that uses \tcode{operator<} instead. +That is, \tcode{comp(*i, *j) != false} defaults to \tcode{*i < *j != false}. +For algorithms other than those described in~\ref{alg.binary.search}, +\tcode{comp} shall induce a strict weak ordering on the values. + +\pnum +The term \term{strict} refers to the requirement +of an irreflexive relation (\tcode{!comp(x, x)} for all \tcode{x}), +and the term \term{weak} to requirements +that are not as strong as those for a total ordering, +but stronger than those for a partial ordering. +If we define \tcode{equiv(a, b)} as \tcode{!comp(a, b) \&\& !comp(b, a)}, +then the requirements are that \tcode{comp} and \tcode{equiv} +both be transitive relations: + +\begin{itemize} +\item \tcode{comp(a, b) \&\& comp(b, c)} implies \tcode{comp(a, c)} +\item \tcode{equiv(a, b) \&\& equiv(b, c)} implies \tcode{equiv(a, c)} +\end{itemize} +\begin{note} +Under these conditions, it can be shown that +\begin{itemize} +\item + \tcode{equiv} is an equivalence relation, +\item + \tcode{comp} induces a well-defined relation + on the equivalence classes determined by \tcode{equiv}, and +\item + the induced relation is a strict total ordering. +\end{itemize} +\end{note} + +\pnum +\indexdefn{sequence!sorted!with respect to a comparator and projection}% +A sequence is \term{sorted with respect to a \tcode{comp} and \tcode{proj}} +for a comparator and projection \tcode{comp} and \tcode{proj} +if for every iterator \tcode{i} pointing to the sequence and +every non-negative integer \tcode{n} +such that \tcode{i + n} is a valid iterator +pointing to an element of the sequence, +\begin{codeblock} +bool(invoke(comp, invoke(proj, *(i + n)), invoke(proj, *i))) +\end{codeblock} +is \tcode{false}. + +\pnum +\indexdefn{sequence!sorted!with respect to a comparator}% +A sequence is \term{sorted with respect to a comparator \tcode{comp}} +for a comparator \tcode{comp} +if it is sorted with respect to +\tcode{comp} and \tcode{identity\{\}} (the identity projection). + +\pnum +A sequence \range{start}{finish} is +\term{partitioned with respect to an expression} \tcode{f(e)} +if there exists an integer \tcode{n} +such that for all \tcode{0 <= i < (finish - start)}, +\tcode{f(*(start + i))} is \tcode{true} if and only if \tcode{i < n}. + +\pnum +In the descriptions of the functions that deal with ordering relationships +we frequently use a notion of equivalence to describe concepts +such as stability. +The equivalence to which we refer is not necessarily an \tcode{operator==}, +but an equivalence relation induced by the strict weak ordering. +That is, two elements \tcode{a} and \tcode{b} are considered equivalent +if and only if \tcode{!(a < b) \&\& !(b < a)}. + +\rSec2[alg.sort]{Sorting} + +\rSec3[sort]{\tcode{sort}} + +\indexlibraryglobal{sort}% +\begin{itemdecl} +template + constexpr void sort(RandomAccessIterator first, RandomAccessIterator last); +template + void sort(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last); + +template + constexpr void sort(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); +template + void sort(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + +template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + ranges::sort(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + 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} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\expects +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} meets +the \oldconcept{Value\-Swappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} meets +the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}) requirements. + +\pnum +\effects +Sorts the elements in the range \range{first}{last} +with respect to \tcode{comp} and \tcode{proj}. + +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. + +\pnum +\complexity +Let $N$ be \tcode{last - first}. +\bigoh{N \log N} comparisons and projections. +\end{itemdescr} + +\rSec3[stable.sort]{\tcode{stable_sort}} + +\indexlibraryglobal{stable_sort}% +\begin{itemdecl} +template + constexpr void stable_sort(RandomAccessIterator first, RandomAccessIterator last); +template + void stable_sort(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last); + +template + constexpr void stable_sort(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); +template + void stable_sort(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + +template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I ranges::stable_sort(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + 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} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\expects +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} meets +the \oldconcept{Value\-Swappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} meets +the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}) requirements. + +\pnum +\effects +Sorts the elements in the range \range{first}{last} +with respect to \tcode{comp} and \tcode{proj}. + +\pnum +\returns +\tcode{last} for the overloads in namespace \tcode{ranges}. + +\pnum +\complexity +Let $N$ be \tcode{last - first}. +If enough extra memory is available, $N \log(N)$ comparisons. +Otherwise, at most $N \log^2(N)$ comparisons. +In either case, twice as many projections as the number of comparisons. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} + +\rSec3[partial.sort]{\tcode{partial_sort}} + +\indexlibraryglobal{partial_sort}% +\begin{itemdecl} +template + constexpr void partial_sort(RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last); +template + void partial_sort(ExecutionPolicy&& exec, + RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last); + +template + constexpr void partial_sort(RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last, + Compare comp); +template + void partial_sort(ExecutionPolicy&& exec, + RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last, + Compare comp); + +template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + 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} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\expects +\range{first}{middle} and \range{middle}{last} are valid ranges. +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} meets +the \oldconcept{ValueSwappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} meets +the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}) requirements. + +\pnum +\effects +Places the first \tcode{middle - first} elements +from the range \range{first}{last} +as sorted with respect to \tcode{comp} and \tcode{proj} +into the range \range{first}{middle}. +The rest of the elements in the range \range{middle}{last} +are placed in an unspecified order. +\indextext{unspecified}% + +\pnum +\returns +\tcode{last} for the overload in namespace \tcode{ranges}. + +\pnum +\complexity +Approximately \tcode{(last - first) * log(middle - first)} comparisons, and +twice as many projections. +\end{itemdescr} + +\begin{itemdecl} +template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr borrowed_iterator_t + ranges::partial_sort(R&& r, iterator_t middle, Comp comp = {}, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ranges::partial_sort(ranges::begin(r), middle, ranges::end(r), comp, proj); +\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}% +\begin{itemdecl} +template + constexpr RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last); +template + RandomAccessIterator + partial_sort_copy(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last); + +template + constexpr RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Compare comp); +template + RandomAccessIterator + partial_sort_copy(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Compare comp); + +template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{random_access_iterator}@ I2, @\libconcept{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> + constexpr ranges::partial_sort_copy_result + ranges::partial_sort_copy(I1 first, S1 last, I2 result_first, S2 result_last, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{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>> + 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} +\pnum +Let $N$ be $\min(\tcode{last - first}, \ \tcode{result_last - result_first})$. +Let \tcode{comp} be \tcode{less\{\}}, and +\tcode{proj1} and \tcode{proj2} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\mandates +For the overloads in namespace \tcode{std}, +the expression \tcode{*first} +is writable\iref{iterator.requirements.general} to \tcode{result_first}. + +\pnum +\expects +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} meets +the \oldconcept{Value\-Swappable} requirements\iref{swappable.requirements}, +the type of \tcode{*result_first} meets +the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and +\oldconcept{\-Move\-Assignable} (\tref{cpp17.moveassignable}) requirements. + +\pnum +For iterators \tcode{a1} and \tcode{b1} in \range{first}{last}, and +iterators \tcode{x2} and \tcode{y2} in \range{result_first}{result_last}, +after evaluating the assignment \tcode{*y2 = *b1}, let $E$ be the value of +\begin{codeblock} +bool(invoke(comp, invoke(proj1, *a1), invoke(proj2, *y2))). +\end{codeblock} +Then, after evaluating the assignment \tcode{*x2 = *a1}, $E$ is equal to +\begin{codeblock} +bool(invoke(comp, invoke(proj2, *x2), invoke(proj2, *y2))). +\end{codeblock} +\begin{note} +Writing a value from the input range into the output range does not affect +how it is ordered by \tcode{comp} and \tcode{proj1} or \tcode{proj2}. +\end{note} + +\pnum +\effects +Places the first $N$ elements +as sorted with respect to \tcode{comp} and \tcode{proj2} +into the range \range{result_first}{result_first + $N$}. + +\pnum +\returns +\begin{itemize} +\item + \tcode{result_first + $N$} for the overloads in namespace \tcode{std}. +\item + \tcode{\{last, result_first + $N$\}} for + the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +Approximately \tcode{(last - first) * log $N$} comparisons, +and twice as many projections. +\end{itemdescr} + +\rSec3[is.sorted]{\tcode{is_sorted}} + +\indexlibraryglobal{is_sorted}% +\begin{itemdecl} +template + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return is_sorted_until(first, last) == last;} +\end{itemdescr} + +\indexlibraryglobal{is_sorted}% +\begin{itemdecl} +template + bool is_sorted(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return is_sorted_until(std::forward(exec), first, last) == last; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{is_sorted}% +\begin{itemdecl} +template + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last, + Compare comp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return is_sorted_until(first, last, comp) == last;} +\end{itemdescr} + + +\indexlibraryglobal{is_sorted}% +\begin{itemdecl} +template + bool is_sorted(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Compare comp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return is_sorted_until(std::forward(exec), first, last, comp) == last; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{is_sorted}% +\begin{itemdecl} +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr bool ranges::is_sorted(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + constexpr bool ranges::is_sorted(R&& r, Comp comp = {}, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\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 + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last); +template + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); + +template + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last, + Compare comp); +template + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Compare comp); + +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr I ranges::is_sorted_until(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\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} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\returns +The last iterator \tcode{i} in \crange{first}{last} +for which the range \range{first}{i} +is sorted with respect to \tcode{comp} and \tcode{proj}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\rSec2[alg.nth.element]{Nth element} + +\indexlibraryglobal{nth_element}% +\begin{itemdecl} +template + constexpr void nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last); +template + void nth_element(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last); + +template + constexpr void nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last, Compare comp); +template + void nth_element(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last, Compare comp); + +template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + 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} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\expects +\range{first}{nth} and \range{nth}{last} are valid ranges. +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} meets +the \oldconcept{ValueSwappable} requirements\iref{swappable.requirements}, and +the type of \tcode{*first} meets +the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}) requirements. + +\pnum +\effects +After \tcode{nth_element} the element in the position pointed to by \tcode{nth} +is the element that would be in that position +if the whole range were sorted with respect to \tcode{comp} and \tcode{proj}, +unless \tcode{nth == last}. +Also for every iterator \tcode{i} in the range \range{first}{nth} +and every iterator \tcode{j} in the range \range{nth}{last} +it holds that: +\tcode{bool(invoke(comp, invoke(proj, *j), invoke(proj, *i)))} is \tcode{false}. + +\pnum +\returns +\tcode{last} for the overload in namespace \tcode{ranges}. + +\pnum +\complexity +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} + +\begin{itemdecl} +template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr borrowed_iterator_t + ranges::nth_element(R&& r, iterator_t nth, Comp comp = {}, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ranges::nth_element(ranges::begin(r), nth, ranges::end(r), comp, proj); +\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} + +\pnum +All of the algorithms in \ref{alg.binary.search} are versions of binary search and +assume that the sequence being searched +is partitioned with respect to an expression +formed by binding the search key to an argument of the comparison function. +They work on non-random access iterators minimizing the number of comparisons, +which will be logarithmic for all types of iterators. +They are especially appropriate for random access iterators, +because these algorithms do a logarithmic number of steps +through the data structure. +For non-random access iterators they execute a linear number of steps. + +\rSec3[lower.bound]{\tcode{lower_bound}} + +\indexlibraryglobal{lower_bound}% +\begin{itemdecl} +template::value_type> + constexpr ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, + const T& value); + +template::value_type, + class Compare> + constexpr ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); + +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 I ranges::lower_bound(I first, S last, const T& value, Comp comp = {}, + Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = + ranges::less> + constexpr borrowed_iterator_t + ranges::lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} and +\tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + +\pnum +\expects +The elements \tcode{e} of \range{first}{last} +are partitioned with respect to the expression\\ +\tcode{bool(invoke(comp, invoke(proj, e), value))}. + +\pnum +\returns +The furthermost iterator \tcode{i} in the range \crange{first}{last} +such that for every iterator \tcode{j} in the range \range{first}{i}, +\tcode{bool(invoke(comp, invoke(proj, *j), value))} is \tcode{true}. + +\pnum +\complexity +At most $\log_2(\tcode{last - first}) + \bigoh{1}$ comparisons and projections. +\end{itemdescr} + +\rSec3[upper.bound]{\tcode{upper_bound}} + +\indexlibraryglobal{upper_bound}% +\begin{itemdecl} +template::value_type> + constexpr ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, + const T& value); + +template::value_type, + class Compare> + constexpr ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); + +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 I ranges::upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = + ranges::less> + constexpr borrowed_iterator_t + ranges::upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} and +\tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + +\pnum +\expects +The elements \tcode{e} of \range{first}{last} +are partitioned with respect to the expression\\ +\tcode{!bool(invoke(comp, value, invoke(proj, e)))}. + +\pnum +\returns +The furthermost iterator \tcode{i} in the range \crange{first}{last} +such that for every iterator \tcode{j} in the range \range{first}{i}, +\tcode{!bool(invoke(comp, value, invoke(proj, *j)))} is \tcode{true}. + +\pnum +\complexity +At most $\log_2(\tcode{last - first}) + \bigoh{1}$ comparisons and projections. +\end{itemdescr} + +\rSec3[equal.range]{\tcode{equal_range}} + +\indexlibraryglobal{equal_range}% +\begin{itemdecl} +template::value_type> + constexpr pair + equal_range(ForwardIterator first, + ForwardIterator last, const T& value); + +template::value_type, + class Compare> + constexpr pair + equal_range(ForwardIterator first, + ForwardIterator last, const T& value, + Compare comp); + +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 + ranges::equal_range(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = + ranges::less> + constexpr borrowed_subrange_t + ranges::equal_range(R&& r, const T& value, Comp comp = {}, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} and +\tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + +\pnum +\expects +The elements \tcode{e} of \range{first}{last} +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 \range{first}{last}, +\tcode{bool(comp(e, value))} implies \tcode{!bool(comp(\brk{}value, e))} +for the overloads in namespace \tcode{std}. + +\pnum +\returns +\begin{itemize} +\item +For the overloads in namespace \tcode{std}: +\begin{codeblock} +{lower_bound(first, last, value, comp), + upper_bound(first, last, value, comp)} +\end{codeblock} +\item +For the overloads in namespace \tcode{ranges}: +\begin{codeblock} +{ranges::lower_bound(first, last, value, comp, proj), + ranges::upper_bound(first, last, value, comp, proj)} +\end{codeblock} +\end{itemize} + +\pnum +\complexity +At most +$2 * \log_2(\tcode{last - first}) + \bigoh{1}$ comparisons and projections. +\end{itemdescr} + +\rSec3[binary.search]{\tcode{binary_search}} + +\indexlibraryglobal{binary_search}% +\begin{itemdecl} +template::value_type> + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value); + +template::value_type, + class Compare> + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); + +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 bool ranges::binary_search(I first, S last, const T& value, Comp comp = {}, + Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + class T = projected_value_t, Proj>, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = + ranges::less> + constexpr bool ranges::binary_search(R&& r, const T& value, Comp comp = {}, + Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} and +\tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + +\pnum +\expects +The elements \tcode{e} of \range{first}{last} +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 \range{first}{last}, +\tcode{bool(comp(e, value))} implies \tcode{!bool(comp(\brk{}value, e))} +for the overloads in namespace \tcode{std}. + +\pnum +\returns +\tcode{true} if and only if +for some iterator \tcode{i} in the range \range{first}{last}, +\tcode{!bool(invoke(comp, invoke(proj, *i), value)) \&\& +!bool(invoke(comp, value, invoke(proj, *i)))} +is \tcode{true}. + +\pnum +\complexity +At most $\log_2(\tcode{last - first}) + \bigoh{1}$ comparisons and projections. +\end{itemdescr} + +\rSec2[alg.partitions]{Partitions} + +\indexlibraryglobal{is_partitioned}% +\begin{itemdecl} +template + constexpr bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); +template + bool is_partitioned(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, Predicate pred); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr bool ranges::is_partitioned(I first, S last, Pred pred, Proj proj = {}); +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} +\pnum +Let \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameter named \tcode{proj}. + +\pnum +\returns +\tcode{true} if and only if the elements \tcode{e} of \range{first}{last} +are partitioned with respect to the expression +\tcode{bool(invoke(pred, invoke(proj, e)))}. + +\pnum +\complexity +Linear. +At most \tcode{last - first} applications of \tcode{pred} and \tcode{proj}. +\end{itemdescr} + +\indexlibraryglobal{partition}% +\begin{itemdecl} +template + constexpr ForwardIterator + partition(ForwardIterator first, ForwardIterator last, Predicate pred); +template + ForwardIterator + 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> + constexpr subrange + ranges::partition(I first, S last, Pred pred, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + 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} +\pnum +Let \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameter named \tcode{proj} +and let $E(x)$ be \tcode{bool(invoke(\brk{}pred, invoke(proj, $x$)))}. + +\pnum +\expects +For the overloads in namespace \tcode{std}, +\tcode{ForwardIterator} meets +the \oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. + +\pnum +\effects +Places all the elements \tcode{e} in \range{first}{last} +that satisfy $E(\tcode{e})$ before all the elements that do not. + +\pnum +\returns +Let \tcode{i} be an iterator such that $E(\tcode{*j})$ is +\tcode{true} for every iterator \tcode{j} in \range{first}{i} and +\tcode{false} for every iterator \tcode{j} in \range{i}{last}. +Returns: +\begin{itemize} +\item \tcode{i} for the overloads in namespace \tcode{std}. +\item \tcode{\{i, last\}} for the overloads in namespace \tcode{ranges}. +\end{itemize} + + +\pnum +\complexity +Let $N = \tcode{last - first}$: +\begin{itemize} +\item + 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 + for the overloads in namespace \tcode{std} or + models \libconcept{bidirectional_iterator} + for the overloads in namespace \tcode{ranges}, + and at most $N$ swaps otherwise. +\item + For the parallel algorithm overloads, + \bigoh{N \log N} swaps and \bigoh{N} applications of the predicate. +\end{itemize} + +\end{itemdescr} + +\indexlibraryglobal{stable_partition}% +\begin{itemdecl} +template + BidirectionalIterator + constexpr stable_partition(BidirectionalIterator first, BidirectionalIterator last, + Predicate pred); +template + BidirectionalIterator + stable_partition(ExecutionPolicy&& exec, + BidirectionalIterator first, BidirectionalIterator last, Predicate pred); + +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{permutable}@ + constexpr subrange ranges::stable_partition(I first, S last, Pred pred, Proj proj = {}); +template<@\libconcept{bidirectional_range}@ R, class Proj = identity, + @\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} +\pnum +Let \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameter named \tcode{proj} +and let $E(x)$ be \tcode{bool(invoke(\brk{}pred, invoke(proj, $x$)))}. + +\pnum +\expects +For the overloads in namespace \tcode{std}, +\tcode{BidirectionalIterator} meets +the \oldconcept{Value\-Swappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} meets +the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}) requirements. + +\pnum +\effects +Places all the elements \tcode{e} in \range{first}{last} +that satisfy $E(\tcode{e})$ before all the elements that do not. +The relative order of the elements in both groups is preserved. + +\pnum +\returns +Let \tcode{i} be an iterator +such that for every iterator \tcode{j} in \range{first}{i}, +$E(\tcode{*j})$ is \tcode{true}, +and for every iterator \tcode{j} in the range \range{i}{last}, +$E(\tcode{*j})$ is \tcode{false}. +Returns: +\begin{itemize} +\item \tcode{i} for the overloads in namespace \tcode{std}. +\item \tcode{\{i, last\}} for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +Let $N$ = \tcode{last - first}: +\begin{itemize} +\item + 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 parallel algorithm overloads, + \bigoh{N \log N} swaps and \bigoh{N} applications of the predicate. +\end{itemize} +\end{itemdescr} + +\indexlibraryglobal{partition_copy}% +\begin{itemdecl} +template + constexpr pair + partition_copy(InputIterator first, InputIterator last, + OutputIterator1 out_true, OutputIterator2 out_false, Predicate pred); +template + pair + partition_copy(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + ForwardIterator1 out_true, ForwardIterator2 out_false, Predicate pred); + +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ O1, @\libconcept{weakly_incrementable}@ O2, + class Proj = identity, @\libconcept{indirect_unary_predicate}@> Pred> + requires @\libconcept{indirectly_copyable}@ && @\libconcept{indirectly_copyable}@ + constexpr ranges::partition_copy_result + ranges::partition_copy(I first, S last, O1 out_true, O2 out_false, Pred pred, + Proj proj = {}); +template<@\libconcept{input_range}@ R, @\libconcept{weakly_incrementable}@ O1, @\libconcept{weakly_incrementable}@ O2, + class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + requires @\libconcept{indirectly_copyable}@, O1> && + @\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} +\pnum +Let \tcode{proj} be \tcode{identity\{\}} +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}, +the expression \tcode{*first} +is writable\iref{iterator.requirements.general} +to \tcode{out_true} and \tcode{out_false}. + +\pnum +\expects +The input range and output ranges do not overlap. + +\begin{note} +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}{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 $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{\{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 +At most \tcode{last - first} applications of \tcode{pred} and \tcode{proj}. +\end{itemdescr} + +\indexlibraryglobal{partition_point}% +\begin{itemdecl} +template + constexpr ForwardIterator + partition_point(ForwardIterator first, ForwardIterator last, Predicate pred); + +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_unary_predicate}@> Pred> + constexpr I ranges::partition_point(I first, S last, Pred pred, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\libconcept{indirect_unary_predicate}@, Proj>> Pred> + constexpr borrowed_iterator_t + ranges::partition_point(R&& r, Pred pred, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameter named \tcode{proj} +and let $E(x)$ be \tcode{bool(invoke(\brk{}pred, invoke(proj, $x$)))}. + +\pnum +\expects +The elements \tcode{e} of \range{first}{last} +are partitioned with respect to $E(\tcode{e})$. + +\pnum +\returns +An iterator \tcode{mid} +such that $E(\tcode{*i})$ is \tcode{true} +for all iterators \tcode{i} in \range{first}{mid}, and +\tcode{false} for all iterators \tcode{i} in \range{mid}{last}. + +\pnum +\complexity +\bigoh{\log(\tcode{last - first})} applications +of \tcode{pred} and \tcode{proj}. +\end{itemdescr} + +\rSec2[alg.merge]{Merge} + +\indexlibraryglobal{merge}% +\begin{itemdecl} +template + constexpr OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); +template + ForwardIterator + merge(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + +template + constexpr OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); +template + ForwardIterator + merge(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + +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, + class Proj2 = identity> + requires @\libconcept{mergeable}@ + constexpr ranges::merge_result + ranges::merge(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, class Comp = ranges::less, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, O, Comp, Proj1, Proj2> + 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: +\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 +The ranges \range{first1}{last1} and \range{first2}{last2} +are sorted with respect to \tcode{comp} and \tcode{proj1} or \tcode{proj2}, +respectively. +The resulting range does not overlap with either of the original ranges. + +\pnum +\effects +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 $E$ is \tcode{true}. + +\pnum +\returns +\begin{itemize} +\item + \tcode{result + $N$} + for the overloads in namespace \tcode{std}. +\item + \tcode{\{first1 + $K$, first2 + $N$ - $K$, result + $N$\}} + for the overloads in namespace \tcode{ranges}. +\end{itemize} + +\pnum +\complexity +\begin{itemize} +\item + For the non-parallel algorithm overloads, + at most $N - 1$ comparisons and applications of each projection. +\item + For the parallel algorithm overloads, + \bigoh{N} comparisons and applications of each projection. +\end{itemize} + +\pnum +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} + +\indexlibraryglobal{inplace_merge}% +\begin{itemdecl} +template + constexpr void inplace_merge(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last); +template + void inplace_merge(ExecutionPolicy&& exec, + BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last); + +template + constexpr void inplace_merge(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, Compare comp); +template + void inplace_merge(ExecutionPolicy&& exec, + BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, Compare comp); + +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + 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} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\expects +\range{first}{middle} and \range{middle}{last} are valid ranges +sorted with respect to \tcode{comp} and \tcode{proj}. +For the overloads in namespace \tcode{std}, +\tcode{BidirectionalIterator} meets +the \oldconcept{Value\-Swappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} meets +the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}) requirements. + +\pnum +\effects +Merges two sorted consecutive ranges +\range{first}{middle} and \range{middle}{last}, +putting the result of the merge into the range \range{first}{last}. +The resulting range is sorted with respect to \tcode{comp} and \tcode{proj}. + +\pnum +\returns +\tcode{last} for the overload in namespace \tcode{ranges}. + +\pnum +\complexity +Let $N = \tcode{last - first}$: +\begin{itemize} +\item + 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} +In either case, twice as many projections as comparisons. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} + +\begin{itemdecl} +template<@\libconcept{bidirectional_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr borrowed_iterator_t + ranges::inplace_merge(R&& r, iterator_t middle, Comp comp = {}, Proj proj = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ranges::inplace_merge(ranges::begin(r), middle, ranges::end(r), comp, proj); +\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} + +\pnum +Subclause \ref{alg.set.operations} defines all the basic set operations on sorted structures. +They also work with \tcode{multiset}s\iref{multiset} +containing multiple copies of equivalent elements. +The semantics of the set operations are generalized to \tcode{multiset}s +in a standard way by defining \tcode{set_union} +to contain the maximum number of occurrences of every element, +\tcode{set_intersection} to contain the minimum, and so on. + +\rSec3[includes]{\tcode{includes}} + +\indexlibraryglobal{includes}% +\begin{itemdecl} +template + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); +template + bool includes(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + +template + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp); +template + bool includes(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + Compare comp); + +template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, + projected> Comp = ranges::less> + constexpr bool ranges::includes(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Proj1 = identity, + class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, Proj1>, + 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} +\pnum +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. + +\pnum +\expects +The ranges \range{first1}{last1} and \range{first2}{last2} are sorted +with respect to \tcode{comp} and \tcode{proj1} or \tcode{proj2}, respectively. + +\pnum +\returns +\tcode{true} +if and only if \range{first2}{last2} is a subsequence of \range{first1}{last1}. +\begin{note} +A sequence $S$ is a subsequence of another sequence $T$ if $S$ can be obtained +from $T$ by removing some, all, or none of $T$'s elements and keeping the +remaining elements in the same order. +\end{note} + +\pnum +\complexity +At most \tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} +comparisons and applications of each projection. +\end{itemdescr} + +\rSec3[set.union]{\tcode{set_union}} + +\indexlibraryglobal{set_union}% +\begin{itemdecl} +template + constexpr OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); +template + ForwardIterator + set_union(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + +template + constexpr OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); +template + ForwardIterator + set_union(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + +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, class Proj2 = identity> + requires @\libconcept{mergeable}@ + constexpr ranges::set_union_result + ranges::set_union(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, O, Comp, Proj1, Proj2> + 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: +\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 +The ranges \range{first1}{last1} and \range{first2}{last2} are sorted +with respect to \tcode{comp} and \tcode{proj1} or \tcode{proj2}, respectively. +The resulting range does not overlap with either of the original ranges. + +\pnum +\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 +\begin{itemize} +\item + \tcode{result_last} + for the overloads in namespace \tcode{std}. +\item + \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 -All of the algorithms are separated from the particular implementations of data structures and are -parameterized by iterator types. -Because of this, they can work with program-defined data structures, as long -as these data structures have iterator types satisfying the assumptions on the algorithms. - -\pnum -For purposes of determining the existence of data races, algorithms shall -not modify objects referenced through an iterator argument unless the -specification requires such modification. - -\pnum -Throughout this Clause, the names of template parameters -are used to express type requirements. -\begin{itemize} -\item -If an algorithm's template parameter is named -\tcode{InputIterator}, -\tcode{InputIterator1}, -or -\tcode{InputIterator2}, -the template argument shall satisfy the -requirements of an input iterator~(\ref{input.iterators}). -\item -If an algorithm's template parameter is named -\tcode{OutputIterator}, -\tcode{OutputIterator1}, -or -\tcode{OutputIterator2}, -the template argument shall satisfy the requirements -of an output iterator~(\ref{output.iterators}). -\item -If an algorithm's template parameter is named -\tcode{ForwardIterator}, -\tcode{ForwardIterator1}, -or -\tcode{ForwardIterator2}, -the template argument shall satisfy the requirements -of a forward iterator~(\ref{forward.iterators}). -\item -If an algorithm's template parameter is named -\tcode{BidirectionalIterator}, -\tcode{Bidirectional\-Iterator1}, -or -\tcode{BidirectionalIterator2}, -the template argument shall satisfy the requirements -of a bidirectional iterator~(\ref{bidirectional.iterators}). -\item -If an algorithm's template parameter is named -\tcode{RandomAccessIterator}, -\tcode{Random\-AccessIterator1}, -or -\tcode{RandomAccessIterator2}, -the template argument shall satisfy the requirements -of a random-access iterator~(\ref{random.access.iterators}). -\end{itemize} - -\pnum -If an algorithm's -\synopsis{Effects} -section says that a value pointed to by any iterator passed -as an argument is modified, then that algorithm has an additional -type requirement: -The type of that argument shall satisfy the requirements -of a mutable iterator~(\ref{iterator.requirements}). -\enternote -This requirement does not affect arguments that are named -\tcode{OutputIterator}, -\tcode{OutputIterator1}, -or -\tcode{OutputIterator2}, -because output iterators must always be mutable. -\exitnote - -\pnum -Both in-place and copying versions are provided for certain -algorithms.\footnote{The decision whether to include a copying version was -usually based on complexity considerations. When the cost of doing the operation -dominates the cost of copy, the copying version is not included. For example, -\tcode{sort_copy} is not included because the cost of sorting is much more -significant, and users might as well do \tcode{copy} followed by \tcode{sort}.} -When such a version is provided for \textit{algorithm} it is called -\textit{algorithm\tcode{_copy}}. Algorithms that take predicates end with the -suffix \tcode{_if} (which follows the suffix \tcode{_copy}). - -\pnum -The -\tcode{Predicate} -parameter is used whenever an algorithm expects a function object~(\ref{function.objects}) -that, when applied to the result -of dereferencing the corresponding iterator, returns a value testable as -\tcode{true}. -In other words, if an algorithm -takes -\tcode{Predicate pred} -as its argument and \tcode{first} -as its iterator argument, it should work correctly in the -construct -\tcode{pred(*first)} contextually converted to \tcode{bool} (Clause~\ref{conv}). -The function object -\tcode{pred} -shall not apply any non-constant -function through the dereferenced iterator. - -\pnum -The -\tcode{BinaryPredicate} -parameter is used whenever an algorithm expects a function object that when applied to -the result of dereferencing two corresponding iterators or to dereferencing an -iterator and type -\tcode{T} -when -\tcode{T} -is part of the signature returns a value testable as -\tcode{true}. -In other words, if an algorithm takes -\tcode{BinaryPredicate binary_pred} -as its argument and \tcode{first1} and \tcode{first2} as -its iterator arguments, it should work correctly in -the construct -\tcode{binary_pred(*first1, *first2)} contextually converted to \tcode{bool} (Clause~\ref{conv}). -\tcode{BinaryPredicate} -always takes the first -iterator's \tcode{value_type} -as its first argument, that is, in those cases when -\tcode{T value} -is part of the signature, it should work -correctly in the -construct \tcode{binary_pred(*first1, value)} contextually converted to \tcode{bool} (Clause~\ref{conv}). -\tcode{binary_pred} shall not -apply any non-constant function through the dereferenced iterators. - -\pnum -\enternote -Unless otherwise specified, algorithms that take function objects as arguments -are permitted to copy those function objects freely. Programmers for whom object -identity is important should consider using a wrapper class that points to a -noncopied implementation object such as \tcode{reference_wrapper}~(\ref{refwrap}), or some equivalent solution. -\exitnote +\complexity +At most \tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} +comparisons and applications of each projection. \pnum -When the description of an algorithm gives an expression such as -\tcode{*first == value} -for a condition, the expression shall evaluate to -either true or false in boolean contexts. +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} -\pnum -In the description of the algorithms operators -\tcode{+} -and -\tcode{-} -are used for some of the iterator categories for which -they do not have to be defined. -In these cases the semantics of -\tcode{a+n} -is the same as that of +\rSec3[set.intersection]{\tcode{set_intersection}} -\begin{codeblock} -X tmp = a; -advance(tmp, n); -return tmp; -\end{codeblock} +\indexlibraryglobal{set_intersection}% +\begin{itemdecl} +template + constexpr OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); +template + ForwardIterator + set_intersection(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); -and that of -\tcode{b-a} -is the same as of +template + constexpr OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); +template + ForwardIterator + set_intersection(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + +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, class Proj2 = identity> + requires @\libconcept{mergeable}@ + constexpr ranges::set_intersection_result + ranges::set_intersection(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, O, Comp, Proj1, Proj2> + 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{codeblock} -return distance(a, b); -\end{codeblock} +\begin{itemdescr} +\pnum +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} -\rSec1[alg.nonmodifying]{Non-modifying sequence operations} +\pnum +\expects +The ranges \range{first1}{last1} and \range{first2}{last2} are sorted +with respect to \tcode{comp} and \tcode{proj1} or \tcode{proj2}, respectively. +The resulting range does not overlap with either of the original ranges. -\rSec2[alg.all_of]{All of} +\pnum +\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$}. -\indexlibrary{\idxcode{all_of}}% -\begin{itemdecl} -template - bool all_of(InputIterator first, InputIterator last, Predicate pred); -\end{itemdecl} +\pnum +\returns +\begin{itemize} +\item + \tcode{result_last} + for the overloads in namespace \tcode{std}. +\item + \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} -\begin{itemdescr} \pnum -\returns \tcode{true} if -\range{first}{last} is empty or if -\tcode{pred(*i)} is \tcode{true} for every iterator \tcode{i} in the range \range{first}{last}, and \tcode{false} otherwise. +\complexity +At most \tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} +comparisons and applications of each projection. \pnum -\complexity At most \tcode{last - first} applications of the predicate. +\remarks +Stable\iref{algorithm.stable}. \end{itemdescr} -\rSec2[alg.any_of]{Any of} +\rSec3[set.difference]{\tcode{set_difference}} -\indexlibrary{\idxcode{any_of}}% +\indexlibraryglobal{set_difference}% \begin{itemdecl} -template - bool any_of(InputIterator first, InputIterator last, Predicate pred); +template + constexpr OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); +template + ForwardIterator + set_difference(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + +template + constexpr OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); +template + ForwardIterator + set_difference(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + +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, class Proj2 = identity> + requires @\libconcept{mergeable}@ + constexpr ranges::set_difference_result + ranges::set_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, O, Comp, Proj1, Proj2> + 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 -\returns \tcode{false} if \range{first}{last} is empty or -if there is no iterator \tcode{i} in the range -\range{first}{last} such that \tcode{pred(*i)} is \tcode{true}, and \tcode{true} otherwise. +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 -\complexity At most \tcode{last - first} applications of the predicate. -\end{itemdescr} +\expects +The ranges \range{first1}{last1} and \range{first2}{last2} are sorted +with respect to \tcode{comp} and \tcode{proj1} or \tcode{proj2}, respectively. +The resulting range does not overlap with either of the original ranges. -\rSec2[alg.none_of]{None of} +\pnum +\effects +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$}. -\indexlibrary{\idxcode{none_of}}% -\begin{itemdecl} -template - bool none_of(InputIterator first, InputIterator last, Predicate pred); -\end{itemdecl} +\pnum +\returns +\begin{itemize} +\item + \tcode{result_last} + for the overloads in namespace \tcode{std}. +\item + \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} -\begin{itemdescr} \pnum -\returns \tcode{true} if -\range{first}{last} is empty or if -\tcode{pred(*i)} is \tcode{false} for every iterator \tcode{i} in the range \range{first}{last}, and \tcode{false} otherwise. +\complexity +At most \tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} +comparisons and applications of each projection. \pnum -\complexity At most \tcode{last - first} applications of the predicate. +\remarks +Stable\iref{algorithm.stable}. \end{itemdescr} -\rSec2[alg.foreach]{For each} +\rSec3[set.symmetric.difference]{\tcode{set_symmetric_difference}} -\indexlibrary{\idxcode{for_each}}% +\indexlibraryglobal{set_symmetric_difference}% \begin{itemdecl} -template - Function for_each(InputIterator first, InputIterator last, Function f); +template + constexpr OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); +template + ForwardIterator + set_symmetric_difference(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + +template + constexpr OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); +template + ForwardIterator + set_symmetric_difference(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + +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, class Proj2 = identity> + requires @\libconcept{mergeable}@ + constexpr ranges::set_symmetric_difference_result + ranges::set_symmetric_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result, + Comp comp = {}, Proj1 proj1 = {}, + Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, @\libconcept{weakly_incrementable}@ O, + class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{mergeable}@, iterator_t, O, Comp, Proj1, Proj2> + constexpr ranges::set_symmetric_difference_result, + 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 -\requires \tcode{Function} shall meet the requirements of -\tcode{MoveConstructible} (Table~\ref{moveconstructible}). -\enternote \tcode{Function} need not meet the requirements of -\tcode{CopyConstructible} (Table~\ref{copyconstructible}). \exitnote +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 +The ranges \range{first1}{last1} and \range{first2}{last2} are sorted +with respect to \tcode{comp} and \tcode{proj1} or \tcode{proj2}, respectively. +The resulting range does not overlap with either of the original ranges. \pnum \effects -Applies -\tcode{f} to the result of dereferencing every iterator in the range -\range{first}{last}, -starting from -\tcode{first} -and proceeding to -\tcode{last - 1}. -\enternote If the type of \tcode{first} satisfies the -requirements of a mutable iterator, \tcode{f} may apply nonconstant -functions through the dereferenced iterator.\exitnote +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 -\tcode{std::move(f)}. +\begin{itemize} +\item + \tcode{result_last} + for the overloads in namespace \tcode{std}. +\item + \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 \complexity -Applies \tcode{f} -exactly -\tcode{last - first} -times. +At most \tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} +comparisons and applications of each projection. \pnum -\notes -If \tcode{f} returns a result, the result is ignored. +\remarks +Stable\iref{algorithm.stable}. \end{itemdescr} -\rSec2[alg.find]{Find} +\rSec2[alg.heap.operations]{Heap operations} + +\rSec3[alg.heap.operations.general]{General} + +\pnum +A random access range \range{a}{b} is a +\defnx{heap with respect to \tcode{comp} and \tcode{proj}} +{heap with respect to comp and proj@heap with respect to \tcode{comp} and \tcode{proj}} +for a comparator and projection \tcode{comp} and \tcode{proj} +if its elements are organized such that: + +\begin{itemize} +\item + With \tcode{$N$ = b - a}, for all $i$, $0 < i < N$, + \tcode{bool(invoke(comp, invoke(proj, a[$\left \lfloor{\frac{i - 1}{2}}\right \rfloor$]), invoke(\brk{}proj, a[$i$])))} + is \tcode{false}. +\item + \tcode{*a} may be removed by \tcode{pop_heap}, or + a new element added by \tcode{push_heap}, + in \bigoh{\log N} time. +\end{itemize} + +\pnum +These properties make heaps useful as priority queues. + +\pnum +\tcode{make_heap} converts a range into a heap and +\tcode{sort_heap} turns a heap into a sorted sequence. -\indexlibrary{\idxcode{find}}% -\indexlibrary{\idxcode{find_if}}% -\indexlibrary{\idxcode{find_if_not}}% +\rSec3[push.heap]{\tcode{push_heap}} + +\indexlibraryglobal{push_heap}% \begin{itemdecl} -template - InputIterator find(InputIterator first, InputIterator last, - const T& value); +template + constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last); -template - InputIterator find_if(InputIterator first, InputIterator last, - Predicate pred); -template - InputIterator find_if_not(InputIterator first, InputIterator last, - Predicate pred); +template + constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + +template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + ranges::push_heap(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr borrowed_iterator_t + ranges::push_heap(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\expects +The range \range{first}{last - 1} +is a valid heap with respect to \tcode{comp} and \tcode{proj}. +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} meets +the \oldconcept{ValueSwappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} meets +the \oldconcept{MoveConstructible} requirements (\tref{cpp17.moveconstructible}) and +the \oldconcept{MoveAssignable} requirements (\tref{cpp17.moveassignable}). + +\pnum +\effects +Places the value in the location \tcode{last - 1} +into the resulting heap \range{first}{last}. + \pnum \returns -The first iterator -\tcode{i} -in the range -\range{first}{last} -for which the following corresponding -conditions hold: -\tcode{*i == value}, \tcode{pred(*i) != false}, \tcode{pred(*i) == false}. -Returns \tcode{last} if no such iterator is found. +\tcode{last} for the overloads in namespace \tcode{ranges}. \pnum \complexity -At most -\tcode{last - first} -applications of the corresponding predicate. +At most $\log(\tcode{last - first})$ comparisons and twice as many projections. \end{itemdescr} -\rSec2[alg.find.end]{Find end} +\rSec3[pop.heap]{\tcode{pop_heap}} -\indexlibrary{\idxcode{find_end}}% +\indexlibraryglobal{pop_heap}% \begin{itemdecl} -template - ForwardIterator1 - find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); +template + constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last); -template - ForwardIterator1 - find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); +template + constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + +template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + ranges::pop_heap(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr borrowed_iterator_t + ranges::pop_heap(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\expects +The range \range{first}{last} +is a valid non-empty heap with respect to \tcode{comp} and \tcode{proj}. +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} meets +the \oldconcept{ValueSwappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} meets +the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}) requirements. + \pnum \effects -Finds a subsequence of equal values in a sequence. +Swaps the value in the location \tcode{first} +with the value in the location +\tcode{last - 1} +and makes +\range{first}{last - 1} +into a heap with respect to \tcode{comp} and \tcode{proj}. \pnum \returns -The last iterator -\tcode{i} -in the range \range{first1}{last1 - (last2 - first2)} -such that for every non-negative integer -\tcode{n < (last2 - first2)}, -the following corresponding conditions hold: -\tcode{*(i + n) == *(\brk{}first2 + n), pred(*(i + n), *(first2 + n)) != false}. -Returns \tcode{last1} -if -\range{first2}{last2} is empty or if -no such iterator is found. +\tcode{last} for the overloads in namespace \tcode{ranges}. \pnum \complexity -At most -\tcode{(last2 - first2) * (last1 - first1 - (last2 - first2) + 1)} -applications of the corresponding predicate. +At most $2 \log(\tcode{last - first})$ comparisons and +twice as many projections. \end{itemdescr} -\rSec2[alg.find.first.of]{Find first} +\rSec3[make.heap]{\tcode{make_heap}} -\indexlibrary{\idxcode{find_first_of}}% +\indexlibraryglobal{make_heap}% \begin{itemdecl} -template - InputIterator - find_first_of(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2); +template + constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last); -template - InputIterator - find_first_of(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2, - BinaryPredicate pred); +template + constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + +template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + ranges::make_heap(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr borrowed_iterator_t + ranges::make_heap(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\expects +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} meets +the \oldconcept{ValueSwap\-pable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} meets +the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}) requirements. + \pnum \effects -Finds an element that matches one of a set of values. +Constructs a heap with respect to \tcode{comp} and \tcode{proj} +out of the range \range{first}{last}. \pnum \returns -The first iterator -\tcode{i} -in the range \range{first1}{last1} -such that for some -iterator -\tcode{j} -in the range \range{first2}{last2} -the following conditions hold: -\tcode{*i == *j, pred(*i,*j) != false}. -Returns \tcode{last1} -if \range{first2}{last2} is empty or -if no such iterator is found. +\tcode{last} for the overloads in namespace \tcode{ranges}. \pnum \complexity -At most -\tcode{(last1-first1) * (last2-first2)} -applications of the corresponding predicate. +At most $3(\tcode{last - first})$ comparisons and twice as many projections. \end{itemdescr} -\rSec2[alg.adjacent.find]{Adjacent find} +\rSec3[sort.heap]{\tcode{sort_heap}} -\indexlibrary{\idxcode{adjacent_find}}% +\indexlibraryglobal{sort_heap}% \begin{itemdecl} -template - ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last); +template + constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last); -template - ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); +template + constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + +template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr I + ranges::sort_heap(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{random_access_range}@ R, class Comp = ranges::less, class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr borrowed_iterator_t + ranges::sort_heap(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. + +\pnum +\expects +The range \range{first}{last} is +a valid heap with respect to \tcode{comp} and \tcode{proj}. +For the overloads in namespace \tcode{std}, +\tcode{RandomAccessIterator} meets +the \oldconcept{ValueSwappable} requirements\iref{swappable.requirements} and +the type of \tcode{*first} meets +the \oldconcept{MoveConst\-ruct\-ible} (\tref{cpp17.moveconstructible}) and +\oldconcept{Move\-Assign\-able} (\tref{cpp17.moveassignable}) requirements. + +\pnum +\effects +Sorts elements in the heap \range{first}{last} +with respect to \tcode{comp} and \tcode{proj}. + \pnum \returns -The first iterator -\tcode{i} -such that both -\tcode{i} -and -\tcode{i + 1} -are in -the range -\range{first}{last} -for which -the following corresponding conditions hold: -\tcode{*i == *(i + 1), pred(*i, *(i + 1)) != false}. -Returns \tcode{last} -if no such iterator is found. +\tcode{last} for the overloads in namespace \tcode{ranges}. \pnum \complexity -For a nonempty range, exactly -\tcode{min((i - first) + 1, (last - first) - 1)} -applications of the corresponding predicate, where \tcode{i} is -\tcode{adjacent_find}'s -return value. +At most $2N \log N$ comparisons, where $N = \tcode{last - first}$, and +twice as many projections. \end{itemdescr} -\rSec2[alg.count]{Count} +\rSec3[is.heap]{\tcode{is_heap}} -\indexlibrary{\idxcode{count}}% -\indexlibrary{\idxcode{count_if}}% +\indexlibraryglobal{is_heap}% \begin{itemdecl} -template - typename iterator_traits::difference_type - count(InputIterator first, InputIterator last, const T& value); - -template - typename iterator_traits::difference_type - count_if(InputIterator first, InputIterator last, Predicate pred); +template + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last); \end{itemdecl} \begin{itemdescr} \pnum \effects -Returns the number of iterators -\tcode{i} -in the range \range{first}{last} -for which the following corresponding -conditions hold: -\tcode{*i == value, pred(*i) != false}. +Equivalent to: \tcode{return is_heap_until(first, last) == last;} +\end{itemdescr} + +\indexlibraryglobal{is_heap}% +\begin{itemdecl} +template + bool is_heap(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last); +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -Exactly -\tcode{last - first} -applications of the corresponding predicate. +\effects +Equivalent to: +\begin{codeblock} +return is_heap_until(std::forward(exec), first, last) == last; +\end{codeblock} \end{itemdescr} -\rSec2[mismatch]{Mismatch} - -\indexlibrary{\idxcode{mismatch}}% +\indexlibraryglobal{is_heap}% \begin{itemdecl} -template - pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); +template + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); +\end{itemdecl} -template - pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return is_heap_until(first, last, comp) == last;} +\end{itemdescr} -template - pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); +\indexlibraryglobal{is_heap}% +\begin{itemdecl} +template + bool is_heap(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); +\end{itemdecl} -template - pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - BinaryPredicate pred); +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return is_heap_until(std::forward(exec), first, last, comp) == last; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{is_heap}% +\begin{itemdecl} +template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr bool ranges::is_heap(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{random_access_range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + constexpr bool ranges::is_heap(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum -\remarks If \tcode{last2} was not given in the argument list, it denotes -\tcode{first2 + (last1 - first1)} below. - -\pnum -\returns -A pair of iterators -\tcode{i} -and -\tcode{j} -such that -\tcode{j == first2 + (i - first1)} -and -\tcode{i} -is the first iterator -in the range \range{first1}{last1} -for which the following corresponding conditions hold: - -\begin{itemize} -\item \tcode{j} is in the range \tcode{[first2, last2)}. -\item \tcode{!(*i == *(first2 + (i - first1)))} -\item \tcode{pred(*i, *(first2 + (i - first1))) == false} -\end{itemize} +\effects +Equivalent to: +\tcode{return ranges::is_heap_until(first, last, comp, proj) == last;} +\end{itemdescr} -Returns the pair -\tcode{first1 + min(last1 - first1, last2 - first2)} -and -\tcode{first2 + min(last1 - first1, last2 - first2)} -if such an iterator -\tcode{i} -is not found. +\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 -\complexity -At most -\tcode{min(last1 - first1, last2 - first2)} -applications of the corresponding predicate. +\effects +Equivalent to: +\begin{codeblock} +return ranges::is_heap_until(std::forward(exec), first, last, comp, proj) == last; +\end{codeblock} \end{itemdescr} -\rSec2[alg.equal]{Equal} - -\indexlibrary{\idxcode{equal}}% +\indexlibraryglobal{is_heap_until}% \begin{itemdecl} -template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); - -template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); +template + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last); +template + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last); -template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); +template + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); +template + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); -template - bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - BinaryPredicate pred); +template<@\libconcept{random_access_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr I ranges::is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{random_access_range}@ R, class Proj = identity, + @\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} \pnum -\remarks If \tcode{last2} was not given in the argument list, it denotes -\tcode{first2 + (last1 - first1)} below. +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. \pnum \returns -If -\tcode{last1 - first1 != last2 - first2}, -return -\tcode{false}. -Otherwise return -\tcode{true} -if for every iterator -\tcode{i} -in the range \range{first1}{last1} -the following corresponding conditions hold: -\tcode{*i == *(first2 + (i - first1)), pred(*i, *(first2 + (i - first1))) != false}. -Otherwise, returns -\tcode{false}. +The last iterator \tcode{i} in \crange{first}{last} +for which the range \range{first}{i} +is a heap with respect to \tcode{comp} and \tcode{proj}. \pnum \complexity -No applications of the corresponding predicate if -\tcode{InputIterator1} -and -\tcode{InputIterator2} -meet the requirements of random access iterators and -\tcode{last1 - first1 != last2 - first2}. -Otherwise, at most -\tcode{min(last1 - first1, last2 - first2)} -applications of the corresponding predicate. +Linear. \end{itemdescr} -\rSec2[alg.is_permutation]{Is permutation} -\indexlibrary{\idxcode{is_permutation}}% +\rSec2[alg.min.max]{Minimum and maximum} + +\indexlibraryglobal{min}% \begin{itemdecl} -template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); -template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, BinaryPredicate pred); -template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); -template - bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); +template + constexpr const T& min(const T& a, const T& b); +template + constexpr const T& min(const T& a, const T& b, Compare comp); + +template> Comp = ranges::less> + constexpr const T& ranges::min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{ForwardIterator1} and \tcode{ForwardIterator2} shall have the same -value type. The comparison function shall be an equivalence relation. +\expects +For the first form, \tcode{T} meets the +\oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). \pnum -\remarks If \tcode{last2} was not given in the argument list, it denotes -\tcode{first2 + (last1 - first1)} below. +\returns +The smaller value. +Returns the first argument when the arguments are equivalent. \pnum -\returns If \tcode{last1 - first1 != last2 - first2}, return \tcode{false}. -Otherwise return \tcode{true} if there exists a permutation of the elements in the -range \range{first2}{first2 + (last1 - first1)}, beginning with \tcode{ForwardIterator2 -begin}, such that \tcode{equal(first1, last1, begin)} returns \tcode{true} or -\tcode{equal(first1, last1, begin, pred)} returns \tcode{true}; otherwise, returns -\tcode{false}. +\complexity +Exactly one comparison and two applications of the projection, if any. \pnum -\complexity No applications of the corresponding predicate if \tcode{ForwardIterator1} -and \tcode{ForwardIter\-ator2} meet the requirements of random access iterators and -\tcode{last1 - first1 != last2 - first2}. -Otherwise, exactly \tcode{distance(first1, last1)} applications of the -corresponding predicate if \tcode{equal(\brk{}first1, last1, first2, last2)} -would return \tcode{true} if \tcode{pred} was not given in the argument list -or \tcode{equal(first1, last1, first2, last2, pred)} would return \tcode{true} if pred was given in the argument list; otherwise, at -worst \bigoh{N^2}, where $N$ has the value \tcode{distance(first1, last1)}. +\remarks +An invocation may explicitly specify +an argument for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. \end{itemdescr} -\rSec2[alg.search]{Search} - -\indexlibrary{\idxcode{search}}% +\indexlibraryglobal{min}% \begin{itemdecl} -template - ForwardIterator1 - search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - -template - ForwardIterator1 - search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); +template + constexpr T min(initializer_list r); +template + constexpr T min(initializer_list r, Compare comp); + +template<@\libconcept{copyable}@ T, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr T ranges::min(initializer_list r, Comp comp = {}, Proj proj = {}); +template<@\libconcept{input_range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + 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} \pnum -\effects -Finds a subsequence of equal values in a sequence. +\expects +\tcode{ranges::distance(r) > 0}. +For the overloads in namespace \tcode{std}, +\tcode{T} meets the \oldconcept{\-Copy\-Constructible} requirements. +For the first form, \tcode{T} meets the \oldconcept{LessThanComparable} +requirements (\tref{cpp17.lessthancomparable}). \pnum \returns -The first iterator -\tcode{i} -in the range \range{first1}{last1 - (last2-first2)} -such that for every non-negative integer -\tcode{n} -less than -\tcode{last2 - first2} -the following corresponding conditions hold: -\tcode{*(i + n) == *(first2 + n), pred(*(i + n), *(first2 + n)) != false}. -Returns \tcode{first1} -if \range{first2}{last2} is empty, -otherwise returns \tcode{last1} -if no such iterator is found. +The smallest value in the input range. +Returns a copy of the leftmost element +when several elements are equivalent to the smallest. \pnum \complexity -At most -\tcode{(last1 - first1) * (last2 - first2)} -applications of the corresponding predicate. +Exactly \tcode{ranges::distance(r) - 1} comparisons +and twice as many applications of the projection, if any. + +\pnum +\remarks +An invocation may explicitly specify +an argument for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. \end{itemdescr} -\indexlibrary{\idxcode{search_n}}% +\indexlibraryglobal{max}% \begin{itemdecl} -template - ForwardIterator - search_n(ForwardIterator first, ForwardIterator last, Size count, - const T& value); +template + constexpr const T& max(const T& a, const T& b); +template + constexpr const T& max(const T& a, const T& b, Compare comp); -template - ForwardIterator - search_n(ForwardIterator first, ForwardIterator last, Size count, - const T& value, BinaryPredicate pred); +template> Comp = ranges::less> + constexpr const T& ranges::max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum -\requires -The type -\tcode{Size} -shall be convertible to integral type~(\ref{conv.integral}, \ref{class.conv}). - -\pnum -\effects -Finds a subsequence of equal values in a sequence. +\expects +For the first form, \tcode{T} meets the +\oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). \pnum \returns -The first iterator -\tcode{i} -in the range \range{first}{last-count} -such that for every non-negative integer -\tcode{n} -less than -\tcode{count} -the following corresponding conditions hold: -\tcode{*(i + n) == value, pred(*(i + n),value) != false}. -Returns \tcode{last} -if no such iterator is found. +The larger value. +Returns the first argument when the arguments are equivalent. \pnum \complexity -At most -\tcode{last - first} -applications of the corresponding predicate. -\end{itemdescr} - -\rSec1[alg.modifying.operations]{Mutating sequence operations} +Exactly one comparison and two applications of the projection, if any. -\rSec2[alg.copy]{Copy} +\pnum +\remarks +An invocation may explicitly specify +an argument for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. +\end{itemdescr} -\indexlibrary{\idxcode{copy}}% +\indexlibraryglobal{max}% \begin{itemdecl} -template - OutputIterator copy(InputIterator first, InputIterator last, - OutputIterator result); +template + constexpr T max(initializer_list r); +template + constexpr T max(initializer_list r, Compare comp); + +template<@\libconcept{copyable}@ T, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr T ranges::max(initializer_list r, Comp comp = {}, Proj proj = {}); +template<@\libconcept{input_range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + 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} \pnum -\effects Copies elements in the range \range{first}{last} into the range \range{result}{result + (last - first)} starting from \tcode{first} and proceeding to \tcode{last}. For each non-negative integer \tcode{n < (last - first)}, performs \tcode{*(result + n) = *(first + n)}. +\expects +\tcode{ranges::distance(r) > 0}. +For the overloads in namespace \tcode{std}, +\tcode{T} meets the \oldconcept{\-Copy\-Constructible} requirements. +For the first form, \tcode{T} meets the \oldconcept{LessThanComparable} +requirements (\tref{cpp17.lessthancomparable}). \pnum -\returns \tcode{result + (last - first)}. +\returns +The largest value in the input range. +Returns a copy of the leftmost element +when several elements are equivalent to the largest. \pnum -\requires \tcode{result} shall not be in the range \range{first}{last}. +\complexity +Exactly \tcode{ranges::distance(r) - 1} comparisons +and twice as many applications of the projection, if any. \pnum -\complexity Exactly \tcode{last - first} assignments. +\remarks +An invocation may explicitly specify +an argument for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. \end{itemdescr} -\indexlibrary{\idxcode{copy_n}}% +\indexlibraryglobal{minmax}% \begin{itemdecl} -template - OutputIterator copy_n(InputIterator first, Size n, - OutputIterator result); +template + constexpr pair minmax(const T& a, const T& b); +template + constexpr pair minmax(const T& a, const T& b, Compare comp); + +template> Comp = ranges::less> + constexpr ranges::minmax_result + ranges::minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum -\effects For each non-negative integer -$i < n$, performs \tcode{*(result + i) = *(first + i)}. +\expects +For the first form, \tcode{T} meets the +\oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). + +\pnum +\returns +\tcode{\{b, a\}} if \tcode{b} is smaller than \tcode{a}, and +\tcode{\{a, b\}} otherwise. \pnum -\returns \tcode{result + n}. +\complexity +Exactly one comparison and two applications of the projection, if any. \pnum -\complexity Exactly \tcode{n} assignments. +\remarks +An invocation may explicitly specify +an argument for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. \end{itemdescr} -\indexlibrary{\idxcode{copy_n}}% +\indexlibraryglobal{minmax}% \begin{itemdecl} -template - OutputIterator copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); -\end{itemdecl} +template + constexpr pair minmax(initializer_list t); +template + constexpr pair minmax(initializer_list t, Compare comp); +template<@\libconcept{copyable}@ T, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr ranges::minmax_result + ranges::minmax(initializer_list r, Comp comp = {}, Proj proj = {}); +template<@\libconcept{input_range}@ R, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@, Proj>> Comp = ranges::less> + 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} \pnum -\requires The ranges \range{first}{last} and \range{result}{result + (last - first)} shall not overlap. +\expects +\tcode{ranges::distance(r) > 0}. +For the overloads in namespace \tcode{std}, +\tcode{T} meets the \oldconcept{\-Copy\-Constructible} requirements. +For the first form, type \tcode{T} meets the \oldconcept{LessThanComparable} +requirements (\tref{cpp17.lessthancomparable}). \pnum -\effects Copies all of the elements referred to by the iterator \tcode{i} in the range \range{first}{last} -for which \tcode{pred(*i)} is \tcode{true}. - -\pnum -\returns The end of the resulting range. +\returns +Let \tcode{X} be the return type. +Returns \tcode{X\{x, y\}}, +where \tcode{x} is a copy of the leftmost element with the smallest value and +\tcode{y} a copy of the rightmost element with the largest value +in the input range. \pnum -\complexity Exactly \tcode{last - first} applications of the corresponding predicate. +\complexity +At most $(3/2)\tcode{ranges::distance(r)}$ applications +of the corresponding predicate +and twice as many applications of the projection, if any. \pnum -\remarks Stable~(\ref{algorithm.stable}). +\remarks +An invocation may explicitly specify +an argument for the template parameter \tcode{T} +of the overloads in namespace \tcode{std}. \end{itemdescr} - -\indexlibrary{\idxcode{copy_backward}}% +\indexlibraryglobal{min_element}% \begin{itemdecl} -template - BidirectionalIterator2 - copy_backward(BidirectionalIterator1 first, - BidirectionalIterator1 last, - BidirectionalIterator2 result); +template + constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last); + +template + ForwardIterator min_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); + +template + constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last, + Compare comp); +template + ForwardIterator min_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, Compare comp); + +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr I ranges::min_element(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\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} \pnum -\effects -Copies elements in the range \range{first}{last} -into the -range \range{result - (last-first)}{result} -starting from -\tcode{last - 1} -and proceeding to \tcode{first}.\footnote{\tcode{copy_backward} -should be used instead of copy when \tcode{last} -is in -the range -\range{result - (last - first)}{result}.} -For each positive integer -\tcode{n <= (last - first)}, -performs -\tcode{*(result - n) = *(last - n)}. - -\pnum -\requires -\tcode{result} -shall not be in the range -\brange{first}{last}. +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. \pnum \returns -\tcode{result - (last - first)}. +The first iterator \tcode{i} in the range \range{first}{last} +such that for every iterator \tcode{j} in the range \range{first}{last}, +\begin{codeblock} +bool(invoke(comp, invoke(proj, *j), invoke(proj, *i))) +\end{codeblock} +is \tcode{false}. +Returns \tcode{last} if \tcode{first == last}. \pnum \complexity -Exactly -\tcode{last - first} -assignments. +Exactly $\max(\tcode{last - first - 1}, 0)$ comparisons and +twice as many projections. \end{itemdescr} -\rSec2[alg.move]{Move} - -\indexlibrary{move\tcode{move}}% +\indexlibraryglobal{max_element}% \begin{itemdecl} -template - OutputIterator move(InputIterator first, InputIterator last, - OutputIterator result); -\end{itemdecl} +template + constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last); +template + ForwardIterator max_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); +template + constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last, + Compare comp); +template + ForwardIterator max_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Compare comp); + +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr I ranges::max_element(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\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} \pnum -\effects -Moves elements in the range \range{first}{last} -into the range \range{result}{result + (last - first)} -starting from first and proceeding to last. -For each non-negative integer -\tcode{n < (last-first)}, -performs -\tcode{*(result + n)} \tcode{= std::move(*(first + n))}. +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameters by those names. \pnum \returns -\tcode{result + (last - first)}. - -\pnum -\requires -\tcode{result} -shall not be in the range -\range{first}{last}. +The first iterator \tcode{i} in the range \range{first}{last} +such that for every iterator \tcode{j} in the range \range{first}{last}, +\begin{codeblock} +bool(invoke(comp, invoke(proj, *i), invoke(proj, *j))) +\end{codeblock} +is \tcode{false}. +Returns \tcode{last} if \tcode{first == last}. \pnum \complexity -Exactly -\tcode{last - first} -move assignments. +Exactly $\max(\tcode{last - first - 1}, 0)$ comparisons and +twice as many projections. \end{itemdescr} -\indexlibrary{\idxcode{move_backward}}% +\indexlibraryglobal{minmax_element}% \begin{itemdecl} -template - BidirectionalIterator2 - move_backward(BidirectionalIterator1 first, - BidirectionalIterator1 last, - BidirectionalIterator2 result); +template + constexpr pair + minmax_element(ForwardIterator first, ForwardIterator last); +template + pair + minmax_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); + +template + constexpr pair + minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); +template + pair + minmax_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, Compare comp); + +template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, + @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> + constexpr ranges::minmax_element_result + ranges::minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{forward_range}@ R, class Proj = identity, + @\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} \begin{itemdescr} -\pnum -\effects -Moves elements in the range \range{first}{last} -into the -range \range{result - (last-first)}{result} -starting from -\tcode{last - 1} -and proceeding to first.\footnote{\tcode{move_backward} -should be used instead of move when last -is in -the range -\range{result - (last - first)}{result}.} -For each positive integer -\tcode{n <= (last - first)}, -performs -\tcode{*(result - n) = std::move(*(last - n))}. - -\pnum -\requires -\tcode{result} -shall not be in the range -\brange{first}{last}. - \pnum \returns -\tcode{result - (last - first)}. +\tcode{\{first, first\}} if \range{first}{last} is empty, otherwise +\tcode{\{m, M\}}, where \tcode{m} is +the first iterator in \range{first}{last} such that no iterator in the range refers +to a smaller element, and where \tcode{M} is the last iterator +\begin{footnote} +This behavior +intentionally differs from \tcode{max_element}. +\end{footnote} +in \range{first}{last} such that no iterator in the range refers to a larger element. \pnum \complexity -Exactly -\tcode{last - first} -assignments. +Let $N$ be \tcode{last - first}. +At most $\max(\bigl\lfloor{\frac{3}{2}} (N-1)\bigr\rfloor, 0)$ comparisons and +twice as many applications of the projection, if any. \end{itemdescr} -\rSec2[alg.swap]{swap} +\rSec2[alg.clamp]{Bounded value} -\indexlibrary{\idxcode{swap_ranges}}% +\indexlibraryglobal{clamp}% \begin{itemdecl} -template - ForwardIterator2 - swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); +template + constexpr const T& clamp(const T& v, const T& lo, const T& hi); +template + constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp); +template> Comp = ranges::less> + constexpr const T& + ranges::clamp(const T& v, const T& lo, const T& hi, Comp comp = {}, Proj proj = {}); \end{itemdecl} - \begin{itemdescr} \pnum -\effects -For each non-negative integer -\tcode{n < (last1 - first1)} -performs: -\tcode{swap(*(first1 + n), \brk{}*(first2 + n))}. +Let \tcode{comp} be \tcode{less\{\}} +for the overloads with no parameter \tcode{comp}, +and let \tcode{proj} be \tcode{identity\{\}} +for the overloads with no parameter \tcode{proj}. \pnum -\requires -The two ranges \range{first1}{last1} -and -\range{first2}{first2 + (last1 - first1)} -shall not overlap. -\tcode{*(first1 + n)} shall be swappable with~(\ref{swappable.requirements}) -\tcode{*(first2 + n)}. +\expects +\tcode{bool(invoke(comp, invoke(proj, hi), invoke(proj, lo)))} is \tcode{false}. +For the first form, type \tcode{T} +meets the \oldconcept{LessThan\-Comparable} +requirements (\tref{cpp17.lessthancomparable}). \pnum \returns -\tcode{first2 + (last1 - first1)}. - -\pnum -\complexity -Exactly -\tcode{last1 - first1} -swaps. -\end{itemdescr} - -\indexlibrary{\idxcode{iter_swap}}% -\begin{itemdecl} -template - void iter_swap(ForwardIterator1 a, ForwardIterator2 b); -\end{itemdecl} - +\tcode{lo} if \tcode{bool(invoke(comp, invoke(proj, v), invoke(proj, lo)))} is \tcode{true}, +\tcode{hi} if \tcode{bool(\brk{}invoke(comp, invoke(proj, hi), invoke(proj, v)))} is \tcode{true}, +otherwise \tcode{v}. -\begin{itemdescr} \pnum -\effects -\tcode{swap(*a, *b)}. +\begin{note} +If NaN is avoided, \tcode{T} can be a floating-point type. +\end{note} \pnum -\requires -\tcode{a} and \tcode{b} shall be dereferenceable. \tcode{*a} shall be -swappable with~(\ref{swappable.requirements}) \tcode{*b}. +\complexity +At most two comparisons and three applications of the projection. \end{itemdescr} -\rSec2[alg.transform]{Transform} +\rSec2[alg.lex.comparison]{Lexicographical comparison} -\indexlibrary{\idxcode{transform}}% +\indexlibraryglobal{lexicographical_compare}% \begin{itemdecl} -template - OutputIterator - transform(InputIterator first, InputIterator last, - OutputIterator result, UnaryOperation op); +template + constexpr bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); +template + bool + lexicographical_compare(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); -template - OutputIterator - transform(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, OutputIterator result, - BinaryOperation binary_op); +template + constexpr bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp); +template + bool + lexicographical_compare(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + Compare comp); + +template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, + class Proj1 = identity, class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, + projected> Comp = ranges::less> + constexpr bool + ranges::lexicographical_compare(I1 first1, S1 last1, I2 first2, S2 last2, + Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Proj1 = identity, + class Proj2 = identity, + @\libconcept{indirect_strict_weak_order}@, Proj1>, + projected, Proj2>> Comp = ranges::less> + 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} \pnum -\effects -Assigns through every iterator -\tcode{i} -in the range -\range{result}{result + (last1 - first1)} -a new -corresponding value equal to -\tcode{op(*(first1 + (i - result))} -or -\tcode{binary_op(*(first1 + (i - result)), *(first2 + (i - result)))}. +\returns +\tcode{true} if and only if +the sequence of elements defined by the range \range{first1}{last1} +is lexicographically less than +the sequence of elements defined by the range \range{first2}{last2}. \pnum -\requires -\tcode{op} and \tcode{binary_op} -shall not invalidate iterators or subranges, or modify elements in the ranges -\crange{first1}{last1}, -\crange{first2}{first2 + (last1 - first1)}, -and -\crange{result} -{result + (last1 - first1)}.\footnote{The use of fully -closed ranges is intentional.} +\complexity +At most $2 \min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ applications +of the corresponding comparison and each projection, if any. \pnum -\returns -\tcode{result + (last1 - first1)}. +\remarks +If two sequences have the same number of elements and +their corresponding elements (if any) are equivalent, +then neither sequence is lexicographically less than the other. +If one sequence is a proper prefix of the other, +then the shorter sequence is lexicographically less than the longer sequence. +Otherwise, the lexicographical comparison of the sequences yields +the same result as the comparison +of the first corresponding pair of elements that are not equivalent. \pnum -\complexity -Exactly -\tcode{last1 - first1} -applications of -\tcode{op} or \tcode{binary_op}. +\begin{example} +\tcode{ranges::lexicographical_compare(I1, S1, I2, S2, Comp, Proj1, Proj2)} +can be implemented as: +\begin{codeblock} +for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) { + if (invoke(comp, invoke(proj1, *first1), invoke(proj2, *first2))) return true; + if (invoke(comp, invoke(proj2, *first2), invoke(proj1, *first1))) return false; +} +return first1 == last1 && first2 != last2; +\end{codeblock} +\end{example} \pnum -\notes -\tcode{result} may be equal to \tcode{first} -in case of unary transform, -or to \tcode{first1} or \tcode{first2} -in case of binary transform. +\begin{note} +An empty sequence is lexicographically less than any non-empty sequence, +but not less than any empty sequence. +\end{note} \end{itemdescr} -\rSec2[alg.replace]{Replace} +\rSec2[alg.three.way]{Three-way comparison algorithms} -\indexlibrary{\idxcode{replace}}% -\indexlibrary{\idxcode{replace_if}}% +\indexlibraryglobal{lexicographical_compare_three_way}% \begin{itemdecl} -template - void replace(ForwardIterator first, ForwardIterator last, - const T& old_value, const T& new_value); - -template - void replace_if(ForwardIterator first, ForwardIterator last, - Predicate pred, const T& new_value); +template + constexpr auto + lexicographical_compare_three_way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2, + Cmp comp) + -> decltype(comp(*b1, *b2)); \end{itemdecl} \begin{itemdescr} \pnum -\requires -The expression -\tcode{*first = new_value} -shall be valid. +Let $N$ be $\min(\tcode{e1 - b1}, \tcode{e2 - b2})$. +Let $E(n)$ be \tcode{comp(*(b1 + $n$), *(b2 + $n$))}. \pnum -\effects -Substitutes elements referred by the iterator -\tcode{i} -in the range \range{first}{last} -with \tcode{new_value}, -when the following corresponding conditions hold: -\tcode{*i == old_value}, \tcode{pred(*i) != false}. +\mandates +\tcode{decltype(comp(*b1, *b2))} is a comparison category type. + +\pnum +\returns +$E(i)$, where $i$ is the smallest integer in \range{0}{$N$} +such that \tcode{$E(i)$ != 0} is \tcode{true}, or +\tcode{(e1 - b1) <=> (e2 - b2)} if no such integer exists. \pnum \complexity -Exactly -\tcode{last - first} -applications of the corresponding predicate. +At most $N$ applications of \tcode{comp}. \end{itemdescr} -\indexlibrary{\idxcode{replace_copy}}% -\indexlibrary{\idxcode{replace_copy_if}}% +\indexlibraryglobal{lexicographical_compare_three_way}% \begin{itemdecl} -template - OutputIterator - replace_copy(InputIterator first, InputIterator last, - OutputIterator result, - const T& old_value, const T& new_value); - -template - OutputIterator - replace_copy_if(InputIterator first, InputIterator last, - OutputIterator result, - Predicate pred, const T& new_value); +template + constexpr auto + lexicographical_compare_three_way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2); \end{itemdecl} \begin{itemdescr} -\pnum -\requires -The results of the expressions -\tcode{*first} -and -\tcode{new_value} -shall be writable to the -\tcode{result} -output iterator. -The ranges -\range{first}{last} -and -\range{result}{result + (last - first)} -shall not overlap. - \pnum \effects -Assigns to every iterator -\tcode{i} -in the -range -\range{result}{result + (last - first)} -either -\tcode{new_value} -or -\tcode{*\brk(first + (i - result))} -depending on whether the following corresponding conditions hold: - +Equivalent to: \begin{codeblock} -*(first + (i - result)) == old_value -pred(*(first + (i - result))) != false +return lexicographical_compare_three_way(b1, e1, b2, e2, compare_three_way()); \end{codeblock} - -\pnum -\returns -\tcode{result + (last - first)}. - -\pnum -\complexity -Exactly -\tcode{last - first} -applications of the corresponding predicate. \end{itemdescr} -\rSec2[alg.fill]{Fill} +\rSec2[alg.permutation.generators]{Permutation generators} -\indexlibrary{\idxcode{fill}}% -\indexlibrary{\idxcode{fill_n}}% +\indexlibraryglobal{next_permutation}% \begin{itemdecl} -template - void fill(ForwardIterator first, ForwardIterator last, const T& value); +template + constexpr bool next_permutation(BidirectionalIterator first, + BidirectionalIterator last); -template - OutputIterator fill_n(OutputIterator first, Size n, const T& value); +template + constexpr bool next_permutation(BidirectionalIterator first, + BidirectionalIterator last, Compare comp); + +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr ranges::next_permutation_result + ranges::next_permutation(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{bidirectional_range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr ranges::next_permutation_result> + ranges::next_permutation(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum -\requires -The expression -\tcode{value} -shall be writable to the output iterator. The type -\tcode{Size} -shall be convertible to an integral type~(\ref{conv.integral}, \ref{class.conv}). +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + +\pnum +\expects +For the overloads in namespace \tcode{std}, +\tcode{BidirectionalIterator} meets +the \oldconcept{Value\-Swappable} requirements\iref{swappable.requirements}. \pnum \effects -The first algorithm assigns \tcode{value} through all the iterators in the range -\range{first}{last}. The second algorithm assigns \tcode{value} -through all the iterators in the range \range{first}{first + n} -if \tcode{n} is positive, otherwise it does nothing. +Takes a sequence defined by the range \range{first}{last} +and transforms it into the next permutation. +The next permutation is found by assuming that the set of all permutations +is lexicographically sorted with respect to \tcode{comp} and \tcode{proj}. +If no such permutation exists, +transforms the sequence into the first permutation; +that is, the ascendingly-sorted one. \pnum -\returns \tcode{fill_n} returns \tcode{first + n} for non-negative values of \tcode{n} -and \tcode{first} for negative values. +\returns +Let \tcode{B} be \tcode{true} if a next permutation was found and +otherwise \tcode{false}. +Returns: +\begin{itemize} +\item \tcode{B} for the overloads in namespace \tcode{std}. +\item \tcode{\{ last, B \}} for the overloads in namespace \tcode{ranges}. +\end{itemize} \pnum \complexity -Exactly -\tcode{last - first}, -\tcode{n}, or 0 assignments, respectively. +At most \tcode{(last - first) / 2} swaps. \end{itemdescr} -\rSec2[alg.generate]{Generate} - -\indexlibrary{\idxcode{generate}}% -\indexlibrary{\idxcode{generate_n}}% +\indexlibraryglobal{prev_permutation}% \begin{itemdecl} -template - void generate(ForwardIterator first, ForwardIterator last, - Generator gen); +template + constexpr bool prev_permutation(BidirectionalIterator first, + BidirectionalIterator last); -template - OutputIterator generate_n(OutputIterator first, Size n, Generator gen); +template + constexpr bool prev_permutation(BidirectionalIterator first, + BidirectionalIterator last, Compare comp); + +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@ S, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@ + constexpr ranges::prev_permutation_result + ranges::prev_permutation(I first, S last, Comp comp = {}, Proj proj = {}); +template<@\libconcept{bidirectional_range}@ R, class Comp = ranges::less, + class Proj = identity> + requires @\libconcept{sortable}@, Comp, Proj> + constexpr ranges::prev_permutation_result> + ranges::prev_permutation(R&& r, Comp comp = {}, Proj proj = {}); \end{itemdecl} \begin{itemdescr} \pnum -\effects -The first algorithm invokes the function object \tcode{gen} and assigns the return -value of \tcode{gen} through all the iterators in the range -\range{first}{last}. The second algorithm invokes the function object -\tcode{gen} and assigns the return value of \tcode{gen} through all the iterators in -the range \range{first}{first + n} if \tcode{n} is positive, -otherwise it does nothing. +Let \tcode{comp} be \tcode{less\{\}} +and \tcode{proj} be \tcode{identity\{\}} +for overloads with no parameters by those names. + +\pnum +\expects +For the overloads in namespace \tcode{std}, +\tcode{BidirectionalIterator} meets +the \oldconcept{Value\-Swappable} requirements\iref{swappable.requirements}. \pnum -\requires -\tcode{gen} takes no arguments, -\tcode{Size} -shall be convertible to an integral type~(\ref{conv.integral}, \ref{class.conv}). +\effects +Takes a sequence defined by the range \range{first}{last} +and transforms it into the previous permutation. +The previous permutation is found by assuming that the set of all permutations +is lexicographically sorted with respect to \tcode{comp} and \tcode{proj}. +If no such permutation exists, +transforms the sequence into the last permutation; +that is, the descendingly-sorted one. \pnum -\returns \tcode{generate_n} returns \tcode{first + n} for non-negative values of \tcode{n} -and \tcode{first} for negative values. +\returns +Let \tcode{B} be \tcode{true} if a previous permutation was found and +otherwise \tcode{false}. +Returns: +\begin{itemize} +\item \tcode{B} for the overloads in namespace \tcode{std}. +\item \tcode{\{ last, B \}} for the overloads in namespace \tcode{ranges}. +\end{itemize} \pnum \complexity -Exactly -\tcode{last - first}, -\tcode{n}, or 0 -invocations of \tcode{gen} and assignments, respectively. +At most \tcode{(last - first) / 2} swaps. \end{itemdescr} -\rSec2[alg.remove]{Remove} +\rSec1[numeric.ops.overview]{Header \tcode{} synopsis} -\indexlibrary{\idxcode{remove}}% -\indexlibrary{\idxcode{remove_if}}% -\begin{itemdecl} -template - ForwardIterator remove(ForwardIterator first, ForwardIterator last, - const T& value); +\indexheader{numeric}% +\begin{codeblock} +// mostly freestanding +namespace std { + // \ref{accumulate}, accumulate + template + constexpr T accumulate(InputIterator first, InputIterator last, T init); + template + constexpr T accumulate(InputIterator first, InputIterator last, T init, + BinaryOperation binary_op); + + // \ref{reduce}, reduce + template + constexpr typename iterator_traits::value_type + reduce(InputIterator first, InputIterator last); + template + constexpr T reduce(InputIterator first, InputIterator last, T init); + template + constexpr T reduce(InputIterator first, InputIterator last, T init, + BinaryOperation binary_op); + template + typename iterator_traits::value_type + reduce(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + T reduce(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, T init); + template + 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 + template + constexpr T inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init); + template + constexpr T inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, + BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); + + // \ref{transform.reduce}, transform reduce + template + constexpr T transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init); + template + constexpr T transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, + BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); + template + constexpr T transform_reduce(InputIterator first, InputIterator last, T init, + BinaryOperation binary_op, UnaryOperation unary_op); + template + 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, // 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, T init, + BinaryOperation binary_op, UnaryOperation unary_op); + + // \ref{partial.sum}, partial sum + template + constexpr OutputIterator + partial_sum(InputIterator first, InputIterator last, + OutputIterator result); + template + constexpr OutputIterator + partial_sum(InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation binary_op); + + // \ref{exclusive.scan}, exclusive scan + template + constexpr OutputIterator + exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, T init); + template + constexpr OutputIterator + exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, T init, BinaryOperation binary_op); + template + ForwardIterator2 + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, T init, BinaryOperation binary_op); + + // \ref{inclusive.scan}, inclusive scan + template + constexpr OutputIterator + inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result); + template + constexpr OutputIterator + inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation binary_op); + template + constexpr OutputIterator + inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation binary_op, T init); + template + ForwardIterator2 + inclusive_scan(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + template + ForwardIterator2 + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryOperation binary_op, T init); + + // \ref{transform.exclusive.scan}, transform exclusive scan + template + constexpr OutputIterator + transform_exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, T init, + BinaryOperation binary_op, UnaryOperation unary_op); + template + ForwardIterator2 + 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); + + // \ref{transform.inclusive.scan}, transform inclusive scan + template + constexpr OutputIterator + transform_inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + BinaryOperation binary_op, UnaryOperation unary_op); + template + constexpr OutputIterator + transform_inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + BinaryOperation binary_op, UnaryOperation unary_op, T init); + template + ForwardIterator2 + 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, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op, UnaryOperation unary_op, T init); + + // \ref{adjacent.difference}, adjacent difference + template + constexpr OutputIterator + adjacent_difference(InputIterator first, InputIterator last, + OutputIterator result); + template + constexpr OutputIterator + adjacent_difference(InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation binary_op); + template + ForwardIterator2 + adjacent_difference(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + template + ForwardIterator2 + adjacent_difference(ExecutionPolicy&& exec, // freestanding-deleted, see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryOperation binary_op); + + // \ref{numeric.iota}, iota + template + constexpr void iota(ForwardIterator first, ForwardIterator last, T value); -template - ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, - Predicate pred); -\end{itemdecl} + namespace ranges { + template + using @\libglobal{iota_result}@ = out_value_result; -\begin{itemdescr} -\pnum -\requires -The type of -\tcode{*first} -shall satisfy the \tcode{MoveAssignable} -requirements (Table~\ref{moveassignable}). + template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ T> + requires @\libconcept{indirectly_writable}@ + constexpr iota_result iota(O first, S last, T value); -\pnum -\effects -Eliminates all the elements referred to by iterator -\tcode{i} -in the range \range{first}{last} -for which the following corresponding conditions hold: -\tcode{*i == value, pred(*i) != false}. + template<@\libconcept{weakly_incrementable}@ T, @\libconcept{output_range}@ R> + constexpr iota_result, T> iota(R&& r, T value); + } -\pnum -\returns -The end of the resulting range. + // \ref{numeric.ops.gcd}, greatest common divisor + template + constexpr common_type_t gcd(M m, N n); + + // \ref{numeric.ops.lcm}, least common multiple + template + constexpr common_type_t lcm(M m, N n); + + // \ref{numeric.ops.midpoint}, midpoint + template + constexpr T midpoint(T a, T b) noexcept; + template + constexpr T* midpoint(T* a, T* b); + + // \ref{numeric.sat}, saturation arithmetic + template + constexpr T saturating_add(T x, T y) noexcept; + template + constexpr T saturating_sub(T x, T y) noexcept; + template + constexpr T saturating_mul(T x, T y) noexcept; + template + constexpr T saturating_div(T x, T y) noexcept; + template + constexpr T saturating_cast(U x) noexcept; +} +\end{codeblock} + +\rSec1[numeric.ops]{Generalized numeric operations} + +\rSec2[numeric.ops.general]{General} \pnum -\remarks Stable~(\ref{algorithm.stable}). +\begin{note} +The use of closed ranges as well as semi-open ranges +to specify requirements throughout \ref{numeric.ops} is intentional. +\end{note} + +\rSec2[numerics.defns]{Definitions} +\indexlibrary{generalized_noncommutative_sum@\tcode{\placeholder{GENERALIZED_NONCOMMUTATIVE_SUM}}}% \pnum -\complexity -Exactly -\tcode{last - first} -applications of the corresponding predicate. +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, $\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 -\realnote each element in the range \range{ret}{last}, where \tcode{ret} is -the returned value, has a valid but unspecified state, because the algorithms -can eliminate elements by moving from elements that were originally -in that range. -\end{itemdescr} +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}. -\indexlibrary{\idxcode{remove_copy}}% -\indexlibrary{\idxcode{remove_copy_if}}% -\begin{itemdecl} -template - OutputIterator - remove_copy(InputIterator first, InputIterator last, - OutputIterator result, const T& value); +\rSec2[accumulate]{Accumulate} -template - OutputIterator - remove_copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); +\indexlibraryglobal{accumulate}% +\begin{itemdecl} +template + constexpr T accumulate(InputIterator first, InputIterator last, T init); +template + constexpr T accumulate(InputIterator first, InputIterator last, T init, + BinaryOperation binary_op); \end{itemdecl} \begin{itemdescr} \pnum -\requires -The ranges -\range{first}{last} -and -\range{result}{result + (last - first)} -shall not overlap. The expression \tcode{*result = *first} shall be valid. +\expects +\tcode{T} meets +the \oldconcept{CopyConstructible} (\tref{cpp17.copyconstructible}) +and \oldconcept{CopyAssignable} (\tref{cpp17.copyassignable}) requirements. +In the range \crange{first}{last}, +\tcode{binary_op} neither modifies elements +nor invalidates iterators or subranges. +\begin{footnote} +The use of fully closed ranges is intentional. +\end{footnote} \pnum \effects -Copies all the elements referred to by the iterator -\tcode{i} -in the range -\range{first}{last} -for which the following corresponding conditions do not hold: -\tcode{*i == value, pred(*i) != false}. +Computes its result by +initializing the accumulator \tcode{acc} with the initial value \tcode{init} +and then modifies it with +\tcode{acc = std::move(acc) + *i} or +\tcode{acc = binary_op(std::move(acc), *i)} +for every iterator \tcode{i} in the range \range{first}{last} in order. +\begin{footnote} +\tcode{accumulate} is similar +to the APL reduction operator and Common Lisp reduce function, +but it avoids the difficulty of defining the result of reduction +on an empty sequence by always requiring an initial value. +\end{footnote} +\end{itemdescr} -\pnum -\returns -The end of the resulting range. +\rSec2[reduce]{Reduce} -\pnum -\complexity -Exactly -\tcode{last - first} -applications of the corresponding predicate. +\indexlibraryglobal{reduce}% +\begin{itemdecl} +template + constexpr typename iterator_traits::value_type + reduce(InputIterator first, InputIterator last); +\end{itemdecl} +\begin{itemdescr} \pnum -\remarks Stable~(\ref{algorithm.stable}). +\effects +Equivalent to: +\begin{codeblock} +return reduce(first, last, + typename iterator_traits::value_type{}); +\end{codeblock} \end{itemdescr} -\rSec2[alg.unique]{Unique} - -\indexlibrary{\idxcode{unique}}% +\indexlibraryglobal{reduce}% \begin{itemdecl} -template - ForwardIterator unique(ForwardIterator first, ForwardIterator last); - -template - ForwardIterator unique(ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); +template + typename iterator_traits::value_type + reduce(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); \end{itemdecl} \begin{itemdescr} \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 the following conditions hold: -\tcode{*(i - 1) == *i} -or -\tcode{pred(*(i - 1), *i) != false}. +Equivalent to: +\begin{codeblock} +return reduce(std::forward(exec), first, last, + typename iterator_traits::value_type{}); +\end{codeblock} +\end{itemdescr} -\pnum -\requires -The comparison function shall be an equivalence relation. -The type of \tcode{*first} shall satisfy the -\tcode{MoveAssignable} requirements (Table~\ref{moveassignable}). -\pnum -\returns -The end of the resulting range. +\indexlibraryglobal{reduce}% +\begin{itemdecl} +template + constexpr T reduce(InputIterator first, InputIterator last, T init); +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -For nonempty ranges, exactly -\tcode{(last - first) - 1} -applications of the corresponding predicate. +\effects +Equivalent to: +\begin{codeblock} +return reduce(first, last, init, plus<>()); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{unique_copy}}% +\indexlibraryglobal{reduce}% \begin{itemdecl} -template - OutputIterator - unique_copy(InputIterator first, InputIterator last, - OutputIterator result); - -template - OutputIterator - unique_copy(InputIterator first, InputIterator last, - OutputIterator result, BinaryPredicate pred); +template + T reduce(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, T init); \end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return reduce(std::forward(exec), first, last, init, plus<>()); +\end{codeblock} +\end{itemdescr} + + +\indexlibraryglobal{reduce}% +\begin{itemdecl} +template + constexpr T reduce(InputIterator first, InputIterator last, T init, + BinaryOperation binary_op); +template + T reduce(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, T init, + BinaryOperation binary_op); +\end{itemdecl} \begin{itemdescr} + \pnum -\requires -The comparison function shall be an equivalence relation. -The ranges -\range{first}{last} -and -\range{result}{result+(last-first)} -shall not overlap. The expression -\tcode{*result = *first} -shall be valid. If neither -\tcode{InputIterator} -nor -\tcode{OutputIterator} -meets the requirements of forward iterator then the value type of -\tcode{InputIterator} -shall be \tcode{CopyConstructible} (Table~\ref{copyconstructible}) and -\tcode{CopyAssignable} (Table~\ref{copyassignable}). -Otherwise \tcode{CopyConstructible} is not required. +\mandates +All of +\begin{itemize} +\item \tcode{binary_op(init, *first)}, +\item \tcode{binary_op(*first, init)}, +\item \tcode{binary_op(init, init)}, and +\item \tcode{binary_op(*first, *first)} +\end{itemize} +are convertible to \tcode{T}. \pnum -\effects -Copies only the first element from every consecutive group of equal elements referred to by -the iterator -\tcode{i} -in the range -\range{first}{last} -for which the following corresponding conditions hold: -\tcode{*i == *(i - 1)} -or -\tcode{pred(*i, *(i - 1)) != false}. +\expects +\begin{itemize} +\item + \tcode{T} meets the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) requirements. +\item + \tcode{binary_op} neither invalidates iterators or subranges, + nor modifies elements in the range \crange{first}{last}. +\end{itemize} \pnum \returns -The end of the resulting range. +\tcode{\placeholdernc{GENERALIZED_SUM}(binary_op, init, *i, $\dotsc$)} +for every \tcode{i} in \range{first}{last}. \pnum \complexity -For nonempty ranges, exactly -\tcode{last - first - 1} -applications of the corresponding predicate. +\bigoh{\tcode{last - first}} applications of \tcode{binary_op}. + +\pnum +\begin{note} +The difference between \tcode{reduce} and \tcode{accumulate} is that +\tcode{reduce} applies \tcode{binary_op} in an unspecified order, +which yields a nondeterministic result +for non-associative or non-commutative \tcode{binary_op} +such as floating-point addition. +\end{note} \end{itemdescr} -\rSec2[alg.reverse]{Reverse} +\rSec2[inner.product]{Inner product} -\indexlibrary{\idxcode{reverse}}% +\indexlibraryglobal{inner_product}% \begin{itemdecl} -template - void reverse(BidirectionalIterator first, BidirectionalIterator last); +template + constexpr T inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init); +template + constexpr T inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, + BinaryOperation1 binary_op1, + BinaryOperation2 binary_op2); \end{itemdecl} \begin{itemdescr} \pnum -\effects -For each non-negative integer -\tcode{i < (last - first)/2}, -applies -\tcode{iter_swap} -to all pairs of iterators -\tcode{first + i, (last - i) - 1}. - -\pnum -\requires -\tcode{*first} shall be swappable~(\ref{swappable.requirements}). +\expects +\tcode{T} meets +the \oldconcept{CopyConstructible} (\tref{cpp17.copyconstructible}) +and \oldconcept{CopyAssignable} (\tref{cpp17.copyassignable}) requirements. +In the ranges \crange{first1}{last1} and +\crange{first2}{first2 + (last1 - first1)} +\tcode{binary_op1} and \tcode{binary_op2} +neither modifies elements nor invalidates iterators or subranges. +\begin{footnote} +The use of fully closed ranges is intentional. +\end{footnote} \pnum -\complexity -Exactly -\tcode{(last - first)/2} -swaps. +\effects +Computes its result by +initializing the accumulator \tcode{acc} with the initial value \tcode{init} +and then modifying it with +\tcode{acc = std::move(acc) + (*i1) * (*i2)} or +\tcode{acc = binary_op1(std::move(acc), binary_op2(*i1, *i2))} +for every iterator \tcode{i1} in the range \range{first1}{last1} +and iterator \tcode{i2} in the range \range{first2}{first2 + (last1 - first1)} +in order. \end{itemdescr} -\indexlibrary{\idxcode{reverse_copy}}% +\rSec2[transform.reduce]{Transform reduce} +\indexlibraryglobal{transform_reduce}% \begin{itemdecl} -template - OutputIterator - reverse_copy(BidirectionalIterator first, - BidirectionalIterator last, OutputIterator result); +template + constexpr T transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, + T init); \end{itemdecl} \begin{itemdescr} \pnum \effects -Copies the range -\range{first}{last} -to the range -\range{result}{result+(last-first)} -such that -for every non-negative integer -\tcode{i < (last - first)} -the following assignment takes place: -\tcode{*(result + (last - first) - 1 - i) = *(first + i)}. - -\pnum -\requires -The ranges -\range{first}{last} -and -\range{result}{result+(last-first)} -shall not overlap. - -\pnum -\returns -\tcode{result + (last - first)}. - -\pnum -\complexity -Exactly -\tcode{last - first} -assignments. +Equivalent to: +\begin{codeblock} +return transform_reduce(first1, last1, first2, init, plus<>(), multiplies<>()); +\end{codeblock} \end{itemdescr} -\rSec2[alg.rotate]{Rotate} - -\indexlibrary{\idxcode{rotate}}% +\indexlibraryglobal{transform_reduce}% \begin{itemdecl} -template - ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, - ForwardIterator last); +template + T transform_reduce(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, + T init); \end{itemdecl} \begin{itemdescr} \pnum \effects -For each non-negative integer -\tcode{i < (last - first)}, -places the element from the position -\tcode{first + i} -into position -\tcode{first + (i + (last - middle)) \% (last - first)}. +Equivalent to: +\begin{codeblock} +return transform_reduce(std::forward(exec), + first1, last1, first2, init, plus<>(), multiplies<>()); +\end{codeblock} +\end{itemdescr} -\pnum -\returns \tcode{first + (last - middle)}. +\indexlibraryglobal{transform_reduce}% +\begin{itemdecl} +template + constexpr T transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, + T init, + BinaryOperation1 binary_op1, + BinaryOperation2 binary_op2); +template + T transform_reduce(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, + T init, + BinaryOperation1 binary_op1, + BinaryOperation2 binary_op2); +\end{itemdecl} +\begin{itemdescr} \pnum -\notes -This is a left rotate. +\mandates +All of + \begin{itemize} + \item \tcode{binary_op1(init, init)}, + \item \tcode{binary_op1(init, binary_op2(*first1, *first2))}, + \item \tcode{binary_op1(binary_op2(*first1, *first2), init)}, and + \item \tcode{binary_op1(binary_op2(*first1, *first2), binary_op2(*first1, *first2))} + \end{itemize} + are convertible to \tcode{T}. \pnum -\requires -\range{first}{middle} -and -\range{middle}{last} -shall be valid ranges. -\tcode{ForwardIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). The type of \tcode{*first} shall satisfy -the requirements of \tcode{MoveConstructible} -(Table~\ref{moveconstructible}) and the -requirements of -\tcode{MoveAssignable} -(Table~\ref{moveassignable}). +\expects +\begin{itemize} +\item + \tcode{T} meets the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) requirements. +\item + Neither \tcode{binary_op1} nor \tcode{binary_op2} + invalidates subranges, nor modifies elements in the ranges + \crange{first1}{last1} and \crange{first2}{first2 + (last1 - first1)}. +\end{itemize} +\pnum +\returns +\begin{codeblock} +@\placeholdernc{GENERALIZED_SUM}@(binary_op1, init, binary_op2(*i, *(first2 + (i - first1))), @$\dotsc$@) +\end{codeblock} +for every iterator \tcode{i} in \range{first1}{last1}. \pnum \complexity -At most -\tcode{last - first} -swaps. +\bigoh{\tcode{last1 - first1}} applications each +of \tcode{binary_op1} and \tcode{binary_op2}. \end{itemdescr} -\indexlibrary{\idxcode{rotate_copy}}% +\indexlibraryglobal{transform_reduce}% \begin{itemdecl} -template - OutputIterator - rotate_copy(ForwardIterator first, ForwardIterator middle, - ForwardIterator last, OutputIterator result); +template + constexpr T transform_reduce(InputIterator first, InputIterator last, T init, + BinaryOperation binary_op, UnaryOperation unary_op); +template + T transform_reduce(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + T init, BinaryOperation binary_op, UnaryOperation unary_op); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Copies the range -\range{first}{last} -to the range -\range{result}{result + (last - first)} -such that for each non-negative integer -\tcode{i < (last - first)} -the following assignment takes place: -\tcode{*(result + i) = *(first + -(i + (middle - first)) \% (last - first))}. +\mandates + All of + \begin{itemize} + \item \tcode{binary_op(init, init)}, + \item \tcode{binary_op(init, unary_op(*first))}, + \item \tcode{binary_op(unary_op(*first), init)}, and + \item \tcode{binary_op(unary_op(*first), unary_op(*first))} + \end{itemize} + are convertible to \tcode{T}. \pnum -\returns -\tcode{result + (last - first)}. +\expects +\begin{itemize} +\item + \tcode{T} meets the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) requirements. +\item + Neither \tcode{unary_op} nor \tcode{binary_op} invalidates subranges, + nor modifies elements in the range \crange{first}{last}. +\end{itemize} \pnum -\requires -The ranges -\range{first}{last} -and -\range{result}{result + (last - first)} -shall not overlap. +\returns +\begin{codeblock} +@\placeholdernc{GENERALIZED_SUM}@(binary_op, init, unary_op(*i), @$\dotsc$@) +\end{codeblock} +for every iterator \tcode{i} in \range{first}{last}. \pnum \complexity -Exactly -\tcode{last - first} -assignments. +\bigoh{\tcode{last - first}} applications each of \tcode{unary_op} and +\tcode{binary_op}. + +\pnum +\begin{note} +\tcode{transform_reduce} does not apply \tcode{unary_op} to \tcode{init}. +\end{note} \end{itemdescr} -\rSec2[alg.random.shuffle]{Shuffle} +\rSec2[partial.sum]{Partial sum} -\indexlibrary{\idxcode{shuffle}}% +\indexlibraryglobal{partial_sum}% \begin{itemdecl} -template - void shuffle(RandomAccessIterator first, - RandomAccessIterator last, - UniformRandomNumberGenerator&& g); +template + constexpr OutputIterator + partial_sum(InputIterator first, InputIterator last, + OutputIterator result); +template + constexpr OutputIterator + partial_sum(InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation binary_op); \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +\tcode{InputIterator}'s value type is constructible from \tcode{*first}. +The result of the +expression \tcode{std::move(acc) + *i} or \tcode{binary_op(std::move(acc), *i)} +is implicitly convertible to \tcode{InputIt\-er\-a\-tor}'s value type. +\tcode{acc} is writable\iref{iterator.requirements.general} to \tcode{result}. + +\pnum +\expects +In the ranges \crange{first}{last} and \crange{result}{result + (last - first)} +\tcode{binary_op} neither modifies elements +nor invalidates iterators or subranges. +\begin{footnote} +The use of fully closed ranges is intentional. +\end{footnote} + \pnum \effects -Permutes the elements in the range -\range{first}{last} -such that each possible permutation of those elements has equal probability of appearance. +For a non-empty range, +the function creates an accumulator \tcode{acc} +whose type is \tcode{InputIterator}'s value type, +initializes it with \tcode{*first}, +and assigns the result to \tcode{*result}. +For every iterator \tcode{i} in \range{first + 1}{last} in order, +\tcode{acc} is then modified by +\tcode{acc = std::move(acc) + *i} or \tcode{acc = binary_op(std::move(acc), *i)} +and the result is assigned to \tcode{*(result + (i - first))}. \pnum -\requires -\tcode{RandomAccessIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). -The type -\tcode{UniformRandomNumberGenerator} shall meet the requirements of a uniform -random number generator~(\ref{rand.req.urng}) type whose return type is -convertible to -\tcode{iterator_traits::difference_type}. +\returns +\tcode{result + (last - first)}. \pnum \complexity -Exactly -\tcode{(last - first) - 1} -swaps. +Exactly \tcode{(last - first) - 1} applications of the binary operation. \pnum -\notes -To the extent that the implementation of this function makes use of random -numbers, the object \tcode{g} shall serve as the implementation's source of -randomness. - +\remarks +\tcode{result} may be equal to \tcode{first}. \end{itemdescr} -\rSec2[alg.partitions]{Partitions} +\rSec2[exclusive.scan]{Exclusive scan} -\indexlibrary{\idxcode{is_partitioned}}% +\indexlibraryglobal{exclusive_scan}% \begin{itemdecl} -template - bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); +template + constexpr OutputIterator + exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, T init); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{InputIterator}'s value type shall be convertible to \tcode{Predicate}'s argument type. +\effects +Equivalent to: +\begin{codeblock} +return exclusive_scan(first, last, result, init, plus<>()); +\end{codeblock} +\end{itemdescr} -\pnum -\returns \tcode{true} if -\range{first}{last} is empty or if -\range{first}{last} is partitioned by \tcode{pred}, i.e. if all elements that satisfy \tcode{pred} appear before those that do not. +\indexlibraryglobal{exclusive_scan}% +\begin{itemdecl} +template + ForwardIterator2 + exclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, T init); +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity Linear. At most \tcode{last - first} applications of \tcode{pred}. +\effects +Equivalent to: +\begin{codeblock} +return exclusive_scan(std::forward(exec), + first, last, result, init, plus<>()); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{partition}}% +\indexlibraryglobal{exclusive_scan}% \begin{itemdecl} -template - ForwardIterator - partition(ForwardIterator first, - ForwardIterator last, Predicate pred); +template + constexpr OutputIterator + exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, T init, BinaryOperation binary_op); +template + ForwardIterator2 + exclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, T init, BinaryOperation binary_op); \end{itemdecl} \begin{itemdescr} \pnum -\effects Places all the elements in the range \range{first}{last} that satisfy \tcode{pred} before all the elements that do not satisfy it. - -\pnum -\returns An iterator \tcode{i} such that for every iterator \tcode{j} in the range -\range{first}{i} \tcode{pred(*j) != false}, and for every iterator \tcode{k} in the -range \range{i}{last}, \tcode{pred(*k) == false}. +\mandates + All of + \begin{itemize} + \item \tcode{binary_op(init, init)}, + \item \tcode{binary_op(init, *first)}, and + \item \tcode{binary_op(*first, *first)} + \end{itemize} + are convertible to \tcode{T}. -\pnum -\requires -\tcode{ForwardIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). \pnum -\complexity If ForwardIterator meets the requirements for a BidirectionalIterator, at most -\tcode{(last - first) / 2} swaps are done; otherwise at most \tcode{last - first} swaps -are done. Exactly \tcode{last - first} applications of the predicate are done. -\end{itemdescr} - -\indexlibrary{\idxcode{stable_partition}}% -\begin{itemdecl} -template - BidirectionalIterator - stable_partition(BidirectionalIterator first, - BidirectionalIterator last, Predicate pred); -\end{itemdecl} +\expects +\begin{itemize} +\item + \tcode{T} meets the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) requirements. +\item + \tcode{binary_op} neither invalidates iterators or subranges, + nor modifies elements in + the ranges \crange{first}{last} or \crange{result}{result + (last - first)}. +\end{itemize} -\begin{itemdescr} \pnum \effects -Places all the elements in the range -\range{first}{last} -that satisfy \tcode{pred} before all the -elements that do not satisfy it. +For each integer \tcode{K} in \range{0}{last - first} +assigns through \tcode{result + K} the value of: +\begin{codeblock} +@\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}@( + binary_op, init, *(first + 0), *(first + 1), @$\dotsc$@, *(first + K - 1)) +\end{codeblock} \pnum \returns -An iterator -\tcode{i} -such that for every iterator -\tcode{j} -in the range -\range{first}{i}, -\tcode{pred(*j) != false}, -and for every iterator -\tcode{k} -in the range -\range{i}{last}, -\tcode{pred(*k) == false}. -The relative order of the elements in both groups is preserved. +The end of the resulting range beginning at \tcode{result}. + +\pnum +\complexity +\bigoh{\tcode{last - first}} applications of \tcode{binary_op}. \pnum -\requires -\tcode{BidirectionalIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). The type -of \tcode{*first} shall satisfy the requirements of -\tcode{MoveConstructible} (Table~\ref{moveconstructible}) and of -\tcode{MoveAssignable} (Table~\ref{moveassignable}). +\remarks +\tcode{result} may be equal to \tcode{first}. \pnum -\complexity -At most -\tcode{(last - first) * log(last - first)} -swaps, but only linear number of swaps if there is enough extra memory. -Exactly -\tcode{last - first} -applications of the predicate. +\begin{note} +The difference between \tcode{exclusive_scan} and \tcode{inclusive_scan} is +that \tcode{exclusive_scan} excludes the $i^\text{th}$ input element +from the $i^\text{th}$ sum. +If \tcode{binary_op} is not mathematically associative, +the behavior of \tcode{exclusive_scan} can be nondeterministic. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{partition_copy}}% +\rSec2[inclusive.scan]{Inclusive scan} + +\indexlibraryglobal{inclusive_scan}% \begin{itemdecl} -template - pair - partition_copy(InputIterator first, InputIterator last, - OutputIterator1 out_true, OutputIterator2 out_false, - Predicate pred); +template + constexpr OutputIterator + inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result); \end{itemdecl} - \begin{itemdescr} \pnum -\requires \tcode{InputIterator}'s value type shall be \tcode{CopyAssignable}, and shall be -writable to the \tcode{out_true} and \tcode{out_false} \tcode{OutputIterator}s, and shall be -convertible to \tcode{Predicate}'s argument type. The input range shall not overlap with -either of the output ranges. - -\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{pred(*i)} is \tcode{true}, or to the output range beginning with \tcode{out_false} otherwise. - -\pnum -\returns A pair \tcode{p} such that \tcode{p.first} is the end of the output range beginning at \tcode{out_true} and \tcode{p.second} is the end of the output range beginning at \tcode{out_false}. - -\pnum -\complexity Exactly \tcode{last - first} applications of \tcode{pred}. +\effects +Equivalent to: +\begin{codeblock} +return inclusive_scan(first, last, result, plus<>()); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{partition_point}}% +\indexlibraryglobal{inclusive_scan}% \begin{itemdecl} -template - ForwardIterator partition_point(ForwardIterator first, - ForwardIterator last, - Predicate pred); +template + ForwardIterator2 + inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); \end{itemdecl} - \begin{itemdescr} \pnum -\requires \tcode{ForwardIterator}'s value type shall be convertible to \tcode{Predicate}'s argument type. \range{first}{last} shall be partitioned by \tcode{pred}, i.e. all elements that satisfy \tcode{pred} shall appear before those that do not. - -\pnum -\returns An iterator \tcode{mid} such that \tcode{all_of(first, mid, pred)} and \tcode{none_of(mid, last, pred)} are both true. - -\pnum -\complexity \bigoh{log(last - first)} applications of \tcode{pred}. +\effects +Equivalent to: +\begin{codeblock} +return inclusive_scan(std::forward(exec), first, last, result, plus<>()); +\end{codeblock} \end{itemdescr} +\indexlibraryglobal{inclusive_scan}% +\begin{itemdecl} +template + constexpr OutputIterator + inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation binary_op); +template + ForwardIterator2 + inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryOperation binary_op); + +template + constexpr OutputIterator + inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation binary_op, T init); +template + ForwardIterator2 + inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryOperation binary_op, T init); +\end{itemdecl} -\rSec1[alg.sorting]{Sorting and related operations} - +\begin{itemdescr} \pnum -All the operations in~\ref{alg.sorting} have two versions: one that takes a function object of type -\tcode{Compare} -and one that uses an -\tcode{operator<}. +Let \tcode{U} be the value type of \tcode{decltype(first)}. \pnum -\tcode{Compare} -is a function object -type~(\ref{function.objects}). The return value of the function call operation applied to -an object of type \tcode{Compare}, when contextually converted to -\tcode{bool} (Clause~\ref{conv}), -yields \tcode{true} if the first argument of the call -is less than the second, and -\tcode{false} -otherwise. -\tcode{Compare comp} -is used throughout for algorithms assuming an ordering relation. -It is assumed that -\tcode{comp} -will not apply any non-constant function through the dereferenced iterator. +\mandates +If \tcode{init} is provided, all of +\begin{itemize} +\item \tcode{binary_op(init, init)}, +\item \tcode{binary_op(init, *first)}, and +\item \tcode{binary_op(*first, *first)} +\end{itemize} +are convertible to \tcode{T}; +otherwise, \tcode{binary_op(*first, *first)} +is convertible to \tcode{U}. \pnum -For all algorithms that take -\tcode{Compare}, -there is a version that uses -\tcode{operator<} -instead. -That is, -\tcode{comp(*i, *j) != false} -defaults to -\tcode{*i < *j != false}. -For algorithms other than those described in~\ref{alg.binary.search} to work correctly, -\tcode{comp} has to induce a strict weak ordering on the values. - -\pnum -The term -\techterm{strict} -refers to the -requirement of an irreflexive relation (\tcode{!comp(x, x)} for all \tcode{x}), -and the term -\techterm{weak} -to requirements that are not as strong as -those for a total ordering, -but stronger than those for a partial -ordering. -If we define -\tcode{equiv(a, b)} -as -\tcode{!comp(a, b) \&\& !comp(b, a)}, -then the requirements are that -\tcode{comp} -and -\tcode{equiv} -both be transitive relations: - -\begin{itemize} -\item -\tcode{comp(a, b) \&\& comp(b, c)} -implies -\tcode{comp(a, c)} -\item -\tcode{equiv(a, b) \&\& equiv(b, c)} -implies -\tcode{equiv(a, c)} -\enternote -Under these conditions, it can be shown that +\expects \begin{itemize} \item -\tcode{equiv} -is an equivalence relation -\item -\tcode{comp} -induces a well-defined relation on the equivalence -classes determined by -\tcode{equiv} + If \tcode{init} is provided, + \tcode{T} meets the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) requirements; + otherwise, \tcode{U} + meets the \oldconcept{MoveConstructible} requirements. \item -The induced relation is a strict total ordering. -\exitnote -\end{itemize} + \tcode{binary_op} neither invalidates iterators or subranges, + nor modifies elements in + the ranges \crange{first}{last} or \crange{result}{result + (last - first)}. \end{itemize} \pnum -A sequence is -\techterm{sorted with respect to a comparator} -\tcode{comp} if for every iterator -\tcode{i} -pointing to the sequence and every non-negative integer -\tcode{n} -such that -\tcode{i + n} -is a valid iterator pointing to an element of the sequence, -\tcode{comp(*(i + n), *i) == false}. - -\pnum -A sequence -\range{start}{finish} -is -\techterm{partitioned with respect to an expression} -\tcode{f(e)} -if there exists an integer -\tcode{n} -such that for all -\tcode{0 <= i < distance(start, finish)}, -\tcode{f(*(start + i))} -is true if and only if -\tcode{i < n}. - -\pnum -In the descriptions of the functions that deal with ordering relationships we frequently use a notion of -equivalence to describe concepts such as stability. -The equivalence to which we refer is not necessarily an -\tcode{operator==}, -but an equivalence relation induced by the strict weak ordering. -That is, two elements -\tcode{a} -and -\tcode{b} -are considered equivalent if and only if -\tcode{!(a < b) \&\& !(b < a)}. - -\rSec2[alg.sort]{Sorting} - -\rSec3[sort]{\tcode{sort}} - -\indexlibrary{\idxcode{sort}}% -\begin{itemdecl} -template - void sort(RandomAccessIterator first, RandomAccessIterator last); +\effects +For each integer \tcode{K} in \range{0}{last - first} +assigns through \tcode{result + K} the value of +\begin{itemize} +\item + \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op, + 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), $\dotsc$, *(first + K))}\\otherwise. +\end{itemize} -template - void sort(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); -\end{itemdecl} +\pnum +\returns +The end of the resulting range beginning at \tcode{result}. -\begin{itemdescr} \pnum -\effects -Sorts the elements in the range -\range{first}{last}. +\complexity +\bigoh{\tcode{last - first}} applications of \tcode{binary_op}. \pnum -\requires -\tcode{RandomAccessIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). The type -of \tcode{*first} shall satisfy the requirements of -\tcode{MoveConstructible} (Table~\ref{moveconstructible}) and of -\tcode{MoveAssignable} (Table~\ref{moveassignable}). +\remarks +\tcode{result} may be equal to \tcode{first}. \pnum -\complexity -\bigoh{N\log(N)} -(where -\tcode{$N$ == last - first}) -comparisons. +\begin{note} +The difference between \tcode{exclusive_scan} and \tcode{inclusive_scan} is +that \tcode{inclusive_scan} includes the $i^\text{th}$ input element +in the $i^\text{th}$ sum. +If \tcode{binary_op} is not mathematically associative, +the behavior of \tcode{inclusive_scan} can be nondeterministic. +\end{note} \end{itemdescr} -\rSec3[stable.sort]{\tcode{stable_sort}} +\rSec2[transform.exclusive.scan]{Transform exclusive scan} -\indexlibrary{\idxcode{stable_sort}}% +\indexlibraryglobal{transform_exclusive_scan}% \begin{itemdecl} -template - void stable_sort(RandomAccessIterator first, RandomAccessIterator last); - -template - void stable_sort(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +template + constexpr OutputIterator + transform_exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, T init, + BinaryOperation binary_op, UnaryOperation unary_op); +template + ForwardIterator2 + transform_exclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, T init, + BinaryOperation binary_op, UnaryOperation unary_op); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Sorts the elements in the range \range{first}{last}. +\mandates + All of + \begin{itemize} + \item \tcode{binary_op(init, init)}, + \item \tcode{binary_op(init, unary_op(*first))}, and + \item \tcode{binary_op(unary_op(*first), unary_op(*first))} + \end{itemize} + are convertible to \tcode{T}. + +\pnum +\expects +\begin{itemize} +\item + \tcode{T} meets the \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) requirements. +\item + Neither \tcode{unary_op} nor \tcode{binary_op} + invalidates iterators or subranges, nor modifies elements in + the ranges \crange{first}{last} or \crange{result}{result + (last - first)}. +\end{itemize} \pnum -\requires -\tcode{RandomAccessIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). The type -of \tcode{*first} shall satisfy the requirements of -\tcode{MoveConstructible} (Table~\ref{moveconstructible}) and of -\tcode{MoveAssignable} (Table~\ref{moveassignable}). +\effects +For each integer \tcode{K} in \range{0}{last - first} +assigns through \tcode{result + K} the value of: +\begin{codeblock} +@\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}@( + binary_op, init, + unary_op(*(first + 0)), unary_op(*(first + 1)), @$\dotsc$@, unary_op(*(first + K - 1))) +\end{codeblock} +\pnum +\returns +The end of the resulting range beginning at \tcode{result}. \pnum \complexity -It does at most $N \log^2(N)$ -(where -\tcode{$N$ == last - first}) -comparisons; if enough extra memory is available, it is -$N \log(N)$. +\bigoh{\tcode{last - first}} applications each +of \tcode{unary_op} and \tcode{binary_op}. + +\pnum +\remarks +\tcode{result} may be equal to \tcode{first}. \pnum -\remarks Stable~(\ref{algorithm.stable}). +\begin{note} +The difference between \tcode{transform_exclusive_scan} and +\tcode{transform_inclusive_scan} is that \tcode{trans\-form\-_\-exclusive_scan} +excludes the $i^\text{th}$ input element from the $i^\text{th}$ sum. +If \tcode{binary_op} is not mathematically associative, +the behavior of \tcode{transform_exclusive_scan} can be nondeterministic. +\tcode{transform_exclusive_scan} +does not apply \tcode{unary_op} to \tcode{init}. +\end{note} \end{itemdescr} -\rSec3[partial.sort]{\tcode{partial_sort}} +\rSec2[transform.inclusive.scan]{Transform inclusive scan} -\indexlibrary{\idxcode{partial_sort}}% +\indexlibraryglobal{transform_inclusive_scan}% \begin{itemdecl} -template - void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last); - -template - void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last, - Compare comp); +template + constexpr OutputIterator + transform_inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + BinaryOperation binary_op, UnaryOperation unary_op); +template + ForwardIterator2 + transform_inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op, UnaryOperation unary_op); +template + constexpr OutputIterator + transform_inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + BinaryOperation binary_op, UnaryOperation unary_op, + T init); +template + ForwardIterator2 + transform_inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op, UnaryOperation unary_op, + T init); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Places the first -\tcode{middle - first} -sorted elements from the range -\range{first}{last} -into the range -\range{first}{middle}. -The rest of the elements in the range -\range{middle}{last} -are placed in an unspecified order. -\indextext{unspecified}% +Let \tcode{U} be the value type of \tcode{decltype(first)}. \pnum -\requires -\tcode{RandomAccessIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). The type -of \tcode{*first} shall satisfy the requirements of -\tcode{MoveConstructible} (Table~\ref{moveconstructible}) and of -\tcode{MoveAssignable} (Table~\ref{moveassignable}). - +\mandates +If \tcode{init} is provided, all of +\begin{itemize} +\item \tcode{binary_op(init, init)}, +\item \tcode{binary_op(init, unary_op(*first))}, and +\item \tcode{binary_op(unary_op(*first), unary_op(*first))} +\end{itemize} +are convertible to \tcode{T}; +otherwise, \tcode{binary_op(unary_op(*first), unary_op(*first))} +is convertible to \tcode{U}. \pnum -\complexity -It takes approximately -\tcode{(last - first) * log(middle - first)} -comparisons. -\end{itemdescr} - -\rSec3[partial.sort.copy]{\tcode{partial_sort_copy}} - -\indexlibrary{\idxcode{partial_sort_copy}}% -\begin{itemdecl} -template - RandomAccessIterator - partial_sort_copy(InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last); - -template - RandomAccessIterator - partial_sort_copy(InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last, - Compare comp); -\end{itemdecl} +\expects +\begin{itemize} +\item + If \tcode{init} is provided, \tcode{T} meets the + \oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) requirements; + otherwise, \tcode{U} meets the + \oldconcept{MoveConstructible} requirements. +\item + Neither \tcode{unary_op} nor \tcode{binary_op} invalidates + iterators or subranges, nor modifies elements in + the ranges \crange{first}{last} or \crange{result}{result + (last - first)}. +\end{itemize} -\begin{itemdescr} \pnum \effects -Places the first -\tcode{min(last - first, result_last - result_first)} -sorted elements into the range -\range{result_first}{result_first + min(last - first, result_last - result_first)}. +For each integer \tcode{K} in \range{0}{last - first} +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)), $\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)), $\dotsc$, unary_op(*(first + K)))}\\ + otherwise. +\end{itemize} \pnum \returns -The smaller of: -\tcode{result_last} or -\tcode{result_first + (last - first)}. +The end of the resulting range beginning at \tcode{result}. \pnum -\requires -\tcode{RandomAccessIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). The type -of \tcode{*result_first} shall satisfy the requirements of -\tcode{MoveConstructible} (Table~\ref{moveconstructible}) and of -\tcode{Move\-Assignable} (Table~\ref{moveassignable}). +\complexity +\bigoh{\tcode{last - first}} applications each +of \tcode{unary_op} and \tcode{binary_op}. +\pnum +\remarks +\tcode{result} may be equal to \tcode{first}. \pnum -\complexity -Approximately -\tcode{(last - first) * log(min(last - first, result_last - result_first))} -comparisons. +\begin{note} +The difference between \tcode{transform_exclusive_scan} and +\tcode{transform_inclusive_scan} is that \tcode{trans\-form\-_\-inclusive_scan} +includes the $i^\text{th}$ input element in the $i^\text{th}$ sum. +If \tcode{binary_op} is not mathematically associative, +the behavior of \tcode{transform_inclusive_scan} can be nondeterministic. +\tcode{transform_inclusive_scan} does not +apply \tcode{unary_op} to \tcode{init}. +\end{note} \end{itemdescr} -\rSec3[is.sorted]{\tcode{is_sorted}} +\rSec2[adjacent.difference]{Adjacent difference} -\indexlibrary{\idxcode{is_sorted}}% +\indexlibraryglobal{adjacent_difference}% \begin{itemdecl} -template - bool is_sorted(ForwardIterator first, ForwardIterator last); +template + constexpr OutputIterator + adjacent_difference(InputIterator first, InputIterator last, + OutputIterator result); +template + ForwardIterator2 + adjacent_difference(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); + +template + constexpr OutputIterator + adjacent_difference(InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation binary_op); +template + ForwardIterator2 + adjacent_difference(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryOperation binary_op); \end{itemdecl} - \begin{itemdescr} \pnum -\returns \tcode{is_sorted_until(first, last) == last} -\end{itemdescr} - -\indexlibrary{\idxcode{is_sorted}}% -\begin{itemdecl} -template - bool is_sorted(ForwardIterator first, ForwardIterator last, - Compare comp); -\end{itemdecl} - +Let \tcode{T} be the value type of \tcode{decltype(first)}. +For the overloads that do not take an argument \tcode{binary_op}, +let \tcode{binary_op} be an lvalue +that denotes an object of type \tcode{minus<>}. -\begin{itemdescr} \pnum -\returns \tcode{is_sorted_until(first, last, comp) == last} -\end{itemdescr} - -\indexlibrary{\idxcode{is_sorted_until}}% -\begin{itemdecl} -template - ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last); -template - ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last, - Compare comp); -\end{itemdecl} - +\mandates +\begin{itemize} +\item + For the overloads with no \tcode{ExecutionPolicy}, + \tcode{T} is constructible from \tcode{*first}. + \tcode{acc} (defined below) is + writable\iref{iterator.requirements.general} + to the \tcode{result} output iterator. + The result of the expression \tcode{binary_op(val, std::move(acc))} + is writable to \tcode{result}. +\item + For the overloads with an \tcode{ExecutionPolicy}, + the result of the expressions \tcode{binary_op(*first, *first)} and + \tcode{*first} are writable to \tcode{result}. +\end{itemize} -\begin{itemdescr} \pnum -\returns If \tcode{distance(first, last) < 2}, returns -\tcode{last}. Otherwise, returns -the last iterator \tcode{i} in \crange{first}{last} for which the -range \range{first}{i} is sorted. +\expects +\begin{itemize} +\item + For the overloads with no \tcode{ExecutionPolicy}, + \tcode{T} meets the \oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}) + requirements. +\item + For all overloads, in the ranges \crange{first}{last} + and \crange{result}{result + (last - first)}, + \tcode{binary_op} neither modifies elements + nor invalidates iterators or subranges. +\begin{footnote} +The use of fully closed ranges is intentional. +\end{footnote} +\end{itemize} \pnum -\complexity Linear. -\end{itemdescr} - -\rSec2[alg.nth.element]{Nth element} - -\indexlibrary{\idxcode{nth_element}}% -\begin{itemdecl} -template - void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last); - -template - void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last, Compare comp); -\end{itemdecl} +\effects +For the overloads with no \tcode{ExecutionPolicy} and a non-empty range, +the function creates an accumulator \tcode{acc} of type \tcode{T}, +initializes it with \tcode{*first}, +and assigns the result to \tcode{*result}. +For every iterator \tcode{i} in \range{first + 1}{last} in order, +creates an object \tcode{val} whose type is \tcode{T}, +initializes it with \tcode{*i}, +computes \tcode{binary_op(val, std::move(acc))}, +assigns the result to \tcode{*(result + (i - first))}, and +move assigns from \tcode{val} to \tcode{acc}. -\begin{itemdescr} \pnum -After -\tcode{nth_element} -the element in the position pointed to by \tcode{nth} -is the element that would be -in that position if the whole range were sorted, unless \tcode{nth == last}. -Also for every iterator -\tcode{i} -in the range -\range{first}{nth} -and every iterator -\tcode{j} -in the range -\range{nth}{last} -it holds that: -\tcode{!(*j < *i)} -or -\tcode{comp(*j, *i) == false}. +For the overloads with an \tcode{ExecutionPolicy} and a non-empty range, +performs \tcode{*result = *first}. +Then, for every \tcode{d} in \crange{1}{last - first - 1}, +performs \tcode{*(result + d) = binary_op(*(first + d), *(first + (d - 1)))}. \pnum -\requires -\tcode{RandomAccessIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). The type -of \tcode{*first} shall satisfy the requirements of -\tcode{MoveConstructible} (Table~\ref{moveconstructible}) and of -\tcode{MoveAssignable} (Table~\ref{moveassignable}). - +\returns +\tcode{result + (last - first)}. \pnum \complexity -Linear on average. -\end{itemdescr} - -\rSec2[alg.binary.search]{Binary search} +Exactly \tcode{(last - first) - 1} applications of the binary operation. \pnum -All of the algorithms in this section are versions of binary search -and assume that the sequence being searched is partitioned with respect to -an expression formed by binding the search key to an argument of the -implied or explicit comparison function. -They work on non-random access iterators minimizing the number of comparisons, -which will be logarithmic for all types of iterators. -They are especially appropriate for random access iterators, -because these algorithms do a logarithmic number of steps -through the data structure. -For non-random access iterators they execute a linear number of steps. +\remarks +For the overloads with no \tcode{ExecutionPolicy}, +\tcode{result} may be equal to \tcode{first}. +For the overloads with an \tcode{ExecutionPolicy}, +the ranges \range{first}{last} and \range{result}{result + (last - first)} +shall not overlap. +\end{itemdescr} -\rSec3[lower.bound]{\tcode{lower_bound}} +\rSec2[numeric.iota]{Iota} -\indexlibrary{\idxcode{lower_bound}}% +\indexlibraryglobal{iota}% \begin{itemdecl} template - ForwardIterator - lower_bound(ForwardIterator first, ForwardIterator last, - const T& value); - -template - ForwardIterator - lower_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); + constexpr void iota(ForwardIterator first, ForwardIterator last, T value); \end{itemdecl} \begin{itemdescr} \pnum -\requires -The elements -\tcode{e} -of -\range{first}{last} -shall be partitioned with respect to the expression -\tcode{e < value} -or -\tcode{comp(e, value)}. +\mandates +\tcode{T} is convertible to \tcode{ForwardIterator}'s value type. +The expression \tcode{++val}, where \tcode{val} has type \tcode{T}, +is well-formed. \pnum -\returns -The furthermost iterator -\tcode{i} -in the range -\crange{first}{last} -such that for every iterator -\tcode{j} -in the range -\range{first}{i} -the following corresponding conditions hold: -\tcode{*j < value} -or -\tcode{comp(*j, value) != false}. +\effects +For each element referred to by the iterator \tcode{i} +in the range \range{first}{last}, +assigns \tcode{*i = value} and increments \tcode{value} +as if by \tcode{++value}. \pnum \complexity -At most -$\log_2(\tcode{last - first}) + \bigoh{1}$ -comparisons. +Exactly \tcode{last - first} increments and assignments. \end{itemdescr} -\rSec3[upper.bound]{\tcode{upper_bound}} - -\indexlibrary{\idxcode{upper_bound}}% +\indexlibraryglobal{iota}% \begin{itemdecl} -template - ForwardIterator - upper_bound(ForwardIterator first, ForwardIterator last, - const T& value); - -template - ForwardIterator - upper_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); +template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ T> + requires @\libconcept{indirectly_writable}@ + constexpr ranges::iota_result ranges::iota(O first, S last, T value); +template<@\libconcept{weakly_incrementable}@ T, @\libconcept{output_range}@ R> + constexpr ranges::iota_result, T> ranges::iota(R&& r, T value); \end{itemdecl} \begin{itemdescr} \pnum -\requires -The elements -\tcode{e} -of -\range{first}{last} -shall be partitioned with respect to the expression -\tcode{!(value < e)} -or -\tcode{!comp(\brk{}value, e)}. - -\pnum -\returns -The furthermost iterator -\tcode{i} -in the range -\crange{first}{last} -such that for every iterator -\tcode{j} -in the range -\range{first}{i} -the following corresponding conditions hold: -\tcode{!(value < *j)} -or -\tcode{comp(value, *j) == false}. - -\pnum -\complexity -At most -$\log_2(\tcode{last - first}) + \bigoh{1}$ -comparisons. +\effects +Equivalent to: +\begin{codeblock} +while (first != last) { + *first = as_const(value); + ++first; + ++value; +} +return {std::move(first), std::move(value)}; +\end{codeblock} \end{itemdescr} -\rSec3[equal.range]{\tcode{equal_range}} +\rSec2[numeric.ops.gcd]{Greatest common divisor} -\indexlibrary{\idxcode{equal_range}}% +\indexlibraryglobal{gcd}% \begin{itemdecl} -template - pair - equal_range(ForwardIterator first, - ForwardIterator last, const T& value); - -template - pair - equal_range(ForwardIterator first, - ForwardIterator last, const T& value, - Compare comp); +template + constexpr common_type_t gcd(M m, N n); \end{itemdecl} \begin{itemdescr} \pnum -\requires -The elements -\tcode{e} -of -\range{first}{last} -shall be partitioned with respect to the expressions -\tcode{e < value} -and -\tcode{!(value < e)} -or -\tcode{comp(e, value)} -and -\tcode{!comp(value, e)}. -Also, for all elements -\tcode{e} -of -\tcode{[first, last)}, -\tcode{e < value} -shall imply -\tcode{!(value < e)} -or -\tcode{comp(e, value)} -shall imply -\tcode{!comp(value, e)}. +\mandates +\tcode{M} and \tcode{N} both are integer types other than +\cv{}~\tcode{bool}. + +\pnum +\expects +$|\tcode{m}|$ and $|\tcode{n}|$ +are representable as a value of \tcode{common_type_t}. +\begin{note} +These requirements ensure, for example, +that $\tcode{gcd(m, m)} = |\tcode{m}|$ +is representable as a value of type \tcode{M}. +\end{note} + \pnum \returns -\begin{codeblock} -make_pair(lower_bound(first, last, value), - upper_bound(first, last, value)) -\end{codeblock} -or -\begin{codeblock} -make_pair(lower_bound(first, last, value, comp), - upper_bound(first, last, value, comp)) -\end{codeblock} +Zero when \tcode{m} and \tcode{n} are both zero. Otherwise, +returns the greatest common divisor of $|\tcode{m}|$ and $|\tcode{n}|$. \pnum -\complexity -At most -$2 * \log_2(\tcode{last - first}) + \bigoh{1}$ -comparisons. +\throws +Nothing. \end{itemdescr} -\rSec3[binary.search]{\tcode{binary_search}} +\rSec2[numeric.ops.lcm]{Least common multiple} -\indexlibrary{\idxcode{binary_search}}% +\indexlibraryglobal{lcm}% \begin{itemdecl} -template - bool binary_search(ForwardIterator first, ForwardIterator last, - const T& value); - -template - bool binary_search(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); +template + constexpr common_type_t lcm(M m, N n); \end{itemdecl} \begin{itemdescr} \pnum -\requires -The elements -\tcode{e} -of -\range{first}{last} -are partitioned with respect to the expressions -\tcode{e < value} -and -\tcode{!(value < e)} -or -\tcode{comp(e, value)} -and -\tcode{!comp(value, e)}. -Also, for all elements -\tcode{e} -of -\tcode{[first, last)}, -\tcode{e < value} -implies -\tcode{!(value < e)} -or -\tcode{comp(e, value)} -implies -\tcode{!comp(value, e)}. +\mandates +\tcode{M} and \tcode{N} both are integer types other than +\cv{}~\tcode{bool}. + +\pnum +\expects +$|\tcode{m}|$ and $|\tcode{n}|$ +are representable as a value of \tcode{common_type_t}. +The least common multiple of $|\tcode{m}|$ and $|\tcode{n}|$ +is representable as a value of type \tcode{common_type_t}. \pnum \returns -\tcode{true} -if there is an iterator -\tcode{i} -in the range -\range{first}{last} -that satisfies the corresponding conditions: -\tcode{!(*i < value) \&\& !(value < *i)} -or -\tcode{comp(*i, value) == false \&\& comp(value, *i) == false}. +Zero when either \tcode{m} or \tcode{n} is zero. +Otherwise, returns the least common multiple of $|\tcode{m}|$ and $|\tcode{n}|$. \pnum -\complexity -At most -$\log_2(\tcode{last - first}) + \bigoh{1}$ -comparisons. +\throws +Nothing. \end{itemdescr} -\rSec2[alg.merge]{Merge} +\rSec2[numeric.ops.midpoint]{Midpoint} -\indexlibrary{\idxcode{merge}}% +\indexlibraryglobal{midpoint}% \begin{itemdecl} -template - OutputIterator - merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - -template - OutputIterator - merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); +template + constexpr T midpoint(T a, T b) noexcept; \end{itemdecl} +\begin{itemdescr} +\pnum +\constraints +\tcode{T} is an arithmetic type other than \cv{}~\tcode{bool}. + +\pnum +\returns +Half the sum of \tcode{a} and \tcode{b}. +If \tcode{T} is an integer type and the sum is odd, +the result is rounded towards \tcode{a}. -\begin{itemdescr} \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 + (last1 - first1) + (last2 - first2)}, such that the resulting range satisfies -\tcode{is_sorted(result, result_last)} or \tcode{is_sorted(result, result_last, comp)}, respectively. +\remarks +No overflow occurs. +If \tcode{T} is a floating-point type, at most one inexact operation occurs. +\end{itemdescr} +\indexlibraryglobal{midpoint}% +\begin{itemdecl} +template + constexpr T* midpoint(T* a, T* b); +\end{itemdecl} +\begin{itemdescr} \pnum -\requires The ranges \range{first1}{last1} and \range{first2}{last2} shall be -sorted with respect to \tcode{operator<} or \tcode{comp}. -The resulting range shall not overlap with either of the original ranges. +\constraints +\tcode{T} is an object type. \pnum -\returns -\tcode{result + (last1 - first1) + (last2 - first2)}. +\mandates +\tcode{T} is a complete type. \pnum -\complexity -At most -\tcode{(last1 - first1) + (last2 - first2) - 1} -comparisons. +\expects +\tcode{a} and \tcode{b} point to, respectively, +elements $i$ and $j$ of the same array object \tcode{x}. +\begin{note} +As specified in \ref{basic.compound}, +an object that is not an array element +is considered to belong to a single-element array for this purpose and +a pointer past the last element of an array of $n$ elements +is considered to be equivalent to a pointer +to a hypothetical array element $n$ for this purpose. +\end{note} \pnum -\remarks Stable~(\ref{algorithm.stable}). +\returns +A pointer to array element $i+\frac{j-i}{2}$ of \tcode{x}, +where the result of the division is truncated towards zero. \end{itemdescr} -\indexlibrary{\idxcode{inplace_merge}}% -\begin{itemdecl} -template - void inplace_merge(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last); +\rSec2[numeric.sat]{Saturation arithmetic} -template - void inplace_merge(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, Compare comp); +\rSec3[numeric.sat.func]{Arithmetic functions} + +\pnum +In the following descriptions, an arithmetic operation +is performed as a mathematical operation with infinite range and then +it is determined whether the mathematical result fits into the result type. + +\indexlibraryglobal{saturating_add}% +\begin{itemdecl} +template + constexpr T saturating_add(T x, T y) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Merges two sorted consecutive ranges -\range{first}{middle} -and -\range{middle}{last}, -putting the result of the merge into the range -\range{first}{last}. -The resulting range will be in non-decreasing order; -that is, for every iterator -\tcode{i} -in -\range{first}{last} -other than -\tcode{first}, -the condition -\tcode{*i < *(i - 1)} -or, respectively, -\tcode{comp(*i, *(i - 1))} -will be false. - -\pnum -\requires -The ranges \range{first}{middle} and \range{middle}{last} shall be -sorted with respect to \tcode{operator<} or \tcode{comp}. -\tcode{BidirectionalIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). The type -of \tcode{*first} shall satisfy the requirements of -\tcode{MoveConstructible} (Table~\ref{moveconstructible}) and of -\tcode{MoveAssignable} (Table~\ref{moveassignable}). - - -\pnum -\complexity -When enough additional memory is available, -\tcode{(last - first) - 1} -comparisons. -If no additional memory is available, an algorithm with complexity -$N \log(N)$ -(where -\tcode{N} -is equal to -\tcode{last - first}) -may be used. - -\pnum -\remarks Stable~(\ref{algorithm.stable}). +\constraints +\tcode{T} is a signed or unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +If $\tcode{x} + \tcode{y}$ is representable as a value of type \tcode{T}, $\tcode{x} + \tcode{y}$; +otherwise, either the largest or smallest representable value of type \tcode{T}, +whichever is closer to the value of $\tcode{x} + \tcode{y}$. \end{itemdescr} -\rSec2[alg.set.operations]{Set operations on sorted structures} +\indexlibraryglobal{saturating_sub}% +\begin{itemdecl} +template + constexpr T saturating_sub(T x, T y) noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -This section defines all the basic set operations on sorted structures. -They also work with -\tcode{multiset}s~(\ref{multiset}) -containing multiple copies of equivalent elements. -The semantics of the set operations are generalized to -\tcode{multiset}s -in a standard way by defining -\tcode{set_union()} -to contain the maximum number of occurrences of every element, -\tcode{set_intersection()} -to contain the minimum, and so on. +\constraints +\tcode{T} is a signed or unsigned integer type\iref{basic.fundamental}. -\rSec3[includes]{\tcode{includes}} +\pnum +\returns +If $\tcode{x} - \tcode{y}$ is representable as a value of type \tcode{T}, $\tcode{x} - \tcode{y}$; +otherwise, either the largest or smallest representable value of type \tcode{T}, +whichever is closer to the value of $\tcode{x} - \tcode{y}$. +\end{itemdescr} -\indexlibrary{\idxcode{includes}}% +\indexlibraryglobal{saturating_mul}% \begin{itemdecl} -template - bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); - -template - bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - Compare comp); +template + constexpr T saturating_mul(T x, T y) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{true} -if \range{first2}{last2} is empty or -if every element in the range -\range{first2}{last2} -is contained in the range -\range{first1}{last1}. -Returns -\tcode{false} -otherwise. +\constraints +\tcode{T} is a signed or unsigned integer type\iref{basic.fundamental}. \pnum -\complexity -At most -\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +\returns +If $\tcode{x} \times \tcode{y}$ is representable as a value of type \tcode{T}, $\tcode{x} \times \tcode{y}$; +otherwise, either the largest or smallest representable value of type \tcode{T}, +whichever is closer to the value of $\tcode{x} \times \tcode{y}$. \end{itemdescr} -\rSec3[set.union]{\tcode{set_union}} - -\indexlibrary{\idxcode{set_union}}% +\indexlibraryglobal{saturating_div}% \begin{itemdecl} -template - OutputIterator - set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - -template - OutputIterator - set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); +template + constexpr T saturating_div(T x, T y) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\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. +\constraints +\tcode{T} is a signed or unsigned integer type\iref{basic.fundamental}. \pnum -\requires -The resulting range shall not overlap with either of the original ranges. +\expects +\tcode{y != 0} is \tcode{true}. \pnum \returns -The end of the constructed range. - -\pnum -\complexity -At most -\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +If \tcode{T} is a signed integer type +and \tcode{x == numeric_limits::min() \&\& y == -1} is \tcode{true}, +\tcode{numeric_limits::max()}, otherwise, \tcode{x / y}. \pnum -\notes 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 shall be copied to the output -range, in order, and then $\max(n - m, 0)$ elements from the second range shall -be copied to the output range, in order. +\remarks +A function call expression +that violates the precondition in the \Fundescx{Preconditions} element +is not a core constant expression\iref{expr.const.core}. \end{itemdescr} -\rSec3[set.intersection]{\tcode{set_intersection}} +\rSec3[numeric.sat.cast]{Casting} -\indexlibrary{\idxcode{set_intersection}}% +\indexlibraryglobal{saturating_cast}% \begin{itemdecl} -template - OutputIterator - set_intersection(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - -template - OutputIterator - set_intersection(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); +template + constexpr R saturating_cast(T x) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\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. +\constraints +\tcode{R} and \tcode{T} are signed or unsigned integer types\iref{basic.fundamental}. \pnum -\requires -The resulting range shall not overlap with either of the original ranges. +\returns +If \tcode{x} is representable as a value of type \tcode{R}, \tcode{x}; +otherwise, either the largest or smallest representable value of type \tcode{R}, +whichever is closer to the value of \tcode{x}. +\end{itemdescr} + +\rSec1[specialized.algorithms]{Specialized \tcode{} algorithms} + +\rSec2[specialized.algorithms.general]{General} \pnum -\returns -The end of the constructed range. +The contents specified in \ref{specialized.algorithms} +are declared in the header \libheaderref{memory}. \pnum -\complexity -At most -\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +Unless otherwise specified, +if an exception is thrown in the following algorithms, +objects constructed by a placement \grammarterm{new-expression}\iref{expr.new} +are destroyed in an unspecified order +before allowing the exception to propagate. \pnum -\notes 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 shall be copied from the first range -to the output range, in order. -\end{itemdescr} +\begin{note} +When new objects are created by +the algorithms specified in \ref{specialized.algorithms}, +the lifetime ends for any existing objects +(including potentially-overlapping subobjects \ref{intro.object}) +in storage that is reused \ref{basic.life}. +\end{note} -\rSec3[set.difference]{\tcode{set_difference}} +\pnum +Some algorithms specified in \ref{specialized.algorithms} +make use of the following exposition-only function templates: +\begin{codeblock} +template + constexpr void* @\placeholdernc{voidify}@(T& obj) noexcept { + return addressof(obj); + } + +template + constexpr decltype(auto) @\exposid{deref-move}@(I& it) { + if constexpr (is_lvalue_reference_v) + return std::move(*it); + else + return *it; + } +\end{codeblock} -\indexlibrary{\idxcode{set_difference}}% -\begin{itemdecl} -template - OutputIterator - set_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); +\rSec2[special.mem.concepts]{Special memory concepts} -template - OutputIterator - set_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); +\pnum +Some algorithms in this subclause are constrained with the following +exposition-only concepts: + +\begin{itemdecl} +template +concept @\defexposconcept{nothrow-input-iterator}@ = // \expos + @\libconcept{input_iterator}@ && + is_lvalue_reference_v> && + @\libconcept{same_as}@>, iter_value_t>; \end{itemdecl} \begin{itemdescr} \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. +A type \tcode{I} models \exposconcept{nothrow-input-iterator} only if +no exceptions are thrown from increment, +copy construction, move construction, +copy assignment, move assignment, +or indirection through valid iterators. \pnum -\requires -The resulting range shall not overlap with either of the original ranges. +\begin{note} +This concept allows some \libconcept{input_iterator}\iref{iterator.concept.input} +operations to throw exceptions. +\end{note} +\end{itemdescr} -\pnum -\returns -The end of the constructed range. +\begin{itemdecl} +template +concept @\defexposconcept{nothrow-sentinel-for}@ = @\libconcept{sentinel_for}@; // \expos +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -At most -\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +Types \tcode{S} and \tcode{I} model \exposconcept{nothrow-sentinel-for} +only if no exceptions are thrown from copy construction, move construction, +copy assignment, move assignment, or comparisons between +valid values of type \tcode{I} and \tcode{S}. \pnum -\notes -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} -shall be copied to the output range. +\begin{note} +This concept allows some \libconcept{sentinel_for}\iref{iterator.concept.sentinel} +operations to throw exceptions. +\end{note} \end{itemdescr} -\rSec3[set.symmetric.difference]{\tcode{set_symmetric_difference}} - -\indexlibrary{\idxcode{set_symmetric_difference}}% \begin{itemdecl} -template - OutputIterator - set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - -template - OutputIterator - set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); +template +concept @\defexposconcept{nothrow-sized-sentinel-for}@ = // \expos + @\exposconcept{nothrow-sentinel-for}@ && + @\libconcept{sized_sentinel_for}@; \end{itemdecl} \begin{itemdescr} \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. +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 -\requires -The resulting range shall not overlap with either of the original ranges. +\begin{note} +This concept allows some \libconcept{sized_sentinel_for}\iref{iterator.concept.sizedsentinel} +operations to throw exceptions. +\end{note} +\end{itemdescr} -\pnum -\returns -The end of the constructed range. +\begin{itemdecl} +template +concept @\defexposconcept{nothrow-input-range}@ = // \expos + @\libconcept{range}@ && + @\exposconcept{nothrow-input-iterator}@> && + @\exposconcept{nothrow-sentinel-for}@, iterator_t>; +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -At most -\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +A type \tcode{R} models \exposconcept{nothrow-input-range} only if +no exceptions are thrown from calls to \tcode{ranges::begin} and +\tcode{ranges::end} on an object of type \tcode{R}. +\end{itemdescr} +\begin{itemdecl} +template +concept @\defexposconcept{nothrow-forward-iterator}@ = // \expos + @\exposconcept{nothrow-input-iterator}@ && + @\libconcept{forward_iterator}@ && + @\exposconcept{nothrow-sentinel-for}@; +\end{itemdecl} + +\begin{itemdescr} \pnum -\notes -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$. +\begin{note} +This concept allows some \libconcept{forward_iterator}\iref{iterator.concept.forward} +operations to throw exceptions. +\end{note} \end{itemdescr} -\rSec2[alg.heap.operations]{Heap operations} +\begin{itemdecl} +template +concept @\defexposconcept{nothrow-forward-range}@ = // \expos + @\exposconcept{nothrow-input-range}@ && + @\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 -\techterm{heap} -is a particular organization of elements in a range between two random access iterators -\range{a}{b}. -Its two key properties are: +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{description} -\item{(1)} There is no element greater than -\tcode{*a} -in the range and -\item{(2)} \tcode{*a} -may be removed by -\tcode{pop_heap()}, -or a new element added by -\tcode{push_heap()}, -in -$\mathcal{O}(\log(N))$ -time. -\end{description} +\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 -These properties make heaps useful as priority queues. +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 -\tcode{make_heap()} -converts a range into a heap and -\tcode{sort_heap()} -turns a heap into a sorted sequence. +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} -\rSec3[push.heap]{\tcode{push_heap}} +\rSec2[uninitialized.construct.default]{\tcode{uninitialized_default_construct}} -\indexlibrary{\idxcode{push_heap}}% +\indexlibraryglobal{uninitialized_default_construct}% \begin{itemdecl} -template - void push_heap(RandomAccessIterator first, RandomAccessIterator last); - -template - void push_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +template + constexpr void uninitialized_default_construct(NoThrowForwardIterator first, + NoThrowForwardIterator last); \end{itemdecl} \begin{itemdescr} \pnum \effects -Places the value in the location -\tcode{last - 1} -into the resulting heap -\range{first}{last}. +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_default_construct}% +\begin{itemdecl} +namespace ranges { + template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> + requires @\libconcept{default_initializable}@> + constexpr I uninitialized_default_construct(I first, S last); + template<@\exposconcept{nothrow-forward-range}@ R> + requires @\libconcept{default_initializable}@> + constexpr borrowed_iterator_t uninitialized_default_construct(R&& r); +} +\end{itemdecl} +\begin{itemdescr} \pnum -\requires -The range -\range{first}{last - 1} -shall be a valid heap. -The type of \tcode{*first} shall satisfy -the \tcode{MoveConstructible} requirements -(Table~\ref{moveconstructible}) and the -\tcode{MoveAssignable} requirements -(Table~\ref{moveassignable}). +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>; +return first; +\end{codeblock} +\end{itemdescr} +\indexlibraryglobal{uninitialized_default_construct_n}% +\begin{itemdecl} +template + constexpr NoThrowForwardIterator + uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -At most -\tcode{log(last - first)} -comparisons. +\effects +Equivalent to: +\begin{codeblock} +for (; n > 0; (void)++first, --n) + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type; +return first; +\end{codeblock} \end{itemdescr} -\rSec3[pop.heap]{\tcode{pop_heap}} - -\indexlibrary{\idxcode{pop_heap}}% +\indexlibraryglobal{uninitialized_default_construct_n}% \begin{itemdecl} -template - void pop_heap(RandomAccessIterator first, RandomAccessIterator last); - -template - void pop_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +namespace ranges { + template<@\exposconcept{nothrow-forward-iterator}@ I> + requires @\libconcept{default_initializable}@> + constexpr I uninitialized_default_construct_n(I first, iter_difference_t n); +} \end{itemdecl} \begin{itemdescr} \pnum -\requires -The range -\range{first}{last} -shall be a valid non-empty heap. -\tcode{RandomAccessIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). The type -of \tcode{*first} shall satisfy the requirements of -\tcode{MoveConstructible} (Table~\ref{moveconstructible}) and of -\tcode{MoveAssignable} (Table~\ref{moveassignable}). +\effects +Equivalent to: +\begin{codeblock} +return uninitialized_default_construct(counted_iterator(first, n), + default_sentinel).base(); +\end{codeblock} +\end{itemdescr} + +\rSec2[uninitialized.construct.value]{\tcode{uninitialized_value_construct}} +\indexlibraryglobal{uninitialized_value_construct}% +\begin{itemdecl} +template + constexpr void uninitialized_value_construct(NoThrowForwardIterator first, + NoThrowForwardIterator last); +\end{itemdecl} +\begin{itemdescr} \pnum \effects -Swaps the value in the location \tcode{first} -with the value in the location -\tcode{last - 1} -and makes -\range{first}{last - 1} -into a heap. +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type(); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_value_construct}% +\begin{itemdecl} +namespace ranges { + template<@\exposconcept{nothrow-forward-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> + requires @\libconcept{default_initializable}@> + constexpr I uninitialized_value_construct(I first, S last); + template<@\exposconcept{nothrow-forward-range}@ R> + requires @\libconcept{default_initializable}@> + constexpr borrowed_iterator_t uninitialized_value_construct(R&& r); +} +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -At most -\tcode{2 * log(last - first)} -comparisons. +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>(); +return first; +\end{codeblock} \end{itemdescr} -\rSec3[make.heap]{\tcode{make_heap}} - -\indexlibrary{\idxcode{make_heap}}% +\indexlibraryglobal{uninitialized_value_construct_n}% \begin{itemdecl} -template - void make_heap(RandomAccessIterator first, RandomAccessIterator last); - -template - void make_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +template + constexpr NoThrowForwardIterator + uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); \end{itemdecl} \begin{itemdescr} \pnum \effects -Constructs a heap out of the range -\range{first}{last}. +Equivalent to: +\begin{codeblock} +for (; n > 0; (void)++first, --n) + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type(); +return first; +\end{codeblock} +\end{itemdescr} -\pnum -\requires The type of \tcode{*first} shall satisfy -the \tcode{MoveConstructible} requirements -(Table~\ref{moveconstructible}) and the -\tcode{MoveAssignable} requirements -(Table~\ref{moveassignable}). +\indexlibraryglobal{uninitialized_value_construct_n}% +\begin{itemdecl} +namespace ranges { + template<@\exposconcept{nothrow-forward-iterator}@ I> + requires @\libconcept{default_initializable}@> + constexpr I uninitialized_value_construct_n(I first, iter_difference_t n); +} +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -At most -\tcode{3 * (last - first)} -comparisons. +\effects +Equivalent to: +\begin{codeblock} +return uninitialized_value_construct(counted_iterator(first, n), + default_sentinel).base(); +\end{codeblock} \end{itemdescr} -\rSec3[sort.heap]{\tcode{sort_heap}} - -\indexlibrary{\idxcode{sort_heap}}% -\begin{itemdecl} -template - void sort_heap(RandomAccessIterator first, RandomAccessIterator last); +\rSec2[uninitialized.copy]{\tcode{uninitialized_copy}} -template - void sort_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +\indexlibraryglobal{uninitialized_copy}% +\begin{itemdecl} +template + constexpr NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last, + NoThrowForwardIterator result); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Sorts elements in the heap -\range{first}{last}. +\expects +\countedrange{result}{(last - first)} does not overlap with \range{first}{last}. \pnum -\requires The range \range{first}{last} shall be a valid heap. -\tcode{RandomAccessIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). The type -of \tcode{*first} shall satisfy the requirements of -\tcode{MoveConstructible} (Table~\ref{moveconstructible}) and of -\tcode{MoveAssignable} (Table~\ref{moveassignable}). - +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++result, (void)++first) + ::new (@\placeholdernc{voidify}@(*result)) iterator_traits::value_type(*first); +\end{codeblock} \pnum -\complexity -At most $N \log(N)$ -comparisons (where -\tcode{N == last - first}). +\returns +\tcode{result}. \end{itemdescr} -\rSec3[is.heap]{\tcode{is_heap}} - -\indexlibrary{\idxcode{is_heap}}% +\indexlibraryglobal{uninitialized_copy}% \begin{itemdecl} - template - bool is_heap(RandomAccessIterator first, RandomAccessIterator last); +namespace ranges { + 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> + constexpr uninitialized_copy_result + uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); + template<@\libconcept{input_range}@ IR, @\exposconcept{nothrow-forward-range}@ OR> + requires @\libconcept{constructible_from}@, range_reference_t> + constexpr uninitialized_copy_result, borrowed_iterator_t> + uninitialized_copy(IR&& in_range, OR&& out_range); +} \end{itemdecl} - \begin{itemdescr} \pnum -\returns \tcode{is_heap_until(first, last) == last} +\expects +\range{ofirst}{olast} does not overlap with \range{ifirst}{ilast}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; ifirst != ilast && ofirst != olast; ++ofirst, (void)++ifirst) + ::new (@\placeholdernc{voidify}@(*ofirst)) remove_reference_t>(*ifirst); +return {std::move(ifirst), ofirst}; +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{is_heap}}% +\indexlibraryglobal{uninitialized_copy_n}% \begin{itemdecl} - template - bool is_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); +template + constexpr NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, + NoThrowForwardIterator result); \end{itemdecl} - \begin{itemdescr} \pnum -\returns \tcode{is_heap_until(first, last, comp) == last} +\expects +\countedrange{result}{n} does not overlap with \countedrange{first}{n}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; n > 0; ++result, (void)++first, --n) + ::new (@\placeholdernc{voidify}@(*result)) iterator_traits::value_type(*first); +\end{codeblock} + +\pnum +\returns +\tcode{result}. \end{itemdescr} -\indexlibrary{\idxcode{is_heap_until}}% +\indexlibraryglobal{uninitialized_copy_n}% \begin{itemdecl} - template - RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last); - template - RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +namespace ranges { + 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, O ofirst, S olast); +} \end{itemdecl} - \begin{itemdescr} \pnum -\returns If \tcode{distance(first, last) < 2}, returns -\tcode{last}. Otherwise, returns -the last iterator \tcode{i} in \crange{first}{last} for which the -range \range{first}{i} is a heap. +\expects +\range{ofirst}{olast} does not overlap with +\countedrange{ifirst}{n}. \pnum -\complexity Linear. +\effects +Equivalent to: +\begin{codeblock} +auto t = uninitialized_copy(counted_iterator(std::move(ifirst), n), + default_sentinel, ofirst, olast); +return {std::move(t.in).base(), t.out}; +\end{codeblock} \end{itemdescr} +\rSec2[uninitialized.move]{\tcode{uninitialized_move}} -\rSec2[alg.min.max]{Minimum and maximum} - -\indexlibrary{\idxcode{min}}% +\indexlibraryglobal{uninitialized_move}% \begin{itemdecl} -template constexpr const T& min(const T& a, const T& b); -template - constexpr const T& min(const T& a, const T& b, Compare comp); +template + constexpr NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last, + NoThrowForwardIterator result); \end{itemdecl} \begin{itemdescr} \pnum -\requires -Type -\tcode{T} -is -\tcode{LessThanComparable} (Table~\ref{lessthancomparable}). - -\pnum -\returns -The smaller value. +\expects +\countedrange{result}{(last - first)} does not overlap with \range{first}{last}. \pnum -\notes -Returns the first argument when the arguments are equivalent. +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; (void)++result, ++first) + ::new (@\placeholdernc{voidify}@(*result)) + iterator_traits::value_type(@\exposid{deref-move}@(first)); +return result; +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{min}}% +\indexlibraryglobal{uninitialized_move}% \begin{itemdecl} -template - constexpr T min(initializer_list t); -template - constexpr T min(initializer_list t, Compare comp); +namespace ranges { + 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> + constexpr uninitialized_move_result + uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); + template<@\libconcept{input_range}@ IR, @\exposconcept{nothrow-forward-range}@ OR> + requires @\libconcept{constructible_from}@, range_rvalue_reference_t> + constexpr uninitialized_move_result, borrowed_iterator_t> + uninitialized_move(IR&& in_range, OR&& out_range); +} \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{T} is \tcode{LessThanComparable} and \tcode{CopyConstructible} and -\tcode{t.size() > 0}. +\expects +\range{ofirst}{olast} does not overlap with \range{ifirst}{ilast}. \pnum -\returns The smallest value in the initializer_list. +\effects +Equivalent to: +\begin{codeblock} +for (; ifirst != ilast && ofirst != olast; ++ofirst, (void)++ifirst) + ::new (@\placeholder{voidify}@(*ofirst)) + remove_reference_t>(ranges::iter_move(ifirst)); +return {std::move(ifirst), ofirst}; +\end{codeblock} \pnum -\remarks Returns a copy of the leftmost argument when several arguments are equivalent to the smallest.\ +\begin{note} +If an exception is thrown, some objects in the range \range{ifirst}{ilast} are +left in a valid, but unspecified state. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{max}}% +\indexlibraryglobal{uninitialized_move_n}% \begin{itemdecl} -template constexpr const T& max(const T& a, const T& b); -template - constexpr const T& max(const T& a, const T& b, Compare comp); +template + constexpr pair + uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result); \end{itemdecl} \begin{itemdescr} \pnum -\requires -Type -\tcode{T} -is -\tcode{LessThanComparable} (Table~\ref{lessthancomparable}). - -\pnum -\returns -The larger value. +\expects +\countedrange{result}{n} does not overlap with \countedrange{first}{n}. \pnum -\notes -Returns the first argument when the arguments are equivalent. +\effects +Equivalent to: +\begin{codeblock} +for (; n > 0; ++result, (void)++first, --n) + ::new (@\placeholdernc{voidify}@(*result)) + iterator_traits::value_type(@\exposid{deref-move}@(first)); +return {first, result}; +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{max}}% +\indexlibraryglobal{uninitialized_move_n}% \begin{itemdecl} -template - constexpr T max(initializer_list t); -template - constexpr T max(initializer_list t, Compare comp); +namespace ranges { + template<@\libconcept{input_iterator}@ I, @\exposconcept{nothrow-forward-iterator}@ O, @\exposconcept{nothrow-sentinel-for}@ S> + requires @\libconcept{constructible_from}@, iter_rvalue_reference_t> + constexpr uninitialized_move_n_result + uninitialized_move_n(I ifirst, iter_difference_t n, O ofirst, S olast); +} \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{T} is \tcode{LessThanComparable} and \tcode{CopyConstructible} and \tcode{t.size() > 0}. +\expects +\range{ofirst}{olast} does not overlap with \countedrange{ifirst}{n}. \pnum -\returns The largest value in the initializer_list. +\effects +Equivalent to: +\begin{codeblock} +auto t = uninitialized_move(counted_iterator(std::move(ifirst), n), + default_sentinel, ofirst, olast); +return {std::move(t.in).base(), t.out}; +\end{codeblock} \pnum -\remarks Returns a copy of the leftmost argument when several arguments are equivalent to the largest. +\begin{note} +If an exception is thrown, some objects in the range +\countedrange{ifirst}{n} +are left in a valid but unspecified state. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{minmax}}% +\rSec2[uninitialized.fill]{\tcode{uninitialized_fill}} + +\indexlibraryglobal{uninitialized_fill}% \begin{itemdecl} -template constexpr pair minmax(const T& a, const T& b); -template - constexpr pair minmax(const T& a, const T& b, Compare comp); +template::value_type> + constexpr void uninitialized_fill(NoThrowForwardIterator first, + NoThrowForwardIterator last, const T& x); \end{itemdecl} - \begin{itemdescr} \pnum -\requires -Type -\tcode{T} -shall be -\tcode{LessThanComparable} (Table~\ref{lessthancomparable}). - -\pnum -\returns -\tcode{pair(b, a)} if \tcode{b} is smaller -than \tcode{a}, and -\tcode{pair(a, b)} otherwise. +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type(x); +\end{codeblock} +\end{itemdescr} -\pnum -\notes -Returns \tcode{pair(a, b)} when the arguments are equivalent. +\indexlibraryglobal{uninitialized_fill}% +\begin{itemdecl} +namespace ranges { + 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 = range_value_t> + requires @\libconcept{constructible_from}@, const T&> + constexpr borrowed_iterator_t uninitialized_fill(R&& r, const T& x); +} +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -Exactly one comparison. +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>(x); +return first; +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{minmax}}% +\indexlibraryglobal{uninitialized_fill_n}% \begin{itemdecl} -template - constexpr pair minmax(initializer_list t); -template - constexpr pair minmax(initializer_list t, Compare comp); +template::value_type> + constexpr NoThrowForwardIterator + uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{T} is \tcode{LessThanComparable} and \tcode{CopyConstructible} and \tcode{t.size() > 0}. - -\pnum -\returns \tcode{pair(x, y)}, where \tcode{x} has the smallest and \tcode{y} has the -largest value in the initializer list. +\effects +Equivalent to: +\begin{codeblock} +for (; n--; ++first) + ::new (@\placeholdernc{voidify}@(*first)) iterator_traits::value_type(x); +return first; +\end{codeblock} +\end{itemdescr} -\pnum -\remarks \tcode{x} is a copy of the leftmost argument when several arguments are equivalent to -the smallest. \tcode{y} is a copy of the rightmost argument when several arguments are -equivalent to the largest. +\indexlibraryglobal{uninitialized_fill_n}% +\begin{itemdecl} +namespace ranges { + 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); +} +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity At most \tcode{(3/2) * t.size()} applications of the corresponding predicate. +\effects +Equivalent to: +\begin{codeblock} +return uninitialized_fill(counted_iterator(first, n), default_sentinel, x).base(); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{min_element}}% +\rSec2[specialized.construct]{\tcode{construct_at}} + +\indexlibraryglobal{construct_at} \begin{itemdecl} -template - ForwardIterator min_element(ForwardIterator first, ForwardIterator last); +template + constexpr T* construct_at(T* location, Args&&... args); -template - ForwardIterator min_element(ForwardIterator first, ForwardIterator last, - Compare comp); +namespace ranges { + template + constexpr T* construct_at(T* location, Args&&... args); +} \end{itemdecl} \begin{itemdescr} \pnum -\returns -The first iterator -\tcode{i} -in the range -\range{first}{last} -such that for every iterator -\tcode{j} -in the range -\range{first}{last} -the following corresponding conditions hold: -\tcode{!(*j < *i)} -or -\tcode{comp(*j, *i) == false}. -Returns -\tcode{last} -if -\tcode{first == last}. +\constraints +\tcode{is_unbounded_array_v} is \tcode{false}. +The expression \tcode{::new (declval()) T(\linebreak{}declval()...)} +is well-formed when treated as an unevaluated operand\iref{term.unevaluated.operand}. \pnum -\complexity -Exactly -\tcode{max((last - first) - 1, 0)} -applications of the corresponding comparisons. +\mandates +If \tcode{is_array_v} is \tcode{true}, \tcode{sizeof...(Args)} is zero. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if constexpr (is_array_v) + return ::new (@\placeholdernc{voidify}@(*location)) T[1](); +else + return ::new (@\placeholdernc{voidify}@(*location)) T(std::forward(args)...); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{max_element}}% +\rSec2[specialized.destroy]{\tcode{destroy}} + +\indexlibraryglobal{destroy_at}% \begin{itemdecl} -template - ForwardIterator max_element(ForwardIterator first, ForwardIterator last); -template - ForwardIterator max_element(ForwardIterator first, ForwardIterator last, - Compare comp); +template + constexpr void destroy_at(T* location); +namespace ranges { + template<@\libconcept{destructible}@ T> + constexpr void destroy_at(T* location) noexcept; +} \end{itemdecl} \begin{itemdescr} \pnum -\returns -The first iterator -\tcode{i} -in the range -\range{first}{last} -such that for every iterator -\tcode{j} -in the range -\range{first}{last} -the following corresponding conditions hold: -\tcode{!(*i < *j)} -or -\tcode{comp(*i, *j) == false}. -Returns -\tcode{last} -if -\tcode{first == last}. - -\pnum -\complexity -Exactly -\tcode{max((last - first) - 1, 0)} -applications of the corresponding comparisons. +\effects +\begin{itemize} +\item If \tcode{T} is an array type, equivalent to + \tcode{destroy(begin(*location), end(*location))}. +\item Otherwise, equivalent to + \tcode{location->\~T()}. +\end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{minmax_element}}% +\indexlibraryglobal{destroy}% \begin{itemdecl} -template - pair - minmax_element(ForwardIterator first, ForwardIterator last); -template - pair - minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); +template + constexpr void destroy(NoThrowForwardIterator first, NoThrowForwardIterator last); \end{itemdecl} - \begin{itemdescr} \pnum -\returns -\tcode{make_pair(first, first)} if \range{first}{last} is empty, otherwise -\tcode{make_pair(m, M)}, where \tcode{m} is -the first iterator in \range{first}{last} such that no iterator in the range refers to a smaller element, and where \tcode{M} is the last iterator -\footnote{This behavior intentionally differs from \tcode{max_element()}.} -in \range{first}{last} such that no iterator in the range refers to a larger element. - -\pnum -\complexity -At most -$max(\lfloor{\frac{3}{2}} (N-1)\rfloor, 0)$ -applications of the corresponding predicate, where $N$ is \tcode{distance(first, last)}. +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + destroy_at(addressof(*first)); +\end{codeblock} \end{itemdescr} -\rSec2[alg.lex.comparison]{Lexicographical comparison} - -\indexlibrary{\idxcode{lexicographical_compare}}% +\indexlibraryglobal{destroy}% \begin{itemdecl} -template - bool - lexicographical_compare(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); - -template - bool - lexicographical_compare(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - Compare comp); +namespace ranges { + template<@\exposconcept{nothrow-input-iterator}@ I, @\exposconcept{nothrow-sentinel-for}@ S> + requires @\libconcept{destructible}@> + constexpr I destroy(I first, S last) noexcept; + template<@\exposconcept{nothrow-input-range}@ R> + requires @\libconcept{destructible}@> + constexpr borrowed_iterator_t destroy(R&& r) noexcept; +} \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{true} -if the sequence of elements defined by the range -\range{first1}{last1} -is lexicographically less than the sequence of elements defined by the range -\range{first2}{last2} and -\tcode{false} -otherwise. +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + destroy_at(addressof(*first)); +return first; +\end{codeblock} +\end{itemdescr} -\pnum -\complexity -At most -\tcode{2*min((last1 - first1), (last2 - first2))} -applications of the corresponding comparison. +\indexlibraryglobal{destroy_n}% +\begin{itemdecl} +template + constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, Size n); +\end{itemdecl} +\begin{itemdescr} \pnum -\notes -If two sequences have the same number of elements and their corresponding -elements are equivalent, then neither sequence is lexicographically -less than the other. -If one sequence is a prefix of the other, then the shorter sequence is -lexicographically less than the longer sequence. -Otherwise, the lexicographical comparison of the sequences yields the same -result as the comparison of the first corresponding pair of -elements that are not equivalent. - +\effects +Equivalent to: \begin{codeblock} -for ( ; first1 != last1 && first2 != last2 ; ++first1, ++first2) { - if (*first1 < *first2) return true; - if (*first2 < *first1) return false; -} -return first1 == last1 && first2 != last2; +for (; n > 0; (void)++first, --n) + destroy_at(addressof(*first)); +return first; \end{codeblock} - -\pnum -\remarks\ An empty sequence is lexicographically less than any non-empty sequence, but -not less than any empty sequence. - \end{itemdescr} -\rSec2[alg.permutation.generators]{Permutation generators} - -\indexlibrary{\idxcode{next_permutation}}% +\indexlibraryglobal{destroy_n}% \begin{itemdecl} -template - bool next_permutation(BidirectionalIterator first, - BidirectionalIterator last); - -template - bool next_permutation(BidirectionalIterator first, - BidirectionalIterator last, Compare comp); +namespace ranges { + template<@\exposconcept{nothrow-input-iterator}@ I> + requires @\libconcept{destructible}@> + constexpr I destroy_n(I first, iter_difference_t n) noexcept; +} \end{itemdecl} \begin{itemdescr} \pnum \effects -Takes a sequence defined by the range -\range{first}{last} -and transforms it into the next permutation. -The next permutation is found by assuming that the set of all permutations is -lexicographically sorted with respect to -\tcode{operator<} -or \tcode{comp}. -If such a permutation exists, it returns -\tcode{true}. -Otherwise, it transforms the sequence into the smallest permutation, -that is, the ascendingly sorted one, and returns -\tcode{false}. +Equivalent to: +\begin{codeblock} +return destroy(counted_iterator(std::move(first), n), default_sentinel).base(); +\end{codeblock} +\end{itemdescr} -\pnum -\requires -\tcode{BidirectionalIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). +\rSec1[alg.rand]{Specialized \tcode{} algorithms} +\rSec2[alg.rand.general]{General} \pnum -\complexity -At most -\tcode{(last - first)/2} -swaps. -\end{itemdescr} +The contents specified in \ref{alg.rand} +are declared in the header \libheaderrefx{random}{rand.synopsis}. -\indexlibrary{\idxcode{prev_permutation}}% -\begin{itemdecl} -template - bool prev_permutation(BidirectionalIterator first, - BidirectionalIterator last); +\rSec2[alg.rand.generate]{\tcode{generate_random}} -template - bool prev_permutation(BidirectionalIterator first, - BidirectionalIterator last, Compare comp); +\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); \end{itemdecl} \begin{itemdescr} \pnum \effects -Takes a sequence defined by the range -\range{first}{last} -and transforms it into the previous permutation. -The previous permutation is found by assuming that the set of all permutations is -lexicographically sorted with respect to -\tcode{operator<} -or \tcode{comp}. +\begin{itemize} +\item +Calls \tcode{g.generate_random(std::forward(r))} +if this expression is well-formed. +\item +Otherwise, if \tcode{R} models \libconcept{sized_range}, +fills \tcode{r} with \tcode{ranges::size(r)} values of +type \tcode{invoke_result_t} by performing +an unspecified number of invocations of +the form \tcode{g()} or \tcode{g.generate_random(s)}, +if such an expression is well-formed for a value \tcode{N} and +an object \tcode{s} of type \tcode{span, N>}. +\begin{note} +Values of \tcode{N} can differ between invocations. +\end{note} +\item +Otherwise, calls \tcode{ranges::generate(std::forward(r), ref(g))}. +\end{itemize} \pnum \returns -\tcode{true} -if such a permutation exists. -Otherwise, it transforms the sequence into the largest permutation, -that is, the descendingly sorted one, and returns -\tcode{false}. +\tcode{ranges::end(r)}. \pnum -\requires -\tcode{BidirectionalIterator} shall satisfy the requirements of -\tcode{ValueSwappable}~(\ref{swappable.requirements}). +\remarks +The effects of \tcode{generate_random(r, g)} shall be equivalent to +\tcode{ranges::generate(std::for\-ward(r), ref(g))}. +\begin{note} +This implies that \tcode{g.generate_random(a)} fills \tcode{a} +with the same values as produced by invocation of \tcode{g()}. +\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); +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -At most -\tcode{(last - first)/2} -swaps. +\effects +Equivalent to: +\begin{codeblock} +return generate_random(subrange(std::move(first), last), g); +\end{codeblock} \end{itemdescr} -\rSec1[alg.c.library]{C library algorithms} +\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); +\end{itemdecl} +\begin{itemdescr} \pnum -Table~\ref{tab:algorithms.hdr.cstdlib} describes some of the contents of the header \tcode{}. - -\begin{libsyntab3}{cstdlib}{tab:algorithms.hdr.cstdlib} -\type & \tcode{size_t} & \\ \hline -\functions & \tcode{bsearch} & \tcode{qsort} \\ -\end{libsyntab3} +\effects +\begin{itemize} +\item +Calls \tcode{d.generate_random(std::forward(r), g)} +if this expression is well-formed. +\item +Otherwise, if \tcode{R} models \libconcept{sized_range}, +fills \tcode{r} with \tcode{ranges::size(r)} values of +type \tcode{invoke_result_t} +by performing an unspecified number of invocations of +the form \tcode{invoke(d, g)} or \tcode{d.generate_random(s, g)}, +if such an expression is well-formed +for a value \tcode{N} and +an object \tcode{s} of type \tcode{span, N>}. +\begin{note} +Values of N can differ between invocations. +\end{note} +\item +Otherwise, calls +\begin{codeblock} +ranges::generate(std::forward(r), [&d, &g] { return invoke(d, g); }); +\end{codeblock} +\end{itemize} \pnum -The contents are the same as the Standard C library header -\tcode{} -with the following exceptions: +\returns +\tcode{ranges::end(r)}. \pnum -The function signature: - +\remarks +The effects of \tcode{generate_random(r, g, d)} shall be equivalent to \begin{codeblock} -bsearch(const void *, const void *, size_t, size_t, - int (*)(const void *, const void *)); +ranges::generate(std::forward(r), [&d, &g] { return invoke(d, g); }) \end{codeblock} +\begin{note} +This implies that \tcode{d.generate_random(a, g)} +fills \tcode{a} with the values with the same random distribution +as produced by invocation of \tcode{invoke(d, g)}. +\end{note} +\end{itemdescr} -is replaced by the two declarations: +\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); +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Equivalent to: \begin{codeblock} -extern "C" void* bsearch(const void* key, const void* base, - size_t nmemb, size_t size, - int (*compar)(const void*, const void*)); -extern "C++" void* bsearch(const void* key, const void* base, - size_t nmemb, size_t size, - int (*compar)(const void*, const void*)); +return generate_random(subrange(std::move(first), last), g, d); \end{codeblock} +\end{itemdescr} -both of which have the same behavior as the original declaration. +\rSec1[alg.c.library]{C library algorithms} \pnum -The function signature: - -\begin{codeblock} -qsort(void *, size_t, size_t, - int (*)(const void *, const void *)); -\end{codeblock} +\begin{note} +The header \libheaderref{cstdlib} +declares the functions described in this subclause. +\end{note} -is replaced by the two declarations: +\indexlibraryglobal{bsearch}% +\indexlibraryglobal{qsort}% +\begin{itemdecl} +void* bsearch(const void* key, void* base, size_t nmemb, size_t size, + @\placeholder{c-compare-pred}@* compar); +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} -\begin{codeblock} -extern "C" void qsort(void* base, size_t nmemb, size_t size, - int (*compar)(const void*, const void*)); -extern "C++" void qsort(void* base, size_t nmemb, size_t size, - int (*compar)(const void*, const void*)); -\end{codeblock} +\begin{itemdescr} +\pnum +\expects +For \tcode{qsort}, the objects in the array pointed to by \tcode{base} +are of trivially copyable type. -both of which have the same behavior as the original declaration. The behavior is -undefined unless the objects in the array pointed to by \tcode{base} are of trivial type. +\pnum +\effects +These functions have the semantics specified in the C standard library. -\enternote -Because the function argument \tcode{compar()} may throw an exception, -\tcode{bsearch()} -and -\tcode{qsort()} -are allowed to propagate the exception~(\ref{res.on.exception.handling}). -\exitnote +\pnum +\throws +Any exception thrown by \tcode{compar}\iref{res.on.exception.handling}. +\end{itemdescr} -\xref -ISO C 7.10.5. +\xrefc{7.24.6} diff --git a/source/assets/example_01.pdf b/source/assets/example_01.pdf new file mode 100644 index 0000000000..2d4c06ffe4 Binary files /dev/null and b/source/assets/example_01.pdf differ diff --git a/source/assets/example_01.tex b/source/assets/example_01.tex new file mode 100644 index 0000000000..ffda6ec746 --- /dev/null +++ b/source/assets/example_01.tex @@ -0,0 +1,14 @@ +\documentclass[9pt]{standalone} + +\usepackage{fontspec} + +\setmainfont{NewCM10-Regular} +\setmonofont{NewCMMono10-Regular} + +\newfontfamily\notoemoji{Noto Color Emoji}[Renderer=HarfBuzz] + +\newcommand{\emo}[1]{{\notoemoji\raisebox{1pt}{\scriptsize #1}}} + +\begin{document} +\texttt{Спасибо, Виктор \emo{♥}!} +\end{document} diff --git a/source/assets/example_02.pdf b/source/assets/example_02.pdf new file mode 100644 index 0000000000..65a9fb12f9 Binary files /dev/null and b/source/assets/example_02.pdf differ diff --git a/source/assets/example_02.tex b/source/assets/example_02.tex new file mode 100644 index 0000000000..0b48a5aacc --- /dev/null +++ b/source/assets/example_02.tex @@ -0,0 +1,14 @@ +\documentclass[9pt]{standalone} + +\usepackage{fontspec} + +\setmainfont{NewCM10-Regular} +\setmonofont{NewCMMono10-Regular} + +\newfontfamily\notoemoji{Noto Color Emoji}[Renderer=HarfBuzz] + +\newcommand{\emo}[1]{{\notoemoji\scriptsize #1}} + +\begin{document} +\emo{🤷🏻‍♂️} +\end{document} diff --git a/source/assets/example_03.pdf b/source/assets/example_03.pdf new file mode 100644 index 0000000000..74f7bd263c Binary files /dev/null and b/source/assets/example_03.pdf differ diff --git a/source/assets/example_03.tex b/source/assets/example_03.tex new file mode 100644 index 0000000000..17479d4b6d --- /dev/null +++ b/source/assets/example_03.tex @@ -0,0 +1,14 @@ +\documentclass[9pt]{standalone} + +\usepackage{fontspec} + +\setmainfont{NewCM10-Regular} +\setmonofont{NewCMMono10-Regular} + +\newfontfamily\notoemoji{Noto Color Emoji}[Renderer=HarfBuzz] + +\newcommand{\emo}[1]{{\notoemoji\scriptsize #1}} + +\begin{document} +\emo{🤷} +\end{document} diff --git a/source/assets/example_04.pdf b/source/assets/example_04.pdf new file mode 100644 index 0000000000..b02c6214d2 Binary files /dev/null and b/source/assets/example_04.pdf differ diff --git a/source/assets/example_04.tex b/source/assets/example_04.tex new file mode 100644 index 0000000000..414cdf0822 --- /dev/null +++ b/source/assets/example_04.tex @@ -0,0 +1,14 @@ +\documentclass[9pt]{standalone} + +\usepackage{fontspec} + +\setmainfont{NewCM10-Regular} +\setmonofont{NewCMMono10-Regular} + +\newfontfamily\notoemoji{Noto Color Emoji}[Renderer=HarfBuzz] + +\newcommand{\emo}[1]{{\notoemoji\scriptsize #1}} + +\begin{document} +\emo{♂} +\end{document} diff --git a/source/assets/example_05.pdf b/source/assets/example_05.pdf new file mode 100644 index 0000000000..047d45a9b3 Binary files /dev/null and b/source/assets/example_05.pdf differ diff --git a/source/assets/example_05.tex b/source/assets/example_05.tex new file mode 100644 index 0000000000..109eb45f3f --- /dev/null +++ b/source/assets/example_05.tex @@ -0,0 +1,14 @@ +\documentclass[9pt]{standalone} + +\usepackage{fontspec} + +\setmainfont{NewCM10-Regular} +\setmonofont{NewCMMono10-Regular} + +\newfontfamily\notoemoji{Noto Color Emoji}[Renderer=HarfBuzz] + +\newcommand{\emo}[1]{{\notoemoji\scriptsize #1}} + +\begin{document} +\emo{🤡} +\end{document} diff --git a/source/assets/example_06.pdf b/source/assets/example_06.pdf new file mode 100644 index 0000000000..5d8f5392da Binary files /dev/null and b/source/assets/example_06.pdf differ diff --git a/source/assets/example_06.tex b/source/assets/example_06.tex new file mode 100644 index 0000000000..f63b99cc89 --- /dev/null +++ b/source/assets/example_06.tex @@ -0,0 +1,10 @@ +\documentclass[9pt]{standalone} + +\usepackage{fontspec} + +\setmainfont{NewCM10-Regular} +\setmonofont{NewCMMono10-Regular} + +\begin{document} +\texttt{ẹ́} +\end{document} diff --git a/source/figdag.dot b/source/assets/figdag.dot similarity index 100% rename from source/figdag.dot rename to source/assets/figdag.dot diff --git a/source/assets/figdag.pdf b/source/assets/figdag.pdf new file mode 100644 index 0000000000..26c743ece5 Binary files /dev/null and b/source/assets/figdag.pdf differ diff --git a/source/figname.dot b/source/assets/figname.dot similarity index 100% rename from source/figname.dot rename to source/assets/figname.dot diff --git a/source/assets/figname.pdf b/source/assets/figname.pdf new file mode 100644 index 0000000000..a7f5bd30c0 Binary files /dev/null and b/source/assets/figname.pdf differ diff --git a/source/fignonvirt.dot b/source/assets/fignonvirt.dot similarity index 100% rename from source/fignonvirt.dot rename to source/assets/fignonvirt.dot diff --git a/source/assets/fignonvirt.pdf b/source/assets/fignonvirt.pdf new file mode 100644 index 0000000000..302424c78a Binary files /dev/null and b/source/assets/fignonvirt.pdf differ diff --git a/source/figvirt.dot b/source/assets/figvirt.dot similarity index 100% rename from source/figvirt.dot rename to source/assets/figvirt.dot diff --git a/source/assets/figvirt.pdf b/source/assets/figvirt.pdf new file mode 100644 index 0000000000..ddbbeb3176 Binary files /dev/null and b/source/assets/figvirt.pdf differ diff --git a/source/figvirtnonvirt.dot b/source/assets/figvirtnonvirt.dot similarity index 100% rename from source/figvirtnonvirt.dot rename to source/assets/figvirtnonvirt.dot diff --git a/source/assets/figvirtnonvirt.pdf b/source/assets/figvirtnonvirt.pdf new file mode 100644 index 0000000000..5591593dc5 Binary files /dev/null and b/source/assets/figvirtnonvirt.pdf differ diff --git a/source/assets/iso-logo-caution.png b/source/assets/iso-logo-caution.png new file mode 100644 index 0000000000..49b12792b8 Binary files /dev/null and b/source/assets/iso-logo-caution.png differ diff --git a/source/valuecategories.dot b/source/assets/valuecategories.dot similarity index 100% rename from source/valuecategories.dot rename to source/assets/valuecategories.dot diff --git a/source/assets/valuecategories.pdf b/source/assets/valuecategories.pdf new file mode 100644 index 0000000000..3cff95520a Binary files /dev/null and b/source/assets/valuecategories.pdf differ diff --git a/source/atomics.tex b/source/atomics.tex deleted file mode 100644 index dce734a0bb..0000000000 --- a/source/atomics.tex +++ /dev/null @@ -1,1355 +0,0 @@ -%!TEX root = std.tex -\rSec0[atomics]{Atomic operations library} - -\rSec1[atomics.general]{General} - -\pnum -This Clause describes components for fine-grained atomic access. This access is -provided via operations on atomic objects. - -\pnum -The following subclauses describe atomics requirements and components for types -and operations, as summarized below. - -\begin{libsumtab}{Atomics library summary}{tab:atomics.lib.summary} -\ref{atomics.order} & Order and Consistency & - \\ -\ref{atomics.lockfree} & Lock-free Property & - \\ -\ref{atomics.types.generic} & Atomic Types & \tcode{} - \\ -\ref{atomics.types.operations} & Operations on Atomic Types & - \\ -\ref{atomics.flag} & Flag Type and Operations & - \\ -\ref{atomics.fences} & Fences & - \\ -\end{libsumtab} - -\rSec1[atomics.syn]{Header \tcode{} synopsis} - -\indexlibrary{\idxhdr{atomic}}% -\begin{codeblock} -namespace std { - // \ref{atomics.order}, order and consistency - enum memory_order; - template - T kill_dependency(T y) noexcept; - - // \ref{atomics.lockfree}, lock-free property - #define ATOMIC_BOOL_LOCK_FREE @\unspec@ - #define ATOMIC_CHAR_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@ - - // \ref{atomics.types.generic}, generic types - template struct atomic; - template<> struct atomic<@\textit{integral}@>; - template struct atomic; - - // \ref{atomics.types.operations.general}, general operations on atomic types - // In the following declarations, \textit{atomic-type} is either - // \tcode{atomic} or a named base class for \tcode{T} from - // Table~\ref{tab:atomics.integral} or inferred from Table~\ref{tab:atomics.typedefs} or from \tcode{bool}. - // If it is \tcode{atomic}, then the declaration is a template - // declaration prefixed with \tcode{template }. - bool atomic_is_lock_free(const volatile @\textit{atomic-type}@*) noexcept; - bool atomic_is_lock_free(const @\textit{atomic-type}@*) noexcept; - void atomic_init(volatile @\textit{atomic-type}@*, T) noexcept; - void atomic_init(@\textit{atomic-type}@*, T) noexcept; - void atomic_store(volatile @\textit{atomic-type}@*, T) noexcept; - void atomic_store(@\textit{atomic-type}@*, T) noexcept; - void atomic_store_explicit(volatile @\textit{atomic-type}@*, T, memory_order) noexcept; - void atomic_store_explicit(@\textit{atomic-type}@*, T, memory_order) noexcept; - T atomic_load(const volatile @\textit{atomic-type}@*) noexcept; - T atomic_load(const @\textit{atomic-type}@*) noexcept; - T atomic_load_explicit(const volatile @\textit{atomic-type}@*, memory_order) noexcept; - T atomic_load_explicit(const @\textit{atomic-type}@*, memory_order) noexcept; - T atomic_exchange(volatile @\textit{atomic-type}@*, T) noexcept; - T atomic_exchange(@\textit{atomic-type}@*, T) noexcept; - T atomic_exchange_explicit(volatile @\textit{atomic-type}@*, T, memory_order) noexcept; - T atomic_exchange_explicit(@\textit{atomic-type}@*, T, memory_order) noexcept; - bool atomic_compare_exchange_weak(volatile @\textit{atomic-type}@*, T*, T) noexcept; - bool atomic_compare_exchange_weak(@\textit{atomic-type}@*, T*, T) noexcept; - bool atomic_compare_exchange_strong(volatile @\textit{atomic-type}@*, T*, T) noexcept; - bool atomic_compare_exchange_strong(@\textit{atomic-type}@*, T*, T) noexcept; - bool atomic_compare_exchange_weak_explicit(volatile @\textit{atomic-type}@*, T*, T, - memory_order, memory_order) noexcept; - bool atomic_compare_exchange_weak_explicit(@\textit{atomic-type}@*, T*, T, - memory_order, memory_order) noexcept; - bool atomic_compare_exchange_strong_explicit(volatile @\textit{atomic-type}@*, T*, T, - memory_order, memory_order) noexcept; - bool atomic_compare_exchange_strong_explicit(@\textit{atomic-type}@*, T*, T, - memory_order, memory_order) noexcept; - - // \ref{atomics.types.operations.templ}, templated operations on atomic types - template - T atomic_fetch_add(volatile @atomic@*, T) noexcept; - template - T atomic_fetch_add(@atomic@*, T) noexcept; - template - T atomic_fetch_add_explicit(volatile atomic*, T, memory_order) noexcept; - template - T atomic_fetch_add_explicit(atomic*, T, memory_order) noexcept; - template - T atomic_fetch_sub(volatile atomic*, T) noexcept; - template - T atomic_fetch_sub(atomic*, T) noexcept; - template - T atomic_fetch_sub_explicit(volatile atomic*, T, memory_order) noexcept; - template - T atomic_fetch_sub_explicit(atomic*, T, memory_order) noexcept; - template - T atomic_fetch_and(volatile atomic*, T) noexcept; - template - T atomic_fetch_and(atomic*, T) noexcept; - template - T atomic_fetch_and_explicit(volatile atomic*, T, memory_order) noexcept; - template - T atomic_fetch_and_explicit(atomic*, T, memory_order) noexcept; - template - T atomic_fetch_or(volatile atomic*, T) noexcept; - template - T atomic_fetch_or(atomic*, T) noexcept; - template - T atomic_fetch_or_explicit(volatile atomic*, T, memory_order) noexcept; - template - T atomic_fetch_or_explicit(atomic*, T, memory_order) noexcept; - template - T atomic_fetch_xor(volatile atomic*, T) noexcept; - template - T atomic_fetch_xor(atomic*, T) noexcept; - template - T atomic_fetch_xor_explicit(volatile atomic*, T, memory_order) noexcept; - template - T atomic_fetch_xor_explicit(atomic*, T, memory_order) noexcept; - - // \ref{atomics.types.operations.arith}, arithmetic operations on atomic types - // In the following declarations, \textit{atomic-integral} is either - // \tcode{atomic} or a named base class for \tcode{T} from - // Table~\ref{tab:atomics.integral} or inferred from Table~\ref{tab:atomics.typedefs}. - // If it is \tcode{atomic}, then the declaration is a template - // specialization declaration prefixed with \tcode{template <>}. - - @\textit{integral}@ atomic_fetch_add(volatile @\textit{atomic-integral}@*, @\textit{integral}@) noexcept; - @\textit{integral}@ atomic_fetch_add(@\textit{atomic-integral}@*, @\textit{integral}@) noexcept; - @\textit{integral}@ atomic_fetch_add_explicit(volatile @\textit{atomic-integral}@*, @\textit{integral}@, memory_order) noexcept; - @\textit{integral}@ atomic_fetch_add_explicit(@\textit{atomic-integral}@*, @\textit{integral}@, memory_order) noexcept; - @\textit{integral}@ atomic_fetch_sub(volatile @\textit{atomic-integral}@*, @\textit{integral}@) noexcept; - @\textit{integral}@ atomic_fetch_sub(@\textit{atomic-integral}@*, @\textit{integral}@) noexcept; - @\textit{integral}@ atomic_fetch_sub_explicit(volatile @\textit{atomic-integral}@*, @\textit{integral}@, memory_order) noexcept; - @\textit{integral}@ atomic_fetch_sub_explicit(@\textit{atomic-integral}@*, @\textit{integral}@, memory_order) noexcept; - @\textit{integral}@ atomic_fetch_and(volatile @\textit{atomic-integral}@*, @\textit{integral}@) noexcept; - @\textit{integral}@ atomic_fetch_and(@\textit{atomic-integral}@*, @\textit{integral}@) noexcept; - @\textit{integral}@ atomic_fetch_and_explicit(volatile @\textit{atomic-integral}@*, @\textit{integral}@, memory_order) noexcept; - @\textit{integral}@ atomic_fetch_and_explicit(@\textit{atomic-integral}@*, @\textit{integral}@, memory_order) noexcept; - @\textit{integral}@ atomic_fetch_or(volatile @\textit{atomic-integral}@*, @\textit{integral}@) noexcept; - @\textit{integral}@ atomic_fetch_or(@\textit{atomic-integral}@*, @\textit{integral}@) noexcept; - @\textit{integral}@ atomic_fetch_or_explicit(volatile @\textit{atomic-integral}@*, @\textit{integral}@, memory_order) noexcept; - @\textit{integral}@ atomic_fetch_or_explicit(@\textit{atomic-integral}@*, @\textit{integral}@, memory_order) noexcept; - @\textit{integral}@ atomic_fetch_xor(volatile @\textit{atomic-integral}@*, @\textit{integral}@) noexcept; - @\textit{integral}@ atomic_fetch_xor(@\textit{atomic-integral}@*, @\textit{integral}@) noexcept; - @\textit{integral}@ atomic_fetch_xor_explicit(volatile @\textit{atomic-integral}@*, @\textit{integral}@, memory_order) noexcept; - @\textit{integral}@ atomic_fetch_xor_explicit(@\textit{atomic-integral}@*, @\textit{integral}@, memory_order) noexcept; - - // \ref{atomics.types.operations.pointer}, partial specializations for pointers - - template - T* atomic_fetch_add(volatile atomic*, ptrdiff_t) noexcept; - template - T* atomic_fetch_add(atomic*, ptrdiff_t) noexcept; - template - T* atomic_fetch_add_explicit(volatile atomic*, ptrdiff_t, memory_order) noexcept; - template - T* atomic_fetch_add_explicit(atomic*, ptrdiff_t, memory_order) noexcept; - template - T* atomic_fetch_sub(volatile atomic*, ptrdiff_t) noexcept; - template - T* atomic_fetch_sub(atomic*, ptrdiff_t) noexcept; - template - T* atomic_fetch_sub_explicit(volatile atomic*, ptrdiff_t, memory_order) noexcept; - template - T* atomic_fetch_sub_explicit(atomic*, ptrdiff_t, memory_order) noexcept; - - // \ref{atomics.types.operations.req}, initialization - #define ATOMIC_VAR_INIT(value) @\seebelow@ - - // \ref{atomics.flag}, flag type and operations - struct atomic_flag; - bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept; - bool atomic_flag_test_and_set(atomic_flag*) noexcept; - bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order) noexcept; - bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order) noexcept; - void atomic_flag_clear(volatile atomic_flag*) noexcept; - void atomic_flag_clear(atomic_flag*) noexcept; - void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept; - void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept; - #define ATOMIC_FLAG_INIT @\seebelow@ - - // \ref{atomics.fences}, fences - extern "C" void atomic_thread_fence(memory_order) noexcept; - extern "C" void atomic_signal_fence(memory_order) noexcept; -} -\end{codeblock} - -\rSec1[atomics.order]{Order and consistency} - -\begin{codeblock} -namespace std { - typedef enum memory_order { - memory_order_relaxed, memory_order_consume, memory_order_acquire, - memory_order_release, memory_order_acq_rel, memory_order_seq_cst - } memory_order; -} -\end{codeblock} - -\pnum -The enumeration \tcode{memory_order} specifies the detailed regular -(non-atomic) memory synchronization order as defined in -\ref{intro.multithread} and may provide for operation ordering. Its -enumerated values and their meanings are as follows: - -\begin{itemize} -\item \tcode{memory_order_relaxed}: no operation orders memory. - -\item \tcode{memory_order_release}, \tcode{memory_order_acq_rel}, and -\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. - -\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. -\end{itemize} - -\enternote Atomic operations specifying \tcode{memory_order_relaxed} are relaxed -with respect to memory ordering. Implementations must still guarantee that any -given atomic access to a particular atomic object be indivisible with respect -to all other atomic accesses to that object. \exitnote - -\pnum -An atomic operation \term{A} that performs a release operation on an atomic -object \term{M} synchronizes with an atomic operation \term{B} that performs -an acquire operation on \term{M} and takes its value from any side effect in the -release sequence headed by \term{A}. - -\pnum -There shall be a single total order \textit{S} on all \tcode{memory_order_seq_cst} -operations, consistent with the ``happens before'' order and modification orders for all -affected locations, such that each \tcode{memory_order_seq_cst} operation -\textit{B} that loads a -value from an atomic object \textit{M} -observes one of the following values: - -\begin{itemize} -\item the result of the last modification \textit{A} of \textit{M} that precedes -\textit{B} in \textit{S}, if it exists, or - -\item if \textit{A} exists, the result of some modification of \textit{M} -that is not -\tcode{memory_order_seq_cst} and that does not happen before \textit{A}, or - -\item if \textit{A} does not exist, the result of some modification of \textit{M} -that is not -\tcode{memory_order_seq_cst}. -\end{itemize} - -\enternote Although it is not explicitly required that \textit{S} include locks, it can -always be extended to an order that does include lock and unlock operations, since the -ordering between those is already included in the ``happens before'' ordering. \exitnote - -\pnum -For an atomic operation \textit{B} that reads the value of an atomic object \textit{M}, -if there is a \tcode{memory_order_seq_cst} fence \textit{X} sequenced before \textit{B}, -then \textit{B} observes either the last \tcode{memory_order_seq_cst} modification of -\textit{M} preceding \textit{X} in the total order \textit{S} or a later modification of -\textit{M} in its modification order. - -\pnum -For atomic operations \textit{A} and \textit{B} on an atomic object \textit{M}, where -\textit{A} modifies \textit{M} and \textit{B} takes its value, if there is a -\tcode{memory_order_seq_cst} fence \textit{X} such that \textit{A} is sequenced before -\textit{X} and \textit{B} follows \textit{X} in \textit{S}, then \textit{B} observes -either the effects of \textit{A} or a later modification of \textit{M} in its -modification order. - -\pnum -For atomic operations \textit{A} and \textit{B} on an atomic object \textit{M}, where -\textit{A} modifies \textit{M} and \textit{B} takes its value, if there are -\tcode{memory_order_seq_cst} fences \textit{X} and \textit{Y} such that \textit{A} is -sequenced before \textit{X}, \textit{Y} is sequenced before \textit{B}, and \textit{X} -precedes \textit{Y} in \textit{S}, then \textit{B} observes either the effects of -\textit{A} or a later modification of \textit{M} in its modification order. - -\pnum -For atomic modifications \textit{A} and \textit{B} of an atomic object \textit{M}, -\textit{B} occurs later than \textit{A} in the modification order of \textit{M} if: - -\begin{itemize} -\item there is a \tcode{memory_order_seq_cst} fence \textit{X} such that \textit{A} -is sequenced before \textit{X}, and \textit{X} precedes \textit{B} in \textit{S}, or -\item there is a \tcode{memory_order_seq_cst} fence \textit{Y} such that \textit{Y} -is sequenced before \textit{B}, and \textit{A} precedes \textit{Y} in \textit{S}, or -\item there are \tcode{memory_order_seq_cst} fences \textit{X} and \textit{Y} such that \textit{A} -is sequenced before \textit{X}, \textit{Y} is sequenced before \textit{B}, -and \textit{X} precedes \textit{Y} in \textit{S}. -\end{itemize} - - -\pnum -\enternote \tcode{memory_order_seq_cst} ensures sequential consistency only for a -program that is free of data races and uses exclusively \tcode{memory_order_seq_cst} -operations. Any use of weaker ordering will invalidate this guarantee unless extreme -care is used. In particular, \tcode{memory_order_seq_cst} fences ensure a total order -only for the fences themselves. Fences cannot, in general, be used to restore sequential -consistency for atomic operations with weaker ordering specifications. \exitnote - -\pnum -Implementations should ensure that no ``out-of-thin-air'' values are computed that -circularly depend on their own computation. - -\enternote For example, with \tcode{x} and \tcode{y} initially zero, - -\begin{codeblock} -// Thread 1: -r1 = y.load(memory_order_relaxed); -x.store(r1, memory_order_relaxed); -\end{codeblock} - -\begin{codeblock} -// Thread 2: -r2 = x.load(memory_order_relaxed); -y.store(r2, memory_order_relaxed); -\end{codeblock} - -should not produce \tcode{r1 == r2 == 42}, since the store of 42 to \tcode{y} is only -possible if the store to \tcode{x} stores \tcode{42}, which circularly depends on the -store to \tcode{y} storing \tcode{42}. Note that without this restriction, such an -execution is possible. -\exitnote - -\pnum -\enternote The recommendation similarly disallows \tcode{r1 == r2 == 42} in the -following example, with \tcode{x} and \tcode{y} again initially zero: - -\begin{codeblock} -// Thread 1: -r1 = x.load(memory_order_relaxed); -if (r1 == 42) y.store(42, memory_order_relaxed); -\end{codeblock} - -\begin{codeblock} -// Thread 2: -r2 = y.load(memory_order_relaxed); -if (r2 == 42) x.store(42, memory_order_relaxed); -\end{codeblock} - -\exitnote - -\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. - -\pnum -Implementations should make atomic stores visible to atomic loads within a reasonable -amount of time. - -\indexlibrary{\idxcode{kill_dependency}}% -\begin{itemdecl} -template - T kill_dependency(T y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects The argument does not carry a dependency to the return -value~(\ref{intro.multithread}). - -\pnum -\returns \tcode{y}. -\end{itemdescr} - - -\rSec1[atomics.lockfree]{Lock-free property} - -\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_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@ -\end{codeblock} - -\pnum -The \tcode{ATOMIC_..._LOCK_FREE} macros indicate the lock-free property of the -corresponding atomic types, with the signed and unsigned variants grouped -together. The properties also apply to the corresponding (partial) specializations of the -\tcode{atomic} template. A value of 0 indicates that the types are never -lock-free. A value of 1 indicates that the types are sometimes lock-free. A -value of 2 indicates that the types are always lock-free. - -\pnum -The function \tcode{atomic_is_lock_free}~(\ref{atomics.types.operations}) -indicates whether the object is lock-free. In any given program execution, the -result of the lock-free query shall be consistent for all pointers of the same -type. - -\pnum -\enternote Operations that are lock-free should also be address-free. That is, -atomic operations on the same memory location via two different addresses will -communicate atomically. The implementation should not depend on any -per-process state. This restriction enables communication by memory that is -mapped into a process more than once and by memory that is shared between two -processes. \exitnote - -\rSec1[atomics.types.generic]{Atomic types} - -\begin{codeblock} -namespace std { - template struct atomic { - bool is_lock_free() const volatile noexcept; - bool is_lock_free() const noexcept; - void store(T, memory_order = memory_order_seq_cst) volatile noexcept; - void store(T, memory_order = memory_order_seq_cst) noexcept; - T load(memory_order = memory_order_seq_cst) const volatile noexcept; - T load(memory_order = memory_order_seq_cst) const noexcept; - operator T() const volatile noexcept; - operator T() const noexcept; - T exchange(T, memory_order = memory_order_seq_cst) volatile noexcept; - T exchange(T, memory_order = memory_order_seq_cst) noexcept; - bool compare_exchange_weak(T&, T, memory_order, memory_order) volatile noexcept; - bool compare_exchange_weak(T&, T, memory_order, memory_order) noexcept; - bool compare_exchange_strong(T&, T, memory_order, memory_order) volatile noexcept; - bool compare_exchange_strong(T&, T, memory_order, memory_order) noexcept; - bool compare_exchange_weak(T&, T, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_weak(T&, T, memory_order = memory_order_seq_cst) noexcept; - bool compare_exchange_strong(T&, T, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_strong(T&, T, memory_order = memory_order_seq_cst) noexcept; - - atomic() noexcept = default; - constexpr atomic(T) noexcept; - atomic(const atomic&) = delete; - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; - T operator=(T) volatile noexcept; - T operator=(T) noexcept; - }; - - template <> struct atomic<@\textit{integral}@> { - bool is_lock_free() const volatile noexcept; - bool is_lock_free() const noexcept; - void store(@\textit{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - void store(@\textit{integral}@, memory_order = memory_order_seq_cst) noexcept; - @\textit{integral}@ load(memory_order = memory_order_seq_cst) const volatile noexcept; - @\textit{integral}@ load(memory_order = memory_order_seq_cst) const noexcept; - operator @\textit{integral()}@ const volatile noexcept; - operator @\textit{integral()}@ const noexcept; - @\textit{integral}@ exchange(@\textit{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\textit{integral}@ exchange(@\textit{integral}@, memory_order = memory_order_seq_cst) noexcept; - bool compare_exchange_weak(@\textit{integral}@&, @\textit{integral}@, memory_order, memory_order) volatile noexcept; - bool compare_exchange_weak(@\textit{integral}@&, @\textit{integral}@, memory_order, memory_order) noexcept; - bool compare_exchange_strong(@\textit{integral}@&, @\textit{integral}@, memory_order, memory_order) volatile noexcept; - bool compare_exchange_strong(@\textit{integral}@&, @\textit{integral}@, memory_order, memory_order) noexcept; - bool compare_exchange_weak(@\textit{integral}@&, @\textit{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_weak(@\textit{integral}@&, @\textit{integral}@, memory_order = memory_order_seq_cst) noexcept; - bool compare_exchange_strong(@\textit{integral}@&, @\textit{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_strong(@\textit{integral}@&, @\textit{integral}@, memory_order = memory_order_seq_cst) noexcept; - @\textit{integral}@ fetch_add(@\textit{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\textit{integral}@ fetch_add(@\textit{integral}@, memory_order = memory_order_seq_cst) noexcept; - @\textit{integral}@ fetch_sub(@\textit{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\textit{integral}@ fetch_sub(@\textit{integral}@, memory_order = memory_order_seq_cst) noexcept; - @\textit{integral}@ fetch_and(@\textit{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\textit{integral}@ fetch_and(@\textit{integral}@, memory_order = memory_order_seq_cst) noexcept; - @\textit{integral}@ fetch_or(@\textit{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\textit{integral}@ fetch_or(@\textit{integral}@, memory_order = memory_order_seq_cst) noexcept; - @\textit{integral}@ fetch_xor(@\textit{integral}@, memory_order = memory_order_seq_cst) volatile noexcept; - @\textit{integral}@ fetch_xor(@\textit{integral}@, memory_order = memory_order_seq_cst) noexcept; - - atomic() noexcept = default; - constexpr atomic(@\textit{integral}@) noexcept; - atomic(const atomic&) = delete; - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; - @\textit{integral}@ operator=(@\textit{integral}@) volatile noexcept; - @\textit{integral}@ operator=(@\textit{integral}@) noexcept; - - @\textit{integral}@ operator++(int) volatile noexcept; - @\textit{integral}@ operator++(int) noexcept; - @\textit{integral}@ operator--(int) volatile noexcept; - @\textit{integral}@ operator--(int) noexcept; - @\textit{integral}@ operator++() volatile noexcept; - @\textit{integral}@ operator++() noexcept; - @\textit{integral}@ operator--() volatile noexcept; - @\textit{integral}@ operator--() noexcept; - @\textit{integral}@ operator+=(@\textit{integral}@) volatile noexcept; - @\textit{integral}@ operator+=(@\textit{integral}@) noexcept; - @\textit{integral}@ operator-=(@\textit{integral}@) volatile noexcept; - @\textit{integral}@ operator-=(@\textit{integral}@) noexcept; - @\textit{integral}@ operator&=(@\textit{integral}@) volatile noexcept; - @\textit{integral}@ operator&=(@\textit{integral}@) noexcept; - @\textit{integral}@ operator|=(@\textit{integral}@) volatile noexcept; - @\textit{integral}@ operator|=(@\textit{integral}@) noexcept; - @\textit{integral}@ operator^=(@\textit{integral}@) volatile noexcept; - @\textit{integral}@ operator^=(@\textit{integral}@) noexcept; - }; - - template struct atomic { - bool is_lock_free() const volatile noexcept; - bool is_lock_free() const noexcept; - void store(T*, memory_order = memory_order_seq_cst) volatile noexcept; - void store(T*, memory_order = memory_order_seq_cst) noexcept; - T* load(memory_order = memory_order_seq_cst) const volatile noexcept; - T* load(memory_order = memory_order_seq_cst) const noexcept; - operator T*() const volatile noexcept; - operator T*() const noexcept; - T* exchange(T*, memory_order = memory_order_seq_cst) volatile noexcept; - T* exchange(T*, memory_order = memory_order_seq_cst) noexcept; - bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept; - bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept; - bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept; - bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept; - bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) noexcept; - bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept; - bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) noexcept; - T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept; - T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept; - T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept; - T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept; - - atomic() noexcept = default; - constexpr atomic(T*) noexcept; - atomic(const atomic&) = delete; - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; - T* operator=(T*) volatile noexcept; - T* operator=(T*) noexcept; - - T* operator++(int) volatile noexcept; - T* operator++(int) noexcept; - T* operator--(int) volatile noexcept; - T* operator--(int) noexcept; - T* operator++() volatile noexcept; - T* operator++() noexcept; - T* operator--() volatile noexcept; - T* operator--() noexcept; - T* operator+=(ptrdiff_t) volatile noexcept; - T* operator+=(ptrdiff_t) noexcept; - T* operator-=(ptrdiff_t) volatile noexcept; - T* operator-=(ptrdiff_t) noexcept; - }; -} -\end{codeblock} - -\pnum -There is a generic class template \tcode{atomic}. The type of the template argument -\tcode{T} shall be trivially copyable~(\ref{basic.types}). \enternote Type arguments that are -not also statically initializable may be difficult to use. \exitnote - -\pnum -The semantics of the operations on specializations of \tcode{atomic} are defined -in~\ref{atomics.types.operations}. - -\pnum -Specializations and instantiations of the \tcode{atomic} template shall have a deleted copy constructor, a deleted -copy assignment operator, and a constexpr value constructor. - -\pnum -There shall be explicit specializations of the \tcode{atomic} -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}, -\tcode{char16_t}, -\tcode{char32_t}, -\tcode{wchar_t}, -and any other types needed by the typedefs in the header \tcode{}. -For each integral type \textit{integral}, the specialization -\tcode{atomic} provides additional atomic operations appropriate to integral types. -There shall be a specialization \tcode{atomic} which provides the general -atomic operations as specified in \ref{atomics.types.operations.general}. - -\pnum -The atomic integral specializations and the specialization \tcode{atomic} -shall have standard layout. They shall each have a trivial default constructor -and a trivial destructor. They shall each support aggregate initialization -syntax. - -\pnum -There shall be pointer partial specializations of the \tcode{atomic} class template. -These specializations shall have standard layout, trivial default constructors, and trivial destructors. -They shall each support aggregate initialization syntax. - -\pnum -There shall be named types corresponding to the integral specializations of -\tcode{atomic}, as specified in Table~\ref{tab:atomics.integral}, and a named type -\tcode{atomic_bool} corresponding to the specified \tcode{atomic}. Each named -type is either a typedef to the corresponding specialization or a base class of the -corresponding specialization. If it is a base class, it shall support the same -member functions as the corresponding specialization. - -\begin{floattablebase} -{\tcode{atomic} integral typedefs}{tab:atomics.integral}{ll}{ht} -\hline -\textbf{Named type} & \textbf{Integral argument type} \\ \hline -\tcode{atomic_char} & \tcode{char} \\ -\tcode{atomic_schar} & \tcode{signed char} \\ -\tcode{atomic_uchar} & \tcode{unsigned char} \\ -\tcode{atomic_short} & \tcode{short} \\ -\tcode{atomic_ushort} & \tcode{unsigned short} \\ -\tcode{atomic_int} & \tcode{int} \\ -\tcode{atomic_uint} & \tcode{unsigned int} \\ -\tcode{atomic_long} & \tcode{long} \\ -\tcode{atomic_ulong} & \tcode{unsigned long} \\ -\tcode{atomic_llong} & \tcode{long long} \\ -\tcode{atomic_ullong} & \tcode{unsigned long long} \\ -\tcode{atomic_char16_t} & \tcode{char16_t} \\ -\tcode{atomic_char32_t} & \tcode{char32_t} \\ -\tcode{atomic_wchar_t} & \tcode{wchar_t} \\ -\hline -\end{floattablebase} - -\pnum -There shall be atomic typedefs corresponding to the typedefs in the header \tcode{} as -specified in Table~\ref{tab:atomics.typedefs}. - -\begin{floattablebase} -{\tcode{atomic} \tcode{} typedefs}{tab:atomics.typedefs}{ll}{ht} -\hline -\textbf{Atomic typedef} & \textbf{\tcode{} type} \\ \hline -\tcode{atomic_int_least8_t} & \tcode{int_least8_t} \\ -\tcode{atomic_uint_least8_t} & \tcode{uint_least8_t} \\ -\tcode{atomic_int_least16_t} & \tcode{int_least16_t} \\ -\tcode{atomic_uint_least16_t} & \tcode{uint_least16_t} \\ -\tcode{atomic_int_least32_t} & \tcode{int_least32_t} \\ -\tcode{atomic_uint_least32_t} & \tcode{uint_least32_t} \\ -\tcode{atomic_int_least64_t} & \tcode{int_least64_t} \\ -\tcode{atomic_uint_least64_t} & \tcode{uint_least64_t} \\ -\tcode{atomic_int_fast8_t} & \tcode{int_fast8_t} \\ -\tcode{atomic_uint_fast8_t} & \tcode{uint_fast8_t} \\ -\tcode{atomic_int_fast16_t} & \tcode{int_fast16_t} \\ -\tcode{atomic_uint_fast16_t} & \tcode{uint_fast16_t} \\ -\tcode{atomic_int_fast32_t} & \tcode{int_fast32_t} \\ -\tcode{atomic_uint_fast32_t} & \tcode{uint_fast32_t} \\ -\tcode{atomic_int_fast64_t} & \tcode{int_fast64_t} \\ -\tcode{atomic_uint_fast64_t} & \tcode{uint_fast64_t} \\ -\tcode{atomic_intptr_t} & \tcode{intptr_t} \\ -\tcode{atomic_uintptr_t} & \tcode{uintptr_t} \\ -\tcode{atomic_size_t} & \tcode{size_t} \\ -\tcode{atomic_ptrdiff_t} & \tcode{ptrdiff_t} \\ -\tcode{atomic_intmax_t} & \tcode{intmax_t} \\ -\tcode{atomic_uintmax_t} & \tcode{uintmax_t} \\ -\hline -\end{floattablebase} - -\pnum -\enternote The representation of an atomic specialization need not have the same size as its -corresponding argument type. Specializations should have the same size whenever possible, as -this reduces the effort required to port existing code. \exitnote - -\rSec1[atomics.types.operations]{Operations on atomic types} - -\rSec2[atomics.types.operations.general]{General operations on atomic types} - -\pnum -The implementation shall provide the functions and function templates identified as ``general operations -on atomic types'' in~\ref{atomics.syn}. - -\pnum -In the declarations of these functions and function templates, the name -\textit{atomic-type} refers to either \tcode{atomic} or to a named base class for \tcode{T} -from Table~\ref{tab:atomics.integral} or inferred from Table~\ref{tab:atomics.typedefs}. - -\rSec2[atomics.types.operations.templ]{Templated operations on atomic types} - -\pnum -The implementation shall declare but not define the -function templates identified as ``templated operations on atomic types'' in~\ref{atomics.syn}. - -\rSec2[atomics.types.operations.arith]{Arithmetic operations on atomic types} - -\pnum -The implementation shall provide the functions and function template specializations identified as ``arithmetic operations -on atomic types'' in~\ref{atomics.syn}. - -\pnum -In the declarations of these functions and function template specializations, the name \textit{integral} refers to an -integral type and the name \textit{atomic-integral} refers to either -\tcode{atomic<\textit{integral}>} or to a named base class for \tcode{\textit{integral}} from -Table~\ref{tab:atomics.integral} or inferred from Table~\ref{tab:atomics.typedefs}. - -\rSec2[atomics.types.operations.pointer]{Operations on atomic pointer types} - -\pnum -The implementation shall provide the function template specializations -identified as ``partial specializations for pointers'' in~\ref{atomics.syn}. - -\rSec2[atomics.types.operations.req]{Requirements for operations on atomic types} - -\pnum -There are only a few kinds of operations on atomic types, though there are many -instances on those kinds. This section specifies each general kind. The specific -instances are defined in -\ref{atomics.types.generic}, \ref{atomics.types.operations.general}, -\ref{atomics.types.operations.arith}, and \ref{atomics.types.operations.pointer}. - -\pnum -In the following operation definitions: - -\begin{itemize} -\item an \textit{A} refers to one of the atomic types. -\item a \textit{C} refers to its corresponding non-atomic type. -\item an \textit{M} refers to type of the other argument for arithmetic operations. For -integral atomic types, \textit{M} is \textit{C}. For atomic address types, \textit{M} is -\tcode{std::ptrdiff_t}. -\item the non-member functions not ending in \tcode{_explicit} have the semantics of their -corresponding \tcode{_explicit} functions with \tcode{memory_order} arguments of -\tcode{memory_order_seq_cst}. -\end{itemize} - -\pnum -\enternote Many operations are volatile-qualified. The ``volatile as device register'' -semantics have not changed in the standard. This qualification means that volatility is -preserved when applying these operations to volatile objects. It does not mean that -operations on non-volatile objects become volatile. Thus, volatile qualified operations -on non-volatile objects may be merged under some conditions. \exitnote - -\indexlibrary{\idxcode{atomic type}!constructor}% -\begin{itemdecl} -@\textit{A}@::@\textit{A}@() noexcept = default; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -leaves the atomic object in an uninitialized state. -\enternote -These semantics ensure compatibility with C. -\exitnote -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!constructor}% -\begin{itemdecl} -constexpr @\textit{A}@::@\textit{A}@(@\textit{C}@ desired) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Initializes the object with the value \tcode{desired}. -Initialization is not an atomic operation~(\ref{intro.multithread}). -\enternote it is possible to have an access to an atomic object \tcode{A} -race with its construction, for example by communicating the address of the -just-constructed object \tcode{A} to another thread via -\tcode{memory_order_relaxed} operations on a suitable atomic pointer -variable, and then immediately accessing \tcode{A} in the receiving thread. -This results in undefined behavior. \exitnote -\end{itemdescr} - -\begin{itemdecl} -#define 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 is -initialization-compatible with \textit{value}. -\enternote This operation may need to initialize locks. \exitnote -Concurrent access to the variable being initialized, even via an atomic operation, -constitutes a data race. \enterexample -\begin{codeblock} -atomic v = ATOMIC_VAR_INIT(5); -\end{codeblock} -\exitexample -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!\idxcode{atomic_is_lock_free}}% -\indexlibrary{\idxcode{atomic_is_lock_free}!\idxcode{atomic type}}% -\begin{itemdecl} -bool atomic_is_lock_free(const volatile @\textit{A}@* object) noexcept; -bool atomic_is_lock_free(const @\textit{A}@* object) noexcept; -bool @\textit{A}@::is_lock_free() const volatile noexcept; -bool @\textit{A}@::is_lock_free() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns True if the object's operations are lock-free, false otherwise. -\end{itemdescr} - -\begin{itemdecl} -void atomic_init(volatile @\textit{A}@* object, @\textit{C}@ desired) noexcept; -void atomic_init(@\textit{A}@* object, @\textit{C}@ desired) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Non-atomically -initializes \tcode{*object} with value \tcode{desired}. This function shall only be applied -to objects that have been default constructed, and then only once. -\enternote -These semantics ensure compatibility with C. -\exitnote -\enternote -Concurrent access from another thread, even via an atomic operation, constitutes -a data race. -\exitnote - -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!\idxcode{atomic_store}}% -\indexlibrary{\idxcode{atomic_store}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{atomic_store_explicit}}% -\indexlibrary{\idxcode{atomic_store_explicit}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{store}}% -\indexlibrary{\idxcode{store}!\idxcode{atomic type}}% -\begin{itemdecl} -void atomic_store(volatile @\textit{A}@* object, @\textit{C}@ desired) noexcept; -void atomic_store(@\textit{A}@* object, @\textit{C}@ desired) noexcept; -void atomic_store_explicit(volatile @\textit{A}@* object, @\textit{C}@ desired, memory_order order) noexcept; -void atomic_store_explicit(@\textit{A}@* object, @\textit{C}@ desired, memory_order order) noexcept; -void @\textit{A}@::store(@\textit{C}@ desired, memory_order order = memory_order_seq_cst) volatile noexcept; -void @\textit{A}@::store(@\textit{C}@ desired, memory_order order = memory_order_seq_cst) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires The \tcode{order} argument shall not be \tcode{memory_order_consume}, -\tcode{memory_order_acquire}, nor \tcode{memory_order_acq_rel}. - -\pnum -\effects Atomically replaces the value pointed to by \tcode{object} or by \tcode{this} -with the value of \tcode{desired}. Memory is affected according to the value of -\tcode{order}. -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!\idxcode{operator=}}% -\indexlibrary{\idxcode{operator=}!\idxcode{atomic type}}% -\begin{itemdecl} -@\textit{C} \textit{A}@::operator=(@\textit{C}@ desired) volatile noexcept; -@\textit{C}@ @\textit{A}@::operator=(@\textit{C}@ desired) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{store(desired)} - -\pnum -\returns \tcode{desired} -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!\idxcode{atomic_load}}% -\indexlibrary{\idxcode{atomic_load}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{atomic_load_explicit}}% -\indexlibrary{\idxcode{atomic_load_explicit}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{load}}% -\indexlibrary{\idxcode{load}!\idxcode{atomic type}}% -\begin{itemdecl} -@\textit{C}@ atomic_load(const volatile @\textit{A}@* object) noexcept; -@\textit{C}@ atomic_load(const @\textit{A}@* object) noexcept; -@\textit{C}@ atomic_load_explicit(const volatile @\textit{A}@* object, memory_order) noexcept; -@\textit{C}@ atomic_load_explicit(const @\textit{A}@* object, memory_order) noexcept; -@\textit{C}@ @\textit{A}@::load(memory_order order = memory_order_seq_cst) const volatile noexcept; -@\textit{C}@ @\textit{A}@::load(memory_order order = memory_order_seq_cst) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires The \tcode{order} argument shall not be \tcode{memory_order_release} nor \tcode{memory_order_acq_rel}. - -\pnum -\effects Memory is affected according to the value of \tcode{order}. - -\pnum -\returns Atomically returns the value pointed to by \tcode{object} or by \tcode{this}. -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!operator C@\tcode{operator \textit{C}}}% -\indexlibrary{operator C@\tcode{operator \textit{C}}!\idxcode{atomic type}}% -\begin{itemdecl} -@\textit{A}@::operator @\textit{C}@() const volatile noexcept; -@\textit{A}@::operator @\textit{C}@() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{load()} - -\pnum -\returns The result of \tcode{load()}. -\end{itemdescr} - - -\indexlibrary{\idxcode{atomic type}!\idxcode{atomic_exchange}}% -\indexlibrary{\idxcode{atomic_exchange}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{atomic_exchange_explicit}}% -\indexlibrary{\idxcode{atomic_exchange_explicit}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{exchange}}% -\indexlibrary{\idxcode{exchange}!\idxcode{atomic type}}% -\begin{itemdecl} -@\textit{C}@ atomic_exchange(volatile @\textit{A}@* object, @\textit{C}@ desired) noexcept; -@\textit{C}@ atomic_exchange(@\textit{A}@* object, @\textit{C}@ desired) noexcept; -@\textit{C}@ atomic_exchange_explicit(volatile @\textit{A}@* object, @\textit{C}@ desired, memory_order) noexcept; -@\textit{C}@ atomic_exchange_explicit(@\textit{A}@* object, @\textit{C}@ desired, memory_order) noexcept; -@\textit{C}@ @\textit{A}@::exchange(@\textit{C}@ desired, memory_order order = memory_order_seq_cst) volatile noexcept; -@\textit{C}@ @\textit{A}@::exchange(@\textit{C}@ desired, memory_order order = memory_order_seq_cst) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Atomically replaces the value pointed to by \tcode{object} or by \tcode{this} -with \tcode{desired}. -Memory is affected according to the value of \tcode{order}. -These operations are atomic read-modify-write operations~(\ref{intro.multithread}). - -\pnum -\returns Atomically returns the value pointed to by \tcode{object} or by \tcode{this} immediately before the effects. -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!\idxcode{atomic_compare_exchange_weak}}% -\indexlibrary{\idxcode{atomic_compare_exchange_weak}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{atomic_compare_exchange_strong}}% -\indexlibrary{\idxcode{atomic_compare_exchange_strong}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!atomic_compare_exchange_weak_explicit@\tcode{atomic_compare_exchange_weak_-\\explicit}}% -\indexlibrary{\idxcode{atomic_compare_exchange_weak_explicit}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!atomic_compare_exchange_strong_explicit@\tcode{atomic_compare_exchange_strong_-\\explicit}}% -\indexlibrary{\idxcode{atomic_compare_exchange_strong_explicit}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{compare_exchange_weak}}% -\indexlibrary{\idxcode{compare_exchange_weak}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{compare_exchange_strong}}% -\indexlibrary{\idxcode{compare_exchange_strong}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{compare_exchange_weak_explicit}}% -\indexlibrary{\idxcode{compare_exchange_weak_explicit}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{compare_exchange_strong_explicit}}% -\indexlibrary{\idxcode{compare_exchange_strong_explicit}!\idxcode{atomic type}}% -\begin{itemdecl} -bool atomic_compare_exchange_weak(volatile @\textit{A}@* object, @\textit{C}@* expected, @\textit{C}@ desired) noexcept; -bool atomic_compare_exchange_weak(@\textit{A}@* object, @\textit{C}@* expected, @\textit{C}@ desired) noexcept; -bool atomic_compare_exchange_strong(volatile @\textit{A}@* object, @\textit{C}@* expected, @\textit{C}@ desired) noexcept; -bool atomic_compare_exchange_strong(@\textit{A}@* object, @\textit{C}@* expected, @\textit{C}@ desired) noexcept; -bool atomic_compare_exchange_weak_explicit(volatile @\textit{A}@* object, @\textit{C}@* expected, @\textit{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool atomic_compare_exchange_weak_explicit(@\textit{A}@* object, @\textit{C}@* expected, @\textit{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool atomic_compare_exchange_strong_explicit(volatile @\textit{A}@* object, @\textit{C}@* expected, @\textit{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool atomic_compare_exchange_strong_explicit(@\textit{A}@* object, @\textit{C}@* expected, @\textit{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool @\textit{A}@::compare_exchange_weak(@\textit{C}@& expected, @\textit{C}@ desired, - memory_order success, memory_order failure) volatile noexcept; -bool @\textit{A}@::compare_exchange_weak(@\textit{C}@& expected, @\textit{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool @\textit{A}@::compare_exchange_strong(@\textit{C}@& expected, @\textit{C}@ desired, - memory_order success, memory_order failure) volatile noexcept; -bool @\textit{A}@::compare_exchange_strong(@\textit{C}@& expected, @\textit{C}@ desired, - memory_order success, memory_order failure) noexcept; -bool @\textit{A}@::compare_exchange_weak(@\textit{C}@& expected, @\textit{C}@ desired, - memory_order order = memory_order_seq_cst) volatile noexcept; -bool @\textit{A}@::compare_exchange_weak(@\textit{C}@& expected, @\textit{C}@ desired, - memory_order order = memory_order_seq_cst) noexcept; -bool @\textit{A}@::compare_exchange_strong(@\textit{C}@& expected, @\textit{C}@ desired, - memory_order order = memory_order_seq_cst) volatile noexcept; -bool @\textit{A}@::compare_exchange_strong(@\textit{C}@& expected, @\textit{C}@ desired, - memory_order order = memory_order_seq_cst) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires The \tcode{failure} argument shall not be \tcode{memory_order_release} nor -\tcode{memory_order_acq_rel}. The \tcode{failure} argument shall be no stronger than the -\tcode{success} argument. - -\pnum -\effects Atomically, compares the contents of the memory pointed to by \tcode{object} or by \tcode{this} -for equality with that in \tcode{expected}, and if true, replaces the contents of the memory pointed to -by \tcode{object} or by \tcode{this} with that in \tcode{desired}, and if false, updates the -contents of the memory in \tcode{expected} with the contents of the memory pointed to by \tcode{object} or by -\tcode{this}. Further, if the comparison is true, memory is affected according to the -value of \tcode{success}, and if the comparison is false, memory is affected according -to the value of \tcode{failure}. When only one \tcode{memory_order} argument is -supplied, the value of \tcode{success} is \tcode{order}, and the value of -\tcode{failure} is \tcode{order} except that a value of \tcode{memory_order_acq_rel} -shall be replaced by the value \tcode{memory_order_acquire} and a value of -\tcode{memory_order_release} shall be replaced by the value -\tcode{memory_order_relaxed}. If the operation returns \tcode{true}, these -operations are atomic read-modify-write -operations~(\ref{intro.multithread}). Otherwise, these operations are atomic load operations. - -\pnum -\returns The result of the comparison. - -\pnum -\enternote For example, the effect of -\tcode{atomic_compare_exchange_strong} is -\begin{codeblock} -if (memcmp(object, expected, sizeof(*object)) == 0) - memcpy(object, &desired, sizeof(*object)); -else - memcpy(expected, object, sizeof(*object)); -\end{codeblock} -\exitnote -\enterexample the expected use of the compare-and-exchange operations is as follows. The -compare-and-exchange operations will update \tcode{expected} when another iteration of -the loop is needed. -\begin{codeblock} -expected = current.load(); -do { - desired = function(expected); -} while (!current.compare_exchange_weak(expected, desired)); -\end{codeblock} -\exitexample - -\pnum -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 -atomic object. - -\pnum -\note -A weak compare-and-exchange operation may fail spuriously. That is, even when -the contents of memory referred to by \tcode{expected} and \tcode{object} are -equal, it may return false and store back to \tcode{expected} the same memory -contents that were originally there. -\enternote This -spurious failure enables implementation of compare-and-exchange on a broader class of -machines, e.g., load-locked store-conditional machines. A -consequence of spurious failure is that nearly all uses of weak compare-and-exchange -will be in a loop. - -When a compare-and-exchange is in a loop, the weak version will yield better performance -on some platforms. When a weak compare-and-exchange would require a loop and a strong one -would not, the strong one is preferable. -\exitnote - -\pnum -\enternote The \tcode{memcpy} and \tcode{memcmp} semantics of the compare-and-exchange -operations may result in failed comparisons for values that compare equal with -\tcode{operator==} if the underlying type has padding bits, trap bits, or alternate -representations of the same value. Thus, \tcode{compare_exchange_strong} should be used -with extreme care. On the other hand, \tcode{compare_exchange_weak} should converge -rapidly. \exitnote -\end{itemdescr} - -\pnum -The following operations perform arithmetic computations. The key, operator, and computation correspondence is: - -\begin{floattable} -{Atomic arithmetic computations}{tab:atomic.arithmetic.computations}{lll|lll} -\hline -\tcode{Key} & - Op & - Computation & -\tcode{Key} & - Op & - Computation \\ \hline -\tcode{add} & - \tcode{+} & - addition & -\tcode{sub} & - \tcode{-} & - subtraction \\ -\tcode{or} & - \tcode{|} & - bitwise inclusive or & -\tcode{xor} & - \tcode{\^{}} & - bitwise exclusive or \\ -\tcode{and} & - \tcode{\&} & - bitwise and &&&\\\hline -\end{floattable} - -\indexlibrary{\idxcode{atomic type}!\idxcode{atomic_fetch_}}% -\indexlibrary{\idxcode{atomic_fetch_}!\idxcode{atomic type}}% -\indexlibrary{\idxcode{atomic type}!\idxcode{fetch_}}% -\indexlibrary{\idxcode{fetch_}!\idxcode{atomic type}}% -\begin{itemdecl} -@\textit{C}@ atomic_fetch_@\textit{key}@(volatile @\textit{A}@* object, @\textit{M}@ operand) noexcept; -@\textit{C}@ atomic_fetch_@\textit{key}@(@\textit{A}@* object, @\textit{M}@ operand) noexcept; -@\textit{C}@ atomic_fetch_@\textit{key}@_explicit(volatile @\textit{A}@* object, @\textit{M}@ operand, memory_order order) noexcept; -@\textit{C}@ atomic_fetch_@\textit{key}@_explicit(@\textit{A}@* object, @\textit{M}@ operand, memory_order order) noexcept; -@\textit{C}@ @\textit{A}@::fetch_@\textit{key}@(@\textit{M}@ operand, memory_order order = memory_order_seq_cst) volatile noexcept; -@\textit{C}@ @\textit{A}@::fetch_@\textit{key}@(@\textit{M}@ operand, memory_order order = memory_order_seq_cst) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Atomically replaces the value pointed to by \tcode{object} or by -\tcode{this} with the result of the \textit{computation} applied to the -value pointed to by \tcode{object} or by \tcode{this} and the given \tcode{operand}. -Memory is affected according to the value of \tcode{order}. -These operations are atomic read-modify-write operations~(\ref{intro.multithread}). - -\pnum -\returns Atomically, the value pointed to by \tcode{object} or by \tcode{this} immediately before the effects. - -\pnum -\note For signed integer types, arithmetic is defined to use two's complement -representation. There are no undefined results. For address types, the result may be an -undefined address, but the operations otherwise have no undefined behavior. -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!\idxcode{operator "@=}}% -\indexlibrary{\idxcode{operator "@=}!\idxcode{atomic type}}% -\begin{itemdecl} -@\textit{C}@ @\textit{A}@::operator @\textit{op}@=(@\textit{M}@ operand) volatile noexcept; -@\textit{C}@ @\textit{A}@::operator @\textit{op}@=(@\textit{M}@ operand) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{fetch_\textit{key}(operand)} - -\pnum -\returns \tcode{fetch_\textit{key}(operand) op operand} -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!\idxcode{operator++}}% -\indexlibrary{\idxcode{operator++}!\idxcode{atomic type}}% -\begin{itemdecl} -@\textit{C}@ @\textit{A}@::operator++(int) volatile noexcept; -@\textit{C}@ @\textit{A}@::operator++(int) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{fetch_add(1)} -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!\idxcode{operator\dcr}}% -\indexlibrary{\idxcode{operator\dcr}!\idxcode{atomic type}}% -\begin{itemdecl} -@\textit{C}@ @\textit{A}@::operator--(int) volatile noexcept; -@\textit{C}@ @\textit{A}@::operator--(int) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{fetch_sub(1)} -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!\idxcode{operator++}}% -\indexlibrary{\idxcode{operator++}!\idxcode{atomic type}}% -\begin{itemdecl} -@\textit{C}@ @\textit{A}@::operator++() volatile noexcept; -@\textit{C}@ @\textit{A}@::operator++() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{fetch_add(1)} - -\pnum -\returns \tcode{fetch_add(1) + 1} -\end{itemdescr} - -\indexlibrary{\idxcode{atomic type}!\idxcode{operator\dcr}}% -\indexlibrary{\idxcode{operator\dcr}!\idxcode{atomic type}}% -\begin{itemdecl} -@\textit{C}@ @\textit{A}@::operator--() volatile noexcept; -@\textit{C}@ @\textit{A}@::operator--() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{fetch_sub(1)} - -\pnum -\returns \tcode{fetch_sub(1) - 1} -\end{itemdescr} - -\rSec1[atomics.flag]{Flag type and operations} - -\begin{codeblock} -namespace std { - typedef struct atomic_flag { - bool test_and_set(memory_order = memory_order_seq_cst) volatile noexcept; - bool test_and_set(memory_order = memory_order_seq_cst) noexcept; - void clear(memory_order = memory_order_seq_cst) volatile noexcept; - void clear(memory_order = memory_order_seq_cst) noexcept; - - atomic_flag() noexcept = default; - atomic_flag(const atomic_flag&) = delete; - atomic_flag& operator=(const atomic_flag&) = delete; - atomic_flag& operator=(const atomic_flag&) volatile = delete; - } atomic_flag; - - bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept; - bool atomic_flag_test_and_set(atomic_flag*) noexcept; - bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order) noexcept; - bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order) noexcept; - void atomic_flag_clear(volatile atomic_flag*) noexcept; - void atomic_flag_clear(atomic_flag*) noexcept; - void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept; - void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept; - - #define ATOMIC_FLAG_INIT @\seebelow@ -} -\end{codeblock} - -\pnum -The \tcode{atomic_flag} type provides the classic test-and-set functionality. It has two states, set and clear. - -\pnum -Operations on an object of type \tcode{atomic_flag} shall be lock-free. \enternote Hence -the operations should also be address-free. No other type requires lock-free operations, -so the \tcode{atomic_flag} type is the minimum hardware-implemented type needed to -conform to this International standard. The remaining types can be emulated with -\tcode{atomic_flag}, though with less than ideal properties. \exitnote - -\pnum -The \tcode{atomic_flag} type shall have standard layout. It shall have a trivial default constructor, a deleted copy constructor, a deleted copy assignment operator, and a trivial destructor. - -\pnum -The macro \tcode{ATOMIC_FLAG_INIT} shall be defined in such a way that it can be used to initialize an object of type \tcode{atomic_flag} to the -clear state. The macro can be used in the form: -\begin{codeblock} -atomic_flag guard = ATOMIC_FLAG_INIT; -\end{codeblock} -It is unspecified whether the macro can be used in other initialization contexts. -For a complete static-duration object, that initialization shall be static. -Unless initialized with \tcode{ATOMIC_FLAG_INIT}, it is unspecified whether an -\tcode{atomic_flag} object has an initial state of set or clear. - -\indexlibrary{\idxcode{atomic_flag_test_and_set}}% -\indexlibrary{\idxcode{atomic_flag_test_and_set_explicit}}% -\begin{itemdecl} -bool atomic_flag_test_and_set(volatile atomic_flag* object) noexcept; -bool atomic_flag_test_and_set(atomic_flag* object) noexcept; -bool atomic_flag_test_and_set_explicit(volatile atomic_flag* object, memory_order order) noexcept; -bool atomic_flag_test_and_set_explicit(atomic_flag* object, memory_order order) noexcept; -bool atomic_flag::test_and_set(memory_order order = memory_order_seq_cst) volatile noexcept; -bool atomic_flag::test_and_set(memory_order order = memory_order_seq_cst) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Atomically sets the value pointed to by \tcode{object} or by \tcode{this} to true. Memory is affected according to the value of -\tcode{order}. These operations are atomic read-modify-write operations~(\ref{intro.multithread}). - -\pnum -\returns Atomically, the value of the object immediately before the effects. \end{itemdescr} - -\indexlibrary{\idxcode{atomic_flag_clear}}% -\indexlibrary{\idxcode{atomic_flag_clear_explicit}}% -\indexlibrary{\idxcode{atomic_flag}!\idxcode{clear}}% -\indexlibrary{\idxcode{clear}!\idxcode{atomic_flag}}% -\begin{itemdecl} -void atomic_flag_clear(volatile atomic_flag* object) noexcept; -void atomic_flag_clear(atomic_flag* object) noexcept; -void atomic_flag_clear_explicit(volatile atomic_flag* object, memory_order order) noexcept; -void atomic_flag_clear_explicit(atomic_flag* object, memory_order order) noexcept; -void atomic_flag::clear(memory_order order = memory_order_seq_cst) volatile noexcept; -void atomic_flag::clear(memory_order order = memory_order_seq_cst) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires The \tcode{order} argument shall not be \tcode{memory_order_consume}, -\tcode{memory_order_acquire}, nor \tcode{memory_order_acq_rel}. - -\pnum -\effects Atomically sets the value pointed to by \tcode{object} or by \tcode{this} to -false. Memory is affected according to the value of \tcode{order}. -\end{itemdescr} - -\rSec1[atomics.fences]{Fences} - -\pnum -This section introduces synchronization primitives called \term{fences}. Fences can have -acquire semantics, release semantics, or both. A fence with acquire semantics is called -an \term{acquire fence}. A fence with release semantics is called a \term{release -fence}. - -\pnum -A release fence \textit{A} synchronizes with an acquire fence \textit{B} if there exist -atomic operations \textit{X} and \textit{Y}, both operating on some atomic object -\textit{M}, such that \textit{A} is sequenced before \textit{X}, \textit{X} modifies -\textit{M}, \textit{Y} is sequenced before \textit{B}, and \textit{Y} reads the value -written by \textit{X} or a value written by any side effect in the hypothetical release -sequence \textit{X} would head if it were a release operation. - -\pnum -A release fence \textit{A} synchronizes with an atomic operation \textit{B} that -performs an acquire operation on an atomic object \textit{M} if there exists an atomic -operation \textit{X} such that \textit{A} is sequenced before \textit{X}, \textit{X} -modifies \textit{M}, and \textit{B} reads the value written by \textit{X} or a value -written by any side effect in the hypothetical release sequence \textit{X} would head if -it were a release operation. - -\pnum -An atomic operation \textit{A} that is a release operation on an atomic object -\textit{M} synchronizes with an acquire fence \textit{B} if there exists some atomic -operation \textit{X} on \textit{M} such that \textit{X} is sequenced before \textit{B} -and reads the value written by \textit{A} or a value written by any side effect in the -release sequence headed by \textit{A}. - -\indexlibrary{\idxcode{atomic_thread_fence}}% -\begin{itemdecl} -extern "C" void atomic_thread_fence(memory_order order) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects depending on the value of \tcode{order}, this operation: - -\begin{itemize} -\item has no effects, if \tcode{order == memory_order_relaxed}; - -\item is an acquire fence, if \tcode{order == memory_order_acquire || order == -memory_order_consume}; - -\item is a release fence, if \tcode{order == memory_order_release}; - -\item is both an acquire fence and a release fence, if \tcode{order == -memory_order_acq_rel}; - -\item is a sequentially consistent acquire and release fence, if \tcode{order == memory_order_seq_cst}. -\end{itemize} -\end{itemdescr} - -\indexlibrary{\idxcode{atomic_signal_fence}}% -\begin{itemdecl} -extern "C" void atomic_signal_fence(memory_order order) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to \tcode{atomic_thread_fence(order)}, except that -the resulting ordering constraints are established only between a thread and a -signal handler executed in the same thread. - -\pnum -\realnote \tcode{atomic_signal_fence} can be used to specify the order in which actions -performed by the thread become visible to the signal handler. - -\pnum -\realnote compiler optimizations and reorderings of loads and stores are inhibited in -the same way as with \tcode{atomic_thread_fence}, but the hardware fence instructions -that \tcode{atomic_thread_fence} would have inserted are not emitted. -\end{itemdescr} diff --git a/source/back.tex b/source/back.tex index 480d572aa7..03939906da 100644 --- a/source/back.tex +++ b/source/back.tex @@ -1,20 +1,167 @@ %!TEX root = std.tex + +\renewcommand{\leftmark}{\bibname} + +\begin{thebibliography}{99} +% ISO documents in numerical order. +\bibitem{iso4217} + ISO 4217:2015, + \doccite{Codes for the representation of currencies} +\bibitem{iso14882:2023} + ISO/IEC 14882:2023, + \doccite{Programming Languages --- \Cpp{}} +\bibitem{iso14882:2020} + ISO/IEC 14882:2020, + \doccite{Programming Languages --- \Cpp{}} +\bibitem{iso14882:2017} + ISO/IEC 14882:2017, + \doccite{Programming Languages --- \Cpp{}} +\bibitem{iso14882:2014} + ISO/IEC 14882:2014, + \doccite{Information technology --- Programming Languages --- \Cpp{}} +\bibitem{iso14882:2011} + ISO/IEC 14882:2011, + \doccite{Information technology --- Programming Languages --- \Cpp{}} +\bibitem{iso14882:2003} + ISO/IEC 14882:2003, + \doccite{Programming Languages --- \Cpp{}} +\bibitem{iso18661-3} + ISO/IEC TS 18661-3:2015, + \doccite{Information Technology --- + Programming languages, their environments, and system software interfaces --- + Floating-point extensions for C --- Part 3: Interchange and extended types} +% Other international standards. +\bibitem{iana-charset} + IANA Character Sets Database. + Available from:\newline + \url{https://www.iana.org/assignments/character-sets/}, 2021-04-01 +\bibitem{iana-tz} + IANA Time Zone Database. + Available from: \url{https://www.iana.org/time-zones} +\bibitem{unicode-charmap} + Unicode Character Mapping Markup Language [online]. + Edited by Mark Davis and Markus Scherer. Revision 5.0.1; 2017-05-31 + Available from: \url{https://www.unicode.org/reports/tr22/tr22-8.html} +% Literature references. +\bibitem{cpp-r} + Bjarne Stroustrup, + \doccite{The \Cpp{} Programming Language, second edition}, Chapter R\@. + Addison-Wesley Publishing Company, ISBN 0-201-53992-6, copyright \copyright 1991 AT\&T +\bibitem{kr} + Brian W.\ Kernighan and Dennis M.\ Ritchie, + \doccite{The C Programming Language}, Appendix A\@. + Prentice-Hall, 1978, ISBN 0-13-110163-3, copyright \copyright 1978 AT\&T +\bibitem{cpp-lib} + P.\,J.\ Plauger, + \doccite{The Draft Standard \Cpp{} Library}. + Prentice-Hall, ISBN 0-13-117003-1, copyright \copyright 1995 P.\,J.\ Plauger +\bibitem{linalg-stable} + J.\ Demmel, I.\ Dumitriu, and O.\ Holtz, + \doccite{Fast linear algebra is stable}, + Numerische Mathematik 108 (59--91), 2007. +\bibitem{blas1} + C.\,L.\ Lawson, R.\,J.\ Hanson, D.\ Kincaid, and F.\,T.\ Krogh, + \doccite{Basic linear algebra subprograms for Fortran usage}. + ACM Trans.\ Math.\ Soft., Vol.\ 5, pp.\ 308--323, 1979. +\bibitem{blas2} + Jack J.\ Dongarra, Jeremy Du Croz, Sven Hammarling, and Richard J.\ Hanson, + \doccite{An Extended Set of FORTRAN Basic Linear Algebra Subprograms}. + ACM Trans.\ Math.\ Soft., Vol.\ 14, No.\ 1, pp.\ 1--17, Mar.\ 1988. +\bibitem{blas3} + Jack J.\ Dongarra, Jeremy Du Croz, Sven Hammarling, and Iain Duff, + \doccite{A Set of Level 3 Basic Linear Algebra Subprograms}. + ACM Trans.\ Math.\ Soft., Vol.\ 16, No.\ 1, pp.\ 1--17, Mar.\ 1990. +\bibitem{lapack} + E.\ Anderson, Z.\ Bai, C.\ Bischof, S.\ Blackford, J.\ Demmel, J.\ Dongarra, + J.\ Du Croz, A.\ Greenbaum, S.\ Hammarling, A.\ McKenney, and D.\ Sorensen, + \doccite{LAPACK Users' Guide, Third Edition}. + SIAM, Philadelphia, PA, USA, 1999. +\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.\ Clint Whaley, + \doccite{An Updated Set of Basic Linear Algebra Subprograms (BLAS)}. + 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, pp.\ 1901--1909, 1966. +\end{thebibliography} + +% FIXME: For unknown reasons, hanging paragraphs are not indented within our +% glossaries by default. +\let\realglossitem\glossitem +\renewcommand{\glossitem}[4]{\hangpara{4em}{1}\realglossitem{#1}{#2}{#3}{#4}} + +\clearpage +\renewcommand{\glossaryname}{Cross-references} +\renewcommand{\preglossaryhook}{Each clause and subclause label is listed below along with the +corresponding clause or subclause number and page number, in alphabetical order by label.\\} +\twocolglossary +\renewcommand{\leftmark}{\glossaryname} +{ +\raggedright +\printglossary[xrefindex] +} + +\clearpage +\input{xrefdelta} +\renewcommand{\glossaryname}{Cross-references from ISO \CppXVII{}} +\renewcommand{\preglossaryhook}{All clause and subclause labels from +ISO \CppXVII{} (ISO/IEC 14882:2017, \doccite{Programming Languages --- \Cpp{}}) +are present in this document, with the exceptions described below.\\} +\renewcommand{\leftmark}{\glossaryname} +{ +\raggedright +\printglossary[xrefdelta] +} + +\clearpage +\renewcommand{\leftmark}{\indexname} +\renewcommand{\preindexhook}{Constructions whose name appears in \exposid{monospaced italics} are for exposition only.\\} +{ +\raggedright \printindex[generalindex] +} \clearpage -\renewcommand{\indexname}{Index of grammar productions} -\renewcommand{\preindexhook}{The first page number for each entry is the page in the -general text where the grammar production is defined. The second page number is the -corresponding page in the Grammar summary (Annex~\ref{gram}).\\} +\renewcommand{\preindexhook}{The first bold page number for each entry is the page in the +general text where the grammar production is defined. The second bold page number is the +corresponding page in the Grammar summary\iref{gram}. Other page numbers refer to pages where the grammar production is mentioned in the general text.\\} +{ +\raggedright \printindex[grammarindex] +} + +\clearpage +\renewcommand{\preindexhook}{The bold page number for each entry refers to +the page where the synopsis of the header is shown.\\} +{ +\raggedright +\printindex[headerindex] +} \clearpage -\renewcommand{\preindexhook}{} -\renewcommand{\indexname}{Index of library names} +\renewcommand{\preindexhook}{Constructions whose name appears in \exposid{italics} are for exposition only.\\} +{ +\raggedright \printindex[libraryindex] +} + +\clearpage +\renewcommand{\preindexhook}{The bold page number for each entry is the page +where the concept is defined. +Other page numbers refer to pages where the concept is mentioned in the general text. +Concepts whose name appears in \exposid{italics} are for exposition only.\\} +{ +\raggedright +\printindex[conceptindex] +} \clearpage -\renewcommand{\preindexhook}{The entries in this section are rough descriptions; exact +\renewcommand{\preindexhook}{The entries in this index are rough descriptions; exact specifications are at the indicated page in the general text.\\} -\renewcommand{\indexname}{Index of implementation-defined behavior} +{ +\raggedright \printindex[impldefindex] +} diff --git a/source/basic.tex b/source/basic.tex index d720097605..c1f58de60a 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -1,158 +1,303 @@ %!TEX root = std.tex -\rSec0[basic]{Basic concepts} +\rSec0[basic]{Basics} -%gram: \rSec1[gram.basic]{Basic concepts} -%gram: +\gramSec[gram.basic]{Basics} -\pnum -\enternote This Clause presents the basic concepts of the \Cpp language. -It explains the difference between an \term{object} and a -\term{name} and how they relate to the value categories for expressions. -It introduces the concepts of a -\term{declaration} and a \term{definition} and presents \Cpp's -notion of \term{type}, \term{scope}, \term{linkage}, and -\term{storage} \term{duration}. The mechanisms for starting and -terminating a program are discussed. Finally, this Clause presents the -\term{fundamental} types of the language and lists the ways of constructing -\term{compound} types from these.\exitnote - -\pnum -\enternote This Clause does not cover concepts that affect only a single -part of the language. Such concepts are discussed in the relevant -Clauses. \exitnote - -\pnum -\indextext{name}% -\indextext{declaration}% +\rSec1[basic.pre]{Preamble} \indextext{type}% \indextext{object}% -\indextext{storage~class}% +\indextext{storage class}% \indextext{scope}% \indextext{linkage}% -\indextext{region!declarative}% -\indextext{entity}% -An \defn{entity} is a value, object, reference, function, enumerator, type, -class member, bit-field, template, template specialization, namespace, parameter -pack, or \tcode{this}. - -\pnum -A \defn{name} is a use of an \grammarterm{identifier}~(\ref{lex.name}), -\grammarterm{operator-function-id}~(\ref{over.oper}), -\grammarterm{literal-operator-id}~(\ref{over.literal}), -\grammarterm{conversion-function-id}~(\ref{class.conv.fct}), or -\grammarterm{template-id}~(\ref{temp.names}) that denotes an entity or -\grammarterm{label}~(\ref{stmt.goto}, \ref{stmt.label}). \pnum -Every name that denotes an entity is introduced by a -\term{declaration}. Every name that denotes a label is introduced -either by a \tcode{goto} statement~(\ref{stmt.goto}) or a -\grammarterm{labeled-statement}~(\ref{stmt.label}). +\begin{note} +This Clause presents the basic concepts of the \Cpp{} language. +It explains the difference between an object and a +name and how they relate to the value categories for expressions. +It introduces the concepts of a +declaration and a definition and presents \Cpp{}'s +notion of type, scope, linkage, and +storage duration. The mechanisms for starting and +terminating a program are discussed. Finally, this Clause presents the +fundamental types of the language and lists the ways of constructing +compound types from these. +\end{note} \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. +\begin{note} +This Clause does not cover concepts that affect only a single +part of the language. Such concepts are discussed in the relevant +Clauses. +\end{note} \pnum -Some names denote types or templates. In general, -whenever a name is encountered it is necessary to determine whether that name denotes -one of these entities before continuing to parse the program that contains it. The -process that determines this is called -\indextext{lookup!name}% -\term{name lookup}~(\ref{basic.lookup}). +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 -Two names are \term{the same} if - +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{conversion-function-id}{s} formed -with the same type, or -\item they are \grammarterm{template-id}{s} that refer to the same class, -function, or variable~(\ref{temp.type}), or -\item they are the names of literal operators~(\ref{over.literal}) formed with +\item they are \grammarterm{literal-operator-id}{s} formed with the same literal suffix identifier. \end{itemize} \pnum -\indextext{translation~unit!name~and}% +Every name is introduced by a \defn{declaration}, which is a +\begin{itemize} +\item +\grammarterm{name-declaration}, +\grammarterm{block-declaration}, or +\grammarterm{member-declaration}\iref{dcl.pre,class.mem}, +\item +\grammarterm{init-declarator}\iref{dcl.decl}, +\item +\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}, +\item +\grammarterm{member-declarator}\iref{class.mem}, +\item +\grammarterm{using-declarator}\iref{namespace.udecl}, +\item +\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 +\grammarterm{class-specifier}\iref{class.pre}, +\item +\grammarterm{enum-specifier} or +\grammarterm{enumerator-definition}\iref{dcl.enum}, +\item +\grammarterm{exception-declaration}\iref{except.pre}, or +\item +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} + +\pnum +\begin{note} +Some names denote types or templates. +In general, whenever a name is encountered +it is necessary to look it up\iref{basic.lookup} +to determine whether that name denotes one of these entities +before continuing to parse the program that contains it. +\end{note} + +\pnum +A \defn{variable} is introduced by the +declaration $D$ of +\begin{itemize} +\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}% \indextext{linkage}% A name used in more than one translation unit can potentially refer to the same entity in these translation units depending on the -linkage~(\ref{basic.link}) of the name specified in each +linkage\iref{basic.link} of the name specified in each translation unit. \rSec1[basic.def]{Declarations and definitions} \pnum -\indextext{declaration!definition~versus}% +\indextext{declaration!definition versus}% \indextext{declaration}% \indextext{declaration!name}% -A declaration (Clause~\ref{dcl.dcl}) may introduce -one or more names into a translation -unit or redeclare names introduced by previous declarations. +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 attributes of these names. -A declaration may also have effects including: - +declaration specifies the interpretation and semantic properties of these names. +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 (Clause~\ref{dcl.dcl}), -\item controlling template instantiation~(\ref{temp.explicit}), -\item use of attributes (Clause~\ref{dcl.dcl}), and +\item a static assertion\iref{dcl.pre}, +\item controlling template instantiation\iref{temp.explicit}, +\item guiding template argument deduction for constructors\iref{temp.deduct.guide}, +\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}% -A declaration is a \defn{definition} unless it declares a function -without specifying the function's body~(\ref{dcl.fct.def}), it contains +Each entity declared by a declaration is +also \defnx{defined}{define} by that declaration unless: +\begin{itemize} +\item +it declares a function +without specifying the function's body\iref{dcl.fct.def}, +\item +it contains the \indextext{declaration!\idxcode{extern}}% -\tcode{extern} specifier~(\ref{dcl.stc}) or a -\grammarterm{linkage-specification}\footnote{Appearing inside the braced-enclosed +\keyword{extern} specifier\iref{dcl.stc} or a +\grammarterm{linkage-specification} +\begin{footnote} +Appearing inside the brace-enclosed \grammarterm{declaration-seq} in a \grammarterm{linkage-specification} does -not affect whether a declaration is a definition.} -(\ref{dcl.link}) and neither an \grammarterm{initializer} nor a +not affect whether a declaration is a definition. +\end{footnote}\iref{dcl.link} +and neither an \grammarterm{initializer} nor a \grammarterm{function-body}, -\indextext{declaration!\idxcode{static member}}% -it declares a static data member in a class -definition (\ref{class.mem},~\ref{class.static}), -\indextext{declaration!class~name}% -it is a class name declaration~(\ref{class.name}), +\item +\indextext{declaration!static member@\tcode{static} member}% +it declares a non-inline static data member in a class +definition\iref{class.mem,class.static}, +\item +it declares a static data member outside a class definition +and the variable was defined within the class with the \keyword{constexpr} +specifier\iref{class.static.data} (this usage is deprecated; see \ref{depr.static.constexpr}), +\item +\indextext{declaration!class name}% +it is an \grammarterm{elaborated-type-specifier}\iref{class.name}, +\item it is an -\indextext{declaration!opaque~enum}% -\grammarterm{opaque-enum-declaration}~(\ref{dcl.enum}), +\indextext{declaration!opaque enum}% +\grammarterm{opaque-enum-declaration}\iref{dcl.enum}, +\item it is a \indextext{parameter!template}\indextext{template parameter}% -\grammarterm{template-parameter}~(\ref{temp.param}), +\grammarterm{template-parameter}\iref{temp.param}, +\item it is a \indextext{declaration!parameter}\indextext{parameter declaration}% -\grammarterm{parameter-declaration}~(\ref{dcl.fct}) in a function +\grammarterm{parameter-declaration}\iref{dcl.fct} in a function \indextext{declarator}% declarator that is not the \grammarterm{declarator} of a \grammarterm{function-definition}, -or it is a +\item +it is a \indextext{declaration!\idxcode{typedef}}% -\tcode{typedef} declaration~(\ref{dcl.typedef}), -an \grammarterm{alias-declaration}~(\ref{dcl.typedef}), -a -\grammarterm{using-declaration}~(\ref{namespace.udecl}), -a \grammarterm{static_assert-declaration} (Clause~\ref{dcl.dcl}), an -\grammarterm{attribute-declaration} (Clause~\ref{dcl.dcl}), an -\grammarterm{empty-declaration} (Clause~\ref{dcl.dcl}), -a \grammarterm{using-directive}~(\ref{namespace.udir}), -an explicit instantiation declaration~(\ref{temp.explicit}), or -an explicit specialization~(\ref{temp.expl.spec}) whose +\keyword{typedef} declaration\iref{dcl.typedef}, +\item it is +an \grammarterm{alias-declaration}\iref{dcl.typedef}, +\item it is +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}, +\item +it is an +\grammarterm{empty-declaration}\iref{dcl.pre}, +\item it is +a \grammarterm{using-directive}\iref{namespace.udir}, +\item it is +a \grammarterm{using-enum-declaration}\iref{enum.udecl}, +\item it is +a \grammarterm{template-declaration}\iref{temp.pre} +whose \grammarterm{template-head} is not followed by +either a \grammarterm{concept-definition} or a \grammarterm{declaration} +that defines a function, a class, a variable, or a static data member, +\item it is +an explicit instantiation declaration\iref{temp.explicit}, or +\item it is +an \grammarterm{explicit-specialization}\iref{temp.expl.spec} whose \grammarterm{declaration} is not a definition. - -\enterexample all but one of the following are definitions: - -\indextext{example!definition}% +\end{itemize} +A declaration is said to be a \defn{definition} of each entity that it defines. +\begin{example} +All but one of the following are definitions: \begin{codeblock} int a; // defines \tcode{a} extern const int c = 1; // defines \tcode{c} @@ -166,40 +311,38 @@ 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} whereas these are just declarations: -\indextext{example!declaration}% \begin{codeblock} extern int a; // declares \tcode{a} extern const int c; // declares \tcode{c} 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} -\exitexample +\end{example} \pnum -\enternote +\begin{note} \indextext{implementation-generated}% -In some circumstances, \Cpp implementations implicitly define the -default constructor~(\ref{class.ctor}), -copy constructor~(\ref{class.copy}), -move constructor~(\ref{class.copy}), -copy assignment operator~(\ref{class.copy}), -move assignment operator~(\ref{class.copy}), -or destructor~(\ref{class.dtor}) member functions. \exitnote -\enterexample given - +In some circumstances, \Cpp{} implementations implicitly define the +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} member functions. +\end{note} +\begin{example} +Given \begin{codeblock} #include struct C { - std::string s; // \tcode{std::string} is the standard library class (Clause~\ref{strings}) + std::string s; // \tcode{std::string} is the standard library class\iref{string.classes} }; int main() { @@ -208,1217 +351,1807 @@ b = a; } \end{codeblock} - the implementation will implicitly define functions to make the definition of \tcode{C} equivalent to - \begin{codeblock} struct C { std::string s; C() : s() { } C(const C& x): s(x.s) { } C(C&& x): s(static_cast(x.s)) { } - // \tcode{: s(std::move(x.s)) \{ \}} + @\rlap{\textnormal{\textit{//}}}@ : s(std::move(x.s)) { } C& operator=(const C& x) { s = x.s; return *this; } C& operator=(C&& x) { s = static_cast(x.s); return *this; } - // \tcode{\{ s = std::move(x.s); return *this; \}} + @\rlap{\textnormal{\textit{//}}}@ { s = std::move(x.s); return *this; } ~C() { } }; \end{codeblock} -\exitexample +\end{example} \pnum -\enternote A class name can also be implicitly declared by an -\grammarterm{elaborated-type-specifier}~(\ref{dcl.type.elab}). -\exitnote +\begin{note} +A class name can also be implicitly declared by an +\grammarterm{elaborated-type-specifier}\iref{dcl.type.elab}. +\end{note} \pnum \indextext{type!incomplete}% -A program is ill-formed if the definition of any object gives the object -an incomplete type~(\ref{basic.types}). +In the definition of an object, +the type of that object shall not be +an incomplete type\iref{term.incomplete.type}, +an abstract class type\iref{class.abstract}, or +a (possibly multidimensional) array thereof. +\rSec1[basic.def.odr]{One-definition rule}% \indextext{object!definition}% \indextext{function!definition}% \indextext{class!definition}% \indextext{enumerator!definition}% -\indextext{one-definition~rule|(}% -\rSec1[basic.def.odr]{One definition rule} +\indextext{one-definition rule|(}% + +\pnum +Each of the following is termed a \defnadj{definable}{item}: +\begin{itemize} +\item a class type\iref{class}, +\item an enumeration type\iref{dcl.enum}, +\item a function\iref{dcl.fct}, +\item a variable\iref{basic.pre}, +\item a templated entity\iref{temp.pre}, +\item a default argument for a parameter +(for a function in a given scope)\iref{dcl.fct.default}, or +\item a default template argument\iref{temp.param}. +\end{itemize} \pnum No translation unit shall contain more than one definition of any -variable, function, class type, enumeration type, or template. +definable item. \pnum -An expression is \defn{potentially evaluated} unless it is an -unevaluated operand (Clause~\ref{expr}) or a subexpression thereof. -The set of \defn{potential results} of an expression \tcode{e} is +\indextext{expression!potentially evaluated}% +An expression or conversion is \defn{potentially evaluated} unless it is +an unevaluated operand\iref{expr.context}, +a subexpression thereof, or +a conversion in an initialization or conversion sequence in such a context. +The set of \defn{potential results} of an expression $E$ is defined as follows: - \begin{itemize} -\item If \tcode{e} is an -\grammarterm{id-expression}~(\ref{expr.prim.general}), the set -contains only \tcode{e}. -\item If \tcode{e} is a class member access -expression~(\ref{expr.ref}), the set contains the potential results of -the object expression. -\item If \tcode{e} is a pointer-to-member -expression~(\ref{expr.mptr.oper}) whose second operand is a constant -expression, the set contains the potential results of the object -expression. -\item If \tcode{e} has the form \tcode{(e1)}, the set contains the -potential results of \tcode{e1}. -\item If \tcode{e} is a glvalue conditional -expression~(\ref{expr.cond}), the set is the union of the sets of +\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$, +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, +the set contains the \grammarterm{id-expression} designating the data member. +\item If $E$ is a pointer-to-member +expression\iref{expr.mptr.oper} of the form +$E_1$ \tcode{.*} $E_2$, +the set contains the potential results of $E_1$. +\item If $E$ has the form \tcode{($E_1$)}, the set contains the +potential results of $E_1$. +\item If $E$ is a glvalue conditional +expression\iref{expr.cond}, the set is the union of the sets of potential results of the second and third operands. -\item If \tcode{e} is a comma expression~(\ref{expr.comma}), the set +\item If $E$ is a comma expression\iref{expr.comma}, the set contains the potential results of the right operand. \item Otherwise, the set is empty. \end{itemize} -\enternote -This set is a (possibly-empty) set of \grammarterm{id-expression}{s}, -each of which is either \tcode{e} or a subexpression of \tcode{e}. -\enterexample +\begin{note} +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 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} + +\pnum +A function is \defnx{named by}{function!named by expression or conversion} +an expression or conversion as follows: +\begin{itemize} +\item + A function is named by an expression or conversion + if it is the selected member + of an overload set\iref{basic.lookup,over.match,over.over} + in an overload resolution performed + as part of forming that expression or conversion, + 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}, + calls to named functions\iref{expr.call}, + operator overloading\iref{over}, + user-defined conversions\iref{class.conv.fct}, + allocation functions for \grammarterm{new-expression}{s}\iref{expr.new}, as well as + non-default initialization\iref{dcl.init}. + A constructor selected to copy or move an object of class type + is considered to be named by an expression or conversion + even if the call is actually elided by the implementation\iref{class.copy.elision}. +\end{note} +\item + A deallocation function for a class + is named by a \grammarterm{new-expression} + if it is the single matching deallocation function + for the allocation function selected by overload resolution, + as specified in~\ref{expr.new}. +\item + A deallocation function for a class + is named by a \grammarterm{delete-expression} + if it is the selected usual deallocation function + as specified in~\ref{expr.delete} and~\ref{class.free}. +\end{itemize} + +\pnum +\label{term.odr.use}% +A variable is named by an expression +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$ +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.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 +\item +\tcode{x} is a non-volatile object +that is usable in constant expressions at $P$ and +has no mutable subobjects, and +\begin{itemize} +\item +$E$ is a class member access expression\iref{expr.ref} +naming a non-static data member of reference type and +whose object expression has non-volatile-qualified type, or +\item +the lvalue-to-rvalue conversion\iref{conv.lval} is applied to $E$ and +$E$ has non-volatile-qualified non-class type. +\end{itemize} +\end{itemize} +\end{itemize} +\begin{example} +\begin{codeblock} +int f(int); +int g(int&); +struct A { + int x; +}; +struct B { + int& r; +}; +int h(bool cond) { + constexpr A a = {1}; + constexpr const volatile A& r = a; // odr-uses \tcode{a} + int _ = f(cond ? a.x : r.x); // does not odr-use \tcode{a} or \tcode{r} + int x, y; + constexpr B b1 = {x}, b2 = {y}; // odr-uses \tcode{x} and \tcode{y} + int _ = g(cond ? b1.r : b2.r); // does not odr-use \tcode{b1} or \tcode{b2} + int _ = ((cond ? x : y), 0); // does not odr-use \tcode{x} or \tcode{y} + return [] { + return b1.r; // error: \tcode{b1} is odr-used here because the object + // referred to by \tcode{b1.r} is not constexpr-referenceable here + }(); +} \end{codeblock} -\exitexample -\exitnote - -\pnum -A variable \tcode{x} whose name appears as a -potentially-evaluated expression \tcode{ex} is \defn{odr-used} by \tcode{ex} unless -applying the lvalue-to-rvalue conversion (\ref{conv.lval}) to \tcode{x} yields -a constant expression~(\ref{expr.const}) that does not invoke any non-trivial -functions -and, if \tcode{x} is an object, \tcode{ex} is an element of -the set of potential results of an expression \tcode{e}, where either the lvalue-to-rvalue -conversion~(\ref{conv.lval}) is applied to \tcode{e}, or \tcode{e} is -a discarded-value expression~(Clause \ref{expr}). -\tcode{this} is odr-used if it appears as a potentially-evaluated expression -(including as the result of the implicit transformation in the body of a non-static -member function~(\ref{class.mfct.non-static})). +\end{example} + +\pnum +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 +(including as the result of any implicit transformation to +a class member access expression\iref{expr.prim.id.general}). + +\pnum A virtual member function is odr-used if it is not pure. -A function whose name appears as a potentially-evaluated -expression is odr-used if it is the unique lookup result or the selected -member of a set of overloaded functions~(\ref{basic.lookup}, \ref{over.match}, \ref{over.over}), -unless it is a pure virtual function and either -its name is not explicitly qualified or -the expression forms a pointer to member~(\ref{expr.unary.op}). -\enternote This covers calls to named -functions~(\ref{expr.call}), operator overloading (Clause~\ref{over}), -user-defined conversions~(\ref{class.conv.fct}), allocation function for -placement new~(\ref{expr.new}), as well as non-default -initialization~(\ref{dcl.init}). A constructor selected to copy or move an -object of class type is odr-used even if the -call is actually elided by the implementation~(\ref{class.copy}). \exitnote An allocation -or deallocation function for a class is odr-used by a \grammarterm{new-expression} -appearing in a potentially-evaluated expression as specified -in~\ref{expr.new} and~\ref{class.free}. A deallocation function for a -class is odr-used by a delete expression appearing in a -potentially-evaluated expression as specified in~\ref{expr.delete} -and~\ref{class.free}. A non-placement allocation or deallocation +A function is odr-used if it is named by +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 definition of the destructor of that class, or by being selected by the lookup at the point of definition of a virtual -destructor~(\ref{class.dtor}).\footnote{An implementation is not required +destructor\iref{class.dtor}. +\begin{footnote} +An implementation is not required to call allocation and deallocation functions from constructors or destructors; however, this -is a permissible implementation technique.} +is a permissible implementation technique. +\end{footnote} + +\pnum An assignment operator function in a class is odr-used by an implicitly-defined -copy-assignment or move-assignment function for another class as specified -in~\ref{class.copy}. +copy assignment or move assignment function for another class as specified +in~\ref{class.copy.assign}. A constructor for a class is odr-used as specified in~\ref{dcl.init}. A destructor for a class is odr-used if it is potentially -invoked~(\ref{class.dtor}). +invoked\iref{class.dtor}. + +\pnum +A local entity\iref{basic.pre} +is \defn{odr-usable} in a scope\iref{basic.scope.scope} if +\begin{itemize} +\item either the local entity is not \tcode{*\keyword{this}}, or +an enclosing class or non-lambda function parameter scope exists and, +if the innermost such scope is a function parameter scope, +it corresponds to a non-static member function, and +\item +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 parameter scope), +either +\begin{itemize} +\item the intervening scope is a block scope, +\item the intervening scope is a contract-assertion scope\iref{basic.scope.contract}, +\item the intervening scope is the function parameter scope of +a \grammarterm{lambda-expression} or \grammarterm{requires-expression}, or +\item the intervening scope is the lambda scope of +a \grammarterm{lambda-expression} +that has a \grammarterm{simple-capture} +naming the entity or has a \grammarterm{capture-default}, and +the block scope of the \grammarterm{lambda-expression} +is also an intervening scope. +\end{itemize} +\end{itemize} + +If a local entity is odr-used +in a scope in which it is not odr-usable, +the program is ill-formed. +\begin{example} +\begin{codeblock} +void f(int n) { + [] { n = 1; }; // error: \tcode{n} is not odr-usable due to intervening lambda-expression + struct A { + 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 + // outside the block scope of the \grammarterm{lambda-expression} + [&] { [n]{ return n; }; }; // OK +} +\end{codeblock} +\end{example} + +\pnum +\begin{example} +\begin{codeblock} +void g() { + constexpr int x = 1; + auto lambda = [] {}; // OK + lambda.operator()(); // OK, does not consider \tcode{x} at all + lambda.operator()(); // OK, does not odr-use \tcode{x} + lambda.operator()(); // error: odr-uses \tcode{x} from a context where \tcode{x} is not odr-usable +} + +void h() { + constexpr int x = 1; + auto lambda = [] { (T)x; }; // OK + lambda.operator()(); // OK, does not odr-use \tcode{x} + lambda.operator()(); // OK, does not odr-use \tcode{x} + lambda.operator()(); // error: odr-uses \tcode{x} from a context where \tcode{x} is not odr-usable +} +\end{codeblock} +\end{example} \pnum -Every program shall contain exactly one definition of every non-inline -function or variable that is odr-used in that program; no diagnostic required. +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. 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.ctor}, \ref{class.dtor} and -\ref{class.copy}). An inline function shall be defined in every -translation unit in which it is odr-used. +implicitly defined (see~\ref{class.default.ctor}, \ref{class.copy.ctor}, +\ref{class.dtor}, and \ref{class.copy.assign}). +\begin{example} +\begin{codeblock} +auto f() { + struct A {}; + return A{}; +} +decltype(f()) g(); +auto x = g(); +\end{codeblock} +A program containing this translation unit is ill-formed +because \tcode{g} is odr-used but not defined, +and cannot be defined in any other translation unit +because the local class \tcode{A} cannot be named outside this +translation unit. +\end{example} + +\pnum +A \defn{definition domain} is +a \grammarterm{private-module-fragment} or +the portion of a translation unit +excluding its \grammarterm{private-module-fragment} (if any). +A definition of an inline function or variable shall be reachable +from the end of every definition domain +in which it is odr-used outside of a discarded statement. \pnum \indextext{type!incomplete}% -Exactly one definition of a class is required in a translation unit if +A definition of a class shall be reachable in every context in which the class is used in a way that requires the class type to be complete. -\enterexample the following complete translation unit is well-formed, +\begin{example} +The following complete translation unit is well-formed, even though it never defines \tcode{X}: - \begin{codeblock} struct X; // declare \tcode{X} as a struct type struct X* x1; // use \tcode{X} in pointer formation X* x2; // use \tcode{X} in pointer formation \end{codeblock} -\exitexample -\enternote The rules for declarations and expressions +\end{example} +\begin{note} +The rules for declarations and expressions describe in which contexts complete class types are required. A class -type \tcode{T} must be complete if: - +type \tcode{T} must be complete if \begin{itemize} -\item an object of type \tcode{T} is defined~(\ref{basic.def}), or +\item an object of type \tcode{T} is defined\iref{basic.def}, or \item a non-static class data member of type \tcode{T} is -declared~(\ref{class.mem}), or -\item \tcode{T} is used as the object type or array element type in a -\grammarterm{new-expression}~(\ref{expr.new}), or +declared\iref{class.mem}, or +\item \tcode{T} is used as the allocated type or array element type in a +\grammarterm{new-expression}\iref{expr.new}, or \item an lvalue-to-rvalue conversion is applied to a glvalue referring -to an object of type \tcode{T}~(\ref{conv.lval}), or +to an object of type \tcode{T}\iref{conv.lval}, or \item an expression is converted (either implicitly or explicitly) to -type \tcode{T} (Clause~\ref{conv}, \ref{expr.type.conv}, -\ref{expr.dynamic.cast}, \ref{expr.static.cast}, \ref{expr.cast}), or +type \tcode{T}\iref{conv,expr.type.conv, +expr.dynamic.cast,expr.static.cast,expr.cast}, or \item an expression that is not a null pointer constant, and has type -other than \term{cv} \tcode{void*}, is converted to the type pointer to \tcode{T} -or reference to \tcode{T} using a standard conversion -(Clause~\ref{conv}), a \tcode{dynamic_cast}~(\ref{expr.dynamic.cast}) or -a \tcode{static_cast}~(\ref{expr.static.cast}), or +other than \cv{}~\tcode{\keyword{void}*}, is converted to the type pointer to \tcode{T} +or reference to \tcode{T} using a standard conversion\iref{conv}, +a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or +a \keyword{static_cast}\iref{expr.static.cast}, or \item a class member access operator is applied to an expression of type -\tcode{T}~(\ref{expr.ref}), or -\item the \tcode{typeid} operator~(\ref{expr.typeid}) or the -\tcode{sizeof} operator~(\ref{expr.sizeof}) is applied to an operand of +\tcode{T}\iref{expr.ref}, or +\item the \keyword{typeid} operator\iref{expr.typeid} or the +\keyword{sizeof} operator\iref{expr.sizeof} is applied to an operand of type \tcode{T}, or \item a function with a return type or argument type of type \tcode{T} -is defined~(\ref{basic.def}) or called~(\ref{expr.call}), or +is defined\iref{basic.def} or called\iref{expr.call}, or \item a class with a base class of type \tcode{T} is -defined (Clause~\ref{class.derived}), or -\item an lvalue of type \tcode{T} is assigned to~(\ref{expr.ass}), or +defined\iref{class.derived}, 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 -\tcode{alignof} expression~(\ref{expr.alignof}), or +\keyword{alignof} expression\iref{expr.alignof}, or \item an \grammarterm{exception-declaration} has type \tcode{T}, reference to -\tcode{T}, or pointer to \tcode{T}~(\ref{except.handle}). +\tcode{T}, or pointer to \tcode{T}\iref{except.handle}. \end{itemize} -\exitnote - -\pnum -There can be more than one definition of a class type -(Clause~\ref{class}), enumeration type~(\ref{dcl.enum}), inline function -with external linkage~(\ref{dcl.fct.spec}), class template -(Clause~\ref{temp}), non-static function template~(\ref{temp.fct}), -static data member of a class template~(\ref{temp.static}), member -function of a class template~(\ref{temp.mem.func}), or template -specialization for which some template parameters are not -specified~(\ref{temp.spec}, \ref{temp.class.spec}) in a program provided -that each definition appears in a different translation unit, and -provided the definitions satisfy the following requirements. Given such -an entity named \tcode{D} defined in more than one translation unit, -then +\end{note} + +\pnum +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. + +\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 +\item +if the definitions in different translation units +do not satisfy the following requirements, +\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. +Given such an item, +for all definitions of \tcode{D}, or, +if \tcode{D} is an unnamed enumeration, +for all definitions of \tcode{D} that are reachable at any given program point, +the following requirements shall be satisfied. +\begin{itemize} +\item Each such definition +shall not be attached to a named module\iref{module.unit}. +\item Each such definition shall consist of +the same sequence of tokens, +where the definition of a closure type +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 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} -\item each definition of \tcode{D} shall consist of the same sequence of -tokens; and -\item in each definition of \tcode{D}, corresponding names, looked up -according to~\ref{basic.lookup}, shall refer to an entity defined within -the definition of \tcode{D}, or shall refer to the same entity, after -overload resolution~(\ref{over.match}) and after matching of partial -template specialization~(\ref{temp.over}), except that a name can refer -to a non-volatile \tcode{const} object with internal or no linkage if the -object has the same literal type in all definitions of \tcode{D}, -and the object is initialized with a constant -expression~(\ref{expr.const}), and the object is not odr-used, and the object -has the same value in all definitions of \tcode{D}; and -\item in each definition of \tcode{D}, corresponding entities shall have the -same language linkage; and -\item in each definition of \tcode{D}, the overloaded operators referred +\item +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.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} +or +\item +a reference with internal or no linkage +initialized with a constant expression such that +the reference refers to the same object or function in all definitions of \tcode{D}. +\end{itemize} + +\item In each such definition, except within +the default arguments and default template arguments of \tcode{D}, +corresponding \grammarterm{lambda-expression}{s} shall have +the same closure type (see below). + +\item In each such definition, corresponding entities shall have the +same language linkage. + +\item In each such definition, +const objects with static or thread storage duration +shall be constant-initialized if +the object is constant-initialized in any such definition. + +\item In each such definition, +corresponding manifestly constant-evaluated expressions +that are not value-dependent +shall have the same value\iref{expr.const,temp.dep.constexpr}. + +\item In each such definition, the overloaded operators referred to, the implicit calls to conversion functions, constructors, operator new functions and operator delete functions, shall refer to the same -function, or to a function defined within the definition of \tcode{D}; -and -\item in each definition of \tcode{D}, a default argument used by an -(implicit or explicit) function call is treated as if its token sequence -were present in the definition of \tcode{D}; that is, the default -argument is subject to the three requirements described above (and, if -the default argument has sub-expressions with default arguments, this -requirement applies recursively).\footnote{\ref{dcl.fct.default} -describes how default argument names are looked up.} -\item if \tcode{D} is a class with an implicitly-declared -constructor~(\ref{class.ctor}), it is as if the constructor was +function. + +\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}, +\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 +For the purposes of the preceding requirements: + +\begin{itemize} +\item If \tcode{D} is a class with an implicitly-declared +constructor\iref{class.default.ctor,class.copy.ctor}, +it is as if the constructor was implicitly defined in every translation unit where it is odr-used, and the implicit definition in every translation unit shall call the same -constructor for a base class or a class member of \tcode{D}. -\enterexample - +constructor for a subobject of \tcode{D}. +\begin{example} \begin{codeblock} -//translation unit 1: +// translation unit 1: struct X { - X(int); X(int, int); + X(int, int, int); +}; +X::X(int, int = 0) { } +class D { + X x = 0; }; -X::X(int = 0) { } -class D: public X { }; -D d2; // \tcode{X(int)} called by \tcode{D()} +D d1; // \tcode{X(int, int)} called by \tcode{D()} -//translation unit 2: +// translation unit 2: struct X { - X(int); X(int, int); + X(int, int, int); +}; +X::X(int, int = 0, int = 0) { } +class D { + X x = 0; }; -X::X(int = 0, int = 0) { } -class D: public X { }; // \tcode{X(int, int)} called by \tcode{D()}; - // \tcode{D()}'s implicit definition - // violates the ODR +D d2; // \tcode{X(int, int, int)} called by \tcode{D()}; + // \tcode{D()}'s implicit definition violates the ODR \end{codeblock} -\exitexample -\end{itemize} - -If \tcode{D} is a template and is defined in more than one -translation unit, then the preceding requirements -shall apply both to names from the template's enclosing scope used in the -template definition~(\ref{temp.nondep}), and also to dependent names at -the point of instantiation~(\ref{temp.dep}). If the definitions of -\tcode{D} satisfy all these requirements, then the behavior is -as if there were a single definition of \tcode{D}. If the definitions of -\tcode{D} do not satisfy these requirements, then the behavior is -undefined.% -\indextext{one-definition~rule|)} - -\rSec1[basic.scope]{Scope}% -\indextext{scope|(} +\end{example} -\rSec2[basic.scope.declarative]{Declarative regions and scopes}% -\indextext{scope!declarations and|(} +\item If \tcode{D} is a class with +a defaulted three-way comparison operator function\iref{class.spaceship}, +it is as if the operator was +implicitly defined in every translation unit where it is odr-used, and the +implicit definition in every translation unit shall call the same +comparison operators for each subobject of \tcode{D}. -\pnum -\indextext{name!scope~of}% -Every name is introduced in some portion of program text called a -\indextext{region!declarative}% -\indextext{scope!potential}% -\defn{declarative region}, which is the largest part of the program -in which that name is \defn{valid}, that is, in which that name may -be used as an unqualified name to refer to the same entity. In general, -each particular name is valid only within some possibly discontiguous -portion of program text called its \defn{scope}. To determine the -scope of a declaration, it is sometimes convenient to refer to the -\defn{potential scope} of a declaration. The scope of a declaration -is the same as its potential scope unless the potential scope contains -another declaration of the same name. In that case, the potential scope -of the declaration in the inner (contained) declarative region is -excluded from the scope of the declaration in the outer (containing) -declarative region. +\item +If \tcode{D} is a template and is defined in more than one +translation unit, the requirements +apply both to names from the template's enclosing scope used in the +template definition, and also to dependent names at +the point of instantiation\iref{temp.dep}. +\end{itemize} \pnum -\enterexample -in - +These requirements also apply to corresponding entities +defined within each definition of \tcode{D} +(including the closure types of \grammarterm{lambda-expression}{s}, +but excluding entities defined within default arguments or +default template arguments of either \tcode{D} or +an entity not defined within \tcode{D}). +For each such entity and for \tcode{D} itself, +the behavior is as if there is a single entity with a single definition, +including in the application of these requirements to other entities. +\begin{note} +The entity is still declared in multiple translation units, and \ref{basic.link} +still applies to these declarations. In particular, +\grammarterm{lambda-expression}{s}\iref{expr.prim.lambda} +appearing in the type of \tcode{D} can result +in the different declarations having distinct types, and +\grammarterm{lambda-expression}{s} appearing in a default argument of \tcode{D} +might still denote different types in different translation units. +\end{note} + +\pnum +\begin{example} \begin{codeblock} -int j = 24; -int main() { - int i = j, j; - j = 42; +inline void f(bool cond, void (*p)()) { + if (cond) f(false, []{}); } +inline void g(bool cond, void (*p)() = []{}) { + if (cond) g(false); +} +struct X { + void h(bool cond, void (*p)() = []{}) { + if (cond) h(false); + } +}; \end{codeblock} -the identifier \tcode{j} is declared twice as a name (and used twice). -The declarative region of the first \tcode{j} includes the entire -example. The potential scope of the first \tcode{j} begins immediately -after that \tcode{j} and extends to the end of the program, but its -(actual) scope excludes the text between the \tcode{,} and the -\tcode{\}}. The declarative region of the second declaration of -\tcode{j} (the \tcode{j} immediately before the semicolon) includes all -the text between \tcode{\{} and \tcode{\}}, but its potential scope -excludes the declaration of \tcode{i}. The scope of the second -declaration of \tcode{j} is the same as its potential scope. -\exitexample - -\pnum -The names declared by a declaration are introduced into the scope in -which the declaration occurs, except that the presence of a -\tcode{friend} specifier~(\ref{class.friend}), certain uses of the -\grammarterm{elaborated-type-specifier}~(\ref{dcl.type.elab}), and -\grammarterm{using-directive}{s}~(\ref{namespace.udir}) alter this general -behavior. +If the definition of \tcode{f} appears in multiple translation units, +the behavior of the program is as if +there is only one definition of \tcode{f}. +If the definition of \tcode{g} appears in multiple translation units, +the program is ill-formed (no diagnostic required) because +each such definition uses a default argument that +refers to a distinct \grammarterm{lambda-expression} closure type. +The definition of \tcode{X} can appear +in multiple translation units of a valid program; +the \grammarterm{lambda-expression}{s} defined within +the default argument of \tcode{X::h} within the definition of \tcode{X} +denote the same closure type in each translation unit. +\end{example} + +\pnum +If, at any point in the program, +there is more than one +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. +\indextext{one-definition rule|)} -\pnum -Given a set of declarations in a single declarative region, each of -which specifies the same unqualified name, +\rSec1[basic.scope]{Scope}% +\indextext{scope|(} +\rSec2[basic.scope.scope]{General} + +\pnum +The declarations in a program appear in a number of \defnx{scopes}{scope} +that are in general discontiguous. +The \defnadj{global}{scope} contains the entire program; +every other scope $S$ is introduced by a +declaration, +\grammarterm{parameter-declaration-clause}, +\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$. +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. +A scope \defnx{intervenes}{scope!intervene} +between a program point $P$ and a scope $S$ +(that does not contain $P$) if it is or contains $S$ but does not contain $P$. + +\pnum +Unless otherwise specified: \begin{itemize} -\item they shall all refer to the same entity, or all refer to functions -and function templates; or -\item exactly one declaration shall declare a class name or enumeration -name that is not a typedef name and the other declarations shall all -refer to the same variable or enumerator, or all refer to functions and -function templates; in this case the class name or enumeration name is -hidden~(\ref{basic.scope.hiding}). \enternote A namespace name or a -class template name must be unique in its declarative -region~(\ref{namespace.alias}, Clause~\ref{temp}). \exitnote +\item +The smallest scope that contains a scope $S$ is +the \defnadj{parent}{scope} of $S$. +\item +No two declarations (re)introduce the same entity. +\item +A declaration \defnx{inhabits}{scope!inhabit} +the immediate scope at its locus\iref{basic.scope.pdecl}. +\item +A declaration's \defnadj{target}{scope} is the scope it inhabits. +\item +Any names (re)introduced by a declaration are \defnx{bound}{name!bound} to it +in its target scope. \end{itemize} -\enternote These restrictions apply to the declarative region into which -a name is introduced, which is not necessarily the same as the region in -which the declaration occurs. In particular, -\grammarterm{elaborated-type-specifier}{s}~(\ref{dcl.type.elab}) and -friend declarations~(\ref{class.friend}) may introduce a (possibly not -visible) name into an enclosing namespace; these restrictions apply to -that region. Local extern declarations~(\ref{basic.link}) may introduce -a name into the declarative region where the declaration appears and -also introduce a (possibly not visible) name into an enclosing -namespace; these restrictions apply to both regions. \exitnote - -\pnum -\enternote The name lookup rules are summarized in~\ref{basic.lookup}. -\exitnote - -\rSec2[basic.scope.pdecl]{Point of declaration} +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} +Special cases include that: +\begin{itemize} +\item +Template parameter scopes are parents +only to other template parameter scopes\iref{basic.scope.temp}. +\item +Corresponding declarations with appropriate linkage +declare the same entity\iref{basic.link}. +\item +The \grammarterm{declaration} of a \grammarterm{template-declaration} +inhabits the same scope as the \grammarterm{template-declaration}. +\item +Friend declarations and +declarations of template specializations do not bind names\iref{dcl.meaning}; +those with qualified names target a specified scope, and +other friend declarations and +certain \grammarterm{elaborated-type-specifier}s\iref{dcl.type.elab} +target a larger enclosing scope. +\item +Block-scope extern 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}. +\item +A class's name is also bound in its own scope\iref{class.pre}. +\item +The names of the members of an anonymous union are bound in +the union's parent scope\iref{class.union.anon}. +\end{itemize} +\end{note} \pnum -\indextext{name!point~of declaration}% -The \defn{point of declaration} for a name is immediately after its -complete declarator (Clause~\ref{dcl.decl}) and before its -\grammarterm{initializer} (if any), except as noted below. \enterexample - +Two non-static member functions have +\defnadjx{corresponding}{object parameters}{object parameter} if +\begin{itemize} +\item +exactly one is an implicit object member function +with no \grammarterm{ref-qualifier} and +the types of their object parameters\iref{dcl.fct}, +after removing references, +are the same, or +\item +their object parameters have the same type. +\end{itemize} +\indextext{template!function!corresponding object parameter}% +Two non-static member function templates have +\defnadjx{corresponding}{object parameters}{object parameter} if +\begin{itemize} +\item +exactly one is an implicit object member function +with no \grammarterm{ref-qualifier} and +the types of their object parameters, +after removing any references, +are equivalent, or +\item +the types of their object parameters are equivalent. +\end{itemize} +\indextext{template!function!corresponding signature}% +Two function templates have +\defnadjx{corresponding}{signatures}{signature} if +their \grammarterm{template-parameter-list}{s} +have the same length, +their corresponding \grammarterm{template-parameter}{s} are equivalent, +they have equivalent non-object-parameter-type-lists and return types (if any), and, +if both are non-static members, they have corresponding object parameters. + +\pnum +Two declarations \defn{correspond} +if they (re)introduce the same name, +both declare constructors, or +both declare destructors, +unless +\begin{itemize} +\item +either is a \grammarterm{using-declarator}, or +\item +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, +function, or +function template, or +\item +each declares a function or function template +and they do not declare corresponding overloads. +\end{itemize} +Two function or function template declarations declare +\defn{corresponding overloads} if +\begin{itemize} +\item +both declare functions with the same non-object-parameter-type-list, +\begin{footnote} +An implicit object parameter\iref{over.match.funcs} +is not part of the parameter-type-list. +\end{footnote} +equivalent\iref{temp.over.link} trailing \grammarterm{requires-clause}s +(if any, except as specified in \ref{temp.friend}), and, +if both are non-static members, +they have corresponding object parameters, or +\item +both declare function templates with corresponding signatures and equivalent +\grammarterm{template-head}s and +trailing \grammarterm{requires-clause}s (if any). +\end{itemize} +\begin{note} +Declarations can correspond even if neither binds a name. +\begin{example} \begin{codeblock} -unsigned char x = 12; -{ unsigned char x = x; } +struct A { + friend void f(); // \#1 +}; +struct B { + friend void f() {} // corresponds to, and defines, \#1 +}; \end{codeblock} +\end{example} +\end{note} +\begin{example} +\begin{codeblock} +typedef int Int; +enum E : int { a }; +void f(int); // \#1 +void f(Int) {} // defines \#1 +void f(E) {} // OK, another overload -Here the second \tcode{x} is initialized with its own (indeterminate) -value. \exitexample +struct X { + static void f(); + void f() const; // error: redeclaration + void g(); + void g() const; // OK + void g() &; // error: redeclaration + + void h(this X&, int); + void h(int) &&; // OK, another overload + void j(this const X&); + void j() const &; // error: redeclaration + void k(); + void k(this X&); // error: redeclaration +}; +\end{codeblock} +\end{example} \pnum -\enternote -\indextext{name~hiding}% -a name from an outer scope remains visible up -to the point of declaration of the name that hides it.\enterexample +A declaration is \defnx{name-independent}{declaration!name-independent} +if its name is \tcode{_} (\unicode{005f}{low line}) and it declares +\begin{itemize} +\item +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: +%FIXME: "that has no \grammarterm{storage-class-specifier} and +%FIXME: that is not inhabiting a namespace scope," +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? +a non-static data member of other than an anonymous union. +\end{itemize} +\recommended +Implementations should not emit a warning +that a name-independent declaration is used or unused. + +\pnum +\indextext{declaration!potentially conflict}% +Two declarations \defn{potentially conflict} +if they correspond and +cause their shared name to denote different entities\iref{basic.link}. +The program is ill-formed +if, in any scope, a name is bound to two declarations $A$ and $B$ +that potentially conflict and $A$ precedes $B$\iref{basic.lookup}, +unless $B$ is name-independent. +\begin{note} +An \grammarterm{id-expression} that names a unique name-independent declaration +is usable until an additional declaration of the same name +is introduced in the same scope\iref{basic.lookup.general}. +\end{note} +\begin{note} +Overload resolution can consider potentially conflicting declarations +found in multiple scopes +(e.g., via \grammarterm{using-directive}s or for operator functions), +in which case it is often ambiguous. +\end{note} +\begin{example} \begin{codeblock} -const int i = 2; -{ int i[i]; } -\end{codeblock} +void f() { + int x,y; + void x(); // error: different entity for \tcode{x} + int y; // error: redefinition +} +enum { f }; // error: different entity for \tcode{::f} +namespace A {} +namespace B = A; +namespace B = A; // OK, no effect +namespace B = B; // OK, no effect +namespace A = B; // OK, no effect +namespace B {} // error: different entity for \tcode{B} -declares a block-scope array of two integers. \exitexample \exitnote +void g() { + int _; + _ = 0; // OK + int _; // OK, name-independent declaration + _ = 0; // error: two non-function declarations in the lookup set +} +void h () { + int _; // \#1 + _ ++; // OK + static int _; // error: conflicts with \#1 because static variables are not name-independent +} +\end{codeblock} +\end{example} + +\pnum +\indextext{declaration!nominable}% +A declaration is \defn{nominable} +in a class, class template, or namespace $E$ at a point $P$ if +it precedes $P$, +it does not inhabit a block scope, and +its target scope is the scope associated with $E$ or, +if $E$ is a namespace, +any element of the inline namespace set of $E$\iref{namespace.def}. +\begin{example} +\begin{codeblock} +namespace A { + void f() {void g();} + inline namespace B { + struct S { + friend void h(); + static int i; + }; + } +} +\end{codeblock} +At the end of this example, +the declarations of \tcode{f}, \tcode{B}, \tcode{S}, and \tcode{h} +are nominable in \tcode{A}, but those of \tcode{g} and \tcode{i} are not. +\end{example} + +\pnum +When instantiating a templated entity\iref{temp.pre}, +any scope $S$ introduced by any part of the template definition is considered +to be introduced by the instantiated entity and +to contain the instantiations of any declarations that inhabit $S$. + +\rSec2[basic.scope.pdecl]{Point of declaration} + +\indextext{declaration!point of|see{locus}}% +\indextext{scope!declarations and|see{locus}}% +\indextext{locus|(}% + +\pnum +\indextext{declaration!locus|see{locus}}% +The \defn{locus} of a declaration\iref{basic.pre} that is a declarator +is immediately after the complete declarator\iref{dcl.decl}. +\begin{example} +\begin{codeblock} +unsigned char x = 12; +{ unsigned char x = x; } +\end{codeblock} +Here, the initialization of the second \tcode{x} has undefined behavior, +because the initializer accesses the second \tcode{x} +outside its lifetime\iref{basic.life}. +\end{example} \pnum -The point of declaration for a class or class template first declared by a -\grammarterm{class-specifier} is immediately after the \grammarterm{identifier} or -\grammarterm{simple-template-id} (if any) in its \grammarterm{class-head} -(Clause~\ref{class}). The point of declaration for an enumeration is -immediately after the \grammarterm{identifier} (if any) in either its -\grammarterm{enum-specifier}~(\ref{dcl.enum}) or its first -\grammarterm{opaque-enum-declaration}~(\ref{dcl.enum}), whichever comes first. -The point of declaration of an alias or alias template immediately -follows the \grammarterm{type-id} to which the -alias refers. +\begin{note} +\indextext{name hiding}% +A name from an outer scope remains visible up to +the locus of the declaration that hides it. +\begin{example} +\begin{codeblock} +const int i = 2; +{ int i[i]; } +\end{codeblock} +declares a block-scope array of two integers. +\end{example} +\end{note} \pnum -The point of declaration of a \grammarterm{using-declaration} that does not name a -constructor is immediately after the \grammarterm{using-declaration}~(\ref{namespace.udecl}). +The locus of a \grammarterm{class-specifier} is immediately after +the \grammarterm{identifier} or \grammarterm{simple-template-id} (if any) +in its \grammarterm{class-head}\iref{class.pre}. +The locus of an \grammarterm{enum-specifier} +is immediately after +its \grammarterm{enum-head}; +the locus of an \grammarterm{opaque-enum-declaration} +is immediately after it\iref{dcl.enum}. +%FIXME: What's "it" below? What's "it" above? +The locus of an \grammarterm{alias-declaration} is immediately after it. \pnum -\indextext{declaration!enumerator point~of}% -The point of declaration for an enumerator is immediately after its -\grammarterm{enumerator-definition}.\enterexample +The locus of a \grammarterm{using-declarator} +that does not name a constructor +is immediately after the \grammarterm{using-declarator}\iref{namespace.udecl}. +\pnum +The locus of an \grammarterm{enumerator-definition} is immediately after it. +\begin{example} \begin{codeblock} const int x = 12; { enum { x = x }; } \end{codeblock} - Here, the enumerator \tcode{x} is initialized with the value of the -constant \tcode{x}, namely 12. \exitexample +constant \tcode{x}, namely 12. +\end{example} \pnum -After the point of declaration of a class member, the member name can be -looked up in the scope of its class. \enternote +\begin{note} \indextext{type!incomplete}% -this is true even if the class is an incomplete class. For example, - +After the declaration of a class member, +the member name can be found in the scope of its class +even if the class is an incomplete class. +\begin{example} \begin{codeblock} struct X { enum E { z = 16 }; - int b[X::z]; // OK + int b[X::z]; // OK }; \end{codeblock} -\exitnote +\end{example} +\end{note} \pnum -The point of declaration of a class first declared in an -\grammarterm{elaborated-type-specifier} is as follows: +The locus of an \grammarterm{elaborated-type-specifier} +that is a declaration\iref{dcl.type.elab} is immediately after it. -\begin{itemize} -\item for a declaration of the form - -\begin{ncbnf} -class-key attribute-specifier-seq\opt identifier \terminal{;} -\end{ncbnf} - -the \grammarterm{identifier} is declared to be a -\grammarterm{class-name} in the scope that contains the declaration, -otherwise -\item for an \grammarterm{elaborated-type-specifier} of the form - -\begin{ncbnf} -class-key identifier -\end{ncbnf} - -if the -\grammarterm{elaborated-type-specifier} is used in the -\grammarterm{decl-specifier-seq} or \grammarterm{parameter-declaration-clause} -of a function defined in namespace scope, the \grammarterm{identifier} is -declared as a \grammarterm{class-name} in the namespace that contains the -declaration; otherwise, except as a friend declaration, the -\grammarterm{identifier} is declared in the smallest namespace or block -scope that contains the declaration. \enternote -These rules also apply within templates. \exitnote \enternote Other -forms of \grammarterm{elaborated-type-specifier} do not declare a new name, -and therefore must refer to an existing \grammarterm{type-name}. -See~\ref{basic.lookup.elab} and~\ref{dcl.type.elab}. \exitnote -\end{itemize} +\pnum +The locus of an injected-class-name declaration\iref{class.pre} +is immediately following the opening brace of the class definition. \pnum -The point of declaration for an -\grammarterm{injected-class-name} (Clause~\ref{class}) is immediately following -the opening brace of the class definition. +The locus of the implicit declaration of +a function-local predefined variable\iref{dcl.fct.def.general} +is immediately before +the \grammarterm{function-body} of its function's definition. \pnum -The point of declaration for a function-local predefined -variable~(\ref{dcl.fct.def}) is immediately before the -\grammarterm{function-body} of a function definition. +The locus of the declaration of a structured binding\iref{dcl.struct.bind} +is immediately after +the \grammarterm{identifier-list} of the structured binding declaration. \pnum -The point of declaration for a template parameter is immediately after its complete -\grammarterm{template-parameter}. \enterexample +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. +\begin{example} \begin{codeblock} typedef unsigned char T; template struct A { }; \end{codeblock} -\exitexample +\end{example} \pnum -\enternote Friend declarations refer to functions or classes that are -members of the nearest enclosing namespace, but they do not introduce -new names into that namespace~(\ref{namespace.memdef}). Function -declarations at block scope and variable declarations with the -\tcode{extern} specifier at block scope refer to declarations that are -members of an enclosing namespace, but they do not introduce new names -into that scope. -\exitnote +The locus of a \grammarterm{result-name-introducer}\iref{dcl.contract.res} +is immediately after it. \pnum -\enternote For point of instantiation of a template, -see~\ref{temp.point}.\exitnote% -\indextext{scope!declarations and|)} - -\rSec2[basic.scope.block]{Block scope} +The locus of a \grammarterm{concept-definition} +is immediately after its \grammarterm{concept-name}\iref{temp.concept}. +\begin{note} +The \grammarterm{constraint-expression} cannot use +the \grammarterm{concept-name}. +\end{note} \pnum -\indextext{scope!block}% -\indextext{local~scope|see{block scope}}% -A name declared in a block~(\ref{stmt.block}) is local to that block; it has -\defn{block scope}. -Its potential scope begins at its point of -declaration~(\ref{basic.scope.pdecl}) and ends at the end of its block. -A variable declared at block scope is a \defn{local variable}. +The locus of a \grammarterm{namespace-definition} +with an \grammarterm{identifier} +is immediately after the \grammarterm{identifier}. +\begin{note} +An identifier is invented +for an \grammarterm{unnamed-namespace-definition}\iref{namespace.unnamed}. +\end{note} \pnum -\indextext{parameter!scope~of}% -The potential scope of a function parameter name -(including one appearing in a -\grammarterm{lambda-declarator}) -or of a function-local predefined variable -in a function -definition~(\ref{dcl.fct.def}) begins at its point of declaration. If -the function has a \grammarterm{function-try-block} the potential scope of -a parameter -or of a function-local predefined variable -ends at the end of the last associated handler, otherwise it ends -at the end of the outermost block of the function definition. A -parameter name shall not be redeclared in the outermost block of the -function definition nor in the outermost block of any handler associated -with a \grammarterm{function-try-block}. +\begin{note} +Friend declarations can introduce functions or classes +that belong to the nearest enclosing namespace or block scope, +but they do not bind names anywhere\iref{class.friend}. +Function declarations at block scope and +variable declarations with the \keyword{extern} specifier at block scope +declare entities +that belong to the nearest enclosing namespace, +but they do not bind names in it. +\end{note} \pnum -\indextext{scope!exception~declaration}% -The name declared in an \grammarterm{exception-declaration} -is local to the -\grammarterm{handler} and shall not be redeclared in the outermost block of the -\grammarterm{handler}. +\begin{note} +For point of instantiation of a template, see~\ref{temp.point}. +\end{note} +\indextext{locus|)} -\pnum -Names declared in the \grammarterm{for-init-statement}, the \grammarterm{for-range-declaration}, and in the -\grammarterm{condition} of \tcode{if}, \tcode{while}, \tcode{for}, and -\tcode{switch} statements are local to the \tcode{if}, \tcode{while}, -\tcode{for}, or \tcode{switch} statement (including the controlled -statement), and shall not be redeclared in a subsequent condition of -that statement nor in the outermost block (or, for the \tcode{if} -statement, any of the outermost blocks) of the controlled statement; -see~\ref{stmt.select}. +\rSec2[basic.scope.block]{Block scope} -\rSec2[basic.scope.proto]{Function prototype scope} +\indextext{local scope|see{scope, block}}% \pnum -\indextext{scope!function~prototype}% -\indextext{function~prototype}% -In a function declaration, or in any function declarator except the -declarator of a function definition~(\ref{dcl.fct.def}), names of -parameters (if supplied) have function prototype scope, which terminates -at the end of the nearest enclosing function declarator. - -\rSec2[basic.funscope]{Function scope} +Each +\begin{itemize} +\item +selection, iteration, or expansion statement\iref{stmt.select,stmt.iter,stmt.expand}, +\item +substatement of such a statement, +\item +\indextext{scope!\idxgram{handler}}% +\grammarterm{handler}\iref{except.pre}, or +\item +compound statement\iref{stmt.block} +that is not the \grammarterm{compound-statement} of a \grammarterm{handler} +\end{itemize} +introduces a \defnadj{block}{scope} +that includes that statement or \grammarterm{handler}. +\begin{note} +A substatement that is also a block has only one scope. +\end{note} +A variable that belongs to a block scope is a \defn{block variable}. +\begin{example} +\begin{codeblock} +int i = 42; +int a[10]; -\pnum -\indextext{scope!function}% -\indextext{label!scope~of}% -Labels~(\ref{stmt.label}) have \term{function scope} and -may be used anywhere in the function in which they are declared. Only -labels have function scope. +for (int i = 0; i < 10; i++) + a[i] = i; -\rSec2[basic.scope.namespace]{Namespace scope} +int j = i; // \tcode{j = 42} +\end{codeblock} +\end{example} \pnum -\indextext{scope!namespace}% -The declarative region of a \grammarterm{namespace-definition} is its -\grammarterm{namespace-body}. Entities declared in a -\grammarterm{namespace-body} are said to be \defn{members} of the -namespace, and names introduced by these declarations into the -declarative region of the namespace are said to be \defn{member -names} of the namespace. A namespace member name has namespace scope. -Its potential scope includes its namespace from the name's point of -declaration~(\ref{basic.scope.pdecl}) onwards; and for each -\grammarterm{using-directive}~(\ref{namespace.udir}) that nominates the -member's namespace, the member's potential scope includes that portion -of the potential scope of the \grammarterm{using-directive} that follows -the member's point of declaration. \enterexample - +If a declaration +that is not a name-independent declaration and +that binds a name in the block scope $S$ of a +\begin{itemize} +\item +\grammarterm{compound-statement} of a \grammarterm{lambda-expression}, +\grammarterm{function-body}, or \grammarterm{function-try-block}, +\item +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} +potentially conflicts with a declaration +whose target scope is the parent scope of $S$, +the program is ill-formed. +\begin{example} \begin{codeblock} -namespace N { - int i; - int g(int a) { return a; } - int j(); - void q(); +if (int x = f()) { + int x; // error: redeclaration of \tcode{x} } -namespace { int l=1; } -// the potential scope of \tcode{l} is from its point of declaration -// to the end of the translation unit - -namespace N { - int g(char a) { // overloads \tcode{N::g(int)} - return l+a; // \tcode{l} is from unnamed namespace - } - - int i; // error: duplicate definition - int j(); // OK: duplicate function declaration - - int j() { // OK: definition of \tcode{N::j()} - return g(i); // calls \tcode{N::g(int)} - } - int q(); // error: different return type +else { + int x; // error: redeclaration of \tcode{x} } \end{codeblock} -\exitexample - -\pnum -A namespace member can also be referred to after the \tcode{::} scope -resolution operator~(\ref{expr.prim}) applied to the name of its -namespace or the name of a namespace which nominates the member's -namespace in a \grammarterm{using-directive;} see~\ref{namespace.qual}. - -\pnum -\indextext{scope!global namespace}% -\indextext{scope!global}% -The outermost declarative region of a translation unit is also a -namespace, called the \defn{global namespace}. A name declared in -the global namespace has \defn{global namespace scope} (also called -\defn{global scope}). The potential scope of such a name begins at -its point of declaration~(\ref{basic.scope.pdecl}) and ends at the end -of the translation unit that is its declarative region. -\indextext{name!global}% -A name with global namespace scope is said to be a -\defnx{global name}{global}. - -\rSec2[basic.scope.class]{Class scope} - -\pnum -\indextext{scope!class}% -The following rules describe the scope of names declared in classes. - -\begin{enumeraten} -\item The potential scope of a name declared in a class consists not -only of the declarative region following the name's point of -declaration, but also of all function bodies, default arguments, -\grammarterm{exception-specification}{s}, and -\grammarterm{brace-or-equal-initializers} of non-static data members -in that class (including such -things in nested classes). -\item A name \tcode{N} used in a class \tcode{S} shall refer to the same -declaration in its context and when re-evaluated in the completed scope -of \tcode{S}. No diagnostic is required for a violation of this rule. -\item If reordering member declarations in a class yields an alternate -valid program under (1) and (2), the program is ill-formed, no -diagnostic is required. -\item A name declared within a member function hides a declaration of -the same name whose scope extends to or past the end of the member -function's class. -\item The potential scope of a declaration that extends to or past the -end of a class definition also extends to the regions defined by its -member definitions, even if the members are defined lexically outside -the class (this includes static data member definitions, nested class -definitions, and member function definitions, including the member function -body and any portion of the -declarator part of such definitions which follows the \grammarterm{declarator-id}, -including a \grammarterm{parameter-declaration-clause} and any default -arguments~(\ref{dcl.fct.default})).\enterexample - -\begin{codeblock} -typedef int c; -enum { i = 1 }; - -class X { - char v[i]; // error: \tcode{i} refers to \tcode{::i} - // but when reevaluated is \tcode{X::i} - int f() { return sizeof(c); } // OK: \tcode{X::c} - char c; - enum { i = 2 }; -}; +\end{example} -typedef char* T; -struct Y { - T a; // error: \tcode{T} refers to \tcode{::T} - // but when reevaluated is \tcode{Y::T} - typedef long T; - T b; -}; +\rSec2[basic.scope.param]{Function parameter scope} -typedef int I; -class D { - typedef I I; // error, even though no reordering involved -}; -\end{codeblock} -\exitexample -\end{enumeraten} +\indextext{scope!function prototype|see{scope, function parameter}}% +\indextext{parameter!scope of}% \pnum -The name of a class member shall only be used as follows: - +A \grammarterm{parameter-declaration-clause} $P$ introduces +a \defnadj{function parameter}{scope} that includes $P$. +\begin{note} +A function parameter cannot be used for its value +within the \grammarterm{parameter-declaration-clause}\iref{dcl.fct.default}. +\end{note} \begin{itemize} -\item in the scope of its class (as described above) or a class derived -(Clause~\ref{class.derived}) from its class, -\item after the \tcode{.} operator applied to an expression of the type -of its class~(\ref{expr.ref}) or a class derived from its class, -\item after the \tcode{->} operator applied to a pointer to an object of -its class~(\ref{expr.ref}) or a class derived from its class, -\item after the \tcode{::} scope resolution operator~(\ref{expr.prim}) -applied to the name of its class or a class derived from its class. +\item +If $P$ is associated with a \grammarterm{declarator} and +is preceded by a (possibly-parenthesized) \grammarterm{noptr-declarator} of +the form +\grammarterm{declarator-id} \opt{\grammarterm{attribute-specifier-seq}}, +its scope extends to the end of the nearest enclosing +\grammarterm{init-declarator}, +\grammarterm{member-declarator}, +\grammarterm{declarator} of a \grammarterm{parameter-declaration} or +a \grammarterm{nodeclspec-function-declaration}, or +\grammarterm{function-definition}, +but does not include the locus of the associated \grammarterm{declarator}. +\begin{note} +In this case, $P$ declares the parameters of a function +(or a function or template parameter declared with function type). +A member function's parameter scope is nested within its class's scope. +\end{note} +\item +If $P$ is associated with a \grammarterm{lambda-declarator}, +its scope extends to the end of the \grammarterm{compound-statement} +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}. +\item +If $P$ is associated with a \grammarterm{deduction-guide}, +its scope extends to the end of the \grammarterm{deduction-guide}. \end{itemize} -\rSec2[basic.scope.enum]{Enumeration scope}% -\indextext{enumeration scope}% -\indextext{scope!enumeration} - -\pnum -The name of a scoped enumerator~(\ref{dcl.enum}) has -\defn{enumeration scope}. Its potential scope begins at -its point of declaration and terminates at the end of the -\grammarterm{enum-specifier}. +\rSec2[basic.scope.lambda]{Lambda scope} -\rSec2[basic.scope.temp]{Template parameter scope}% -\indextext{template~parameter~scope}% -\indextext{scope!template~parameter}% +A \grammarterm{lambda-expression} \tcode{E} introduces a \defnadj{lambda}{scope} +that starts immediately after the \grammarterm{lambda-introducer} of \tcode{E} +and extends to the end of the \grammarterm{compound-statement} of \tcode{E}. -\pnum -The declarative region of the name of a template parameter of a template -\grammarterm{template-parameter} is the smallest \grammarterm{template-parameter-list} -in which the name was introduced. +\rSec2[basic.scope.namespace]{Namespace scope} \pnum -The declarative region of the name of a template parameter of a template is the smallest -\grammarterm{template-declaration} in which the name was introduced. Only template -parameter names belong to this declarative region; any other kind of name introduced by -the \grammarterm{declaration} of a \grammarterm{template-declaration} is instead -introduced into the same declarative region where it would be introduced as a result of -a non-template declaration of the same name. \enterexample - +Any \grammarterm{namespace-definition} for a namespace $N$ introduces +a \defnadj{namespace}{scope} +that includes the \grammarterm{namespace-body} +for every \grammarterm{namespace-definition} for $N$. +For each non-friend redeclaration or specialization +whose target scope is or is contained by the scope, +the portion after the +\grammarterm{declarator-id}, +\grammarterm{class-head-name}, or +\grammarterm{enum-head-name} +is also included in the scope. +The global scope is +the namespace scope of the global namespace\iref{basic.namespace}. +\begin{example} \begin{codeblock} -namespace N { - template struct A { }; // \#1 - template void f(U) { } // \#2 - struct B { - template friend int g(struct C*); // \#3 - }; +namespace Q { + namespace V { void f(); } + void V::f() { // in the scope of \tcode{V} + void h(); // declares \tcode{Q::V::h} + } } \end{codeblock} +\end{example} -The declarative regions of \tcode{T}, \tcode{U} and \tcode{V} are the -\grammarterm{template-declaration}{s} on lines \tcode{\#1}, \tcode{\#2} and \tcode{\#3}, -respectively. But the names \tcode{A}, \tcode{f}, \tcode{g} and \tcode{C} all belong to -the same declarative region --- namely, the \grammarterm{namespace-body} of \tcode{N}. -(\tcode{g} is still considered to belong to this declarative region in spite of its -being hidden during qualified and unqualified name lookup.) -\exitexample +\rSec2[basic.scope.class]{Class scope} \pnum -The potential scope of a template parameter name begins at its point of -declaration~(\ref{basic.scope.pdecl}) and ends at the end of its declarative region. -\enternote This implies that a \grammarterm{template-parameter} can be used in the -declaration of subsequent \grammarterm{template-parameter}{s} and their default -arguments but cannot be used in preceding \grammarterm{template-parameter}{s} or their -default arguments. For example, - -\begin{codeblock} -template class X { /* ... */ }; -template void f(T* p = new T); -\end{codeblock} - -This also implies that a \grammarterm{template-parameter} can be used in the -specification of base classes. For example, - +Any declaration of a class or class template $C$ introduces +a \defnadj{class}{scope} +that includes the \grammarterm{member-specification} of +the \grammarterm{class-specifier} for $C$ (if any). +For each non-friend redeclaration or specialization +whose target scope is or is contained by the scope, +the portion after the +\grammarterm{declarator-id}, +\grammarterm{class-head-name}, or +\grammarterm{enum-head-name} is also included in the scope. +\begin{note} +Lookup from a program point +before the \grammarterm{class-specifier} of a class +will find no bindings in the class scope. +\begin{example} \begin{codeblock} -template class X : public Array { /* ... */ }; -template class Y : public T { /* ... */ }; -\end{codeblock} - -The use of a template parameter as a base class implies that a class used as a template -argument must be defined and not just declared when the class template is instantiated. -\exitnote - -\pnum -The declarative region of the name of a template parameter is nested within the -immediately-enclosing declarative region. \enternote As a result, a -\grammarterm{template-parameter} hides any entity with the same name in an enclosing -scope~(\ref{basic.scope.hiding}). \enterexample +template +struct B { + D::type x; // \#1 +}; -\begin{codeblock} -typedef int N; -template class T> struct A; +struct A { using type = int; }; +struct C : A, B {}; // error at \#1: \tcode{C::type} not found \end{codeblock} +\end{example} +\end{note} -Here, \tcode{X} is a non-type template parameter of type \tcode{int} and \tcode{Y} is a -non-type template parameter of the same type as the second template parameter of -\tcode{A}. \exitexample\exitnote - -\pnum -\enternote Because the name of a template parameter cannot be redeclared within its -potential scope~(\ref{temp.local}), a template parameter's scope is often its potential -scope. However, it is still possible for a template parameter name to be hidden; -see~\ref{temp.local}. \exitnote - -\rSec2[basic.scope.hiding]{Name hiding} - -\pnum -\indextext{scope~name~hiding~and}% -\indextext{name~hiding}% -\indextext{hiding|see{name hiding}}% -A name can be hidden by an explicit declaration of that same name in a -nested declarative region or derived class~(\ref{class.member.lookup}). +\rSec2[basic.scope.enum]{Enumeration scope}% \pnum -\indextext{name~hiding}% -A class name~(\ref{class.name}) or enumeration name~(\ref{dcl.enum}) can -be hidden by the name of a variable, data member, function, or enumerator declared in -the same scope. If a class or enumeration name and a variable, data member, function, -or enumerator are declared in the same scope (in any order) with the -same name, the class or enumeration name is hidden wherever the variable, data member, -function, or enumerator name is visible. +Any declaration of an enumeration $E$ introduces +an \defnadj{enumeration}{scope} +that includes the \grammarterm{enumerator-list} of +the \grammarterm{enum-specifier} for $E$ (if any). -\pnum -In a member function definition, the declaration of a name -at block scope -hides -the declaration of a member of the class with the same name; -see~\ref{basic.scope.class}. The declaration of a member in a derived -class (Clause~\ref{class.derived}) hides the declaration of a member of -a base class of the same name; see~\ref{class.member.lookup}. +\rSec2[basic.scope.temp]{Template parameter scope}% \pnum -During the lookup of a name qualified by a namespace name, declarations -that would otherwise be made visible by a \grammarterm{using-directive} can -be hidden by declarations with the same name in the namespace containing -the \grammarterm{using-directive;} see~(\ref{namespace.qual}). +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}. + +\pnum +Each \grammarterm{template-declaration} $D$ introduces +a template parameter scope +that extends from the beginning of its \grammarterm{template-parameter-list} +to the end of the \grammarterm{template-declaration}. +Any declaration outside the \grammarterm{template-parameter-list} +that would inhabit that scope instead inhabits the same scope as $D$. +The parent scope of any scope $S$ that is not a template parameter scope +is the smallest scope that contains $S$ and is not a template parameter scope. +\begin{note} +Therefore, only template parameters belong to a template parameter scope, and +only template parameter scopes have +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. -\pnum -\indextext{visibility}% -If a name is in scope and is not hidden it is said to be \defn{visible}.% \indextext{scope|)} \rSec1[basic.lookup]{Name lookup}% -\indextext{scope!name~lookup~and|(}% -\indextext{lookup!name|(}% + +\indextext{lookup!name|(} + +\rSec2[basic.lookup.general]{General}% +\indextext{scope!name lookup and|see{lookup, name}}% \pnum +\defnx{Name lookup}{lookup!name} associates the use of a name +with a set of declarations\iref{basic.def} of that name. The name lookup rules apply uniformly to all names (including -\grammarterm{typedef-name}{s}~(\ref{dcl.typedef}), -\grammarterm{namespace-name}{s}~(\ref{basic.namespace}), and -\grammarterm{class-name}{s}~(\ref{class.name})) wherever the grammar allows -such names in the context discussed by a particular rule. Name lookup -associates the use of a name with a declaration~(\ref{basic.def}) of -that name. Name lookup shall find an unambiguous declaration for the -name (see~\ref{class.member.lookup}). Name lookup may associate more -than one declaration with a name if it finds the name to be a function -name; the declarations are said to form a set of overloaded -functions~(\ref{over.load}). Overload resolution~(\ref{over.match}) -takes place after name lookup has succeeded. The access rules -(Clause~\ref{class.access}) are considered only once name lookup and +\grammarterm{typedef-name}{s}\iref{dcl.typedef}, +\grammarterm{namespace-name}{s}\iref{basic.namespace}, and +\grammarterm{class-name}{s}\iref{class.name}) wherever the grammar allows +such names in the context discussed by a particular rule. +Unless otherwise specified, +the program is ill-formed if no declarations are found. +If the declarations found by name lookup +all denote functions or function templates, +the declarations are said to form an \defn{overload set}. +Otherwise, +if the declarations found by name lookup do not all denote the same entity, +\indextext{lookup!ambiguous}% +they are \defn{ambiguous} and the program is ill-formed. +Overload resolution\iref{over.match,over.over} +takes place after name lookup has succeeded. The access rules\iref{class.access} +are considered only once name lookup and function overload resolution (if applicable) have succeeded. Only after name lookup, function overload resolution (if applicable) and access -checking have succeeded are the attributes introduced by the name's -declaration used further in expression processing (Clause~\ref{expr}). - -\pnum -A name ``looked up in the context of an expression'' is looked up as an -unqualified name in the scope where the expression is found. - -\pnum -The injected-class-name of a class (Clause~\ref{class}) is also -considered to be a member of that class for the purposes of name hiding -and lookup. - -\pnum -\enternote \ref{basic.link} discusses linkage issues. The notions of -scope, point of declaration and name hiding are discussed -in~\ref{basic.scope}. \exitnote - -\rSec2[basic.lookup.unqual]{Unqualified name lookup} - -\pnum -\indextext{lookup!unqualified~name}% -\indextext{name!unqualified}% -In all the cases listed in~\ref{basic.lookup.unqual}, the scopes are -searched for a declaration in the order listed in each of the respective -categories; name lookup ends as soon as a declaration is found for the -name. If no declaration is found, the program is ill-formed. +checking have succeeded +are the semantic properties introduced by the declarations +used in further processing. + +\pnum +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} +The declaration might appear in a scope that does not contain $P$. +\end{note} +\indextext{precede|see{declaration, precede}}% +A declaration $X$ \defnx{precedes}{declaration!precede} +a program point $P$ in a translation unit $L$ +if $P$ follows $X$, $X$ inhabits a class scope and is reachable from $P$, or +else $X$ appears in a translation unit $D$ and +\begin{itemize} +\item +$P$ follows +a \grammarterm{module-import-declaration} or \grammarterm{module-declaration} +that imports $D$ (directly or indirectly), and +\item +$X$ appears after the \grammarterm{module-declaration} in $D$ (if any) and +before the \grammarterm{private-module-fragment} in $D$ (if any), and +\item +either $X$ is exported or else $D$ and $L$ are part of the same module and +$X$ does not inhabit a namespace with internal linkage or +declare a name with internal linkage. +\begin{note} +Names declared by a \grammarterm{using-declaration} have no linkage. +\end{note} +\end{itemize} +\begin{note} +A \grammarterm{module-import-declaration} imports both +the named translation unit(s) and +any modules named by exported +\grammarterm{module-import-declaration}{s} within them, +recursively. +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module Q; +export int sq(int i) { return i*i; } +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +export module R; +export import Q; +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#3} +import R; +int main() { return sq(9); } // OK, \tcode{sq} from module \tcode{Q} +\end{codeblocktu} +\end{example} +\end{note} + +\pnum +\indextext{scope!search!single}% +A \defnadj{single}{search} in a scope $S$ +for a name $N$ from a program point $P$ +finds all declarations that precede $P$ +to which any name that is the same as $N$\iref{basic.pre} is bound in $S$. +If any such declaration is a \grammarterm{using-declarator} +whose terminal name\iref{expr.prim.id.unqual} +is not dependent\iref{temp.dep.type}, +it is replaced by the declarations named by +the \grammarterm{using-declarator}\iref{namespace.udecl}. + +\pnum +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 type alias or template) +is therefore hidden by any other entity in its scope. +\end{note} +\indextext{type-only!lookup|see{lookup, type-only}}% +However, if a lookup is \defnx{type-only}{lookup!type-only}, +only declarations of +types and templates whose specializations are types are considered; +furthermore, if declarations +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}% +\indextext{lookup!member name}% +\indextext{ambiguity!base class member}% +\indextext{ambiguity!member access} + +\pnum +\indextext{scope!search}% +A \defn{search} in a scope $X$ for a name $M$ from a program point $P$ +is a single search in $X$ for $M$ from $P$ +unless $X$ is the scope of a class or class template $T$, in which case the +following steps define the result of the search. +\begin{note} +The result differs only +if $M$ is a \grammarterm{conversion-function-id} or +if the single search would find nothing. +\end{note} + +\pnum +The \defn{lookup set} for a name $N$ in a class or class template $C$, called $S(N,C)$, +consists of two component sets: +the \term{declaration set}, a set of members named $N$; and +the \term{subobject set}, +a set of subobjects where declarations of these members were found +(possibly via \grammarterm{using-declaration}{s}). +In the declaration set, type declarations (including injected-class-names) +are replaced by the types they designate. $S(N,C)$ is calculated as follows: + +\pnum +The declaration set is the result of +a single search in the scope of $C$ for $N$ +from immediately after the \grammarterm{class-specifier} of $C$ +if $P$ is in a complete-class context of $C$ or +from $P$ otherwise. +If the resulting declaration set is not empty, the subobject set +contains $C$ itself, and calculation is complete. + +\pnum +Otherwise (i.e., $C$ does not contain a declaration of $N$ +or the resulting declaration set is empty), $S(N,C)$ is initially empty. +Calculate the lookup set for $N$ +in each direct non-dependent\iref{temp.dep.type} base class subobject $B_i$, and +merge each such lookup set $S(N,B_i)$ in turn into $S(N,C)$. +\begin{note} +If $C$ is incomplete, +only base classes whose \grammarterm{base-specifier} appears before $P$ +are considered. +If $C$ is an instantiated class, its base classes are not dependent. +\end{note} + +\pnum +The following steps define the result of merging lookup set $S(N,B_i)$ +into the intermediate $S(N,C)$: -\pnum -The declarations from the namespace nominated by a -\grammarterm{using-directive} become visible in a namespace enclosing the -\grammarterm{using-directive}; see~\ref{namespace.udir}. For the purpose of -the unqualified name lookup rules described -in~\ref{basic.lookup.unqual}, the declarations from the namespace -nominated by the \grammarterm{using-directive} are considered members of -that enclosing namespace. +\begin{itemize} +\item If each of the subobject members of $S(N,B_i)$ is a base class +subobject of at least one of the subobject members of $S(N,C)$, or if +$S(N,B_i)$ is empty, $S(N,C)$ is unchanged and the merge is complete. +Conversely, if each of the subobject members of $S(N,C)$ is a base class +subobject of at least one of the subobject members of $S(N,B_i)$, or if +$S(N,C)$ is empty, the new $S(N,C)$ is a copy of $S(N,B_i)$. + +\item Otherwise, if the declaration sets of $S(N,B_i)$ and $S(N,C)$ +differ, the merge is ambiguous: the new $S(N,C)$ is a lookup set with an +invalid declaration set and the union of the subobject sets. In +subsequent merges, an invalid declaration set is considered different +from any other. + +\item Otherwise, the new $S(N,C)$ is a lookup set with the shared set of +declarations and the union of the subobject sets. +\end{itemize} \pnum -The lookup for an unqualified name used as the -\grammarterm{postfix-expression} of a function call is described -in~\ref{basic.lookup.argdep}. \enternote For purposes of determining -(during parsing) whether an expression is a -\grammarterm{postfix-expression} for a function call, the usual name lookup -rules apply. The rules in~\ref{basic.lookup.argdep} have no effect on -the syntactic interpretation of an expression. For example, - +The result of the search is the declaration set of $S(M,T)$. +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. +\begin{example} \begin{codeblock} -typedef int f; -namespace N { - struct A { - friend void f(A &); - operator int(); - void g(A a) { - int i = f(a); // \tcode{f} is the typedef, not the friend - // function: equivalent to \tcode{int(a)} - } - }; +struct A { int x; }; // S(x,A) = \{ \{ \tcode{A::x} \}, \{ \tcode{A} \} \} +struct B { float x; }; // S(x,B) = \{ \{ \tcode{B::x} \}, \{ \tcode{B} \} \} +struct C: public A, public B { }; // S(x,C) = \{ invalid, \{ \tcode{A} in \tcode{C}, \tcode{B} in \tcode{C} \} \} +struct D: public virtual C { }; // S(x,D) = S(x,C) +struct E: public virtual C { char x; }; // S(x,E) = \{ \{ \tcode{E::x} \}, \{ \tcode{E} \} \} +struct F: public D, public E { }; // S(x,F) = S(x,E) +int main() { + F f; + f.x = 0; // OK, lookup finds \tcode{E::x} } \end{codeblock} -Because the expression is not a function call, the argument-dependent -name lookup~(\ref{basic.lookup.argdep}) does not apply and the friend -function \tcode{f} is not found. \exitnote - -\pnum -A name used in global scope, outside of any function, class or -user-declared namespace, shall be declared before its use in global -scope. - -\pnum -A name used in a user-declared namespace outside of the definition of -any function or class shall be declared before its use in that namespace -or before its use in a namespace enclosing its namespace. - -\pnum -A name used in the definition of a function following the function's -\grammarterm{declarator-id}\footnote{This refers to unqualified names -that occur, for instance, in -a type or default argument in the -\grammarterm{parameter-declaration-clause} or used in the function body.} -that is a member of namespace \tcode{N} (where, only for the purpose of -exposition, \tcode{N} could represent the global scope) shall be -declared before its use in the block in which it is used or in one of -its enclosing blocks~(\ref{stmt.block}) or, shall be declared before its -use in namespace \tcode{N} or, if \tcode{N} is a nested namespace, shall -be declared before its use in one of \tcode{N}'s enclosing namespaces. -\enterexample - +$S(\tcode{x},\tcode{F})$ is unambiguous because the \tcode{A} and \tcode{B} base +class subobjects of \tcode{D} are also base class subobjects of \tcode{E}, so +$S(\tcode{x},\tcode{D})$ is discarded in the first merge step. +\end{example} + +\pnum +If $M$ is a non-dependent \grammarterm{conversion-function-id}, +conversion function templates that are members of $T$ are considered. +For each such template $F$, the lookup set $S(t,T)$ is constructed, +considering a function template declaration to have the name $t$ +only if it corresponds to a declaration of $F$\iref{basic.scope.scope}. +The members of the declaration set of each such lookup set, +which shall not be an invalid set, are included in the result. +\begin{note} +Overload resolution will discard those +that cannot convert to the type specified by $M$\iref{temp.over}. +\end{note} + +\pnum +\begin{note} +A static member, a nested type or an enumerator defined in a base class +\tcode{T} can unambiguously be found even if an object has more than one +base class subobject of type \tcode{T}. Two base class subobjects share +the non-static member subobjects of their common virtual base classes. +\end{note} +\begin{example} \begin{codeblock} -namespace A { - namespace N { - void f(); - } -} -void A::N::f() { - i = 5; - // The following scopes are searched for a declaration of \tcode{i}: - // 1) outermost block scope of \tcode{A::N::f}, before the use of \tcode{i} - // 2) scope of namespace \tcode{N} - // 3) scope of namespace \tcode{A} - // 4) global scope, before the definition of \tcode{A::N::f} +struct V { + int v; +}; +struct A { + int a; + static int s; + enum { e }; +}; +struct B : A, virtual V { }; +struct C : A, virtual V { }; +struct D : B, C { }; + +void f(D* pd) { + pd->v++; // OK, only one \tcode{v} (virtual) + pd->s++; // OK, only one \tcode{s} (static) + int i = pd->e; // OK, only one \tcode{e} (enumerator) + pd->a++; // error: ambiguous: two \tcode{a}{s} in \tcode{D} } \end{codeblock} -\exitexample - -\pnum -A name used in the definition of a class \tcode{X} outside of a member -function body, default argument, \grammarterm{exception-specification}, -\grammarterm{brace-or-equal-initializer} of a non-static data member, -or nested class definition\footnote{This refers to unqualified names -following the class name; such a name may be used in the -\grammarterm{base-clause} or may be used in the class definition.} -shall be declared in one of the following ways: - -\begin{itemize} -\item before its use in class \tcode{X} or be a member of a base class -of \tcode{X}~(\ref{class.member.lookup}), or -\item if \tcode{X} is a nested class of class -\tcode{Y}~(\ref{class.nest}), before the definition of \tcode{X} in -\tcode{Y}, or shall be a member of a base class of \tcode{Y} (this -lookup applies in turn to \tcode{Y} 's enclosing classes, starting with -the innermost enclosing class),\footnote{This lookup applies whether the -definition of \tcode{X} is -nested within \tcode{Y}'s definition or whether \tcode{X}'s definition -appears in a namespace scope enclosing \tcode{Y} 's -definition~(\ref{class.nest}).} -or -\item if \tcode{X} is a local class~(\ref{class.local}) or is a nested -class of a local class, before the definition of class \tcode{X} in a -block enclosing the definition of class \tcode{X}, or -\item if \tcode{X} is a member of namespace \tcode{N}, or is a nested -class of a class that is a member of \tcode{N}, or is a local class or a -nested class within a local class of a function that is a member of -\tcode{N}, before the definition of class \tcode{X} in namespace -\tcode{N} or in one of \tcode{N} 's enclosing namespaces. -\end{itemize} - -\enterexample - +\end{example} + +\pnum +\begin{note} +\indextext{dominance!virtual base class}% +When virtual base classes are used, a hidden declaration can be reached +along a path through the subobject lattice that does not pass through +the hiding declaration. This is not an ambiguity. The identical use with +non-virtual base classes is an ambiguity; in that case there is no +unique instance of the name that hides all the others. +\end{note} +\begin{example} \begin{codeblock} -namespace M { - class B { }; -} +struct V { int f(); int x; }; +struct W { int g(); int y; }; +struct B : virtual V, W { + int f(); int x; + int g(); int y; +}; +struct C : virtual V, W { }; +struct D : B, C { void glorp(); }; \end{codeblock} + +\begin{importgraphic} +{Name lookup} +{class.lookup} +{figname.pdf} +\end{importgraphic} + +As illustrated in \fref{class.lookup}, +the names declared in \tcode{V} and the left-hand instance of \tcode{W} +are hidden by those in \tcode{B}, but the names declared in the +right-hand instance of \tcode{W} are not hidden at all. \begin{codeblock} -namespace N { - class Y : public M::B { - class X { - int a[i]; - }; - }; +void D::glorp() { + x++; // OK, \tcode{B::x} hides \tcode{V::x} + f(); // OK, \tcode{B::f()} hides \tcode{V::f()} + y++; // error: \tcode{B::y} and \tcode{C}'s \tcode{W::y} + g(); // error: \tcode{B::g()} and \tcode{C}'s \tcode{W::g()} } - -// The following scopes are searched for a declaration of \tcode{i}: -// 1) scope of class \tcode{N::Y::X}, before the use of \tcode{i} -// 2) scope of class \tcode{N::Y}, before the definition of \tcode{N::Y::X} -// 3) scope of \tcode{N::Y}'s base class \tcode{M::B} -// 4) scope of namespace \tcode{N}, before the definition of \tcode{N::Y} -// 5) global scope, before the definition of \tcode{N} \end{codeblock} +\end{example} +\indextext{ambiguity!class conversion}% -\exitexample \enternote When looking for a prior declaration of a class -or function introduced by a \tcode{friend} declaration, scopes outside -of the innermost enclosing namespace scope are not considered; -see~\ref{namespace.memdef}. \exitnote \enternote \ref{basic.scope.class} -further describes the restrictions on the use of names in a class -definition. \ref{class.nest} further describes the restrictions on the -use of names in nested class definitions. \ref{class.local} further -describes the restrictions on the use of names in local class -definitions. \exitnote - -\pnum -For the members of a class \tcode{X}, a name used in a member function -body, in a default argument, in an \grammarterm{exception-specification}, in the -\grammarterm{brace-or-equal-initializer} of a non-static data -member~(\ref{class.mem}), or in the definition of a class member -outside of the definition of \tcode{X}, following the -member's -\grammarterm{declarator-id}\footnote{That is, an unqualified name that occurs, -for instance, in a -type in the -\grammarterm{parameter-declaration-clause} or in the -\grammarterm{exception-specification}.}, shall be declared in one of the -following ways: - -\begin{itemize} -\item before its use in the block in which it is used or in an enclosing -block~(\ref{stmt.block}), or - -\item shall be a member of class \tcode{X} or be a member of a base -class of \tcode{X}~(\ref{class.member.lookup}), or - -\item if \tcode{X} -is a nested class of class \tcode{Y}~(\ref{class.nest}), shall be a -member of \tcode{Y}, or shall be a member of a base class of \tcode{Y} -(this lookup applies in turn to \tcode{Y}'s enclosing classes, starting -with the innermost enclosing class),\footnote{This lookup applies whether -the member function is defined -within the definition of class \tcode{X} or whether the member function -is defined in a namespace scope enclosing \tcode{X}'s definition.} -or - -\item if \tcode{X} is a local class~(\ref{class.local}) or is a nested -class of a local class, before the definition of class \tcode{X} in a -block enclosing the definition of class \tcode{X}, or - -\item if \tcode{X} is a member of namespace \tcode{N}, or is a nested -class of a class that is a member of \tcode{N}, or is a local class or a -nested class within a local class of a function that is a member of -\tcode{N}, before the use of the name, in namespace \tcode{N} -or in one of \tcode{N} 's enclosing namespaces. -\end{itemize} - -\enterexample +\pnum +An explicit or implicit conversion from a pointer to or +an expression designating an object +of a +derived class to a pointer or reference to one of its base classes shall +unambiguously refer to a unique object representing the base class. +\begin{example} \begin{codeblock} -class B { }; -namespace M { - namespace N { - class X : public B { - void f(); - }; - } -} -void M::N::X::f() { - i = 16; -} +struct V { }; +struct A { }; +struct B : A, virtual V { }; +struct C : A, virtual V { }; +struct D : B, C { }; -// The following scopes are searched for a declaration of \tcode{i}: -// 1) outermost block scope of \tcode{M::N::X::f}, before the use of \tcode{i} -// 2) scope of class \tcode{M::N::X} -// 3) scope of \tcode{M::N::X}'s base class \tcode{B} -// 4) scope of namespace \tcode{M::N} -// 5) scope of namespace \tcode{M} -// 6) global scope, before the definition of \tcode{M::N::X::f} +void g() { + D d; + B* pb = &d; + A* pa = &d; // error: ambiguous: \tcode{C}'s \tcode{A} or \tcode{B}'s \tcode{A}? + V* pv = &d; // OK, only one \tcode{V} subobject +} \end{codeblock} -\exitexample \enternote \ref{class.mfct} and~\ref{class.static} further -describe the restrictions on the use of names in member function -definitions. \ref{class.nest} further describes the restrictions on the -use of names in the scope of nested classes. \ref{class.local} further -describes the restrictions on the use of names in local class -definitions. \exitnote - -\pnum -Name lookup for a name used in the definition of a \tcode{friend} -function~(\ref{class.friend}) defined inline in the class granting -friendship shall proceed as described for lookup in member function -definitions. If the \tcode{friend} function is not defined in the class -granting friendship, name lookup in the \tcode{friend} function -definition shall proceed as described for lookup in namespace member -function definitions. - -\pnum -In a \tcode{friend} declaration naming a member function, a name used in -the function declarator and not part of a \grammarterm{template-argument} -in the \grammarterm{declarator-id} is first looked up in the scope of the -member function's class~(\ref{class.member.lookup}). If it is not found, -or if the name is part of a -\grammarterm{template-argument} in -the \grammarterm{declarator-id}, the look up is -as described for unqualified names in the definition of the class -granting friendship. \enterexample +\end{example} +\pnum +\begin{note} +Even if the result of name lookup is unambiguous, use of a name found in +multiple subobjects might still be +ambiguous\iref{conv.mem,expr.ref,class.access.base}. +\end{note} +\begin{example} \begin{codeblock} -struct A { - typedef int AT; - void f1(AT); - void f2(float); - template void f3(); +struct B1 { + void f(); + static void f(int); + int i; }; -struct B { - typedef char AT; - typedef float BT; - friend void A::f1(AT); // parameter type is \tcode{A::AT} - friend void A::f2(BT); // parameter type is \tcode{B::BT} - friend void A::f3(); // template argument is \tcode{B::AT} +struct B2 { + void f(double); +}; +struct I1: B1 { }; +struct I2: B1 { }; + +struct D: I1, I2, B2 { + using B1::f; + using B2::f; + void g() { + f(); // Ambiguous conversion of \keyword{this} + f(0); // Unambiguous (static) + f(0.0); // Unambiguous (only one \tcode{B2}) + int B1::* mpB1 = &D::i; // Unambiguous + int D::* mpD = &D::i; // Ambiguous conversion + } }; \end{codeblock} -\exitexample +\end{example} -\pnum -During the lookup for a name used as a default -argument~(\ref{dcl.fct.default}) in a function -\grammarterm{parameter-declaration-clause} or used in the -\grammarterm{expression} of a \grammarterm{mem-initializer} for a -constructor~(\ref{class.base.init}), the function parameter names are -visible and hide the names of entities declared in the block, class or -namespace scopes containing the function declaration. \enternote -\ref{dcl.fct.default} further describes the restrictions on the use of -names in default arguments. \ref{class.base.init} further describes the -restrictions on the use of names in a \grammarterm{ctor-initializer}. -\exitnote +\rSec2[basic.lookup.unqual]{Unqualified name lookup} -\pnum -During the lookup of a name used in the -\grammarterm{constant-expression} of an \grammarterm{enumerator-definition}, -previously declared \grammarterm{enumerator}{s} of the enumeration are visible -and hide the names of entities declared in the block, class, or namespace -scopes containing the \grammarterm{enum-specifier}. +\indextext{name!unqualified}% \pnum -A name used in the definition of a \tcode{static} data member of class -\tcode{X}~(\ref{class.static.data}) (after the \grammarterm{qualified-id} -of the static member) is looked up as if the name was used in a member -function of \tcode{X}. \enternote \ref{class.static.data} further -describes the restrictions on the use of names in the definition of a -\tcode{static} data member. \exitnote +A \grammarterm{using-directive} is +\term{active} in a scope $S$ at a program point $P$ +if it precedes $P$ and inhabits either $S$ or +the scope of a namespace nominated by a \grammarterm{using-directive} +that is active in $S$ at $P$. \pnum -If a variable member of a namespace is defined outside of the scope of -its namespace then any name that appears in the definition of the -member (after the \grammarterm{declarator-id}) is looked up as if the -definition of the member occurred in its namespace. -\enterexample - +An \term{unqualified search} in a scope $S$ from a program point $P$ +includes the results of searches from $P$ in +\begin{itemize} +\item +$S$, and +\item +for any scope $U$ that contains $P$ and is or is contained by $S$, +each namespace contained by $S$ that is nominated by +a \grammarterm{using-directive} that is active in $U$ at $P$. +\end{itemize} +If no declarations are found, +the results of the unqualified search are +the results of an unqualified search in the parent scope of $S$, if any, +from $P$. +\begin{note} +When a class scope is searched, +the scopes of its base classes are also searched\iref{class.member.lookup}. +If it inherits from a single base, +it is as if the scope of the base immediately contains +the scope of the derived class. +Template parameter scopes +that are associated with one scope in the chain of parents +are also considered\iref{temp.local}. +\end{note} + +\pnum +\defnx{Unqualified name lookup}{lookup!unqualified name} +from a program point performs an unqualified search in its immediate scope. + +\pnum +An \defnadj{unqualified}{name} is a name +that does not immediately follow a \grammarterm{nested-name-specifier} or +the \tcode{.} or \tcode{->} in a class member access expression\iref{expr.ref}, +possibly after a \keyword{template} keyword or \tcode{\~}. +Unless otherwise specified, +such a name undergoes unqualified name lookup from the point where it appears. + +\pnum +An unqualified name that is a component name\iref{expr.prim.id.unqual} of +a \grammarterm{type-specifier} or \grammarterm{ptr-operator} of +a \grammarterm{conversion-type-id} is looked up in the same fashion +as the \grammarterm{conversion-function-id} in which it appears. +If that lookup finds nothing, it undergoes unqualified name lookup; +in each case, only names +that denote types or templates whose specializations are types are considered. +\begin{example} \begin{codeblock} -namespace N { - int i = 4; - extern int j; -} +struct T1 { struct U { int i; }; }; +struct T2 { }; +struct U1 {}; +struct U2 {}; -int i = 2; +struct B { + using T = T1; + using U = U1; + operator U1 T1::*(); + operator U1 T2::*(); + operator U2 T1::*(); + operator U2 T2::*(); +}; -int N::j = i; // \tcode{N::j == 4} +template +int g() { + using U = U2; + X().operator U T::*(); // \#1, searches for \tcode{T} in the scope of \tcode{X} first + X().operator U decltype(T())::*(); // \#2 + return 0; +} +int x = g(); // \#1 calls \tcode{B::operator U1 T1::*} + // \#2 calls \tcode{B::operator U1 T2::*} \end{codeblock} -\exitexample - -\pnum -A name used in the handler for a \grammarterm{function-try-block} -(Clause~\ref{except}) is looked up as if the name was used in the -outermost block of the function definition. In particular, the function -parameter names shall not be redeclared in the -\grammarterm{exception-declaration} nor in the outermost block of a handler -for the \grammarterm{function-try-block}. Names declared in the outermost -block of the function definition are not found when looked up in the -scope of a handler for the \grammarterm{function-try-block}. \enternote But -function parameter names are found. \exitnote - -\pnum -\enternote The rules for name lookup in template definitions are -described in~\ref{temp.res}. \exitnote +\end{example} + +\pnum +In a friend declaration \grammarterm{declarator} +whose \grammarterm{declarator-id} is a \grammarterm{qualified-id} +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$. +If that lookup finds nothing, it undergoes unqualified name lookup. +\begin{example} +\begin{codeblock} +using I = int; +using D = double; +namespace A { + inline namespace N {using C = char; } + using F = float; + void f(I); + void f(D); + void f(C); + void f(F); +} +struct X0 {using F = float; }; +struct W { + using D = void; + struct X : X0 { + void g(I); + void g(::D); + void g(F); + }; +}; +namespace B { + typedef short I, F; + class Y { + friend void A::f(I); // error: no \tcode{void A::f(short)} + friend void A::f(D); // OK + friend void A::f(C); // error: \tcode{A::N::C} not found + friend void A::f(F); // OK + friend void W::X::g(I); // error: no \tcode{void X::g(short)} + friend void W::X::g(D); // OK + friend void W::X::g(F); // OK + }; +} +\end{codeblock} +\end{example} \rSec2[basic.lookup.argdep]{Argument-dependent name lookup}% \indextext{lookup!argument-dependent} \pnum When the \grammarterm{postfix-expression} in -a function call~(\ref{expr.call}) is an \grammarterm{unqualified-id}, other namespaces not considered -during the usual unqualified lookup~(\ref{basic.lookup.unqual}) may be -searched, and in those namespaces, namespace-scope friend function or -function template declarations~(\ref{class.friend}) not otherwise -visible may be found. -These modifications to the search depend on the types of the arguments -(and for template template arguments, the namespace of the template -argument). -\enterexample - +a function call\iref{expr.call} is an \grammarterm{unqualified-id}, +and unqualified lookup\iref{basic.lookup.unqual} +for the name in the \grammarterm{unqualified-id} does not find any +\begin{itemize} +\item +declaration of a class member, or +\item +function declaration inhabiting a block scope, or +\item +declaration not of a function or function template +\end{itemize} +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 type template template arguments, the namespace of the template argument), +as specified below. +\begin{example} \begin{codeblock} namespace N { struct S { }; @@ -1427,99 +2160,209 @@ void g() { N::S s; - f(s); // OK: calls \tcode{N::f} - (f)(s); // error: \tcode{N::f} not considered; parentheses - // prevent argument-dependent lookup + f(s); // OK, calls \tcode{N::f} + (f)(s); // error: \tcode{N::f} not considered; parentheses prevent argument-dependent lookup } \end{codeblock} - -\exitexample +\end{example} \pnum -For each argument type \tcode{T} in the function call, there is a set of -zero or more associated namespaces and a set of zero or more associated -classes to be considered. The sets of namespaces and classes is -determined entirely by the types of the function arguments (and the -namespace of any template template argument). Typedef names and -\grammarterm{using-declaration}{s} used to specify the types do not -contribute to this set. The sets of namespaces and classes are -determined in the following way: - -\begin{itemize} -\item If \tcode{T} is a fundamental type, its associated sets of -namespaces and classes are both empty. - -\item If \tcode{T} is a class type (including unions), its associated -classes are: the class itself; the class of which it is a member, if -any; and its direct and indirect base classes. Its associated namespaces -are the innermost enclosing namespaces of its associated classes. -Furthermore, if \tcode{T} is a class template specialization, its -associated namespaces and classes also include: the namespaces and -classes associated with the types of the template arguments provided for -template type parameters (excluding template template parameters); the -namespaces of which any template template arguments are members; and the -classes of which any member templates used as template template -arguments are members. \enternote Non-type template arguments do not -contribute to the set of associated namespaces.\exitnote - -\item If \tcode{T} is an enumeration type, its associated namespace is -the innermost enclosing namespace of its declaration. If it is a class member, its -associated class is the member's class; else it has no associated class. - -\item If \tcode{T} is a pointer to \tcode{U} or an array of \tcode{U}, -its associated namespaces and classes are those associated with -\tcode{U}. - -\item If \tcode{T} is a function type, its associated namespaces and -classes are those associated with the function parameter types and those -associated with the return type. +\begin{note} +For purposes of determining +(during parsing) whether an expression is a +\grammarterm{postfix-expression} for a function call, the usual name lookup +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} +(see \ref{temp.names}). +For example, +\begin{codeblock} +int h; +void g(); +namespace N { + struct A {}; + template int f(T); + template int g(T); + template int h(T); +} -\item If \tcode{T} is a pointer to a member function of a class -\tcode{X}, its associated namespaces and classes are those associated -with the function parameter types and return type, together with those -associated with \tcode{X}. +int x = f(N::A()); // OK, lookup of \tcode{f} finds nothing, \tcode{f} treated as template name +int y = g(N::A()); // OK, lookup of \tcode{g} finds a function, \tcode{g} treated as template name +int z = h(N::A()); // error: \tcode{h<} does not begin a \grammarterm{template-id} +\end{codeblock} -\item If \tcode{T} is a pointer to a data member of class \tcode{X}, its -associated namespaces and classes are those associated with the member -type together with those associated with \tcode{X}. - -\end{itemize} - -If an associated namespace is an inline namespace~(\ref{namespace.def}), its -enclosing namespace is also included in the set. If an associated namespace -directly contains inline namespaces, those inline namespaces are also included -in the set. -In addition, if the argument is the name or address of a set of -overloaded functions and/or function templates, its associated classes -and namespaces are the union of those associated with each of the -members of the set, i.e., the classes and namespaces associated with its -parameter types and return type. -Additionally, if the aforementioned set of overloaded functions is named with -a \grammarterm{template-id}, its associated classes and namespaces also include -those of its type \grammarterm{template-argument}{s} and its template -\grammarterm{template-argument}{s}. - -\pnum -Let \term{X} be the lookup set produced by unqualified -lookup~(\ref{basic.lookup.unqual}) and let \term{Y} be the lookup set produced -by argument dependent lookup (defined as follows). If \term{X} contains +The rules have no effect on the syntactic interpretation of an expression. +For example, +\begin{codeblock} +typedef int f; +namespace N { + struct A { + friend void f(A &); + operator int(); + void g(A a) { + int i = f(a); // \tcode{f} is the typedef, not the friend function: equivalent to \tcode{int(a)} + } + }; +} +\end{codeblock} +Because the expression is not a function call, +argument-dependent name lookup does not apply and +the friend function \tcode{f} is not found. +\end{note} + +\pnum +For each argument type \tcode{T} in the function call, +there is a set of zero or more \defnx{associated entities}{entity!associated} +to be considered. +The set of entities is determined entirely by +the types of the function 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 a declaration of a class member, or +\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), +its associated entities are: +the class itself; +the class of which it is a member, if any; +and, if it is a complete type, its direct and indirect base classes. +Furthermore, if \tcode{T} is a class template specialization, +its associated entities also include: +the entities +associated with the types of the template arguments +provided for template type parameters; +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} +Constant template arguments, +variable template template arguments, and +concept template arguments +do not +contribute to the set of associated entities. +\end{note} + +\item If \tcode{T} is an enumeration type, +its associated entities are \tcode{T} +and, if it is a class member, the member's class. + +\item If \tcode{T} is a pointer to \tcode{U} or an array of \tcode{U}, +its associated entities are those associated with \tcode{U}. -\item a block-scope function declaration that is not a -\grammarterm{using-declaration}, or +\item If \tcode{T} is a function type, its associated +entities are those associated with the function parameter types and those +associated with the return type. -\item a declaration that is neither a function or a function template +\item If \tcode{T} is a pointer to a member function of a class +\tcode{X}, its associated entities are those associated +with the function parameter types and return type, together with those +associated with \tcode{X}. +\item If \tcode{T} is a pointer to a data member of class \tcode{X}, its +associated entities are those associated with the member +type together with those associated with \tcode{X}. +\end{itemize} +In addition, if the argument is an overload set or the address of such a set, +its associated entities +are the union of those associated with each of the +members of the set, i.e., the entities associated with its +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 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 +\begin{itemize} +\item +are found by a search of 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 +\item +are exported, +are attached to a named module \tcode{M}\iref{module.interface}, +do not appear in the translation unit containing the point of the lookup, and +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} -then \term{Y} is empty. Otherwise \term{Y} is the set of declarations -found in the namespaces associated with the argument types as described -below. The set of declarations found by the lookup of the name is the -union of \term{X} and \term{Y}. \enternote The namespaces and classes -associated with the argument types can include namespaces and classes -already considered by the ordinary unqualified lookup. \exitnote -\enterexample +If the lookup is for 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 +appears in another translation unit, +is attached to the global module, and +is either discarded\iref{module.global.frag} or has internal linkage. + +\pnum +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module M; +namespace R { + export struct X {}; + export void f(X); +} +namespace S { + export void f(R::X, R::X); +} +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#2} +export module N; +import M; +export R::X make(); +namespace R { static int g(X); } +export template void apply(T t, U u) { + f(t, u); + g(t); +} +\end{codeblocktu} + +\begin{codeblocktu}{Translation unit \#3} +module Q; +import N; +namespace S { + struct Z { template operator T(); }; +} +void test() { + auto x = make(); // OK, \tcode{decltype(x)} is \tcode{R::X} in module \tcode{M} + R::f(x); // error: \tcode{R} and \tcode{R::f} are not visible here + f(x); // OK, calls \tcode{R::f} from interface of \tcode{M} + f(x, S::Z()); // error: \tcode{S::f} in module \tcode{M} not considered + // even though \tcode{S} is an associated namespace + apply(x, S::Z()); // error: \tcode{S::f} is visible in instantiation context, but + // \tcode{R::g} has internal linkage and cannot be used outside TU \#2 +} +\end{codeblocktu} +\end{example} +\pnum +\begin{note} +The set of associated namespaces can include namespaces +already considered by ordinary unqualified lookup. +\end{note} +\begin{example} \begin{codeblock} namespace NS { class T { }; @@ -1529,52 +2372,37 @@ NS::T parm; void g(NS::T, float); int main() { - f(parm); // OK: calls \tcode{NS::f} + f(parm); // OK, calls \tcode{NS::f} extern void g(NS::T, float); - g(parm, 1); // OK: calls \tcode{g(NS::T, float)} + g(parm, 1); // OK, calls \tcode{g(NS::T, float)} } \end{codeblock} -\exitexample - -\pnum -When considering an associated namespace, the lookup is the same as the -lookup performed when the associated namespace is used as a -qualifier~(\ref{namespace.qual}) except that: - -\begin{itemize} -\item Any \grammarterm{using-directive}{s} in the associated namespace are -ignored. - -\item Any namespace-scope friend functions or friend function templates -declared in associated classes are visible within their respective -namespaces even if they are not visible during an ordinary -lookup~(\ref{class.friend}). - -\item All names except those of (possibly overloaded) functions and -function templates are ignored. - -\end{itemize} +\end{example} \rSec2[basic.lookup.qual]{Qualified name lookup} +\rSec3[basic.lookup.qual.general]{General} + \pnum -\indextext{lookup!qualified~name|(}% +\indextext{lookup!qualified name|(}% \indextext{name!qualified}% \indextext{qualification!explicit}% -The name of a class or namespace member -or enumerator can be referred to after the -\tcode{::} scope resolution operator~(\ref{expr.prim}) applied to a -\grammarterm{nested-name-specifier} that denotes its class, -namespace, or enumeration. +Lookup of an \grammarterm{identifier} +followed by a \tcode{::} scope resolution operator +considers only +namespaces, types, and templates whose specializations are types. If a -\tcode{::} scope resolution -operator -in a \grammarterm{nested-name-specifier} is not preceded by a \grammarterm{decltype-specifier}, -lookup of the name preceding that \tcode{::} considers only namespaces, types, and -templates whose specializations are types. If the -name found does not designate a namespace or a class, enumeration, or dependent type, -the program is ill-formed.\enterexample - +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}. +\begin{example} \begin{codeblock} class A { public: @@ -1582,66 +2410,140 @@ }; int main() { int A; - A::n = 42; // OK - A b; // ill-formed: \tcode{A} does not name a type + A::n = 42; // OK + A b; // error: \tcode{A} does not name a type +} +template struct B : A {}; +namespace N { + template void B(); + int f() { + return B<0>::n; // error: \tcode{N::B<0>} is not a type + } } \end{codeblock} -\exitexample +\end{example} -\pnum -\enternote Multiply qualified names, such as \tcode{N1::N2::N3::n}, can -be used to refer to members of nested classes~(\ref{class.nest}) or -members of nested namespaces. \exitnote +\indextext{operator!scope resolution}% +\indextext{scope resolution operator|see{operator, scope resolution}}% \pnum -In a declaration in which the \grammarterm{declarator-id} is a -\grammarterm{qualified-id}, names used before the \grammarterm{qualified-id} -being declared are looked up in the defining namespace scope; names -following the \grammarterm{qualified-id} are looked up in the scope of the -member's class or namespace. \enterexample - +A \defnadj{member-qualified}{name} is +the (unique) component name\iref{expr.prim.id.unqual}, if any, of +\begin{itemize} +\item +an \grammarterm{unqualified-id} or +\item +a \grammarterm{nested-name-specifier} of the form +\grammarterm{type-name} \tcode{::} or \grammarterm{namespace-name} \tcode{::} +\end{itemize} +in the \grammarterm{id-expression} of a class member access expression\iref{expr.ref}. +A \defnadj{qualified}{name} is +\begin{itemize} +\item a member-qualified name or +\item the terminal name of +\begin{itemize} +\item a \grammarterm{qualified-id}, +\item a \grammarterm{using-declarator}, +\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}. +\end{itemize} +\end{itemize} +The \defn{lookup context} of a member-qualified name is +the type of its associated object expression +(considered dependent if the object expression is type-dependent). +The lookup context of any other qualified name is +the type, template, or namespace +nominated by the preceding \grammarterm{nested-name-specifier}. +\begin{note} +When parsing a class member access, +the name following the \tcode{->} or \tcode{.} is +a qualified name even though it is not yet known of which kind. +\end{note} +\begin{example} +In +\begin{codeblock} + N::C::m.Base::f() +\end{codeblock} +\tcode{Base} is a member-qualified name; +the other qualified names are \tcode{C}, \tcode{m}, and \tcode{f}. +\end{example} + +\pnum +\defnx{Qualified name lookup}{lookup!qualified name} +in a class, namespace, or enumeration performs +a search of the scope associated with it\iref{class.member.lookup} +except as specified below. +Unless otherwise specified, +a qualified name undergoes qualified name lookup in its lookup context +from the point where it appears +unless the lookup context either +is dependent and is not the current instantiation\iref{temp.dep.type} or +is not a class or class template. +If nothing is found by qualified lookup for a member-qualified name +that is the terminal name\iref{expr.prim.id.unqual} of +a \grammarterm{nested-name-specifier} and +is not dependent, it undergoes unqualified lookup. +\begin{note} +During lookup for a template specialization, no names are dependent. +\end{note} +\begin{example} \begin{codeblock} -class X { }; -class C { - class X { }; - static const int number = 50; - static X arr[number]; +int f(); +struct A { + int B, C; + template using D = void; + using T = void; + void f(); }; -X C::arr[number]; // ill-formed: - // equivalent to: \tcode{::X} \tcode{C::arr[C::number];} - // not to: \tcode{C::X} \tcode{C::arr[C::number];} +using B = A; +template using C = A; +template using D = A; +template using X = A; + +template +void g(T *p) { // as instantiated for \tcode{g}: + p->X<0>::f(); // error: \tcode{A::X} not found in \tcode{((p->X) < 0) > ::f()} + p->template X<0>::f(); // OK, \tcode{::X} found in definition context + p->B::f(); // OK, non-type \tcode{A::B} ignored + p->template C<0>::f(); // error: \tcode{A::C} is not a template + p->template D<0>::f(); // error: \tcode{A::D<0>} is not a class type + p->T::f(); // error: \tcode{A::T} is not a class type +} +template void g(A*); \end{codeblock} -\exitexample - -\pnum -\indextext{scope~resolution~operator}% -A name prefixed by the unary scope operator \tcode{::}~(\ref{expr.prim}) -is looked up in global scope, in the translation unit where it is used. -The name shall be declared in global namespace scope or shall be a name -whose declaration is visible in global scope because of a -\grammarterm{using-directive}~(\ref{namespace.qual}). The use of \tcode{::} -allows a global name to be referred to even if its identifier has been -hidden~(\ref{basic.scope.hiding}). +\end{example} \pnum -A name prefixed by a \grammarterm{nested-name-specifier} that -nominates an enumeration type shall represent an \grammarterm{enumerator} -of that enumeration. - -\pnum -If a \grammarterm{pseudo-destructor-name}~(\ref{expr.pseudo}) contains a -\grammarterm{nested-name-specifier}, the \grammarterm{type-name}{s} are looked -up as types in the scope designated by the -\grammarterm{nested-name-specifier}. Similarly, in a -\grammarterm{qualified-id} of the form: - -\begin{ncbnf} -nested-name-specifier\opt class-name \terminal{::} \terminal{\tilde} class-name -\end{ncbnf} - -the second \grammarterm{class-name} is looked up in the same scope as the -first. \enterexample - +If a qualified name $Q$ follows a \tcode{\~}: +\begin{itemize} +\item +If $Q$ is a member-qualified name, +it undergoes unqualified lookup as well as qualified lookup. +\item +Otherwise, its \grammarterm{nested-name-specifier} $N$ shall nominate a type. +If $N$ has another \grammarterm{nested-name-specifier} $S$, +$Q$ is looked up as if its lookup context were that nominated by $S$. +\item +Otherwise, if the terminal name of $N$ is a member-qualified name $M$, +$Q$ is looked up as if $\tcode{\~}Q$ appeared in place of $M$ (as above). +\item +Otherwise, $Q$ undergoes unqualified lookup. +\item +Each lookup for $Q$ considers only +types (if $Q$ is not followed by a \tcode{<}) and +templates whose specializations are types. +If it finds nothing or is ambiguous, it is discarded. +\item +The \grammarterm{type-name} that is or contains $Q$ +shall refer to its (original) lookup context (ignoring cv-qualification) under +the interpretation established by at least one (successful) lookup performed. +\end{itemize} +\begin{example} \begin{codeblock} struct C { typedef int I; @@ -1649,80 +2551,47 @@ typedef int I1, I2; extern int* p; extern int* q; -p->C::I::~I(); // \tcode{I} is looked up in the scope of \tcode{C} -q->I1::~I2(); // \tcode{I2} is looked up in the scope of - // the postfix-expression - +void f() { + p->C::I::~I(); // \tcode{I} is looked up in the scope of \tcode{C} + q->I1::~I2(); // \tcode{I2} is found by unqualified lookup +} struct A { ~A(); }; typedef A AB; int main() { AB* p; - p->AB::~AB(); // explicitly calls the destructor for \tcode{A} + p->AB::~AB(); // explicitly calls the destructor for \tcode{A} } \end{codeblock} -\exitexample \enternote \ref{basic.lookup.classref} describes how name -lookup proceeds after the \tcode{.} and \tcode{->} operators. \exitnote +\end{example} \rSec3[class.qual]{Class members} -\pnum -\indextext{lookup!class~member}% -If the \grammarterm{nested-name-specifier} of a \grammarterm{qualified-id} -nominates a class, the name specified after the -\grammarterm{nested-name-specifier} is looked up in the scope of the -class~(\ref{class.member.lookup}), except for the cases listed below. -The name shall represent one or more members of that class or of one of -its base classes (Clause~\ref{class.derived}). \enternote A class member -can be referred to using a \grammarterm{qualified-id} at any point in its -potential scope~(\ref{basic.scope.class}). \exitnote The exceptions to -the name lookup rule above are the following: - -\begin{itemize} -\item a destructor name is looked up as specified -in~\ref{basic.lookup.qual}; - -\item a \grammarterm{conversion-type-id} of a -\grammarterm{conversion-function-id} is looked up -in the same manner as a \grammarterm{conversion-type-id} in a class member -access (see~\ref{basic.lookup.classref}); - -\item the names in a \grammarterm{template-argument} of a -\grammarterm{template-id} are looked up in the context in which the entire -\grammarterm{postfix-expression} occurs. - -\item the lookup for a name specified in a -\grammarterm{using-declaration}~(\ref{namespace.udecl}) also finds class or -enumeration names hidden within the same -scope~(\ref{basic.scope.hiding}). - -\end{itemize} +\indextext{lookup!class member}% \pnum -In a lookup in which function names are not ignored\footnote{Lookups in which +In a lookup for a qualified name $N$ whose lookup context is a class $C$ +in which function names are not ignored, +\begin{footnote} +Lookups in which function names are ignored include names appearing in a \grammarterm{nested-name-specifier}, an -\grammarterm{elaborated-type-specifier}, or a \grammarterm{base-specifier}.} -and the \grammarterm{nested-name-specifier} nominates a class \tcode{C}: - +\grammarterm{elaborated-type-specifier}, or a \grammarterm{base-specifier}. +\end{footnote} \begin{itemize} -\item if the name specified after the \grammarterm{nested-name-specifier}, -when looked up in \tcode{C}, is the injected-class-name of \tcode{C} (Clause~\ref{class}), or \item -in a \grammarterm{using-declaration}~(\ref{namespace.udecl}) that is a \grammarterm{member-declaration}, -if the name specified after the \grammarterm{nested-name-specifier} is the same as the -\grammarterm{identifier} or the \grammarterm{simple-template-id}'s -\grammarterm{template-name} in the last component of the \grammarterm{nested-name-specifier}, +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} -the name is instead considered to name the -constructor of class \tcode{C}. \enternote For example, the constructor -is not an acceptable lookup result in an -\grammarterm{elaborated-type-specifier} so the constructor would not be -used in place of the injected-class-name. \exitnote Such a constructor -name shall be used only in the \grammarterm{declarator-id} of a declaration -that names a constructor or in a \grammarterm{using-declaration}. \enterexample - +$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}. +\begin{example} \begin{codeblock} struct A { A(); }; struct B: public A { B(); }; @@ -1731,50 +2600,26 @@ B::B() { } B::A ba; // object of type \tcode{A} -A::A a; // error, \tcode{A::A} is not a type name +A::A a; // error: \tcode{A::A} is not a type name struct A::A a2; // object of type \tcode{A} \end{codeblock} -\exitexample - -\pnum -A class member name hidden by a name in a nested declarative region or -by the name of a derived class member can still be found if qualified by -the name of its class followed by the \tcode{::} operator. +\end{example} \rSec3[namespace.qual]{Namespace members} \pnum -\indextext{lookup!namespace~member}% -If the \grammarterm{nested-name-specifier} of a \grammarterm{qualified-id} -nominates a namespace (including the case where the -\grammarterm{nested-name-specifier} is \tcode{::}, i.e., nominating -the global namespace), the name specified after the -\grammarterm{nested-name-specifier} is looked up in the scope of the -namespace. -The names in a \grammarterm{template-argument} of a -\grammarterm{template-id} are looked up in the context in which the -entire \grammarterm{postfix-expression} occurs. - -\pnum -For a namespace \tcode{X} and name \tcode{m}, the namespace-qualified lookup set -$S(X, m)$ is defined as follows: Let $S'(X, m)$ be the set of all -declarations of \tcode{m} in \tcode{X} and the inline namespace set of -\tcode{X}~(\ref{namespace.def}). If $S'(X, m)$ is not empty, $S(X, m)$ -is $S'(X, m)$; otherwise, $S(X, m)$ is the union of $S(N_i, m)$ for -all namespaces $N_i$ nominated by \grammarterm{using-directives} in -\tcode{X} and its inline namespace set. - -\pnum -Given \tcode{X::m} (where \tcode{X} is a user-declared namespace), or -given \tcode{::m} (where X is the global namespace), if -$S(X, m)$ is the empty set, the program is ill-formed. Otherwise, if -$S(X, m)$ has exactly one member, or if the context of the reference is -a \grammarterm{using-declaration}~(\ref{namespace.udecl}), $S(X, m)$ -is the -required set of declarations of \tcode{m}. Otherwise if the use of -\tcode{m} is not one that allows a unique declaration to be chosen from -$S(X, m)$, the program is ill-formed. \enterexample - +Qualified name lookup in a namespace $N$ additionally searches +every element of the inline namespace set of $N$\iref{namespace.def}. +If nothing is found, +the results of the lookup are the results of qualified name lookup +in each namespace nominated by a \grammarterm{using-directive} +that precedes the point of the lookup and +inhabits $N$ or an element of $N$'s inline namespace set. +\begin{note} +If a \grammarterm{using-directive} refers to a namespace +that has already been considered, it does not affect the result. +\end{note} +\begin{example} \begin{codeblock} int x; namespace Y { @@ -1807,36 +2652,32 @@ void h() { - AB::g(); // \tcode{g} is declared directly in \tcode{AB,} - // therefore \tcode{S} is \{ \tcode{AB::g()} \} and \tcode{AB::g()} is chosen - AB::f(1); // \tcode{f} is not declared directly in \tcode{AB} so the rules are - // applied recursively to \tcode{A} and \tcode{B;} - // namespace \tcode{Y} is not searched and \tcode{Y::f(float)} - // is not considered; - // \tcode{S} is \{ \tcode{A::f(int)}, \tcode{B::f(char)} \} and overload - // resolution chooses \tcode{A::f(int)} + AB::g(); // \tcode{g} is declared directly in \tcode{AB}, therefore \tcode{S} is $\{ \tcode{AB::g()} \}$ and \tcode{AB::g()} is chosen + + AB::f(1); // \tcode{f} is not declared directly in \tcode{AB} so the rules are applied recursively to \tcode{A} and \tcode{B}; + // namespace \tcode{Y} is not searched and \tcode{Y::f(float)} is not considered; + // \tcode{S} is $\{ \tcode{A::f(int)}, \tcode{B::f(char)} \}$ and overload resolution chooses \tcode{A::f(int)} + AB::f('c'); // as above but resolution chooses \tcode{B::f(char)} - AB::x++; // \tcode{x} is not declared directly in \tcode{AB}, and - // is not declared in \tcode{A} or \tcode{B} , so the rules are - // applied recursively to \tcode{Y} and \tcode{Z}, - // \tcode{S} is \{ \} so the program is ill-formed - AB::i++; // \tcode{i} is not declared directly in \tcode{AB} so the rules are - // applied recursively to \tcode{A} and \tcode{B}, - // \tcode{S} is \{ \tcode{A::i} , \tcode{B::i} \} so the use is ambiguous - // and the program is ill-formed - AB::h(16.8); // \tcode{h} is not declared directly in \tcode{AB} and - // not declared directly in \tcode{A} or \tcode{B} so the rules are - // applied recursively to \tcode{Y} and \tcode{Z}, - // \tcode{S} is \{ \tcode{Y::h(int)}, \tcode{Z::h(double)} \} and overload - // resolution chooses \tcode{Z::h(double)} + AB::x++; // \tcode{x} is not declared directly in \tcode{AB}, and is not declared in \tcode{A} or \tcode{B}, so the rules + // are applied recursively to \tcode{Y} and \tcode{Z}, \tcode{S} is $\{ \}$ so the program is ill-formed + + AB::i++; // \tcode{i} is not declared directly in \tcode{AB} so the rules are applied recursively to \tcode{A} and \tcode{B}, + // \tcode{S} is $\{ \tcode{A::i}, \tcode{B::i} \}$ so the use is ambiguous and the program is ill-formed + + AB::h(16.8); // \tcode{h} is not declared directly in \tcode{AB} and not declared directly in \tcode{A} or \tcode{B} so the rules + // are applied recursively to \tcode{Y} and \tcode{Z}, \tcode{S} is $\{ \tcode{Y::h(int)}, \tcode{Z::h(double)} \}$ and + // overload resolution chooses \tcode{Z::h(double)} } \end{codeblock} +\end{example} \pnum +\begin{note} The same declaration found more than once is not an ambiguity (because -it is still a unique declaration). For example: - +it is still a unique declaration). +\begin{example} \begin{codeblock} namespace A { int a; @@ -1857,7 +2698,7 @@ void f() { - BC::a++; // OK: \tcode{S} is \{ \tcode{A::a}, \tcode{A::a} \} + BC::a++; // OK, \tcode{S} is $\{ \tcode{A::a}, \tcode{A::a} \}$ } namespace D { @@ -1871,14 +2712,16 @@ void g() { - BD::a++; // OK: S is \{ \tcode{ A::a}, \tcode{ A::a} \} + BD::a++; // OK, \tcode{S} is $\{ \tcode{A::a}, \tcode{A::a} \}$ } \end{codeblock} +\end{example} +\end{note} \pnum +\begin{example} Because each referenced namespace is searched at most once, the following is well-defined: - \begin{codeblock} namespace B { int b; @@ -1895,24 +2738,20 @@ void f() { - A::a++; // OK: \tcode{a} declared directly in \tcode{A}, \tcode{S} is \{\tcode{A::a}\} - B::a++; // OK: both \tcode{A} and \tcode{B} searched (once), \tcode{S} is \{\tcode{A::a}\} - A::b++; // OK: both \tcode{A} and \tcode{B} searched (once), \tcode{S} is \{\tcode{B::b}\} - B::b++; // OK: \tcode{b} declared directly in \tcode{B}, \tcode{S} is \{\tcode{B::b}\} + A::a++; // OK, \tcode{a} declared directly in \tcode{A}, \tcode{S} is $\{ \tcode{A::a} \}$ + B::a++; // OK, both \tcode{A} and \tcode{B} searched (once), \tcode{S} is $\{ \tcode{A::a} \}$ + A::b++; // OK, both \tcode{A} and \tcode{B} searched (once), \tcode{S} is $\{ \tcode{B::b} \}$ + B::b++; // OK, \tcode{b} declared directly in \tcode{B}, \tcode{S} is $\{ \tcode{B::b} \}$ } \end{codeblock} -\exitexample +\end{example} \pnum -During the lookup of a qualified namespace member name, if the lookup -finds more than one declaration of the member, and if one declaration -introduces a class name or enumeration name and the other declarations -either introduce the same variable, the same enumerator or a set of -functions, the non-type name hides the class or enumeration name if and -only if the declarations are from the same namespace; otherwise (the -declarations are from different namespaces), the program is ill-formed. -\enterexample - +\begin{note} +Class and enumeration declarations are not discarded +because of other declarations found in other searches. +\end{note} +\begin{example} \begin{codeblock} namespace A { struct x { }; @@ -1927,1338 +2766,1284 @@ namespace C { using namespace A; using namespace B; - int i = C::x; // OK, \tcode{A::x} (of type \tcode{int} ) + int i = C::x; // OK, \tcode{A::x} (of type \tcode{int}) int j = C::y; // ambiguous, \tcode{A::y} or \tcode{B::y} } \end{codeblock} -\exitexample - -\pnum -In a declaration for a namespace member in which the -\grammarterm{declarator-id} is a \grammarterm{qualified-id}, given that the -\grammarterm{qualified-id} for the namespace member has the form - -\begin{ncbnf} -nested-name-specifier unqualified-id -\end{ncbnf} - -the -\grammarterm{unqualified-id} shall name a member of the namespace -designated by the \grammarterm{nested-name-specifier} -or of an element of the inline namespace set~(\ref{namespace.def}) of that namespace. -\enterexample - -\begin{codeblock} -namespace A { - namespace B { - void f1(int); - } - using namespace B; -} -void A::f1(int){ } // ill-formed, \tcode{f1} is not a member of \tcode{A} -\end{codeblock} - -\exitexample However, in such namespace member declarations, the -\grammarterm{nested-name-specifier} may rely on \grammarterm{using-directive}{s} -to implicitly provide the initial part of the -\grammarterm{nested-name-specifier}. \enterexample - -\begin{codeblock} -namespace A { - namespace B { - void f1(int); - } -} - -namespace C { - namespace D { - void f1(int); - } -} +\end{example} -using namespace A; -using namespace C::D; -void B::f1(int){ } // OK, defines \tcode{A::B::f1(int)} -\end{codeblock} -\exitexample -\indextext{lookup!qualified~name|)}% +\indextext{lookup!qualified name|)}% \rSec2[basic.lookup.elab]{Elaborated type specifiers}% -\indextext{lookup!elaborated~type~specifier|(}% -\indextext{type~specifier!elaborated} +\indextext{lookup!elaborated type specifier|(}% +\indextext{type specifier!elaborated} \pnum -An \grammarterm{elaborated-type-specifier}~(\ref{dcl.type.elab}) may be -used to refer to a previously declared \grammarterm{class-name} or -\grammarterm{enum-name} even though the name has been hidden by a non-type -declaration~(\ref{basic.scope.hiding}). +If the \grammarterm{class-key} or \keyword{enum} keyword +in an \grammarterm{elaborated-type-specifier} +is followed by an \grammarterm{identifier} +that is not followed by \tcode{::}, +lookup for the \grammarterm{identifier} is type-only\iref{basic.lookup.general}. +\begin{note} +In general, the recognition of an \grammarterm{elaborated-type-specifier} +depends on the following tokens. +If the \grammarterm{identifier} is followed by \tcode{::}, +see \ref{basic.lookup.qual}. +\end{note} \pnum -If the \grammarterm{elaborated-type-specifier} has no -\grammarterm{nested-name-specifier}, and unless the -\grammarterm{elaborated-type-specifier} appears in a declaration with the -following form: - -\begin{ncbnf} -class-key attribute-specifier-seq\opt identifier \terminal{;} -\end{ncbnf} - -the \grammarterm{identifier} is looked up according -to~\ref{basic.lookup.unqual} but ignoring any non-type names that have -been declared. If the \grammarterm{elaborated-type-specifier} is introduced -by the \tcode{enum} keyword and this lookup does not find a previously -declared \grammarterm{type-name}, the \grammarterm{elaborated-type-specifier} -is ill-formed. If the \grammarterm{elaborated-type-specifier} is introduced -by the \grammarterm{class-key} and this lookup does not find a previously -declared \grammarterm{type-name}, or if the -\grammarterm{elaborated-type-specifier} appears in a declaration with the -form: - -\begin{ncbnf} -class-key attribute-specifier-seq\opt identifier \terminal{;} -\end{ncbnf} - -the \grammarterm{elaborated-type-specifier} is a declaration that -introduces the \grammarterm{class-name} as described -in~\ref{basic.scope.pdecl}. +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}, +the \grammarterm{elaborated-type-specifier} is ill-formed. \pnum -If the \grammarterm{elaborated-type-specifier} has a -\grammarterm{nested-name-specifier}, qualified name lookup is performed, as -described in~\ref{basic.lookup.qual}, but ignoring any non-type names -that have been declared. If the name lookup does not find a previously -declared \grammarterm{type-name}, the \grammarterm{elaborated-type-specifier} -is ill-formed. \enterexample - +\begin{example} \begin{codeblock} struct Node { - struct Node* Next; // OK: Refers to \tcode{Node} at global scope - struct Data* Data; // OK: Declares type \tcode{Data} - // at global scope and member \tcode{Data} + struct Node* Next; // OK, refers to injected-class-name \tcode{Node} + struct Data* Data; // OK, declares type \tcode{Data} at global scope and member \tcode{Data} }; struct Data { - struct Node* Node; // OK: Refers to \tcode{Node} at global scope - friend struct ::Glob; // error: \tcode{Glob} is not declared - // cannot introduce a qualified type~(\ref{dcl.type.elab}) - friend struct Glob; // OK: Refers to (as yet) undeclared \tcode{Glob} - // at global scope. - /* ... */ + struct Node* Node; // OK, refers to \tcode{Node} at global scope + friend struct ::Glob; // error: \tcode{Glob} is not declared, cannot introduce a qualified type\iref{dcl.type.elab} + friend struct Glob; // OK, refers to (as yet) undeclared \tcode{Glob} at global scope. + @\commentellip@ }; struct Base { - struct Data; // OK: Declares nested \tcode{Data} - struct ::Data* thatData; // OK: Refers to \tcode{::Data} - struct Base::Data* thisData; // OK: Refers to nested \tcode{Data} - friend class ::Data; // OK: global \tcode{Data} is a friend - friend class Data; // OK: nested \tcode{Data} is a friend - struct Data @\tcode{\{ /* ... */ \};}@ // Defines nested \tcode{Data} + struct Data; // OK, declares nested \tcode{Data} + struct ::Data* thatData; // OK, refers to \tcode{::Data} + struct Base::Data* thisData; // OK, refers to nested \tcode{Data} + friend class ::Data; // OK, global \tcode{Data} is a friend + friend class Data; // OK, nested \tcode{Data} is a friend + struct Data { @\commentellip@ }; // Defines nested \tcode{Data} }; -struct Data; // OK: Redeclares \tcode{Data} at global scope -struct ::Data; // error: cannot introduce a qualified type~(\ref{dcl.type.elab}) -struct Base::Data; // error: cannot introduce a qualified type~(\ref{dcl.type.elab}) +struct Data; // OK, redeclares \tcode{Data} at global scope +struct ::Data; // error: cannot introduce a qualified type\iref{dcl.type.elab} +struct Base::Data; // error: cannot introduce a qualified type\iref{dcl.type.elab} struct Base::Datum; // error: \tcode{Datum} undefined -struct Base::Data* pBase; // OK: refers to nested \tcode{Data} +struct Base::Data* pBase; // OK, refers to nested \tcode{Data} \end{codeblock} -\exitexample % -\indextext{lookup!elaborated~type~specifier|)}% +\end{example} +\indextext{lookup!elaborated type specifier|)}% -\rSec2[basic.lookup.classref]{Class member access} +\rSec2[basic.lookup.udir]{Using-directives and namespace aliases} \pnum -\indextext{lookup!class member}% -In a class member access expression~(\ref{expr.ref}), if the \tcode{.} -or \tcode{->} token is immediately followed by an \grammarterm{identifier} -followed by a \tcode{<}, the identifier must be looked up to determine -whether the \tcode{<} is the beginning of a template argument -list~(\ref{temp.names}) or a less-than operator. The identifier is first -looked up in the class of the object expression. If the identifier is -not found, it is then looked up in the context of the entire -\grammarterm{postfix-expression} and shall name a class template. - -\pnum -If the \grammarterm{id-expression} in a class member -access~(\ref{expr.ref}) is an \grammarterm{unqualified-id}, and the type of -the object expression is of a class type \tcode{C}, the -\grammarterm{unqualified-id} is looked up in the scope of class \tcode{C}. -For a pseudo-destructor call~(\ref{expr.pseudo}), -the \grammarterm{unqualified-id} is looked up in the context of the complete -\grammarterm{postfix-expression}. - -\pnum -If the \grammarterm{unqualified-id} is \tcode{\~}\grammarterm{type-name}, the -\grammarterm{type-name} is looked up in the context of the entire -\grammarterm{postfix-expression}. If the type \tcode{T} of the object -expression is of a class type \tcode{C}, the \grammarterm{type-name} is -also looked up in the scope of class \tcode{C}. At least one of the -lookups shall find a name that refers to (possibly cv-qualified) -\tcode{T}. \enterexample +\indextext{lookup!using-directives and}% +\indextext{lookup!namespace aliases and}% +In a \grammarterm{using-directive} or \grammarterm{namespace-alias-definition}, +during the lookup for a \grammarterm{namespace-name} or for a name in a +\grammarterm{nested-name-specifier}{} +only namespace names are considered.% +\indextext{lookup!name|)}% -\begin{codeblock} -struct A { }; +\rSec1[basic.splice]{Splice specifiers} +\indextext{splice|(}% -struct B { - struct A { }; - void f(::A* a); -}; +\begin{bnf} +\nontermdef{splice-specifier}\br + \terminal{[:} constant-expression \terminal{:]} +\end{bnf} -void B::f(::A* a) { - a->~A(); // OK: lookup in \tcode{*a} finds the injected-class-name -} -\end{codeblock}\exitexample +\begin{bnf} +\nontermdef{splice-specialization-specifier}\br + splice-specifier \terminal{<} \opt{template-argument-list} \terminal{>} +\end{bnf} \pnum -If the \grammarterm{id-expression} in a class member access is a -\grammarterm{qualified-id} of the form - -\begin{indented} -\tcode{class-name-or-namespace-name::...} -\end{indented} - -the \grammarterm{class-name-or-namespace-name} following the \tcode{.} or -\tcode{->} operator is -first looked up in the class of the object expression and the name, if found, -is used. Otherwise it is looked up in the context of the entire -\grammarterm{postfix-expression}. \enternote See~\ref{basic.lookup.qual}, which -describes the lookup of a name before \tcode{::}, which will only find a type -or namespace name. \exitnote +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 -If the \grammarterm{qualified-id} has the form +A non-dependent \grammarterm{splice-specifier} of +a \grammarterm{splice-specialization-specifier} shall designate a template. -\begin{indented} -\tcode{::class-name-or-namespace-name::...} -\end{indented} +\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; +}; -the \grammarterm{class-name-or-namespace-name} is looked up in global scope -as a \grammarterm{class-name} or \grammarterm{namespace-name}. +using alias = [:^^TCls:]<([:^^v:])>; + // OK, a \grammarterm{splice-specialization-specifier} with a parenthesized \grammarterm{splice-expression} as a template argument -\pnum -If the \grammarterm{nested-name-specifier} contains a -\grammarterm{simple-template-id}~(\ref{temp.names}), the names in its -\grammarterm{template-argument}{s} are looked up in the context in which the -entire \grammarterm{postfix-expression} occurs. +static_assert(alias::s == 2); -\pnum -If the \grammarterm{id-expression} is a \grammarterm{conversion-function-id}, -its \grammarterm{conversion-type-id} -is first looked up in the class of the object expression and the name, if -found, is used. Otherwise it is looked up in the context -of the entire \grammarterm{postfix-expression}. -In each of these lookups, only names that denote types or templates whose -specializations are types are considered. -\enterexample -\begin{codeblock} -struct A { }; -namespace N { - struct A { - void g() { } - template operator T(); - }; -} +auto o1 = [:^^TCls:]<([:^^v:])>(); // error: < means less than +auto o2 = typename [:^^TCls:]<([:^^v:])>(); // OK, \tcode{o2} is an object of type \tcode{TCls<1>} -int main() { - N::A a; - a.operator A(); // calls \tcode{N::A::operator N::A} +consteval int bad_splice(std::meta::info v) { + return [:v:]; // error: \tcode{v} is not constant } \end{codeblock} -\exitexample - -\rSec2[basic.lookup.udir]{Using-directives and namespace aliases} - -\pnum -\indextext{lookup!using-directives~and}% -\indextext{lookup!namespace~aliases~and}% -In a \grammarterm{using-directive} or \grammarterm{namespace-alias-definition}, -during the lookup for a \grammarterm{namespace-name} or for a name in a -\grammarterm{nested-name-specifier}{} -only namespace names are considered.% -\indextext{lookup!name|)}% -\indextext{scope!name~lookup~and|)} +\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 \defn{translation -units} (Clause~\ref{lex}) 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 - declaration-seq\opt + \opt{declaration-seq}\br + \opt{global-module-fragment} module-declaration \opt{declaration-seq} \opt{private-module-fragment} \end{bnf} \pnum -\indextext{linkage}% -\indextext{translation~unit}% -\indextext{linkage!internal}% -\indextext{linkage!external}% -A name is said to have \defn{linkage} when it might denote the same -object, reference, function, type, template, namespace or value as a -name introduced by a declaration in another scope: - -\begin{itemize} -\item When a name has \defn{external linkage}\indextext{linkage!external}, -the entity it denotes -can be referred to by names from scopes of other translation units or -from other scopes of the same translation unit. - -\item When a name has \defn{internal linkage}\indextext{linkage!internal}, -the entity it denotes -can be referred to by names from other scopes in the same translation -unit. - -\item When a name has \defn{no linkage}\indextext{linkage!no}, the entity it denotes -cannot be referred to by names from other scopes. -\end{itemize} - -\pnum -\indextext{linkage!\idxcode{static}~and}% -\indextext{\idxcode{static}!linkage~of}% -\indextext{linkage!\idxcode{const}~and}% -\indextext{\idxcode{const}!linkage~of}% -\indextext{linkage!\idxcode{inline}~and}% -\indextext{\idxcode{inline}!linkage~of}% -A name having namespace scope~(\ref{basic.scope.namespace}) has internal -linkage if it is the name of - +\indextext{translation unit}% +A name has +\defnadj{external}{linkage}, +\defnadj{module}{linkage}, +\defnadj{internal}{linkage}, or +\defnadj{no}{linkage}, +as determined by the rules below. +\begin{note} +All declarations of an entity with a name with internal linkage +appear in the same translation unit. +All declarations of an entity with module linkage +are attached to the same module. +\end{note} + +\pnum +\indextext{linkage!\idxcode{static} and}% +\indextext{\idxcode{static}!linkage of}% +\indextext{linkage!\idxcode{const} and}% +\indextext{\idxcode{const}!linkage of}% +\indextext{linkage!\idxcode{inline} and}% +\indextext{\idxcode{inline}!linkage of}% +The name of an entity +that belongs to a namespace scope\iref{basic.scope.namespace} +has internal linkage if it is the name of \begin{itemize} -\item a variable, function or function template that is -explicitly declared \tcode{static}; or, - -\item a variable of non-volatile const-qualified type that is -neither explicitly declared \tcode{extern} nor previously -declared to have external linkage; or - -\item a data member of an anonymous union. +\item + a variable, variable template, function, or function template that is + explicitly declared \keyword{static}; or +\item + a non-template variable of non-volatile const-qualified type, unless + \begin{itemize} + \item it is declared in the purview of a module interface unit + (outside the \grammarterm{private-module-fragment}, if any) or + module partition, or + \item it is explicitly declared \keyword{extern}, or + \item it is inline, or + \item it was previously declared and the prior declaration did + not have internal linkage; or + \end{itemize} +\item + a data member of an anonymous union. \end{itemize} +\begin{note} +An instantiated variable template that has const-qualified type +can have external or module linkage, even if not declared \keyword{extern}. +\end{note} \pnum An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage. -A name having namespace scope -that has not been given internal linkage above -has the same linkage as the enclosing namespace if it is the name of - +The name of an entity that belongs to a namespace scope, +that has not been given internal linkage above, +and that is the name of \begin{itemize} \item a variable; or - \item a function; or - -\item \indextext{class!linkage~of}% -a named class (Clause~\ref{class}), or an unnamed class defined in a +\item +\indextext{class!linkage of}% +a named class\iref{class.pre}, or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage -purposes~(\ref{dcl.typedef}); or - -\item \indextext{enumeration!linkage~of}% -a named enumeration~(\ref{dcl.enum}), or an unnamed enumeration defined +purposes\iref{dcl.typedef}; or +\item +\indextext{enumeration!linkage of}% +a named enumeration\iref{dcl.enum}, or an unnamed enumeration defined in a typedef declaration in which the enumeration has the typedef name -for linkage purposes~(\ref{dcl.typedef}); or - -\item an enumerator belonging to an enumeration with linkage; or - -\item a template. +for linkage purposes\iref{dcl.typedef}; or +\item an unnamed enumeration +that has an enumerator as a name for linkage purposes\iref{dcl.enum}; or +\item a template +\end{itemize} +has its linkage determined as follows: +\begin{itemize} +\item +\indextext{friend function!linkage of}% +if the entity is a function or function template +first declared in a friend declaration and +that declaration is a definition and +the enclosing class is defined within an \grammarterm{export-declaration}, +the name has the same linkage, if any, +as the name of the enclosing class\iref{class.friend}; +\item +otherwise, +\indextext{friend function!linkage of}% +if the entity is a function or function template +declared in a friend declaration and +a corresponding non-friend declaration is reachable, +%FIXME: Which declaration is "that prior declaration"? +%FIXME: "prior" with respect to what? And what about dependent lookup? +the name has the linkage determined from that prior declaration, +\item +otherwise, +if the enclosing namespace has internal linkage, +the name has internal linkage; +\item +otherwise, +if the declaration of the name is +attached to a named module\iref{module.unit} +and is not exported\iref{module.interface}, +the name has module linkage; +\item +otherwise, +the name has external linkage. \end{itemize} \pnum -In addition, a member function, static data member, a named class or -enumeration of class scope, or an unnamed class or enumeration defined -in a class-scope typedef declaration such that the class or enumeration -has the typedef name for linkage purposes~(\ref{dcl.typedef}), has -the same linkage, if any, as the name of the class of which it is a -member. +In addition, +a member function, +a static data member, +a named class or enumeration that inhabits a class scope, or +an unnamed class or enumeration defined in a typedef declaration +that inhabits a class scope +such that the class or enumeration +has the typedef name for linkage purposes\iref{dcl.typedef}, +has the same linkage, if any, as the name of the class of which it is a member. \pnum -The name of a function declared in block scope and the name of a variable declared by a -block scope \tcode{extern} declaration have linkage. If there is a visible declaration -of an entity with linkage having the same name and type, ignoring entities declared -outside the innermost enclosing namespace scope, the block scope declaration declares -that same entity and receives the linkage of the previous declaration. If there is more -than one such matching entity, the program is ill-formed. Otherwise, if no matching -entity is found, the block scope entity receives external linkage.\enterexample - +\begin{example} \begin{codeblock} static void f(); +extern "C" void h(); static int i = 0; // \#1 -void g() { +void q() { extern void f(); // internal linkage - int i; // \#2 \tcode{i} has no linkage + extern void g(); // \tcode{::g}, external linkage + extern void h(); // C language linkage + int i; // \#2: \tcode{i} has no linkage { extern void f(); // internal linkage - extern int i; // \#3 external linkage - } -} -\end{codeblock} - -There are three objects named \tcode{i} in this program. The object with -internal linkage introduced by the declaration in global scope (line -\tcode{\#1} ), the object with automatic storage duration and no linkage -introduced by the declaration on line \tcode{\#2}, and the object with -static storage duration and external linkage introduced by the -declaration on line \tcode{\#3}. \exitexample - -\pnum -When a block scope declaration of an entity with linkage is not found to -refer to some other declaration, then that entity is a member of the -innermost enclosing namespace. However such a declaration does not -introduce the member name in its namespace scope. \enterexample - -\begin{codeblock} -namespace X { - void p() { - q(); // error: \tcode{q} not yet declared - extern void q(); // \tcode{q} is a member of namespace \tcode{X} - } - - void middle() { - q(); // error: \tcode{q} not yet declared + extern int i; // \#3: internal linkage } - - void q() @\tcode{\{ /* ... */ \}}@ // definition of \tcode{X::q} } - -void q() @\tcode{\{ /* ... */ \}}@ // some other, unrelated \tcode{q} \end{codeblock} -\exitexample +Even though the declaration at line \#2 hides the declaration at line \#1, +the declaration at line \#3 still redeclares \#1 and receives internal linkage. +\end{example} \pnum \indextext{linkage!no}% Names not covered by these rules have no linkage. Moreover, except as -noted, a name declared at block scope~(\ref{basic.scope.block}) has no -linkage. A type is said to have linkage if and only if: +noted, a name declared at block scope\iref{basic.scope.block} has no +linkage. +\pnum +Two declarations of entities declare the same entity +if, considering declarations of unnamed types to introduce their names +for linkage purposes, if any\iref{dcl.typedef,dcl.enum}, +they correspond\iref{basic.scope.scope}, +have the same target scope that is not a function or template parameter scope, +neither is a name-independent declaration, +and either \begin{itemize} -\item it is a class or enumeration type that is named (or has a name for -linkage purposes~(\ref{dcl.typedef})) and the name has linkage; or - -\item it is an unnamed class or enumeration member of a class with linkage; or - -\item it is a specialization of a class template (Clause~\ref{temp})\footnote{A class -template has the linkage of the innermost enclosing class or namespace in which -it is declared.}; -or - -\item it is a fundamental type~(\ref{basic.fundamental}); or - -\item it is a compound type~(\ref{basic.compound}) other than a class or -enumeration, compounded exclusively from types that have linkage; or - -\item it is a cv-qualified~(\ref{basic.type.qualifier}) version of a -type that has linkage. +\item +they appear in the same translation unit, or +\item +they both declare type aliases or namespace aliases that have the same underlying entity, or +\item +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}. +\end{note} + +\pnum +If a declaration $H$ that declares a name with internal linkage +precedes a declaration $D$ in another translation unit $U$ and +would declare the same entity as $D$ if it appeared in $U$, +the program is ill-formed. +\begin{note} +Such an $H$ can appear only in a header unit. +\end{note} + +\pnum +\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 +int g(); // \#2, attached to the global module +\end{codeblocktu} + +\begin{codeblocktu}{Module interface of \tcode{M}} +module; +#include "decls.h" +export module M; +export using ::f; // OK, does not declare an entity, exports \#1 +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: conflicts with \#3 +int k(); // error: conflicts with \#4 +\end{codeblocktu} +\end{example} +As a consequence of these rules, +all declarations of an entity are attached to the same module; +the entity is said to be \defnx{attached}{attached!entity} to that module. -A type without linkage shall not be used as the type of a variable or -function with external linkage unless +\pnum +\indextext{consistency!type declaration}% +\indextext{declaration!multiple}% +For any two declarations of an entity $E$: \begin{itemize} -\item the entity has C language linkage~(\ref{dcl.link}), or - -\item the entity is declared within an unnamed -namespace~(\ref{namespace.def}), or - -\item the entity is not odr-used~(\ref{basic.def.odr}) or is defined in -the same translation unit. +\item +If one declares $E$ to be a variable or function, +the other shall declare $E$ as one of the same type. +\item +If one declares $E$ to be an enumerator, the other shall do so. +\item +If one declares $E$ to be a namespace, the other shall do so. +\item +If one declares $E$ to be a type, +the other shall declare $E$ to be a type of the same kind\iref{dcl.type.elab}. +\item +If one declares $E$ to be a class template, +the other shall do so with the same kind and +an equivalent \grammarterm{template-head}\iref{temp.over.link}. +\begin{note} +The declarations can supply different default template arguments. +\end{note} +\item +If one declares $E$ to be a function template or +a (partial specialization of a) variable template, +the other shall declare $E$ to be one +with an equivalent \grammarterm{template-head} and type. +\item +If one declares $E$ to be an alias template, +the other shall declare $E$ to be one with +an equivalent \grammarterm{template-head} and \grammarterm{defining-type-id}. +\item +If one declares $E$ to be a concept, the other shall do so. \end{itemize} -\enternote In other words, a type without linkage contains a class or enumeration that -cannot be named outside its translation unit. An entity with external linkage declared -using such a type could not correspond to any other entity in another translation unit -of the program and thus must be defined in the -translation unit if it is odr-used. Also note that classes with linkage may contain members -whose types do not have linkage, and that typedef names are ignored in the determination -of whether a type has linkage. \exitnote - -\enterexample +Types are compared after all adjustments of types (during which +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. +\begin{example} \begin{codeblock} -template struct B { - void g(T) { } - void h(T); - friend void i(B, T) { } -}; - -void f() { - struct A { int x; }; // no linkage - A a = { 1 }; - B ba; // declares \tcode{B::g(A)} and \tcode{B::h(A)} - ba.g(a); // OK - ba.h(a); // error: \tcode{B::h(A) not defined in the translation unit} - i(ba, a); // OK -} +int f(int x, int x); // error: different entities for \tcode{x} +void g(); // \#1 +void g(int); // OK, different entity from \#1 +int g(); // error: same entity as \#1 with different type +void h(); // \#2 +namespace h {} // error: same entity as \#2, but not a function \end{codeblock} -\exitexample +\end{example} \pnum -Two names that are the same (Clause~\ref{basic}) and that are declared -in different scopes shall denote the same variable, function, -type, enumerator, template or namespace if +\begin{note} +Linkage to non-\Cpp{} declarations can be achieved using a +\grammarterm{linkage-specification}\iref{dcl.link}. +\end{note} +\indextext{linkage|)} +\pnum +A declaration $D$ \defnx{names}{name} an entity $E$ if \begin{itemize} -\item both names have external linkage or else both names have internal -linkage and are declared in the same translation unit; and - -\item both names refer to members of the same namespace or to members, -not by inheritance, of the same class; and - -\item when both names denote functions, the parameter-type-lists of the -functions~(\ref{dcl.fct}) are identical; and - -\item when both names denote function templates, the -signatures~(\ref{temp.over.link}) are the same. +\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}, +\grammarterm{nested-name-specifier}, +\grammarterm{template-name}, or +\grammarterm{concept-name} +denoting $E$, or +\item +$E$ is a function or function template and +$D$ contains an expression that names $E$\iref{basic.def.odr} or +an \grammarterm{id-expression} +that refers to a set of overloads that contains $E$. +\begin{note} +Non-dependent names in an instantiated declaration +do not refer to a set of overloads\iref{temp.res}. +\end{note} \end{itemize} \pnum -\indextext{consistency!type declaration}% -\indextext{declaration!multiple}% -After all adjustments of types (during which -typedefs~(\ref{dcl.typedef}) are replaced by their definitions), the -types specified by all declarations referring to a given variable or -function shall be identical, except that declarations for an array -object can specify array types that differ by the presence or absence of -a major array bound~(\ref{dcl.array}). A violation of this rule on type -identity does not require a diagnostic. +A declaration is an \defn{exposure} +if it either names a TU-local entity (defined below), ignoring +\begin{itemize} +\item +the \grammarterm{function-body} +for a non-inline function or function template +(but not the deduced return type +for a (possibly instantiated) definition of a function +with a declared return type that uses a placeholder type\iref{dcl.spec.auto}), +\item +the \grammarterm{initializer} +for a variable or variable template (but not the variable's type), +\item +friend declarations in a class definition, and +\item +any reference to a non-volatile const object or reference +with internal or no linkage initialized with a constant expression +that is not an odr-use\iref{term.odr.use}, +\end{itemize} +or defines a constexpr variable initialized to a TU-local value (defined below). +\begin{note} +An inline function template can be an exposure even though +certain explicit specializations of it would be usable in other translation units. +\end{note} \pnum -\enternote Linkage to non-\Cpp declarations can be achieved using a -\grammarterm{linkage-specification}~(\ref{dcl.link}). \exitnote% -\indextext{linkage|)} +An entity is \defnx{TU-local}{TU-local!entity} if it is +\begin{itemize} +\item +a type, type alias, namespace, namespace alias, function, variable, or template that +\begin{itemize} +\item +has a name with internal linkage, or +\item +does not have a name with linkage and is declared, +or introduced by a \grammarterm{lambda-expression}, +within the definition of a TU-local entity, +\end{itemize} +\item +a type with no name that is defined outside a +\grammarterm{class-specifier}, +function body, or +\grammarterm{initializer} +or is introduced by a \grammarterm{defining-type-specifier} +that is used to declare only TU-local entities, +\item +a specialization of a TU-local template, +\item +a specialization of a template with any TU-local template argument, or +\item +a specialization of a template +whose (possibly instantiated) declaration is an exposure. +\begin{note} +A specialization can be produced by implicit or explicit instantiation. +\end{note} +\end{itemize} -\rSec1[basic.start]{Start and termination} +\pnum +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, +\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, 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} -\rSec2[basic.start.main]{Main function} +\pnum +If a (possibly instantiated) declaration of, or a deduction guide for, +a non-TU-local entity in a module interface unit +(outside the \grammarterm{private-module-fragment}, if any) or +module partition\iref{module.unit} is an exposure, +the program is ill-formed. +Such a declaration in any other context is deprecated\iref{depr.local}. \pnum -\indextext{program!start|(}% -\indextext{\idxcode{main()}}% -A program shall contain a global function called \tcode{main}, which is the designated -start of the program. It is \impldef{defining \tcode{main} in freestanding environment} -whether a program in a freestanding environment is required to define a \tcode{main} -function. \enternote In a freestanding environment, start-up and termination is -\impldef{start-up and termination in freestanding environment}; start-up contains the -execution of constructors for objects of namespace scope with static storage duration; -termination contains the execution of destructors for objects with static storage -duration. \exitnote +If a declaration that appears in one translation unit +names a TU-local entity declared +in another translation unit that is not a header unit, +the program is ill-formed. +A declaration instantiated for a template specialization\iref{temp.spec} +appears at the point of instantiation of the specialization\iref{temp.point}. \pnum -An implementation shall not predefine the \tcode{main} function. This -function shall not be overloaded. It shall have a declared return type of type -\tcode{int}, but otherwise its type is \impldef{parameters to \tcode{main}}. -\indextext{\idxcode{main()}!implementation-defined parameters~to}% -An implementation shall allow both +\begin{example} +\begin{codeblocktu}{Translation unit \#1} +export module A; +static void f() {} +inline void it() { f(); } // error: is an exposure of \tcode{f} +static inline void its() { f(); } // OK +template void g() { its(); } // OK +template void g<0>(); -\begin{itemize} -\item a function of \tcode{()} returning \tcode{int} and -\item a function of \tcode{(int}, pointer to pointer to \tcode{char)} returning \tcode{int} -\end{itemize} +decltype(f) *fp; // error: \tcode{f} (though not its type) is TU-local +auto &fr = f; // OK +constexpr auto &fr2 = fr; // error: is an exposure of \tcode{f} +constexpr static auto fp2 = fr; // OK -\indextext{\idxcode{argc}}% -\indextext{\idxcode{argv}}% -as the type of \tcode{main}~(\ref{dcl.fct}). -\indextext{\idxcode{main()}!parameters~to}% -\indextext{environment!program}% -In the latter form, for purposes of exposition, the first function -parameter is called \tcode{argc} and the second function parameter is -called \tcode{argv}, where \tcode{argc} shall be the number of -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 -characters of null-terminated multibyte strings (\ntmbs -s)~(\ref{multibyte.strings}) and \tcode{argv[0]} shall be the pointer to -the initial character of a \ntmbs that represents the name used to -invoke the program or \tcode{""}. The value of \tcode{argc} shall be -non-negative. The value of \tcode{argv[argc]} shall be 0. \enternote It -is recommended that any further (optional) parameters be added after -\tcode{argv}. \exitnote +struct S { void (&ref)(); } s{f}; // OK, value is TU-local +constexpr extern struct W { S &s; } wrap{s}; // OK, value is not TU-local -\pnum -The function \tcode{main} shall not be used within -a program. -\indextext{\idxcode{main()}!implementation-defined linkage~of}% -The linkage~(\ref{basic.link}) of \tcode{main} is -\impldef{linkage of \tcode{main}}. A program that defines \tcode{main} as -deleted or that declares \tcode{main} to be -\tcode{inline}, \tcode{static}, or \tcode{constexpr} is ill-formed. The name \tcode{main} is -not otherwise reserved. \enterexample member functions, classes, and -enumerations can be called \tcode{main}, as can entities in other -namespaces. \exitexample +static auto x = []{f();}; // OK +auto x2 = x; // error: the closure type is TU-local +int y = ([]{f();}(),0); // error: the closure type is not TU-local +int y2 = (x,0); // OK -\pnum -\indextext{\idxcode{exit}}% -\indexlibrary{\idxcode{exit}}% -\indextext{termination!program}% -Terminating the program -without leaving the current block (e.g., by calling the function -\tcode{std::exit(int)} (\ref{support.start.term})) does not destroy any -objects with automatic storage duration~(\ref{class.dtor}). 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. +namespace N { + struct A {}; + void adl(A); + static void adl(int); +} +void adl(double); -\pnum -\indextext{termination!program}% -\indextext{\idxcode{main()}!return from}% -A return statement 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. If -control reaches the end of \tcode{main} without encountering a -\tcode{return} statement, the effect is that of executing +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; +void other() { + g<0>(); // OK, specialization is explicitly instantiated + g<1>(); // error: instantiation uses TU-local \tcode{its} + h(N::A{}); // error: overload set contains TU-local \tcode{N::adl(int)} + h(0); // OK, calls \tcode{adl(double)} + adl(N::A{}); // OK; \tcode{N::adl(int)} not found, calls \tcode{N::adl(N::A)} + fr(); // OK, calls \tcode{f} + constexpr auto ptr = fr; // error: \tcode{fr} is not usable in constant expressions here +} +\end{codeblocktu} +\end{example} + +\rSec1[basic.memobj]{Memory and objects} + +\rSec2[intro.memory]{Memory model} + +\pnum +\indextext{memory model|(}% +The fundamental storage unit in the \Cpp{} memory model is the +\defn{byte}. +A byte is at least large enough to contain +the ordinary literal encoding of any element of the basic +\indextext{character set!basic literal}% +literal character set\iref{lex.charset} +and the eight-bit code units of the Unicode +\indextext{UTF-8}% +UTF-8 encoding form +and is composed of a contiguous sequence of +bits, +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. + +\pnum +\begin{note} +The representation of types is described +in~\ref{basic.types.general}. +\end{note} + +\pnum +A \defn{memory location} is +the storage occupied by the object representation of +either an object of scalar type that is not a bit-field +or a maximal sequence of adjacent bit-fields all having nonzero width. +\begin{note} +Various +features of the language, such as references and virtual functions, might +involve additional memory locations that are not accessible to programs but are +managed by the implementation. +\end{note} +Two or more threads of +execution\iref{intro.multithread} can access separate memory +locations without interfering with each other. + +\pnum +\begin{note} +Thus a bit-field and an adjacent non-bit-field are in separate memory +locations, and therefore can be concurrently updated by two threads of execution +without interference. The same applies to two bit-fields, if one is declared +inside a nested struct declaration and the other is not, or if the two are +separated by a zero-length bit-field declaration, or if they are separated by a +non-bit-field declaration. It is not safe to concurrently update two bit-fields +in the same struct if all fields between them are also bit-fields of nonzero +width. +\end{note} + +\pnum +\begin{example} +A class declared as \begin{codeblock} -return 0; +struct { + char a; + int b:5, + c:11, + :0, + d:8; + struct {int ee:8;} e; +}; \end{codeblock} - -\rSec2[basic.start.init]{Initialization of non-local variables} +contains four separate memory locations: The member \tcode{a} and bit-fields +\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 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} +\indextext{memory model|)} + +\rSec2[intro.object]{Object model} + +\pnum +\indextext{object model|(}% +The constructs in a \Cpp{} program create, destroy, refer to, access, and +manipulate objects. +An \defn{object} is created +by a definition\iref{basic.def}, +by a \grammarterm{new-expression}\iref{expr.new}, +by an operation that implicitly creates objects (see below), +when implicitly changing the active member of a union\iref{class.union}, +or +when a temporary object is created\iref{conv.rval,class.temporary}. +An object occupies a region of storage +in its period of construction\iref{class.cdtor}, +throughout its lifetime\iref{basic.life}, +and +in its period of destruction\iref{class.cdtor}. +\begin{note} +A function is not an object, regardless of whether or not it +occupies storage in the way that objects do. +\end{note} +The properties of an +object are determined when the object is created. An object can have a +name\iref{basic.pre}. An object has a storage +duration\iref{basic.stc} which influences its +lifetime\iref{basic.life}. An object has a +type\iref{basic.types}. +\begin{note} +Some objects are +polymorphic\iref{class.virtual}; the implementation +generates information associated with each such object that makes it +possible to determine that object's type during program execution. +\end{note} + +\pnum +\indextext{subobject}% +Objects can contain other objects, called \defnx{subobjects}{subobject}. +A subobject can be +a \defn{member subobject}\iref{class.mem}, a \defn{base class subobject}\iref{class.derived}, +or an array element. +\indextext{object!complete}% +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 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 +\begin{itemize} +\item +the lifetime of \placeholder{e}'s containing object has begun and not ended, and +\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{initialization}% -\indextext{initialization!static and thread}% -There are two broad classes of named non-local variables: those with static storage -duration~(\ref{basic.stc.static}) and those with thread storage -duration~(\ref{basic.stc.thread}). Non-local variables with static storage duration -are initialized as a consequence of program initiation. Non-local variables with -thread storage duration are initialized as a consequence of thread execution. -Within each of these phases of initiation, initialization occurs as follows. +\indextext{object!providing storage for}% +If a complete object is created\iref{expr.new} +in storage associated with another object \placeholder{e} +of type ``array of $N$ \tcode{\keyword{unsigned} \keyword{char}}'' or +of type ``array of $N$ \tcode{std::byte}''\iref{cstddef.syn}, +that array \defn{provides storage} +for the created object if +\begin{itemize} +\item +the lifetime of \placeholder{e} has begun and not ended, and +\item +the storage for the new object fits entirely within \placeholder{e}, and +\item +there is no array object that satisfies these constraints nested within \placeholder{e}. +\end{itemize} +\begin{note} +If that portion of the array +previously provided storage for another object, +the lifetime of that object ends +because its storage was reused\iref{basic.life}. +\end{note} +\begin{example} +\begin{codeblock} +// assumes that \tcode{sizeof(int)} is equal to 4 -\pnum -\indextext{initialization!\idxcode{static object}}% -\indextext{initialization!dynamic}% -\indextext{initialization!run-time}% -\indextext{start!program}% -\indextext{initialization!order~of}% -Variables with static storage duration~(\ref{basic.stc.static}) or thread storage -duration~(\ref{basic.stc.thread}) shall be zero-initialized~(\ref{dcl.init}) before -any other initialization takes place. -A \term{constant initializer} for an object \tcode{o} is an expression that is a -constant expression, except that it may also invoke \tcode{constexpr} constructors -for \tcode{o} and its subobjects even if those objects are of non-literal class -types \enternote such a class may have a non-trivial destructor \exitnote. -\indextext{initialization!constant}% -\term{Constant initialization} is performed: +template +struct AlignedUnion { + alignas(T...) unsigned char data[max(sizeof(T)...)]; +}; +int f() { + AlignedUnion au; + int *p = new (au.data) int; // OK, \tcode{au.data} provides storage + char *c = new (au.data) char(); // OK, ends lifetime of \tcode{*p} + char *d = new (au.data + 1) char(); + return *c + *d; // OK +} +struct A { unsigned char a[32]; }; +struct B { unsigned char b[16]; }; +alignas(int) A a; +B *b = new (a.a + 8) B; // \tcode{a.a} provides storage for \tcode{*b} +int *p = new (b->b + 4) int; // \tcode{b->b} provides storage for \tcode{*p} + // \tcode{a.a} does not provide storage for \tcode{*p} (directly), + // but \tcode{*p} is nested within \tcode{a} (see below) +\end{codeblock} +\end{example} + +\pnum +\indextext{object!nested within}% +An object \placeholder{a} is \defn{nested within} another object \placeholder{b} if \begin{itemize} \item -if each full-expression (including implicit conversions) that appears in -the initializer of a reference with static or thread storage duration is a -constant expression~(\ref{expr.const}) and the reference is bound to a glvalue -designating an object with static storage duration, to a temporary object -(see~\ref{class.temporary}) or subobject thereof, or to a function; - +\placeholder{a} is a subobject of \placeholder{b}, or \item -if an object with static or thread storage duration is initialized -by a constructor call, and if the initialization full-expression is a constant -initializer for the object; +\placeholder{b} provides storage for \placeholder{a}, or +\item +there exists an object \placeholder{c} +where \placeholder{a} is nested within \placeholder{c}, +and \placeholder{c} is nested within \placeholder{b}. +\end{itemize} +\pnum +For every object \tcode{x}, there is some object called the +\defn{complete object of} \tcode{x}, determined as follows: +\begin{itemize} \item -if an object with static or thread storage duration is not initialized by a constructor call -and if either the object is value-initialized or every full-expression that -appears in its initializer is a constant expression. +If \tcode{x} is a complete object, then the complete object +of \tcode{x} is itself. +\item +Otherwise, the complete object of \tcode{x} is the complete object +of the (unique) object that contains \tcode{x}. \end{itemize} -Together, zero-initialization and constant initialization are called \defn{static -initialization}; all other initialization is \defn{dynamic initialization}. Static -initialization shall be performed before any dynamic initialization takes place. Dynamic -initialization of a non-local variable with static storage duration is -\defn{unordered} if the variable is an implicitly or explicitly instantiated -specialization, and otherwise is \defn{ordered} \enternote an explicitly -specialized static data member or variable template specialization has -ordered initialization.\exitnote. Variables with ordered -initialization defined within a single translation unit shall be initialized in the order of -their definitions in the translation unit. If a program starts a thread~(\ref{thread.threads}), -the subsequent initialization of a variable is unsequenced with respect to the initialization -of a variable defined in a different translation unit. Otherwise, the initialization of a -variable is indeterminately sequenced with respect to the initialization of a variable defined -in a different translation unit. If a program starts a thread, the subsequent unordered -initialization of a variable is unsequenced with respect to every other dynamic initialization. -Otherwise, the unordered initialization of a variable is indeterminately sequenced with respect -to every other dynamic initialization. \enternote This definition permits initialization of a -sequence of ordered variables concurrently with another sequence. \exitnote \enternote The -initialization of local static variables is described in~\ref{stmt.dcl}. \exitnote +\pnum +If a complete object, a member subobject, or an array element is of +class type, its type is considered the \defn{most derived +class}, to distinguish it from the class type of any base class subobject; +an object of a most derived class type or of a non-class type is called a +\defn{most derived object}. \pnum -An implementation is permitted to perform the initialization of a -non-local variable with static storage duration as a static -initialization even if such initialization is not required to be done -statically, provided that +A \defn{potentially-overlapping subobject} is either: +\begin{itemize} +\item a base class subobject, or +\item a non-static data member +declared with the \tcode{no_unique_address} attribute\iref{dcl.attr.nouniqueaddr}. +\end{itemize} +\pnum +\indextext{object!zero size}% +\indextext{object!nonzero size}% +An object has nonzero size if it +\begin{itemize} +\item is not a potentially-overlapping subobject, or +\item is not of class type, or +\item is of a class type with virtual member functions or virtual base classes, or +\item has subobjects of nonzero size or unnamed bit-fields of nonzero length. +\end{itemize} +Otherwise, if the object is a base class subobject +of a standard-layout class type +with no non-static data members, +it has zero size. +Otherwise, the circumstances under which the object has zero size +are \impldef{which non-standard-layout objects +containing no data are considered empty}. +\indextext{most derived object!bit-field}% +Unless it is a bit-field\iref{class.bit}, +an object with nonzero size +shall occupy one or more bytes of storage, +including every byte that is occupied in full or in part +by any of its subobjects. +An object of trivially copyable or +standard-layout type\iref{basic.types.general} shall occupy contiguous bytes of +storage. + +\pnum +An object is a \defnadj{potentially non-unique}{object} if it is \begin{itemize} \item -the dynamic version of the initialization does not change the -value of any other object of namespace scope prior to its initialization, and - + a string literal object\iref{lex.string}, \item -the static version of the initialization produces the same value -in the initialized variable as would be produced by the dynamic -initialization if all variables not required to be initialized statically -were initialized dynamically. + 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} -% \item -\enternote As a consequence, if the initialization of an object \tcode{obj1} refers to an -object \tcode{obj2} of namespace scope 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, - +\pnum +\indextext{most derived object!bit-field}% +\indextext{most derived object!zero size subobject}% +Unless an object is a bit-field or a subobject of zero size, the +address of that object is the address of the first byte it occupies. +Two objects +with overlapping lifetimes +that are not bit-fields +may have the same address if +\begin{itemize} +\item one is nested within the other, +\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{example} \begin{codeblock} -inline double fd() { return 1.0; } -extern double d1; -double d2 = d1; // unspecified: - // may be 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(); // may be initialized statically or dynamically to \tcode{1.0} +static const char test1 = 'x'; +static const char test2 = 'x'; +const bool b = &test1 != &test2; // always \tcode{true} + +static const char (&r) [] = "x"; +static const char *s = "x"; +static std::initializer_list il = { 'x' }; +const bool b2 = r != il.begin(); // unspecified result +const bool b3 = r != s; // unspecified result +const bool b4 = il.begin() != &test1; // always \tcode{true} +const bool b5 = r != &test1; // always \tcode{true} \end{codeblock} -\exitnote +\end{example} +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 -\indextext{evaluation!unspecified order~of}% -It is \impldef{dynamic initialization of static objects before \tcode{main}} whether the -dynamic initialization of a non-local variable with static storage duration is -done before the first statement of \tcode{main}. If the initialization is deferred to -some point in time after the first statement of \tcode{main}, it shall occur before the -first odr-use~(\ref{basic.def.odr}) of any function or variable -defined in the same translation unit as the variable -to be initialized.\footnote{A non-local variable with static storage duration -having initialization -with side-effects must be initialized even if it is not -odr-used (\ref{basic.def.odr},~\ref{basic.stc.static}).} -\enterexample +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} -// - File 1 - -#include "a.h" -#include "b.h" -B b; -A::A(){ - b.Use(); -} +struct A { + struct X { + int i; + int j; + }; -// - File 2 - -#include "a.h" -A a; + struct Y { + X x1; + X x2; + }; -// - File 3 - -#include "a.h" -#include "b.h" -extern A a; -extern B b; + union { + int i; + int arr[4]; + Y y; + }; +}; -int main() { - a.Use(); - b.Use(); +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} +within a specified region of storage. +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{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, +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. +\begin{note} +Such operations do not start the lifetimes of subobjects of such objects +that are not themselves of implicit-lifetime types. +\end{note} + +\pnum +Further, after implicitly creating objects within a specified region of storage, +some operations are described as producing a pointer to a +\defnadj{suitable created}{object}. +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. +If multiple such pointer values would give the program defined behavior, +it is unspecified which such pointer value is produced. + +\pnum +\begin{example} +\begin{codeblock} +#include +struct X { int a, b; }; +X *make_x() { + // The call to \tcode{std::malloc} implicitly creates an object of type \tcode{X} + // and its subobjects \tcode{a} and \tcode{b}, and returns a pointer to that \tcode{X} object + // (or an object that is pointer-interconvertible\iref{basic.compound} with it), + // in order to give the subsequent class member access operations + // defined behavior. + X *p = (X*)std::malloc(sizeof(struct X)); + p->a = 1; + p->b = 2; + return p; } \end{codeblock} - -It is implementation-defined whether either \tcode{a} or \tcode{b} is -initialized before \tcode{main} is entered or whether the -initializations are delayed until \tcode{a} is first odr-used in -\tcode{main}. In particular, if \tcode{a} is initialized before -\tcode{main} is entered, it is not guaranteed that \tcode{b} will be -initialized before it is odr-used by the initialization of \tcode{a}, that -is, before \tcode{A::A} is called. If, however, \tcode{a} is initialized -at some point after the first statement of \tcode{main}, \tcode{b} will -be initialized prior to its use in \tcode{A::A}. \exitexample - -\pnum -It is \impldef{dynamic initialization of thread-local objects before entry} whether the -dynamic initialization of a non-local variable with static or -thread storage duration -is done before the first statement of the initial function of the thread. If the -initialization is deferred to some point in time after the first statement of the -initial function of the thread, it shall occur before the first -odr-use~(\ref{basic.def.odr}) of any variable with -thread storage duration defined in the same translation unit as the variable to be -initialized. +\end{example} + +\pnum +Except during constant evaluation, +an operation that begins the lifetime of +an array of \tcode{unsigned char} or \tcode{std::byte} +implicitly creates objects within the region of storage occupied by the array. +\begin{note} +The array object provides storage for these objects. +\end{note} +Except during constant evaluation, +any implicit or explicit invocation of a function +named \tcode{\keyword{operator} \keyword{new}} or \tcode{\keyword{operator} \keyword{new}[]} +implicitly creates objects in the returned region of storage and +returns a pointer to a suitable created object. +\begin{note} +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|)} + +\rSec2[basic.align]{Alignment} + +\pnum +Object types have \defnx{alignment requirements}{alignment requirement!implementation-defined}\iref{basic.fundamental,basic.compound} +which place restrictions on the addresses at which an object of that type +may be allocated. An \defn{alignment} is an \impldef{alignment} +integer value representing the number of bytes between successive addresses +at which a given object can be allocated. An object type imposes an alignment +requirement on every object of that type; stricter alignment can be requested +using the \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. \pnum -If the initialization of a non-local variable with static or thread storage duration -exits via -an exception, \tcode{std::terminate} is called~(\ref{except.terminate}).% -\indextext{program!start|)} - -\rSec2[basic.start.term]{Termination} +A \defnadj{fundamental}{alignment} is represented by an alignment +less than or equal to the greatest alignment supported by the implementation in +all contexts, which is equal to +\tcode{\keyword{alignof}(std::max_align_t)}\iref{support.types}. +The alignment required for a type may be different when it is used as the type +of a complete object and when it is used as the type of a subobject. +\begin{example} +\begin{codeblock} +struct B { long double d; }; +struct D : virtual B { char c; }; +\end{codeblock} -\pnum -\indextext{program!termination|(}% -\indextext{object!destructor static}% -\indextext{\idxcode{main()}!return from}% -Destructors~(\ref{class.dtor}) for initialized objects -(that is, objects whose lifetime~(\ref{basic.life}) has begun) -with static storage duration -are called as a result of returning from \tcode{main} and as a result of calling -\indextext{\idxcode{exit}}% -\indexlibrary{\idxcode{exit}}% -\tcode{std::exit}~(\ref{support.start.term}). -Destructors for initialized objects with thread storage duration within a given thread -are called as a result of returning from the initial function of that thread and as a -result of that thread calling \tcode{std::exit}. -The completions of the destructors for all initialized objects with thread storage -duration within that thread are sequenced before the initiation of the destructors of -any object with static storage duration. -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. -If the completion of the constructor or dynamic initialization of an object with static -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. -\enternote This definition permits concurrent destruction. \exitnote 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-scope -object with static storage duration initialized during the construction -of the subobjects is destroyed. -If the destruction of an object with static or thread storage duration -exits via an exception, -\tcode{std::terminate} is called~(\ref{except.terminate}). +When \tcode{D} is the type of a complete object, it will have a subobject of +type \tcode{B}, so it must be aligned appropriately for a \tcode{\keyword{long} \keyword{double}}. +If \tcode{D} appears as a subobject of another object that also has \tcode{B} +as a virtual base class, the \tcode{B} subobject might be part of a different +subobject, reducing the alignment requirements on the \tcode{D} subobject. +\end{example} +The result of the \keyword{alignof} operator reflects the alignment +requirement of the type in the complete-object case. \pnum -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. +An \defnadj{extended}{alignment} is represented by an alignment +greater than \tcode{\keyword{alignof}(std::max_align_t)}. It is \impldef{support for extended alignments} +whether any extended alignments are supported and the contexts in which they are +supported\iref{dcl.align}. A type having an extended alignment +requirement is an \defnadj{over-aligned}{type}. +\begin{note} +Every over-aligned type is or contains a class type +to which extended alignment applies (possibly through a non-static data member). +\end{note} +A \defnadj{new-extended}{alignment} is represented by +an alignment greater than \mname{STDCPP_DEFAULT_NEW_ALIGNMENT}\iref{cpp.predefined}. \pnum -\indextext{\idxcode{atexit}}% -\indexlibrary{\idxcode{atexit}}% -If the completion of the initialization of an object with static storage -duration is sequenced before a call to \tcode{std::atexit}~(see -\tcode{},~\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} is sequenced before the completion of the initialization of -an object with static storage duration, the call to the destructor for the -object is sequenced before the call to the function passed to \tcode{std::atexit}. If a -call to \tcode{std::atexit} is sequenced before another call to \tcode{std::atexit}, the -call to the function passed to the second \tcode{std::atexit} call is sequenced before -the call to the function passed to the first \tcode{std::atexit} call. +Alignments are represented as values of the type \tcode{std::size_t}. +Valid alignments include only those values returned by an \keyword{alignof} +expression for the fundamental types plus an additional \impldef{alignment additional +values} +set of values, which may be empty. +Every alignment value shall be a non-negative integral power of two. \pnum -If there is a use of a standard library object or function not permitted within signal -handlers~(\ref{support.runtime}) that does not happen before~(\ref{intro.multithread}) -completion of destruction of objects with static storage duration and execution of -\tcode{std::atexit} registered functions~(\ref{support.start.term}), the program has -undefined behavior. \enternote If there is a use of an object with static storage -duration that does not happen before the object's destruction, the program has undefined -behavior. Terminating every thread before a call to \tcode{std::exit} or the exit from -\tcode{main} is sufficient, but not necessary, to satisfy these requirements. These -requirements permit thread managers as static-storage-duration objects. \exitnote +Alignments have an order from \defnx{weaker}{alignment!weaker} to +\defnx{stronger}{alignment!stronger} or \defnx{stricter}{alignment!stricter} alignments. Stricter +alignments have larger alignment values. An address that satisfies an alignment +requirement also satisfies any weaker valid alignment requirement. \pnum -\indextext{\idxcode{abort}}% -\indexlibrary{\idxcode{abort}}% -\indextext{termination!program}% -Calling the function \tcode{std::abort()} declared in -\indextext{\idxhdr{cstdlib}}% -\tcode{} terminates the program without executing any destructors -and without calling -the functions passed to \tcode{std::atexit()} or \tcode{std::at_quick_exit()}.% -\indextext{program!termination|)} - -\rSec1[basic.stc]{Storage duration} +The alignment requirement of a complete type can be queried using an +\keyword{alignof} expression\iref{expr.alignof}. Furthermore, +the narrow character types\iref{basic.fundamental} shall have the weakest +alignment requirement. +\begin{note} +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 -\indextext{storage~duration|(}% -Storage duration is the property of an object that defines the minimum -potential lifetime of the storage containing the object. The storage -duration is determined by the construct used to create the object and is -one of the following: +Comparing alignments is meaningful and provides the obvious results: \begin{itemize} -\item static storage duration -\item thread storage duration -\item automatic storage duration -\item dynamic storage duration +\item Two alignments are equal when their numeric values are equal. +\item Two alignments are different when their numeric values are not equal. +\item When an alignment is larger than another it represents a stricter alignment. \end{itemize} \pnum -\indextext{storage~duration!static}% -\indextext{storage~duration!thread}% -\indextext{storage~duration!automatic}% -\indextext{storage~duration!dynamic}% -Static, thread, and automatic storage durations are associated with objects -introduced by declarations~(\ref{basic.def}) and implicitly created by -the implementation~(\ref{class.temporary}). The dynamic storage duration -is associated with objects created with \tcode{operator} -\tcode{new}~(\ref{expr.new}). +\begin{note} +The runtime pointer alignment function\iref{ptr.align} +can be used to obtain an aligned pointer within a buffer; +an \grammarterm{alignment-specifier}\iref{dcl.align} +can be used to align storage explicitly. +\end{note} \pnum -The storage duration categories apply to references as well. The -lifetime of a reference is its storage duration. +If a request for a specific extended alignment in a specific context is not +supported by an implementation, the program is ill-formed. -\rSec2[basic.stc.static]{Static storage duration} +\rSec2[basic.life]{Lifetime} \pnum -\indextext{storage~duration!static}% -All variables which do not have dynamic storage duration, do not have thread -storage duration, and are not local -have \defn{static storage duration}. The -storage for these entities shall last for the duration of the -program~(\ref{basic.start.init}, \ref{basic.start.term}). +In this subclause, ``before'' and ``after'' refer to the ``happens before'' +relation\iref{intro.multithread}. \pnum -If a variable with static storage duration has initialization or a -destructor with side effects, it shall not be eliminated even if it -appears to be unused, except that a class object or its copy/move may be -eliminated as specified in~\ref{class.copy}. +\indextext{object lifetime|(}% +The \defn{lifetime} of an object or reference is a runtime property of the +object or reference. +A variable is said to have \defnadj{vacuous}{initialization} +if it is default-initialized, no other initialization is performed, and, +if it is of class type or a (possibly multidimensional) array thereof, +a trivial constructor of that class type is selected for +the default-initialization. +The lifetime of an object of type \tcode{T} begins when: +\begin{itemize} +\item storage with the proper alignment and size + for type \tcode{T} is obtained, and +\item its initialization (if any) is complete + (including vacuous initialization)\iref{dcl.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}, +and except as described in \ref{allocator.members}. +The lifetime of an object \placeholder{o} of type \tcode{T} ends when: +\begin{itemize} +\item if \tcode{T} is a non-class type, the object is destroyed, or +\item if \tcode{T} is a class type, the destructor call starts, or +\item the storage which the object occupies is released, +or is reused by an object that is not nested within \placeholder{o}\iref{intro.object}. +\end{itemize} +When evaluating a \grammarterm{new-expression}, +storage is considered reused after it is returned from the allocation function, +but before the evaluation of the \grammarterm{new-initializer}\iref{expr.new}. +\begin{example} +\begin{codeblock} +struct S { + int m; +}; -\pnum -\indextext{object!\idxcode{local static}}% -The keyword \tcode{static} can be used to declare a local variable with -static storage duration. \enternote \ref{stmt.dcl} describes the -initialization of local \tcode{static} variables; \ref{basic.start.term} -describes the destruction of local \tcode{static} variables. \exitnote +void f() { + S x{1}; + new(&x) S(x.m); // undefined behavior +} +\end{codeblock} +\end{example} \pnum -\indextext{member!\idxcode{class static}}% -The keyword \tcode{static} applied to a class data member in a class -definition gives the data member static storage duration. +\indextext{reference lifetime}% +The lifetime of a reference begins when its initialization is complete. +The lifetime of a reference ends as if it were a scalar object requiring storage. -\rSec2[basic.stc.thread]{Thread storage duration} +\pnum +\begin{note} +\ref{class.base.init} +describes the lifetime of base and member subobjects. +\end{note} \pnum -\indextext{storage~duration!thread}% -All variables declared with the \tcode{thread_local} keyword have \defn{thread -storage duration}. The storage for these entities shall last for the duration of -the thread in which they are created. There is a distinct object or reference -per thread, and use of the declared name refers to the entity associated with -the current thread. - -\pnum -A variable with thread storage duration shall be initialized before -its first odr-use~(\ref{basic.def.odr}) and, if constructed, shall be destroyed on thread exit. - -\rSec2[basic.stc.auto]{Automatic storage duration} - -\pnum -\indextext{storage~duration!automatic}% -\indextext{storage~duration!\idxcode{register}}% -\indextext{storage~duration!local object}% -Block-scope variables explicitly declared \tcode{register} or -not explicitly declared \tcode{static}, \tcode{thread_local}, or \tcode{extern} have -\defn{automatic storage duration}. The storage -for these entities lasts until the block in which they are created exits. - -\pnum -\enternote -These variables are initialized and destroyed as described in~\ref{stmt.dcl}. -\exitnote - -\pnum -If a variable with automatic storage duration has initialization or a destructor with side -effects, it shall not be destroyed before the end of its block, nor -shall it be eliminated as an optimization even if it appears to be -unused, except that a class object or its copy/move may be eliminated as -specified in~\ref{class.copy}. - -\rSec2[basic.stc.dynamic]{Dynamic storage duration}% -\indextext{storage~duration!dynamic|(} - -\pnum -Objects can be created dynamically during program -execution~(\ref{intro.execution}), using -\indextext{\idxcode{new}}% -\grammarterm{new-expression}{s}~(\ref{expr.new}), and destroyed using -\indextext{\idxcode{delete}}% -\grammarterm{delete-expression}{s}~(\ref{expr.delete}). A \Cpp implementation -provides access to, and management of, dynamic storage via the global -\defn{allocation functions} \tcode{operator new} and \tcode{operator -new[]} and the global \defn{deallocation functions} \tcode{operator -delete} and \tcode{operator delete[]}. - -\pnum -The library provides default definitions for the global allocation and -deallocation functions. Some global allocation and deallocation -functions are replaceable~(\ref{new.delete}). 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~(\ref{replacement.functions}). The -following allocation and deallocation functions~(\ref{support.dynamic}) -are implicitly declared in global scope in each translation unit of a -program. - -\begin{codeblock} -void* operator new(std::size_t); -void* operator new[](std::size_t); -void operator delete(void*) noexcept; -void operator delete[](void*) noexcept; -void operator delete(void*, std::size_t) noexcept; -void operator delete[](void*, std::size_t) noexcept; -\end{codeblock} - -These implicit declarations introduce only the function names -\tcode{operator} \tcode{new}, \tcode{operator} \tcode{new[]}, -\tcode{op\-er\-a\-tor} \tcode{delete}, and \tcode{operator} -\tcode{delete[]}. \enternote The implicit declarations do not introduce -the names \tcode{std}, -\tcode{std\colcol{}size_t}, or any other names that the library uses to -declare these names. Thus, a \grammarterm{new-expression}, -\grammarterm{delete-expression} or function call that refers to one of -these functions without including the header \tcode{} is -well-formed. However, referring to \tcode{std} -or \tcode{std::size_t} is ill-formed unless the name has been declared -by including the appropriate header. \exitnote Allocation and/or -deallocation functions can also be declared and defined for any -class~(\ref{class.free}). - -\pnum -Any allocation and/or deallocation functions defined in a \Cpp program, -including the default versions in the library, shall conform to the -semantics specified in~\ref{basic.stc.dynamic.allocation} -and~\ref{basic.stc.dynamic.deallocation}. - -\rSec3[basic.stc.dynamic.allocation]{Allocation functions} - -\pnum -\indextext{function!allocation}% -An allocation function shall be a class member function or a global -function; a program is ill-formed if an allocation function is declared -in a namespace scope other than global scope or declared static in -global scope. The return type shall be \tcode{void*}. The first -parameter shall have type \tcode{std::size_t}~(\ref{support.types}). The -first parameter shall not have an associated default -argument~(\ref{dcl.fct.default}). The value of the first parameter shall -be interpreted as the requested size of the allocation. An allocation -function can be a function template. Such a template shall declare its -return type and first parameter as specified above (that is, template -parameter types shall not be used in the return type and first parameter -type). Template allocation functions shall have two or more parameters. - -\pnum -The allocation function attempts to allocate the requested amount of -storage. If it is successful, it shall return the address of the start -of a block of storage whose length in bytes shall be at least as large -as the requested size. There are no constraints on the contents of the -allocated storage on return from the allocation function. The order, -contiguity, and initial value of storage allocated by successive calls -to an allocation function are unspecified. The pointer returned shall be -suitably aligned so that it can be converted to a pointer of any -complete object type with a fundamental alignment requirement~(\ref{basic.align}) -and then used to access the object or array in the -storage allocated (until the storage is explicitly deallocated by a call -to a corresponding deallocation function). Even if the size of the space -requested is zero, the request can fail. If the request succeeds, the -value returned shall be a non-null pointer value~(\ref{conv.ptr}) -\tcode{p0} different from any previously returned value \tcode{p1}, -unless that value \tcode{p1} was subsequently passed to an -\tcode{operator} \tcode{delete}. -Furthermore, for the library allocation functions -in~\ref{new.delete.single} and~\ref{new.delete.array}, -\tcode{p0} shall point to a block of storage disjoint from the storage -for any other object accessible to the caller. -The effect of indirecting through a pointer -returned as a request for zero size is undefined.\footnote{The intent is -to have \tcode{operator new()} implementable by -calling \tcode{std::malloc()} or \tcode{std::calloc()}, so the rules are -substantially the same. \Cpp differs from C in requiring a zero request -to return a non-null pointer.} - -\pnum -An allocation function that fails to allocate storage can invoke the -currently installed new-handler function~(\ref{new.handler}), if any. -\enternote -\indextext{\idxcode{new_handler}}% -A program-supplied allocation function can obtain the address of the -currently installed \tcode{new_handler} using the -\tcode{std::get_new_handler} function~(\ref{set.new.handler}). \exitnote -If an allocation function that has a non-throwing -exception specification~(\ref{except.spec}) -fails to allocate storage, it shall return a null pointer. Any other -allocation function that fails to allocate storage shall indicate -failure only by throwing an exception~(\ref{except.throw}) of a type -that would match a handler~(\ref{except.handle}) of type -\tcode{std::bad_alloc}~(\ref{bad.alloc}). - -\pnum -A global allocation function is only called as the result of a new -expression~(\ref{expr.new}), or called directly using the function call -syntax~(\ref{expr.call}), or called indirectly through calls to the -functions in the \Cpp standard library. \enternote In particular, a -global allocation function is not called to allocate storage for objects -with static storage duration~(\ref{basic.stc.static}), for objects or references -with thread storage duration~(\ref{basic.stc.thread}), for objects of -type \tcode{std::type_info}~(\ref{expr.typeid}), or for an -exception object~(\ref{except.throw}). -\exitnote - -\rSec3[basic.stc.dynamic.deallocation]{Deallocation functions} - -\pnum -\indextext{function!deallocation}% -Deallocation functions shall be class member functions or global -functions; a program is ill-formed if deallocation functions are -declared in a namespace scope other than global scope or declared static -in global scope. - -\pnum -\indextext{\idxcode{delete}!overloading~and}% -Each deallocation function shall return \tcode{void} and its first -parameter shall be \tcode{void*}. A deallocation function can have more -than one parameter. -The global \tcode{operator delete} with exactly one parameter is a usual -(non-placement) deallocation function. The global \tcode{operator delete} with -exactly two parameters, the second of which has type \tcode{std::size_t}, is a usual -deallocation function. Similarly, the global \tcode{operator delete[]} with exactly one -parameter is a usual deallocation function. The global \tcode{operator delete[]} with -exactly two parameters, the second of which has type \tcode{std::size_t}, is a usual -deallocation function.\footnote{This deallocation function precludes use of an -allocation function \tcode{void operator new(std::size_t, std::size_t)} as a placement -allocation function (\ref{diff.cpp11.basic}).} -If a class \tcode{T} has a member deallocation -function named \tcode{operator} \tcode{delete} with exactly one -parameter, then that function is a usual deallocation -function. If class \tcode{T} does not declare such an \tcode{operator} -\tcode{delete} but does declare a member deallocation function named -\tcode{operator} \tcode{delete} with exactly two parameters, the second -of which has type \tcode{std::size_t}, then this -function is a usual deallocation function. Similarly, if a class -\tcode{T} has a member deallocation function named \tcode{operator} -\tcode{delete[]} with exactly one parameter, then that function is a -usual (non-placement) deallocation function. If class \tcode{T} does not -declare such an \tcode{operator} \tcode{delete[]} but does declare a -member deallocation function named \tcode{operator} \tcode{delete[]} -with exactly two parameters, the second of which has type -\tcode{std::size_t}, then this function is a usual deallocation -function. A deallocation function can be an instance of a function -template. Neither the first parameter nor the return type shall depend -on a template parameter. \enternote That is, a deallocation function -template shall have a first parameter of type \tcode{void*} and a return -type of \tcode{void} (as specified above). \exitnote A deallocation -function template shall have two or more function parameters. A template -instance is never a usual deallocation function, regardless of its -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. Otherwise, -the behavior is undefined if -the -value supplied to \tcode{operator} \tcode{delete(void*)} in the standard -library is not one of the values returned by a previous invocation of -either \tcode{operator} \tcode{new(std::size_t)} or \tcode{operator} -\tcode{new(std::size_t,} \tcode{const} \tcode{std::nothrow_t\&)} in the -standard library, and -the behavior is undefined if -the value supplied to \tcode{operator} -\tcode{delete[](void*)} in the standard library is not one of the -values returned by a previous invocation of either \tcode{operator} -\tcode{new[](std::size_t)} or \tcode{operator} -\tcode{new[](std::size_t,} \tcode{const} \tcode{std::nothrow_t\&)} in -the standard library. - -\pnum -If the argument given to a deallocation function in the standard library -is a pointer that is not the null pointer value~(\ref{conv.ptr}), the -deallocation function shall deallocate the storage referenced by the -pointer, rendering invalid all pointers referring to any part of the -deallocated storage. -\indextext{object!undefined deleted}% -Indirection through an invalid pointer value and passing an invalid -pointer value to a deallocation function have undefined behavior. Any -other use of an invalid pointer value has implementation-defined -behavior.\footnote{Some implementations might define that copying an - invalid pointer value causes a system-generated runtime fault.} - -\rSec3[basic.stc.dynamic.safety]{Safely-derived pointers} - -\pnum -\indextext{pointer!safely-derived|(}% -\indextext{pointer!to~traceable~object}% -A \defn{traceable pointer object} is - -\begin{itemize} -\item an object of an object pointer -type~(\ref{basic.compound}), or -\item an object of an integral type that is at least as large as \tcode{std::intptr_t}, -or -\item a sequence of elements in an array of narrow character -type~(\ref{basic.fundamental}), where the size and alignment of the sequence -match those of some object pointer type. -\end{itemize} - -\pnum -\indextext{safely-derived pointer}% -A pointer value is a \grammarterm{safely-derived pointer} to a dynamic object only if it -has an object pointer type and it is one of the following: - -\begin{itemize} -\item the value returned by a call to the \Cpp standard library implementation of -\tcode{::operator new(std\colcol{}size_t)};\footnote{This section does not impose restrictions -on indirection through pointers to memory not allocated by \tcode{::operator new}. This -maintains the ability of many \Cpp implementations to use binary libraries and -components written in other languages. In particular, this applies to C binaries, -because indirection through pointers to memory allocated by \tcode{std\colcol{}malloc} is not restricted.} - -\item the result of taking the address of an object (or one of its - subobjects) designated by an lvalue resulting from indirection - through a safely-derived pointer value; - -\item the result of well-defined pointer arithmetic~(\ref{expr.add}) using a safely-derived pointer -value; - -\item the result of a well-defined pointer -conversion~(\ref{conv.ptr},~\ref{expr.cast}) of a safely-derived pointer value; - -\item the result of a \tcode{reinterpret_cast} of a safely-derived pointer value; - -\item the result of a \tcode{reinterpret_cast} of an integer representation of a -safely-derived pointer value; - -\item the value of an object whose value was copied from a traceable pointer object, -where at the time of the copy the source object contained a copy of a safely-derived -pointer value. -\end{itemize} - -\pnum -\indextext{integer representation}% -\indextext{safely-derived pointer!integer representation}% -\indextext{pointer, integer representation of safely-derived}% -An integer value is an \grammarterm{integer representation of a safely-derived pointer} -only if its type is at least as large as \tcode{std::intptr_t} and it is one of the -following: - -\begin{itemize} -\item the result of a \tcode{reinterpret_cast} of a safely-derived pointer value; - -\item the result of a valid conversion of an integer representation of a safely-derived -pointer value; - -\item the value of an object whose value was copied from a traceable pointer object, -where at the time of the copy the source object contained an integer representation of a -safely-derived pointer value; - -\item the result of an additive or bitwise operation, one of whose operands is an -integer representation of a safely-derived pointer value \tcode{P}, if that result -converted by \tcode{reinterpret_cast} would compare equal to a safely-derived -pointer computable from \tcode{reinterpret_cast(P)}. -\end{itemize} - -\pnum -An implementation may have \defn{relaxed pointer safety}, in which case the -validity of a pointer value does not depend on whether it is a safely-derived -pointer value. Alternatively, an implementation may have \defn{strict pointer -safety}, in which case a pointer value referring to an object with dynamic -storage duration that is not a safely-derived pointer -value is an invalid pointer value unless -the referenced complete object has previously been declared -reachable~(\ref{util.dynamic.safety}). \enternote -the effect of using an invalid pointer value (including passing it to a -deallocation function) is undefined, see~\ref{basic.stc.dynamic.deallocation}. -This is true even if the unsafely-derived pointer value might compare equal to -some safely-derived pointer value. \exitnote It is implementation -defined\indeximpldef{whether an implementation has relaxed or strict pointer -safety} whether an implementation has relaxed or strict pointer safety.% -\indextext{pointer!safely-derived|)}% -\indextext{storage~duration!dynamic|)} - -\rSec2[basic.stc.inherit]{Duration of subobjects} - -\pnum -\indextext{storage~duration!class member}% -The storage duration of member subobjects, base class subobjects and -array elements is that of their complete object~(\ref{intro.object}). -\indextext{storage~duration|)}% - -\rSec1[basic.life]{Object lifetime} - -\pnum -\indextext{object~lifetime|(}% -\indextext{initialization!non-vacuous}% -The \defn{lifetime} of an object is a runtime property of the -object. -An object is said to have \term{non-vacuous initialization} if it is of a class or -aggregate type and it or one of its members is initialized by a constructor -other than a trivial default constructor. \enternote initialization by a -trivial copy/move constructor is non-vacuous initialization. \exitnote -The lifetime of an object of type \tcode{T} begins when: - -\begin{itemize} -\item storage with the proper alignment and size for type \tcode{T} is -obtained, and - -\item if the object has non-vacuous initialization, its initialization is complete. -\end{itemize} - -The lifetime of an object of type \tcode{T} ends when: - -\begin{itemize} -\item if \tcode{T} is a class type with a non-trivial -destructor~(\ref{class.dtor}), the destructor call starts, or - -\item the storage which the object occupies is reused or released. -\end{itemize} - -\pnum -\enternote The lifetime of an array object starts as soon as storage with proper size and -alignment is obtained, and its lifetime ends when the storage which the -array occupies is reused or released. \ref{class.base.init} -describes the lifetime of base and member subobjects. \exitnote - -\pnum -The properties ascribed to objects throughout this International -Standard apply for a given object only during its lifetime. \enternote +The properties ascribed to objects and references throughout this document +apply for a given object or reference only during its lifetime. +\begin{note} In particular, before the lifetime of an object starts and after its lifetime ends there are significant restrictions on the use of the -object, as described below, in~\ref{class.base.init} and +object, as described below, in~\ref{class.base.init}, and in~\ref{class.cdtor}. Also, the behavior of an object under construction -and destruction might not be the same as the behavior of an object whose +and destruction can differ from the behavior of an object whose lifetime has started and not ended. \ref{class.base.init} -and~\ref{class.cdtor} describe the behavior of objects during the -construction and destruction phases. \exitnote +and~\ref{class.cdtor} describe the behavior of an object during its periods +of construction and destruction. +\end{note} \pnum -A program may end the lifetime of any object by reusing the storage -which the object occupies or by explicitly calling the destructor for an -object of a class type with a non-trivial destructor. For an object of a -class type with a non-trivial destructor, the program is not required to -call the destructor explicitly before the storage which the object -occupies is reused or released; however, if there is no explicit call to -the destructor or if a \grammarterm{delete-expression}~(\ref{expr.delete}) -is not used to release the storage, the destructor shall not be -implicitly called and any program that depends on the side effects -produced by the destructor has undefined behavior. +A program may end the lifetime of an object of class type without invoking the +destructor, by reusing or releasing the storage as described above. +\begin{note} +A \grammarterm{delete-expression}\iref{expr.delete} invokes the destructor +prior to releasing the storage. +\end{note} +In this case, the destructor is not implicitly invoked. +\begin{note} +The correct behavior of a program often depends on +the destructor being invoked for each object of class type. +\end{note} \pnum Before the lifetime of an object has started but after the storage which -the object will occupy has been allocated\footnote{For example, before the -construction of a global object of -non-POD class type~(\ref{class.cdtor}).} -or, after the lifetime of an object has ended and before the storage -which the object occupied is reused or released, any pointer that refers -to the storage location where the object will be or was located may be +the object will occupy has been allocated +\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 +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. For an object under construction or destruction, see~\ref{class.cdtor}. Otherwise, such a pointer refers to allocated -storage~(\ref{basic.stc.dynamic.deallocation}), and using the pointer as -if the pointer were of type \tcode{void*}, is +storage\iref{basic.stc.dynamic.allocation}, and using the pointer as +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 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}, - -\item the pointer is used to access a non-static data member or call a -non-static member function of the object, or - -\item the pointer is implicitly converted~(\ref{conv.ptr}) to a pointer -to a virtual base class, or - -\item the pointer is used as the operand of a -\tcode{static_cast}~(\ref{expr.static.cast}), except when the conversion -is to pointer to \term{cv} \tcode{void}, or to pointer to \term{cv} -\tcode{void} and subsequently to pointer to either \term{cv} -\tcode{char} or \term{cv} \tcode{unsigned char}, or - -\item the pointer is used as the operand of a -\tcode{dynamic_cast}~(\ref{expr.dynamic.cast}). \enterexample - +\item + the pointer is used as the operand of a \grammarterm{delete-expression}, +\item + the pointer is used to access a non-static data member or call a + non-static member function of the object, or +\item + the pointer is converted\iref{conv.ptr,expr.static.cast} to a pointer + to a virtual base class or to a base class thereof, or +\item + the pointer is used as the operand of a + \keyword{dynamic_cast}\iref{expr.dynamic.cast}. +\end{itemize} +\begin{example} \begin{codeblock} #include @@ -3274,72 +4059,79 @@ void B::mutate() { new (this) D2; // reuses storage --- ends the lifetime of \tcode{*this} f(); // undefined behavior - ... = this; // OK, \tcode{this} points to valid memory + ... = this; // OK, \keyword{this} points to valid memory } void g() { void* p = std::malloc(sizeof(D1) + sizeof(D2)); B* pb = new (p) D1; pb->mutate(); - &pb; // OK: \tcode{pb} points to valid memory - void* q = pb; // OK: \tcode{pb} points to valid memory - pb->f(); // undefined behavior, lifetime of \tcode{*pb} has ended + *pb; // OK, \tcode{pb} points to valid memory + void* q = pb; // OK, \tcode{pb} points to valid memory + pb->f(); // undefined behavior: lifetime of \tcode{*pb} has ended } \end{codeblock} -\exitexample -\end{itemize} +\end{example} \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. For an object under construction or destruction, see~\ref{class.cdtor}. Otherwise, such a glvalue refers to -allocated storage~(\ref{basic.stc.dynamic.deallocation}), and using the +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 an lvalue-to-rvalue conversion~(\ref{conv.lval}) is applied to such a glvalue, - -\item the glvalue is used to access a non-static data member or call a -non-static member function of the object, or - -\item the glvalue is bound to a reference -to a virtual base class~(\ref{dcl.init.ref}), or - +\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 as the operand of a -\tcode{dynamic_cast}~(\ref{expr.dynamic.cast}) or as the operand of -\tcode{typeid}. +\keyword{dynamic_cast}\iref{expr.dynamic.cast} or as the operand of +\keyword{typeid}. \end{itemize} -\pnum -If, after the lifetime of an object has ended and before the storage -which the object occupied is reused or released, a new object is created -at the storage location which the original object occupied, a pointer -that pointed to the original object, a reference that referred to the -original object, or the name of the original object will automatically -refer to the new object and, once the lifetime of the new object has -started, can be used to manipulate the new object, if: +\begin{note} +Therefore, undefined behavior results +if an object that is being constructed in one thread is referenced from another +thread without adequate synchronization. +\end{note} +\pnum +An object $o_1$ is \defn{transparently replaceable} by an object $o_2$ if either \begin{itemize} -\item the storage for the new object exactly overlays the storage -location which the original object occupied, and - -\item the new object is of the same type as the original object -(ignoring the top-level cv-qualifiers), and +\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), or +\end{itemize} -\item the type of the original object is not const-qualified, and, if a -class type, does not contain any non-static data member whose type is -const-qualified or a reference type, and +\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} -\item the original object was a most derived object~(\ref{intro.object}) -of type \tcode{T} and the new object is a most derived object of type -\tcode{T} (that is, they are not base class subobjects). \enterexample +\pnum +After the lifetime of an object has ended and before the storage which the +object occupied is reused or released, if a new object is created at the +storage location which the original object occupied and the original object was +transparently replaceable by the new object, a pointer that pointed to the +original object, a reference that referred to the original object, or the name +of the original object will automatically refer to the new object and, once the +lifetime of the new object has started, can be used to manipulate the new +object. +\begin{example} \begin{codeblock} struct C { int i; @@ -3361,44 +4153,51 @@ c1 = c2; // well-defined c1.f(); // well-defined; \tcode{c1} refers to a new object of type \tcode{C} \end{codeblock} - -\exitexample -\end{itemize} +\end{example} +\begin{note} +If these conditions are not met, +a pointer to the new object can be obtained from +a pointer that represents the address of its storage +by calling \tcode{std::launder}\iref{ptr.launder}. +\end{note} \pnum If a program ends the lifetime of an object of type \tcode{T} with -static~(\ref{basic.stc.static}), thread~(\ref{basic.stc.thread}), -or automatic~(\ref{basic.stc.auto}) -storage duration and if \tcode{T} has a non-trivial destructor,\footnote{That +static\iref{basic.stc.static}, thread\iref{basic.stc.thread}, +or automatic\iref{basic.stc.auto} +storage duration and if \tcode{T} has a non-trivial destructor, +\begin{footnote} +That is, an object for which a destructor will be called implicitly---upon exit from the block for an object with automatic storage duration, upon exit from the thread for an object with thread storage duration, or upon exit from the program for an object -with static storage duration.} -the program must ensure that an object of the original type occupies +with static storage duration. +\end{footnote} +and another object of the original type does not occupy that same storage location when the implicit destructor call takes -place; otherwise the behavior of the program is undefined. This is true -even if the block is exited with an exception. \enterexample - +place, the behavior of the program is undefined. This is true +even if the block is exited with an exception. +\begin{example} \begin{codeblock} class T { }; struct B { - ~B(); + ~B(); }; void h() { - B b; - new (&b) T; + B b; + new (&b) T; } // undefined behavior at block exit \end{codeblock} -\exitexample +\end{example} \pnum -Creating a new object at the storage location that a \tcode{const} -object with static, thread, or automatic storage duration occupies or, at the -storage location that such a \tcode{const} object used to occupy before -its lifetime ended results in undefined behavior. \enterexample - +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. +\begin{example} \begin{codeblock} struct B { B(); @@ -3409,876 +4208,3997 @@ void h() { b.~B(); - new (const_cast(&b)) const B; // undefined behavior + new (const_cast(&b)) const B; // undefined behavior } \end{codeblock} -\exitexample - -\pnum -In this section, ``before'' and ``after'' refer to the ``happens before'' -relation~(\ref{intro.multithread}). \enternote Therefore, undefined behavior results -if an object that is being constructed in one thread is referenced from another -thread without adequate synchronization. \exitnote% -\indextext{object~lifetime|)} +\end{example} +\indextext{object lifetime|)} -\rSec1[basic.types]{Types}% -\indextext{type|(} - -\pnum -\enternote -\ref{basic.types} and the subclauses thereof -impose requirements on implementations regarding the representation -of types. -There are two kinds of types: fundamental types and compound types. -Types describe objects (\ref{intro.object}), -references (\ref{dcl.ref}), -or functions (\ref{dcl.fct}). -\exitnote +\rSec2[basic.indet]{Indeterminate and erroneous values} \pnum -\indextext{object!byte~copying~and|(}% -\indextext{type!trivially~copyable}% -For any object (other than a base-class subobject) of trivially copyable type -\tcode{T}, whether or not the object holds a valid value of type -\tcode{T}, the underlying bytes~(\ref{intro.memory}) making up the -object can be copied into an array of \tcode{char} or \tcode{unsigned} -\tcode{char}.\footnote{By using, for example, the library -functions~(\ref{headers}) \tcode{std::memcpy} or \tcode{std::memmove}.} -If the content of the array of \tcode{char} or \tcode{unsigned} -\tcode{char} is copied back into the object, the object shall -subsequently hold its original value. \enterexample - +When storage for an object with automatic or dynamic storage duration +is obtained, +the bytes comprising the storage for the object +have the following initial value: +\begin{itemize} +\item +If the object has dynamic storage duration, or +is the object associated with a variable or function parameter +whose first declaration is marked with +the \tcode{[[indeterminate]]} attribute\iref{dcl.attr.indet}, +the bytes have \defnadjx{indeterminate}{values}{value}; +\item +otherwise, the bytes have \defnadjx{erroneous}{values}{value}, +where each value is determined by the implementation +independently of the state of the program. +\end{itemize} +If no initialization is performed for an object (including subobjects), +such a byte retains its initial value +until that value is replaced\iref{dcl.init.general,expr.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. +\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 +if an erroneous value is produced by an evaluation, +the behavior is erroneous and +the result of the evaluation is that erroneous value: +\begin{itemize} +\item + If an indeterminate or erroneous value of + unsigned ordinary character type\iref{basic.fundamental} + or \tcode{std::byte} type\iref{cstddef.syn} + is produced by the evaluation of: + \begin{itemize} + \item + the second or third operand of a conditional expression\iref{expr.cond}, + \item + the right operand of a comma expression\iref{expr.comma}, + \item + the operand of a cast or conversion\iref{conv.integral, + expr.type.conv,expr.static.cast,expr.cast} + to an unsigned ordinary character type + or \tcode{std::byte} type\iref{cstddef.syn}, or + \item + a discarded-value expression\iref{expr.context}, + \end{itemize} + then the result of the operation is an indeterminate value or + that erroneous value, respectively. +\item + If an indeterminate or erroneous value of + unsigned ordinary character type or \tcode{std::byte} type + is produced by the evaluation of + the right operand of a simple assignment operator\iref{expr.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 + the value of the object referred to by the left operand. +\item + If an indeterminate or erroneous value of unsigned ordinary character type + is produced by the evaluation of the initialization expression + when initializing an object of unsigned ordinary character type, + that object is initialized to an indeterminate + value or that erroneous value, respectively. +\item + If an indeterminate 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, + that object is initialized to an indeterminate value or + that erroneous value, respectively. +\end{itemize} +Converting an indeterminate or erroneous value of +unsigned ordinary character type or \tcode{std::byte} type +produces an indeterminate or erroneous value, respectively. +In the latter case, +the result of the conversion is the value of the converted operand. +\begin{example} \begin{codeblock} -#define 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} -\exitexample - -\pnum -For any trivially copyable type \tcode{T}, if two pointers to \tcode{T} point to -distinct \tcode{T} objects \tcode{obj1} and \tcode{obj2}, where neither -\tcode{obj1} nor \tcode{obj2} is a base-class subobject, if the underlying -bytes~(\ref{intro.memory}) making up -\tcode{obj1} are copied into \tcode{obj2},\footnote{By using, for example, -the library functions~(\ref{headers}) \tcode{std::memcpy} or \tcode{std::memmove}.} - \tcode{obj2} shall subsequently hold the same value as -\tcode{obj1}. \enterexample +int f(bool b) { + unsigned char *c = new unsigned char; + unsigned char d = *c; // OK, \tcode{d} has an indeterminate value + int e = d; // undefined behavior + return b ? d : 0; // undefined behavior if \tcode{b} is \tcode{true} +} -\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} -\exitexample% -\indextext{object!byte~copying~and|)} - -\pnum -The \defn{object representation} -\indextext{representation!object}% -of an object of type \tcode{T} is the -sequence of \term{N} \tcode{unsigned} \tcode{char} objects taken up -by the object of type \tcode{T}, where \term{N} equals -\tcode{sizeof(T)}. The -\indextext{representation!value}% -\defn{value representation} -of an object is the set of bits that hold -the value of type \tcode{T}. 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.\footnote{The -intent is that the memory model of \Cpp is compatible -with that of ISO/IEC 9899 Programming Language C.} +int g(bool b) { + unsigned char c; + unsigned char d = c; // no erroneous behavior, but \tcode{d} has an erroneous value -\pnum -\indextext{type!incomplete}% -\indextext{type!incompletely-defined object}% -\indextext{object type!incompletely-defined}% -A class that has been declared but not defined, an enumeration type in certain -contexts~(\ref{dcl.enum}), or an array of unknown -size or of incomplete element type, is an \defn{incompletely-defined object -type}.\footnote{The size and layout of an instance of an incompletely-defined -object type is unknown.} -Incompletely-defined object types and the void types are \term{incomplete -types}~(\ref{basic.fundamental}). Objects shall not be defined to have an -incomplete type. + assert(c == d); // holds, both integral promotions have erroneous behavior -\pnum -A class type (such as ``\tcode{class X}'') might be incomplete at one -point in a translation unit and complete later on; the type -``\tcode{class X}'' is the same type at both points. The declared type -of an array object might be an array of incomplete class type and -therefore incomplete; if the class type is completed later on in the -translation unit, the array type becomes complete; the array type at -those two points is the same type. The declared type of an array object -might be an array of unknown bound and therefore be incomplete at one -point in a translation unit and complete later on; the array types at -those two points (``array of unknown bound of \tcode{T}'' and ``array of -\tcode{N} \tcode{T}'') are different types. The type of a pointer to array of -unknown size, or of a type defined by a \tcode{typedef} declaration to -be an array of unknown size, cannot be completed. \enterexample + int e = d; // erroneous behavior + return b ? d : 0; // erroneous behavior if \tcode{b} is \tcode{true} +} -\indextext{type!example~of incomplete}% -\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 -typedef int UNKA[]; // \tcode{UNKA} is an incomplete type -UNKA* arrp; // \tcode{arrp} is a pointer to an incomplete type -UNKA** arrpp; +void h() { + int d1, d2; -void foo() { - xp++; // ill-formed: \tcode{X} is incomplete - arrp++; // ill-formed: incomplete type - arrpp++; // OK: sizeof \tcode{UNKA*} is known -} + int e1 = d1; // erroneous behavior + int e2 = d1; // erroneous behavior -struct X { int i; }; // now \tcode{X} is a complete type -int arr[10]; // now the type of \tcode{arr} is complete + assert(e1 == e2); // holds + assert(e1 == d1); // holds, erroneous behavior + assert(e2 == d1); // holds, erroneous behavior -X x; -void bar() { - xp = &x; // OK; type is ``pointer to \tcode{X}'' - arrp = &arr; // ill-formed: different types - xp++; // OK: \tcode{X} is complete - arrp++; // ill-formed: \tcode{UNKA} can't be completed + std::memcpy(&d2, &d1, sizeof(int)); // no erroneous behavior, but \tcode{d2} has an erroneous value + assert(e1 == d2); // holds, erroneous behavior + assert(e2 == d2); // holds, erroneous behavior } \end{codeblock} -\exitexample +\end{example} -\pnum -\enternote The rules for declarations and expressions describe in which -contexts incomplete types are prohibited. \exitnote +\rSec2[basic.stc]{Storage duration} -\pnum -\indextext{object~type}% -An \defn{object type} is a (possibly cv-qualified) type that is not -a function type, not a reference type, and not a void type. +\rSec3[basic.stc.general]{General} \pnum -Arithmetic types~(\ref{basic.fundamental}), enumeration types, pointer -types, pointer to member types~(\ref{basic.compound}), -\tcode{std::nullptr_t}, -and -cv-qualified versions of these -types~(\ref{basic.type.qualifier}) are collectively called -\indextext{scalar~type}% -\term{scalar types}. Scalar types, -POD classes (Clause~\ref{class}), arrays of such types and -\grammarterm{cv-qualified} versions of these -types~(\ref{basic.type.qualifier}) are collectively called -\indextext{type!POD}% -\term{POD types}. -Cv-unqualified scalar types, trivially copyable class types (Clause~\ref{class}), arrays of -such types, and non-volatile const-qualified versions of these -types~(\ref{basic.type.qualifier}) are collectively called \defn{trivially -copyable types}. -Scalar types, trivial class types (Clause~\ref{class}), -arrays of such types and cv-qualified versions of these -types~(\ref{basic.type.qualifier}) are collectively called -\defn{trivial types}. Scalar types, standard-layout class -types (Clause~\ref{class}), arrays of such types and -cv-qualified versions of these types~(\ref{basic.type.qualifier}) -are collectively called \defn{standard-layout types}. - -\pnum -A type is a \defn{literal type} if it is: - -\begin{itemize} -\item \tcode{void}; or -\item a scalar type; or -\item a reference type; or -\item an array of literal type; or -\item a class type (Clause~\ref{class}) that -has all of the following properties: +\indextext{storage duration|(}% +The \defn{storage duration} is the property of an object that defines the minimum +potential lifetime of the storage containing the object. The storage +duration is determined by the construct used to create the object and is +one of the following: \begin{itemize} -\item it has a trivial destructor, -\item it is an aggregate type~(\ref{dcl.init.aggr}) or has -at least one \tcode{constexpr} constructor or constructor template that is not a copy or move constructor, and -\item all of its non-static data members and base classes are -of non-volatile literal types. -\end{itemize} +\item static storage duration +\item thread storage duration +\item automatic storage duration +\item dynamic storage duration \end{itemize} +\begin{note} +After the duration of a region of storage has ended, +the use of pointers to that region of storage is limited\iref{basic.compound}. +\end{note} \pnum -\indextext{layout-compatible~type}% -Two types \cvqual{cv1} \tcode{T1} and \cvqual{cv2} \tcode{T2} are -\defn{layout-compatible} types -if \tcode{T1} and \tcode{T2} are the same type, -layout-compatible enumerations~(\ref{dcl.enum}), or -layout-compatible standard-layout class types~(\ref{class.mem}). - -\rSec2[basic.fundamental]{Fundamental types} +\indextext{storage duration!static}% +\indextext{storage duration!thread}% +\indextext{storage duration!automatic}% +\indextext{storage duration!dynamic}% +Static, thread, and automatic storage durations are associated with objects +introduced by declarations\iref{basic.def} and +with temporary objects\iref{class.temporary}. +The dynamic storage duration +is associated with objects created by a +\grammarterm{new-expression}\iref{expr.new} or +with implicitly created objects\iref{intro.object}. \pnum -\indextext{type!fundamental}% -\indextext{type!integral}% -\indextext{type!floating point}% -\indextext{type!implementation-defined @\tcode{sizeof}}% -\indextext{type!Boolean}% -\indextext{type!\idxcode{char}}% -\indextext{type!character}% -\indextext{type!narrow character}% -Objects declared as characters (\tcode{char}) shall be large enough to -store any member of the implementation's basic character set. If a -character from this set is stored in a character object, the integral -value of that character object is equal to the value of the single -character literal form of that character. It is \impldef{signedness of \tcode{char}} -whether a \tcode{char} object can hold negative values. -\indextext{\idxcode{char}!implementation-defined sign~of}% -\indextext{type!\idxcode{signed char}}% -\indextext{type!\idxcode{unsigned char}}% -Characters can be explicitly declared \tcode{unsigned} or -\tcode{signed}. -\indextext{character!\idxcode{signed}}% -Plain \tcode{char}, \tcode{signed char}, and \tcode{unsigned char} are -three distinct types, collectively called \term{narrow character types}. -A \tcode{char}, a \tcode{signed char}, and an -\tcode{unsigned char} occupy the same amount of storage and have the -same alignment requirements~(\ref{basic.align}); that is, they have the -same object representation. For narrow character types, all bits of the object -representation participate in the value representation. For unsigned narrow -character types, each possible bit pattern of the value representation -represents a distinct number. These requirements do not hold for other types. In -any particular implementation, a plain \tcode{char} object can take on -either the same values as a \tcode{signed char} or an \tcode{unsigned -char}; which one is \impldef{representation of \tcode{char}}. -For each value \placeholder{i} of type \tcode{unsigned char} in the range -0 to 255 inclusive, there exists a value \placeholder{j} of type -\tcode{char} such that the result of an integral -conversion~(\ref{conv.integral}) from \placeholder{i} to \tcode{char} is -\placeholder{j}, and the result of an integral conversion from -\placeholder{j} to \tcode{unsigned char} is \placeholder{i}. - -\pnum -\indextext{type!standard~signed~integer}% -\indextext{standard~signed~integer~type}% -There are five \term{standard signed integer types} : -\indextext{type!\idxcode{signed char}}% -\indextext{type!\idxcode{short}}% -\indextext{type!\idxcode{int}}% -\indextext{type!\idxcode{long}}% -\indextext{type!\idxcode{long long}}% -``\tcode{signed char}'', ``\tcode{short int}'', ``\tcode{int}'', -``\tcode{long int}'', and ``\tcode{long} \tcode{long} \tcode{int}''. In -this list, each type provides at least as much storage as those -preceding it in the list. -\indextext{type!extended~signed~integer}% -\indextext{extended~signed~integer~type}% -\indextext{type!signed~integer}% -\indextext{signed~integer~type}% -There may also be \impldef{extended signed integer types} \term{extended signed -integer types}. The standard and -extended signed integer types are collectively called \term{signed integer types}. -\indextext{integral~type!implementation-defined @\tcode{sizeof}}% -Plain -\tcode{int}s have the natural size suggested by the architecture of the -execution environment\footnote{that is, large enough to contain any value in the range of -\tcode{INT_MIN} and \tcode{INT_MAX}, as defined in the header -\tcode{}.}; -the other signed integer types are provided to meet special needs. +The storage duration categories apply to references as well. \pnum -\indextext{type!\idxcode{unsigned}}% -For each of the standard signed integer types, -there exists a corresponding (but different) -\indextext{type!standard~unsigned~integer}% -\indextext{standard~unsigned~integer~type}% -\term{standard unsigned integer type}: -\indextext{type!\idxcode{unsigned char}}% -\indextext{type!\idxcode{unsigned short}}% -\indextext{type!\idxcode{unsigned int}}% -\indextext{type!\idxcode{unsigned long}}% -\indextext{type!\idxcode{unsigned long long}}% -``\tcode{unsigned char}'', ``\tcode{unsigned short int}'', -``\tcode{unsigned int}'', ``\tcode{unsigned long int}'', and -``\tcode{unsigned} \tcode{long} \tcode{long} \tcode{int}'', each of -which occupies the same amount of storage and has the same alignment -requirements~(\ref{basic.align}) as the corresponding signed integer -type\footnote{See~\ref{dcl.type.simple} regarding the correspondence between types and -the sequences of \grammarterm{type-specifier}{s} that designate them.}; -that is, each signed integer type has the same object representation as -its corresponding unsigned integer type. -\indextext{type!extended~unsigned~integer}% -\indextext{extended~unsigned~integer~type}% -\indextext{type!unsigned~integer}% -\indextext{unsigned~integer~type}% -Likewise, for each of the extended signed integer types there exists a -corresponding \term{extended unsigned integer type} with the same amount of storage and alignment -requirements. The standard and extended unsigned integer types are -collectively called \term{unsigned integer types}. The range of non-negative -values of a \term{signed integer} type is a subrange of the corresponding -\term{unsigned integer} type, and the value -representation of each corresponding signed/unsigned type shall be the -same. -\indextext{type!standard~integer}% -\indextext{standard~integer~type}% -\indextext{type!extended~integer}% -\indextext{extended~integer~type}% -The standard signed integer types and standard unsigned integer types -are collectively called the \term{standard integer types}, and the extended -signed integer types and extended -unsigned integer types are collectively called the \term{extended -integer types}. The signed and unsigned integer types shall satisfy -the constraints given in the C standard, section 5.2.4.2.1. +\indextext{storage duration!class member}% +The storage duration of subobjects and reference members +is that of their complete object\iref{intro.object}. +\indextext{storage duration|)}% -\pnum -\indextext{arithmetic!\idxcode{unsigned}}% -Unsigned integers shall obey the laws of arithmetic modulo $2^n$ where $n$ is -the number of bits in the value representation of that particular size of -integer.\footnote{This implies that -unsigned arithmetic does not overflow because a result -that cannot be represented by the resulting unsigned integer type is -reduced modulo the number that is one greater than the largest value -that can be represented by the resulting unsigned integer type.} +\rSec3[basic.stc.static]{Static storage duration} \pnum -\indextext{type!\idxcode{char16_t}}% -\indextext{type!\idxcode{char32_t}}% -\indextext{\idxcode{wchar_t}!implementation-defined}% -\indextext{type!\idxcode{wchar_t}}% -\indextext{type!underlying wchar_t@underlying \tcode{wchar_t}}% -Type \tcode{wchar_t} is a distinct type whose values can represent -distinct codes for all members of the largest extended character set -specified among the supported locales~(\ref{locale}). Type -\tcode{wchar_t} shall have the same size, signedness, and alignment -requirements~(\ref{basic.align}) as one of the other integral types, -called its \defn{underlying type}. Types \tcode{char16_t} and -\tcode{char32_t} denote distinct types with the same size, signedness, -and alignment as \tcode{uint_least16_t} and \tcode{uint_least32_t}, -respectively, in \tcode{}, called the underlying types. - -\pnum -\indextext{Boolean~type}% -Values of type \tcode{bool} are either \tcode{true} or -\tcode{false}.\footnote{Using a \tcode{bool} value in ways described by this International -Standard as ``undefined,'' such as by examining the value of an -uninitialized automatic object, might cause it to behave as if it is -neither \tcode{true} nor \tcode{false}.} -\enternote There are no \tcode{signed}, \tcode{unsigned}, \tcode{short}, -or \tcode{long bool} types or values. \exitnote Values of type -\tcode{bool} participate in integral promotions~(\ref{conv.prom}). - -\pnum -Types \tcode{bool}, \tcode{char}, \tcode{char16_t}, \tcode{char32_t}, -\tcode{wchar_t}, and the signed and unsigned integer types are -collectively called -\indextext{integral~type}% -\term{integral} types.\footnote{Therefore, enumerations~(\ref{dcl.enum}) are not integral; however, -enumerations can be promoted to integral types as specified -in~\ref{conv.prom}.} -A synonym for integral type is -\indextext{integer~type}% -\term{integer type}. The representations of integral types shall -define values by use of a pure binary numeration system.\footnote{A positional -representation for integers that uses the binary digits 0 -and 1, in which the values represented by successive bits are additive, -begin with 1, and are multiplied by successive integral power of 2, -except perhaps for the bit with the highest position. (Adapted from the -\doccite{American National Dictionary for Information Processing Systems}.)} -\enterexample this International Standard permits 2's complement, 1's -complement and signed magnitude representations for integral types. -\exitexample - -\pnum -\indextext{floating~point~type}% -There are three \term{floating point} types: -\indextext{type!\idxcode{float}}% -\tcode{float}, -\indextext{type!\idxcode{double}}% -\tcode{double}, -and -\indextext{type!\idxcode{long double}}% -\tcode{long double}. The type \tcode{double} provides at least as much -precision as \tcode{float}, and the type \tcode{long double} provides at -least as much precision as \tcode{double}. The set of values of the type -\tcode{float} is a subset of the set of values of the type -\tcode{double}; the set of values of the type \tcode{double} is a subset -of the set of values of the type \tcode{long} \tcode{double}. The value -representation of floating-point types is \impldef{value representation of -floating-point types}. -\indextext{floating~point~type!implementation-defined}% -\indextext{type!arithmetic}% -\term{Integral} and \term{floating} types are collectively -called \term{arithmetic} types. -\indextext{\idxcode{numeric_limits}!specializations for arithmetic types}% -Specializations of the standard template -\tcode{std::numeric_limits}~(\ref{support.limits}) shall specify the -maximum and minimum values of each arithmetic type for an -implementation. +All variables which +\begin{itemize} +\item +do not have thread storage duration and +\item +belong to a namespace scope\iref{basic.scope.namespace} or +are first declared with +the \keyword{static} or \keyword{extern} keywords\iref{dcl.stc} +\end{itemize} +have \defnadj{static}{storage duration}. +The storage for these entities lasts for the duration of the +program\iref{basic.start.static,basic.start.term}. \pnum -\indextext{type!\idxcode{void}}% -The \tcode{void} type has an empty set of values. The \tcode{void} type -is an incomplete type that cannot be completed. It is used as the return -type for functions that do not return a value. Any expression can be -explicitly converted to type \term{cv} -\tcode{void}~(\ref{expr.cast}). An expression of type \tcode{void} shall -be used only as an expression statement~(\ref{stmt.expr}), as an operand -of a comma expression~(\ref{expr.comma}), as a second or third operand -of \tcode{?:}~(\ref{expr.cond}), as the operand of -\tcode{typeid}, \tcode{noexcept}, or \tcode{decltype}, as -the expression in a return statement~(\ref{stmt.return}) for a function -with the return type \tcode{void}, or as the operand of an explicit conversion -to type \cv\ \tcode{void}. - -\pnum -A value of type \tcode{std::nullptr_t} is a null pointer -constant~(\ref{conv.ptr}). Such values participate in the pointer and the -pointer to member conversions~(\ref{conv.ptr}, \ref{conv.mem}). -\tcode{sizeof(std::nullptr_t)} shall be equal to \tcode{sizeof(void*)}. - -\pnum -\enternote -Even if the implementation defines two or more basic types to have the -same value representation, they are nevertheless different types. -\exitnote - -\rSec2[basic.compound]{Compound types} +If a variable with static storage duration has initialization or a +destructor with side effects, it shall not be eliminated even if it +appears to be unused, except that a class object or its copy/move may be +eliminated as specified in~\ref{class.copy.elision}. \pnum -\indextext{type!compound}% -Compound types can be constructed in the following ways: +\begin{note} +\indextext{object!local static@local \tcode{static}}% +The keyword \keyword{static} can be used to declare +a block variable\iref{basic.scope.block} with static storage duration; +\ref{stmt.dcl} and \ref{basic.start.term} describe the +initialization and destruction of such variables. +\indextext{member!class static@class \tcode{static}}% +The keyword \keyword{static} applied to +a class data member in a class definition +gives the data member static storage duration\iref{class.static.data}. +\end{note} -\begin{itemize} -\item \indextext{type!array}% -\term{arrays} of objects of a given type,~\ref{dcl.array}; - -\item \indextext{type!function}% -\term{functions}, which have parameters of given types and return -\tcode{void} or references or objects of a given type,~\ref{dcl.fct}; +\rSec3[basic.stc.thread]{Thread storage duration} -\item \indextext{type!pointer}% -\term{pointers} to \tcode{void} or objects or functions (including -static members of classes) of a given type,~\ref{dcl.ptr}; +\pnum +All variables declared with the \keyword{thread_local} keyword have +\defnadj{thread}{storage duration}. +The storage for these entities lasts for the duration of +the thread in which they are created. There is a distinct object or reference +per thread, and use of the declared name refers to the entity associated with +the current thread. -\item % -\indextext{reference}% -\indextext{reference!lvalue}% -\indextext{reference!rvalue}% -\indextext{lvalue~reference}% -\indextext{rvalue~reference}% -\term{references} to objects or functions of a given -type,~\ref{dcl.ref}. There are two types of references: -\begin{itemize} -\item \term{lvalue reference} -\item \term{rvalue reference} -\end{itemize} +\pnum +\begin{note} +A variable with thread storage duration is initialized as specified +in~\ref{basic.start.static}, \ref{basic.start.dynamic}, and \ref{stmt.dcl} +and, if constructed, is destroyed on thread exit\iref{basic.start.term}. +\end{note} -\item \indextext{class}% -\term{classes} containing a sequence of objects of various types -(Clause~\ref{class}), a set of types, enumerations and functions for -manipulating these objects~(\ref{class.mfct}), and a set of restrictions -on the access to these entities (Clause~\ref{class.access}); - -\item \indextext{\idxcode{union}}% -\term{unions}, which are classes capable of containing objects of -different types at different times,~\ref{class.union}; - -\item \indextext{\idxcode{enum}}% -\term{enumerations}, which comprise a set of named constant values. -Each distinct enumeration constitutes a different -\indextext{type!enumerated}% -\term{enumerated type},~\ref{dcl.enum}; - -\item \indextext{member~pointer~to|see{pointer to member}}% -\indextext{pointer~to~member}% -\term{pointers to non-static} -\footnote{Static class members are objects or functions, and pointers to them are -ordinary pointers to objects or functions.} -\term{class members}, which identify members of a given -type within objects of a given class,~\ref{dcl.mptr}. -\end{itemize} +\rSec3[basic.stc.auto]{Automatic storage duration} \pnum -These methods of constructing types can be applied recursively; -restrictions are mentioned in~\ref{dcl.ptr}, \ref{dcl.array}, -\ref{dcl.fct}, and~\ref{dcl.ref}. Constructing a type such that the number of -bytes in its object representation exceeds the maximum value representable in -the type \tcode{std::size_t}~(\ref{support.types}) is ill-formed. +\indextext{storage duration!local object}% +Variables that belong to a block scope and are +not explicitly declared \keyword{static}, \keyword{thread_local}, or \keyword{extern} have +\defnadj{automatic}{storage duration}. The storage +for such variables lasts until the block in which they are created exits. +\begin{note} +These variables are initialized and destroyed as described in~\ref{stmt.dcl}. +\end{note} +Variables that belong to a parameter scope also have automatic storage duration. +The storage for a function parameter lasts until +immediately after its destruction\iref{expr.call}. \pnum -\indextext{terminology!pointer}% -The type of a pointer to \tcode{void} or a pointer to an object type is -called an \defn{object pointer type}. \enternote A pointer to \tcode{void} -does not have a pointer-to-object type, however, because \tcode{void} is not -an object type. \exitnote The type of a pointer that can designate a function -is called a \defn{function pointer type}. -A pointer to objects of type \tcode{T} is referred to as a ``pointer to -\tcode{T}.'' \enterexample a pointer to an object of type \tcode{int} is -referred to as ``pointer to \tcode{int} '' and a pointer to an object of -class \tcode{X} is called a ``pointer to \tcode{X}.'' \exitexample -Except for pointers to static members, text referring to ``pointers'' -does not apply to pointers to members. Pointers to incomplete types are -allowed although there are restrictions on what can be done with -them~(\ref{basic.align}). -\indextext{address}% -A valid value of an object -pointer type represents either the address of a byte in -memory~(\ref{intro.memory}) or a null pointer~(\ref{conv.ptr}). If an -object of type \tcode{T} is located at an address \tcode{A}, a pointer -of type \term{cv} \tcode{T*} whose value is the address \tcode{A} is -said to \term{point to} that object, regardless of how the value was -obtained. \enternote For instance, the address one past the end of an -array~(\ref{expr.add}) would be considered to point to an unrelated -object of the array's element type that might be located at that -address. There are further restrictions on pointers to objects with dynamic storage -duration; see~\ref{basic.stc.dynamic.safety}. \exitnote The value representation of -pointer types is \impldef{value representation of pointer types}. Pointers to -layout-compatible types shall -have the same value representation and alignment -requirements~(\ref{basic.align}). -\enternote Pointers to over-aligned types~(\ref{basic.align}) have no special -representation, but their range of valid values is restricted by the extended -alignment requirement. This International Standard specifies only two ways -of obtaining such a pointer: taking the address of a valid object with -an over-aligned type, and using one of the runtime pointer alignment functions. -An implementation may provide other means of obtaining a valid pointer value -for an over-aligned type.\exitnote +If a variable with automatic storage duration has initialization or a destructor with side +effects, an implementation shall not destroy it before the end of its block +nor eliminate it as an optimization, even if it appears to be +unused, except that a class object or its copy/move may be eliminated as +specified in~\ref{class.copy.elision}. -\pnum -\indextext{pointer|seealso{\tcode{void*}}}% -\indextext{\idxcode{void*}!type}% -A pointer to \cv-qualified~(\ref{basic.type.qualifier}) or \cv-unqualified -\tcode{void} -can be used to point to objects of -unknown type. Such a pointer shall be able to hold any object pointer. -An object of type \cv\ -\tcode{void*} shall have the same representation and alignment -requirements as \cv\ \tcode{char*}. +\rSec3[basic.stc.dynamic]{Dynamic storage duration}% -\rSec2[basic.type.qualifier]{CV-qualifiers} +\rSec4[basic.stc.dynamic.general]{General}% +\indextext{storage duration!dynamic|(} \pnum -\indextext{cv-qualifier}% -\indextext{\idxcode{const}}% -\indextext{\idxcode{volatile}}% -A type mentioned in~\ref{basic.fundamental} and~\ref{basic.compound} is -a \term{cv-unqualified type}. Each type which is a -cv-unqualified complete or incomplete object type or is -\tcode{void}~(\ref{basic.types}) has three corresponding cv-qualified -versions of its type: a \grammarterm{const-qualified} version, a -\term{volatile-qualified} version, and a -\term{const-volatile-qualified} version. The term -\term{object type}~(\ref{intro.object}) includes the cv-qualifiers -specified in the \grammarterm{decl-specifier-seq}~(\ref{dcl.spec}), -\grammarterm{declarator} (Clause~\ref{dcl.decl}), -\grammarterm{type-id}~(\ref{dcl.name}), or -\grammarterm{new-type-id}~(\ref{expr.new}) when the object is created. +Objects can be created dynamically during program +execution\iref{intro.execution}, using +\indextext{\idxcode{new}}% +\grammarterm{new-expression}{s}\iref{expr.new}, and destroyed using +\indextext{\idxcode{delete}}% +\grammarterm{delete-expression}{s}\iref{expr.delete}. A \Cpp{} implementation +provides access to, and management of, dynamic storage via +the global \defnx{allocation functions}{allocation function} +\tcode{\keyword{operator} \keyword{new}} and +\tcode{\keyword{operator} \keyword{new}[]} and +the global \defnx{deallocation functions}{deallocation function} +\tcode{\keyword{operator} \keyword{delete}} and +\tcode{\keyword{operator} \keyword{delete}[]}. +\begin{note} +The non-allocating forms described in \ref{new.delete.placement} +do not perform allocation or deallocation. +\end{note} -\begin{itemize} -\item A \term{const object} is an object of type \tcode{const T} or a - non-mutable subobject of such an object. +\pnum +The library provides default definitions for the global allocation and +deallocation functions. Some global allocation and deallocation +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. -\item A \term{volatile object} is an object of type - \tcode{volatile T}, a subobject of such an object, or a mutable - subobject of a const volatile object. +\begin{codeblock} +void* operator new(std::size_t); +void* operator new(std::size_t, std::align_val_t); -\item A \term{const volatile object} is an object of type - \tcode{const volatile T}, a non-mutable subobject of such an object, - a const subobject of a volatile object, or a non-mutable volatile - subobject of a const object. +void operator delete(void*) noexcept; +void operator delete(void*, std::size_t) noexcept; +void operator delete(void*, std::align_val_t) noexcept; +void operator delete(void*, std::size_t, std::align_val_t) noexcept; -\end{itemize} +void* operator new[](std::size_t); +void* operator new[](std::size_t, std::align_val_t); -The cv-qualified or -cv-unqualified versions of a type -are distinct types; however, they shall have the same representation and -alignment requirements~(\ref{basic.align}).\footnote{The same representation -and alignment requirements are meant to imply -interchangeability as arguments to functions, return values from -functions, and non-static data members of unions.} +void operator delete[](void*) noexcept; +void operator delete[](void*, std::size_t) noexcept; +void operator delete[](void*, std::align_val_t) noexcept; +void operator delete[](void*, std::size_t, std::align_val_t) noexcept; +\end{codeblock} -\pnum -\indextext{array!\idxcode{const}}% -A compound type~(\ref{basic.compound}) is not cv-qualified by the -cv-qualifiers (if any) of the types from which it is compounded. Any -cv-qualifiers applied to an array type affect the array element type, -not the array type~(\ref{dcl.array}). +These implicit declarations introduce only the function names +\tcode{\keyword{operator} \keyword{new}}, +\tcode{\keyword{operator} \keyword{new}[]}, +\tcode{\keyword{operator} \keyword{delete}}, and +\tcode{\keyword{operator} \keyword{delete}[]}. +\begin{note} +The implicit declarations do not introduce +the names \tcode{std}, +\tcode{std::size_t}, +\tcode{std::align_val_t}, +or any other names that the library uses to +declare these names. Thus, a \grammarterm{new-expression}, +\grammarterm{delete-expression}, or function call that refers to one of +these functions without importing or including the header \libheaderref{new} +or importing a \Cpp{} library module\iref{std.modules} +is well-formed. However, referring to \tcode{std} +or \tcode{std::size_t} +or \tcode{std::align_val_t} +is ill-formed unless +a standard library declaration\iref{cstddef.syn,new.syn,std.modules} +of that name precedes\iref{basic.lookup.general} the use of that name. +\end{note} +Allocation and/or +deallocation functions may also be declared and defined for any +class\iref{class.free}. \pnum -See~\ref{dcl.fct} and~\ref{class.this} regarding function -types that have \grammarterm{cv-qualifier}{s}. +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 -There is a partial ordering on cv-qualifiers, so that a type can be -said to be \grammarterm{more cv-qualified} than another. -Table~\ref{tab:relations.on.const.and.volatile} shows the relations that -constitute this ordering. +\indextext{storage duration!dynamic|)} -\begin{floattable}{Relations on \tcode{const} and \tcode{volatile}}{tab:relations.on.const.and.volatile} -{ccc} -\topline -\cvqual{no cv-qualifier} &<& \tcode{const} \\ -\cvqual{no cv-qualifier} &<& \tcode{volatile} \\ -\cvqual{no cv-qualifier} &<& \tcode{const volatile} \\ -\tcode{const} &<& \tcode{const volatile} \\ -\tcode{volatile} &<& \tcode{const volatile} \\ -\end{floattable} +\rSec4[basic.stc.dynamic.allocation]{Allocation functions} \pnum -In this International Standard, the notation \term{cv} (or -\term{cv1}, \term{cv2}, etc.), used in the description of types, -represents an arbitrary set of cv-qualifiers, i.e., one of -\{\tcode{const}\}, \{\tcode{volatile}\}, \{\tcode{const}, -\tcode{volatile}\}, or the empty set. -\indextext{cv-qualifier!top-level} -For a type \cv\ \tcode{T}, the \term{top-level cv-qualifiers} -of that type are those denoted by \cv. -\enterexample -The type corresponding to the \grammarterm{type-id} -\tcode{const int\&} -has no top-level cv-qualifiers. -The type corresponding to the \grammarterm{type-id} -\tcode{volatile int * const} -has the top-level cv-qualifier \tcode{const}. -For a class type \tcode{C}, -the type corresponding to the \grammarterm{type-id} -\tcode{void (C::* volatile)(int) const} -has the top-level cv-qualifier \tcode{volatile}. -\exitexample +\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 ``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 +is interpreted as the requested size of the allocation. An allocation +function can be a function template. Such a template shall declare its +return type and first parameter as specified above (that is, template +parameter types shall not be used in the return type and first parameter +type). Allocation function templates shall have two or more parameters. \pnum -Cv-qualifiers applied to an array -type attach to the underlying element type, so the notation -``\term{cv} \tcode{T},'' where \tcode{T} is an array type, refers to -an array whose elements are so-qualified. An array type whose elements -are cv-qualified is also considered to have the same cv-qualifications -as its elements.% -\indextext{type|)} -\enterexample -\begin{codeblock} -typedef char CA[5]; -typedef const char CC; -CC arr1[5] = { 0 }; -const CA arr2 = { 0 }; -\end{codeblock} -The type of both \tcode{arr1} and \tcode{arr2} is ``array of 5 -\tcode{const char},'' and the array type is considered to be -\tcode{const}-qualified. -\exitexample +An allocation function attempts to allocate the requested amount of +storage. If it is successful, it returns the address of the start +of a block of storage whose length in bytes is at least as large +as the requested size. +The order, +contiguity, and initial value of storage allocated by successive calls +to an allocation function are unspecified. +Even if the size of the space +requested is zero, the request can fail. If the request succeeds, the +value returned by a replaceable allocation function +is a non-null pointer value\iref{basic.compound} +\tcode{p0} different from any previously returned value \tcode{p1}, +unless that value \tcode{p1} was subsequently passed to a +replaceable deallocation function. +Furthermore, for the library allocation functions +in~\ref{new.delete.single} and~\ref{new.delete.array}, +\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. +\begin{footnote} +The intent is +to have \tcode{\keyword{operator} \keyword{new}()} implementable by +calling \tcode{std::malloc()} or \tcode{std::calloc()}, so the rules are +substantially the same. \Cpp{} differs from C in requiring a zero request +to return a non-null pointer. +\end{footnote} -\rSec1[basic.lval]{Lvalues and rvalues} \pnum -Expressions are categorized according to the taxonomy in Figure~\ref{fig:categories}. - -\begin{importgraphic} -{Expression category taxonomy} -{fig:categories} -{valuecategories.pdf} -\end{importgraphic} - +For an allocation function other than +a reserved placement allocation function\iref{new.delete.placement}, +the pointer returned on a successful call +shall represent the address of storage that is aligned as follows: \begin{itemize} -\item An \defn{lvalue} (so called, historically, because lvalues could appear -on the left-hand side of an assignment expression) designates a function or an object. -\enterexample If \tcode{E} is an expression of pointer type, then \tcode{*E} is -an lvalue expression referring to the object or function to which \tcode{E} points. -As another example, the result of calling a function whose return type is an -lvalue reference is an lvalue. \exitexample - -\item An \defn{xvalue} (an ``eXpiring'' value) also refers to an object, usually near -the end of its lifetime (so that its resources may be moved, for example). -Certain kinds of expressions involving rvalue references~(\ref{dcl.ref}) yield xvalues. -\enterexample The result of calling a function whose return type is an rvalue reference -to an object type is an xvalue~(\ref{expr.call}). \exitexample - -\item A \defn{glvalue} (``generalized'' lvalue) is an lvalue or an xvalue. - -\item An \defn{rvalue} (so called, historically, because rvalues could appear -on the right-hand side of an assignment expression) is an xvalue, a temporary -object~(\ref{class.temporary}) or subobject thereof, or a value that is not -associated with an object. - -\item A \defn{prvalue} (``pure'' rvalue) is an rvalue that is not an xvalue. -\enterexample The result of calling a function whose return type is not a reference -is a prvalue. The value of a literal such as \tcode{12}, \tcode{7.3e5}, or \tcode{true} -is also a prvalue. \exitexample +\item + If the allocation function takes an argument + of type \tcode{std::align_val_t}, + the storage will have the alignment specified + by the value of this argument. +\item + Otherwise, if the allocation function is named \tcode{\keyword{operator} \keyword{new}[]}, + the storage is aligned for any object that + does not have new-extended alignment\iref{basic.align} and + is no larger than the requested size. +\item + Otherwise, the storage is aligned for any object that + does not have new-extended alignment and is of the requested size. \end{itemize} -Every expression belongs to exactly one of the fundamental classifications in this -taxonomy: lvalue, xvalue, or prvalue. This property of an expression is called -its \defn{value category}. \enternote The discussion of each built-in operator in -Clause~\ref{expr} indicates the category of the value it yields and the value categories -of the operands it expects. For example, the built-in assignment operators expect that -the left operand is an lvalue and that the right operand is a prvalue and yield an -lvalue as the result. User-defined operators are functions, and the categories of -values they expect and yield are determined by their parameter and return types. \exitnote - -\pnum -Whenever a glvalue appears in a context where a prvalue is expected, the glvalue is converted -to a prvalue; see~\ref{conv.lval}, \ref{conv.array}, -and~\ref{conv.func}. -\enternote -An attempt to bind an rvalue reference to an lvalue is not such a context; see~\ref{dcl.init.ref}. -\exitnote - \pnum -The discussion of reference initialization in~\ref{dcl.init.ref} and of -temporaries in~\ref{class.temporary} indicates the behavior of lvalues -and rvalues in other significant contexts. - -\pnum -Unless otherwise indicated~(\ref{expr.call}), prvalues -shall always have complete types or the -\tcode{void} type; in addition to these types, glvalues can also have -incomplete types. -\enternote -class and array prvalues can have cv-qualified types; other prvalues -always have cv-unqualified types. See Clause~\ref{expr}. -\exitnote +An allocation function that fails to allocate storage can invoke the +currently installed new-handler function\iref{new.handler}, if any. +\begin{note} +\indextext{\idxcode{new_handler}}% +A program-supplied allocation function can obtain the +currently installed \tcode{new_handler} using the +\tcode{std::get_new_handler} function\iref{get.new.handler}. +\end{note} +An allocation function that has a non-throwing +exception specification\iref{except.spec} +indicates failure by returning +a null pointer value. +Any other allocation function +never returns a null pointer value and +indicates failure only by throwing an exception\iref{except.throw} of a type +that would match a handler\iref{except.handle} of type +\tcode{std::bad_alloc}\iref{bad.alloc}. \pnum -An lvalue for an object is necessary in order to modify the object -except that an rvalue of class type can also be used to modify its -referent under certain circumstances. \enterexample a member function -called for an object~(\ref{class.mfct}) can modify the object. -\exitexample +A global allocation function is only called as the result of a new +expression\iref{expr.new}, or called directly using the function call +syntax\iref{expr.call}, or called indirectly to allocate storage for +a coroutine state\iref{dcl.fct.def.coroutine}, +or called indirectly through calls to the +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}, +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} \pnum -Functions cannot be modified, but pointers to functions can be -modifiable. +\indextext{function!deallocation}% +A deallocation function that is not a class member function +shall belong to the global scope and not have a name with internal linkage. + +\pnum +A deallocation function +is a \defnadj{destroying}{operator delete} +if it has at least two parameters +and its second parameter +is of type \tcode{std::destroying_delete_t}. +A destroying operator delete +shall be a class member function named \tcode{\keyword{operator} \keyword{delete}}. +\begin{note} +Array deletion cannot use a destroying operator delete. +\end{note} + +\pnum +\indextext{\idxcode{delete}!overloading and}% +Each deallocation function shall return \keyword{void}. +If the function is a destroying operator delete +declared in class type \tcode{C}, +the type of its first parameter shall be ``pointer to \tcode{C}''; +otherwise, the type of its first +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 +whose parameters after the first are +\begin{itemize} +\item +optionally, a parameter of type \tcode{std::destroying_delete_t}, then +\item +optionally, a parameter of type \tcode{std::size_t}, +\begin{footnote} +The global \tcode{\keyword{operator} \keyword{delete}(\keyword{void}*, std::size_t)} +precludes use of an +allocation function \tcode{\keyword{void} \keyword{operator} \keyword{new}(std::size_t, std::size_t)} as a placement +allocation function\iref{diff.cpp11.basic}. +\end{footnote} +then +\item +optionally, a parameter of type \tcode{std::align_val_t}. +\end{itemize} +A destroying operator delete shall be a usual deallocation function. +A deallocation function may be an instance of a function +template. Neither the first parameter nor the return type shall depend +on a template parameter. +A deallocation +function template shall have two or more function parameters. A template +instance is never a usual deallocation function, regardless of its +signature. \pnum -A pointer to an incomplete type can be modifiable. At some point in the -program when the pointed to type is complete, the object at which the -pointer points can also be modified. +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. \pnum -The referent of a \tcode{const}-qualified expression shall not be -modified (through that expression), except that if it is of class type -and has a \tcode{mutable} component, that component can be -modified~(\ref{dcl.type.cv}). +If the argument given to a deallocation function in the standard library +is a pointer that is not the null pointer value\iref{basic.compound}, the +deallocation function shall deallocate the storage referenced by the +pointer, ending the duration of the region of storage. -\pnum -If an expression can be used to modify the object to which it refers, -the expression is called \term{modifiable}. A program that attempts -to modify an object through a nonmodifiable lvalue or rvalue expression -is ill-formed. +\rSec2[class.temporary]{Temporary objects} \pnum -If a program attempts to access the stored value of an object through a glvalue -of other than one of the following types the behavior is -undefined:\footnote{The intent of this list is to specify those circumstances in which an -object may or may not be aliased.} - +\indextext{temporary}% +\indextext{optimization of temporary|see{temporary, elimination of}}% +\indextext{temporary!elimination of}% +\indextext{temporary!implementation-defined generation of}% +A \defnadj{temporary}{object} is an object created \begin{itemize} -\item the dynamic type of the object, - -\item a cv-qualified version of the dynamic type of the object, - -\item a type similar (as defined in~\ref{conv.qual}) to the dynamic type -of the object, - -\item a type that is the signed or unsigned type corresponding to the -dynamic type of the object, +\item +when a prvalue is converted to an xvalue\iref{conv.rval} and +\item +when needed by the implementation to pass or return an object of suitable type (see below). +\end{itemize} +Even when the creation of the temporary object is +unevaluated\iref{expr.context}, +all the semantic restrictions shall be respected as if the temporary object +had been created and later destroyed. +\begin{note} +This includes accessibility\iref{class.access} and whether it is deleted, +for the constructor selected and for the destructor. However, in the special +case of the operand of a +\grammarterm{decltype-specifier}\iref{dcl.type.decltype}, no temporary is introduced, +so the foregoing does not apply to such a prvalue. +\end{note} + +\pnum +The materialization of a temporary object is generally +delayed as long as possible +in order to avoid creating unnecessary temporary objects. +\begin{note} +Temporary objects are materialized: +\begin{itemize} +\item +when binding a reference to a prvalue\iref{dcl.init.ref,expr.type.conv, +expr.dynamic.cast,expr.static.cast,expr.const.cast,expr.cast}, +\item +when performing certain member accesses on a class prvalue\iref{expr.ref,expr.mptr.oper}, +\item +when invoking an implicit object member function on a class prvalue\iref{expr.call}, +\item +when performing an array-to-pointer conversion or subscripting on an array prvalue\iref{conv.array,expr.sub}, +\item +when initializing an object of type \tcode{std::initializer_list} from a \grammarterm{braced-init-list}\iref{dcl.init.list}, +\item +for certain unevaluated operands\iref{expr.typeid,expr.sizeof}, and +\item +when a prvalue that has type other than \cv{}~\keyword{void} appears as a discarded-value expression\iref{expr.context}. +\end{itemize} +\end{note} +\begin{example} +Consider the following code: +\begin{codeblock} +class X { +public: + X(int); + X(const X&); + X& operator=(const X&); + ~X(); +}; -\item a type that is the signed or unsigned type corresponding to a -cv-qualified version of the dynamic type of the object, +class Y { +public: + Y(int); + Y(Y&&); + ~Y(); +}; -\item an aggregate or union type that includes one of the aforementioned types among its -elements or non-static data members (including, recursively, an element or non-static data member of a -subaggregate or contained union), +X f(X); +Y g(Y); -\item a type that is a (possibly cv-qualified) base class type of the dynamic type of -the object, +void h() { + X a(1); + X b = f(X(2)); + Y c = g(Y(3)); + a = f(a); +} +\end{codeblock} -\item a \tcode{char} or \tcode{unsigned} \tcode{char} type. +\indextext{class object copy|see{constructor, copy}}% +\indextext{constructor!copy}% +\tcode{X(2)} is constructed in the space used to hold \tcode{f()}'s argument and +\tcode{Y(3)} is constructed in the space used to hold \tcode{g()}'s argument. +Likewise, +\tcode{f()}'s result is constructed directly in \tcode{b} and +\tcode{g()}'s result is constructed directly in \tcode{c}. +On the other hand, the expression +\tcode{a = f(a)} +requires a temporary for +the result of \tcode{f(a)}, +which is materialized so that the reference parameter +of \tcode{X::operator=(const X\&)} can bind to it. +\end{example} + +\pnum +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 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 +to be passed to or returned from functions in registers. +\end{note} + +\pnum +\indextext{temporary!constructor for}% +\indextext{temporary!destructor for}% +\indextext{temporary!destruction of}% +Temporary objects are destroyed as the last step +in evaluating +the full-expression\iref{intro.execution} +that (lexically) contains the point where +they were created. +This is true even if that evaluation ends in throwing an exception. +The +\indextext{value computation}% +value computations and +\indextext{side effects}% +side effects of destroying a temporary object +are associated only with the full-expression, not with any specific +subexpression. + +\pnum +\indextext{initializer!temporary and declarator}% +\indextext{temporary!order of destruction of}% +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 +an array while the entire array is copied\iref{expr.prim.lambda.capture,class.copy.ctor}. +In either case, if the constructor has one or more default arguments, +the destruction of every temporary created in a default argument is +sequenced before the construction of the next array element, if any. + +\pnum +The third context is when a reference binds to a temporary object. +\begin{footnote} +The same rules apply to initialization of an + \tcode{initializer_list} object\iref{dcl.init.list} with its + underlying temporary array. +\end{footnote} +The temporary object to which the reference is bound or the temporary object +that is the complete object of a subobject to which the reference is bound +persists for the lifetime of the reference if the glvalue +to which the reference is bound +was obtained through one of the following: +\begin{itemize} +\item + a temporary materialization conversion\iref{conv.rval}, +\item + \tcode{(} \grammarterm{expression} \tcode{)}, + where \grammarterm{expression} is one of these expressions, +\item + subscripting\iref{expr.sub} of an array operand, + where that operand is one of these expressions, +\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\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 + the right operand is a pointer to data member of non-reference type, +\item + a + \begin{itemize} + \item \keyword{const_cast}\iref{expr.const.cast}, + \item \keyword{static_cast}\iref{expr.static.cast}, + \item \keyword{dynamic_cast}\iref{expr.dynamic.cast}, or + \item \keyword{reinterpret_cast}\iref{expr.reinterpret.cast} + \end{itemize} + converting, without a user-defined conversion, + a glvalue operand that is one of these expressions + 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 +\item + a comma expression\iref{expr.comma} that is a glvalue + where the right operand is one of these expressions. \end{itemize} +\begin{example} +\begin{codeblock} +template using id = T; -\rSec1[basic.align]{Alignment} +int i = 1; +int&& a = id{1, 2, 3}[i]; // temporary array has same lifetime as \tcode{a} +const int& b = static_cast(0); // temporary \tcode{int} has same lifetime as \tcode{b} +int&& c = cond ? id{1, 2, 3}[i] : static_cast(0); + // exactly one of the two temporaries is lifetime-extended +\end{codeblock} +\end{example} +\begin{note} +An explicit type conversion\iref{expr.type.conv,expr.cast} +is interpreted as +a sequence of elementary casts, +covered above. +\begin{example} +\begin{codeblock} +const int& x = (const int&)1; // temporary for value \tcode{1} has same lifetime as \tcode{x} +\end{codeblock} +\end{example} +\end{note} +\begin{note} +If a temporary object has a reference member initialized by another temporary object, +lifetime extension applies recursively to such a member's initializer. +\begin{example} +\begin{codeblock} +struct S { + const int& m; +}; +const S& s = S{1}; // both \tcode{S} and \tcode{int} temporaries have lifetime of \tcode{s} +\end{codeblock} +\end{example} +\end{note} -\pnum -\indextext{alignment~requirement!implementation-defined}% -Object types have \term{alignment requirements} (\ref{basic.fundamental},~\ref{basic.compound}) -which place restrictions on the addresses at which an object of that type -may be allocated. An \term{alignment} is an \impldef{alignment} -integer value representing the number of bytes between successive addresses -at which a given object can be allocated. An object type imposes an alignment -requirement on every object of that type; stricter alignment can be requested -using the alignment specifier~(\ref{dcl.align}). +The exceptions to this lifetime rule are: +\begin{itemize} +\item A temporary object bound to a reference parameter in a function call\iref{expr.call} +persists until the completion of the full-expression containing the call. + +\item A temporary object bound to a reference element of +an aggregate of class type initialized from +a parenthesized \grammarterm{expression-list}\iref{dcl.init} +persists until the completion of the full-expression +containing the \grammarterm{expression-list}. + +\item A temporary bound to a reference in a \grammarterm{new-initializer}\iref{expr.new} persists until the completion of the full-expression containing the \grammarterm{new-initializer}. +\begin{note} +This might introduce a dangling reference. +\end{note} +\begin{example} +\begin{codeblock} +struct S { int mi; const std::pair& mp; }; +S a { 1, {2,3} }; +S* p = new S{ 1, {2,3} }; // creates dangling reference +\end{codeblock} +\end{example} +\end{itemize} \pnum -\indextext{fundamental~alignment}% -\indextext{alignment!fundamental}% -A \term{fundamental alignment} is represented by an alignment -less than or equal to the greatest alignment supported by the implementation in -all contexts, which is equal to -\tcode{alignof(std::max_align_t)}~(\ref{support.types}). -The alignment required for a type might be different when it is used as the type -of a complete object and when it is used as the type of a subobject. \enterexample +The fourth context is when a temporary object +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 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 +with unique names +are destroyed at the end of the structured binding declaration. + +\pnum +Let \tcode{x} and \tcode{y} each be either +a temporary object whose lifetime is not extended, or +a function parameter. +If the lifetimes of \tcode{x} and \tcode{y} end at +the end of the same full-expression, and +\tcode{x} is initialized before \tcode{y}, then +the destruction of \tcode{y} is sequenced before that of \tcode{x}. +If the lifetime of two or more temporaries +with lifetimes extending beyond the full-expressions in which they were created +ends at the same point, +these temporaries are destroyed at that point in the reverse order of the +completion of their construction. +In addition, the destruction of such temporaries shall +take into account the ordering of destruction of objects with static, thread, or +automatic storage duration\iref{basic.stc.static,basic.stc.thread,basic.stc.auto}; +that is, if +\tcode{obj1} +is an object with the same storage duration as the temporary and +created before the temporary is created +the temporary shall be destroyed before +\tcode{obj1} +is destroyed; +if +\tcode{obj2} +is an object with the same storage duration as the temporary and +created after the temporary is created +the temporary shall be destroyed after +\tcode{obj2} +is destroyed. + +\pnum +\begin{example} \begin{codeblock} -struct B { long double d; }; -struct D : virtual B { char c; } +struct S { + S(); + S(int); + friend S operator+(const S&, const S&); + ~S(); +}; +S obj1; +const S& cr = S(16)+S(23); +S obj2; \end{codeblock} -When \tcode{D} is the type of a complete object, it will have a subobject of -type \tcode{B}, so it must be aligned appropriately for a \tcode{long double}. -If \tcode{D} appears as a subobject of another object that also has \tcode{B} -as a virtual base class, the \tcode{B} subobject might be part of a different -subobject, reducing the alignment requirements on the \tcode{D} subobject. -\exitexample The result of the \tcode{alignof} operator reflects the alignment -requirement of the type in the complete-object case. - +The expression +\tcode{S(16) + S(23)} +creates three temporaries: +a first temporary +\tcode{T1} +to hold the result of the expression +\tcode{S(16)}, +a second temporary +\tcode{T2} +to hold the result of the expression +\tcode{S(23)}, +and a third temporary +\tcode{T3} +to hold the result of the addition of these two expressions. +The temporary +\tcode{T3} +is then bound to the reference +\tcode{cr}. +It is unspecified whether +\tcode{T1} +or +\tcode{T2} +is created first. +On an implementation where +\tcode{T1} +is created before +\tcode{T2}, +\tcode{T2} +shall be destroyed before +\tcode{T1}. +The temporaries +\tcode{T1} +and +\tcode{T2} +are bound to the reference parameters of +\tcode{\keyword{operator}+}; +these temporaries are destroyed at the end of the full-expression +containing the call to +\tcode{\keyword{operator}+}. +The temporary +\tcode{T3} +bound to the reference +\tcode{cr} +is destroyed at the end of +\tcode{cr}'s +lifetime, that is, at the end of the program. +In addition, the order in which +\tcode{T3} +is destroyed takes into account the destruction order of other objects with +static storage duration. +That is, because +\tcode{obj1} +is constructed before +\tcode{T3}, +and +\tcode{T3} +is constructed before +\tcode{obj2}, +\tcode{obj2} +shall be destroyed before +\tcode{T3}, +and +\tcode{T3} +shall be destroyed before +\tcode{obj1}. +\end{example} + +\rSec1[basic.types]{Types}% + +\rSec2[basic.types.general]{General}% +\indextext{type|(} + \pnum -\indextext{extended~alignment}% -\indextext{alignment!extended}% -\indextext{over-aligned~type}% -\indextext{type!over-aligned}% -An \term{extended alignment} is represented by an alignment -greater than \tcode{alignof(std::max_align_t)}. It is implementation-defined -whether any extended alignments are supported and the contexts in which they are -supported~(\ref{dcl.align}). A type having an extended alignment -requirement is an \grammarterm{over-aligned type}. \enternote -every over-aligned type is or contains a class type -to which extended alignment applies (possibly through a non-static data member). -\exitnote +\begin{note} +\ref{basic.types} and the subclauses thereof +impose requirements on implementations regarding the representation +of types. +There are two kinds of types: fundamental types and compound types. +Types describe objects\iref{intro.object}, +references\iref{dcl.ref}, +or functions\iref{dcl.fct}. +\end{note} \pnum -Alignments are represented as values of the type \tcode{std::size_t}. -Valid alignments include only those values returned by an \tcode{alignof} -expression for the fundamental types plus an additional \impldef{alignment additional -values} -set of values, which may be empty. -Every alignment value shall be a non-negative integral power of two. +\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} +of a complete object type \tcode{T} is the +sequence of \placeholder{N} \tcode{\keyword{unsigned} \keyword{char}} objects taken up +by a non-bit-field complete object of type \tcode{T}, +where \placeholder{N} equals +\tcode{\keyword{sizeof}(T)}. +The \defnx{value representation}{representation!value} +of a type \tcode{T} is the set of bits +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 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 +the sequence of \placeholder{N} bits taken up by the object, +where \placeholder{N} is the width of the bit-field\iref{class.bit}. +The value representation of a bit-field object is +the set of bits in the object representation that +participate in representing its value. +\label{term.padding.bits}% +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. +\end{footnote} \pnum -Alignments have an order from \term{weaker} to -\term{stronger} or \term{stricter} alignments. Stricter -alignments have larger alignment values. An address that satisfies an alignment -requirement also satisfies any weaker valid alignment requirement. +\indextext{type!incompletely-defined object}% +A class that has been declared but not defined, an enumeration type in certain +contexts\iref{dcl.enum}, or an array of unknown +bound or of incomplete element type, is an +\defnadj{incompletely-defined}{object type}. +\begin{footnote} +The size and layout of an instance of an incompletely-defined +object type is unknown. +\end{footnote} +\label{term.incomplete.type}% +Incompletely-defined object types and \cv{}~\keyword{void} are +\defnadjx{incomplete}{types}{type}\iref{basic.fundamental}. +\begin{note} +Objects cannot be defined to have an incomplete type\iref{basic.def}. +\end{note} + +\pnum +A class type (such as ``\tcode{\keyword{class} X}'') can be incomplete at one +point in a translation unit and complete later on; the type +``\tcode{\keyword{class} X}'' is the same type at both points. The declared type +of an array object can be an array of incomplete class type and +therefore incomplete; if the class type is completed later on in the +translation unit, the array type becomes complete; the array type at +those two points is the same type. The declared type of an array object +can be an array of unknown bound and therefore be incomplete at one +point in a translation unit and complete later on; the array types at +those two points (``array of unknown bound of \tcode{T}'' and ``array of +\tcode{N} \tcode{T}'') are different types. +\begin{note} +The type of a pointer or reference to array of unknown bound +permanently points to or refers to an incomplete type. +An array of unknown bound named by a \keyword{typedef} declaration +permanently refers to an incomplete type. +In either case, the array type cannot be completed. +\end{note} +\begin{example} +\indextext{type!example of incomplete}% +\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 \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; + +void foo() { + xp++; // error: \tcode{X} is incomplete + arrp++; // error: incomplete type + arrpp++; // OK, \tcode{sizeof(UNKA*)} is known +} + +struct X { int i; }; // now \tcode{X} is a complete type +int arr[10]; // now the type of \tcode{arr} is complete + +X x; +void bar() { + 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 +} +\end{codeblock} +\end{example} \pnum -The alignment requirement of a complete type can be queried using an -\tcode{alignof} expression~(\ref{expr.alignof}). Furthermore, -the narrow character types~(\ref{basic.fundamental}) shall have the weakest +\begin{note} +The rules for declarations and expressions describe in which +contexts incomplete types are prohibited. +\end{note} + +\pnum +\label{term.object.type}% +An \defn{object type} is a (possibly cv-qualified) type that is not +a function type, not a reference type, and not \cv{}~\keyword{void}. + +\pnum +\indextext{class!trivial}% +\indextext{class!trivially copyable}% +\indextext{class!standard-layout}% +\label{term.scalar.type}% +Arithmetic types\iref{basic.fundamental}, enumeration types, +pointer types, pointer-to-member types\iref{basic.compound}, +\tcode{std::meta::\brk{}info}, \tcode{std::nullptr_t}, +and +cv-qualified\iref{basic.type.qualifier} versions of these +types are collectively called +\defnadjx{scalar}{types}{type}. +\label{term.trivially.copyable.type}% +Scalar types, trivially copyable class types\iref{class.prop}, +arrays of such types, and cv-qualified versions of these +types are collectively called \defnadjx{trivially copyable}{types}{type}. +\label{term.standard.layout.type}% +Scalar types, standard-layout class +types\iref{class.prop}, arrays of such types, and +cv-qualified versions of these types +are collectively called \defnadjx{standard-layout}{types}{type}. +\label{term.implicit.lifetime.type}% +Scalar types, implicit-lifetime class types\iref{class.prop}, +array types, and cv-qualified versions of these types +are collectively called \defnadjx{implicit-lifetime}{types}{type}. + +\pnum +\label{term.literal.type}% +A type is a \defnadj{literal}{type} if it is: +\begin{itemize} +\item \cv{}~\keyword{void}; or +\item a scalar type; or +\item a reference type; or +\item an array of literal type; or +\item a possibly cv-qualified class type\iref{class} that +has all of the following properties: +\begin{itemize} +\item it has a constexpr destructor\iref{dcl.constexpr}, +\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}, +\item is an aggregate union type that has either +no variant members or +at least one variant member of non-volatile literal type, +\item is a non-union aggregate type for which +each of its anonymous union members +satisfies the above requirements for an aggregate union type, or +\item has at least one constexpr constructor or constructor template +(possibly inherited\iref{namespace.udecl} from a base class) +that is not a copy or move constructor. +\end{itemize} +\end{itemize} +\end{itemize} +\begin{note} +A literal type is one for which +it might be possible to create an object +within a constant expression. +It is not a guarantee that it is possible to create such an object, +nor is it a guarantee that any object of that type +will be usable in a constant expression. +\end{note} + +\pnum +\label{term.layout.compatible.type}% +Two types \cvqual{cv1} \tcode{T1} and \cvqual{cv2} \tcode{T2} are +\defnadjx{layout-compatible}{types}{type} +if \tcode{T1} and \tcode{T2} are the same type, +layout-compatible enumerations\iref{dcl.enum}, or +layout-compatible standard-layout class types\iref{class.mem}. + +\pnum +A type is \defn{consteval-only} if it is +\begin{itemize} +\item \tcode{std::meta::info}, +\item \cv{}~\tcode{T}, where \tcode{T} is a consteval-only type, +\item a pointer or reference to a consteval-only type, +\item an array of consteval-only type, +\item a function type having a return type or any parameter type that is consteval-only, +\item a class type with any non-static data member having consteval-only type, or +\item a type ``pointer to member of class \tcode{C} of type \tcode{T}'', +where at least one of \tcode{C} or \tcode{T} is a consteval-only type. +\end{itemize} +Every object of consteval-only type 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 subobject thereof, or +\item +an object whose lifetime begins and ends +during the evaluation of a core constant expression. +\end{itemize} +Every function of consteval-only type shall be +an immediate function\iref{expr.const.imm}. + +\rSec2[basic.fundamental]{Fundamental types} + +\pnum +\indextext{type!implementation-defined \tcode{sizeof}}% +There are five \defnadjx{standard signed integer}{types}{type}: +\indextext{type!\idxcode{signed char}}% +\indextext{type!\idxcode{short}}% +\indextext{type!\idxcode{int}}% +\indextext{type!\idxcode{long}}% +\indextext{type!\idxcode{long long}}% +``\tcode{\keyword{signed} \keyword{char}}'', ``\tcode{\keyword{short} \keyword{int}}'', ``\keyword{int}'', +``\tcode{\keyword{long} \keyword{int}}'', and ``\tcode{\keyword{long} \keyword{long} \keyword{int}}''. In +this list, each type provides at least as much storage as those +preceding it in the list. +There may also be \impldef{extended signed integer types} +\defnadjx{extended signed integer}{types}{type}. +The standard and extended signed integer types are collectively called +\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 $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}}% +For each of the standard signed integer types, +there exists a corresponding (but different) +\defnadj{standard unsigned integer}{type}: +\indextext{type!\idxcode{unsigned char}}% +\indextext{type!\idxcode{unsigned short}}% +\indextext{type!\idxcode{unsigned int}}% +\indextext{type!\idxcode{unsigned long}}% +\indextext{type!\idxcode{unsigned long long}}% +``\tcode{\keyword{unsigned} \keyword{char}}'', ``\tcode{\keyword{unsigned} \keyword{short} \keyword{int}}'', +``\tcode{\keyword{unsigned} \keyword{int}}'', ``\tcode{\keyword{unsigned} \keyword{long} \keyword{int}}'', and +``\tcode{\keyword{unsigned} \keyword{long} \keyword{long} \keyword{int}}''. +Likewise, for each of the extended signed integer types, +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 $N$ +as the corresponding signed integer type. +\indextext{arithmetic!\idxcode{unsigned}}% +The range of representable values for the unsigned type is +$0$ to $2^N-1$ (inclusive); +arithmetic for the unsigned type is performed modulo $2^N$. +\begin{note} +Unsigned arithmetic does not overflow. +Overflow for signed arithmetic yields undefined behavior\iref{expr.pre}. +\end{note} + +\pnum +\indextext{signed integer representation!two's complement}% +An unsigned integer type has the same +object representation, +value representation, and +alignment requirements\iref{basic.align} +as the corresponding signed integer type. +For each value $x$ of a signed integer type, +the value of the corresponding unsigned integer type +congruent to $x$ modulo $2^N$ has the same value +of corresponding bits in its value representation. +\begin{footnote} +This +is also known as two's complement representation. +\end{footnote} +\begin{example} +The value $-1$ of a signed integer type has the same representation as +the largest value of the corresponding unsigned type. +\end{example} + +\begin{floattable}{Minimum width}{basic.fundamental.width}{lc} +\topline +\lhdr{Type} & \rhdr{Minimum width $N$} \\ +\capsep +\tcode{\keyword{signed} \keyword{char}} & 8 \\ +\tcode{\keyword{short} \keyword{int}} & 16 \\ +\keyword{int} & 16 \\ +\tcode{\keyword{long} \keyword{int}} & 32 \\ +\tcode{\keyword{long} \keyword{long} \keyword{int}} & 64 \\ +\end{floattable} + +\pnum +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. +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. +\begin{note} +Padding bits have unspecified value, but cannot cause traps. +In contrast, see \IsoC{} 6.2.6.2. +\end{note} +\begin{note} +The signed and unsigned integer types satisfy +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 +\impldef{width of integral type}. + +\pnum +Each value $x$ of an unsigned integer type with width $N$ has +a unique representation $x = x_0 2^0 + x_1 2^1 + \ldots + x_{N-1} 2^{N-1}$, +where each coefficient $x_i$ is either 0 or 1; +this is called the \defn{base-2 representation} of $x$. +The base-2 representation of a value of signed integer type is +the base-2 representation of the congruent value +of the corresponding unsigned integer type. +The standard signed integer types and standard unsigned integer types +are collectively called the \defnadjx{standard integer}{types}{type}, and the extended +signed integer types and extended +unsigned integer types are collectively called the +\defnadjx{extended integer}{types}{type}. + +\pnum +A fundamental type specified to have +a signed or unsigned integer type as its \defnadj{underlying}{type} has +the same object representation, +value representation, +alignment requirements\iref{basic.align}, and +range of representable values as the underlying type. +Further, each value has the same representation in both types. + +\pnum +\indextext{type!\idxcode{char}}% +\indextext{type!character}% +\indextext{\idxcode{char}!implementation-defined sign of}% +\indextext{type!\idxcode{signed char}}% +\indextext{character!\idxcode{signed}}% +\indextext{type!\idxcode{unsigned char}}% +Type \keyword{char} is a distinct type +that has an \impldef{underlying type of \tcode{char}} choice of +``\tcode{\keyword{signed} \keyword{char}}'' or ``\tcode{\keyword{unsigned} \keyword{char}}'' as its underlying type. +The three types \keyword{char}, \tcode{\keyword{signed} \keyword{char}}, and \tcode{\keyword{unsigned} \keyword{char}} +are collectively called +\defnadjx{ordinary character}{types}{type}. +The ordinary character types and \keyword{char8_t} +are collectively called \defnadjx{narrow character}{types}{type}. +For narrow character types, +each possible bit pattern of the object representation represents +a distinct value. +\begin{note} +This requirement does not hold for other types. +\end{note} +\begin{note} +A bit-field of narrow character type whose width is larger than +the width of that type has padding bits; see \ref{basic.types.general}. +\end{note} + +\pnum +\indextext{\idxcode{wchar_t}|see{type, \tcode{wchar_t}}}% +\indextext{type!\idxcode{wchar_t}}% +\indextext{type!underlying!\idxcode{wchar_t}}% +Type \keyword{wchar_t} is a distinct type that has +an \impldef{underlying type of \tcode{wchar_t}} +signed or unsigned integer type as its underlying type. + +\pnum +\indextext{\idxcode{char8_t}|see{type, \tcode{char8_t}}}% +\indextext{type!\idxcode{char8_t}}% +\indextext{type!underlying!\idxcode{char8_t}}% +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}}}% +\indextext{type!\idxcode{char16_t}}% +\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} are distinct types +whose underlying types are \tcode{std::uint_least16_t} and \tcode{std::uint_least32_t}, +respectively, in \libheaderref{cstdint}. + +\pnum +\indextext{Boolean type}% +\indextext{type!Boolean}% +Type \tcode{bool} is a distinct type that has +the same object representation, +value representation, and +alignment requirements as +an \impldef{underlying type of \tcode{bool}} unsigned integer type. +The values of type \keyword{bool} are +\keyword{true} and \keyword{false}. +\begin{note} +There are no \keyword{signed}, \keyword{unsigned}, +\keyword{short}, or \tcode{\keyword{long} \keyword{bool}} types or values. +\end{note} + +\pnum +\indextext{type!integral}% +The types \keyword{char}, \keyword{wchar_t}, +\keyword{char8_t}, \keyword{char16_t}, and \keyword{char32_t} +are collectively called \defnadjx{character}{types}{type}. +The character types, \keyword{bool}, +the signed and unsigned integer types, +and cv-qualified versions\iref{basic.type.qualifier} thereof, +are collectively termed +\defnx{integral types}{integral type}. +A synonym for integral type is \defn{integer type}. +\begin{note} +Enumerations\iref{dcl.enum} are not integral; +however, unscoped enumerations can be promoted to integral types +as specified in \ref{conv.prom}. +\end{note} + +\pnum +\indextext{floating-point type|see{type, floating-point}}% +The three distinct types +\indextext{type!\idxcode{float}}% +\keyword{float}, +\indextext{type!\idxcode{double}}% +\keyword{double}, +and +\indextext{type!\idxcode{long double}}% +\tcode{\keyword{long} \keyword{double}} +can represent floating-point numbers. +The type \keyword{double} provides at least as much +precision as \keyword{float}, and the type \tcode{\keyword{long} \keyword{double}} provides at +least as much precision as \keyword{double}. The set of values of the type +\keyword{float} is a subset of the set of values of the type +\keyword{double}; the set of values of the type \keyword{double} is a subset +of the set of values of the type \tcode{\keyword{long} \keyword{double}}. +The types +\keyword{float}, \keyword{double}, and \tcode{\keyword{long} \keyword{double}}, +and cv-qualified versions\iref{basic.type.qualifier} thereof, +are collectively termed +\defnx{standard floating-point types}{type!floating-point!standard}. +An implementation may also provide additional types +that represent floating-point values and define them (and cv-qualified versions thereof) to be +\defnx{extended floating-point types}{type!floating-point!extended}. +The standard and extended floating-point types +are collectively termed \defnx{floating-point types}{type!floating-point}. +\begin{note} +Any additional implementation-specific types representing floating-point values +that are not defined by the implementation to be extended floating-point types +are not considered to be floating-point types, and +this document imposes no requirements on them or +their interactions with floating-point types. +\end{note} +Except as specified in \ref{basic.extended.fp}, +the object and value representations and accuracy of operations +of floating-point types are \impldef{representation of floating-point types}. + +\pnum +The minimum range of representable values for a floating-point type is +the most negative finite floating-point number representable +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; +likewise, if positive infinity is representable in a type, +the range 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 +a floating-point type adhering to \IsoFloatUndated{}. +\end{note} + +\pnum +Integral and floating-point types are collectively +termed \defnx{arithmetic types}{type!arithmetic}. +\begin{note} +Properties of the arithmetic types, +such as their minimum and maximum representable value, +can be queried using the facilities in the standard library headers +\libheaderref{limits}, +\libheaderref{climits}, and +\libheaderref{cfloat}. +\end{note} + +\pnum +\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. +\begin{note} +An expression of type \cv{}~\keyword{void} can be used as +\begin{itemize} +\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}, +\item the operand of a \keyword{decltype} specifier\iref{dcl.type.decltype}, or +\item the operand of an explicit conversion to type +\cv{}~\keyword{void}\iref{expr.type.conv,expr.static.cast,expr.cast}. +\end{itemize} +\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}. +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}% +The types described in this subclause +are called \defnx{fundamental types}{fundamental type}. +\begin{note} +Even if the implementation defines two or more fundamental types to have the +same value representation, they are nevertheless different types. +\end{note} + +\rSec2[basic.extended.fp]{Optional extended floating-point types} + +\pnum +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 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}. + +\pnum +If the implementation supports an extended floating-point type +whose properties are specified by +the \IsoFloatUndated{} floating-point interchange format binary32, +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. + +\pnum +If the implementation supports an extended floating-point type +whose properties are specified by +the \IsoFloatUndated{} floating-point interchange format binary64, +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. + +\pnum +If the implementation supports an extended floating-point type +whose properties are specified by +the \IsoFloatUndated{} floating-point interchange format binary128, +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. + +\pnum +If the implementation supports an extended floating-point type +with the properties, as specified by \IsoFloatUndated{}, of +radix ($b$) of 2, +storage width in bits ($k$) of 16, +precision in bits ($p$) of 8, +maximum exponent ($emax$) of 127, and +exponent field width in bits ($w$) of 8, then +the 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. + +\pnum +\begin{note} +A summary of the parameters for each type is given in \tref{basic.extended.fp}. +The precision $p$ includes the implicit 1 bit at the beginning of the significand, +so the storage used for the significand is $p-1$ bits. +\IsoFloatUndated{} does not assign a name for a type +having the parameters specified for \tcode{std::bfloat16_t}. +\end{note} +\begin{floattable} +{Properties of named extended floating-point types}{basic.extended.fp}{llllll} +\topline +\lhdr{Parameter} & \chdr{\tcode{float16_t}} & \chdr{\tcode{float32_t}} & +\chdr{\tcode{float64_t}} & \chdr{\tcode{float128_t}} & +\rhdr{\tcode{bfloat16_t}} \\ +\capsep +\IsoFloatUndated{} name & binary16 & binary32 & binary64 & binary128 & \\ +$k$, storage width in bits & 16 & 32 & 64 & 128 & 16 \\ +$p$, precision in bits & 11 & 24 & 53 & 113 & 8 \\ +$emax$, maximum exponent & 15 & 127 & 1023 & 16383 & 127 \\ +$w$, exponent field width in bits & 5 & 8 & 11 & 15 & 8 \\ +\end{floattable} + +\pnum +\recommended +Any names that the implementation provides for +the extended floating-point types described in this subsection +that are in addition to the names declared in the \libheader{stdfloat} header +should be chosen to increase compatibility and interoperability +with the interchange floating types +\tcode{_Float16}, \tcode{_Float32}, \tcode{_Float64}, and \tcode{_Float128} +defined in \IsoC{} H.2.2. + +\rSec2[basic.compound]{Compound types} + +\pnum +\indextext{type!compound}% +Compound types can be constructed in the following ways: +\begin{itemize} +\item \defnx{arrays}{type!array} of objects of a given type, \ref{dcl.array}; + +\item \defnx{functions}{type!function}, which have parameters of given types and return +\keyword{void} or a result of a given type, \ref{dcl.fct}; + +\item \defnx{pointers}{type!pointer} to \cv{}~\keyword{void} or objects or functions (including +static members of classes) of a given type, \ref{dcl.ptr}; + +\item +\indextext{reference!lvalue}% +\indextext{reference!rvalue}% +\defnx{references}{reference} to objects or functions of a given +type, \ref{dcl.ref}. There are two types of references: +\begin{itemize} +\item lvalue reference +\item rvalue reference +\end{itemize} + +\item +\defnx{classes}{class} containing a sequence of class members\iref{class,class.mem}, +and a set of restrictions +on the access to these entities\iref{class.access}; + +\item +\defnx{unions}{\idxcode{union}}, which are classes capable of containing objects of +different types at different times, \ref{class.union}; + +\item +\defnx{enumerations}{\idxcode{enum}}, +which comprise a set of named constant values, \ref{dcl.enum}; + +\item +\indextext{member pointer to|see{pointer to member}}% +\defnx{pointers to non-static class members}{pointer to member},% +\begin{footnote} +Static class members are objects or functions, and pointers to them are +ordinary pointers to objects or functions. +\end{footnote} +which identify members of a given +type within objects of a given class, \ref{dcl.mptr}. +Pointers to data members and pointers to member functions are collectively +called \term{pointer-to-member} types. +\end{itemize} + +\pnum +These methods of constructing types can be applied recursively; +restrictions are mentioned in~\ref{dcl.meaning}. +Constructing a type such that the number of +bytes in its object representation exceeds the maximum value representable in +the type \tcode{std::size_t}\iref{support.types} is ill-formed. + +\pnum +\indextext{terminology!pointer}% +The type of a pointer to \cv{}~\keyword{void} or a pointer to an object type is +called an \defn{object pointer type}. +\begin{note} +A pointer to \keyword{void} +does not have a pointer-to-object type, however, because \keyword{void} is not +an object type. +\end{note} +The type of a pointer that can designate a function +is called a \defn{function pointer type}. +A pointer to an object of type \tcode{T} is referred to as a ``pointer to +\tcode{T}''. +\begin{example} +A pointer to an object of type \keyword{int} is +referred to as ``pointer to \keyword{int}'' and a pointer to an object of +class \tcode{X} is called a ``pointer to \tcode{X}''. +\end{example} +Except for pointers to static members, text referring to ``pointers'' +does not apply to pointers to members. Pointers to incomplete types are +allowed although there are restrictions on what can be done with +them\iref{basic.types.general}. +\indextext{address}% +Every value of pointer type is one of the following: +\begin{itemize} +\item +a \defn{pointer to} an object or function (the pointer is said to \defn{point} to the object or function), or +\item +a \defn{pointer past the end of} an object\iref{expr.add}, or +\item +\indextext{null pointer value|see{value, null pointer}} +the \defnx{null pointer value}{value!null pointer} for that type, or +\item +\indextext{invalid pointer value|see{value, invalid pointer}} +an \defnx{invalid pointer value}{value!invalid pointer}. +\end{itemize} +A value of a +pointer type +that is a pointer to or past the end of an object +\defn{represents the address} of +the first byte in memory\iref{intro.memory} occupied by the object +\begin{footnote} +For an object that is not within its lifetime, +this is the first byte in memory that it will occupy or used to occupy. +\end{footnote} +or the first byte in memory +after the end of the storage occupied by the object, +respectively. +\begin{note} +A pointer past the end of an object\iref{expr.add} +is not considered to point to an unrelated object +of the object's type, +even if the unrelated object is located at that address. +\end{note} +For purposes of pointer arithmetic\iref{expr.add} +and comparison\iref{expr.rel,expr.eq}, +a pointer past the end of the last element of +an array \tcode{x} of $n$ elements +is considered to be equivalent to +a pointer to a hypothetical array element $n$ of \tcode{x}, and +an object of type \tcode{T} that is not an array element +is considered to belong to an array with one element of type \tcode{T}. +The value representation of +pointer types is \impldef{value representation of pointer types}. Pointers to +layout-compatible types shall +have the same value representation and alignment +requirements\iref{basic.align}. +\begin{note} +Pointers to over-aligned types\iref{basic.align} have no special +representation, but their range of valid values is restricted by the extended alignment requirement. -\enternote This enables the narrow character types to be used as the -underlying type for an aligned memory area~(\ref{dcl.align}).\exitnote +\end{note} \pnum -Comparing alignments is meaningful and provides the obvious results: +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 +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$. +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} +\begin{note} +$P$ can be valid in the context of $E$ even +if it points to a type unrelated to that of $O$ or +if $O$ is not within its lifetime, +although further restrictions apply +to such pointer values\iref{basic.life, basic.lval, expr.add}. +\end{note} + +\pnum +Two objects \placeholder{a} and \placeholder{b} are \defn{pointer-interconvertible} if +\begin{itemize} +\item +they are the same object, or +\item +one is a union object and +the other is a non-static data member of that object\iref{class.union}, or +\item +one is a standard-layout class object and +the other is the first non-static data member of that object or +any base class subobject of that object\iref{class.mem}, or +\item +there exists an object \placeholder{c} such that +\placeholder{a} and \placeholder{c} are pointer-interconvertible, and +\placeholder{c} and \placeholder{b} are pointer-interconvertible. +\end{itemize} +If two objects are pointer-interconvertible, +then they have the same address, +and it is possible to obtain a pointer to one +from a pointer to the other +via a \keyword{reinterpret_cast}\iref{expr.reinterpret.cast}. +\begin{note} +An array object and its first element are not pointer-interconvertible, +even though they have the same address. +\end{note} + +\pnum +A byte of storage \placeholder{b} +is \defnx{reachable through}{storage!reachable through a pointer value} +a pointer value that points to an object \placeholder{x} +if there is an object \placeholder{y}, +pointer-interconvertible with \placeholder{x}, +such that \placeholder{b} is within the storage occupied by +\placeholder{y}, or the immediately-enclosing array object +if \placeholder{y} is an array element. + +\pnum +\indextext{pointer|seealso{\tcode{void*}}}% +\indextext{\idxcode{void*}!type}% +A pointer to \cv{}~\keyword{void} +can be used to point to objects of +unknown type. Such a pointer shall be able to hold any object pointer. +An object of type ``pointer to \cv{}~\keyword{void}'' +shall have the same representation and alignment +requirements as an object of type ``pointer to \cv{}~\keyword{char}''. +\rSec2[basic.type.qualifier]{CV-qualifiers} + +\pnum +\indextext{cv-qualifier}% +\indextext{\idxcode{const}}% +\indextext{\idxcode{volatile}}% +Each type other than a function or reference type +is part of a group of four distinct, but related, types: +a \defn{cv-unqualified} version, +a \defn{const-qualified} version, +a \defn{volatile-qualified} version, and +a \defn{const-volatile-qualified} version. +The types in each such group shall have +the same representation and alignment requirements\iref{basic.align}. +\begin{footnote} +The same representation and alignment requirements +are meant to imply interchangeability as +arguments to functions, +return values from functions, and +non-static data members of unions. +\end{footnote} +A function or reference type is always cv-unqualified. \begin{itemize} -\item Two alignments are equal when their numeric values are equal. -\item Two alignments are different when their numeric values are not equal. -\item When an alignment is larger than another it represents a stricter alignment. +\item A \defnadj{const}{object} is an object of type \tcode{\keyword{const} T} or a + non-mutable subobject of a const object. + +\item A \defnadj{volatile}{object} is an object of type + \tcode{\keyword{volatile} T} or a subobject of a volatile object. + +\item A \defnadj{const volatile}{object} is an object of type + \tcode{\keyword{const} \keyword{volatile} T}, a non-mutable subobject of a const volatile object, + a const subobject of a volatile object, or a non-mutable volatile + subobject of a const object. \end{itemize} +\begin{note} +The type of an object\iref{intro.object} includes +the \grammarterm{cv-qualifier}s specified in the +\grammarterm{decl-specifier-seq}\iref{dcl.spec}, +\grammarterm{declarator}\iref{dcl.decl}, +\grammarterm{type-id}\iref{dcl.name}, or +\grammarterm{new-type-id}\iref{expr.new} +when the object is created. +\end{note} \pnum -\enternote The runtime pointer alignment function~(\ref{ptr.align}) -can be used to obtain an aligned pointer within a buffer; the aligned-storage templates -in the library~(\ref{meta.trans.other}) can be used to obtain aligned storage. -\exitnote +Except for array types, a compound type\iref{basic.compound} is not cv-qualified by the +cv-qualifiers (if any) of the types from which it is compounded. \pnum -If a request for a specific extended alignment in a specific context is not -supported by an implementation, the program is ill-formed. Additionally, a -request for runtime allocation of dynamic storage for which the requested -alignment cannot be honored shall be treated as an allocation failure. +\indextext{array!\idxcode{const}}% +An array type whose elements are cv-qualified +is also considered to have the same cv-qualifications +as its elements. +\begin{note} +Cv-qualifiers applied to an array +type attach to the underlying element type, so the notation +``\cv{}~\tcode{T}'', where \tcode{T} is an array type, refers to +an array whose elements are so-qualified\iref{dcl.array}. +\end{note} +\begin{example} +\begin{codeblock} +typedef char CA[5]; +typedef const char CC; +CC arr1[5] = { 0 }; +const CA arr2 = { 0 }; +\end{codeblock} +The type of both \tcode{arr1} and \tcode{arr2} is ``array of 5 +\tcode{\keyword{const} \keyword{char}}'', and the array type is considered to be +const-qualified. +\end{example} +\indextext{type|)} + +\pnum +\begin{note} +See~\ref{dcl.fct} and~\ref{over.match.funcs} regarding function +types that have \grammarterm{cv-qualifier}{s}. +\end{note} + +\pnum +There is a partial ordering on cv-qualifiers, so that a type can be +said to be \defn{more cv-qualified} than another. +\tref{basic.type.qualifier.rel} shows the relations that +constitute this ordering. + +\begin{floattable}{Relations on \keyword{const} and \keyword{volatile}}{basic.type.qualifier.rel} +{ccc} +\topline +\cvqual{no cv-qualifier} &<& \keyword{const} \\ +\cvqual{no cv-qualifier} &<& \keyword{volatile} \\ +\cvqual{no cv-qualifier} &<& \tcode{\keyword{const} \keyword{volatile}} \\ +\keyword{const} &<& \tcode{\keyword{const} \keyword{volatile}} \\ +\keyword{volatile} &<& \tcode{\keyword{const} \keyword{volatile}} \\ +\end{floattable} + +\pnum +In this document, the notation \cv{} (or +\cvqual{cv1}, \cvqual{cv2}, etc.), used in the description of types, +represents an arbitrary set of cv-qualifiers, i.e., one of +\{\keyword{const}\}, \{\keyword{volatile}\}, \{\keyword{const}, +\keyword{volatile}\}, or the empty set. +For a type \cv{}~\tcode{T}, the \defnx{top-level cv-qualifiers}{cv-qualifier!top-level} +of that type are those denoted by \cv. +\begin{example} +The type corresponding to the \grammarterm{type-id} +\tcode{\keyword{const} \keyword{int}\&} +has no top-level cv-qualifiers. +The type corresponding to the \grammarterm{type-id} +\tcode{\keyword{volatile} \keyword{int} * \keyword{const}} +has the top-level cv-qualifier \keyword{const}. +For a class type \tcode{C}, +the type corresponding to the \grammarterm{type-id} +\tcode{\keyword{void} (C::* \keyword{volatile})(\keyword{int}) \keyword{const}} +has the top-level cv-qualifier \keyword{volatile}. +\end{example} + +\rSec2[conv.rank]{Conversion ranks}% +\indextext{conversion!integer rank} + +\pnum +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 +the same representation. + +\item The rank of a signed integer type is greater than the rank +of any signed integer type with a smaller width. + +\item The rank of \tcode{\keyword{long} \keyword{long} \keyword{int}} is greater +than the rank of \tcode{\keyword{long} \keyword{int}}, which is greater than +the rank of \keyword{int}, which is greater than the rank of +\tcode{\keyword{short} \keyword{int}}, which is greater than the rank of +\tcode{\keyword{signed} \keyword{char}}. + +\item The rank of any unsigned integer type equals the rank of the +corresponding signed integer type. + +\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. + +\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 +types\iref{basic.fundamental}. + +\item The rank of any extended signed integer type relative to another +extended signed integer type with the same width is \impldef{rank of extended signed +integer type}, but still subject to the other rules for determining the integer +conversion rank. + +\item For all integer types \tcode{T1}, \tcode{T2}, and \tcode{T3}, if +\tcode{T1} has greater rank than \tcode{T2} and \tcode{T2} has greater +rank than \tcode{T3}, then \tcode{T1} has greater rank than +\tcode{T3}. +\end{itemize} + +\begin{note} +The integer conversion rank is used in the definition of the integral +promotions\iref{conv.prom} and the usual arithmetic +conversions\iref{expr.arith.conv}. +\end{note} + +\pnum +Every floating-point type has a \defnadj{floating-point}{conversion rank} +defined as follows: +\begin{itemize} +\item +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 +The rank of \tcode{\keyword{long} \keyword{double}} is greater than +the rank of \keyword{double}, +which is greater than the rank of \keyword{float}. +\item +Two extended floating-point types with the same set of values have equal ranks. +\item +An extended floating-point type with the same set of values as +exactly one cv-unqualified standard floating-point type +has a rank equal to the rank of that standard floating-point type. +\item +An extended floating-point type with the same set of values as +more than one cv-unqualified standard floating-point type +has a rank equal to the rank of \keyword{double}. +\begin{tailnote} +The treatment of \tcode{std::float64_t} differs from +that of the analogous \tcode{_Float64} in C, +for example on platforms where all of +\tcode{\keyword{long} \keyword{double}}, +\keyword{double}, and +\tcode{std::float64_t} +have the same set of values (see \IsoC{} H.4.3). +\end{tailnote} +\end{itemize} +\begin{note} +The conversion ranks of floating-point types \tcode{T1} and \tcode{T2} +are unordered if the set of values of \tcode{T1} is +neither a subset nor a superset of the set of values of \tcode{T2}. +This can happen when one type has both a larger range and a lower precision +than the other. +\end{note} + +\pnum +Floating-point types that have equal floating-point conversion ranks +are ordered by floating-point conversion subrank. +The subrank forms a total order among types with equal ranks. +The types +\tcode{std::float16_t}, +\tcode{std::float32_t}, +\tcode{std::float64_t}, and +\tcode{std::float128_t}\iref{stdfloat.syn} +have a greater conversion subrank than any standard floating-point type +with equal conversion rank. +Otherwise, the conversion subrank order is +\impldef{floating-point conversion subrank}. + +\pnum +\begin{note} +The floating-point conversion rank and subrank are used in +the definition of the usual arithmetic conversions\iref{expr.arith.conv}. +\end{note} + +\rSec1[basic.exec]{Program execution} + +\rSec2[intro.execution]{Sequential execution} +\indextext{program execution|(} + +\pnum +An instance of each object with automatic storage +duration\iref{basic.stc.auto} is associated with each entry into its +block. Such an object exists and retains its last-stored value during +the execution of the block and while the block is suspended (by a call +of a function, suspension of a coroutine\iref{expr.await}, or receipt of a signal). + +\pnum +A \defn{constituent expression} is defined as follows: +\begin{itemize} +\item +The constituent expression of an expression is that expression. +\item +The constituent expression of a conversion is +the corresponding implicit function call, if any, or +the converted expression otherwise. +\item +The constituent expressions of a \grammarterm{braced-init-list} or +of a (possibly parenthesized) \grammarterm{expression-list} +are the constituent expressions of the elements of the respective list. +\item +The constituent expressions of a \grammarterm{brace-or-equal-initializer} +of the form \tcode{=}~\grammarterm{initializer-clause} +are the constituent expressions of the \grammarterm{initializer-clause}. +\end{itemize} +\begin{example} +\begin{codeblock} +struct A { int x; }; +struct B { int y; struct A a; }; +B b = { 5, { 1+1 } }; +\end{codeblock} +The constituent expressions of the \grammarterm{initializer} +used for the initialization of \tcode{b} are \tcode{5} and \tcode{1+1}. +\end{example} + +\pnum +The \defnx{immediate subexpressions}{immediate subexpression} of an expression $E$ are +\begin{itemize} +\item +the constituent expressions of $E$'s operands\iref{expr.prop}, +\item +any function call that $E$ implicitly invokes, +\item +if $E$ is a \grammarterm{lambda-expression}\iref{expr.prim.lambda}, +the initialization of the entities captured by copy and +the constituent expressions of the \grammarterm{initializer} of the \grammarterm{init-capture}{s}, +\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, and +\item +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} + +\pnum +A \defn{subexpression} of an expression $E$ is +an immediate subexpression of $E$ or +a subexpression of an immediate subexpression of $E$. +\begin{note} +Expressions appearing in the \grammarterm{compound-statement} of a \grammarterm{lambda-expression} +are not subexpressions of the \grammarterm{lambda-expression}. +\end{note} +The \defnadjx{potentially-evaluated}{subexpressions}{subexpression} of +an expression, conversion, or \grammarterm{initializer} $E$ are +\begin{itemize} +\item +the constituent expressions of $E$ and +\item +the subexpressions thereof that +are not subexpressions of a nested unevaluated operand\iref{term.unevaluated.operand}. +\end{itemize} + +\pnum +A \defn{full-expression} is +\begin{itemize} +\item +an unevaluated operand\iref{expr.context}, +\item +a \grammarterm{constant-expression}\iref{expr.const.core}, +\item +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 +a \grammarterm{mem-initializer}\iref{class.base.init}, +including the constituent expressions of the initializer, +\item +an invocation of a destructor generated at the end of the lifetime +of an object other than a temporary object\iref{class.temporary} +whose lifetime has not been extended, +\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. +\end{itemize} +If a language construct is defined to produce an implicit call of a function, +a use of the language construct is considered to be an expression +for the purposes of this definition. +Conversions applied to the result of an expression in order to satisfy the requirements +of the language construct in which the expression appears +are also considered to be part of the full-expression. +For an initializer, performing the initialization of the entity +(including evaluating default member initializers of an aggregate) +is also considered part of the full-expression. +\begin{example} +\begin{codeblock} +struct S { + S(int i): I(i) { } // full-expression is initialization of \tcode{I} + int& v() { return I; } + ~S() noexcept(false) { } +private: + int I; +}; + +S s1(1); // full-expression comprises call of \tcode{S::S(int)} +void f() { + S s2 = 2; // full-expression comprises call of \tcode{S::S(int)} + if (S(3).v()) // full-expression includes lvalue-to-rvalue and \tcode{int} to \tcode{bool} conversions, + // performed before temporary is deleted at end of full-expression + { } + bool b = noexcept(S(4)); // exception specification of destructor of \tcode{S} considered for \keyword{noexcept} + + // full-expression is destruction of \tcode{s2} at end of block +} +struct B { + B(S = S(0)); +}; +B b[2] = { B(), B() }; // full-expression is the entire initialization + // including the destruction of temporaries +\end{codeblock} +\end{example} + +\pnum +\begin{note} +The evaluation of a full-expression can include the +evaluation of subexpressions that are not lexically part of the +full-expression. For example, subexpressions involved in evaluating +default arguments\iref{dcl.fct.default} are considered to +be created in the expression that calls the function, not the expression +that defines the default argument. +\end{note} + +\pnum +\indextext{value computation|(}% +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 +initiation of side effects. When a call to a library I/O function +returns or an access through a volatile glvalue is evaluated, the side +effect is considered complete, even though some external actions implied +by the call (such as the I/O itself) or by the \keyword{volatile} access +may not have completed yet. + +\pnum +\defnx{Sequenced before}{sequenced before} is an asymmetric, transitive, pair-wise relation between +evaluations executed by a single thread\iref{intro.multithread}, which induces +a partial order among those evaluations. Given any two evaluations \placeholder{A} and +\placeholder{B}, if \placeholder{A} is sequenced before \placeholder{B} +(or, equivalently, \placeholder{B} is \defn{sequenced after} \placeholder{A}), +then the execution of +\placeholder{A} shall precede the execution of \placeholder{B}. If \placeholder{A} is not sequenced +before \placeholder{B} and \placeholder{B} is not sequenced before \placeholder{A}, then \placeholder{A} and +\placeholder{B} are \defn{unsequenced}. +\begin{note} +The execution of unsequenced +evaluations can overlap. +\end{note} +Evaluations \placeholder{A} and \placeholder{B} are +\defn{indeterminately sequenced} when either \placeholder{A} is sequenced before +\placeholder{B} or \placeholder{B} is sequenced before \placeholder{A}, but it is unspecified which. +\begin{note} +Indeterminately sequenced evaluations cannot overlap, but either +can be executed first. +\end{note} +An expression \placeholder{X} +is said to be sequenced before +an expression \placeholder{Y} if +every value computation and every side effect +associated with the expression \placeholder{X} +is sequenced before +every value computation and every side effect +associated with the expression \placeholder{Y}. + +\pnum +Every +\indextext{value computation}% +value computation and +\indextext{side effects}% +side effect associated with a full-expression is +sequenced before every value computation and side effect associated with the +next full-expression to be evaluated. +\begin{footnote} +As specified +in~\ref{class.temporary}, after a full-expression is evaluated, a sequence of +zero or more invocations of destructor functions for temporary objects takes +place, usually in reverse order of the construction of each temporary object. +\end{footnote} + +\pnum +\indextext{evaluation!unspecified order of}% +Except where noted, evaluations of operands of individual operators and +of subexpressions of individual expressions are unsequenced. +\begin{note} +In an expression that is evaluated more than once during the execution +of a program, unsequenced and indeterminately sequenced evaluations of +its subexpressions need not be performed consistently in different +evaluations. +\end{note} +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 +\begin{itemize} +\item +\indextext{side effects}% +a side effect on a memory location\iref{intro.memory} or +\item +starting or ending the lifetime of an object in a memory location +\end{itemize} +is unsequenced relative to +\begin{itemize} +\item +another side effect on the same memory location, +\item +starting or ending the lifetime of an object occupying storage that +overlaps with the memory location, or +\item +a value computation using the value of any object in the same memory location, +\end{itemize} +and the two evaluations are not potentially concurrent\iref{intro.multithread}. +\begin{note} +Starting the lifetime of an object in a memory location can end the lifetime of +objects in other memory locations\iref{basic.life}. +\end{note} +\begin{note} +The next subclause imposes similar, but more complex restrictions on +potentially concurrent computations. +\end{note} + +\begin{example} +\begin{codeblock} +void g(int i) { + i = 7, i++, i++; // \tcode{i} becomes \tcode{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 + + union U { int x, y; } u; + (u.x = 1, 0) + (u.y = 2, 0); // undefined behavior +} +\end{codeblock} +\end{example} + +\pnum +When invoking a function \placeholder{f} (whether or not the function is inline), +every argument expression and +the postfix expression designating \placeholder{f} +are sequenced before +every precondition assertion of \placeholder{f}\iref{dcl.contract.func}, +which in turn are sequenced before +every expression or statement +in the body of \placeholder{f}, +which in turn are sequenced before +every postcondition assertion of \placeholder{f}. + +\pnum +For each +\begin{itemize} +\item function invocation, +\item evaluation of an \grammarterm{await-expression}\iref{expr.await}, or +\item evaluation of a \grammarterm{throw-expression}\iref{expr.throw} +\end{itemize} +\placeholder{F}, +each evaluation that does not occur within \placeholder{F} +but is evaluated on the same thread and as part of the same signal handler (if any) +is either sequenced before all evaluations that occur within \placeholder{F} +or sequenced after all evaluations that occur within \placeholder{F}; +\begin{footnote} +In other words, +function executions do not interleave with each other. +\end{footnote} +if \placeholder{F} invokes or resumes a coroutine\iref{expr.await}, +only evaluations +subsequent to the previous suspension (if any) and +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. +\begin{example} +Evaluation of a \grammarterm{new-expression} invokes one or more allocation +and constructor functions; see~\ref{expr.new}. For another example, +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.% +\indextext{value computation|)}% + +\indextext{behavior!on receipt of signal}% +\indextext{signal}% +\pnum +If a signal handler is executed as a result of a call to the \tcode{std::raise} +function, then the execution of the handler is sequenced after the invocation +of the \tcode{std::raise} function and before its return. +\begin{note} +When a signal is received for another reason, the execution of the +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. + +\rSec2[intro.multithread]{Multi-threaded executions and data races} + +\rSec3[intro.multithread.general]{General} + +\pnum +\indextext{threads!multiple|(}% +\indextext{atomic!operation|(}% +A \defn{thread of execution} (also known as a \defn{thread}) is a single flow of +control within a program, including the initial invocation of a specific +top-level function, and recursively including every function invocation +subsequently executed by the thread. +\begin{note} +When one thread creates another, +the initial call to the top-level function of the new thread is executed by the +new thread, not by the creating thread. +\end{note} +Every thread in a program can +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 +one specific thread, and can be accessed by a different thread only indirectly +through a pointer or reference\iref{basic.compound}. +\end{footnote} +Under a hosted +implementation, a \Cpp{} program can have more than one thread running +concurrently. The execution of each thread proceeds as defined by the remainder +of this document. The execution of the entire program consists of an execution +of all of its threads. +\begin{note} +Usually the execution can be viewed as an +interleaving of all its threads. However, some kinds of atomic operations, for +example, allow executions inconsistent with a simple interleaving, as described +below. +\end{note} +\indextext{implementation!freestanding}% +Under a freestanding implementation, it is \impldef{number of +threads in a program under a freestanding implementation} whether a program can +have more than one thread of execution. + +\pnum +For a signal handler that is not executed as a result of a call to the +\tcode{std::raise} function, it is unspecified which thread of execution +contains the signal handler invocation. + +\rSec3[intro.races]{Data races} + +\pnum +The value of an object visible to a thread $T$ at a particular point is the +initial value of the object, a value assigned to the object by $T$, or a +value assigned to the object by another thread, according to the rules below. +\begin{note} +In some cases, there might instead be undefined behavior. Much of this +subclause is motivated by the desire to support atomic operations with explicit +and detailed visibility constraints. However, it also implicitly supports a +simpler view for more restricted programs. +\end{note} + +\pnum +Two expression evaluations \defn{conflict} if one of them +\begin{itemize} +\item +modifies\iref{defns.access} a memory location\iref{intro.memory} or +\item +starts or ends the lifetime of an object in a memory location +\end{itemize} +and the other one +\begin{itemize} +\item +reads or modifies the same memory location or +\item +starts or ends the lifetime of an object occupying storage that +overlaps with the memory location. +\end{itemize} +\begin{note} +A modification can still conflict +even if it does not alter the value of any bits. +\end{note} + +\pnum +The library defines a number of atomic operations\iref{atomics} and +operations on mutexes\iref{thread} that are specially identified as +synchronization operations. These operations play a special role in making +assignments in one thread visible to another. A synchronization operation on one +or more memory locations is either 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 +addition, there are relaxed atomic operations, which are not synchronization +operations, and atomic read-modify-write operations, which have special +characteristics. +\begin{note} +For example, a call that acquires a mutex will +perform an acquire operation on the locations comprising the mutex. +Correspondingly, a call that releases the same mutex will perform a release +operation on those same locations. Informally, performing a release operation on +$A$ forces prior +\indextext{side effects}% +side effects on other memory locations to become visible +to other threads that later perform a consume or an acquire operation on +$A$. ``Relaxed'' atomic operations are not synchronization operations even +though, like synchronization operations, they cannot contribute to data races. +\end{note} + +\pnum +All modifications to a particular atomic object $M$ occur in some +particular total order, called the \defn{modification order} of $M$. +\begin{note} +There is a separate order for each +atomic object. There is no requirement that these can be combined into a single +total order for all objects. In general this will be impossible since different +threads can observe modifications to different objects in inconsistent orders. +\end{note} + +\pnum +A \defn{release sequence} headed +by a release operation $A$ on an atomic object $M$ +is a maximal contiguous sub-sequence of +\indextext{side effects}% +side effects in the modification order of $M$, +where the first operation is $A$, and +every subsequent operation is an atomic read-modify-write operation. + +\pnum +Certain library calls \defn{synchronize with} other library calls performed by +another thread. For example, an atomic store-release synchronizes with a +load-acquire that takes its value from the store\iref{atomics.order}. +\begin{note} +Except in the specified cases, reading a later value does not +necessarily ensure visibility as described below. Such a requirement would +sometimes interfere with efficient implementation. +\end{note} +\begin{note} +The +specifications of the synchronization operations define when one reads the value +written by another. For atomic objects, the definition is clear. All operations +on a given mutex occur in a single total order. Each mutex acquisition ``reads +the value written'' by the last mutex release. +\end{note} + +\pnum +An evaluation $A$ \defn{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$ happens before $X$ and $X$ happens before $B$. +\end{itemize} +\begin{note} +An evaluation does not happen before itself. +\end{note} + +\pnum +An evaluation $A$ \defn{strongly happens before} +an evaluation $D$ if, either +\begin{itemize} +\item $A$ is sequenced before $D$, or +\item $A$ synchronizes with $D$, and +both $A$ and $D$ are +sequentially consistent atomic operations\iref{atomics.order}, or +\item there are evaluations $B$ and $C$ +such that $A$ is sequenced before $B$, +$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 +$B$ strongly happens before $D$. +\end{itemize} +\begin{note} +Informally, if $A$ strongly happens before $B$, +then $A$ appears to be evaluated before $B$ +in all contexts. +\end{note} + +\pnum +A \defnadjx{visible}{side effect}{side effects} $A$ on a scalar object or bit-field $M$ +with respect to a value computation $B$ of $M$ satisfies the +conditions: +\begin{itemize} +\item $A$ happens before $B$ and +\item there is no other +\indextext{side effects}% +side effect $X$ on $M$ such that $A$ +happens before $X$ and $X$ happens before $B$. +\end{itemize} + +The value of a non-atomic scalar object or bit-field $M$, as determined by +evaluation $B$, is the value stored by the +\indextext{side effects!visible}% +visible side effect $A$. +\begin{note} +If there is ambiguity about which side effect to a +non-atomic object or bit-field is visible, then the behavior is either +unspecified or undefined. +\end{note} +\begin{note} +This states that operations on +ordinary objects are not visibly reordered. This is not actually detectable +without data races, but is needed to ensure that data races, as defined +below, and with suitable restrictions on the use of atomics, correspond to data +races in a simple interleaved (sequentially consistent) execution. +\end{note} + +\pnum +The value of an +atomic object $M$, as determined by evaluation $B$, is the value +stored by some unspecified +side effect $A$ that modifies $M$, where $B$ does not happen +before $A$. +\begin{note} +The set of such side effects is also restricted by the rest of the rules +described here, and in particular, by the coherence requirements below. +\end{note} + +\pnum +\indextext{coherence!write-write}% +If an operation $A$ that modifies an atomic object $M$ happens before +an operation $B$ that modifies $M$, then $A$ is earlier +than $B$ in the modification order of $M$. +\begin{note} +This requirement is known as write-write coherence. +\end{note} + +\pnum +\indextext{coherence!read-read}% +If a +\indextext{value computation}% +value computation $A$ of an atomic object $M$ happens before a +value computation $B$ of $M$, and $A$ takes its value from a side +effect $X$ on $M$, then the value computed by $B$ is either +the value stored by $X$ or the value stored by a +\indextext{side effects}% +side effect $Y$ on $M$, +where $Y$ follows $X$ in the modification order of $M$. +\begin{note} +This requirement is known as read-read coherence. +\end{note} + +\pnum +\indextext{coherence!read-write}% +If a +\indextext{value computation}% +value computation $A$ of an atomic object $M$ happens before an +operation $B$ that modifies $M$, then $A$ takes its value from a side +effect $X$ on $M$, where $X$ precedes $B$ in the +modification order of $M$. +\begin{note} +This requirement is known as +read-write coherence. +\end{note} + +\pnum +\indextext{coherence!write-read}% +If a +\indextext{side effects}% +side effect $X$ on an atomic object $M$ happens before a value +computation $B$ of $M$, then the evaluation $B$ takes its +value from $X$ or from a +\indextext{side effects}% +side effect $Y$ that follows $X$ in the modification order of $M$. +\begin{note} +This requirement is known as write-read coherence. +\end{note} + +\pnum +\begin{note} +The four preceding coherence requirements effectively disallow +compiler reordering of atomic operations to a single object, even if both +operations are relaxed loads. This effectively makes the cache coherence +guarantee provided by most hardware available to \Cpp{} atomic operations. +\end{note} + +\pnum +\begin{note} +The value observed by a load of an atomic depends on the ``happens +before'' relation, which depends on the values observed by loads of atomics. +The intended reading is that there must exist an +association of atomic loads with modifications they observe that, together with +suitably chosen modification orders and the ``happens before'' relation derived +as described above, satisfy the resulting constraints as imposed here. +\end{note} + +\pnum +Two actions are \defn{potentially concurrent} if +\begin{itemize} +\item they are performed by different threads, or +\item they are unsequenced, at least one is performed by a signal handler, and +they are not both performed by the same signal handler invocation. +\end{itemize} +The execution of a program contains a \defn{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 below. +Any such data race results in undefined +behavior. +\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 +other synchronization operations behave as if the operations executed by their +constituent threads were simply interleaved, with each +\indextext{value computation}% +value computation of an +object being taken from the last +\indextext{side effects}% +side effect on that object in that +interleaving. This is normally referred to as ``sequential consistency''. +However, this applies only to data-race-free programs, and data-race-free +programs cannot observe most program transformations that do not change +single-threaded program semantics. In fact, most single-threaded program +transformations remain possible, since any program that behaves +differently as a result has undefined behavior. +\end{note} + +\pnum +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 +groups $A$ and $B$, such that no evaluations in +$B$ happen before evaluations in $A$, and the +evaluations of such \tcode{\keyword{volatile} std::sig_atomic_t} objects take values as though +all evaluations in $A$ happened before the execution of the signal +handler and the execution of the signal handler happened before all evaluations +in $B$. + +\pnum +\begin{note} +Compiler transformations that introduce assignments to a potentially +shared memory location that would not be modified by the abstract machine are +generally precluded by this document, since such an assignment might overwrite +another assignment by a different thread in cases in which an abstract machine +execution would not have encountered a data race. This includes implementations +of data member assignment that overwrite adjacent members in separate memory +locations. Reordering of atomic loads in cases in which the atomics in question +might alias is also generally precluded, since this could violate the coherence +rules. +\end{note} + +\pnum +\begin{note} +It is possible that transformations that introduce a speculative read of a potentially +shared memory location do not preserve the semantics of the \Cpp{} program as +defined in this document, since they potentially introduce a data race. However, +they are typically valid in the context of an optimizing compiler that targets a +specific machine with well-defined semantics for data races. They would be +invalid for a hypothetical machine that is not tolerant of races or provides +hardware race detection. +\end{note} + +\rSec3[intro.progress]{Forward progress} + +\pnum +The implementation may assume 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 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} +This is intended to allow compiler transformations +such as removal, merging, and reordering of empty loops, +even when termination cannot be proven. +An affordance is made for trivial infinite loops, +which cannot be removed nor reordered. +\end{note} + +\pnum +Executions of atomic functions +that are either defined to be lock-free\iref{atomics.flag} +or indicated as lock-free\iref{atomics.lockfree} +are \defnx{lock-free executions}{lock-free execution}. +\begin{itemize} +\item + If there is only one thread that is not blocked\iref{defns.block} + in a standard library function, + a lock-free execution in that thread shall complete. + \begin{note} + Concurrently executing threads + might prevent progress of a lock-free execution. + For example, + this situation can occur + with load-locked store-conditional implementations. + This property is sometimes termed obstruction-free. + \end{note} +\item + When one or more lock-free executions run concurrently, + at least one should complete. + \begin{note} + It is difficult for some implementations + to provide absolute guarantees to this effect, + since repeated and particularly inopportune interference + from other threads + could prevent forward progress, + e.g., + by repeatedly stealing a cache line + for unrelated purposes + between load-locked and store-conditional instructions. + For implementations that follow this recommendation and + ensure that such effects cannot indefinitely delay progress + under expected operating conditions, + such anomalies + can therefore safely be ignored by programmers. + Outside this document, + this property is sometimes termed lock-free. + \end{note} +\end{itemize} + +\pnum +During the execution of a thread of execution, each of the following is termed +an \defn{execution step}: +\begin{itemize} +\item termination of the thread of execution, +\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 +An invocation of a standard library function that blocks\iref{defns.block} +is considered to continuously execute execution steps while waiting for the +condition that it blocks on to be satisfied. +\begin{example} +A library I/O function that blocks until the I/O operation is complete can +be considered to continuously check whether the operation is complete. Each +such check consists of one or more execution steps, for example using +observable behavior of the abstract machine. +\end{example} + +\pnum +A thread of execution \defnx{makes progress}{make progress!thread} +when an execution step occurs or a +lock-free execution does not complete because there are other concurrent threads +that are not blocked in a standard library function (see above). + +\pnum +\indextext{forward progress guarantees!concurrent}% +For a thread of execution providing \defn{concurrent forward progress guarantees}, +the implementation ensures that the thread will eventually make progress for as +long as it has not terminated. +\begin{note} +This applies regardless of whether or not other threads of execution (if any) +have been or are making progress. To eventually fulfill this requirement means that +this will happen in an unspecified but finite amount of time. +\end{note} + +\pnum +It is \impldef{whether the thread that executes \tcode{main} and the threads created +by \tcode{std::thread} or \tcode{std::jthread} provide concurrent forward progress guarantees} whether the +implementation-created thread of execution that executes +\tcode{main}\iref{basic.start.main} and the threads of execution created by +\tcode{std::thread}\iref{thread.thread.class} +or \tcode{std::jthread}\iref{thread.jthread.class} +provide concurrent forward progress guarantees. +General-purpose implementations should provide these guarantees. + +\pnum +\indextext{forward progress guarantees!parallel}% +For a thread of execution providing \defn{parallel forward progress guarantees}, +the implementation is not required to ensure that the thread will eventually make +progress if it has not yet executed any execution step; once this thread has +executed a step, it provides concurrent forward progress guarantees. + +\pnum +\begin{note} +This does not specify a requirement for when to start this thread of execution, +which will typically be specified by the entity that creates this thread of +execution. For example, a thread of execution that provides concurrent forward +progress guarantees and executes tasks from a set of tasks in an arbitrary order, +one after the other, satisfies the requirements of parallel forward progress for +these tasks. +\end{note} + +\pnum +\indextext{forward progress guarantees!weakly parallel}% +For a thread of execution providing \defn{weakly parallel forward progress +guarantees}, the implementation does not ensure that the thread will eventually +make progress. + +\pnum +\begin{note} +Threads of execution providing weakly parallel forward progress guarantees cannot +be expected to make progress regardless of whether other threads make progress or +not; however, blocking with forward progress guarantee delegation, as defined below, +can be used to ensure that such threads of execution make progress eventually. +\end{note} + +\pnum +Concurrent forward progress guarantees are stronger than parallel forward progress +guarantees, which in turn are stronger than weakly parallel forward progress +guarantees. +\begin{note} +For example, some kinds of synchronization between threads of execution might only +make progress if the respective threads of execution provide parallel forward progress +guarantees, but will fail to make progress under weakly parallel guarantees. +\end{note} + +\pnum +\indextext{forward progress guarantees!delegation of}% +When a thread of execution $P$ is specified to +\defnx{block with forward progress guarantee delegation} +{block (execution)!with forward progress guarantee delegation} +on the completion of a set $S$ of threads of execution, +then throughout the whole time of $P$ being blocked on $S$, +the implementation shall ensure that the forward progress guarantees +provided by at least one thread of execution in $S$ +is at least as strong as $P$'s forward progress guarantees. +\begin{note} +It is unspecified which thread or threads of execution in $S$ are chosen +and for which number of execution steps. The strengthening is not permanent and +not necessarily in place for the rest of the lifetime of the affected thread of +execution. As long as $P$ is blocked, the implementation has to eventually +select and potentially strengthen a thread of execution in $S$. +\end{note} +Once a thread of execution in $S$ terminates, it is removed from $S$. +Once $S$ is empty, $P$ is unblocked. + +\pnum +\begin{note} +A thread of execution $B$ thus can temporarily provide an effectively +stronger forward progress guarantee for a certain amount of time, due to a +second thread of execution $A$ being blocked on it with forward +progress guarantee delegation. In turn, if $B$ then blocks with +forward progress guarantee delegation on $C$, this can also temporarily +provide a stronger forward progress guarantee to $C$. +\end{note} + +\pnum +\begin{note} +If all threads of execution in $S$ finish executing (e.g., they terminate +and do not use blocking synchronization incorrectly), then $P$'s execution +of the operation that blocks with forward progress guarantee delegation will not +result in $P$'s progress guarantee being effectively weakened. +\end{note} + +\pnum +\begin{note} +This does not remove any constraints regarding blocking synchronization for +threads of execution providing parallel or weakly parallel forward progress +guarantees because the implementation is not required to strengthen a particular +thread of execution whose too-weak progress guarantee is preventing overall progress. +\end{note} + +\pnum +An implementation should ensure that the last value (in modification order) +assigned by an atomic or synchronization operation will become visible to all +other threads in a finite period of time.% +\indextext{atomic!operation|)}% +\indextext{threads!multiple|)} + +\rSec2[basic.start]{Start and termination} + +\rSec3[basic.start.main]{\tcode{main} function} +\indextext{\idxcode{main} function|(} + +\pnum +\indextext{program!startup|(}% +A program shall contain exactly one function called \tcode{main} +that belongs to the global scope. +Executing a program starts a main thread of execution\iref{intro.multithread,thread.threads} +in which the \tcode{main} function is invoked. +\indextext{implementation!freestanding}% +It is \impldef{defining \tcode{main} in freestanding environment} +whether a program in a freestanding environment is required to define a \tcode{main} +function. +\begin{note} +In a freestanding environment, startup and termination is +\impldef{startup and termination in freestanding environment}; startup contains the +execution of constructors for non-local objects with static storage duration; +termination contains the execution of destructors for objects with static storage +duration. +\end{note} + +\pnum +An implementation shall not predefine the \tcode{main} function. +Its type shall have \Cpp{} language linkage +and it shall have a declared return type of type +\keyword{int}, but otherwise its type is \impldef{parameters to \tcode{main}}. +\indextext{\idxcode{main} function!implementation-defined parameters to}% +An implementation shall allow both +\begin{itemize} +\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}}% +as the type of \tcode{main}\iref{dcl.fct}. +\indextext{\idxcode{main} function!parameters to}% +\indextext{environment!program}% +In the latter form, for purposes of exposition, the first function +parameter is called \tcode{argc} and the second function parameter is +called \tcode{argv}, where \tcode{argc} shall be the number of +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 +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 +invoke the program or \tcode{""}. The value of \tcode{argc} shall be +non-negative. The value of \tcode{argv[argc]} shall be 0. + +\recommended +Any further (optional) parameters should be added after \tcode{argv}. + +\pnum +The function \tcode{main} shall not be named by an expression. +\indextext{\idxcode{main} function!implementation-defined linkage of}% +The linkage\iref{basic.link} of \tcode{main} is +\impldef{linkage of \tcode{main}}. A program that defines \tcode{main} as +deleted or that declares \tcode{main} to be +\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} other than \tcode{"C++"}. +A program that declares +\begin{itemize} +\item +a variable \tcode{main} that belongs to the global scope, or +\item +a function \tcode{main} that belongs to the global scope and +is attached to a named module, or +\item +a function template \tcode{main} that belongs to the global scope, or +\item +an entity named \tcode{main} +with C language linkage (in any namespace) +\end{itemize} +is ill-formed. +The name \tcode{main} is +not otherwise reserved. +\begin{example} +Member functions, classes, and +enumerations can be called \tcode{main}, as can entities in other +namespaces. +\end{example} + +\pnum +\indextext{\idxcode{exit}}% +\indexlibraryglobal{exit}% +\indextext{termination!program}% +Terminating the program +without leaving the current block (e.g., by calling the function +\tcode{std::exit(int)}\iref{support.start.term}) does not destroy any +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. + +\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 \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} +(see also \ref{except.handle}). +\indextext{\idxcode{main} function|)} + +\rSec3[basic.start.static]{Static initialization} + +\pnum +\indextext{initialization}% +\indextext{initialization!static and thread}% +Variables with static storage duration +are initialized as a consequence of program initiation. Variables with +thread storage duration are initialized as a consequence of thread execution. +Within each of these phases of initiation, initialization occurs as follows. + +\pnum +\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.init}. +\indextext{initialization!zero-initialization}% +If constant initialization is not performed, a variable with static +storage duration\iref{basic.stc.static} or thread storage +duration\iref{basic.stc.thread} is zero-initialized\iref{dcl.init}. +Together, zero-initialization and constant initialization are called +\defnadj{static}{initialization}; +all other initialization is \defnadj{dynamic}{initialization}. +All static initialization strongly happens before\iref{intro.races} +any dynamic initialization. +\begin{note} +The dynamic initialization of non-block variables is described +in~\ref{basic.start.dynamic}; that of static block variables is described +in~\ref{stmt.dcl}. +\end{note} + +\pnum +An implementation is permitted to perform the initialization of a +variable with static or thread storage duration as a static +initialization even if such initialization is not required to be done +statically, provided that +\begin{itemize} +\item +the dynamic version of the initialization does not change the +value of any other object of static or thread storage duration +prior to its initialization, and + +\item +the static version of the initialization produces the same value +in the initialized variable as would be produced by the dynamic +initialization if all variables not required to be initialized statically +were initialized dynamically. +\end{itemize} +\begin{note} +As a consequence, if the initialization of an object \tcode{obj1} refers to an +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: +\begin{codeblock} +inline double fd() { return 1.0; } +extern double d1; +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} + +\pnum +\indextext{initialization!dynamic non-block}% +\indextext{start!program}% +\indextext{initialization!order of}% +Dynamic initialization of a non-block variable with static storage duration is +unordered if the variable is an implicitly or explicitly instantiated +specialization, is partially-ordered if the variable +is an inline variable that is not an implicitly or explicitly instantiated +specialization, and otherwise is ordered. +\begin{note} +A non-inline explicit specialization of a templated variable +has ordered initialization. +\end{note} + +\pnum +A declaration \tcode{D} is +\defn{appearance-ordered} before a declaration \tcode{E} if +\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\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 is ordered as follows: +\begin{itemize} +\item +If \tcode{V} and \tcode{W} have ordered initialization and +the definition of \tcode{V} +is appearance-ordered before the definition of \tcode{W}, or +if \tcode{V} has partially-ordered initialization, +\tcode{W} does not have unordered initialization, and +for every definition \tcode{E} of \tcode{W} +there exists a definition \tcode{D} of \tcode{V} +such that \tcode{D} is appearance-ordered before \tcode{E}, then +\begin{itemize} +\item +if the program does not start a thread\iref{intro.multithread} +other than the main thread\iref{basic.start.main} +or \tcode{V} and \tcode{W} have ordered initialization and +they are defined in the same translation unit, +the initialization of \tcode{V} +is sequenced before +the initialization of \tcode{W}; +\item +otherwise, +the initialization of \tcode{V} +strongly happens before +the initialization of \tcode{W}. +\end{itemize} + +\item +Otherwise, if the program starts a thread +other than the main thread +before either \tcode{V} or \tcode{W} is initialized, +it is unspecified in which threads +the initializations of \tcode{V} and \tcode{W} occur; +the initializations are unsequenced if they occur in the same thread. + +\item +Otherwise, the initializations of \tcode{V} and \tcode{W} are indeterminately sequenced. +\end{itemize} +\begin{note} +This definition permits initialization of a sequence of +ordered variables concurrently with another sequence. +\end{note} + +\pnum +\indextext{non-initialization odr-use|see{odr-use, non-initialization}}% +A \defnx{non-initialization odr-use}{odr-use!non-initialization} +is an odr-use\iref{term.odr.use} not caused directly or indirectly by +the initialization of a non-block static or thread storage duration variable. + +\pnum +\indextext{evaluation!unspecified order of}% +It is \impldef{dynamic initialization of static variables before \tcode{main}} +whether the dynamic initialization of a +non-block non-inline variable with static storage duration +is sequenced before the first statement of \tcode{main} or is deferred. +If it is deferred, it strongly happens before +any non-initialization odr-use +of any non-inline function or non-inline variable +defined in the same translation unit as the variable to be initialized. +\begin{footnote} +A non-block variable with static storage duration +having initialization +with side effects is initialized in this case, +even if it is not itself odr-used\iref{term.odr.use,basic.stc.static}. +\end{footnote} +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. + +\recommended +An implementation should choose such points in a way +that allows the programmer to avoid deadlocks. +\begin{example} +\begin{codeblock} +// - File 1 - +#include "a.h" +#include "b.h" +B b; +A::A() { + b.Use(); +} + +// - File 2 - +#include "a.h" +A a; + +// - File 3 - +#include "a.h" +#include "b.h" +extern A a; +extern B b; + +int main() { + a.Use(); + b.Use(); +} +\end{codeblock} + +It is \impldef{dynamic initialization of static variables before \tcode{main}} +whether either \tcode{a} or \tcode{b} is +initialized before \tcode{main} is entered or whether the +initializations are delayed until \tcode{a} is first odr-used in +\tcode{main}. In particular, if \tcode{a} is initialized before +\tcode{main} is entered, it is not guaranteed that \tcode{b} will be +initialized before it is odr-used by the initialization of \tcode{a}, that +is, before \tcode{A::A} is called. If, however, \tcode{a} is initialized +at some point after the first statement of \tcode{main}, \tcode{b} will +be initialized prior to its use in \tcode{A::A}. +\end{example} + +\pnum +It is \impldef{dynamic initialization of static inline variables before \tcode{main}} +whether the dynamic initialization of a +non-block inline variable with static storage duration +is sequenced before the first statement of \tcode{main} or is deferred. +If it is deferred, it strongly happens before +any non-initialization odr-use +of that variable. +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. + +\pnum +It is \impldef{dynamic initialization of thread-local variables before entry} +whether the dynamic initialization of a +non-block non-inline variable with thread storage duration +is sequenced before the first statement of the initial function of a thread or is deferred. +If it is deferred, +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 +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. + +\pnum +If the initialization of +a non-block variable with static or thread storage duration +exits via an exception, +the function \tcode{std::terminate} is called\iref{except.terminate}.% +\indextext{program!startup|)} + +\rSec3[basic.start.term]{Termination} + +\pnum +\indextext{program!termination|(}% +\indextext{object!destructor static}% +\indextext{\idxcode{main} function!return from}% +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 +\indextext{\idxcode{exit}}% +\indexlibraryglobal{exit}% +\tcode{std::exit}\iref{support.start.term}. +The call to \tcode{std::exit} is sequenced before +the destructions and the registered functions. +\begin{note} +Returning from \tcode{main} invokes \tcode{std::exit}\iref{basic.start.main}. +\end{note} + +\pnum +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 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 +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. +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 +passes through the definition of the previously destroyed block variable. +\begin{note} +Likewise, the behavior is undefined +if the block variable is used indirectly (e.g., through a pointer) +after its destruction. +\end{note} + +\pnum +\indextext{\idxcode{atexit}}% +\indexlibraryglobal{atexit}% +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 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 +the call to the function passed to the first \tcode{std::atexit} call. + +\pnum +If there is a use of a standard library object or function not permitted within signal +handlers\iref{support.runtime} that does not happen before\iref{intro.multithread} +completion of destruction of objects with static storage duration and execution of +\tcode{std::atexit} registered functions\iref{support.start.term}, the program has +undefined behavior. +\begin{note} +If there is a use of an object with static storage +duration that does not happen before the object's destruction, the program has undefined +behavior. Terminating every thread before a call to \tcode{std::exit} or the exit from +\tcode{main} is sufficient, but not necessary, to satisfy these requirements. These +requirements permit thread managers as static-storage-duration objects. +\end{note} + +\pnum +\indextext{\idxcode{abort}}% +\indexlibraryglobal{abort}% +\indextext{termination!program}% +Calling the function \tcode{std::abort()} declared in +\libheaderref{cstdlib} terminates the program without executing any destructors +and without calling +the functions passed to \tcode{std::atexit()} or \tcode{std::at_quick_exit()}.% +\indextext{program!termination|)} +\indextext{program execution|)} + +\rSec1[basic.contract]{Contract assertions}% +\indextext{contract assertion|(}% + +\rSec2[basic.contract.general]{General}% + +\pnum +\defnx{Contract assertions}{contract assertion} +allow the programmer to specify +properties of the state of the program +that are expected to hold at +certain points during execution. +Contract assertions are introduced by +\grammarterm{precondition-specifier}s, +\grammarterm{postcondition-specifier}s\iref{dcl.contract.func}, and +\grammarterm{assertion-statement}s\iref{stmt.contract.assert}. + +\pnum +Each contract assertion has a \defnadjx{contract-assertion}{predicate}{predicate}, +which is an expression of type \tcode{bool}. + +\begin{note} +The value of the predicate is used to identify program states that are +expected. +\end{note} + +\pnum +An invocation of the macro \tcode{va_start}\iref{cstdarg.syn} +shall not be a subexpression +of the predicate of a contract assertion, +no diagnostic required. + +\pnum +\begin{note} +Within the predicate of a contract assertion, +\grammarterm{id-expression}s referring to +variables declared outside the contract assertion +are \keyword{const}\iref{expr.prim.id.unqual}, +\tcode{this} is a pointer to \keyword{const}\iref{expr.prim.this}, +and the result object can be named +if a \grammarterm{result-name-introducer}\iref{dcl.contract.res} has been specified. +\end{note} + +\rSec2[basic.contract.eval]{Evaluation} + +\pnum +\indexdefn{evaluation semantics|see{contract evaluation semantics}}% +\indexdefn{checking semantics|see{contract evaluation semantics!checking}}% +\indexdefn{terminating semantics|see{contract evaluation semantics!terminating}}% +An evaluation of a contract assertion +uses one of the following four \defn{evaluation semantics}: +\defnx{ignore}{contract evaluation semantics!ignore}, +\defnx{observe}{contract evaluation semantics!observe}, +\defnx{enforce}{contract evaluation semantics!enforce}, or +\defnx{quick-enforce}{contract evaluation semantics!quick-enforce}. +Observe, enforce, and quick-enforce are \defnx{checking semantics}{contract evaluation semantics!checking}; +enforce and quick-enforce are \defnx{terminating semantics}{contract evaluation semantics!terminating}. + +\pnum +It is +\impldef{evaluation semantic used for the evaluation of a contract assertion} +which evaluation semantic is used +for any given evaluation of a contract assertion. +\begin{note} +The range and flexibility of available choices of +evaluation semantics depends on the implementation +and need not allow all four evaluation semantics as possibilities. +The evaluation semantics can differ +for different evaluations of the same contract assertion, +including evaluations during constant evaluation. +\end{note} + +\pnum +\recommended +An implementation should provide +the option to translate a program +such that all evaluations of contract assertions use the ignore semantic +as well as +the option to translate a program +such that all evaluations of contract assertions use the enforce semantic. +By default, +evaluations of contract assertions should use the enforce semantic. + +\pnum +The evaluation of a contract assertion using the ignore semantic has no effect. +\begin{note} +The predicate is potentially evaluated\iref{basic.def.odr}, +but not evaluated. +\end{note} + +\pnum +The evaluation $A$ of a contract assertion +using a checking semantic +determines the value of the predicate. +It is unspecified +whether the predicate is evaluated. +Let $B$ be the value that would result from evaluating the predicate. +\begin{note} +To determine whether a predicate would evaluate +to \keyword{true} or \keyword{false}, +an alternative evaluation +that produces the same value as the predicate +but has no side effects +can occur. +\begin{example} +\begin{codeblock} +struct S { + mutable int g = 5; +} s; +void f() + pre(( s.g++, false )); // \#1 +void g() +{ + f(); // Increment of \tcode{s.g} might not occur, even if \#1 uses a checking semantic. +} +\end{codeblock} +\end{example} +\end{note} + +\pnum +There is an observable checkpoint\iref{intro.abstract} $C$ +that happens before $A$ +such that any other 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. + +\indextext{contract assertion|)} diff --git a/source/charname.tex b/source/charname.tex deleted file mode 100644 index e071c9e78b..0000000000 --- a/source/charname.tex +++ /dev/null @@ -1,30 +0,0 @@ -%!TEX root = std.tex -\normannex{charname}{Universal character names for identifier characters} - -\rSec1[charname.allowed]{Ranges of characters allowed} - -\begin{codeblock} -00A8, 00AA, 00AD, 00AF, 00B2-00B5, 00B7-00BA, 00BC-00BE, 00C0-00D6, 00D8-00F6, 00F8-00FF - -0100-167F, 1681-180D, 180F-1FFF - -200B-200D, 202A-202E, 203F-2040, 2054, 2060-206F - -2070-218F, 2460-24FF, 2776-2793, 2C00-2DFF, 2E80-2FFF - -3004-3007, 3021-302F, 3031-303F - -3040-D7FF - -F900-FD3D, FD40-FDCF, FDF0-FE44, FE47-FFFD - -10000-1FFFD, 20000-2FFFD, 30000-3FFFD, 40000-4FFFD, 50000-5FFFD, - 60000-6FFFD, 70000-7FFFD, 80000-8FFFD, 90000-9FFFD, A0000-AFFFD, - B0000-BFFFD, C0000-CFFFD, D0000-DFFFD, E0000-EFFFD -\end{codeblock} - -\rSec1[charname.disallowed]{Ranges of characters disallowed initially} - -\begin{codeblock} -0300-036F, 1DC0-1DFF, 20D0-20FF, FE20-FE2F -\end{codeblock} diff --git a/source/classes.tex b/source/classes.tex index 9d34a609da..78a504f0a5 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -2,19 +2,20 @@ \rSec0[class]{Classes}% \indextext{class|(} -%gram: \rSec1[gram.class]{Classes} -%gram: +\gramSec[gram.class]{Classes} \indextext{class!member function|see{member function, class}} +\rSec1[class.pre]{Preamble} + \pnum \indextext{\idxcode{\{\}}!class declaration}% \indextext{\idxcode{\{\}}!class definition}% -\indextext{type!class~and}% -\indextext{object~class|see{also~class~object}}% +\indextext{type!class and}% +\indextext{object class|see{class object}}% A class is a type. -\indextext{name~class|see{class~name}}% -Its name becomes a \grammarterm{class-name}~(\ref{class.name}) within its +\indextext{name class|see{class name}}% +Its name becomes a \grammarterm{class-name}\iref{class.name} within its scope. \begin{bnf} @@ -23,56 +24,67 @@ simple-template-id \end{bnf} -\grammarterm{Class-specifier}{s} and -\grammarterm{elaborated-type-specifier}{s}~(\ref{dcl.type.elab}) are used to -make \grammarterm{class-name}{s}. An object of a class consists of a +A \grammarterm{class-specifier} or +an \grammarterm{elaborated-type-specifier}\iref{dcl.type.elab} is used to +make a \grammarterm{class-name}. An object of a class consists of a (possibly empty) sequence of members and base class objects. \begin{bnf} \nontermdef{class-specifier}\br - class-head \terminal{\{} member-specification\opt \terminal{\}} + class-head \terminal{\{} \opt{member-specification} \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{class-head}\br - class-key attribute-specifier-seq\opt class-head-name class-virt-specifier\opt base-clause\opt\br - class-key attribute-specifier-seq\opt base-clause\opt + 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} \begin{bnf} \nontermdef{class-head-name}\br - nested-name-specifier\opt class-name + \opt{nested-name-specifier} class-name +\end{bnf} + +\begin{bnf} +\nontermdef{class-property-specifier-seq}\br + class-property-specifier \opt{class-property-specifier-seq} \end{bnf} \begin{bnf} -\nontermdef{class-virt-specifier}\br - \terminal{final} +\nontermdef{class-property-specifier}\br + \keyword{final} \end{bnf} \begin{bnf} \nontermdef{class-key}\br - \terminal{class}\br - \terminal{struct}\br - \terminal{union} + \keyword{class}\br + \keyword{struct}\br + \keyword{union} \end{bnf} +A class declaration where the \grammarterm{class-name} +in the \grammarterm{class-head-name} is a \grammarterm{simple-template-id} +shall be an explicit specialization\iref{temp.expl.spec} or +a partial specialization\iref{temp.spec.partial}. A \grammarterm{class-specifier} whose \grammarterm{class-head} omits the -\grammarterm{class-head-name} defines an unnamed class. \enternote An unnamed class thus can't -be \tcode{final}. \exitnote +\grammarterm{class-head-name} defines an \defnadj{unnamed}{class}. +\begin{note} +An unnamed class thus can't +be \tcode{final}. +\end{note} +Otherwise, the \grammarterm{class-name} is an \grammarterm{identifier}; +it is not looked up, and the \grammarterm{class-specifier} introduces it. \pnum -A \grammarterm{class-name} is inserted into the scope in which it is -declared immediately after the \grammarterm{class-name} is seen. The -\grammarterm{class-name} is also inserted into the scope of the class -itself; this is known as the \grammarterm{injected-class-name}. -\indextext{\idxgram{injected-class-name}}% +\indextext{component name}% +The component name of the +\grammarterm{class-name} is also bound in the scope of the class (template) +itself; this is known as the \defn{injected-class-name}. For purposes of access checking, the injected-class-name is treated as if it were a public member name. -\indextext{definition!class}% -A \grammarterm{class-specifier} is commonly referred to as a class -definition. -\indextext{definition!class}% +A \grammarterm{class-specifier} is commonly referred to as a \defnx{class +definition}{definition!class}. A class is considered defined after the closing brace of its \grammarterm{class-specifier} has been seen even though its member functions are in general not yet defined. @@ -81,77 +93,105 @@ whenever it is named. \pnum -If a class is marked with the \grammarterm{class-virt-specifier} \tcode{final} and it appears -as a \grammarterm{base-type-specifier} in a \grammarterm{base-clause} -(Clause~\ref{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}. \enterexample +If a \grammarterm{class-head-name} contains a \grammarterm{nested-name-specifier}, +the \grammarterm{class-specifier} shall not inhabit a class scope. +If its \grammarterm{class-name} is an \grammarterm{identifier}, +the \grammarterm{class-specifier} shall correspond to +one or more declarations nominable in +the class, class template, or namespace to which the +\grammarterm{nested-name-specifier} refers; +they shall all have the same target scope, and the target scope of the +\grammarterm{class-specifier} is that scope. +\begin{example} +\begin{codeblock} +namespace N { + template + struct A { + struct B; + }; +} +using N::A; +template struct A::B {}; // OK +template<> struct A {}; // OK +\end{codeblock} +\end{example} + +\pnum +\begin{note} +The \grammarterm{class-key} determines +whether the class is a union\iref{class.union} and +whether access is public or private by default\iref{class.access}. +A union holds the value of at most one data member at a time. +\end{note} + +\pnum +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; -struct A final {}; // OK: definition of \tcode{struct A}, +struct A final {}; // OK, definition of \tcode{struct A}, // not value-initialization of variable \tcode{final} struct X { struct C { constexpr operator int() { return 5; } }; - struct B final : C{}; // OK: definition of nested class \tcode{B}, + struct B final : C{}; // OK, definition of nested class \tcode{B}, // not declaration of a bit-field member \tcode{final} }; \end{codeblock} -\exitexample +\end{example} \pnum -Complete objects and member subobjects of class type shall have nonzero -size.\footnote{Base class subobjects are not so constrained.} -\enternote -Class objects can be assigned, passed as arguments to functions, and -returned by functions (except objects of classes for which copying or moving has -been restricted; see~\ref{class.copy}). Other plausible operators, such -as equality comparison, can be defined by the user; see~\ref{over.oper}. -\exitnote - -\pnum -\indextext{\idxcode{struct}!\tcode{class}~versus}% -\indextext{structure}% -\indextext{\idxcode{union}!\tcode{class}~versus}% -A \term{union} is a class defined with the \grammarterm{class-key} -\tcode{union}; -\indextext{access control!\idxcode{union} default member}% -it holds at most one data member at a time~(\ref{class.union}). -\enternote -Aggregates of class type are described in~\ref{dcl.init.aggr}. -\exitnote +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. +Base class subobjects and +members declared with the \tcode{no_unique_address} attribute\iref{dcl.attr.nouniqueaddr} +are not so constrained. +\end{note} -\indextext{class!trivial}% -\indextext{trivial~class}% \pnum -A \defn{trivially copyable class} is a class that: +\begin{note} +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}). +Other plausible operators, such as equality comparison, +can be defined by the user; see~\ref{over.oper}. +\end{note} + +\rSec1[class.prop]{Properties of classes} +\pnum +A \defnadj{trivially copyable}{class} is a class: \begin{itemize} -\item has no non-trivial copy constructors~(\ref{class.copy}), -\item has no non-trivial move constructors~(\ref{class.copy}), -\item has no non-trivial copy assignment operators~(\ref{over.ass},~\ref{class.copy}), -\item has no non-trivial move assignment operators~(\ref{over.ass},~\ref{class.copy}), and -\item has a trivial destructor~(\ref{class.dtor}). +\item that has at least one eligible +copy constructor, move constructor, +copy assignment operator, or +move assignment operator\iref{special,class.copy.ctor,class.copy.assign}, +\item where each eligible copy constructor, move constructor, copy assignment operator, +and move assignment operator is trivial, and +\item that has a trivial, non-deleted destructor\iref{class.dtor}. \end{itemize} -A \term{trivial class} is a class that has a default -constructor~(\ref{class.ctor}), has no non-trivial default constructors, and is trivially copyable. -\enternote In particular, a trivially copyable or trivial class does not have -virtual functions or virtual base classes.\exitnote - -\indextext{class!standard-layout}% -\indextext{standard-layout~class}% \pnum -A class \tcode{S} is a \grammarterm{standard-layout class} if it: +A class \tcode{S} is a \defnadj{standard-layout}{class} if it: \begin{itemize} \item has no non-static data members of type non-standard-layout class (or array of such types) or reference, -\item has no virtual functions~(\ref{class.virtual}) and no -virtual base classes~(\ref{class.mi}), +\item has no virtual functions\iref{class.virtual} and no +virtual base classes\iref{class.mi}, -\item has the same access control (Clause~\ref{class.access}) +\item has the same access control\iref{class.access} for all non-static data members, \item has no non-standard-layout base classes, @@ -161,126 +201,126 @@ \item has all non-static data members and bit-fields in the class and its base classes first declared in the same class, and -\item has no element of the set $M(\mathtt{S})$ of types (defined below) -as a base class.\footnote{This ensures that two subobjects that have the -same class type and that +\item has no element of the set $M(\mathtt{S})$ of types +as a base class, +where for any type \tcode{X}, $M(\mathtt{X})$ is defined as follows. +\begin{footnote} + +This ensures that two subobjects that have the same class type and that belong to the same most derived object are not allocated at the same -address~(\ref{expr.eq}).} -\end{itemize} +address\iref{expr.eq}. +\end{footnote} +\begin{note} +$M(\mathtt{X})$ is the set of the types of all non-base-class subobjects +that can be at a zero offset in \tcode{X}. +\end{note} -$M(\mathtt{X})$ is defined as follows: \begin{itemize} -\item If \tcode{X} is a non-union class type, the set $M(\mathtt{X})$ is -empty if \tcode{X} has no (possibly inherited (Clause~\ref{class.derived})) -non-static data members; -otherwise, it consists of the type of the first non-static data member -of \tcode{X} (where said member may be an anonymous union), $\mathtt{X}_0$, -and the elements of $M(\mathtt{X}_0)$. +\item If \tcode{X} is a non-union class type with no non-static data members, +the set $M(\mathtt{X})$ is empty. + +\item If \tcode{X} is a non-union class type with a non-static data +member of type $\mathtt{X}_0$ +that is either of zero size or +is the first non-static data member of \tcode{X} +(where said member may be an anonymous union), +the set $M(\mathtt{X})$ consists of $\mathtt{X}_0$ and the elements of +$M(\mathtt{X}_0)$. \item If \tcode{X} is a union type, the set $M(\mathtt{X})$ is the union of all $M(\mathtt{U}_i)$ and the set containing all $\mathtt{U}_i$, -where each $\mathtt{U}_i$ is the type of the $i$th non-static data member +where each $\mathtt{U}_i$ is the type of the $i^\text{th}$ non-static data member of \tcode{X}. -\item If \tcode{X} is a non-class type, the set $M(\mathtt{X})$ is empty. -\end{itemize} +\item If \tcode{X} is an array type with element type $\mathtt{X}_e$, +the set $M(\mathtt{X})$ consists of $\mathtt{X}_e$ +and the elements of $M(\mathtt{X}_e)$. -\enternote $M(\mathtt{X})$ is the set of the types of all non-base-class subobjects -that are guaranteed in a standard-layout class to be at a zero offset -in \tcode{X}. \exitnote +\item If \tcode{X} is a non-class, non-array type, the set $M(\mathtt{X})$ is empty. +\end{itemize} +\end{itemize} -\enterexample +\pnum +\begin{example} \begin{codeblock} - struct B { int i; }; // standard-layout class - struct C : B { }; // standard-layout class - struct D : C { }; // standard-layout class - struct E : D { char : 4; }; // not a standard-layout class - - struct Q {}; - struct S : Q { }; - struct T : Q { }; - struct U : S, T { }; // not a standard-layout class +struct B { int i; }; // standard-layout class +struct C : B { }; // standard-layout class +struct D : C { }; // standard-layout class +struct E : D { char : 4; }; // not a standard-layout class + +struct Q {}; +struct S : Q { }; +struct T : Q { }; +struct U : S, T { }; // not a standard-layout class \end{codeblock} -\exitexample +\end{example} -\indextext{struct!standard-layout}% -\indextext{standard-layout~struct}% -\indextext{union!standard-layout}% -\indextext{standard-layout~union}% \pnum -A \grammarterm{standard-layout struct} is a standard-layout class -defined with the \grammarterm{class-key} \tcode{struct} or the -\grammarterm{class-key} \tcode{class}. -A \grammarterm{standard-layout union} is a standard-layout class +A \defnadj{standard-layout}{struct} is a standard-layout class +defined with the \grammarterm{class-key} \keyword{struct} or the +\grammarterm{class-key} \keyword{class}. +A \defnadj{standard-layout}{union} is a standard-layout class defined with the -\grammarterm{class-key} \tcode{union}. +\grammarterm{class-key} \keyword{union}. \pnum -\enternote Standard-layout classes are useful for communicating with +\begin{note} +Standard-layout classes are useful for communicating with code written in other programming languages. Their layout is specified -in~\ref{class.mem}.\exitnote +in~\ref{class.mem.general} and~\ref{expr.rel}. +\end{note} \pnum -\indextext{POD struct}\indextext{POD class}\indextext{POD union}% -A \term{POD struct}\footnote{The acronym POD stands for ``plain old data''.} -is a non-union class that is both a trivial class and a -standard-layout class, and has no non-static data members of type non-POD struct, -non-POD union (or array of such types). Similarly, a -\term{POD union} is a union that is both a trivial class and a standard-layout -class, and has no non-static data members of type non-POD struct, non-POD -union (or array of such types). A \term{POD class} is a -class that is either a POD struct or a POD union. - -\enterexample +\begin{example} \begin{codeblock} -struct N { // neither trivial nor standard-layout +struct N { // neither trivially copyable nor standard-layout int i; int j; virtual ~N(); }; -struct T { // trivial but not standard-layout +struct T { // trivially copyable but not standard-layout int i; -private: +private: int j; }; -struct SL { // standard-layout but not trivial +struct SL { // standard-layout but not trivially copyable int i; int j; ~SL(); }; -struct POD { // both trivial and standard-layout +struct POD { // both trivially copyable and standard-layout int i; int j; }; \end{codeblock} -\exitexample +\end{example} \pnum -If a \grammarterm{class-head-name} contains a \grammarterm{nested-name-specifier}, -the \grammarterm{class-specifier} shall refer to a class that was -previously declared directly in the class or namespace to which the -\grammarterm{nested-name-specifier} refers, -or in an element of the inline namespace set~(\ref{namespace.def}) of that namespace -(i.e., not merely inherited or -introduced by a \grammarterm{using-declaration}), and the -\grammarterm{class-specifier} shall appear in a namespace enclosing the -previous declaration. -In such cases, the \grammarterm{nested-name-specifier} of the -\grammarterm{class-head-name} of the -definition shall not begin with a \grammarterm{decltype-specifier}. +\begin{note} +Aggregates of class type are described in~\ref{dcl.init.aggr}. +\end{note} + +\pnum +A class \tcode{S} is an \defnadj{implicit-lifetime}{class} if +\begin{itemize} +\item +it is an aggregate whose destructor is not user-provided or +\item +it has at least one trivial eligible constructor and +a trivial, non-deleted destructor. +\end{itemize} \rSec1[class.name]{Class names} -\indextext{definition!class~name~as type}% -\indextext{structure~tag|see{class~name}}% +\indextext{definition!class name as type}% +\indextext{structure tag|see{class name}}% \indextext{equivalence!type}% \pnum A class definition introduces a new type. -\enterexample - +\begin{example} \begin{codeblock} struct X { int a; }; struct Y { int a; }; @@ -288,89 +328,67 @@ Y a2; int a3; \end{codeblock} - declares three variables of three different types. This implies that - \begin{codeblock} a1 = a2; // error: \tcode{Y} assigned to \tcode{X} a1 = a3; // error: \tcode{int} assigned to \tcode{X} \end{codeblock} - are type mismatches, and that - \begin{codeblock} int f(X); int f(Y); \end{codeblock} - \indextext{overloading}% -declare an overloaded (Clause~\ref{over}) function \tcode{f()} and not -simply a single function \tcode{f()} twice. For the same reason, - +declare overloads\iref{over} named \tcode{f} and not +simply a single function \tcode{f} twice. For the same reason, \begin{codeblock} struct S { int a; }; -struct S { int a; }; // error, double definition +struct S { int a; }; // error: double definition \end{codeblock} - is ill-formed because it defines \tcode{S} twice. -\exitexample +\end{example} \pnum -\indextext{definition!scope~of class}% -\indextext{class~name!scope~of}% -A class declaration introduces the class name into the scope where -\indextext{name~hiding!class definition}% -it is declared and hides any -class, variable, function, or other declaration of that name in an -enclosing scope~(\ref{basic.scope}). If a class name is declared in a -scope where a variable, function, or enumerator of the same name is also -declared, then when both declarations are in scope, the class can be -referred to only using an -\grammarterm{elaborated-type-specifier}~(\ref{basic.lookup.elab}). -\enterexample - +\indextext{definition!scope of class}% +\begin{note} +It can be necessary to use an \grammarterm{elaborated-type-specifier} +to refer to a class +that belongs to a scope in which its name is also bound to +a variable, function, or enumerator\iref{basic.lookup.elab}. +\begin{example} \begin{codeblock} struct stat { // ... }; -stat gstat; // use plain \tcode{stat} to - // define variable +stat gstat; // use plain \tcode{stat} to define variable -int stat(struct stat*); // redeclare \tcode{stat} as function +int stat(struct stat*); // \tcode{stat} now also names a function void f() { - struct stat* ps; // \tcode{struct} prefix needed - // to name \tcode{struct stat} - stat(ps); // call \tcode{stat()} + struct stat* ps; // \keyword{struct} prefix needed to name \tcode{struct stat} + stat(ps); // call \tcode{stat} function } \end{codeblock} -\exitexample -\indextext{class~name!elaborated}% +\end{example} +\indextext{class name!elaborated}% \indextext{declaration!forward class}% -A \grammarterm{declaration} consisting solely of \grammarterm{class-key -identifier;} is either a redeclaration of the name in the current scope -or a forward declaration of the identifier as a class name. It -introduces the class name into the current scope. -\enterexample - +An \grammarterm{elaborated-type-specifier} can also be used to declare +an \grammarterm{identifier} as a \grammarterm{class-name}. +\begin{example} \begin{codeblock} struct s { int a; }; void g() { - struct s; // hide global \tcode{struct s} - // with a block-scope declaration + struct s; // hide global \tcode{struct s} with a block-scope declaration s* p; // refer to local \tcode{struct s} struct s { char* p; }; // define local \tcode{struct s} struct s; // redeclaration, has no effect } \end{codeblock} -\exitexample -\enternote +\end{example} Such declarations allow definition of classes that refer to each other. -\indextext{example!friend}% -\enterexample - +\begin{example} \begin{codeblock} class Vector; @@ -384,23 +402,21 @@ friend Vector operator*(const Matrix&, const Vector&); }; \end{codeblock} - -Declaration of \tcode{friend}s is described in~\ref{class.friend}, +Declaration of friends is described in~\ref{class.friend}, operator functions in~\ref{over.oper}. -\exitexample -\exitnote +\end{example} +\end{note} \pnum -\indextext{class~name!elaborated}% -\indextext{elaborated~type~specifier|see{class name, elaborated}}% -\enternote -An \grammarterm{elaborated-type-specifier}~(\ref{dcl.type.elab}) can also +\indextext{class name!elaborated}% +\indextext{elaborated type specifier|see{class name, elaborated}}% +\begin{note} +An \grammarterm{elaborated-type-specifier}\iref{dcl.type.elab} can also be used as a \grammarterm{type-specifier} as part of a declaration. It -differs from a class declaration in that if a class of the elaborated -name is in scope the elaborated name will refer to it. -\exitnote -\enterexample - +differs from a class declaration in that it can refer to +an existing class of the given name. +\end{note} +\begin{example} \begin{codeblock} struct s { int a; }; @@ -409,52 +425,56 @@ p->a = s; // parameter \tcode{s} } \end{codeblock} -\exitexample +\end{example} \pnum -\indextext{class~name!point~of declaration}% -\enternote +\indextext{class name!point of declaration}% +\begin{note} The declaration of a class name takes effect immediately after the \grammarterm{identifier} is seen in the class definition or -\grammarterm{elaborated-type-specifier}. For example, - +\grammarterm{elaborated-type-specifier}. +\begin{example} \begin{codeblock} class A * A; \end{codeblock} - first specifies \tcode{A} to be the name of a class and then redefines it as the name of a pointer to an object of that class. This means that -the elaborated form \tcode{class} \tcode{A} must be used to refer to the +the elaborated form \keyword{class} \tcode{A} must be used to refer to the class. Such artistry with names can be confusing and is best avoided. -\exitnote +\end{example} +\end{note} \pnum -\indextext{class~name!\idxcode{typedef}}% -A \grammarterm{typedef-name}~(\ref{dcl.typedef}) that names a class type, -or a cv-qualified version thereof, is also a \grammarterm{class-name}. If a -\grammarterm{typedef-name} that names a cv-qualified class type is used -where a \grammarterm{class-name} is required, the cv-qualifiers are -ignored. A \grammarterm{typedef-name} shall not be used as the -\grammarterm{identifier} in a \grammarterm{class-head}. +\indextext{class name!\idxcode{typedef}}% +A \grammarterm{simple-template-id} is only a \grammarterm{class-name} +if its \grammarterm{template-name} names a class template. \rSec1[class.mem]{Class members}% + +\rSec2[class.mem.general]{General}% \indextext{declaration!member}% -\indextext{data~member|see{member}} +\indextext{data member|see{member}} \begin{bnf} \nontermdef{member-specification}\br - member-declaration member-specification\opt\br - access-specifier \terminal{:} member-specification\opt + member-declaration \opt{member-specification}\br + access-specifier \terminal{:} \opt{member-specification} \end{bnf} \begin{bnf} \nontermdef{member-declaration}\br - attribute-specifier-seq\opt decl-specifier-seq\opt member-declarator-list\opt \terminal{;}\br + \opt{attribute-specifier-seq} \opt{decl-specifier-seq} \opt{member-declarator-list} \terminal{;}\br function-definition\br + friend-type-declaration\br using-declaration\br + using-enum-declaration\br static_assert-declaration\br + consteval-block-declaration\br template-declaration\br + explicit-specialization\br + deduction-guide\br alias-declaration\br + opaque-enum-declaration\br empty-declaration \end{bnf} @@ -466,90 +486,250 @@ \begin{bnf} \nontermdef{member-declarator}\br - declarator virt-specifier-seq\opt pure-specifier\opt\br - declarator brace-or-equal-initializer\opt\br - identifier\opt attribute-specifier-seq\opt \terminal{:} constant-expression + declarator \opt{virt-specifier-seq} \opt{function-contract-specifier-seq} \opt{pure-specifier}\br + declarator requires-clause \opt{function-contract-specifier-seq}\br + declarator brace-or-equal-initializer\br + \opt{identifier} \opt{attribute-specifier-seq} \terminal{:} constant-expression \opt{brace-or-equal-initializer} \end{bnf} \begin{bnf} \nontermdef{virt-specifier-seq}\br - virt-specifier\br - virt-specifier-seq virt-specifier + virt-specifier \opt{virt-specifier-seq} \end{bnf} \begin{bnf} \nontermdef{virt-specifier}\br - \terminal{override}\br - \terminal{final} + \keyword{override}\br + \keyword{final} \end{bnf} \begin{bnf} \nontermdef{pure-specifier}\br - \terminal{= 0} + \terminal{=} \terminal{0} +\end{bnf} + +\begin{bnf} +\nontermdef{friend-type-declaration}\br + \keyword{friend} friend-type-specifier-list \terminal{;} +\end{bnf} + +\begin{bnf} +\nontermdef{friend-type-specifier-list}\br + friend-type-specifier \opt{\terminal{...}}\br + friend-type-specifier-list \terminal{,} friend-type-specifier \opt{\terminal{...}} +\end{bnf} + +\begin{bnf} +\nontermdef{friend-type-specifier}\br + simple-type-specifier\br + elaborated-type-specifier\br + typename-specifier \end{bnf} +\pnum +In the absence of a \grammarterm{virt-specifier-seq}, +the token sequence \tcode{= 0} is treated as a \grammarterm{pure-specifier} +if the type of the \grammarterm{declarator-id}\iref{dcl.meaning.general} +is a function type, and +is otherwise treated as a \grammarterm{brace-or-equal-initializer}. +\begin{note} +If the member declaration acquires a function type through +template instantiation, +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 full set of members of the class; no member can be added elsewhere. +A \defnadj{direct}{member} of a class \tcode{X} is a member of \tcode{X} +that was first declared within the \grammarterm{member-specification} of \tcode{X}, +including anonymous union members\iref{class.union.anon} and direct members thereof. Members of a class are data members, member -functions~(\ref{class.mfct}), nested types, and enumerators. Data -members and member functions are static or non-static; -see~\ref{class.static}. Nested types are -classes~(\ref{class.name},~\ref{class.nest}) and -enumerations~(\ref{dcl.enum}) defined in the class, and arbitrary types -declared as members by use of a typedef declaration~(\ref{dcl.typedef}). -The enumerators of an unscoped enumeration~(\ref{dcl.enum}) defined in the class -are members of the class. Except when used to declare -friends~(\ref{class.friend}), to declare an unnamed bit-field~(\ref{class.bit}), -or to introduce the name of a member of a -base class into a derived -class~(\ref{namespace.udecl}), or when the declaration is an -\grammarterm{empty-declaration}, -\grammarterm{member-declaration}{s} declare members of the class, and each -such \grammarterm{member-declaration} shall declare at least one member -name of the class. A member shall not be declared twice in the -\grammarterm{member-specification}, except that a nested class or member -class template can be declared and then later defined, and except that an +functions\iref{class.mfct}, nested types, enumerators, +and member templates\iref{temp.mem} and specializations thereof. +\begin{note} +A specialization of a static data member template is a static data member. +A specialization of a member function template is a member function. +A specialization of a member class template is a nested class. +\end{note} + +\pnum +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} +For any other \grammarterm{member-declaration}, +each declared entity +that is not an unnamed bit-field\iref{class.bit} +is a member of the class, +and each such \grammarterm{member-declaration} +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 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 +declared as members by use of a typedef declaration\iref{dcl.typedef} +or \grammarterm{alias-declaration}. +The enumerators of an unscoped enumeration\iref{dcl.enum} defined in the class +are members of the class. + +\pnum +A data member or member function +may be declared \keyword{static} in its \grammarterm{member-declaration}, +in which case it is a \defnadj{static}{member} (see~\ref{class.static}) +(a \defnadj{static}{data member}\iref{class.static.data} or +\defnadj{static}{member function}\iref{class.static.mfct}, respectively) +of the class. +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). + +\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 +\grammarterm{member-specification}, except that +\begin{itemize} +\item a nested class or member +class template can be declared and then later defined, and +\item an enumeration can be introduced with an \grammarterm{opaque-enum-declaration} and later redeclared with an \grammarterm{enum-specifier}{}. +\end{itemize} +\begin{note} +A single name can denote several member functions provided their types +are sufficiently different\iref{basic.scope.scope}. +\end{note} \pnum -\indextext{completely~defined}% -A class is considered a completely-defined object -type~(\ref{basic.types}) (or complete type) at the closing \tcode{\}} of -the \grammarterm{class-specifier}. -Within the class -\grammarterm{member-specification}, the class is regarded as complete -within function bodies, default arguments, -\grammarterm{using-declaration}{s} introducing inheriting -constructors~(\ref{class.inhctor}), -\grammarterm{exception-specification}{s}, and -\grammarterm{brace-or-equal-initializer}{s} for non-static data members -(including such things in nested classes). -Otherwise it is regarded as incomplete within its own class -\grammarterm{member-specification}. +A redeclaration of a class member outside its class definition shall be +a definition, +an explicit specialization, or +an explicit instantiation\iref{temp.expl.spec,temp.explicit}. +The member shall not be a non-static data member. + +\pnum +\indextext{completely defined}% +A \defn{complete-class context} of a class (template) is a +\begin{itemize} +\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}, +\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. +\begin{note} +A complete-class context of a nested class is also a complete-class +context of any enclosing class, if the nested class is defined within +the \grammarterm{member-specification} of the enclosing class. +\end{note} + +\pnum +A class \tcode{C} is complete at a program point $P$ +if the definition of \tcode{C} is reachable from $P$\iref{module.reach} +or if $P$ is in a complete-class context of \tcode{C}. +Otherwise, \tcode{C} is incomplete at $P$. + +\pnum +If a \grammarterm{member-declaration} matches +the syntactic requirements of \grammarterm{friend-type-declaration}, +it is a \grammarterm{friend-type-declaration}. + +\pnum +In a \grammarterm{member-declarator}, +an \tcode{=} immediately following the \grammarterm{declarator} +is interpreted as introducing a \grammarterm{pure-specifier} +if the \grammarterm{declarator-id} has function type, +otherwise it is interpreted as introducing +a \grammarterm{brace-or-equal-initializer}. +\begin{example} +\begin{codeblock} +struct S { + using T = void(); + T * p = 0; // OK, \grammarterm{brace-or-equal-initializer} + virtual T f = 0; // OK, \grammarterm{pure-specifier} +}; +\end{codeblock} +\end{example} \pnum -\enternote -A single name can denote several function members provided their types -are sufficiently different (Clause~\ref{over}). -\exitnote +In a \grammarterm{member-declarator} for a bit-field, +the \grammarterm{constant-expression} is parsed as +the longest sequence of tokens +that could syntactically form a \grammarterm{constant-expression}. +\begin{example} +\begin{codeblock} +int a; +const int b = 0; +struct S { + int x1 : 8 = 42; // OK, \tcode{"= 42"} is \grammarterm{brace-or-equal-initializer} + int x2 : 8 { 42 }; // OK, \tcode{"\{ 42 \}"} is \grammarterm{brace-or-equal-initializer} + int y1 : true ? 8 : a = 42; // OK, \grammarterm{brace-or-equal-initializer} is absent + int y2 : true ? 8 : b = 42; // error: cannot assign to \tcode{const int} + int y3 : (true ? 8 : b) = 42; // OK, \tcode{"= 42"} is \grammarterm{brace-or-equal-initializer} + int z : 1 || new int { 0 }; // OK, \grammarterm{brace-or-equal-initializer} is absent +}; +\end{codeblock} +\end{example} \pnum A \grammarterm{brace-or-equal-initializer} shall appear only in the declaration of a data member. (For static data members, see~\ref{class.static.data}; for non-static data members, -see~\ref{class.base.init}). +see~\ref{class.base.init} and~\ref{dcl.init.aggr}). A \grammarterm{brace-or-equal-initializer} for a non-static data member +\indextext{member!default initializer}% +specifies a \defn{default member initializer} for the member, and 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.imm} that +is a potentially-evaluated subexpression\iref{intro.execution} +of a default member initializer +is neither evaluated nor checked for whether it +is a constant expression at the point where the subexpression appears. \pnum -A member shall not be declared with the \tcode{extern} -or \tcode{register} -\nonterminal{storage-class-specifier}. Within a class definition, a member shall not be declared with the \tcode{thread_local} \nonterminal{storage-class-specifier} unless also declared \tcode{static}. +A member shall not be declared with the \keyword{extern} +\grammarterm{storage-class-specifier}. Within a class definition, a member shall not be declared with the \keyword{thread_local} \grammarterm{storage-class-specifier} unless also declared \keyword{static}. \pnum The \grammarterm{decl-specifier-seq} may be omitted in constructor, destructor, @@ -559,9 +739,10 @@ The \grammarterm{member-declarator-list} can be omitted only after a \grammarterm{class-specifier} or an \grammarterm{enum-specifier} or in a -\tcode{friend} declaration~(\ref{class.friend}). A +friend declaration\iref{class.friend}. A \grammarterm{pure-specifier} shall be used only in the declaration of a -virtual function~(\ref{class.virtual}). +virtual function\iref{class.virtual} +that is not a friend declaration. \pnum The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{member-declaration} @@ -572,34 +753,37 @@ A \grammarterm{virt-specifier-seq} shall contain at most one of each \grammarterm{virt-specifier}. A \grammarterm{virt-specifier-seq} -shall appear only in the declaration of a virtual member -function~(\ref{class.virtual}). +shall appear only in the first declaration of a virtual member +function\iref{class.virtual}. \pnum -\indextext{class~object!member}% -Non-\tcode{static}~(\ref{class.static}) data members shall not have -incomplete types. In particular, a class \tcode{C} shall not contain a -non-static member of class \tcode{C}, but it can contain a pointer or -reference to an object of class \tcode{C}. +\indextext{class object!member}% +The type of a non-static data member shall not be an +incomplete type\iref{term.incomplete.type}, +an abstract class type\iref{class.abstract}, +or a (possibly multidimensional) array thereof. +\begin{note} +In particular, a class \tcode{C} cannot contain +a non-static member of class \tcode{C}, +but it can contain a pointer or reference to an object of class \tcode{C}. +\end{note} \pnum -\enternote -See~\ref{expr.prim} for restrictions on the use of non-static data +\begin{note} +See~\ref{expr.prim.id} for restrictions on the use of non-static data members and non-static member functions. -\exitnote +\end{note} \pnum -\enternote +\begin{note} The type of a non-static member function is an ordinary function type, and the type of a non-static data member is an ordinary object type. There are no special member function types or data member types. -\exitnote +\end{note} \pnum -\indextext{example!class~definition}% -\enterexample +\begin{example} A simple example of a class definition is - \begin{codeblock} struct tnode { char tword[20]; @@ -608,57 +792,51 @@ tnode* right; }; \end{codeblock} - which contains an array of twenty characters, an integer, and two pointers to objects of the same type. Once this definition has been given, the declaration - \begin{codeblock} tnode s, *sp; \end{codeblock} - declares \tcode{s} to be a \tcode{tnode} and \tcode{sp} to be a pointer to a \tcode{tnode}. With these declarations, \tcode{sp->count} refers to the \tcode{count} member of the object to which \tcode{sp} points; \tcode{s.left} refers to the \tcode{left} subtree pointer of the object \tcode{s}; and \tcode{s.right->tword[0]} refers to the initial character of the \tcode{tword} member of the \tcode{right} subtree of \tcode{s}. -\exitexample +\end{example} \pnum -\indextext{layout!class~object}% -Nonstatic data members of a (non-union) class -with the same access control (Clause~\ref{class.access}) +\begin{note} +\indextext{layout!class object}% +Non-variant non-static data members of +non-zero size\iref{intro.object} are allocated so that later -members have higher addresses within a class object. -\indextext{allocation!unspecified}% -The order of allocation of non-static data members -with different access control -is unspecified (Clause~\ref{class.access}). -Implementation alignment requirements might cause two adjacent members -not to be allocated immediately after each other; so might requirements -for space for managing virtual functions~(\ref{class.virtual}) and -virtual base classes~(\ref{class.mi}). +members have higher addresses within a class object\iref{expr.rel}. +Implementation alignment requirements can cause two adjacent members +not to be allocated immediately after each other; so can requirements +for space for managing virtual functions\iref{class.virtual} and +virtual base classes\iref{class.mi}. +\end{note} \pnum If \tcode{T} is the name of a class, then each of the following shall have a name different from \tcode{T}: - \begin{itemize} \item every static data member of class \tcode{T}; -\item every member function of class \tcode{T} -\enternote +\item every member function of class \tcode{T}; +\begin{note} This restriction does not apply to constructors, which do not have -names~(\ref{class.ctor}) -\exitnote; +names\iref{class.ctor}. +\end{note}% \item every member of class \tcode{T} that is itself a type; \item every member template of class \tcode{T}; \item every enumerator of every member of class \tcode{T} that is an -unscoped enumerated type; and +unscoped enumeration type; and \item every member of every anonymous union that is a member of class \tcode{T}. @@ -666,117 +844,154 @@ \pnum In addition, if class \tcode{T} has a user-declared -constructor~(\ref{class.ctor}), every non-static data member of class +constructor\iref{class.ctor}, every non-static data member of class \tcode{T} shall have a name different from \tcode{T}. \pnum -The \defn{common initial sequence} of two standard-layout struct (Clause~\ref{class}) +The \defn{common initial sequence} of two standard-layout struct\iref{class.prop} types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first -such entity in each of the structs, such that corresponding entities -have layout-compatible types and either neither entity is a bit-field or -both are bit-fields with the same width. -\enterexample +such entity in each of the structs, such that +\begin{itemize} +\item +corresponding entities +have layout-compatible types\iref{basic.types}, +\item +corresponding entities have the same alignment requirements\iref{basic.align}, +\item +if a \grammarterm{has-attribute-expression}\iref{cpp.cond} +is not \tcode{0} for the \tcode{no_unique_address} attribute, +then neither entity is declared with +the \tcode{no_unique_address} attribute\iref{dcl.attr.nouniqueaddr}, and +\item +either both entities are bit-fields with the same width +or neither is a bit-field. +\end{itemize} +\begin{example} \begin{codeblock} - struct A { int a; char b; }; - struct B { const int b1; volatile char b2; }; - struct C { int c; unsigned : 0; char b; }; - struct D { int d; char b : 4; }; - struct E { unsigned int e; char b; }; +struct A { int a; char b; }; +struct B { const int b1; volatile char b2; }; +struct C { int c; unsigned : 0; char b; }; +struct D { int d; char b : 4; }; +struct E { unsigned int e; char b; }; \end{codeblock} The common initial sequence of \tcode{A} and \tcode{B} comprises all members of either class. The common initial sequence of \tcode{A} and \tcode{C} and of \tcode{A} and \tcode{D} comprises the first member in each case. The common initial sequence of \tcode{A} and \tcode{E} is empty. -\exitexample +\end{example} \pnum -Two standard-layout struct (Clause~\ref{class}) types are layout-compatible if +Two standard-layout struct\iref{class.prop} types are +\defnx{layout-compatible classes}{layout-compatible!class} if their common initial sequence comprises all members and bit-fields of -both classes~(\ref{basic.types}). +both classes\iref{basic.types}. \pnum Two standard-layout unions are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in any order) have layout-compatible -types~(\ref{basic.types}). +types\iref{term.layout.compatible.type}. \pnum -In a standard-layout union with an active member~(\ref{class.union}) +In a standard-layout union with an active member\iref{class.union} of struct type \tcode{T1}, it is permitted to read a non-static data member \tcode{m} of another union member of struct type \tcode{T2} -provided \tcode{m} is part of the common initial sequence of \tcode{T1} and \tcode{T2}. -\enternote -Reading a volatile object through a non-volatile glvalue has -undefined behavior (\ref{dcl.type.cv}). -\exitnote +provided \tcode{m} is part of the common initial sequence of \tcode{T1} and \tcode{T2}; +the behavior is as if the corresponding member of \tcode{T1} were nominated. +\begin{example} +\begin{codeblock} +struct T1 { int a, b; }; +struct T2 { int c; double d; }; +union U { T1 t1; T2 t2; }; +int f() { + U u = { { 1, 2 } }; // active member is \tcode{t1} + return u.t2.c; // OK, as if \tcode{u.t1.a} were nominated +} +\end{codeblock} +\end{example} +\begin{note} +Reading a volatile object through a glvalue of non-volatile type has +undefined behavior\iref{dcl.type.cv}. +\end{note} \pnum If a standard-layout class object has any non-static data members, its address -is the same as the address of its first non-static data member. Otherwise, its -address is the same as the address of its first base class subobject (if any). -\enternote -There might therefore be unnamed padding within a standard-layout struct object, but +is the same as the address of its first non-static data member +if that member is not a bit-field. Its +address is also the same as the address of each of its base class subobjects. +\begin{note} +There can therefore be unnamed padding within a standard-layout struct object +inserted by an implementation, but not at its beginning, as necessary to achieve appropriate alignment. -\exitnote - -\rSec1[class.mfct]{Member functions}% -\indextext{member function!class} +\end{note} +\begin{note} +The object and its first subobject are +pointer-interconvertible\iref{basic.compound,expr.static.cast}. +\end{note} \pnum -Functions declared in the definition of a class, excluding those -declared with a \tcode{friend} specifier~(\ref{class.friend}), are -called member functions of that class. A member function may be declared -\tcode{static} in which case it is a \term{static} member function -of its class~(\ref{class.static}); otherwise it is a -\grammarterm{non-static} member function of its -class~(\ref{class.mfct.non-static},~\ref{class.this}). +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} \pnum \indextext{member function!inline}% -\indextext{definition!member~function}% -A member function may be defined~(\ref{dcl.fct.def}) in its class -definition, in which case it is an \term{inline} member -function~(\ref{dcl.fct.spec}), or it may be defined outside of its class -definition if it has already been declared but not defined in its class -definition. A member function definition that appears outside of the -class definition shall appear in a namespace scope enclosing the class -definition. Except for member function definitions that appear outside -of a class definition, and except for explicit specializations of member -functions of class templates and member function -templates~(\ref{temp.spec}) appearing outside of the class definition, a -member function shall not be redeclared. - -\pnum -An \tcode{inline} member function (whether static or non-static) may -also be defined outside of its class definition provided either its -declaration in the class definition or its definition outside of the -class definition declares the function as \tcode{inline}. -\enternote -Member functions of a class in namespace scope have the linkage of that class. -Member functions of a local class~(\ref{class.local}) have no linkage. -See~\ref{basic.link}. -\exitnote - -\pnum -There shall be at most one definition of a non-inline member function in -a program; no diagnostic is required. There may be more than one -\tcode{inline} member function definition in a program. -See~\ref{basic.def.odr} and~\ref{dcl.fct.spec}. - -\pnum -\indextext{operator!scope~resolution}% -If the definition of a member function is lexically outside its class -definition, the member function name shall be qualified by its class -name using the \tcode{::} operator. -\enternote -A name used in a member function definition (that is, in the -\grammarterm{parameter-declaration-clause} including the default -arguments~(\ref{dcl.fct.default}) or in the member function body) is looked up -as described in~\ref{basic.lookup}. -\exitnote -\enterexample +\indextext{definition!member function}% +If a member function is attached to the global module and is defined\iref{dcl.fct.def} in its class definition, +it is inline\iref{dcl.inline}. +\begin{note} +A member function is also inline if it is declared +\keyword{inline}, \keyword{constexpr}, or \keyword{consteval}. +\end{note} +\pnum +\indextext{operator!scope resolution}% +\begin{example} \begin{codeblock} struct X { typedef int T; @@ -786,869 +1001,5845 @@ void X::f(T t = count) { } \end{codeblock} -The member function \tcode{f} of class \tcode{X} is defined in global -scope; the notation \tcode{X::f} specifies that the function \tcode{f} +The definition of the member function \tcode{f} of class \tcode{X} inhabits the global +scope; the notation \tcode{X::f} indicates that the function \tcode{f} is a member of class \tcode{X} and in the scope of class \tcode{X}. In the function definition, the parameter type \tcode{T} refers to the typedef member \tcode{T} declared in class \tcode{X} and the default argument \tcode{count} refers to the static data member \tcode{count} declared in class \tcode{X}. -\exitexample +\end{example} \pnum -A \tcode{static} local variable in a member function always refers to -the same object, whether or not the member function is \tcode{inline}. - -\pnum -Previously declared member functions may be mentioned in \tcode{friend} declarations. - -\pnum -\indextext{local~class!member~function~in}% +\indextext{local class!member function in}% Member functions of a local class shall be defined inline in their class definition, if they are defined at all. \pnum -\enternote +\begin{note} A member function can be declared (but not defined) using a typedef for a function type. The resulting member function has exactly the same type as it would have if the function declarator were provided explicitly, -see~\ref{dcl.fct}. For example, - +see~\ref{dcl.fct} and \ref{temp.arg}. +\begin{example} \begin{codeblock} -typedef void fv(void); -typedef void fvc(void) const; +typedef void fv(); +typedef void fvc() const; struct S { - fv memfunc1; // equivalent to: \tcode{void memfunc1(void);} + fv memfunc1; // equivalent to: \tcode{void memfunc1();} void memfunc2(); - fvc memfunc3; // equivalent to: \tcode{void memfunc3(void) const;} + fvc memfunc3; // equivalent to: \tcode{void memfunc3() const;} }; fv S::* pmfv1 = &S::memfunc1; fv S::* pmfv2 = &S::memfunc2; fvc S::* pmfv3 = &S::memfunc3; \end{codeblock} +\end{example} +\end{note} -Also see~\ref{temp.arg}. -\exitnote +\rSec2[class.mfct.non.static]{Non-static member functions}% -\rSec2[class.mfct.non-static]{Nonstatic member functions}% -\indextext{member function!nonstatic} +\indextext{member function!non-static} \pnum -A \grammarterm{non-static} member function may be called for an object of -its class type, or for an object of a class derived -(Clause~\ref{class.derived}) from its class type, using the class member -access syntax~(\ref{expr.ref},~\ref{over.match.call}). A non-static +A non-static member function may be called for an object of +its class type, or for an object of a class derived\iref{class.derived} +from its class type, using the class member +access syntax\iref{expr.ref,over.match.call}. A non-static member function may also be called directly using the function call -syntax~(\ref{expr.call},~\ref{over.match.call}) from within -the body of a member function of its class or of a class derived from -its class. - -\pnum -\indextext{member function!call undefined}% -If a non-static member function of a class \tcode{X} is called for an -object that is not of type \tcode{X}, or of a type derived from -\tcode{X}, the behavior is undefined. - -\pnum -When an \grammarterm{id-expression}~(\ref{expr.prim}) that is not part of a -class member access syntax~(\ref{expr.ref}) and not used to form a -pointer to member~(\ref{expr.unary.op}) is used in -a member of class \tcode{X} in a context where \tcode{this} can be -used~(\ref{expr.prim.general}), -if name -lookup~(\ref{basic.lookup}) resolves the name in the -\grammarterm{id-expression} to a non-static non-type member of some class -\tcode{C}, -and if either the \grammarterm{id-expression} is potentially evaluated or -\tcode{C} is \tcode{X} or a base class of \tcode{X}, -the \grammarterm{id-expression} is transformed into a class -member access expression~(\ref{expr.ref}) using -\tcode{(*this)}~(\ref{class.this}) as the \grammarterm{postfix-expression} -to the left of the \tcode{.} operator. -\enternote -If \tcode{C} is not \tcode{X} or a base class of \tcode{X}, the class -member access expression is ill-formed. -\exitnote -Similarly during name lookup, when an -\grammarterm{unqualified-id}~(\ref{expr.prim}) used in the definition of a -member function for class \tcode{X} resolves to a \tcode{static} member, -an enumerator or a nested type of class \tcode{X} or of a base class of -\tcode{X}, the \grammarterm{unqualified-id} is transformed into a -\grammarterm{qualified-id}~(\ref{expr.prim}) in which the -\grammarterm{nested-name-specifier} names the class of the member function. -\indextext{example!member~function}% -\enterexample +syntax\iref{expr.call,over.match.call} from within +its class or a class derived from its class, or +a member thereof, as described below. -\begin{codeblock} -struct tnode { - char tword[20]; - int count; - tnode* left; - tnode* right; - void set(const char*, tnode* l, tnode* r); -}; +\pnum +\indextext{member function!const}% +\indextext{member function!volatile}% +\indextext{member function!const volatile}% +\begin{note} +An implicit object member function can be declared with +\grammarterm{cv-qualifier}{s}, which affect the type of the \keyword{this} +pointer\iref{expr.prim.this}, +and/or a \grammarterm{ref-qualifier}\iref{dcl.fct}; +both affect overload resolution\iref{over.match.funcs}. +\end{note} -void tnode::set(const char* w, tnode* l, tnode* r) { - count = strlen(w)+1; - if (sizeof(tword)<=count) - perror("tnode string too long"); - strcpy(tword,w); - left = l; - right = r; -} +\pnum +An implicit object member function may be declared +virtual\iref{class.virtual} or pure virtual\iref{class.abstract}. -void f(tnode n1, tnode n2) { - n1.set("abc",&n2,0); - n2.set("def",0,0); -} -\end{codeblock} +\rSec2[special]{Special member functions} + +\indextext{~@\tcode{\~}|see{destructor}}% +\indextext{assignment!copy|see{assignment operator, copy}}% +\indextext{assignment!move|see{assignment operator, move}}% +\indextext{implicitly-declared default constructor|see{constructor, default}} -In the body of the member function \tcode{tnode::set}, the member names -\tcode{tword}, \tcode{count}, \tcode{left}, and \tcode{right} refer to -members of the object for which the function is called. Thus, in the -call \tcode{n1.set("abc",\&n2,0)}, \tcode{tword} refers to -\tcode{n1.tword}, and in the call \tcode{n2.set("def",0,0)}, it refers -to \tcode{n2.tword}. The functions \tcode{strlen}, \tcode{perror}, and -\tcode{strcpy} are not members of the class \tcode{tnode} and should be -declared elsewhere.\footnote{See, for example, \tcode{}~(\ref{c.strings}).} -\exitexample +\pnum +\indextext{constructor!default}% +\indextext{constructor!copy}% +\indextext{constructor!move}% +\indextext{assignment operator!copy}% +\indextext{assignment operator!move}% +Default constructors\iref{class.default.ctor}, +copy constructors, move constructors\iref{class.copy.ctor}, +copy assignment operators, move assignment operators\iref{class.copy.assign}, +and prospective destructors\iref{class.dtor} are +\term{special member functions}. +\begin{note} +The implementation will implicitly declare these member functions for some class +types when the program does not explicitly declare them. +The implementation will implicitly define them +as needed\iref{dcl.fct.def.default}. +\end{note} +An implicitly-declared special member function is declared at the closing +\tcode{\}} of the \grammarterm{class-specifier}. +Programs shall not define implicitly-declared special member functions. \pnum -A non-static member function may be declared \tcode{const}, -\tcode{volatile}, or \tcode{const} \tcode{volatile}. These -\grammarterm{cv-qualifiers} affect the type of the \tcode{this} -pointer~(\ref{class.this}). They also affect the function -type~(\ref{dcl.fct}) of the member function; a member function declared -\tcode{const} is a \term{const} member function, a member function -declared \tcode{volatile} is a \term{volatile} member function and a -member function declared \tcode{const} \tcode{volatile} is a -\term{const volatile} member function. -\enterexample +Programs may explicitly refer to implicitly-declared special member functions. +\begin{example} +A program may explicitly call or form a pointer to member +to an implicitly-declared special member function. \begin{codeblock} -struct X { - void g() const; - void h() const volatile; +struct A { }; // implicitly declared \tcode{A::operator=} +struct B : A { + B& operator=(const B &); }; +B& B::operator=(const B& s) { + this->A::operator=(s); // well-formed + return *this; +} \end{codeblock} +\end{example} -\tcode{X::g} is a \tcode{const} member function and \tcode{X::h} is a -\tcode{const} \tcode{volatile} member function. -\exitexample +\pnum +\begin{note} +The special member functions affect the way objects of class type are created, +copied, moved, and destroyed, and how values can be converted to values of other types. +Often such special member functions are called implicitly. +\end{note} \pnum -A non-static member function may be declared with a \grammarterm{ref-qualifier}~(\ref{dcl.fct}); see~\ref{over.match.funcs}. +\indextext{access control!member function and}% +Special member functions obey the usual access rules\iref{class.access}. +\begin{example} +Declaring a constructor protected +ensures that only derived classes and friends can create objects using it. +\end{example} \pnum -A non-static member function may be declared -\term{virtual}~(\ref{class.virtual}) or \term{pure virtual}~(\ref{class.abstract}). +Two special member functions are of the same kind if +\begin{itemize} +\item they are both default constructors, +\item they are both copy or move constructors +with the same first parameter type, or +\item they are both copy or move assignment operators +with the same first parameter type +and the same \grammarterm{cv-qualifier}s and \grammarterm{ref-qualifier}, if any. +\end{itemize} -\rSec2[class.this]{The \tcode{this} pointer}% -\indextext{\idxcode{this}} -\indextext{member function!\idxcode{this}} +\pnum +An \defnadj{eligible}{special member function} is a special member function for which: +\begin{itemize} +\item the function is not deleted, +\item the associated constraints\iref{temp.constr}, if any, are satisfied, and +\item no special member function of the same kind +whose associated constraints, if any, are satisfied +is more constrained\iref{temp.constr.order}. +\end{itemize} \pnum -\indextext{this pointer@\tcode{this}~pointer|see{\tcode{this}}}% -In the body of a non-static~(\ref{class.mfct}) member function, the -keyword \tcode{this} is a prvalue expression whose value is the -address of the object for which the function is called. -\indextext{\idxcode{this}!type~of}% -The type of \tcode{this} in a member function of a class \tcode{X} is -\tcode{X*}. -\indextext{member function!\idxcode{const}}% -If the member function is declared \tcode{const}, the type of -\tcode{this} is \tcode{const} \tcode{X*}, -\indextext{member function!\idxcode{volatile}}% -if the member function is declared \tcode{volatile}, the type of -\tcode{this} is \tcode{volatile} \tcode{X*}, and if the member function -is declared \tcode{const} \tcode{volatile}, the type of \tcode{this} is -\tcode{const} \tcode{volatile} \tcode{X*}. -\indextext{member function!\idxcode{const}}% -\enternote thus in a \tcode{const} member function, the object for which the function is -called is accessed through a \tcode{const} access path. \exitnote -\enterexample +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}. + +\rSec2[class.ctor]{Constructors}% +\rSec3[class.ctor.general]{General}% +\indextext{constructor}% +\indextext{special member function|see{constructor}}% + +\pnum +A \grammarterm{declarator} declares a \defn{constructor} if it is a +function declarator\iref{dcl.fct} of the form +\begin{ncbnf} +ptr-declarator \terminal{(} parameter-declaration-clause \terminal{)} \opt{noexcept-specifier} \opt{attribute-specifier-seq} +\end{ncbnf} +where the \grammarterm{ptr-declarator} consists solely of an +\grammarterm{id-expression}, an optional \grammarterm{attribute-specifier-seq}, +and optional surrounding parentheses, and the \grammarterm{id-expression} has +one of the following forms: +\begin{itemize} +\item +in a friend declaration\iref{class.friend}, +the \grammarterm{id-expression} is a \grammarterm{qualified-id} +that names a constructor\iref{class.qual}; +\item +otherwise, in a \grammarterm{member-declaration} that belongs to the +\grammarterm{member-specification} of a class or class template, +the \grammarterm{id-expression} is the +injected-class-name\iref{class.pre} of the immediately-enclosing entity; + +\item +otherwise, the +\grammarterm{id-expression} is a \grammarterm{qualified-id} +whose \grammarterm{unqualified-id} is +the injected-class-name of its lookup context. +\end{itemize} +Constructors do not have names. +In a constructor declaration, each \grammarterm{decl-specifier} in the optional +\grammarterm{decl-specifier-seq} shall be +\keyword{friend}, +\keyword{inline}, +\keyword{constexpr}, +\keyword{consteval}, or +an \grammarterm{explicit-specifier}. +\begin{example} \begin{codeblock} -struct s { - int a; - int f() const; - int g() { return a++; } - int h() const { return a++; } // error +struct S { + S(); // declares the constructor }; -int s::f() const { return a; } +S::S() { } // defines the constructor \end{codeblock} +\end{example} -The \tcode{a++} in the body of \tcode{s::h} is ill-formed because it -tries to modify (a part of) the object for which \tcode{s::h()} is -called. This is not allowed in a \tcode{const} member function because -\tcode{this} is a pointer to \tcode{const}; that is, \tcode{*this} has -\tcode{const} type. -\exitexample +\pnum +\indextext{constructor!explicit call}% +A constructor is used to initialize objects of its class type. +\begin{note} +Because constructors do not have names, they are never found during +unqualified name lookup; however an explicit type conversion using the functional +notation\iref{expr.type.conv} will cause a constructor to be called to +initialize an object. +The syntax looks like an explicit call of the constructor. +\end{note} +\begin{example} +\begin{codeblock} +complex zz = complex(1,2.3); +cprint( complex(7.8,1.2) ); +\end{codeblock} +\end{example} +\begin{note} +For initialization of objects of class type see~\ref{class.init}. +\end{note} +\begin{note} +\ref{class.temporary} describes the lifetime of temporary objects. +\end{note} +\begin{note} +Explicit constructor calls do not yield lvalues, see~\ref{basic.lval}. +\end{note} \pnum -Similarly, \tcode{volatile} semantics~(\ref{dcl.type.cv}) apply in -\tcode{volatile} member functions when accessing the object and its -non-static data members. +\begin{note} +\indextext{member function!constructor and}% +Some language constructs have special semantics when used during construction; +see~\ref{class.base.init} and~\ref{class.cdtor}. +\end{note} \pnum -A \grammarterm{cv-qualified} member function can be called on an -object-expression~(\ref{expr.ref}) only if the object-expression is as -cv-qualified or less-cv-qualified than the member function. -\enterexample +\indextext{\idxcode{const}!constructor and}% +\indextext{\idxcode{volatile}!constructor and}% +A constructor can be invoked for a +\keyword{const}, +\tcode{volatile} +or +\keyword{const} +\tcode{volatile} +object. +\indextext{restriction!constructor}% +\keyword{const} +and +\tcode{volatile} +semantics\iref{dcl.type.cv} are not applied on an object under construction. +They come into effect when the constructor for the +most derived object\iref{intro.object} ends. -\begin{codeblock} -void k(s& x, const s& y) { - x.f(); - x.g(); - y.f(); - y.g(); // error -} -\end{codeblock} +\pnum +\indextext{constructor!address of}% +The address of a constructor shall not be taken. +\indextext{restriction!constructor}% +\begin{note} +A \tcode{return} statement in the body of a constructor +cannot specify a return value\iref{stmt.return}. +\end{note} -The call \tcode{y.g()} is ill-formed because \tcode{y} is \tcode{const} -and \tcode{s::g()} is a non-\tcode{const} member function, that is, -\tcode{s::g()} is less-qualified than the object-expression \tcode{y}. -\exitexample +\pnum +A constructor shall not be a coroutine. \pnum -\indextext{\idxcode{const}!constructor~and}% -\indextext{\idxcode{const}!destructor~and}% -\indextext{\idxcode{volatile}!constructor~and}% -\indextext{\idxcode{volatile}!destructor~and}% -Constructors~(\ref{class.ctor}) and destructors~(\ref{class.dtor}) shall -not be declared \tcode{const}, \tcode{volatile} or \tcode{const} -\tcode{volatile}. \enternote However, these functions can be invoked to -create and destroy objects with cv-qualified types, -see~(\ref{class.ctor}) and~(\ref{class.dtor}). -\exitnote +A constructor shall not have an explicit object parameter\iref{dcl.fct}. -\rSec1[class.static]{Static members}% -\indextext{member!static}% -\indextext{member function!static}% +\rSec3[class.default.ctor]{Default constructors} \pnum -A data or function member of a class may be declared \tcode{static} in a -class definition, in which case it is a \term{static member} of the class. +\indextext{constructor!inheritance of}% +\indextext{constructor!non-trivial}% +A \defnadj{default}{constructor} for a class \tcode{X} +is a constructor of class \tcode{X} +for which each parameter +that is not a function parameter pack +has a default argument +(including the case of a constructor with no parameters). +\indextext{implicitly-declared default constructor}% +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 +inline public member of its class. \pnum -A \tcode{static} member \tcode{s} of class \tcode{X} may be referred to -using the \grammarterm{qualified-id} expression \tcode{X::s}; it is not -necessary to use the class member access syntax~(\ref{expr.ref}) to -refer to a \tcode{static} member. A \tcode{static} member may be -referred to using the class member access syntax, in which case the -object expression is evaluated. -\enterexample +A defaulted default constructor for class \tcode{X} is defined as deleted if +\begin{itemize} +\item any non-static data member with no default member initializer\iref{class.mem} is +of reference type, + +\item \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 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 +does not result in a usable candidate\iref{over.match.general}, or + +\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, and +either $S$ is non-variant or $S$ has a default member initializer. +\end{itemize} -\begin{codeblock} -struct process { - static void reschedule(); -}; -process& g(); +\pnum +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 +\tcode{X} has no virtual functions\iref{class.virtual} and no virtual base +classes\iref{class.mi}, and -void f() { - process::reschedule(); // OK: no object necessary - g().reschedule(); // \tcode{g()} is called -} -\end{codeblock} -\exitexample +\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 \tcode{X} have trivial default constructors, and + +\item +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} + +Otherwise, the default constructor is +\defnx{non-trivial}{constructor!default!non-trivial}. \pnum -A \tcode{static} member may be referred to directly in the scope of its -class or in the scope of a class derived (Clause~\ref{class.derived}) -from its class; in this case, the \tcode{static} member is referred to -as if a \grammarterm{qualified-id} expression was used, with the -\grammarterm{nested-name-specifier} of the \grammarterm{qualified-id} naming -the class scope from which the static member is referenced. -\enterexample +An implicitly-defined\iref{dcl.fct.def.default} default constructor performs the set of +initializations of the class that would be performed by a user-written default +constructor for that class with no +\grammarterm{ctor-initializer}\iref{class.base.init} and an empty +\grammarterm{compound-statement}. +If that user-written default constructor would be ill-formed, +the program is ill-formed. +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 +its non-static data members are implicitly defined. +\begin{note} +An implicitly-declared default constructor has an +exception specification\iref{except.spec}. +An explicitly-defaulted definition might have an +implicit exception specification, see~\ref{dcl.fct.def}. +\end{note} + +\pnum +\begin{note} +\indextext{constructor!implicitly invoked}% +A default constructor is implicitly invoked to initialize +a class object when no initializer is specified\iref{dcl.init.general}. +Such a default constructor needs to be accessible\iref{class.access}. +\end{note} + +\pnum +\begin{note} +\indextext{order of execution!base class constructor}% +\indextext{order of execution!member constructor}% +\ref{class.base.init} describes the order in which constructors for base +classes and non-static data members are called and +describes how arguments can be specified for the calls to these constructors. +\end{note} + +\rSec3[class.copy.ctor]{Copy/move constructors}% + +\pnum +\indextext{constructor!copy|(}% +\indextext{constructor!move|(}% +\indextext{copy!class object|see{constructor, copy}}% +\indextext{move!class object|see{constructor, move}}% +A non-template constructor for class +\tcode{X} +is +a +copy +constructor if its first parameter is of type +\tcode{X\&}, +\tcode{const X\&}, +\tcode{volatile X\&} +or +\tcode{const volatile X\&}, +and either there are no other parameters +or else all other parameters have default arguments\iref{dcl.fct.default}. +\begin{example} +\tcode{X::X(const X\&)} +and +\tcode{X::X(X\&,int=1)} +are copy constructors. \begin{codeblock} -int g(); struct X { - static int g(); + X(int); + X(const X&, int = 1); }; -struct Y : X { - static int i; +X a(1); // calls \tcode{X(int);} +X b(a, 0); // calls \tcode{X(const X\&, int);} +X c = b; // calls \tcode{X(const X\&, int);} +\end{codeblock} +\end{example} + +\pnum +A non-template constructor for class \tcode{X} is a move constructor if its +first parameter is of type \tcode{X\&\&}, \tcode{const X\&\&}, +\tcode{volatile X\&\&}, or \tcode{const volatile X\&\&}, and either there are +no other parameters or else all other parameters have default +arguments\iref{dcl.fct.default}. +\begin{example} +\tcode{Y::Y(Y\&\&)} is a move constructor. +\begin{codeblock} +struct Y { + Y(const Y&); + Y(Y&&); }; -int Y::i = g(); // equivalent to \tcode{Y::g();} +extern Y f(int); +Y d(f(1)); // calls \tcode{Y(Y\&\&)} +Y e = d; // calls \tcode{Y(const Y\&)} \end{codeblock} -\exitexample +\end{example} \pnum -If an \grammarterm{unqualified-id}~(\ref{expr.prim}) is used in the -definition of a \tcode{static} member following the member's -\grammarterm{declarator-id}, and name lookup~(\ref{basic.lookup.unqual}) -finds that the \grammarterm{unqualified-id} refers to a \tcode{static} -member, enumerator, or nested type of the member's class (or of a base -class of the member's class), the \grammarterm{unqualified-id} is -transformed into a \grammarterm{qualified-id} expression in which the -\grammarterm{nested-name-specifier} names the class scope from which the -member is referenced. -\enternote -See~\ref{expr.prim} for restrictions on the use of non-static data -members and non-static member functions. -\exitnote +\begin{note} +All forms of copy/move constructor can be declared for a class. +\begin{example} +\begin{codeblock} +struct X { + X(const X&); + X(X&); // OK + X(X&&); + X(const X&&); // OK, but possibly not sensible +}; +\end{codeblock} +\end{example} +\end{note} +\pnum +\begin{note} +If a class +\tcode{X} +only has a copy constructor with a parameter of type +\tcode{X\&}, +an initializer of type +\keyword{const} +\tcode{X} +or +\tcode{volatile} +\tcode{X} +cannot initialize an object of type +\cv{}~\tcode{X}. +\begin{example} +\begin{codeblock} +struct X { + X(); // default constructor + X(X&); // copy constructor with a non-const parameter +}; +const X cx; +X x = cx; // error: \tcode{X::X(X\&)} cannot copy \tcode{cx} into \tcode{x} +\end{codeblock} +\end{example} +\end{note} \pnum -Static members obey the usual class member access rules -(Clause~\ref{class.access}). When used in the declaration of a class -member, the \tcode{static} specifier shall only be used in the member -declarations that appear within the \grammarterm{member-specification} of -the class definition. -\enternote -It cannot be specified in member declarations that appear in namespace scope. -\exitnote +A declaration of a constructor for a class +\tcode{X} +is ill-formed if its first parameter is of type +\cv{}~\tcode{X} +and either there are no other parameters or else all other parameters have +default arguments. +A member function template is never instantiated to +produce such a constructor signature. +\begin{example} +\begin{codeblock} +struct S { + template S(T); + S(); +}; -\rSec2[class.static.mfct]{Static member functions} -\indextext{member function!static}% +S g; -\pnum -\enternote -The rules described in~\ref{class.mfct} apply to \tcode{static} member -functions. -\exitnote +void h() { + S a(g); // does not instantiate the member template to produce \tcode{S::S(S)}; + // uses the implicitly declared copy constructor +} +\end{codeblock} +\end{example} \pnum -\enternote -A \tcode{static} member function does not have a \tcode{this} -pointer~(\ref{class.this}). -\exitnote -A \tcode{static} member function shall not be \tcode{virtual}. There -shall not be a \tcode{static} and a non-static member function with the -same name and the same parameter types~(\ref{over.load}). A -\tcode{static} member function shall not be declared \tcode{const}, -\tcode{volatile}, or \tcode{const volatile}. - -\rSec2[class.static.data]{Static data members} -\indextext{member~data!static}% +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}. \pnum -A \tcode{static} data member is not part of the subobjects of a class. If a -\tcode{static} data member is declared \tcode{thread_local} there is one copy of -the member per thread. If a \tcode{static} data member is not declared -\tcode{thread_local} there is one copy of the data member that is shared by all -the objects of the class. +The implicitly-declared copy constructor for a class +\tcode{X} +will have the form +\begin{codeblock} +X::X(const X&) +\end{codeblock} +if each potentially constructed subobject of a class type +\tcode{M} +(or array thereof) +has a copy constructor whose first parameter is of type +\keyword{const} +\tcode{M\&} +or +\keyword{const} +\tcode{volatile} +\tcode{M\&}. +\begin{footnote} +This implies that the reference parameter of the +implicitly-declared copy constructor +cannot bind to a +\tcode{volatile} +lvalue; see~\ref{diff.class}. +\end{footnote} +Otherwise, the implicitly-declared copy constructor will have the form +\begin{codeblock} +X::X(X&) +\end{codeblock} \pnum -\indextext{initialization!static member}% -\indextext{definition!static member}% -The declaration of a \tcode{static} data member in its class definition -is not a definition and may be of an incomplete type other than -cv-qualified \tcode{void}. The definition for a \tcode{static} data -member shall appear in a namespace scope enclosing the member's class -definition. -\indextext{operator~use!scope~resolution}% -In the definition at namespace scope, the name of the \tcode{static} -data member shall be qualified by its class name using the \tcode{::} -operator. The \grammarterm{initializer} expression in the definition of a -\tcode{static} data member is in the scope of its -class~(\ref{basic.scope.class}). -\indextext{example!static@\tcode{static} member}% -\enterexample +\indextext{constructor!move!implicitly declared}% +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, -\begin{codeblock} -class process { - static process* run_chain; - static process* running; -}; +\item +\tcode{X} does not have a user-declared copy constructor, -process* process::running = get_main(); -process* process::run_chain = running; -\end{codeblock} +\item +\tcode{X} does not have a user-declared copy assignment operator, -The \tcode{static} data member \tcode{run_chain} of class -\tcode{process} is defined in global scope; the notation -\tcode{process\colcol{}run_chain} specifies that the member \tcode{run_chain} -is a member of class \tcode{process} and in the scope of class -\tcode{process}. In the \tcode{static} data member definition, the -\grammarterm{initializer} expression refers to the \tcode{static} data -member \tcode{running} of class \tcode{process}. -\exitexample +\item +\tcode{X} does not have a user-declared move assignment operator, and -\enternote -Once the \tcode{static} data member has been defined, it exists even if -no objects of its class have been created. -\enterexample -in the example above, \tcode{run_chain} and \tcode{running} exist even -if no objects of class \tcode{process} are created by the program. -\exitexample -\exitnote +\item +\tcode{X} does not have a user-declared destructor. +\end{itemize} -\pnum -If a non-volatile \tcode{const} \tcode{static} data member is -of integral or enumeration type, -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~(\ref{expr.const}). A \tcode{static} data member of -literal type can be declared in the class definition with the -\tcode{constexpr} specifier; if so, its declaration shall specify a -\grammarterm{brace-or-equal-initializer} in which every -\grammarterm{initializer-clause} that is an \grammarterm{assignment-expression} -is a constant expression. \enternote In both these cases, -the member may appear in constant expressions. \exitnote The -member shall still be defined in a namespace scope if -it is odr-used~(\ref{basic.def.odr}) in the program and the -namespace scope definition shall not contain an \grammarterm{initializer}. +\begin{note} +When the move constructor is not implicitly declared or explicitly supplied, +expressions that otherwise would have invoked the move constructor might instead invoke +a copy constructor. +\end{note} \pnum -\enternote -There shall be exactly one definition of a \tcode{static} data member -that is odr-used~(\ref{basic.def.odr}) in a program; no diagnostic is required. -\exitnote -Unnamed classes and classes contained directly -or indirectly within unnamed classes shall not contain \tcode{static} -data members. +The implicitly-declared move constructor for class \tcode{X} will have the form +\begin{codeblock} +X::X(X&&) +\end{codeblock} \pnum -\indextext{restriction!static@\tcode{static} member local~class}% -\tcode{Static} data members of a class in namespace scope have -the linkage of that class~(\ref{basic.link}). A local class shall not have \tcode{static} -data members. +An implicitly-declared copy/move constructor is an +inline public member of its class. +A defaulted copy/\brk{}move constructor for a class + \tcode{X} is defined as deleted\iref{dcl.fct.def.delete} if \tcode{X} has: +\begin{itemize} +\item a potentially constructed subobject of type + \tcode{M} (or possibly multidimensional array thereof) for which + overload resolution\iref{over.match}, as applied to find + \tcode{M}'s corresponding constructor, + either does not result in a usable candidate\iref{over.match.general} or, + in the case of a variant member, selects a non-trivial function, + +\item any potentially constructed subobject of + class type \tcode{M} (or possibly multidimensional array thereof) + where \tcode{M} has + a destructor that is deleted or inaccessible from the defaulted + constructor, or, + +\item for the copy constructor, a non-static data member of rvalue reference type. +\end{itemize} + +\begin{note} +A defaulted move constructor that is defined as deleted is ignored by overload +resolution\iref{over.match,over.over}. +Such a constructor would otherwise interfere with initialization from +an rvalue which can use the copy constructor instead. +\end{note} \pnum -\tcode{Static} data members are initialized and destroyed exactly like -non-local variables~(\ref{basic.start.init},~\ref{basic.start.term}). +\begin{note} +A 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 -A \tcode{static} data member shall not be -\tcode{mutable}~(\ref{dcl.stc}). +\indextext{constructor!copy!trivial}% +\indextext{constructor!move!trivial}% +A copy/move constructor for class +\tcode{X} +is +trivial +if it is not user-provided and if +\begin{itemize} +\item +class +\tcode{X} +has no virtual functions\iref{class.virtual} +and no virtual base classes\iref{class.mi}, and + +\item +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 +\tcode{X} +that is of class type (or array thereof), +the constructor selected to copy/move that member is trivial; +\end{itemize} -\rSec1[class.union]{Unions}% -\indextext{\idxcode{union}} +\indextext{constructor!move!non-trivial}% +otherwise the copy/move constructor is +\defnx{non-trivial}{constructor!copy!nontrivial}. \pnum -In a union, at most one of the non-static data members can be active at any -time, that is, the value of at most one of the non-static data members can be -stored in a union at any time. \enternote One special guarantee is made in order to -simplify the use of unions: If a standard-layout union contains several standard-layout -structs that share a common initial sequence~(\ref{class.mem}), and if an object of this -standard-layout union type contains one of the standard-layout structs, it is permitted -to inspect the common initial sequence of any of standard-layout struct members; -see~\ref{class.mem}. \exitnote The size of a union is sufficient to contain the largest -of its non-static data members. Each non-static data member is allocated -as if it were the sole member of a struct. All non-static data members of a -union object have the same address. +\begin{note} +The copy/move constructor is implicitly defined even if the implementation elided +its odr-use\iref{term.odr.use,class.temporary}. +\end{note} +The implicitly-defined\iref{dcl.fct.def.default} constructor is constexpr. \pnum -\indextext{member function!\idxcode{union}}% -\indextext{constructor!\idxcode{union}}% -\indextext{destructor!\idxcode{union}}% -A union can have member functions (including constructors and destructors), -\indextext{restriction!\idxcode{union}}% -but not virtual~(\ref{class.virtual}) functions. A union shall not have -base classes. A union shall not be used as a base class. -\indextext{restriction!\idxcode{union}}% -If a union contains a non-static data member of -reference type the program is ill-formed. -\enternote If any non-static data member of a union has a non-trivial -default constructor~(\ref{class.ctor}), -copy constructor~(\ref{class.copy}), -move constructor~(\ref{class.copy}), -copy assignment operator~(\ref{class.copy}), -move assignment operator~(\ref{class.copy}), -or destructor~(\ref{class.dtor}), the corresponding member function -of the union must be user-provided or it will -be implicitly deleted~(\ref{dcl.fct.def.delete}) for the union. \exitnote +Before the defaulted copy/move constructor for a class is +implicitly defined, +all non-user-provided copy/move constructors for its +potentially constructed subobjects +are implicitly defined. +\begin{note} +An implicitly-declared copy/move constructor has an +implied exception specification\iref{except.spec}. +\end{note} + +\pnum +The implicitly-defined copy/move constructor for a non-union class +\tcode{X} +performs a memberwise copy/move of its bases and members. +\begin{note} +Default member initializers of non-static data members are ignored. +\end{note} +The order of initialization is the same as the order of initialization of bases +and members in a user-defined constructor (see~\ref{class.base.init}). +Let \tcode{x} be either the parameter of the constructor or, for the move constructor, an +xvalue referring to the parameter. +Each base or non-static data member +is copied/moved in the manner appropriate to its type: +\begin{itemize} +\item +if the member is an array, each element is +direct-initialized with the corresponding subobject of \tcode{x}; + +\item +if a member \tcode{m} has rvalue reference type \tcode{T\&\&}, it is direct-initialized with +\tcode{static_cast(x.m)}; + +\item +otherwise, the base or member is direct-initialized with the corresponding base or member of \tcode{x}. +\end{itemize} + +\indextext{initialization!virtual base class}% +Virtual base class subobjects shall be initialized only once by +the implicitly-defined copy/move constructor (see~\ref{class.base.init}). \pnum -\enterexample Consider the following union: +The implicitly-defined copy/move constructor for a union +\tcode{X} copies the object representation\iref{term.object.representation} of \tcode{X}. +For each object nested within\iref{intro.object} +the object that is the source of the copy, +a corresponding object $o$ nested within the destination +is identified (if the object is a subobject) or created (otherwise), +and the lifetime of $o$ begins before the copy is performed. +\indextext{constructor!move|)} +\indextext{constructor!copy|)} + +\rSec2[class.copy.assign]{Copy/move assignment operator}% +\pnum +\indextext{assignment operator!copy|(}% +\indextext{assignment operator!move|(}% +\indextext{special member function|see{assignment operator}}% +\indextext{copy!class object|see{assignment operator, copy}}% +\indextext{move!class object|see{assignment operator, move}}% +\indextext{operator!copy assignment|see{assignment operator, copy}}% +\indextext{operator!move assignment|see{assignment operator, move}}% +A user-declared \term{copy} assignment operator \tcode{X::operator=} is a +non-static non-template member function of class \tcode{X} with exactly one +non-object parameter of type \tcode{X}, \tcode{X\&}, \tcode{const X\&}, +\tcode{volatile X\&}, or \tcode{const volatile X\&}. +\begin{footnote} +Because +a template assignment operator or an assignment operator +taking an rvalue reference parameter is never a copy assignment operator, +the presence of such an assignment operator does not suppress the +implicit declaration of a copy assignment operator. Such assignment operators +participate in overload resolution with other assignment operators, including +copy assignment operators, and, if selected, will be used to assign an object. +\end{footnote} +\begin{note} +More than one form of copy assignment operator can be declared for a class. +\end{note} +\begin{note} +If a class +\tcode{X} +only has a copy assignment operator with a non-object parameter of type +\tcode{X\&}, +an expression of type +\tcode{const X} +cannot be assigned to an object of type +\tcode{X}. +\begin{example} \begin{codeblock} -union U { - int i; - float f; - std::string s; +struct X { + X(); + X& operator=(X&); }; +const X cx; +X x; +void f() { + x = cx; // error: \tcode{X::operator=(X\&)} cannot assign \tcode{cx} into \tcode{x} +} \end{codeblock} - -Since \tcode{std::string}~(\ref{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.\exitexample +\end{example} +\end{note} \pnum -\enternote In general, one must use explicit destructor calls and placement -new operators to change the active member of a union. \exitnote -\enterexample -Consider an object \tcode{u} of a \tcode{union} type \tcode{U} having non-static data members -\tcode{m} of type \tcode{M} and \tcode{n} of type \tcode{N}. If \tcode{M} has a non-trivial -destructor and \tcode{N} has a non-trivial constructor (for instance, if they declare or inherit -virtual functions), the active member of \tcode{u} can be safely switched from \tcode{m} to -\tcode{n} using the destructor and placement new operator as follows: +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 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}. +The implicitly-declared copy assignment operator for a class +\tcode{X} +will have the form +\begin{codeblock} +X& X::operator=(const X&) +\end{codeblock} +if +\begin{itemize} +\item +each direct base class \tcode{B} of \tcode{X} +has a copy assignment operator whose non-object parameter is of type +\tcode{const B\&}, \tcode{const volatile B\&}, or \tcode{B}, and +\item +for all the non-static data members of \tcode{X} +that are of a class type \tcode{M} (or array thereof), +each such class type has a copy assignment operator whose non-object parameter is of type +\tcode{const M\&}, \tcode{const volatile M\&}, +or \tcode{M}. +\begin{footnote} +This implies that the reference parameter of the +implicitly-declared copy assignment operator cannot bind to a +\tcode{volatile} lvalue; see~\ref{diff.class}. +\end{footnote} +\end{itemize} +Otherwise, the implicitly-declared copy assignment operator +will have the form \begin{codeblock} -u.m.~M(); -new (&u.n) N; +X& X::operator=(X&) \end{codeblock} -\exitexample \pnum -\indextext{\idxcode{union}!anonymous}% -A union of the form +A user-declared move assignment operator \tcode{X::operator=} is +a non-static non-template member function of class \tcode{X} with exactly +one non-object parameter of type \tcode{X\&\&}, \tcode{const X\&\&}, \tcode{volatile X\&\&}, or +\tcode{const volatile X\&\&}. +\begin{note} +More than one form of move assignment operator can be declared for a class. +\end{note} + +\pnum +\indextext{assignment operator!move!implicitly declared}% +If the definition of a class \tcode{X} does not explicitly declare a +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, + +\item +\tcode{X} does not have a user-declared move constructor, + +\item +\tcode{X} does not have a user-declared copy assignment operator, and -\begin{ncbnftab} -\terminal{union} \terminal{\{} member-specification \terminal{\}} \terminal{;} -\end{ncbnftab} - -is called an \defn{anonymous union}; it defines an unnamed object of unnamed -type. Each \grammarterm{member-declaration} in the \grammarterm{member-specification} -of an anonymous union shall either define a non-static data member or be a -\grammarterm{static_assert-declaration}. -\enternote -Nested types, anonymous unions, and functions cannot be declared within an anonymous -union. -\exitnote -The names of the members of an anonymous union shall be distinct from -the names of any other entity in the scope in which the anonymous union -is declared. For the purpose of name lookup, after the anonymous union -definition, the members of the anonymous union are considered to have -been defined in the scope in which the anonymous union is declared. -\indextext{initialization!\idxcode{union}}% -\enterexample +\item +\tcode{X} does not have a user-declared destructor. +\end{itemize} +\begin{example} +The class definition \begin{codeblock} -void f() { - union { int a; const char* p; }; - a = 1; - p = "Jennifer"; -} +struct S { + int a; + S& operator=(const S&) = default; +}; \end{codeblock} +will not have a default move assignment operator implicitly declared because the +copy assignment operator has been user-declared. The move assignment operator may +be explicitly defaulted. -Here \tcode{a} and \tcode{p} are used like ordinary (nonmember) -variables, but since they are union members they have the same address. -\exitexample +\begin{codeblock} +struct S { + int a; + S& operator=(const S&) = default; + S& operator=(S&&) = default; +}; +\end{codeblock} +\end{example} \pnum -\indextext{\idxcode{union}!global anonymous}% -\indextext{scope!anonymous \tcode{union}~at namespace}% -Anonymous unions declared in a named namespace or in the global -namespace shall be declared \tcode{static}. Anonymous unions declared at -block scope shall be declared with any storage class allowed for a -block-scope variable, or with no storage class. A storage class is not -allowed in a declaration of an anonymous union in a class scope. -\indextext{access~control!anonymous \tcode{union}}% -\indextext{restriction!anonymous \tcode{union}}% -An anonymous union shall not have \tcode{private} or \tcode{protected} -members (Clause~\ref{class.access}). An anonymous union shall not have -function members. +The implicitly-declared move assignment operator for a class \tcode{X} will have the form +\begin{codeblock} +X& X::operator=(X&&) +\end{codeblock} \pnum -A union for which objects, pointers, or references are declared is not an anonymous union. -\enterexample +The implicitly-declared copy/move assignment operator for class +\tcode{X} +has the return type +\tcode{X\&}. +An implicitly-declared copy/move assignment operator is an +inline public member of its class. + +\pnum +A defaulted copy/move assignment operator for +class \tcode{X} is defined as deleted if \tcode{X} has: +\begin{itemize} +\item a non-static data member of \keyword{const} non-class + type (or possibly multidimensional array thereof), or + +\item a non-static data member of reference type, or + +\item a direct non-static data member of class type \tcode{M} + (or possibly 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, + 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} + +\begin{note} +A defaulted move assignment operator that is defined as deleted is ignored by +overload resolution\iref{over.match,over.over}. +\end{note} + +\pnum +\indextext{assignment operator!copy!hidden}% +\indextext{assignment operator!move!hidden}% +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.assign}. +\begin{note} +A \grammarterm{using-declaration} in a derived class \tcode{C} +that names an assignment operator from a base class +never suppresses the implicit declaration of +an assignment operator of \tcode{C}, +even if the base class assignment operator would be +a copy or move assignment operator +if declared as a member of \tcode{C}. +\end{note} + +\pnum +\indextext{assignment operator!copy!trivial}% +\indextext{assignment operator!move!trivial}% +A copy/move assignment operator for class +\tcode{X} +is +trivial +if it is not user-provided and if +\begin{itemize} +\item +class +\tcode{X} +has no virtual functions\iref{class.virtual} +and no virtual base classes\iref{class.mi}, and + +\item the assignment operator 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 +\tcode{X} +that is of class type (or array thereof), +the assignment operator selected to copy/move that member is trivial; +\end{itemize} +\indextext{assignment operator!move!non-trivial}% +otherwise the copy/move assignment operator is +\defnx{non-trivial}{assignment operator!copy!non-trivial}. + +\pnum +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 +implicitly defined, +all non-user-provided copy/move assignment operators for +its direct base classes and +its non-static data members are implicitly defined. +\begin{note} +An implicitly-declared copy/move assignment operator has an +implied exception specification\iref{except.spec}. +\end{note} + +\pnum +The implicitly-defined copy/move assignment operator for a +non-union class \tcode{X} performs memberwise copy/move assignment of its subobjects. The direct +base classes of \tcode{X} are assigned first, in the order of their declaration in the +\grammarterm{base-specifier-list}, and then the immediate non-static data members of +\tcode{X} are assigned, in the order in which they were declared in the class +definition. +Let \tcode{x} be either the parameter of the function or, for the move operator, an +xvalue referring to the parameter. +Each subobject is assigned in the manner appropriate to its type: +\begin{itemize} +\item +if the subobject is of class type, +as if by a call to \tcode{operator=} with the subobject as the object expression +and the corresponding subobject of \tcode{x} as a single function argument +(as if by explicit qualification; that is, +ignoring any possible virtual overriding functions in more derived classes); +\item +if the subobject is an array, each element is assigned, +in the manner appropriate to the element type; +\item +if the subobject is of scalar type, +the built-in assignment operator is used. +\end{itemize} +\indextext{assignment operator!copy!virtual bases and}% +It is unspecified whether subobjects representing virtual base classes +are assigned more than once by the implicitly-defined copy/move assignment +operator. +\begin{example} \begin{codeblock} -void f() { - union { int aa; char* p; } obj, *ptr = &obj; - aa = 1; // error - ptr->aa = 1; // OK -} +struct V { }; +struct A : virtual V { }; +struct B : virtual V { }; +struct C : B, A { }; \end{codeblock} -The assignment to plain \tcode{aa} is ill-formed since the member name -is not visible outside the union, and even if it were visible, it is not -associated with any particular object. -\exitexample -\enternote -Initialization of unions with no user-declared constructors is described -in~(\ref{dcl.init.aggr}). -\exitnote +It is unspecified whether the virtual base class subobject +\tcode{V} +is assigned twice by the implicitly-defined copy/move assignment operator for +\tcode{C}. +\end{example} \pnum -A \term{union-like class} is a union or a class that has an anonymous union as a direct -member. A union-like class \tcode{X} has a set of \term{variant members}. -If \tcode{X} is a union, a non-static data member of \tcode{X} that is not an anonymous -union is a variant member of \tcode{X}. In addition, a non-static data member of an -anonymous union that is a member of \tcode{X} is also a variant member of \tcode{X}. -At most one variant member of a union may have a \grammarterm{brace-or-equal-initializer}. -\enterexample +The implicitly-defined copy/move assignment operator for a +union \tcode{X} copies the object representation\iref{term.object.representation} of \tcode{X}. +If the source and destination of the assignment are not the same object, then +for each object nested within\iref{intro.object} +the object that is the source of the copy, +a corresponding object $o$ nested within the destination is created, +and the lifetime of $o$ begins before the copy is performed. + +\pnum +The implicitly-defined copy/move assignment operator for a class +returns the object for which the assignment operator is invoked, +that is, the object assigned to. +\indextext{assignment operator!move|)} +\indextext{assignment operator!copy|)} + +\rSec2[class.dtor]{Destructors}% +\indextext{destructor}% +\indextext{special member function|see{destructor}}% +\pnum +A declaration whose \grammarterm{declarator-id} +has an \grammarterm{unqualified-id} that begins with a \tcode{\~} +declares a \defnadj{prospective}{destructor}; +its \grammarterm{declarator} shall be a function declarator\iref{dcl.fct} of the form +\begin{ncbnf} +ptr-declarator \terminal{(} parameter-declaration-clause \terminal{)} \opt{noexcept-specifier} \opt{attribute-specifier-seq} +\end{ncbnf} +where the \grammarterm{ptr-declarator} consists solely of an +\grammarterm{id-expression}, an optional \grammarterm{attribute-specifier-seq}, +and optional surrounding parentheses, and the \grammarterm{id-expression} has +one of the following forms: +\begin{itemize} +\item +in a \grammarterm{member-declaration} that belongs to the +\grammarterm{member-specification} of a class or class template +but is not a friend +declaration\iref{class.friend}, the \grammarterm{id-expression} is +\tcode{\~}\grammarterm{class-name} and the \grammarterm{class-name} is the +injected-class-name\iref{class.pre} of the immediately-enclosing entity or + +\item +otherwise, the +\grammarterm{id-expression} is \grammarterm{nested-name-specifier} +\tcode{\~}\grammarterm{class-name} and the \grammarterm{class-name} +is the injected-class-name of the +class nominated by the \grammarterm{nested-name-specifier}. +\end{itemize} + +A prospective destructor shall take no arguments\iref{dcl.fct}. +Each \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq} +of a prospective destructor declaration (if any) +shall be +\keyword{friend}, +\keyword{inline}, +\keyword{virtual}, or +\keyword{constexpr}. +\pnum +\indextext{generated destructor|see{destructor, default}}% +\indextext{destructor!default}% +If a class has no user-declared +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 +inline public member of its class. + +\pnum +An implicitly-declared prospective destructor for a class \tcode{X} will have the form \begin{codeblock} -union U { - int x = 0; - union { }; - union { - int z; - int y = 1; // error: initialization for second variant member of \tcode{U} - }; -}; +~X() \end{codeblock} -\exitexample - -\rSec1[class.bit]{Bit-fields}% -\indextext{bit-field} +\pnum +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 +to select the \defn{destructor} for the class, +also known as the \defnadj{selected}{destructor}. +The program is ill-formed if overload resolution fails. +Destructor selection does not constitute +a reference to, +or odr-use\iref{term.odr.use} of, +the selected destructor, +and in particular, +the selected destructor may be deleted\iref{dcl.fct.def.delete}. \pnum -A \grammarterm{member-declarator} of the form +\indextext{destructor!address of}% +The address of a destructor shall not be taken. +\indextext{restriction!destructor}% +\begin{note} +A \tcode{return} statement in the body of a destructor +cannot specify a return value\iref{stmt.return}. +\end{note} +\indextext{\idxcode{const}!destructor and}% +\indextext{\idxcode{volatile}!destructor and}% +A destructor can be invoked for a +\keyword{const}, +\tcode{volatile} +or +\keyword{const} +\tcode{volatile} +object. +\keyword{const} +and +\tcode{volatile} +semantics\iref{dcl.type.cv} are not applied on an object under destruction. +They stop being in effect when the destructor for the +most derived object\iref{intro.object} starts. -\begin{ncbnftab} -identifier\opt attribute-specifier-seq\opt \terminal{:} constant-expression -\end{ncbnftab} +\pnum +\begin{note} +A declaration of a destructor that does not have a \grammarterm{noexcept-specifier} +has the same exception specification as if it had been implicitly declared\iref{except.spec}. +\end{note} -\indextext{\idxcode{:}!field declaration}% -\indextext{declaration!bit-field}% -specifies a bit-field; -its length is set off from the bit-field name by a colon. The optional \grammarterm{attribute-specifier-seq} appertains to the entity being declared. The bit-field -attribute is not part of the type of the class member. The -\grammarterm{constant-expression} shall be an integral constant expression -with a value greater than or equal to zero. The -value of the integral constant expression may -be larger than the number of bits in the object -representation~(\ref{basic.types}) of the bit-field's type; in such -cases the extra bits are used as padding bits and do not participate in -the value representation~(\ref{basic.types}) of the bit-field. -\indextext{allocation!implementation~defined bit-field}% -Allocation of bit-fields within a class object is -\impldef{allocation of bit-fields within a class object}. -\indextext{bit-field!implementation~defined alignment~of}% -Alignment of bit-fields is \impldef{alignment of bit-fields within a class object}. -\indextext{layout!bit-field}% -Bit-fields are packed into some addressable allocation unit. -\enternote -Bit-fields straddle allocation units on some machines and not on others. -Bit-fields are assigned right-to-left on some machines, left-to-right on -others. -\exitnote +\pnum +A defaulted destructor for a class + \tcode{X} is defined as deleted if +\begin{itemize} +\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, + +\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 -\indextext{bit-field!unnamed}% -A declaration for a bit-field that omits the \grammarterm{identifier} -declares an \grammarterm{unnamed} bit-field. Unnamed bit-fields are not -members and cannot be initialized. -\enternote -An unnamed bit-field is useful for padding to conform to -externally-imposed layouts. -\exitnote -\indextext{bit-field!zero~width~of}% -\indextext{bit-field!alignment~of}% -As a special case, an unnamed bit-field with a width of zero specifies -alignment of the next bit-field at an allocation unit boundary. Only -when declaring an unnamed bit-field may the value of the -\grammarterm{constant-expression} be equal to zero. +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 \tcode{X} have trivial destructors, and + +\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} + +Otherwise, the destructor is +\defnx{non-trivial}{destructor!non-trivial}. \pnum -\indextext{bit-field!type~of}% -A bit-field shall not be a static member. A bit-field shall have -integral or enumeration type~(\ref{basic.fundamental}). -\indextext{Boolean}% -A \tcode{bool} value can successfully be stored in a bit-field of any -nonzero size. -\indextext{bit-field!address~of}% -The address-of operator \tcode{\&} shall not be applied to a bit-field, -so there are no pointers to bit-fields. -\indextext{restriction!bit-field}% -\indextext{restriction!address~of bit-field}% -\indextext{restriction!pointer~to bit-field}% -A non-const reference shall not be bound to a -bit-field~(\ref{dcl.init.ref}). -\enternote -If the initializer for a reference of type \tcode{const} \tcode{T\&} is -an lvalue that refers to a bit-field, the reference is bound to a -temporary initialized to hold the value of the bit-field; the reference -is not bound to the bit-field directly. See~\ref{dcl.init.ref}. -\exitnote +A defaulted destructor is a constexpr destructor. \pnum -If the value \tcode{true} or \tcode{false} is stored into a bit-field of -type \tcode{bool} of any size (including a one bit bit-field), the -original \tcode{bool} value and the value of the bit-field shall compare -equal. If the value of an enumerator is stored into a bit-field of the -same enumeration type and the number of bits in the bit-field is large -enough to hold all the values of that enumeration type~(\ref{dcl.enum}), -the original enumerator value and the value of the bit-field shall -compare equal. -\enterexample +Before a +defaulted destructor for a class is implicitly defined, all the non-user-provided +destructors for its base classes and its non-static data members are +implicitly defined. -\begin{codeblock} -enum BOOL { FALSE=0, TRUE=1 }; -struct A { - BOOL b:1; -}; -A a; -void f() { - a.b = TRUE; - if (a.b == TRUE) // yields \tcode{true} - { /* ... */ } -} -\end{codeblock} -\exitexample +\pnum +\indextext{destructor!virtual}% +\indextext{destructor!pure virtual}% +A prospective destructor can be +declared \keyword{virtual}\iref{class.virtual} +and with a \grammarterm{pure-specifier}\iref{class.abstract}. +If the destructor of a class is virtual and +any objects of that class or any derived class are created in the program, +the destructor shall be defined. -\rSec1[class.nest]{Nested class declarations}% -\indextext{definition!nested~class}% -\indextext{class~local|see{local~class}}% -\indextext{class~nested|see{nested~class}} +\pnum +\begin{note} +\indextext{member function!destructor and}% +Some language constructs have special semantics when used during destruction; +see~\ref{class.cdtor}. +\end{note} \pnum -A class can be declared within another class. A class declared within -another is called a \grammarterm{nested} class. The name of a nested class -is local to its enclosing class. -\indextext{nested~class!scope~of}% -The nested class is in the scope of its enclosing class. -\enternote -See~\ref{expr.prim} for restrictions on the use of non-static data -members and non-static member functions. -\exitnote +\indextext{order of execution!destructor}% +\indextext{order of execution!base class destructor}% +\indextext{order of execution!member destructor}% +After executing the body of the destructor and destroying +any objects with automatic storage duration allocated within the body, a +destructor for class +\tcode{X} +calls the destructors for +\tcode{X}'s +direct non-variant non-static data members other than anonymous unions, +the destructors for +\tcode{X}'s +non-virtual direct base classes and, if +\tcode{X} +is the most derived class\iref{class.base.init}, +its destructor calls the destructors for +\tcode{X}'s +virtual base classes. +All destructors are called as if they were referenced with a qualified name, +that is, ignoring any possible virtual overriding destructors in more +derived classes. +Bases and members are destroyed in the reverse order of the completion of +their constructor (see~\ref{class.base.init}). +\begin{note} +A +\tcode{return} +statement\iref{stmt.return} in a destructor might not directly return to the +caller; before transferring control to the caller, the destructors for the +members and bases are called. +\end{note} +\indextext{order of execution!destructor and array}% +Destructors for elements of an array are called in reverse order of their +construction (see~\ref{class.init}). -\indextext{example!nested~class}% -\enterexample +\pnum +\indextext{destructor!implicit call}% +\indextext{destructor!program termination and}% +A destructor is invoked implicitly +\begin{itemize} +\item for a constructed object with static storage duration\iref{basic.stc.static} at program termination\iref{basic.start.term}, -\begin{codeblock} -int x; -int y; +\item for a constructed object with thread storage duration\iref{basic.stc.thread} at thread exit, -struct enclose { - int x; - static int s; +\item for a constructed object with automatic storage duration\iref{basic.stc.auto} when the block in which an object is created exits\iref{stmt.dcl}, - struct inner { - void f(int i) { - int a = sizeof(x); // OK: operand of sizeof is an unevaluated operand - x = i; // error: assign to \tcode{enclose::x} - s = i; // OK: assign to \tcode{enclose::s} - ::x = i; // OK: assign to global \tcode{x} - y = i; // OK: assign to global \tcode{y} - } - void g(enclose* p, int i) { - p->x = i; // OK: assign to \tcode{enclose::x} - } - }; -}; +\item for a constructed temporary object when its lifetime ends\iref{conv.rval,class.temporary}. +\end{itemize} -inner* p = 0; // error: \tcode{inner} not in scope -\end{codeblock} -\exitexample +\indextext{\idxcode{delete}!destructor and}% +\indextext{destructor!explicit call}% +In each case, the context of the invocation is the context of the construction of +the object. A destructor may also be invoked implicitly through use of a +\grammarterm{delete-expression}\iref{expr.delete} for a constructed object allocated +by a \grammarterm{new-expression}\iref{expr.new}; the context of the invocation is the +\grammarterm{delete-expression}. +\begin{note} +An array of class type contains several subobjects for each of which +the destructor is invoked. +\end{note} +A destructor can also be invoked explicitly. A destructor is \term{potentially invoked} +if it is invoked or as specified in~\ref{expr.new}, +\ref{stmt.return}, \ref{dcl.init.aggr}, +\ref{class.base.init}, and~\ref{except.throw}. +A program is ill-formed if a destructor that is potentially invoked is deleted +or not accessible from the context of the invocation. \pnum -Member functions and static data members of a nested class can be -defined in a namespace scope enclosing the definition of their class. -\indextext{example!nested~class definition}% -\enterexample +At the point of definition of a virtual destructor (including an implicit +definition), the non-array deallocation function is +determined as if for the expression \tcode{delete this} appearing in a +non-virtual destructor of the destructor's class (see~\ref{expr.delete}). +If the lookup fails or if the deallocation function has +a deleted definition\iref{dcl.fct.def}, the program is ill-formed. +\begin{note} +This assures that a deallocation function corresponding to the dynamic type of an +object is available for the +\grammarterm{delete-expression}\iref{class.free}. +\end{note} +\pnum +\indextext{destructor!explicit call}% +In an explicit destructor call, the destructor is specified by a +\tcode{\~{}} +followed by a +\grammarterm{type-name} or \grammarterm{computed-type-specifier} +that denotes the destructor's class type. +The invocation of a destructor is subject to the usual rules for member +functions\iref{class.mfct}; +that is, if the object is not of the destructor's class type and +not of a class derived from the destructor's class type (including when +the destructor is invoked via a null pointer value), the program has +undefined behavior. +\begin{note} +Invoking \keyword{delete} on a null pointer does not call the +destructor; see \ref{expr.delete}. +\end{note} +\begin{example} \begin{codeblock} -struct enclose { - struct inner { - static int x; - void f(int i); - }; +struct B { + virtual ~B() { } +}; +struct D : B { + ~D() { } }; -int enclose::inner::x = 1; +D D_object; +typedef B B_alias; +B* B_ptr = &D_object; -void enclose::inner::f(int i) { /* ... */ } +void f() { + D_object.B::~B(); // calls \tcode{B}'s destructor + B_ptr->~B(); // calls \tcode{D}'s destructor + B_ptr->~B_alias(); // calls \tcode{D}'s destructor + B_ptr->B_alias::~B(); // calls \tcode{B}'s destructor + B_ptr->B_alias::~B_alias(); // calls \tcode{B}'s destructor +} \end{codeblock} -\exitexample +\end{example} +\begin{note} +An explicit destructor call must always be written using +a member access operator\iref{expr.ref} or a \grammarterm{qualified-id}\iref{expr.prim.id.qual}; +in particular, the +\grammarterm{unary-expression} +\tcode{\~{}X()} +in a member function is not an explicit destructor call\iref{expr.unary.op}. +\end{note} \pnum -If class \tcode{X} is defined in a namespace scope, a nested class -\tcode{Y} may be declared in class \tcode{X} and later defined in the -definition of class \tcode{X} or be later defined in a namespace scope -enclosing the definition of class \tcode{X}. -\indextext{example!nested~class forward~declaration}% -\enterexample - +\begin{note} +\indextext{object!destructor and placement of}% +Explicit calls of destructors are rarely needed. +One use of such calls is for objects placed at specific +addresses using a placement +\grammarterm{new-expression}. +Such use of explicit placement and destruction of objects can be necessary +to cope with dedicated hardware resources and for writing memory management +facilities. +\begin{example} \begin{codeblock} -class E { - class I1; // forward declaration of nested class - class I2; - class I1 { }; // definition of nested class +void* operator new(std::size_t, void* p) { return p; } +struct X { + X(int); + ~X(); }; -class E::I2 { }; // definition of nested class +void f(X* p); + +void g() { // rare, specialized use: + char* buf = new char[sizeof(X)]; + X* p = new(buf) X(222); // use \tcode{buf[]} and initialize + f(p); + p->X::~X(); // cleanup +} \end{codeblock} -\exitexample +\end{example} +\end{note} \pnum -\indextext{friend~function!nested~class}% -Like a member function, a friend function~(\ref{class.friend}) defined -within a nested class is in the lexical scope of that class; it obeys -the same rules for name binding as a static member function of that -class~(\ref{class.static}), but it has no special access rights to -members of an enclosing class. - -\rSec1[class.local]{Local class declarations} -\indextext{declaration!local~class}% -\indextext{definition!local~class}% +Once a destructor is invoked for an object, the object's lifetime ends; +the behavior is undefined 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, +and the block is subsequently left in a manner that would ordinarily +invoke implicit destruction of the object, the behavior is undefined. +\end{example} \pnum -A class can be declared within a function definition; such a class is -called a \grammarterm{local} class. The name of a local class is local to -its enclosing scope. -\indextext{local~class!scope~of}% -The local class is in the scope of the enclosing scope, and has the same -access to names outside the function as does the enclosing function. -Declarations in a local class -shall not odr-use~(\ref{basic.def.odr}) a variable with automatic storage -duration from an -enclosing scope. -\enterexample -\indextext{example!local~class}% +\begin{note} +\indextext{fundamental type!destructor and}% +The notation for explicit call of a destructor can be used for any scalar type +name\iref{expr.prim.id.dtor}. +Allowing this makes it possible to write code without having to know if a +destructor exists for a given type. +For example: \begin{codeblock} -int x; -void f() { - static int s ; - int x; - const int N = 5; - extern int q(); - - struct local { - int g() { return x; } // error: odr-use of automatic variable \tcode{x} - int h() { return s; } // OK - int k() { return ::x; } // OK - int l() { return q(); } // OK - int m() { return N; } // OK: not an odr-use - int* n() { return &N; } // error: odr-use of automatic variable \tcode{N} - }; -} - -local* p = 0; // error: \tcode{local} not in scope +typedef int I; +I* p; +p->I::~I(); \end{codeblock} -\exitexample +\end{note} \pnum -An enclosing function has no special access to members of the local -class; it obeys the usual access rules (Clause~\ref{class.access}). -\indextext{member function!local~class}% -Member functions of a local class shall be defined within their class -definition, if they are defined at all. +A destructor shall not be a coroutine. + +\rSec2[class.conv]{Conversions} + +\rSec3[class.conv.general]{General} \pnum -\indextext{nested~class!local~class}% -If class \tcode{X} is a local class a nested class \tcode{Y} may be -declared in class \tcode{X} and later defined in the definition of class -\tcode{X} or be later defined in the same scope as the definition of -class \tcode{X}. -\indextext{restriction!local~class}% -A class nested within -a local class is a local class. +\indextext{conversion!class}% +\indextext{constructor, conversion by|see{conversion, user-defined}}% +\indextext{conversion function|see{conversion, user-defined}}% +\indextext{conversion!implicit}% +Type conversions of class objects can be specified by constructors and +by conversion functions. +These conversions are called +\defnx{user-defined conversions}{conversion!user-defined} +and are used for implicit type conversions\iref{conv}, +for initialization\iref{dcl.init}, +and for explicit type conversions\iref{expr.type.conv,expr.cast, +expr.static.cast}. \pnum -A local class shall not have static data members. +User-defined conversions are applied only where they are unambiguous\iref{class.member.lookup,class.conv.fct}. +Conversions obey the access control rules\iref{class.access}. +Access control is applied after ambiguity resolution\iref{basic.lookup}. -\rSec1[class.nested.type]{Nested type names} -\indextext{type~name!nested}% -\indextext{type~name!nested!scope of}% +\pnum +\begin{note} +See~\ref{over.match} for a discussion of the use of conversions in function calls. +\end{note} \pnum -Type names obey exactly the same scope rules as other names. In -particular, type names defined within a class definition cannot be used -outside their class without qualification. -\enterexample +\indextext{conversion!implicit user-defined}% +At most one user-defined conversion (constructor or conversion function) +is implicitly applied to a single value. +\begin{example} +\begin{codeblock} +struct X { + operator int(); +}; + +struct Y { + operator X(); +}; -\indextext{example!nested type~name}% +Y a; +int b = a; // error: no viable conversion (\tcode{a.operator X().operator int()} not considered) +int c = X(a); // OK, \tcode{a.operator X().operator int()} +\end{codeblock} +\end{example} + +\rSec3[class.conv.ctor]{Conversion by constructor}% +\indextext{conversion!user-defined}% + +\pnum +A constructor that is not explicit\iref{dcl.fct.spec} +specifies a conversion from +the types of its parameters (if any) +to the type of its class. +\begin{example} +\indextext{Jessie}% \begin{codeblock} struct X { - typedef int I; - class Y { /* ... */ }; - I a; + X(int); + X(const char*, int = 0); + X(int, int); +}; + +void f(X arg) { + X a = 1; // \tcode{a = X(1)} + X b = "Jessie"; // \tcode{b = X("Jessie",0)} + a = 2; // \tcode{a = X(2)} + f(3); // \tcode{f(X(3))} + f({1, 2}); // \tcode{f(X(1,2))} +} +\end{codeblock} +\end{example} + +\pnum +\begin{note} +An explicit constructor constructs objects just like non-explicit +constructors, but does so only where the direct-initialization syntax\iref{dcl.init} +or where casts\iref{expr.static.cast,expr.cast} are explicitly +used; see also~\ref{over.match.copy}. +A default constructor can be an explicit constructor; such a constructor +will be used to perform default-initialization +or value-initialization\iref{dcl.init}. +\begin{example} +\begin{codeblock} +struct Z { + explicit Z(); + explicit Z(int); + explicit Z(int, int); }; -I b; // error -Y c; // error -X::Y d; // OK -X::I e; // OK +Z a; // OK, default-initialization performed +Z b{}; // OK, direct initialization syntax used +Z c = {}; // error: copy-list-initialization +Z a1 = 1; // error: no implicit conversion +Z a3 = Z(1); // OK, direct initialization syntax used +Z a2(1); // OK, direct initialization syntax used +Z* p = new Z(1); // OK, direct initialization syntax used +Z a4 = (Z)1; // OK, explicit cast used +Z a5 = static_cast(1); // OK, explicit cast used +Z a6 = { 3, 4 }; // error: no implicit conversion \end{codeblock} -\exitexample% +\end{example} +\end{note} + +\rSec3[class.conv.fct]{Conversion functions}% +\indextext{function!conversion}% +\indextext{fundamental type conversion|see{conversion, user-defined}}% +\indextext{conversion!user-defined}% + +\begin{bnf} +\nontermdef{conversion-function-id}\br + \keyword{operator} conversion-type-id +\end{bnf} + +\begin{bnf} +\nontermdef{conversion-type-id}\br + type-specifier-seq \opt{conversion-declarator} +\end{bnf} + +\begin{bnf} +\nontermdef{conversion-declarator}\br + ptr-operator \opt{conversion-declarator} +\end{bnf} + +\pnum +A declaration +whose \grammarterm{declarator-id} has +an \grammarterm{unqualified-id} that is a \grammarterm{conversion-function-id} +declares a \defnadj{conversion}{function}; +its \grammarterm{declarator} shall be +a function declarator\iref{dcl.fct} of the form +\begin{ncsimplebnf} +noptr-declarator parameters-and-qualifiers +\end{ncsimplebnf} +where the \grammarterm{noptr-declarator} consists solely of +an \grammarterm{id-expression}, +an optional \grammarterm{attribute-specifier-seq}, and +optional surrounding parentheses, and +the \grammarterm{id-expression} has one of the following forms: +\begin{itemize} +\item +in a \grammarterm{member-declaration} that belongs to +the \grammarterm{member-specification} of a class or class template +but is not a friend declaration\iref{class.friend}, +the \grammarterm{id-expression} is a \grammarterm{conversion-function-id}; +\item +otherwise, the \grammarterm{id-expression} is a \grammarterm{qualified-id} +whose \grammarterm{unqualified-id} is a \grammarterm{conversion-function-id}. +\end{itemize} + +\pnum +A conversion function shall have no non-object parameters and +shall be a non-static member function of a class or class template \tcode{X}; +its declared return type is the \grammarterm{conversion-type-id} and +it specifies a conversion from \tcode{X} to +the type specified by the \grammarterm{conversion-type-id}, +interpreted as a \grammarterm{type-id}\iref{dcl.name}. +A \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq} +of a conversion function (if any) shall not be +a \grammarterm{defining-type-specifier}. + +\pnum +\begin{note} +A conversion function is never invoked for +implicit or explicit conversions of an object +to the same object type (or a reference to it), +to a base class of that type (or a reference to it), +or to \cv{}~\keyword{void}. +Even though never directly called to perform a conversion, +such conversion functions can be declared and can potentially +be reached through a call to a virtual conversion function in a base class. +\end{note} +\begin{example} +\begin{codeblock} +struct X { + operator int(); + operator auto() -> short; // error: trailing return type +}; + +void f(X a) { + int i = int(a); + i = (int)a; + i = a; +} +\end{codeblock} +In all three cases the value assigned will be converted by +\tcode{X::operator int()}. +\end{example} + +\pnum +A conversion function may be explicit\iref{dcl.fct.spec}, in which case it is only considered as a user-defined conversion for direct-initialization\iref{dcl.init}. Otherwise, user-defined conversions are not restricted to use in assignments and initializations. +\begin{example} +\begin{codeblock} +class Y { }; +struct Z { + explicit operator Y() const; +}; + +void h(Z z) { + Y y1(z); // OK, direct-initialization + Y y2 = z; // error: no conversion function candidate for copy-initialization + Y y3 = (Y)z; // OK, cast notation +} + +void g(X a, X b) { + int i = (a) ? 1+a : 0; + int j = (a&&b) ? a+b : i; + if (a) { + } +} +\end{codeblock} +\end{example} + +\pnum +The +\grammarterm{conversion-type-id} +shall not represent a function type nor an array type. +The +\grammarterm{conversion-type-id} +in a +\grammarterm{conversion-function-id} +is the longest sequence of +tokens that could possibly form a \grammarterm{conversion-type-id}. +\begin{note} +This prevents ambiguities between the declarator operator \tcode{*} and its expression +counterparts. +\begin{example} +\begin{codeblock} +&ac.operator int*i; // syntax error: + // parsed as: \tcode{\&(ac.operator int *)i} + // not as: \tcode{\&(ac.operator int)*i} +\end{codeblock} +The \tcode{*} is the pointer declarator and not the multiplication operator. +\end{example} +This rule also prevents ambiguities for attributes. +\begin{example} +\begin{codeblock} +operator int [[noreturn]] (); // error: \tcode{noreturn} attribute applied to a type +\end{codeblock} +\end{example} +\end{note} + +\pnum +\indextext{conversion!inheritance of user-defined}% +\begin{note} +A conversion function in a derived class hides only +conversion functions in base classes that convert to the same type. +A conversion function template with a dependent return type hides only +templates in base classes that correspond to it\iref{class.member.lookup}; +otherwise, it hides and is hidden as a non-template function. +Function overload resolution\iref{over.match.best} selects +the best conversion function to perform the conversion. +\begin{example} +\begin{codeblock} +struct X { + operator int(); +}; + +struct Y : X { + operator char(); +}; + +void f(Y& a) { + if (a) { // error: ambiguous between \tcode{X::operator int()} and \tcode{Y::operator char()} + } +} +\end{codeblock} +\end{example} +\end{note} + +\pnum +\indextext{conversion!virtual user-defined}% +Conversion functions can be virtual. + +\pnum +\indextext{conversion!deduced return type of user-defined}% +A conversion function template shall not have a +deduced return type\iref{dcl.spec.auto}. +\begin{example} +\begin{codeblock} +struct S { + template + operator auto() const { return 1.2; } // error: conversion function template +}; +\end{codeblock} +\end{example} + +\rSec2[class.static]{Static members}% + +\rSec3[class.static.general]{General}% +\indextext{member!static}% + +\pnum +A static member \tcode{s} of class \tcode{X} may be referred to +using the \grammarterm{qualified-id} expression \tcode{X::s}; it is not +necessary to use the class member access syntax\iref{expr.ref} to +refer to a static member. A static member may be +referred to using the class member access syntax, in which case the +object expression is evaluated. +\begin{example} +\begin{codeblock} +struct process { + static void reschedule(); +}; +process& g(); + +void f() { + process::reschedule(); // OK, no object necessary + g().reschedule(); // \tcode{g()} is called +} +\end{codeblock} +\end{example} + +\pnum +Static members obey the usual class member access rules\iref{class.access}. +When used in the declaration of a class +member, the \keyword{static} specifier shall only be used in the member +declarations that appear within the \grammarterm{member-specification} of +the class definition. +\begin{note} +It cannot be specified in member declarations that appear in namespace scope. +\end{note} + +\rSec3[class.static.mfct]{Static member functions} +\indextext{member function!static}% + +\pnum +\begin{note} +The rules described in~\ref{class.mfct} apply to static member +functions. +\end{note} + +\pnum +\begin{note} +A static member function does not have a \keyword{this} +pointer\iref{expr.prim.this}. +A static member function cannot be qualified with \keyword{const}, +\tcode{volatile}, or \keyword{virtual}\iref{dcl.fct}. +\end{note} + +\rSec3[class.static.data]{Static data members} +\indextext{member data!static}% + +\pnum +A static data member is not part of the subobjects of a class. If a +static data member is declared \keyword{thread_local} there is one copy of +the member per thread. If a static data member is not declared +\keyword{thread_local} there is one copy of the data member that is shared by all +the objects of the class. + +\pnum +A static data member shall not be \keyword{mutable}\iref{dcl.stc}. +A static data member shall not be a direct member\iref{class.mem} +of an unnamed\iref{class.pre} or local\iref{class.local} class or +of a (possibly indirectly) nested class\iref{class.nest} thereof. + +\pnum +\indextext{initialization!static member}% +\indextext{definition!static member}% +The declaration of a non-inline +static data member in its class definition +is not a definition and may be of an incomplete type other than +\cv{}~\keyword{void}. +\indextext{operator use!scope resolution}% +\begin{note} +The \grammarterm{initializer} in the definition of a +static data member is in the scope of its +class\iref{basic.scope.class}. +\end{note} +\begin{example} +\begin{codeblock} +class process { + static process* run_chain; + static process* running; +}; + +process* process::running = get_main(); +process* process::run_chain = running; +\end{codeblock} + +The definition of the static data member \tcode{run_chain} of class +\tcode{process} inhabits the global scope; the notation +\tcode{process::run_chain} indicates that the member \tcode{run_chain} +is a member of class \tcode{process} and in the scope of class +\tcode{process}. In the static data member definition, the +\grammarterm{initializer} expression refers to the static data +member \tcode{running} of class \tcode{process}. +\end{example} + +\begin{note} +Once the static data member has been defined, it exists even if +no objects of its class have been created. +\begin{example} +In the example above, \tcode{run_chain} and \tcode{running} exist even +if no objects of class \tcode{process} are created by the program. +\end{example} +The initialization and destruction of static data members is described in +\ref{basic.start.static}, \ref{basic.start.dynamic}, and \ref{basic.start.term}. +\end{note} + +\pnum +If a non-volatile non-inline \keyword{const} static data member is +of integral or enumeration type, +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.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}. +The declaration of an inline static data member (which is a definition) +may specify a \grammarterm{brace-or-equal-initializer}. If the +member is declared with the \keyword{constexpr} specifier, it may be +redeclared in namespace scope with no initializer (this usage is +deprecated; see \ref{depr.static.constexpr}). Declarations of other +static data members shall not specify a \grammarterm{brace-or-equal-initializer}. + +\pnum +\begin{note} +There is exactly one definition of a static data member +that is odr-used\iref{term.odr.use} in a valid program. +\end{note} + +\pnum +\begin{note} +Static data members of a class in namespace scope have the linkage of the name of the class\iref{basic.link}. +\end{note} + +\rSec2[class.bit]{Bit-fields}% +\indextext{bit-field} + +\pnum +A \grammarterm{member-declarator} of the form +\begin{ncsimplebnf} +\opt{identifier} \opt{attribute-specifier-seq} \terminal{:} constant-expression \opt{brace-or-equal-initializer} +\end{ncsimplebnf} +\indextext{\idxcode{:}!bit-field declaration}% +\indextext{declaration!bit-field}% +specifies a bit-field. +The optional \grammarterm{attribute-specifier-seq} appertains +to the entity being declared. +A bit-field shall not be a static member. +\indextext{bit-field!type of}% +A bit-field shall have integral or (possibly cv-qualified) enumeration type; +the bit-field semantic property is not part of the type of the class member. +The \grammarterm{constant-expression} shall be an integral constant expression +with a value greater than or equal to zero and +is called the \defn{width} of the bit-field. +If the width of a bit-field is larger than +the width of the bit-field's type +(or, in case of an enumeration type, of its underlying type), +the extra bits are padding bits\iref{term.padding.bits}. +\indextext{allocation!implementation-defined bit-field}% +Allocation of bit-fields within a class object is +\impldef{allocation of bit-fields within a class object}. +\indextext{bit-field!implementation-defined alignment of}% +Alignment of bit-fields is \impldef{alignment of bit-fields within a class object}. +\indextext{layout!bit-field}% +Bit-fields are packed into some addressable allocation unit. +\begin{note} +Bit-fields straddle allocation units on some machines and not on others. +Bit-fields are assigned right-to-left on some machines, left-to-right on +others. +\end{note} + +\pnum +A declaration for a bit-field that omits the \grammarterm{identifier} +declares an \defnadj{unnamed}{bit-field}. Unnamed bit-fields are not +members and cannot be initialized. +An unnamed bit-field shall not be declared with a cv-qualified type. +\begin{note} +An unnamed bit-field is useful for padding to conform to +externally-imposed layouts. +\end{note} +\indextext{bit-field!zero width of}% +\indextext{bit-field!alignment of}% +As a special case, an unnamed bit-field with a width of zero specifies +alignment of the next bit-field at an allocation unit boundary. Only +when declaring an unnamed bit-field may the width be zero. + +\pnum +\indextext{bit-field!address of}% +The address-of operator \tcode{\&} shall not be applied to a bit-field, +so there are no pointers to bit-fields. +\indextext{restriction!bit-field}% +\indextext{restriction!address of bit-field}% +\indextext{restriction!pointer to bit-field}% +A non-const reference shall not bind to a bit-field\iref{dcl.init.ref}. +\begin{note} +If the initializer for a reference of type \keyword{const} \tcode{T\&} is +an lvalue that refers to a bit-field, the reference is bound to a +temporary initialized to hold the value of the bit-field; the reference +is not bound to the bit-field directly. See~\ref{dcl.init.ref}. +\end{note} + +\pnum +If a value of integral type (other than \tcode{bool}) is stored +into a bit-field of width $N$ and the value would be representable +in a hypothetical signed or unsigned integer type +with width $N$ and the same signedness as the bit-field's type, +the original value and the value of the bit-field compare equal. +If the value \tcode{true} or \tcode{false} is stored into a bit-field of +type \tcode{bool} of any size (including a one bit bit-field), the +original \tcode{bool} value and the value of the bit-field compare +equal. If a value of an enumeration type is stored into a bit-field of the +same type and the width is large +enough to hold all the values of that enumeration type\iref{dcl.enum}, +the original value and the value of the bit-field compare equal. +\begin{example} +\begin{codeblock} +enum BOOL { FALSE=0, TRUE=1 }; +struct A { + BOOL b:1; +}; +A a; +void f() { + a.b = TRUE; + if (a.b == TRUE) // yields \tcode{true} + { @\commentellip@ } +} +\end{codeblock} +\end{example} + +\rSec2[class.free]{Allocation and deallocation functions}% +\indextext{free store}% + +\pnum +\indextext{\idxcode{new}!type of}% +\indextext{allocation function!class-specific}% +Any allocation function for a class +\tcode{T} +is a static member (even if not explicitly declared +\keyword{static}). + +\pnum +\begin{example} +\begin{codeblock} +class Arena; +struct B { + void* operator new(std::size_t, Arena*); +}; +struct D1 : B { +}; + +Arena* ap; +void foo(int i) { + new (ap) D1; // calls \tcode{B::operator new(std::size_t, Arena*)} + new D1[i]; // calls \tcode{::operator new[](std::size_t)} + new D1; // error: \tcode{::operator new(std::size_t)} hidden +} +\end{codeblock} +\end{example} + +\pnum +\indextext{\idxcode{delete}!type of}% +\indextext{deallocation function!class-specific}% +Any deallocation function for a class +\tcode{X} +is a static member (even if not explicitly declared +\keyword{static}). +\begin{example} +\begin{codeblock} +class X { + void operator delete(void*); + void operator delete[](void*, std::size_t); +}; + +class Y { + void operator delete(void*, std::size_t); + void operator delete[](void*); +}; +\end{codeblock} +\end{example} + +\pnum +Since member allocation and deallocation functions are +\keyword{static} +they cannot be virtual. +\begin{note} +However, when the +\grammarterm{cast-expression} +of a +\grammarterm{delete-expression} +refers to an object of class type with a virtual destructor, +because the deallocation function is chosen by the destructor +of the dynamic type of the object, the effect is the same in that case. +\begin{example} +\begin{codeblock} +struct B { + virtual ~B(); + void operator delete(void*, std::size_t); +}; + +struct D : B { + void operator delete(void*); +}; + +struct E : B { + void log_deletion(); + void operator delete(E *p, std::destroying_delete_t) { + p->log_deletion(); + p->~E(); + ::operator delete(p); + } +}; + +void f() { + B* bp = new D; + delete bp; // 1: uses \tcode{D::operator delete(void*)} + bp = new E; + delete bp; // 2: uses \tcode{E::operator delete(E*, std::destroying_delete_t)} +} +\end{codeblock} +Here, storage for the object of class +\tcode{D} +is deallocated by +\tcode{D::operator delete()}, +and +the object of class \tcode{E} is destroyed +and its storage is deallocated +by \tcode{E::operator delete()}, +due to the virtual destructor. +\end{example} +\end{note} +\begin{note} +Virtual destructors have no effect on the deallocation function actually +called when the +\grammarterm{cast-expression} +of a +\grammarterm{delete-expression} +refers to an array of objects of class type. +\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} +\end{note} + +\pnum +Access to the deallocation function is checked statically, +even if a different one is actually executed. +\begin{example} +For the call on line ``// 1'' above, +if +\tcode{B::operator delete()} +had been private, the delete expression would have been ill-formed. +\end{example} + +\pnum +\begin{note} +If a deallocation function has no explicit \grammarterm{noexcept-specifier}, it +has a non-throwing exception specification\iref{except.spec}. +\end{note} + +\rSec2[class.nest]{Nested class declarations}% +\indextext{definition!nested class}% + +\pnum +A class can be declared within another class. A class declared within +another is called a \defnadj{nested}{class}. +\begin{note} +See~\ref{expr.prim.id} for restrictions on the use of non-static data +members and non-static member functions. +\end{note} + +\begin{example} +\begin{codeblock} +int x; +int y; + +struct enclose { + int x; + static int s; + + struct inner { + void f(int i) { + int a = sizeof(x); // OK, operand of sizeof is an unevaluated operand + x = i; // error: assign to \tcode{enclose::x} + s = i; // OK, assign to \tcode{enclose::s} + ::x = i; // OK, assign to global \tcode{x} + y = i; // OK, assign to global \tcode{y} + } + void g(enclose* p, int i) { + p->x = i; // OK, assign to \tcode{enclose::x} + } + }; +}; + +inner* p = 0; // error: \tcode{inner} not found +\end{codeblock} +\end{example} + +\pnum +\begin{note} +Nested classes can be defined +either in the enclosing class or in an enclosing namespace; +member functions and static data members of a nested class can be +defined either in the nested class or in an enclosing namespace scope. +\begin{example} +\begin{codeblock} +struct enclose { + struct inner { + static int x; + void f(int i); + }; +}; + +int enclose::inner::x = 1; + +void enclose::inner::f(int i) { @\commentellip@ } + +class E { + class I1; // forward declaration of nested class + class I2; + class I1 { }; // definition of nested class +}; +class E::I2 { }; // definition of nested class +\end{codeblock} +\end{example} +\end{note} + +\pnum +\indextext{friend function!nested class}% +A friend function\iref{class.friend} defined +within a nested class has no special access rights to +members of an enclosing class. + +\rSec1[class.union]{Unions}% + +\rSec2[class.union.general]{General}% +\indextext{\idxcode{union}} + +\pnum +A \defn{union} is a class defined with the \grammarterm{class-key} +\keyword{union}. + +\pnum +In a union, +a non-static data member is \defnx{active}{active!union member} +if its name refers to an object +whose lifetime has begun and has not ended\iref{basic.life}. +At most one of the non-static data members of an object of union type +can be active at any +time, that is, the value of at most one of the non-static data members can be +stored in a union at any time. +\begin{note} +One special guarantee is made in order to +simplify the use of unions: If a standard-layout union contains several standard-layout +structs that share a common initial sequence\iref{class.mem}, and +if a non-static data member of an object of this standard-layout union type +is active and is one of the standard-layout structs, +the common initial sequence of any of the standard-layout struct members can be inspected; +see~\ref{class.mem}. +\end{note} + +\pnum +The size of a union is sufficient to contain the largest +of its non-static data members. Each non-static data member is allocated +as if it were the sole member of a non-union class. +\begin{note} +A union object and its non-static data members are +pointer-interconvertible\iref{basic.compound,expr.static.cast}. +As a consequence, all non-static data members of a +union object have the same address. +\end{note} + +\pnum +\indextext{member function!\idxcode{union}}% +\indextext{constructor!\idxcode{union}}% +\indextext{destructor!\idxcode{union}}% +A union can have member functions (including constructors and destructors), +\indextext{restriction!\idxcode{union}}% +but it shall not have virtual\iref{class.virtual} functions. A union shall not have +base classes. A union shall not be used as a base class. +\indextext{restriction!\idxcode{union}}% +If a union contains a non-static data member of +reference type, the program is ill-formed. +\begin{note} +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} +Consider the following union: +\begin{codeblock} +union U { + int i; + float f; + std::string s; +}; +\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 +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} + +\pnum +When the left operand of an assignment operator +involves a member access expression\iref{expr.ref} +that nominates a union member, +it may begin the lifetime of that union member, +as described below. +For an expression \tcode{E}, +define the set $S(\mathtt{E})$ +of subexpressions of \tcode{E} +as follows: +\begin{itemize} +\item +If \tcode{E} is of the form \tcode{A.B}, +$S(\mathtt{E})$ contains the elements of $S(\mathtt{A})$, +and also contains \tcode{A.B} +if \tcode{B} names a union member of a non-class, non-array type, +or of a class type with a trivial default constructor that is not deleted, +or an array of such types. +\item +If \tcode{E} is of the form \tcode{A[B]} +and is interpreted as a built-in array subscripting operator, +$S(\mathtt{E})$ is $S(\mathtt{A})$ if \tcode{A} is of array type, +$S(\mathtt{B})$ if \tcode{B} is of array type, +and empty otherwise. +\item +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.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 +is a member of a union and +has such an element as an immediate subobject (recursively), +if modification of \tcode{X} would have undefined behavior under~\ref{basic.life}, +an object of the type of \tcode{X} is implicitly created +in the nominated storage; +no initialization is performed and +the beginning of its lifetime is sequenced after +the value computation of the left and right operands +and before the assignment. +\begin{note} +This ends the lifetime of the previously-active +member of the union, if any\iref{basic.life}. +\end{note} +\begin{example} +\begin{codeblock} +union A { int x; int y[4]; }; +struct B { A a; }; +union C { B b; int k; }; +int f() { + C c; // does not start lifetime of any union member + c.b.a.y[3] = 4; // OK, $S($\tcode{c.b.a.y[3]}$)$ contains \tcode{c.b} and \tcode{c.b.a.y}; + // creates objects to hold union members \tcode{c.b} and \tcode{c.b.a.y} + return c.b.a.y[3]; // OK, \tcode{c.b.a.y} refers to newly created object (see \ref{basic.life}) +} + +struct X { const int a; int b; }; +union Y { X x; int k; }; +void g() { + Y y = { { 1, 2 } }; // OK, \tcode{y.x} is active union member\iref{class.mem} + int n = y.x.a; + y.k = 4; // OK, ends lifetime of \tcode{y.x}, \tcode{y.k} is active member of union + y.x.b = n; // undefined behavior: \tcode{y.x.b} modified outside its lifetime, + // $S($\tcode{y.x.b}$)$ is empty because \tcode{X}'s default constructor is deleted, + // so union member \tcode{y.x}'s lifetime does not implicitly start +} +\end{codeblock} +\end{example} + +\pnum +\begin{note} +In cases where the above rule does not apply, +the active member of a union can only be changed by +the use of a placement \grammarterm{new-expression}. +\end{note} +\begin{example} +Consider an object \tcode{u} of a \keyword{union} type \tcode{U} having non-static data members +\tcode{m} of type \tcode{M} and \tcode{n} of type \tcode{N}. If \tcode{M} has a non-trivial +destructor and \tcode{N} has a non-trivial constructor (for instance, if they declare or inherit +virtual functions), the active member of \tcode{u} can be safely switched from \tcode{m} to +\tcode{n} using the destructor and placement \grammarterm{new-expression} as follows: + +\begin{codeblock} +u.m.~M(); +new (&u.n) N; +\end{codeblock} +\end{example} + +\rSec2[class.union.anon]{Anonymous unions} +\indextext{\idxcode{union}!anonymous}% + +\pnum +\indextext{anonymous union!member|see{member, anonymous union}}% +\indextext{anonymous union!variable|see{variable, anonymous union}}% +A union of the form +\begin{ncsimplebnf} +\keyword{union} \terminal{\{} member-specification \terminal{\}} \terminal{;} +\end{ncsimplebnf} +is called an \defn{anonymous union}; it defines an unnamed type and +an unnamed object of that type called +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 define one or more public non-static data members, +be an \grammarterm{empty-declaration}, or +be a \grammarterm{static_assert-declaration}. +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. +\begin{example} +\begin{codeblock} +void f() { + union { int a; const char* p; }; + a = 1; + p = "Jennifer"; +} +\end{codeblock} + +Here \tcode{a} and \tcode{p} are used like ordinary (non-member) +variables, but since they are union members they have the same address. +\end{example} + +\pnum +\indextext{\idxcode{union}!global anonymous}% +\indextext{scope!anonymous \tcode{union} at namespace}% +An anonymous union declared in the scope of a namespace with external linkage +shall use the \grammarterm{storage-class-specifier} \keyword{static}. +Anonymous unions declared at block scope shall not use a \grammarterm{storage-class-specifier} +that is not permitted in the declaration of a block variable. +An anonymous union declaration at class scope shall not have +a \grammarterm{storage-class-specifier}. + +\pnum +\begin{note} +A union for which objects, pointers, or references are declared is not an anonymous union. +\begin{example} +\begin{codeblock} +void f() { + union { int aa; char* p; } obj, *ptr = &obj; + aa = 1; // error + ptr->aa = 1; // OK +} +\end{codeblock} + +The assignment to plain \tcode{aa} is ill-formed since the member name +is not visible outside the union, and even if it were visible, it is not +associated with any particular object. +\end{example} +\end{note} +\begin{note} +Initialization of unions with no user-declared constructors is described +in~\ref{dcl.init.aggr}. +\end{note} + +\pnum +\indextext{class!variant member of}% +A \defnadj{union-like}{class} is a union or a class that has an anonymous union as a direct +member. A union-like class \tcode{X} has a set of \defnx{variant members}{variant member}. +If \tcode{X} is a union, a non-static data member of \tcode{X} that is not an anonymous +union is a variant member of \tcode{X}. In addition, a non-static data member of an +anonymous union that is a member of \tcode{X} is also a variant member of \tcode{X}. +At most one variant member of a union may have a default member initializer. +\begin{example} +\begin{codeblock} +union U { + int x = 0; + union { + int k; + }; + union { + int z; + int y = 1; // error: initialization for second variant member of \tcode{U} + }; +}; +\end{codeblock} +\end{example} + +\rSec1[class.local]{Local class declarations} +\indextext{declaration!local class}% +\indextext{definition!local class}% +\indextext{class!local|see{local class}}% + +\pnum +A class can be declared within a function definition; such a class is +called a \defnadj{local}{class}. +\begin{note} +A declaration in a local class +cannot odr-use\iref{term.odr.use} +a local entity +from an +enclosing scope. +\end{note} +\begin{example} +\begin{codeblock} +int x; +void f() { + static int s; + int x; + const int N = 5; + extern int q(); + int arr[2]; + auto [y, z] = arr; + + struct local { + int g() { return x; } // error: odr-use of non-odr-usable variable \tcode{x} + int h() { return s; } // OK + int k() { return ::x; } // OK + int l() { return q(); } // OK + int m() { return N; } // OK, not an odr-use + int* n() { return &N; } // error: odr-use of non-odr-usable variable \tcode{N} + int p() { return y; } // error: odr-use of non-odr-usable structured binding \tcode{y} + }; +} + +local* p = 0; // error: \tcode{local} not found +\end{codeblock} +\end{example} + +\pnum +An enclosing function has no special access to members of the local +class; it obeys the usual access rules\iref{class.access}. +\indextext{member function!local class}% +Member functions of a local class shall be defined within their class +definition, if they are defined at all. + +\pnum +\indextext{nested class!local class}% +\indextext{restriction!local class}% +A class nested within +a local class is a local class. +A member of a local class \tcode{X} shall be +declared only in the definition of \tcode{X} or, +if the member is a nested class, +in the nearest enclosing block scope of \tcode{X}. + +\pnum +\indextext{restriction!static member local class}% +\begin{note} +A local class cannot have static data members\iref{class.static.data}. +\end{note} + +\rSec1[class.derived]{Derived classes}% + +\rSec2[class.derived.general]{General}% +\indextext{derived class|(} + +\indextext{virtual base class|see{base class, virtual}} +\indextext{virtual function|see{function, virtual}} +\indextext{dynamic binding|see{function, virtual}} + +\pnum +\indextext{base class}% +\indextext{inheritance}% +\indextext{multiple inheritance}% +A list of base classes can be specified in a class definition using +the notation: + +\begin{bnf} +\nontermdef{base-clause}\br + \terminal{:} base-specifier-list +\end{bnf} + + +\begin{bnf} +\nontermdef{base-specifier-list}\br + base-specifier \opt{\terminal{...}}\br + base-specifier-list \terminal{,} base-specifier \opt{\terminal{...}} +\end{bnf} + +\begin{bnf} +\nontermdef{base-specifier}\br + \opt{attribute-specifier-seq} class-or-decltype\br + \opt{attribute-specifier-seq} \keyword{virtual} \opt{access-specifier} class-or-decltype\br + \opt{attribute-specifier-seq} access-specifier \opt{\keyword{virtual}} class-or-decltype +\end{bnf} + +\begin{bnf} +\nontermdef{class-or-decltype}\br + \opt{nested-name-specifier} type-name\br + nested-name-specifier \keyword{template} simple-template-id\br + computed-type-specifier +\end{bnf} + +\indextext{specifier access|see{access specifier}}% +% +\begin{bnf} +\nontermdef{access-specifier}\br + \keyword{private}\br + \keyword{protected}\br + \keyword{public} +\end{bnf} + +The optional \grammarterm{attribute-specifier-seq} appertains to the \grammarterm{base-specifier}. + +\pnum +\indextext{component name}% +The component names of a \grammarterm{class-or-decltype} are those of its +\grammarterm{nested-name-specifier}, +\grammarterm{type-name}, and/or +\grammarterm{simple-template-id}. +\indextext{type!incomplete}% +A \grammarterm{class-or-decltype} shall denote +a (possibly cv-qualified) class type that is not +an incompletely defined class\iref{class.mem}; +any cv-qualifiers are ignored. +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 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 +the \grammarterm{type-name} or \grammarterm{simple-template-id} +is type-only\iref{basic.lookup}. +A class \tcode{B} is a +base class of a class \tcode{D} if it is a direct base class of +\tcode{D} or a direct base class of one of \tcode{D}'s base classes. +A class is an \defnadj{indirect}{base class} of another if it is a base +class but not a direct base class. A class is said to be (directly or +indirectly) \term{derived} from its (direct or indirect) base +classes. +\begin{note} +See \ref{class.access} for the meaning of +\grammarterm{access-specifier}. +\end{note} +\indextext{access control!base class member}% +Members of a base class are also members of the derived class. +\begin{note} +Constructors of a base class can be explicitly inherited\iref{namespace.udecl}. +Base class members can be referred to in +expressions in the same manner as other members of the derived class, +unless their names are hidden or ambiguous\iref{class.member.lookup}. +\indextext{operator!scope resolution}% +The scope resolution operator \tcode{::}\iref{expr.prim.id.qual} can be used +to refer to a direct or indirect base member explicitly, +even if it is hidden in the derived class. +A derived class can itself serve as a base class subject to access +control; see~\ref{class.access.base}. A pointer to a derived class can be +implicitly converted to a pointer to an accessible unambiguous base +class\iref{conv.ptr}. An lvalue of a derived class type can be bound +to a reference to an accessible unambiguous base +class\iref{dcl.init.ref}. +\end{note} + +\pnum +The \grammarterm{base-specifier-list} specifies the type of the +\term{base class subobjects} contained in an +object of the derived class type. +\begin{example} +\begin{codeblock} +struct Base { + int a, b, c; +}; +\end{codeblock} + +\begin{codeblock} +struct Derived : Base { + int b; +}; +\end{codeblock} + +\begin{codeblock} +struct Derived2 : Derived { + int c; +}; +\end{codeblock} + +Here, an object of class \tcode{Derived2} will have a subobject of class +\tcode{Derived} which in turn will have a subobject of class +\tcode{Base}. +\end{example} + +\pnum +A \grammarterm{base-specifier} followed by an ellipsis is a pack +expansion\iref{temp.variadic}. + +\pnum +The order in which the base class subobjects are allocated in the most +derived object\iref{intro.object} is unspecified. +\begin{note} +\indextext{directed acyclic graph|see{DAG}}% +\indextext{lattice|see{DAG}}% +\indextext{lattice|see{subobject}}% +A derived class and its base class subobjects can be represented by a +directed acyclic graph (DAG) where an arrow means ``directly derived +from'' (see \fref{class.dag}). +An arrow need not have a physical representation in memory. +A DAG of subobjects is often referred to as a ``subobject lattice''. +\end{note} + +\begin{importgraphic} +{Directed acyclic graph} +{class.dag} +{figdag.pdf} +\end{importgraphic} + +\pnum +\begin{note} +Initialization of objects representing base classes can be specified in +constructors; see~\ref{class.base.init}. +\end{note} + +\pnum +\begin{note} +A base class subobject can have a layout different +from the layout of a most derived object of the same type. A base class +subobject can have a polymorphic behavior\iref{class.cdtor} +different from the polymorphic behavior of a most derived object of the +same type. A base class subobject can be of zero size; +however, two subobjects that have the same class type and that belong to +the same most derived object cannot be allocated at the same +address\iref{intro.object}. +\end{note} + +\rSec2[class.mi]{Multiple base classes} +\indextext{multiple inheritance}% +\indextext{base class}% + +\pnum +A class can be derived from any number of base classes. +\begin{note} +The use of more than one direct base class is often called multiple inheritance. +\end{note} +\begin{example} +\begin{codeblock} +class A { @\commentellip@ }; +class B { @\commentellip@ }; +class C { @\commentellip@ }; +class D : public A, public B, public C { @\commentellip@ }; +\end{codeblock} +\end{example} + +\pnum +\indextext{layout!class object}% +\indextext{initialization!order of}% +\begin{note} +The order of derivation is not significant except as specified by the +semantics of initialization by constructor\iref{class.base.init}, +cleanup\iref{class.dtor}, and storage +layout\iref{class.mem,class.access.spec}. +\end{note} + +\pnum +A class shall not be specified as a direct base class of a derived class +more than once. +\begin{note} +A class can be an indirect base class more than once and can be a direct +and an indirect base class. There are limited things that can be done +with such a class; +lookup that finds its non-static data members and member functions +in the scope of the derived class will be ambiguous. +However, the static members, enumerations and types can be +unambiguously referred to. +\end{note} +\begin{example} +\begin{codeblock} +class X { @\commentellip@ }; +class Y : public X, public X { @\commentellip@ }; // error + +\end{codeblock} +\begin{codeblock} +class L { public: int next; @\commentellip@ }; +class A : public L { @\commentellip@ }; +class B : public L { @\commentellip@ }; +class C : public A, public B { void f(); @\commentellip@ }; // well-formed +class D : public A, public L { void f(); @\commentellip@ }; // well-formed +\end{codeblock} +\end{example} + +\pnum +\indextext{base class!virtual}% +A base class specifier that does not contain the keyword +\keyword{virtual} specifies a \defnadj{non-virtual}{base class}. A base +class specifier that contains the keyword \keyword{virtual} specifies a +\defnadj{virtual}{base class}. For each distinct occurrence of a +non-virtual base class in the class lattice of the most derived class, +the most derived object\iref{intro.object} shall contain a +corresponding distinct base class subobject of that type. For each +distinct base class that is specified virtual, the most derived object +shall contain a single base class subobject of that type. + +\pnum +\begin{note} +For an object of class type \tcode{C}, each distinct occurrence of a +(non-virtual) base class \tcode{L} in the class lattice of \tcode{C} +corresponds one-to-one with a distinct \tcode{L} subobject within the +object of type \tcode{C}. Given the class \tcode{C} defined above, an +object of class \tcode{C} will have two subobjects of class \tcode{L} as +shown in \fref{class.nonvirt}. + +\begin{importgraphic} +{Non-virtual base} +{class.nonvirt} +{fignonvirt.pdf} +\end{importgraphic} + +In such lattices, explicit qualification can be used to specify which +subobject is meant. The body of function \tcode{C::f} can refer to the +member \tcode{next} of each \tcode{L} subobject: +\begin{codeblock} +void C::f() { A::next = B::next; } // well-formed +\end{codeblock} +Without the \tcode{A::} or \tcode{B::} qualifiers, the definition of +\tcode{C::f} above would be ill-formed because of +ambiguity\iref{class.member.lookup}. +\end{note} + +\pnum +\begin{note} +In contrast, consider the case with a virtual base class: +\begin{codeblock} +class V { @\commentellip@ }; +class A : virtual public V { @\commentellip@ }; +class B : virtual public V { @\commentellip@ }; +class C : public A, public B { @\commentellip@ }; +\end{codeblock} +\begin{importgraphic} +{Virtual base} +{class.virt} +{figvirt.pdf} +\end{importgraphic} +For an object \tcode{c} of class type \tcode{C}, a single subobject of +type \tcode{V} is shared by every base class subobject of \tcode{c} that has a +\keyword{virtual} base class of type \tcode{V}. Given the class \tcode{C} +defined above, an object of class \tcode{C} will have one subobject of +class \tcode{V}, as shown in \fref{class.virt}. +\indextext{DAG!multiple inheritance}% +\indextext{DAG!virtual base class}% +\end{note} + +\pnum +\begin{note} +A class can have both virtual and non-virtual base classes of a given +type. +\begin{codeblock} +class B { @\commentellip@ }; +class X : virtual public B { @\commentellip@ }; +class Y : virtual public B { @\commentellip@ }; +class Z : public B { @\commentellip@ }; +class AA : public X, public Y, public Z { @\commentellip@ }; +\end{codeblock} +For an object of class \tcode{AA}, all \keyword{virtual} occurrences of +base class \tcode{B} in the class lattice of \tcode{AA} correspond to a +single \tcode{B} subobject within the object of type \tcode{AA}, and +every other occurrence of a (non-virtual) base class \tcode{B} in the +class lattice of \tcode{AA} corresponds one-to-one with a distinct +\tcode{B} subobject within the object of type \tcode{AA}. Given the +class \tcode{AA} defined above, class \tcode{AA} has two subobjects of +class \tcode{B}: \tcode{Z}'s \tcode{B} and the virtual \tcode{B} shared +by \tcode{X} and \tcode{Y}, as shown in \fref{class.virtnonvirt}. + +\indextext{DAG!virtual base class}% +\indextext{DAG!non-virtual base class}% +\indextext{DAG!multiple inheritance}% +\begin{importgraphic} +{Virtual and non-virtual base} +{class.virtnonvirt} +{figvirtnonvirt.pdf} +\end{importgraphic} +\end{note} + +\rSec2[class.virtual]{Virtual functions}% +\indextext{function!virtual|(}% +\indextext{type!polymorphic}% + +\pnum +A non-static member function is a \defnadj{virtual}{function} +if it is first declared with the keyword \keyword{virtual} or +if it overrides a virtual member function declared in a base class +(see below). +\begin{footnote} +The use of the \keyword{virtual} specifier in the +declaration of an overriding function is valid but redundant (has empty +semantics). +\end{footnote} +\begin{note} +Virtual functions support dynamic binding and object-oriented +programming. +\end{note} +A class with a virtual member function is called a \defnadj{polymorphic}{class}. +\begin{footnote} +If +all virtual functions are immediate functions, +the class is still polymorphic even if +its internal representation does not otherwise require +any additions for that polymorphic behavior. +\end{footnote} + +\pnum +If a virtual member function $F$ is declared in a class $B$, and, +in a class $D$ derived (directly or indirectly) from $B$, +a declaration of a member function $G$ +corresponds\iref{basic.scope.scope} to a declaration of $F$, +ignoring trailing \grammarterm{requires-clause}s, +\indextext{override|see{function, virtual, override}}% +then $G$ \defnx{overrides}{function!virtual!override} +\begin{footnote} +A function +with the same name but a different parameter list\iref{over} +as a virtual function is not necessarily virtual and +does not override. Access control\iref{class.access} is not considered in +determining overriding. +\end{footnote} +$F$. +For convenience, we say that any virtual function overrides itself. +\indextext{overrider!final}% +A virtual member function $V$ of a class object $S$ is a \defn{final +overrider} unless the most derived class\iref{intro.object} of which $S$ is a +base class subobject (if any) has another member function that overrides $V$. +In a derived class, if a virtual member function of a base class subobject +has more than one final overrider, the program is ill-formed. +\begin{example} +\begin{codeblock} +struct A { + virtual void f(); +}; +struct B : virtual A { + virtual void f(); +}; +struct C : B , virtual A { + using A::f; +}; + +void foo() { + C c; + c.f(); // calls \tcode{B::f}, the final overrider + c.C::f(); // calls \tcode{A::f} because of the using-declaration +} +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +struct A { virtual void f(); }; +struct B : A { }; +struct C : A { void f(); }; +struct D : B, C { }; // OK, \tcode{A::f} and \tcode{C::f} are the final overriders + // for the \tcode{B} and \tcode{C} subobjects, respectively +\end{codeblock} +\end{example} + +\pnum +\begin{note} +A virtual member function does not have to be visible to be overridden, +for example, +\begin{codeblock} +struct B { + virtual void f(); +}; +struct D : B { + void f(int); +}; +struct D2 : D { + void f(); +}; +\end{codeblock} +the function \tcode{f(int)} in class \tcode{D} hides the virtual +function \tcode{f()} in its base class \tcode{B}; \tcode{D::f(int)} is +not a virtual function. However, \tcode{f()} declared in class +\tcode{D2} has the same name and the same parameter list as +\tcode{B::f()}, and therefore is a virtual function that overrides the +function \tcode{B::f()} even though \tcode{B::f()} is not visible in +class \tcode{D2}. +\end{note} + +\pnum +If a virtual function \tcode{f} in some class \tcode{B} is marked with the +\grammarterm{virt-specifier} \keyword{final} and in a class \tcode{D} derived from \tcode{B} +a function \tcode{D::f} overrides \tcode{B::f}, the program is ill-formed. +\begin{example} +\begin{codeblock} +struct B { + virtual void f() const final; +}; + +struct D : B { + void f() const; // error: \tcode{D::f} attempts to override \tcode{final} \tcode{B::f} +}; +\end{codeblock} +\end{example} + +\pnum +If a virtual function is marked with the \grammarterm{virt-specifier} \keyword{override} and +does not override a member function of a base class, the program is ill-formed. +\begin{example} +\begin{codeblock} +struct B { + virtual void f(int); +}; + +struct D : B { + virtual void f(long) override; // error: wrong signature overriding \tcode{B::f} + virtual void f(int) override; // OK +}; +\end{codeblock} +\end{example} + +\pnum +A virtual function shall not have a trailing \grammarterm{requires-clause}\iref{dcl.decl}. +\begin{example} +\begin{codeblock} +template +struct A { + virtual void f() requires true; // error: virtual function cannot be constrained\iref{temp.constr.decl} +}; +\end{codeblock} +\end{example} + +\pnum +The \grammarterm{ref-qualifier}, or lack thereof, of an overriding function +shall be the same as that of the overridden function. + +\pnum +The return type of an overriding function shall be either identical to +the return type of the overridden function or \defnx{covariant}{return type!covariant} with +the classes of the functions. If a function \tcode{D::f} overrides a +function \tcode{B::f}, the return types of the functions are covariant +if they satisfy the following criteria: +\begin{itemize} +\item both are pointers to classes, both are lvalue references to +classes, or both are rvalue references to classes +\begin{footnote} +Multi-level pointers to classes or references to multi-level pointers to +classes are not allowed.% +\end{footnote} + +\item the class in the return type of \tcode{B::f} is the same class as +the class in the return type of \tcode{D::f}, or is an unambiguous and +accessible direct or indirect base class of the class in the return type +of \tcode{D::f} + +\item both pointers or references have the same cv-qualification and the +class type in the return type of \tcode{D::f} has the same +cv-qualification as or less cv-qualification than the class type in the +return type of \tcode{B::f}. +\end{itemize} + +\pnum +If the class type in the covariant return type of \tcode{D::f} differs from that of +\tcode{B::f}, the class type in the return type of \tcode{D::f} shall be +complete at the locus\iref{basic.scope.pdecl} of the overriding declaration or shall be the +class type \tcode{D}. When the overriding function is called as the +final overrider of the overridden function, its result is converted to +the type returned by the (statically chosen) overridden +function\iref{expr.call}. +\begin{example} +\begin{codeblock} +class B { }; +class D : private B { friend class Derived; }; +struct Base { + virtual void vf1(); + virtual void vf2(); + virtual void vf3(); + virtual B* vf4(); + virtual B* vf5(); + void f(); +}; + +struct No_good : public Base { + D* vf4(); // error: \tcode{B} (base class of \tcode{D}) inaccessible +}; + +class A; +struct Derived : public Base { + void vf1(); // virtual and overrides \tcode{Base::vf1()} + void vf2(int); // not virtual, hides \tcode{Base::vf2()} + char vf3(); // error: invalid difference in return type only + D* vf4(); // OK, returns pointer to derived class + A* vf5(); // error: returns pointer to incomplete class + void f(); +}; + +void g() { + Derived d; + Base* bp = &d; // standard conversion: + // \tcode{Derived*} to \tcode{Base*} + bp->vf1(); // calls \tcode{Derived::vf1()} + bp->vf2(); // calls \tcode{Base::vf2()} + bp->f(); // calls \tcode{Base::f()} (not virtual) + B* p = bp->vf4(); // calls \tcode{Derived::vf4()} and converts the + // result to \tcode{B*} + Derived* dp = &d; + D* q = dp->vf4(); // calls \tcode{Derived::vf4()} and does not + // convert the result to \tcode{B*} + dp->vf2(); // error: argument mismatch +} +\end{codeblock} +\end{example} + +\pnum +\begin{note} +The interpretation of the call of a virtual function depends on the type +of the object for which it is called (the dynamic type), whereas the +interpretation of a call of a non-virtual member function depends only +on the type of the pointer or reference denoting that object (the static +type)\iref{expr.call}. +\end{note} + +\pnum +\begin{note} +The \keyword{virtual} specifier implies membership, so a virtual function +cannot be a non-member\iref{dcl.fct.spec} function. Nor can a virtual +function be a static member, since a virtual function call relies on a +specific object for determining which function to invoke. A virtual +function declared in one class can be declared a friend\iref{class.friend} in +another class. +\end{note} + +\pnum +\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}. +\indextext{friend!\tcode{virtual} and}% + +\pnum +\indextext{multiple inheritance!\tcode{virtual} and}% +\begin{example} +Here are some uses of virtual functions with multiple base classes: +\begin{codeblock} +struct A { + virtual void f(); +}; + +struct B1 : A { // note non-virtual derivation + void f(); +}; + +struct B2 : A { + void f(); +}; + +struct D : B1, B2 { // \tcode{D} has two separate \tcode{A} subobjects +}; + +void foo() { + D d; +//\tcode{ A* ap = \&d;} // would be ill-formed: ambiguous + B1* b1p = &d; + A* ap = b1p; + D* dp = &d; + ap->f(); // calls \tcode{D::B1::f} + dp->f(); // error: ambiguous +} +\end{codeblock} +In class \tcode{D} above there are two occurrences of class \tcode{A} +and hence two occurrences of the virtual member function \tcode{A::f}. +The final overrider of \tcode{B1::A::f} is \tcode{B1::f} and the final +overrider of \tcode{B2::A::f} is \tcode{B2::f}. +\end{example} + +\pnum +\begin{example} +The following example shows a function that does not have a unique final +overrider: +\begin{codeblock} +struct A { + virtual void f(); +}; + +struct VB1 : virtual A { // note virtual derivation + void f(); +}; + +struct VB2 : virtual A { + void f(); +}; + +struct Error : VB1, VB2 { // error +}; + +struct Okay : VB1, VB2 { + void f(); +}; +\end{codeblock} +Both \tcode{VB1::f} and \tcode{VB2::f} override \tcode{A::f} but there +is no overrider of both of them in class \tcode{Error}. This example is +therefore ill-formed. Class \tcode{Okay} is well-formed, however, +because \tcode{Okay::f} is a final overrider. +\end{example} + +\pnum +\begin{example} +The following example uses the well-formed classes from above. +\begin{codeblock} +struct VB1a : virtual A { // does not declare \tcode{f} +}; + +struct Da : VB1a, VB2 { +}; + +void foe() { + VB1a* vb1ap = new Da; + vb1ap->f(); // calls \tcode{VB2::f} +} +\end{codeblock} +\end{example} + +\pnum +\indextext{operator!scope resolution}% +\indextext{virtual function call}% +Explicit qualification with the scope operator\iref{expr.prim.id.qual} +suppresses the virtual call mechanism. +\begin{example} +\begin{codeblock} +class B { public: virtual void f(); }; +class D : public B { public: void f(); }; + +void D::f() { @\commentellip@ B::f(); } +\end{codeblock} + +Here, the function call in +\tcode{D::f} +really does call +\tcode{B::f} +and not +\tcode{D::f}. +\end{example} + +\pnum +A deleted function\iref{dcl.fct.def} shall +not override a function that is not deleted. Likewise, +a function that is not deleted shall not override a +deleted function.% +\indextext{function!virtual|)} + +\pnum +A class with an immediate virtual function that overrides +a non-immediate virtual function +shall have consteval-only type\iref{basic.types.general}. +An immediate virtual function shall not be overridden by +a non-immediate virtual function. + +\rSec2[class.abstract]{Abstract classes}% + +\pnum +\begin{note} +The abstract class mechanism supports the notion of a general concept, +such as a \tcode{shape}, of which only more concrete variants, such as +\tcode{circle} and \tcode{square}, can actually be used. An abstract +class can also be used to define an interface for which derived classes +provide a variety of implementations. +\end{note} + +\pnum +A virtual function is specified as +a \defnx{pure virtual function}{function!virtual!pure} by using a +\grammarterm{pure-specifier}\iref{class.mem} in the function declaration +in the class definition. +\begin{note} +Such a function might be inherited: see below. +\end{note} +A class is an \defnadj{abstract}{class} +if it has at least one pure virtual function. +\begin{note} +An abstract class can be used only as a base class of some other class; +no objects of an abstract class can be created +except as subobjects of a class +derived from it\iref{basic.def,class.mem}. +\end{note} +\indextext{definition!pure virtual function}% +A pure virtual function need be defined only if called with, or as if +with\iref{class.dtor}, the \grammarterm{qualified-id} +syntax\iref{expr.prim.id.qual}. +\begin{example} +\begin{codeblock} +class point { @\commentellip@ }; +class shape { // abstract class + point center; +public: + point where() { return center; } + void move(point p) { center=p; draw(); } + virtual void rotate(int) = 0; // pure virtual + virtual void draw() = 0; // pure virtual +}; +\end{codeblock} +\end{example} +\begin{note} +A function declaration cannot provide both a \grammarterm{pure-specifier} +and a definition. +\end{note} +\begin{example} +\begin{codeblock} +struct C { + virtual void f() = 0 { }; // error +}; +\end{codeblock} +\end{example} + +\pnum +\begin{note} +An abstract class type cannot be used +as a parameter or return type of +a function being defined\iref{dcl.fct} or called\iref{expr.call}, +except as specified in \ref{dcl.type.simple}. +Further, an abstract class type cannot be used as +the type of an explicit type conversion\iref{expr.static.cast, +expr.reinterpret.cast,expr.const.cast}, +because the resulting prvalue would be of abstract class type\iref{basic.lval}. +However, pointers and references to abstract class types +can appear in such contexts. +\end{note} + +\pnum +\indextext{function!virtual!pure}% +A class is abstract if it has at least one pure virtual +function for which the final overrider is pure virtual. +\begin{example} +\begin{codeblock} +class ab_circle : public shape { + int radius; +public: + void rotate(int) { } + // \tcode{ab_circle::draw()} is a pure virtual +}; +\end{codeblock} + +Since \tcode{shape::draw()} is a pure virtual function +\tcode{ab_circle::draw()} is a pure virtual by default. The alternative +declaration, +\begin{codeblock} +class circle : public shape { + int radius; +public: + void rotate(int) { } + void draw(); // a definition is required somewhere +}; +\end{codeblock} +would make class \tcode{circle} non-abstract and a definition of +\tcode{circle::draw()} must be provided. +\end{example} + +\pnum +\begin{note} +An abstract class can be derived from a class that is not abstract, and +a pure virtual function can override a virtual function which is not +pure. +\end{note} + +\pnum +\indextext{class!constructor and abstract}% +Member functions can be called from a constructor (or destructor) of an +abstract class; +\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.% +\indextext{derived class|)} + +\rSec1[class.access]{Member access control}% + +\rSec2[class.access.general]{General}% +\indextext{access control|(} + +\indextext{protection|see{access control}} +\indextext{\idxcode{private}|see{access control, \tcode{private}}} +\indextext{\idxcode{protected}|see{access control, \tcode{protected}}} +\indextext{\idxcode{public}|see{access control, \tcode{public}}} + +\pnum +A member of a class can be +\begin{itemize} +\item +\indextext{access control!\idxcode{private}}% +private, +that is, it can be named only by members and friends +of the class in which it is declared; +\item +\indextext{access control!\idxcode{protected}}% +protected, +that is, it can be named only by members and friends +of the class in which it is declared, by classes derived from that class, and by their +friends (see~\ref{class.protected}); or +\item +\indextext{access control!\idxcode{public}}% +public, +that is, it can be named anywhere without access restriction. +\end{itemize} +\begin{note} +A constructor or destructor can be named by an expression\iref{basic.def.odr} +even though it has no name. +\end{note} + +\pnum +A member of a class can also access all the members to which the class has access. +A local class of a member function may access +the same members that the member function itself may access. +\begin{footnote} +Access +permissions are thus transitive and cumulative to nested +and local classes. +\end{footnote} + +\pnum +\indextext{access control!member name}% +\indextext{default access control|see{access control, default}}% +\indextext{access control!default}% +Members of a class defined with the keyword +\keyword{class} +are private by default. +Members of a class defined with the keywords +\keyword{struct} or \keyword{union} +are public by default. +\begin{example} +\begin{codeblock} +class X { + int a; // \tcode{X::a} is private by default +}; + +struct S { + int a; // \tcode{S::a} is public by default +}; +\end{codeblock} +\end{example} + +\pnum +Access control is applied uniformly to declarations and expressions. +\begin{note} +Access control applies to members nominated by +friend declarations\iref{class.friend} and +\grammarterm{using-declaration}{s}\iref{namespace.udecl}. +\end{note} +When a \grammarterm{using-declarator} is named, +access control is applied to it, not to the declarations that replace it. +For an overload set, access control is applied only to +the function selected by overload resolution. +\begin{example} +\begin{codeblock} +struct S { + void f(int); +private: + void f(double); +}; + +void g(S* sp) { + sp->f(2); // OK, access control applied after overload resolution +} +\end{codeblock} +\end{example} +\begin{note} +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 { + class B { }; +public: + typedef B BB; +}; + +void f() { + A::BB x; // OK, typedef \tcode{A::BB} is public + A::B y; // access error, \tcode{A::B} is private +} +\end{codeblock} +\end{example} +\end{note} + +\pnum +\begin{note} +Access control does not prevent members from being found by name lookup or +implicit conversions to base classes from being considered. +\end{note} +The interpretation of a given construct is +established without regard to access control. +If the interpretation +established makes use of inaccessible members or base classes, +the construct is ill-formed. + +\pnum +All access controls in \ref{class.access} affect the ability to name a class member +from the declaration of a particular +entity, including parts of the declaration preceding the name of the entity +being declared and, if the entity is a class, the definitions of members of +the class appearing outside the class's \grammarterm{member-specification}{.} +\begin{note} +This access also applies to implicit references to constructors, +conversion functions, and destructors. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +class A { + typedef int I; // private member + I f() pre(A::x > 0); + friend I g(I) post(A::x <= 0); + static I x; + template struct Q; + template friend struct R; +protected: + struct B { }; +}; + +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 { }; +template struct R { }; + +struct D: A::B, A { }; +\end{codeblock} + +Here, all the uses of +\tcode{A::I} +are well-formed because +\tcode{A::f}, +\tcode{A::x}, and \tcode{A::Q} +are members of class +\tcode{A} +and +\tcode{g} +and \tcode{R} are friends of class +\tcode{A}. +This implies, for example, that access checking on the first use of +\tcode{A::I} +must be deferred until it is determined that this use of +\tcode{A::I} +is as the return type of a member of class +\tcode{A}. +Similarly, the use of \tcode{A::B} as a +\grammarterm{base-specifier} is well-formed because \tcode{D} +is derived from \tcode{A}, so checking of \grammarterm{base-specifier}{s} +must be deferred until the entire \grammarterm{base-specifier-list} has been seen. +\end{example} + +\pnum +\indextext{argument!access checking and default}% +\indextext{access control!default argument}% +Access is checked for a default argument\iref{dcl.fct.default} +at the point of declaration, +rather than at any points of use of the default argument. +Access checking for default arguments in function templates and in +member functions of class templates is performed as described in~\ref{temp.inst}. + +\pnum +Access for a default \grammarterm{template-argument}\iref{temp.param} +is checked in the context in which it appears rather than at any +points of use of it. +\begin{example} +\begin{codeblock} +class B { }; +template class C { +protected: + typedef T TT; +}; + +template +class D : public U { }; + +D >* d; // access error, \tcode{C::TT} is protected +\end{codeblock} +\end{example} + +\rSec2[class.access.spec]{Access specifiers}% +\indextext{access specifier} + +\pnum +Member declarations can be labeled by an +\grammarterm{access-specifier}\iref{class.derived}: + +\begin{ncsimplebnf} +access-specifier \terminal{:} \opt{member-specification} +\end{ncsimplebnf} + +An +\grammarterm{access-specifier} +specifies the access rules for members following it +until the end of the class or until another +\grammarterm{access-specifier} +is encountered. +\begin{example} +\begin{codeblock} +class X { + int a; // \tcode{X::a} is private by default: \keyword{class} used +public: + int b; // \tcode{X::b} is public + int c; // \tcode{X::c} is public +}; +\end{codeblock} +\end{example} + +\pnum +Any number of access specifiers is allowed and no particular order is required. +\begin{example} +\begin{codeblock} +struct S { + int a; // \tcode{S::a} is public by default: \keyword{struct} used +protected: + int b; // \tcode{S::b} is protected +private: + int c; // \tcode{S::c} is private +public: + int d; // \tcode{S::d} is public +}; +\end{codeblock} +\end{example} + +\pnum +When a member is redeclared within its class definition, +the access specified at its redeclaration shall +be the same as at its initial declaration. +\begin{example} +\begin{codeblock} +struct S { + class A; + enum E : int; +private: + class A { }; // error: cannot change access + enum E: int { e0 }; // error: cannot change access +}; +\end{codeblock} +\end{example} + +\pnum +\begin{note} +In a derived class, the lookup of a base class name will find the +injected-class-name instead of the name of the base class in the scope +in which it was declared. The injected-class-name might be less accessible +than the name of the base class in the scope in which it was declared. +\end{note} + +\begin{example} +\begin{codeblock} +class A { }; +class B : private A { }; +class C : public B { + A* p; // error: injected-class-name \tcode{A} is inaccessible + ::A* q; // OK +}; +\end{codeblock} +\end{example} + +\rSec2[class.access.base]{Accessibility of base classes and base class members}% +\indextext{access control!base class}% +\indextext{access specifier}% +\indextext{base class!\idxcode{private}}% +\indextext{base class!\idxcode{protected}}% +\indextext{base class!\idxcode{public}} + +\pnum +If a class is declared to be a base class\iref{class.derived} for another class using the +\keyword{public} +access specifier, the +public members of the base class are accessible as +public members of the derived class and +protected members of the base class are accessible as +protected members of the derived class. +If a class is declared to be a base class for another class using the +\keyword{protected} +access specifier, the +public and protected members of the base class are accessible as +protected members of the derived class. +If a class is declared to be a base class for another class using the +\keyword{private} +access specifier, the +public and protected +members of the base class are accessible as private +members of the derived class. +\begin{footnote} +As specified previously in \ref{class.access}, +private members of a base class remain inaccessible even to derived classes +unless friend +declarations within the base class definition are used to grant access explicitly. +\end{footnote} + +\pnum +In the absence of an +\grammarterm{access-specifier} +for a base class, +\keyword{public} +is assumed when the derived class is +defined with the \grammarterm{class-key} +\keyword{struct} +and +\keyword{private} +is assumed when the class is +defined with the \grammarterm{class-key} +\keyword{class}. +\begin{example} +\begin{codeblock} +class B { @\commentellip@ }; +class D1 : private B { @\commentellip@ }; +class D2 : public B { @\commentellip@ }; +class D3 : B { @\commentellip@ }; // \tcode{B} private by default +struct D4 : public B { @\commentellip@ }; +struct D5 : private B { @\commentellip@ }; +struct D6 : B { @\commentellip@ }; // \tcode{B} public by default +class D7 : protected B { @\commentellip@ }; +struct D8 : protected B { @\commentellip@ }; +\end{codeblock} + +Here +\tcode{B} +is a public base of +\tcode{D2}, +\tcode{D4}, +and +\tcode{D6}, +a private base of +\tcode{D1}, +\tcode{D3}, +and +\tcode{D5}, +and a protected base of +\tcode{D7} +and +\tcode{D8}. +\end{example} + +\pnum +\begin{note} +A member of a private base class can be inaccessible as inherited, +but accessible directly. +Because of the rules on pointer conversions\iref{conv.ptr} and +explicit casts\iref{expr.type.conv,expr.static.cast,expr.cast}, +a conversion from a pointer to a derived class to a pointer +to an inaccessible base class can be ill-formed if an implicit conversion +is used, but well-formed if an explicit cast is used. +\begin{example} +\begin{codeblock} +class B { +public: + int mi; // non-static member + static int si; // static member +}; +class D : private B { +}; +class DD : public D { + void f(); +}; + +void DD::f() { + mi = 3; // error: \tcode{mi} is private in \tcode{D} + si = 3; // error: \tcode{si} is private in \tcode{D} + ::B b; + b.mi = 3; // OK (\tcode{b.mi} is different from \tcode{this->mi}) + b.si = 3; // OK (\tcode{b.si} is different from \tcode{this->si}) + ::B::si = 3; // OK + ::B* bp1 = this; // error: \tcode{B} is a private base class + ::B* bp2 = (::B*)this; // OK with cast + bp2->mi = 3; // OK, access through a pointer to \tcode{B}. +} +\end{codeblock} +\end{example} +\end{note} + +\pnum +A base class +\tcode{B} +of +\tcode{N} +is +\defn{accessible} +at +\placeholder{R}, +if +\begin{itemize} +\item +an invented public member of +\tcode{B} +would be a public member of +\tcode{N}, or +\item +\placeholder{R} +occurs in a direct member or friend of class +\tcode{N}, +and an invented public member of +\tcode{B} +would be a private or protected member of +\tcode{N}, or +\item +\placeholder{R} +occurs in a direct member or friend of a class +\tcode{P} +derived from +\tcode{N}, +and an invented public member of +\tcode{B} +would be a private or protected member of +\tcode{P}, or +\item +there exists a class +\tcode{S} +such that +\tcode{B} +is a base class of +\tcode{S} +accessible at +\placeholder{R} +and +\tcode{S} +is a base class of +\tcode{N} +accessible at +\placeholder{R}. +\end{itemize} + +\begin{example} +\begin{codeblock} +class B { +public: + int m; +}; + +class S: private B { + friend class N; +}; + +class N: private S { + void f() { + B* p = this; // OK because class \tcode{S} satisfies the fourth condition above: \tcode{B} is a base class of \tcode{N} + // accessible in \tcode{f()} because \tcode{B} is an accessible base class of \tcode{S} and \tcode{S} is an accessible + // base class of \tcode{N}. + } +}; +\end{codeblock} +\end{example} + +\pnum +If a base class is accessible, one can implicitly convert a pointer to +a derived class to a pointer to that base class\iref{conv.ptr,conv.mem}. +\begin{note} +It follows that +members and friends of a class +\tcode{X} +can implicitly convert an +\tcode{X*} +to a pointer to a private or protected immediate base class of +\tcode{X}. +\end{note} +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} +is used, or implicit, e.g., when a class member access operator\iref{expr.ref} is used (including cases where an implicit +``\tcode{this->}'' +is +added). +If both a class member access operator and a +\grammarterm{qualified-id} +are used to name the member (as in +\tcode{p->T::m}), +the class designating the member is the class designated by the +\grammarterm{nested-name-specifier} +of the +\grammarterm{qualified-id} +(that is, +\tcode{T}). +\end{note} +A member +\tcode{m} +is accessible at the point +\placeholder{R} +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} +is public, or +\item +\tcode{m} +as a member of +\tcode{N} +is private, and +\placeholder{R} +occurs in a direct member or friend of class +\tcode{N}, +or +\item +\tcode{m} +as a member of +\tcode{N} +is protected, and +\placeholder{R} +occurs in a direct member or friend of class +\tcode{N}, +or in a member of a class +\tcode{P} +derived from +\tcode{N}, +where +\tcode{m} +as a member of +\tcode{P} +is public, private, or protected, or +\item +there exists a base class +\tcode{B} +of +\tcode{N} +that is accessible at +\placeholder{R}, +and +\tcode{m} +is accessible at +\placeholder{R} +when designated in class +\tcode{B}. +\begin{example} +\begin{codeblock} +class B; +class A { +private: + int i; + friend void f(B*); +}; +class B : public A { }; +void f(B* p) { + p->i = 1; // OK, \tcode{B*} can be implicitly converted to \tcode{A*}, and \tcode{f} has access to \tcode{i} in \tcode{A} +} +\end{codeblock} +\end{example} +\end{itemize} + +\pnum +If a class member access operator, including an implicit +``\tcode{this->}'', +is used to access a non-static data member or non-static +member function, the reference is ill-formed if the +left operand (considered as a pointer in the +``\tcode{.}'' +operator case) cannot be implicitly converted to a +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 designated. +\end{note} + +\rSec2[class.friend]{Friends}% +\indextext{friend function!access and}% +\indextext{access control!friend function} + +\pnum +A friend of a class is a function or class that is +given permission to name the private and protected members of the class. +A class specifies its friends, if any, by way of friend declarations. +Such declarations give special access rights to the friends, but they +do not make the nominated friends members of the befriending class. +\begin{example} +The following example illustrates the differences between +members and friends: +\indextext{friend function!member function and}% + +\begin{codeblock} +class X { + int a; + friend void friend_set(X*, int); +public: + void member_set(int); +}; + +void friend_set(X* p, int i) { p->a = i; } +void X::member_set(int i) { a = i; } + +void f() { + X obj; + friend_set(&obj,10); + obj.member_set(10); +} +\end{codeblock} +\end{example} + +\pnum +\indextext{friend!class access and}% +Declaring a class to be a friend implies that private and +protected members of the class granting friendship can be named in the +\grammarterm{base-specifier}{s} and member declarations of the befriended +class. +\begin{example} +\begin{codeblock} +class A { + class B { }; + friend class X; +}; + +struct X : A::B { // OK, \tcode{A::B} accessible to friend + A::B mx; // OK, \tcode{A::B} accessible to member of friend + class Y { + A::B my; // OK, \tcode{A::B} accessible to nested member of friend + }; +}; +\end{codeblock} +\end{example} +\begin{example} +\begin{codeblock} +class X { + enum { a=100 }; + friend class Y; +}; + +class Y { + int v[X::a]; // OK, \tcode{Y} is a friend of \tcode{X} +}; + +class Z { + int v[X::a]; // error: \tcode{X::a} is private +}; +\end{codeblock} +\end{example} + +\pnum +A friend declaration that does not declare a function +shall be a \grammarterm{friend-type-declaration}. + +\begin{note} +A friend declaration can be the +\grammarterm{declaration} in +a \grammarterm{template-declaration}\iref{temp.pre,temp.friend}. +\end{note} +If a \grammarterm{friend-type-specifier} in a friend declaration +designates a (possibly +cv-qualified) class type, that class is declared as a friend; otherwise, the +\grammarterm{friend-type-specifier} is ignored. +\begin{example} +\begin{codeblock} +class C; +typedef C Ct; +class E; + +class X1 { + friend C; // OK, \tcode{class C} is a friend +}; + +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 +}; + +template class R { + friend Ts...; +}; + +template +class R, R> { + friend Ts::Nested..., Us...; +}; + +R rc; // \tcode{class C} is a friend of \tcode{R} +R rce; // classes \tcode{C} and \tcode{E} are friends of \tcode{R} +R Ri; // OK, ``\tcode{friend int;}'' is ignored + +struct E { struct Nested; }; + +R, R> rr; // \tcode{E::Nested} and \tcode{C} are friends of \tcode{R, R>} +\end{codeblock} +\end{example} + +\pnum +\indextext{declaration!overloaded name and \tcode{friend}}% +\begin{note} +A friend declaration refers to an entity, not (all overloads of) a name. +A member function of a class +\tcode{X} +can be a friend of +a class +\tcode{Y}. +\indextext{member function!friend}% +\begin{example} +\begin{codeblock} +class Y { + friend char* X::foo(int); + friend X::X(char); // constructors can be friends + friend X::~X(); // destructors can be friends +}; +\end{codeblock} +\end{example} +\end{note} + +\pnum +\indextext{friend function!inline}% +A function may be defined in a friend declaration of a class if and only if the +class is a non-local class\iref{class.local} and the function name is unqualified. +\begin{example} +\begin{codeblock} +class M { + friend void f() { } // definition of global \tcode{f}, a friend of \tcode{M}, + // not the definition of a member function +}; +\end{codeblock} +\end{example} + +\pnum +Such a function is implicitly an inline\iref{dcl.inline} function +if it is attached to the global module. +\begin{note} +If a friend function is defined outside a class, +it is not in the scope of the class. +\end{note} + +\pnum +No +\grammarterm{storage-class-specifier} +shall appear in the +\grammarterm{decl-specifier-seq} +of a friend declaration. + +\pnum +\indextext{friend!access specifier and}% +A member nominated by a friend declaration shall be accessible in the +class containing the friend declaration. +The meaning of the friend declaration is the same whether the friend declaration +appears in the private, protected, or public\iref{class.mem} +portion of the class +\grammarterm{member-specification}. + +\pnum +\indextext{friend!inheritance and}% +Friendship is neither inherited nor transitive. +\begin{example} +\begin{codeblock} +class A { + friend class B; + int a; +}; + +class B { + friend class C; +}; + +class C { + void f(A* p) { + p->a++; // error: \tcode{C} is not a friend of \tcode{A} despite being a friend of a friend + } +}; + +class D : public B { + void f(A* p) { + p->a++; // error: \tcode{D} is not a friend of \tcode{A} despite being derived from a friend + } +}; +\end{codeblock} +\end{example} + +\pnum +\indextext{local class!friend}% +\indextext{friend!local class and}% +\begin{note} +A friend declaration never binds any names\iref{dcl.meaning,dcl.type.elab}. +\end{note} +\begin{example} +\begin{codeblock} +// Assume \tcode{f} and \tcode{g} have not yet been declared. +void h(int); +template void f2(T); +namespace A { + class X { + friend void f(X); // \tcode{A::f(X)} is a friend + class Y { + friend void g(); // \tcode{A::g} is a friend + friend void h(int); // \tcode{A::h} is a friend + // \tcode{::h} not considered + friend void f2<>(int); // \tcode{::f2<>(int)} is a friend + }; + }; + + // \tcode{A::f}, \tcode{A::g} and \tcode{A::h} are not visible here + X x; + void g() { f(x); } // definition of \tcode{A::g} + void f(X) { @\commentellip@ } // definition of \tcode{A::f} + void h(int) { @\commentellip@ } // definition of \tcode{A::h} + // \tcode{A::f}, \tcode{A::g} and \tcode{A::h} are visible here and known to be friends +} + +using A::x; + +void h() { + A::f(x); + A::X::f(x); // error: \tcode{f} is not a member of \tcode{A::X} + A::X::Y::g(); // error: \tcode{g} is not a member of \tcode{A::X::Y} +} +\end{codeblock} +\end{example} +\begin{example} +\begin{codeblock} +class X; +void a(); +void f() { + class Y; + extern void b(); + class A { + friend class X; // OK, but \tcode{X} is a local class, not \tcode{::X} + friend class Y; // OK + friend class Z; // OK, introduces local class \tcode{Z} + friend void a(); // error, \tcode{::a} is not considered + friend void b(); // OK + friend void c(); // error + }; + X* px; // OK, but \tcode{::X} is found + Z* pz; // error: no \tcode{Z} is found +} +\end{codeblock} +\end{example} + +\rSec2[class.protected]{Protected member access} +\indextext{access control!\idxcode{protected}}% + +\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 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, +e.g., static data members or enumerator member constants. +\end{footnote} +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 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} +class B { +protected: + int i; + static int j; +}; + +class D1 : public B { +}; + +class D2 : public B { + friend void fr(B*,D1*,D2*); + void mem(B*,D1*); +}; + +void fr(B* pb, D1* p1, D2* p2) { + 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 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 designating class \tcode{B} + D2::j = 6; // OK (because refers to static member) +} + +void D2::mem(B* pb, D1* p1) { + pb->i = 1; // error + p1->i = 2; // error + i = 3; // OK (access through \keyword{this}) + B::i = 4; // OK (access through \keyword{this}, qualification ignored) + int B::* pmi_B = &B::i; // error + int B::* pmi_B2 = &D2::i; // OK + j = 5; // OK (because \tcode{j} refers to static member) + B::j = 6; // OK (because \tcode{B::j} refers to static member) +} + +void g(B* pb, D1* p1, D2* p2) { + pb->i = 1; // error + p1->i = 2; // error + p2->i = 3; // error +} +\end{codeblock} +\end{example} + +\rSec2[class.access.virt]{Access to virtual functions}% +\indextext{access control!virtual function} + +\pnum +The access rules\iref{class.access} for a virtual function are determined by its declaration +and are not affected by the rules for a function that later overrides it. +\begin{example} +\begin{codeblock} +class B { +public: + virtual int f(); +}; + +class D : public B { +private: + int f(); +}; + +void f() { + D d; + B* pb = &d; + D* pd = &d; + + pb->f(); // OK, \tcode{B::f()} is public, \tcode{D::f()} is invoked + pd->f(); // error: \tcode{D::f()} is private +} +\end{codeblock} +\end{example} + +\pnum +Access is checked at the call point using the type of the expression used +to denote the object for which the member function is called +(\tcode{B*} +in the example above). +The access of the member function in the class in which it was defined +(\tcode{D} +in the example above) is in general not known. + +\rSec2[class.paths]{Multiple access}% +\indextext{access control!multiple access} + +\pnum +If a declaration can be reached by several paths through a multiple inheritance +graph, the access is that of the path that gives most access. +\begin{example} +\begin{codeblock} +class W { public: void f(); }; +class A : private virtual W { }; +class B : public virtual W { }; +class C : public A, public B { + void f() { W::f(); } // OK +}; +\end{codeblock} + +Since +\tcode{W::f()} +is available to +\tcode{C::f()} +along the public path through +\tcode{B}, +access is allowed. +\end{example} + +\rSec2[class.access.nest]{Nested classes}% +\indextext{access control!nested class}% +\indextext{member function!nested class} + +\pnum +A nested class is a member and as such has the same access rights as any other member. +The members of an enclosing class have no special access to members of a nested +class; the usual access rules\iref{class.access} shall be obeyed. +\begin{example} +\begin{codeblock} +class E { + int x; + class B { }; + + class I { + B b; // OK, \tcode{E::I} can access \tcode{E::B} + int y; + void f(E* p, int i) { + p->x = i; // OK, \tcode{E::I} can access \tcode{E::x} + } + }; + + int g(I* p) { + return p->y; // error: \tcode{I::y} is private + } +}; +\end{codeblock} +\end{example} +\indextext{access control|)} + +\rSec1[class.init]{Initialization}% + +\rSec2[class.init.general]{General}% +\indextext{initialization!class object|(}% +\indextext{initialization!default constructor and}% +\indextext{initialization!constructor and} + +\pnum +When no initializer is specified for an object of (possibly +cv-qualified) class type (or array thereof), or the initializer has +the form +\tcode{()}, +the object is initialized as specified in~\ref{dcl.init}. + +\pnum +An object of class type (or array thereof) can be explicitly initialized; +see~\ref{class.expl.init} and~\ref{class.base.init}. + +\pnum +\indextext{order of execution!constructor and array}% +When an array of class objects is initialized +(either explicitly or implicitly) and the elements are initialized by constructor, +the constructor shall be called for each element of the array, +following the subscript order; see~\ref{dcl.array}. +\begin{note} +Destructors for the array elements are called in reverse order of their +construction. +\end{note} + +\rSec2[class.expl.init]{Explicit initialization}% +\indextext{initialization!explicit}% +\indextext{initialization!constructor and}% + +\pnum +An object of class type can be initialized with a parenthesized +\grammarterm{expression-list}, +where the +\grammarterm{expression-list} +is construed as an argument list for a constructor +that is called to initialize the object. +Alternatively, a single +\grammarterm{assignment-expression} +can be specified as an +\grammarterm{initializer} +using the +\tcode{=} +form of initialization. +Either direct-initialization semantics or copy-initialization semantics apply; +see~\ref{dcl.init}. +\begin{example} +\begin{codeblock} +struct complex { + complex(); + complex(double); + complex(double,double); +}; + +complex sqrt(complex,complex); + +complex a(1); // initialized by calling \tcode{complex(double)} with argument \tcode{1} +complex b = a; // initialized as a copy of \tcode{a} +complex c = complex(1,2); // initialized by calling \tcode{complex(double,double)} with arguments \tcode{1} and \tcode{2} +complex d = sqrt(b,c); // initialized by calling \tcode{sqrt(complex,complex)} with \tcode{d} as its result object +complex e; // initialized by calling \tcode{complex()} +complex f = 3; // initialized by calling \tcode{complex(double)} with argument \tcode{3} +complex g = { 1, 2 }; // initialized by calling \tcode{complex(double, double)} with arguments \tcode{1} and \tcode{2} +\end{codeblock} +\end{example} +\begin{note} +\indextext{initialization!overloaded assignment and}% +Overloading of the assignment operator\iref{over.assign} +has no effect on initialization. +\end{note} + +\pnum +\indextext{initialization!array of class objects}% +\indextext{constructor!array of class objects and}% +An object of class type can also be initialized by a +\grammarterm{braced-init-list}. List-initialization semantics apply; +see~\ref{dcl.init} and~\ref{dcl.init.list}. +\begin{example} +\begin{codeblock} +complex v[6] = { 1, complex(1,2), complex(), 2 }; +\end{codeblock} + +Here, +\tcode{complex::complex(double)} +is called for the initialization of +\tcode{v[0]} +and +\tcode{v[3]}, +\tcode{complex::complex(\brk{}double, double)} +is called for the initialization of +\tcode{v[1]}, +\tcode{complex::complex()} +is called for the initialization of +\tcode{v[2]}, +\tcode{v[4]}, +and +\tcode{v[5]}. +For another example, + +\begin{codeblock} +struct X { + int i; + float f; + complex c; +} x = { 99, 88.8, 77.7 }; +\end{codeblock} + +Here, +\tcode{x.i} +is initialized with \tcode{99}, +\tcode{x.f} +is initialized with \tcode{88.8}, and +\tcode{complex::complex(double)} +is called for the initialization of +\tcode{x.c}. +\end{example} +\begin{note} +Braces can be elided in the +\grammarterm{initializer-list} +for any aggregate, even if the aggregate has members of a class type with +user-defined type conversions; see~\ref{dcl.init.aggr}. +\end{note} + +\pnum +\begin{note} +If +\tcode{T} +is a class type with no default constructor, +any initializing declaration of an object of type +\tcode{T} +(or array thereof) is ill-formed if no +\grammarterm{initializer} +is explicitly specified (see~\ref{class.init} and~\ref{dcl.init}). +\end{note} + +\pnum +\begin{note} +\indextext{order of execution!constructor and static data members}% +The order in which objects with static or thread storage duration +are initialized is described in~\ref{basic.start.dynamic} and~\ref{stmt.dcl}. +\end{note} + +\rSec2[class.base.init]{Initializing bases and members}% +\indextext{initialization!base class}% +\indextext{initialization!member} + +\pnum +In the definition of a constructor for a class, +initializers for direct and virtual base class subobjects and +non-static data members can be specified by a +\grammarterm{ctor-initializer}, +which has the form + +\begin{bnf} +\nontermdef{ctor-initializer}\br + \terminal{:} mem-initializer-list +\end{bnf} + +\begin{bnf} +\nontermdef{mem-initializer-list}\br + mem-initializer \opt{\terminal{...}}\br + mem-initializer-list \terminal{,} mem-initializer \opt{\terminal{...}} +\end{bnf} + +\begin{bnf} +\nontermdef{mem-initializer}\br + mem-initializer-id \terminal{(} \opt{expression-list} \terminal{)}\br + mem-initializer-id braced-init-list +\end{bnf} + +\begin{bnf} +\nontermdef{mem-initializer-id}\br + class-or-decltype\br + identifier +\end{bnf} + +\pnum +Lookup for an unqualified name in a \grammarterm{mem-initializer-id} +ignores the constructor's function parameter scope. +\begin{note} +If the constructor's class contains a member with the same name as a direct +or virtual base class of the class, a +\grammarterm{mem-initializer-id} +naming the member or base class and composed of a single identifier +refers to the class member. +A +\grammarterm{mem-initializer-id} +for the hidden base class can be specified using a qualified name. +\end{note} +Unless the +\grammarterm{mem-initializer-id} +names the constructor's class, +a direct non-static data member of the constructor's class, or +a direct or virtual base of that class, +the +\grammarterm{mem-initializer} +is ill-formed. + +\pnum +A +\grammarterm{mem-initializer-list} +can initialize a base class using any \grammarterm{class-or-decltype} that denotes that base class type. +\begin{example} +\begin{codeblock} +struct A { A(); }; +typedef A global_A; +struct B { }; +struct C: public A, public B { C(); }; +C::C(): global_A() { } // mem-initializer for base \tcode{A} +\end{codeblock} +\end{example} + +\pnum +If a +\grammarterm{mem-initializer-id} +is ambiguous because it designates both a direct non-virtual base class and +an indirect virtual base class, the +\grammarterm{mem-initializer} +is ill-formed. +\begin{example} +\begin{codeblock} +struct A { A(); }; +struct B: public virtual A { }; +struct C: public A, public B { C(); }; +C::C(): A() { } // error: which \tcode{A}? +\end{codeblock} +\end{example} + +\pnum +A +\grammarterm{ctor-initializer} +may initialize a variant member of the +constructor's class. +If a +\grammarterm{ctor-initializer} +specifies more than one +\grammarterm{mem-initializer} +for the same member or for the same base class, +the +\grammarterm{ctor-initializer} +is ill-formed. + +\pnum +A \grammarterm{mem-initializer-list} can delegate to another +constructor of the constructor's class using any +\grammarterm{class-or-decltype} that denotes the constructor's class itself. If a +\grammarterm{mem-initializer-id} designates the constructor's class, +it shall be the only \grammarterm{mem-initializer}; the constructor +is a \defnadj{delegating}{constructor}, and the constructor selected by the +\grammarterm{mem-initializer} is the \defnadj{target}{constructor}. +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. +\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: ill-formed due to recursion with \#4 + C( double d ) : C('a') { } // \#4: ill-formed due to recursion with \#3 +}; +\end{codeblock} +\end{example} + +\pnum +\indextext{initialization!base class}% +\indextext{initialization!member object}% +The +\grammarterm{expression-list} +or \grammarterm{braced-init-list} +in a +\grammarterm{mem-initializer} +is used to initialize the +designated subobject (or, in the case of a delegating constructor, the complete class object) +according to the initialization rules of~\ref{dcl.init} for direct-initialization. +\begin{example} +\begin{codeblock} +struct B1 { B1(int); @\commentellip@ }; +struct B2 { B2(int); @\commentellip@ }; +struct D : B1, B2 { + D(int); + B1 b; + const int c; +}; + +D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { @\commentellip@ } +D d(10); +\end{codeblock} +\end{example} +\begin{note} +The initialization +performed by each \grammarterm{mem-initializer} +constitutes a full-expres\-sion\iref{intro.execution}. +Any expression in +a +\grammarterm{mem-initializer} +is evaluated as part of the full-expression that performs the initialization. +\end{note} +A \grammarterm{mem-initializer} where the \grammarterm{mem-initializer-id} denotes +a virtual base class is ignored during execution of a constructor of any class that is +not the most derived class. + +\pnum +A temporary expression bound to a reference member in a \grammarterm{mem-initializer} +is ill-formed. +\begin{example} +\begin{codeblock} +struct A { + A() : v(42) { } // error + const int& v; +}; +\end{codeblock} +\end{example} + +\pnum +In a non-delegating constructor +other than an implicitly-defined copy/move constructor\iref{class.copy.ctor}, +if a given potentially constructed subobject is not designated by a +\grammarterm{mem-initializer-id} +(including the case where there is no +\grammarterm{mem-initializer-list} +because the constructor has no +\grammarterm{ctor-initializer}), +then +\begin{itemize} +\item if the entity is a non-static data member that has +a default member initializer\iref{class.mem} and either +\begin{itemize} +\item the constructor's class is a union\iref{class.union}, and no other variant +member of that union is designated by a \grammarterm{mem-initializer-id} or + +\item the constructor's class is not a union, and, if the entity is a member of an +anonymous union, no other member of that union is designated by a +\grammarterm{mem-initializer-id}, +\end{itemize} +the entity is initialized from its default member initializer +as specified in~\ref{dcl.init}; + +\item otherwise, if the entity is an anonymous union or a variant member\iref{class.union.anon}, no initialization is performed; + +\item otherwise, the entity is default-initialized\iref{dcl.init}. +\end{itemize} + +\begin{note} +An abstract class\iref{class.abstract} is never a most derived +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} +After the call to a constructor for class +\tcode{X} +for an object with automatic or dynamic storage duration +has completed, if +the constructor was not invoked as part of value-initialization and +a member of +\tcode{X} +is neither initialized nor +given a value +during execution of the \grammarterm{compound-statement} of the body of the constructor, +the member has an indeterminate or erroneous value\iref{basic.indet}. +\end{note} +\begin{example} +\begin{codeblock} +struct A { + A(); +}; + +struct B { + B(int); +}; + +struct C { + C() { } // initializes members as follows: + A a; // OK, calls \tcode{A::A()} + const B b; // error: \tcode{B} has no default constructor + int i; // OK, \tcode{i} has indeterminate or erroneous value + int j = 5; // OK, \tcode{j} has the value \tcode{5} +}; +\end{codeblock} +\end{example} + +\pnum +If a given non-static data member has both a default member initializer +and a \grammarterm{mem-initializer}, the initialization specified by the +\grammarterm{mem-initializer} is performed, and the non-static data member's +default member initializer is ignored. +\begin{example} +Given +% The comment below is misrendered with an overly large space before 'effects' +% if left to listings (see NB US-26 (C++17 CD)) (possibly due to the ff +% ligature), so we fix it up manually. +\begin{codeblock} +struct A { + int i = /* some integer expression with side effects */ ; + A(int arg) : i(arg) { } + // ... +}; +\end{codeblock} +the \tcode{A(int)} constructor will simply initialize \tcode{i} to the value of +\tcode{arg}, and the +\indextext{side effects}% +side effects in \tcode{i}'s default member initializer +will not take place. +\end{example} + +\pnum +A temporary expression bound to a reference member from a +default member initializer is ill-formed. +\begin{example} +\begin{codeblock} +struct A { + A() = default; // OK + A(int v) : v(v) { } // OK + const int& v = 42; // OK +}; +A a1; // error: ill-formed binding of temporary to reference +A a2(1); // OK, unfortunately +\end{codeblock} +\end{example} + +\pnum +In a non-delegating constructor, the destructor for each potentially constructed +subobject of class type is potentially invoked\iref{class.dtor}. +\begin{note} +This provision ensures that destructors can be called for fully-constructed +subobjects in case an exception is thrown\iref{except.ctor}. +\end{note} + +\pnum +In a non-delegating constructor, initialization +proceeds in the following order: +\begin{itemize} +\item +\indextext{initialization!order of virtual base class}% +First, and only for the constructor of the most derived class\iref{intro.object}, +virtual base classes are initialized in the order they appear on a +depth-first left-to-right traversal of the directed acyclic graph of +base classes, +where ``left-to-right'' is the order of appearance of the base classes +in the derived class +\grammarterm{base-specifier-list}. +\item +\indextext{initialization!order of base class}% +Then, direct base classes are initialized in declaration order +as they appear in the +\grammarterm{base-specifier-list} +(regardless of the order of the +\grammarterm{mem-initializer}{s}). +\item +\indextext{initialization!order of member}% +Then, non-static data members are initialized in the order +they were declared in the class definition +(again regardless of the order of the +\grammarterm{mem-initializer}{s}). +\item +Finally, the \grammarterm{compound-statement} of the constructor +body is executed. +\end{itemize} + +\begin{note} +The declaration order is mandated to ensure that base and member +subobjects are destroyed in the reverse order of initialization. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +struct V { + V(); + V(int); +}; + +struct A : virtual V { + A(); + A(int); +}; + +struct B : virtual V { + B(); + B(int); +}; + +struct C : A, B, virtual V { + C(); + C(int); +}; + +A::A(int i) : V(i) { @\commentellip@ } +B::B(int i) { @\commentellip@ } +C::C(int i) { @\commentellip@ } + +V v(1); // use \tcode{V(int)} +A a(2); // use \tcode{V(int)} +B b(3); // use \tcode{V()} +C c(4); // use \tcode{V()} +\end{codeblock} +\end{example} + +\pnum +\indextext{initializer!scope of member}% +\begin{note} +The \grammarterm{expression-list} or \grammarterm{braced-init-list} +of a \grammarterm{mem-initializer} +is in the function parameter scope of the constructor +and can use \keyword{this} to refer to the object being initialized. +\end{note} +\begin{example} +\begin{codeblock} +class X { + int a; + int b; + int i; + int j; +public: + const int& r; + X(int i): r(a), b(i), i(i), j(this->i) { } +}; +\end{codeblock} + +initializes +\tcode{X::r} +to refer to +\tcode{X::a}, +initializes +\tcode{X::b} +with the value of the constructor parameter +\tcode{i}, +initializes +\tcode{X::i} +with the value of the constructor parameter +\tcode{i}, +and initializes +\tcode{X::j} +with the value of +\tcode{X::i}; +this takes place each time an object of class +\tcode{X} +is created. +\end{example} + +\pnum +\indextext{initialization!member function call during}% +Member functions (including virtual member functions, \ref{class.virtual}) can be +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 +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, +\item +a precondition assertion of a constructor, or +\item +a postcondition assertion of a destructor\iref{dcl.contract.func}, +\end{itemize} +the program has undefined behavior. +\begin{example} +\begin{codeblock} +class A { +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()) { } // well-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()) { } // well-defined: bases are all initialized +}; +\end{codeblock} +\end{example} + +\pnum +\begin{note} +\ref{class.cdtor} describes the results of virtual function calls, +\tcode{typeid} +and +\keyword{dynamic_cast}s +during construction for the well-defined cases; +that is, describes the polymorphic behavior +of an object under construction. +\end{note} + +\pnum +\indextext{initializer!pack expansion}% +A \grammarterm{mem-initializer} followed by an ellipsis is +a pack expansion\iref{temp.variadic} that initializes the base +classes specified by a pack expansion in the \grammarterm{base-specifier-list} +for the class. +\begin{example} +\begin{codeblock} +template +class X : public Mixins... { +public: + X(const Mixins&... mixins) : Mixins(mixins)... { } +}; +\end{codeblock} + +\end{example} + +\rSec2[class.inhctor.init]{Initialization by inherited constructor}% +\indextext{initialization!by inherited constructor} + +\pnum +When a constructor for type \tcode{B} is invoked +to initialize an object of a different type \tcode{D} +(that is, when the constructor was inherited\iref{namespace.udecl}), +initialization proceeds as if a defaulted default constructor +were used to initialize the \tcode{D} object and +each base class subobject from which the constructor was inherited, +except that the \tcode{B} subobject is initialized +by the inherited constructor +if the base class subobject were to be initialized +as part of the \tcode{D} object\iref{class.base.init}. +The invocation of the inherited constructor, +including the evaluation of any arguments, +is omitted if the \tcode{B} subobject is not to be initialized +as part of the \tcode{D} object. +The complete initialization is considered to be a single function call; +in particular, unless omitted, +the initialization of the inherited constructor's parameters +is sequenced before the initialization of any part of the \tcode{D} object. +\begin{example} +\begin{codeblock} +struct B1 { + B1(int, ...) { } +}; + +struct B2 { + B2(double) { } +}; + +int get(); + +struct D1 : B1 { + using B1::B1; // inherits \tcode{B1(int, ...)} + int x; + int y = get(); +}; + +void test() { + D1 d(2, 3, 4); // OK, \tcode{B1} is initialized by calling \tcode{B1(2, 3, 4)}, + // then \tcode{d.x} is default-initialized (no initialization is performed), + // then \tcode{d.y} is initialized by calling \tcode{get()} + D1 e; // error: \tcode{D1} has no default constructor +} + +struct D2 : B2 { + using B2::B2; + B1 b; +}; + +D2 f(1.0); // error: \tcode{B1} has no default constructor + +struct W { W(int); }; +struct X : virtual W { using W::W; X() = delete; }; +struct Y : X { using X::X; }; +struct Z : Y, virtual W { using Y::Y; }; +Z z(0); // OK, initialization of \tcode{Y} does not invoke default constructor of \tcode{X} + +template struct Log : T { + using T::T; // inherits all constructors from class \tcode{T} + ~Log() { std::clog << "Destroying wrapper" << std::endl; } +}; +\end{codeblock} +Class template \tcode{Log} wraps any class and forwards all of its constructors, +while writing a message to the standard log +whenever an object of class \tcode{Log} is destroyed. +\end{example} + +\begin{example} +\begin{codeblock} +struct V { V() = default; V(int); }; +struct Q { Q(); }; +struct A : virtual V, Q { + using V::V; + A() = delete; +}; +int bar() { return 42; } +struct B : A { + B() : A(bar()) {} // OK +}; +struct C : B {}; +void foo() { C c; } // \tcode{bar} is not invoked, because the \tcode{V} subobject is not initialized as part of \tcode{B} +\end{codeblock} +\end{example} + +\pnum +If the constructor was inherited from multiple base class subobjects +of type \tcode{B}, the program is ill-formed. +\begin{example} +\begin{codeblock} +struct A { A(int); }; +struct B : A { using A::A; }; + +struct C1 : B { using B::B; }; +struct C2 : B { using B::B; }; + +struct D1 : C1, C2 { + using C1::C1; + using C2::C2; +}; + +struct V1 : virtual B { using B::B; }; +struct V2 : virtual B { using B::B; }; + +struct D2 : V1, V2 { + using V1::V1; + using V2::V2; +}; + +D1 d1(0); // error: ambiguous +D2 d2(0); // OK, initializes virtual \tcode{B} base class, which initializes the \tcode{A} base class + // then initializes the \tcode{V1} and \tcode{V2} base classes as if by a defaulted default constructor + +struct M { M(); M(int); }; +struct N : M { using M::M; }; +struct O : M {}; +struct P : N, O { using N::N; using O::O; }; +P p(0); // OK, use \tcode{M(0)} to initialize \tcode{N}{'s} base class, + // use \tcode{M()} to initialize \tcode{O}{'s} base class +\end{codeblock} +\end{example} + +\pnum +When an object is initialized by an inherited constructor, +initialization of the object is complete +when the initialization of all subobjects is complete.% +\indextext{initialization!class object|)} + +\rSec2[class.cdtor]{Construction and destruction}% +\indextext{construction|(}% +\indextext{destruction|(}% + +\pnum +\indextext{construction!member access}% +\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 +any non-static member or base class of the object after the destructor finishes +execution results in undefined behavior. +\begin{example} +\begin{codeblock} +struct X { int i; }; +struct Y : X { Y(); }; // non-trivial +struct A { int a; }; +struct B : public A { int j; Y y; }; // non-trivial + +extern B bobj; +B* pb = &bobj; // OK +int* p1 = &bobj.a; // undefined behavior: refers to base class member +int* p2 = &bobj.y.i; // undefined behavior: refers to member's member + +A* pa = &bobj; // undefined behavior: upcast to a base class type +B bobj; // definition of \tcode{bobj} + +extern X xobj; +int* p3 = &xobj.i; // OK, all constructors of \tcode{X} are trivial +X xobj; +\end{codeblock} +For another example, +\begin{codeblock} +struct W { int j; }; +struct X : public virtual W { }; +struct Y { + int* p; + X x; + Y() : p(&x.j) { // undefined, \tcode{x} is not yet constructed + } +}; +\end{codeblock} +\end{example} + +\pnum +During the construction 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 thus obtained is unspecified. +\begin{example} +\begin{codeblock} +struct C; +void no_opt(C*); + +struct C { + int c; + C() : c(0) { no_opt(this); } +}; + +const C cobj; + +void no_opt(C* cptr) { + int i = cobj.c * 100; // value of \tcode{cobj.c} is unspecified + cptr->c = 1; + cout << cobj.c * 100 // value of \tcode{cobj.c} is unspecified + << '\n'; +} + +extern struct D d; +struct D { + D(int a) : a(a), b(d.a) {} + int a, b; +}; +D d = D(1); // value of \tcode{d.b} is unspecified +\end{codeblock} +\end{example} + +\pnum +\indextext{construction!pointer to member or base}% +\indextext{destruction!pointer to member or base}% +To explicitly or implicitly convert a pointer (a glvalue) referring to +an object of class +\tcode{X} +to a pointer (reference) to a direct or indirect base class +\tcode{B} +of +\tcode{X}, +the construction of +\tcode{X} +and the construction of all of its direct or indirect bases that directly or +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. +To form a pointer to (or access the value of) a direct non-static member of +an object +\tcode{obj}, +the construction of +\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. +\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} + +\pnum +\indextext{virtual function call!constructor and}% +\indextext{virtual function call!destructor and}% +\indextext{construction!virtual function call}% +\indextext{destruction!virtual function call}% +Member functions, including virtual functions\iref{class.virtual}, can be called +during construction or destruction\iref{class.base.init}. +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, +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 +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. +\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 well-defined, calls \tcode{B::g} + a->f(); // undefined behavior: \tcode{a}'s type not a base of \tcode{B} +} +\end{codeblock} +\end{example} + +\pnum +\indextext{construction!\idxcode{typeid} operator}% +\indextext{destruction!\idxcode{typeid} operator}% +\indextext{\idxcode{typeid}!construction and}% +\indextext{\idxcode{typeid}!destruction and}% +The +\tcode{typeid} +operator\iref{expr.typeid} can be used during construction or destruction\iref{class.base.init}. +When +\tcode{typeid} +is used in a constructor (including the +\grammarterm{mem-initializer} or default member initializer\iref{class.mem} +for a non-static data member) +or in a destructor, or used in a function called (directly or indirectly) from +a constructor or destructor, if the operand of +\tcode{typeid} +refers to the object under construction or destruction, +\tcode{typeid} +yields the +\tcode{std::type_info} +object representing the constructor or destructor's class. +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 +\indextext{construction!dynamic cast and}% +\indextext{destruction!dynamic cast and}% +\indextext{cast!dynamic!construction and}% +\indextext{cast!dynamic!destruction and}% +\keyword{dynamic_cast}s\iref{expr.dynamic.cast} can be used during construction +or destruction\iref{class.base.init}. When a +\keyword{dynamic_cast} +is used in a constructor (including the +\grammarterm{mem-initializer} or default member initializer +for a non-static data member) +or in a destructor, or used in a function called (directly or indirectly) from +a constructor or destructor, if the operand of the +\keyword{dynamic_cast} +refers to the object under construction or destruction, this object is +considered to be a most derived object that has the type of the constructor or +destructor's class. +If the operand of the +\keyword{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 +\keyword{dynamic_cast} +results in undefined behavior. +\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{type_info} for \tcode{B} + typeid(*v); // well-defined: \tcode{*v} has type \tcode{V}, a base of \tcode{B} yields \tcode{type_info} for \tcode{B} + typeid(*a); // undefined behavior: type \tcode{A} not a base of \tcode{B} + dynamic_cast(v); // well-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} +\indextext{destruction|)}% +\indextext{construction|)}% + +\rSec2[class.copy.elision]{Copy/move elision}% + +\pnum +\indextext{temporary!elimination of}% +\indextext{elision!copy constructor|see{constructor, copy, elision}}% +\indextext{elision!move constructor|see{constructor, move, elision}}% +\indextext{constructor!copy!elision}% +\indextext{constructor!move!elision}% +When certain criteria are met, an implementation is +allowed to omit the creation of a class object from +a source object of the same type (ignoring cv-qualification), +even if the selected constructor and/or the +destructor for the object have +\indextext{side effects}% +side effects. In such cases, the +implementation treats the source and target of the +omitted initialization as simply two different ways of +referring to the same object. If the first parameter of the +selected constructor is an rvalue reference to the object's type, +the destruction of that object occurs when the target would have been destroyed; +otherwise, the destruction occurs at the later of the times when the +two objects would have been destroyed without the +optimization. +\begin{note} +Because only one object is destroyed instead of two, +and the creation of one object is omitted, +there is still one object destroyed for each one constructed. +\end{note} +This elision of object creation, called +\indexdefn{copy elision|see{constructor, copy, elision}}% +\indexdefn{elision!copy|see{constructor, copy, elision}}% +\indexdefn{constructor!copy!elision}\indexdefn{constructor!move!elision}\term{copy elision}, +is permitted in the +following circumstances (which may be combined to +eliminate multiple copies): +\begin{itemize} +\item in a \tcode{return} statement\iref{stmt.return} in +a function with a class return type, +when the \grammarterm{expression} is the name of a non-volatile +object $o$ with automatic storage duration (other than a function parameter or a variable +introduced by the \grammarterm{exception-declaration} of a +\grammarterm{handler}\iref{except.handle}), +the copy-initialization of the result object can be +omitted by constructing $o$ directly +into the function call's result object; + +\item in a \grammarterm{throw-expression}\iref{expr.throw}, when the operand +is the name of a non-volatile object $o$ with automatic storage duration +(other than a function parameter or +a variable introduced by +the \grammarterm{exception-declaration} of a \grammarterm{handler}) +that belongs to a scope that does not contain +the innermost enclosing \grammarterm{compound-statement} +associated with a \grammarterm{try-block} (if there is one), +the copy-initialization of the exception object can be omitted by +constructing $o$ directly into the exception object; + +\item in a coroutine\iref{dcl.fct.def.coroutine}, a copy of a coroutine parameter +can be omitted and references to that copy replaced with references to the +corresponding parameter if the meaning of the program will be unchanged except for +the execution of a constructor and destructor for the parameter copy object; + +\item when the \grammarterm{exception-declaration} of a +\grammarterm{handler}\iref{except.handle} declares an object $o$, +the copy-initialization of $o$ can be omitted by treating +the \grammarterm{exception-declaration} as an alias for the exception +object if the meaning of the program will be unchanged except for the execution +of constructors and destructors for the object declared by the +\grammarterm{exception-declaration}. +\begin{note} +There cannot be a move from the exception object because it is +always an lvalue. +\end{note} +\end{itemize} +Copy elision is not permitted +where an expression is evaluated in a context +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 +if the same expression +is evaluated in another context. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +class Thing { +public: + Thing(); + ~Thing(); + Thing(const Thing&); +}; + +Thing f() { + Thing t; + return t; +} + +Thing t2 = f(); + +struct A { + void *p; + constexpr A(): p(this) {} +}; + +constexpr A g() { + A loc; + return loc; +} + +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.const} + +void h() { + A c = g(); // well-formed, \tcode{c.p} can point to \tcode{c} or be dangling +} +\end{codeblock} +Here the criteria for elision can eliminate +the copying of the object \tcode{t} with automatic storage duration +into the result object for the function call \tcode{f()}, +which is the non-local object \tcode{t2}. +Effectively, the construction of \tcode{t} +can be viewed as directly initializing \tcode{t2}, +and that object's destruction will occur at program exit. +Adding a move constructor to \tcode{Thing} has the same effect, but it is the +move construction from the object with automatic storage duration to \tcode{t2} that is elided. +\end{example} + +\pnum +\begin{example} +\begin{codeblock} +class Thing { +public: + Thing(); + ~Thing(); + Thing(Thing&&); +private: + Thing(const Thing&); +}; + +Thing f(bool b) { + Thing t; + if (b) + throw t; // OK, \tcode{Thing(Thing\&\&)} used (or elided) to throw \tcode{t} + return t; // OK, \tcode{Thing(Thing\&\&)} used (or elided) to return \tcode{t} +} + +Thing t2 = f(false); // OK, no extra copy/move performed, \tcode{t2} constructed by call to \tcode{f} + +struct Weird { + Weird(); + Weird(Weird&); +}; + +Weird g(bool b) { + static Weird w1; + Weird w2; + if (b) + return w1; // OK, uses \tcode{Weird(Weird\&)} + else + return w2; // error: \tcode{w2} in this context is an xvalue +} + +int& h(bool b, int i) { + static int s; + if (b) + return s; // OK + else + return i; // error: \tcode{i} is an xvalue +} + +decltype(auto) h2(Thing t) { + return t; // OK, \tcode{t} is an xvalue and \tcode{h2}'s return type is \tcode{Thing} +} + +decltype(auto) h3(Thing t) { + return (t); // OK, \tcode{(t)} is an xvalue and \tcode{h3}'s return type is \tcode{Thing\&\&} +} +\end{codeblock} +\end{example} + +\pnum +\begin{example} +\begin{codeblock} +template void g(const T&); + +template void f() { + T x; + try { + T y; + try { g(x); } + catch (...) { + if (/*...*/) + throw x; // does not move + throw y; // moves + } + g(y); + } catch(...) { + g(x); + g(y); // error: \tcode{y} is not in scope + } +} +\end{codeblock} +\end{example} + +\rSec1[class.compare]{Comparisons}% + +\rSec2[class.compare.default]{Defaulted comparison operator functions}% + +\pnum +A defaulted comparison operator function\iref{over.binary} +shall be a non-template function +that +\begin{itemize} +\item +is a non-static member or friend of some class \tcode{C}, + +\item +is defined as defaulted in \tcode{C} or in +a context where \tcode{C} is complete, and + +\item +either has +two parameters of type \tcode{const C\&} or +two parameters of type \tcode{C}, +where the implicit object parameter (if any) is considered to be +the first parameter. +\end{itemize} +Such a comparison operator function is termed +\indextext{operator!defaulted comparison operator function}% +a defaulted comparison operator function for class \tcode{C}. +Name lookups and access checks in +the implicit definition\iref{dcl.fct.def.default} +of a comparison operator function +are performed from a context equivalent to +its \grammarterm{function-body}. +A definition of a comparison operator as +defaulted that appears in a class shall be the first declaration +of that function. +\begin{example} +\begin{codeblock} +struct S; +bool operator==(S, S) = default; // error: \tcode{S} is not complete +struct S { + friend bool operator==(S, const S&) = default; // error: parameters of different types +}; +enum E { }; +bool operator==(E, E) = default; // error: not a member or friend of a class +\end{codeblock} +\end{example} + +\pnum +A defaulted \tcode{<=>} or \tcode{==} operator function for class \tcode{C} +\indextext{operator!three-way comparison!deleted}% +\indextext{operator!equality!deleted}% +is defined as deleted if +any non-static data member of \tcode{C} is of reference type or +\tcode{C} has variant members\iref{class.union.anon}. + +\pnum +A binary operator expression \tcode{a @ b} is +\defnx{usable}{usable!binary operator expression} +if either + +\begin{itemize} +\item +\tcode{a} or \tcode{b} is of class or enumeration type and +overload resolution\iref{over.match} as applied to \tcode{a @ b} +results in a usable candidate, or + +\item +neither \tcode{a} nor \tcode{b} is of class or enumeration type and +\tcode{a @ b} is a valid expression. +\end{itemize} + +\pnum +If the \grammarterm{member-specification} +does not explicitly declare +any member or friend named \tcode{operator==}, +an \tcode{==} operator function is declared implicitly +for each three-way comparison operator function +defined as defaulted in the \grammarterm{member-specification}, +with the same access and \grammarterm{function-definition} and +in the same class scope as +the respective three-way comparison operator function, +except that the return type is replaced with \tcode{bool} and +the \grammarterm{declarator-id} is replaced with \tcode{operator==}. +\begin{note} +Such an implicitly-declared \tcode{==} operator for a class \tcode{X} +is defined as defaulted +in the definition of \tcode{X} and +has the same \grammarterm{parameter-declaration-clause} and +trailing \grammarterm{requires-clause} as +the respective three-way comparison operator. +It is declared with \keyword{friend}, \keyword{virtual}, \keyword{constexpr}, +or \keyword{consteval} if +the three-way comparison operator function is so declared. +If the three-way comparison operator function +has no \grammarterm{noexcept-specifier}, +the implicitly-declared \tcode{==} operator function +has an implicit exception specification\iref{except.spec} that +can differ from the implicit exception specification of +the three-way comparison operator function. +\end{note} +\begin{example} +\begin{codeblock} +template struct X { + friend constexpr std::partial_ordering operator<=>(X, X) requires (sizeof(T) != 1) = default; + // implicitly declares: \tcode{friend constexpr bool operator==(X, X) requires (sizeof(T) != 1) = default;} + + [[nodiscard]] virtual std::strong_ordering operator<=>(const X&) const = default; + // implicitly declares: \tcode{[[nodiscard]] virtual bool operator==(const X\&) const = default;} +}; +\end{codeblock} +\end{example} +\begin{note} +The \tcode{==} operator function is declared implicitly even if +the defaulted three-way comparison operator function +is defined as deleted. +\end{note} + +\pnum +The direct base class subobjects of \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}, +in the order of their declaration in the \grammarterm{member-specification} of \tcode{C}, +form a list of subobjects. +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 +in the expanded list of subobjects for an object \tcode{x} +(of length $n$), +where $\tcode{x}_i$ is +formed by a sequence of +derived-to-base conversions\iref{over.best.ics}, +class member access expressions\iref{expr.ref}, and +array subscript expressions\iref{expr.sub} applied to \tcode{x}. + +\rSec2[class.eq]{Equality operator} +\indextext{operator!equality!defaulted}% + +\pnum +A defaulted equality operator function\iref{over.binary} +shall have a declared return type \tcode{bool}. + +\pnum +A defaulted \tcode{==} operator function for a class \tcode{C} +is defined as deleted +unless, for each $\tcode{x}_i$ in the expanded list of subobjects +for an object \tcode{x} of type \tcode{C}, +$\tcode{x}_i\tcode{ == }\tcode{x}_i$ +is usable\iref{class.compare.default}. + +\pnum +The return value of a defaulted \tcode{==} operator function +with parameters \tcode{x} and \tcode{y} is determined +by comparing corresponding elements $\tcode{x}_i$ and $\tcode{y}_i$ +in the expanded lists of subobjects for \tcode{x} and \tcode{y} +(in increasing index order) +until the first index $i$ +where $\tcode{x}_i\tcode{ == }\tcode{y}_i$ yields a result value which, +when contextually converted to \tcode{bool}, yields \tcode{false}. +The return value is \tcode{false} if such an index exists +and \tcode{true} otherwise. + +\pnum +\begin{example} +\begin{codeblock} +struct D { + int i; + friend bool operator==(const D& x, const D& y) = default; + // OK, returns \tcode{x.i == y.i} +}; +\end{codeblock} +\end{example} + +\rSec2[class.spaceship]{Three-way comparison} +\indextext{operator!three-way comparison!defaulted}% + +\pnum +The \defnadj{synthesized}{three-way comparison} +of type \tcode{R}\iref{cmp.categories} +of glvalues \tcode{a} and \tcode{b} of the same type +is defined as follows: + +\begin{itemize} +\item +If \tcode{a <=> b} is usable\iref{class.compare.default} and +can be explicitly converted to \tcode{R} using \keyword{static_cast}, +\tcode{static_cast(a <=> b)}. + +\item +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. + +\item +Otherwise, if \tcode{R} is not a comparison category type, or either +the expression \tcode{a == b} or the expression \tcode{a < b} +is not usable, +the synthesized three-way comparison is not defined. + +\item +Otherwise, if \tcode{R} is \tcode{strong_ordering}, then +\begin{codeblock} +a == b ? strong_ordering::equal : +a < b ? strong_ordering::less : + strong_ordering::greater +\end{codeblock} + +\item +Otherwise, if \tcode{R} is \tcode{weak_ordering}, then +\begin{codeblock} +a == b ? weak_ordering::equivalent : +a < b ? weak_ordering::less : + weak_ordering::greater +\end{codeblock} + +\item +Otherwise (when \tcode{R} is \tcode{partial_ordering}), +\begin{codeblock} +a == b ? partial_ordering::equivalent : +a < b ? partial_ordering::less : +b < a ? partial_ordering::greater : + partial_ordering::unordered +\end{codeblock} +\end{itemize} + +\begin{note} +A synthesized three-way comparison is ill-formed +if overload resolution finds usable candidates +that do not otherwise meet the requirements implied by the defined expression. +\end{note} + +\pnum +Let \tcode{R} be the declared return type of +a defaulted three-way comparison operator function, and +let $\tcode{x}_i$ be the elements of +the expanded list of subobjects for +an object \tcode{x} of type \tcode{C}. + +\begin{itemize} +\item +If \tcode{R} is \keyword{auto}, then +let $\cv{}_i~\tcode{R}_i$ be +the type of the expression $\tcode{x}_i\tcode{ <=> }\tcode{x}_i$. +The operator function is defined as deleted +if that expression is not usable or +if $\tcode{R}_i$ is not +a comparison category type\iref{cmp.categories.pre} for any $i$. +The return type is deduced as +the common comparison type (see below) of +$\tcode{R}_0$, $\tcode{R}_1$, $\dotsc$, $\tcode{R}_{n-1}$. +\item +Otherwise, \tcode{R} shall not contain a placeholder type. +If the synthesized three-way comparison of type \tcode{R} +between any objects $\tcode{x}_i$ and $\tcode{x}_i$ +is not defined, +the operator function is defined as deleted. +\end{itemize} + +\pnum +The return value of type \tcode{R} +of the defaulted three-way comparison operator function +with parameters \tcode{x} and \tcode{y} of the same type +is determined by comparing corresponding elements +$\tcode{x}_i$ and $\tcode{y}_i$ +in the expanded lists of subobjects for \tcode{x} and \tcode{y} +(in increasing index order) +until the first index $i$ where +the synthesized three-way comparison of type \tcode{R} +between $\tcode{x}_i$ and $\tcode{y}_i$ +yields a result value $\tcode{v}_i$ where $\tcode{v}_i \mathrel{\tcode{!=}} 0$, +contextually converted to \tcode{bool}, yields \tcode{true}. +The return value is a copy of $\tcode{v}_i$ +if such an index exists and +\tcode{static_cast(std::strong_ordering::equal)} otherwise. + +\pnum +The \defn{common comparison type} \tcode{U} +of a possibly-empty list of $n$ comparison category types +$\tcode{T}_0$, $\tcode{T}_1$, $\dotsc$, $\tcode{T}_{n-1}$ +is defined as follows: + +\begin{itemize} +\item +If at least one $\tcode{T}_i$ is \tcode{std::partial_ordering}, +\tcode{U} is \tcode{std::partial_ordering}\iref{cmp.partialord}. + +\item +Otherwise, if at least one $\tcode{T}_i$ is \tcode{std::weak_ordering}, +\tcode{U} is \tcode{std::weak_ordering}\iref{cmp.weakord}. + +\item +Otherwise, \tcode{U} is \tcode{std::strong_ordering}\iref{cmp.strongord}. +\begin{note} +In particular, this is the result when $n$ is 0. +\end{note} +\end{itemize} + +\rSec2[class.compare.secondary]{Secondary comparison operators} +\indextext{operator!inequality!defaulted}% +\indextext{operator!relational!defaulted}% + +\pnum +\indextext{operator!comparison!secondary}% +A \defn{secondary comparison operator} is +a relational operator\iref{expr.rel} or the \tcode{!=} operator. +A defaulted operator function\iref{over.binary} +for a secondary comparison operator \tcode{@} +shall have a declared return type \tcode{bool}. + +\pnum +The operator function with parameters \tcode{x} and \tcode{y} +is defined as deleted if +\begin{itemize} +\item +a first overload resolution\iref{over.match}, +as applied to \tcode{x @ y}, +\begin{itemize} +\item +does not result in a usable candidate, or +\item +the selected candidate is not a rewritten candidate, or +\end{itemize} + +\item +a second overload resolution for +the expression resulting from the interpretation of \tcode{x @ y} +using the selected rewritten candidate\iref{over.match.oper} +does not result in a usable candidate +(for example, that expression might be \tcode{(x <=> y) @ 0}), or + +\item +\tcode{x @ y} cannot be implicitly converted to \tcode{bool}. +\end{itemize} +In any of the two overload resolutions above, +the defaulted operator function is not considered as +a candidate for the \tcode{@} operator. +Otherwise, the operator function yields \tcode{x @ y}. + +\pnum +\begin{example} +\begin{codeblock} +struct HasNoLessThan { }; + +struct C { + friend HasNoLessThan operator<=>(const C&, const C&); + bool operator<(const C&) const = default; // OK, function is deleted +}; +\end{codeblock} +\end{example} + \indextext{class|)} diff --git a/source/compatibility.tex b/source/compatibility.tex index 8b2f252ee0..e3512400d3 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -1,1887 +1,3756 @@ %!TEX root = std.tex \infannex{diff}{Compatibility} -\rSec1[diff.iso]{\Cpp and ISO C} +\rSec1[diff.cpp23]{\Cpp{} and ISO \CppXXIII{}} + +\rSec2[diff.cpp23.general]{General} \pnum -\indextext{summary!compatibility~with ISO C}% -This subclause lists the differences between \Cpp and -ISO C, by the chapters of this document. +\indextext{summary!compatibility with ISO \CppXXIII{}}% +Subclause \ref{diff.cpp23} lists the differences between \Cpp{} and +ISO \CppXXIII{}, +by the chapters of this document. -\rSec2[diff.lex]{Clause~\ref{lex}: lexical conventions} +\rSec2[diff.cpp23.lex]{\ref{lex}: lexical conventions} -\ref{lex.key} -\change New Keywords\\ -New keywords are added to \Cpp; -see \ref{lex.key}. +\diffref{lex.operators} +\change +New operator \tcode{\caret\caret}. \rationale -These keywords were added in order to implement the new -semantics of \Cpp. +Required for new features. \effect -Change to semantics of well-defined feature. -Any ISO C programs that used any of these keywords as identifiers -are not valid \Cpp programs. -\difficulty -Syntactic transformation. -Converting one specific program is easy. -Converting a large collection -of related programs takes more work. -\howwide -Common. - -\ref{lex.ccon} -\change Type of character literal is changed from \tcode{int} to \tcode{char} -\rationale -This is needed for improved overloaded function argument type -matching. -For example: - +Valid \CppXXIII{} code that contains two consecutive \tcode{\caret} tokens +can be ill-formed in this revision of \Cpp{}. +\begin{example} \begin{codeblock} -int function( int i ); -int function( char c ); - -function( 'x' ); +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} -It is preferable that this call match the second version of -function rather than the first. +\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 -Change to semantics of well-defined feature. -ISO C programs which depend on +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 +Operations mixing a value of an enumeration type and a value of a different +enumeration type or of a floating-point type are no longer valid. +\rationale +Reinforcing type safety. +\effect +A valid \CppXXIII{} program that performs operations mixing a value of an +enumeration type and a value of a different enumeration type or of a +floating-point type is ill-formed. +\begin{example} \begin{codeblock} -sizeof('x') == sizeof(int) +enum E1 { e }; +enum E2 { f }; +bool b = e <= 3.7; // ill-formed; previously well-formed +int k = f - e; // ill-formed; previously well-formed +auto x = true ? e : f; // ill-formed; previously well-formed \end{codeblock} +\end{example} -will not work the same as \Cpp programs. -\difficulty -Simple. -\howwide -Programs which depend upon \tcode{sizeof('x')} are probably rare. - -Subclause \ref{lex.string}: -\change String literals made const\\ -The type of a string literal is changed -from ``array of \tcode{char}'' -to ``array of \tcode{const char}.'' -The type of a \tcode{char16_t} string literal is changed -from ``array of \textit{some-integer-type}'' -to ``array of \tcode{const char16_t}.'' -The type of a \tcode{char32_t} string literal is changed -from ``array of \textit{some-integer-type}'' -to ``array of \tcode{const char32_t}.'' -The type of a wide string literal is changed -from ``array of \tcode{wchar_t}'' -to ``array of \tcode{const wchar_t}.'' +\diffref{expr.rel,expr.eq} +\change +Comparing two objects of array type is no longer valid. \rationale -This avoids calling an inappropriate overloaded function, -which might expect to be able to modify its argument. +The old behavior was confusing since it compared not the contents of the two +arrays, but their addresses. \effect -Change to semantics of well-defined feature. -\difficulty -Syntactic transformation. The fix is to add a cast: - +A valid \CppXXIII{} program directly comparing two array objects is rejected as +ill-formed in this document. +\begin{example} \begin{codeblock} -char* p = "abc"; // valid in C, invalid in \Cpp -void f(char*) { - char* p = (char*)"abc"; // OK: cast added - f(p); - f((char*)"def"); // OK: cast added -} +int arr1[5]; +int arr2[5]; +bool same = arr1 == arr2; // ill-formed; previously well-formed +bool idem = arr1 == +arr2; // compare addresses +bool less = arr1 < +arr2; // compare addresses, unspecified result \end{codeblock} +\end{example} -\howwide -Programs that have a legitimate reason to treat string literals -as pointers to potentially modifiable memory are probably rare. - -\rSec2[diff.basic]{Clause \ref{basic}: basic concepts} +\diffref{expr.delete} +\change +Calling \tcode{delete} on a pointer to an incomplete class is ill-formed. +\rationale +Reduce undefined behavior. +\effect +A valid \CppXXIII{} program that calls \tcode{delete} on an incomplete +class type is ill-formed. +\begin{example} +\begin{codeblock} +struct S; -\ref{basic.def} -\change \Cpp does not have ``tentative definitions'' as in C -E.g., at file scope, +void f(S *p) { + delete p; // ill-formed; previously well-formed +} -\begin{codeblock} -int i; -int i; +struct S {}; \end{codeblock} +\end{example} -is valid in C, invalid in \Cpp. -This makes it impossible to define -mutually referential file-local static objects, if initializers are -restricted to the syntactic forms of C\@. -For example, +\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl}: declarations} +\diffref{dcl.init.list} +\change +Pointer comparisons between \tcode{initializer_list} objects' backing arrays +are unspecified. +\rationale +Permit the implementation to store backing arrays in static read-only memory. +\effect +Valid \CppXXIII{} code +that relies on the result of pointer comparison between backing arrays +may change behavior. +\begin{example} \begin{codeblock} -struct X { int i; struct X* next; }; - -static struct X a; -static struct X b = { 0, &a }; -static struct X a = { 1, &b }; +bool ne(std::initializer_list a, std::initializer_list b) { + return a.begin() != b.begin() + 1; +} +bool b = ne({2,3}, {1,2,3}); // unspecified result; previously \tcode{false} \end{codeblock} +\end{example} +\diffref{dcl.array} +\change +Previously, \tcode{T...[n]} would declare a pack of function parameters. +\tcode{T...[n]} is now a \grammarterm{pack-index-specifier}. \rationale -This avoids having different initialization rules for -fundamental types and user-defined types. +Improve the handling of packs. \effect -Deletion of semantically well-defined feature. -\difficulty -Semantic transformation. -\rationale -In \Cpp, the initializer for one of a set of -mutually-referential file-local static objects must invoke a function -call to achieve the initialization. -\howwide -Seldom. +Valid \CppXXIII{} code that declares a pack of parameters +without specifying a \grammarterm{declarator-id} becomes ill-formed. +\begin{example} +\begin{codeblock} +template +void f(T... [1]); +template +void g(T... ptr[1]); +int main() { + f(nullptr, nullptr); // ill-formed, previously \tcode{void f(int [1], double [1])} + g(nullptr, nullptr); // ok +} +\end{codeblock} +\end{example} -\ref{basic.scope} -\change A \tcode{struct} is a scope in \Cpp, not in C +\diffref{dcl.attr.grammar} +\change +New token \tcode{:]}. \rationale -Class scope is crucial to \Cpp, and a struct is a class. +Required for new features. \effect -Change to semantics of well-defined feature. -\difficulty -Semantic transformation. -\howwide -C programs use \tcode{struct} extremely frequently, but the -change is only noticeable when \tcode{struct}, enumeration, or enumerator -names are referred to outside the \tcode{struct}. -The latter is probably rare. +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} -\ref{basic.link} [also \ref{dcl.type}] -\change A name of file scope that is explicitly declared \tcode{const}, and not explicitly -declared \tcode{extern}, has internal linkage, while in C it would have external linkage -\rationale -Because \tcode{const} objects can be used as compile-time values in -\Cpp, this feature urges programmers to provide explicit initializer -values for each \tcode{const}. -This feature allows the user to put \tcode{const}objects in header files that are included -in many compilation units. -\effect -Change to semantics of well-defined feature. -\difficulty -Semantic transformation -\howwide -Seldom +\rSec2[diff.cpp23.temp]{\ref{temp}: templates} -\ref{basic.start} -\change Main cannot be called recursively and cannot have its address taken +\diffref{temp.constr} +\change +Some atomic constraints become fold expanded constraints. \rationale -The main function may require special actions. +Permit the subsumption of fold expressions. \effect -Deletion of semantically well-defined feature -\difficulty -Trivial: create an intermediary function such as -\tcode{mymain(argc, argv)}. -\howwide -Seldom +Valid \CppXXIII{} code may become ill-formed. +\begin{example} +\begin{codeblock} +template struct A; +struct S { + static constexpr int compare(const S&) { return 1; } +}; -\ref{basic.types} -\change C allows ``compatible types'' in several places, \Cpp does not -For example, -otherwise-identical \tcode{struct} types with different tag names -are ``compatible'' in C but are distinctly different types -in \Cpp. +template +void f(A *, A *) +requires (T::compare(U{}) && ...); // was well-formed (atomic constraint of type \tcode{bool}), + // now ill-formed (results in an atomic constraint of type \tcode{int}) +void g(A *ap) { + f(ap, ap); +} +\end{codeblock} +\end{example} + +\diffref{temp.deduct.call} +\change +Template argument deduction from overload sets succeeds in more cases. \rationale -Stricter type checking is essential for \Cpp. +Allow consideration of constraints to disambiguate overload sets +used as parameters in function calls. \effect -Deletion of semantically well-defined feature. -\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, -according to the ``layout compatibility rules'' of this -International Standard. -\howwide -Common. - -\rSec2[diff.conv]{Clause \ref{conv}: standard conversions} +Valid \CppXXIII{} code may become ill-formed. +\begin{example} +\begin{codeblock} +template +void f(T &&, void (*)(T &&)); -\ref{conv.ptr} -\change Converting \tcode{void*} to a pointer-to-object type requires casting +void g(int &); // \#1 +inline namespace A { + void g(short &&); // \#2 +} +inline namespace B { + void g(short &&); // \#3 +} -\begin{codeblock} -char a[10]; -void* b=a; -void foo() { - char* c=b; +void q() { + int x; + f(x, g); // ill-formed; previously well-formed, deducing \tcode{T = int\&} } \end{codeblock} +There is no change to the applicable deduction rules for +the individual \tcode{g} candidates: +Type deduction from \#1 does not succeed; +type deductions from \#2 and \#3 both succeed. +\end{example} -ISO C will accept this usage of pointer to void being assigned -to a pointer to object type. -\Cpp will not. +\rSec2[diff.cpp23.cpp]{\ref{cpp}: preprocessing directives} + +\diffref{cpp.replace.general} +\change +Additional restrictions on macro names. \rationale -\Cpp tries harder than C to enforce compile-time type safety. +Avoid hard to diagnose or non-portable constructs. \effect -Deletion of semantically well-defined feature. -\difficulty -Could be automated. -Violations will be diagnosed by the \Cpp translator. -The -fix is to add a cast. -For example: +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{}. -\begin{codeblock} -char* c = (char*) b; -\end{codeblock} +\rSec2[diff.cpp23.library]{\ref{library}: library introduction} -\howwide -This is fairly widely used but it is good -programming practice to add the cast when assigning pointer-to-void to pointer-to-object. -Some ISO C translators will give a warning -if the cast is not used. +\diffref{headers} +\change +New headers. +\rationale +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}, +\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.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.expr]{Clause \ref{expr}: expressions} +\rSec2[diff.cpp23.strings]{\ref{strings}: strings library} -\ref{expr.call} -\change Implicit declaration of functions is not allowed +\diffref{string.conversions} +\change +Output of floating-point overloads of \tcode{to_string} and \tcode{to_wstring}. \rationale -The type-safe nature of \Cpp. +Prevent loss of information and improve consistency with other formatting +facilities. \effect -Deletion of semantically well-defined feature. -Note: the original feature was labeled as ``obsolescent'' in ISO C. -\difficulty -Syntactic transformation. -Facilities for producing explicit function declarations are fairly -widespread commercially. -\howwide -Common. - -\ref{expr.sizeof}, \ref{expr.cast} -\change Types must be declared in declarations, not in expressions -In C, a sizeof expression or cast expression may create a new type. -For example, +\tcode{to_string} and \tcode{to_wstring} function calls that take +floating-point arguments may produce a different output. +\begin{example} \begin{codeblock} -p = (void*)(struct x {int i;} *)0; +auto s = std::to_string(1e-7); // \tcode{"1e-07"} + // previously \tcode{"0.000000"} with \tcode{'.'} possibly + // changed according to the global C locale \end{codeblock} -declares a new type, struct x . +\end{example} + +\rSec2[diff.cpp23.io]{\ref{input.output}: input/output library} + +\diffref{istream.unformatted} +\change +Overloaded \tcode{std::basic_istream::ignore}. \rationale -This prohibition helps to clarify the location of -declarations in the source code. +Allow \tcode{char} values to be used as delimiters. \effect -Deletion of a semantically well-defined feature. -\difficulty -Syntactic transformation. -\howwide -Seldom. +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} +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} -\ref{expr.cond}, \ref{expr.ass}, \ref{expr.comma} +\rSec2[diff.cpp23.depr]{\ref{depr}: compatibility features} -\indextext{conversion!lvalue-to-rvalue}% -\indextext{rvalue!lvalue conversion~to}% -\indextext{lvalue}% -\change The result of a conditional expression, an assignment expression, or a comma expression may be an lvalue +\nodiffref +\change +Remove the type alias \tcode{allocator::is_always_equal}. \rationale -\Cpp is an object-oriented language, placing relatively -more emphasis on lvalues. For example, functions may -return lvalues. +Non-empty allocator classes derived from \tcode{allocator} needed to explicitly +define an \tcode{is_always_equal} member type so that \tcode{allocator_traits} +would not use the one from the allocator base class. \effect -Change to semantics of well-defined feature. Some C -expressions that implicitly rely on lvalue-to-rvalue -conversions will yield different results. For example, - +It is simpler to correctly define an allocator class with an allocator base +class. +\begin{example} \begin{codeblock} -char arr[100]; -sizeof(0, arr) -\end{codeblock} +template +struct MyAlloc : allocator { + int tag; +}; -yields -\tcode{100} -in \Cpp and -\tcode{sizeof(char*)} -in C. -\difficulty -Programs must add explicit casts to the appropriate rvalue. -\howwide -Rare. +static_assert(!allocator_traits>::is_always_equal); // Error in \CppXXIII{}, + // OK in \CppXXVI{} +\end{codeblock} +\end{example} -\rSec2[diff.stat]{Clause \ref{stmt.stmt}: statements} +\nodiffref +\change +Removal of atomic access API for \tcode{shared_ptr} objects. +\rationale +The old behavior was brittle. \tcode{shared_ptr} objects using the old API were +not protected by the type system, and certain interactions with code not using +this API would, in some cases, silently produce undefined behavior. A complete +type-safe replacement is provided in the form of \tcode{atomic>}. +\effect +A valid \CppXXIII{} program that relies on the presence of the removed functions +may fail to compile. -\ref{stmt.switch}, \ref{stmt.goto} -\change It is now invalid to jump past a declaration with explicit or implicit initializer (except across entire block not entered) +\nodiffref +\change +Remove the \tcode{basic_string::reserve()} overload with no parameters. \rationale -Constructors used in initializers may allocate -resources which need to be de-allocated upon leaving the -block. -Allowing jump past initializers would require -complicated run-time determination of allocation. -Furthermore, any use of the uninitialized object could be a -disaster. -With this simple compile-time rule, \Cpp assures that -if an initialized variable is in scope, then it has assuredly been -initialized. +The overload of \tcode{reserve} with no parameters is redundant. +The \tcode{shrink_to_fit} member function can be used instead. \effect -Deletion of semantically well-defined feature. -\difficulty -Semantic transformation. -\howwide -Seldom. +A valid \CppXXIII{} program that calls \tcode{reserve()} +on a \tcode{basic_string} object may fail to compile. +The old functionality can be achieved by calling \tcode{shrink_to_fit()} instead, +or the function call can be safely eliminated with no side effects. -\ref{stmt.return} -\change It is now invalid to return (explicitly or implicitly) from a function which is -declared to return a value without actually returning a value +\nodiffref +\change +Remove header \libnoheader{codecvt} and all its contents. \rationale -The caller and callee may assume fairly elaborate -return-value mechanisms for the return of class objects. -If -some flow paths execute a return without specifying any value, -the implementation must embody many more complications. -Besides, -promising to return a value of a given type, and then not returning -such a value, has always been recognized to be a questionable -practice, tolerated only because very-old C had no distinction between -void functions and int functions. +The header has been deprecated for the previous three editions of this document +and no longer implements the current Unicode standard, supporting only the +obsolete UCS-2 encoding. +Ongoing support is at implementer's discretion, +exercising freedoms granted by \ref{zombie.names}. +\effect +A valid \CppXXIII{} program \tcode{\#include}-ing the header or importing the +header unit may fail to compile. Code that uses any of the following names by +importing the standard library modules may fail to compile: +\begin{itemize} +\item \tcode{codecvt_mode}, +\item \tcode{codecvt_utf16}, +\item \tcode{codecvt_utf8}, +\item \tcode{codecvt_utf8_utf16}, +\item \tcode{consume_header}, +\item \tcode{generate_header}, and +\item \tcode{little_endian}. +\end{itemize} + +\nodiffref +\change +Remove header \libnoheader{strstream} and all its contents. +\rationale +The header has been deprecated since the original \Cpp{} standard; the +\libheader{spanstream} header provides an updated, safer facility. +Ongoing support is at implementer's discretion, +exercising freedoms granted by \ref{zombie.names}. +\effect +A valid \CppXXIII{} program \tcode{\#include}-ing the header or importing the +header unit may become ill-formed. Code that uses any of the following classes +by importing one of the standard library modules may become ill-formed: +\begin{itemize} +\item \tcode{istrstream} +\item \tcode{ostrstream} +\item \tcode{strstream} +\item \tcode{strstreambuf} +\end{itemize} + +\nodiffref +\change +Remove convenience interfaces \tcode{wstring_convert} and +\tcode{wbuffer_convert}. +\rationale +These features were underspecified with no clear error reporting mechanism and +were deprecated for the last three editions of this document. +Ongoing support is at implementer's discretion, +exercising freedoms granted by \ref{zombie.names}. \effect -Deletion of semantically well-defined feature. -\difficulty -Semantic transformation. -Add an appropriate return value to the source code, such as zero. -\howwide -Seldom. -For several years, many existing C implementations have produced warnings in -this case. +A valid \CppXXIII{} program using these interfaces may become ill-formed. -\rSec2[diff.dcl]{Clause \ref{dcl.dcl}: declarations} +\rSec1[diff.cpp20]{\Cpp{} and ISO \CppXX{}} -\ref{dcl.stc} -\change In \Cpp, the \tcode{static} or \tcode{extern} specifiers can only be applied to names of objects or functions -Using these specifiers with type declarations is illegal in \Cpp. -In C, these specifiers are ignored when used on type declarations. +\rSec2[diff.cpp20.general]{General} -Example: +\pnum +\indextext{summary!compatibility with ISO \CppXX{}}% +Subclause \ref{diff.cpp20} lists the differences between \Cpp{} and +ISO \CppXX{}, +in addition to those listed above, +by the chapters of this document. -\begin{codeblock} -static struct S { // valid C, invalid in \Cpp - int i; -}; -\end{codeblock} +\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 +not in Normalization Form C, are now rejected. \rationale -Storage class specifiers don't have any meaning when associated -with a type. -In \Cpp, class members can be declared with the \tcode{static} storage -class specifier. -Allowing storage class specifiers on type -declarations could render the code confusing for users. +Prevent confusing characters in identifiers. +Requiring normalization of names ensures consistent linker behavior. \effect -Deletion of semantically well-defined feature. -\difficulty -Syntactic transformation. -\howwide -Seldom. - -\ref{dcl.typedef} -\change A \Cpp typedef name must be different from any class type name declared -in the same scope (except if the typedef is a synonym of the class name with the -same name). In C, a typedef name and a struct tag name declared in the same scope -can have the same name (because they have different name spaces) +Some identifiers are no longer well-formed. -Example: +\diffref{lex.string} +\change +Concatenated \grammarterm{string-literal}s can no longer have +conflicting \grammarterm{encoding-prefix}es. +\rationale +Removal of unimplemented conditionally-supported feature. +\effect +Concatenation of \grammarterm{string-literal}s +with different \grammarterm{encoding-prefix}es +is now ill-formed. +\begin{example} \begin{codeblock} -typedef struct name1 { /*...*/ } name1; // valid C and \Cpp -struct name { /*...*/ }; -typedef int name; // valid C, invalid \Cpp +auto c = L"a" U"b"; // was conditionally-supported; now ill-formed \end{codeblock} +\end{example} -\rationale -For ease of use, \Cpp doesn't require that a type name be prefixed -with the keywords \tcode{class}, \tcode{struct} or \tcode{union} when used in object -declarations or type casts. +\rSec2[diff.cpp20.expr]{\ref{expr}: expressions} -Example: +\diffref{expr.prim.id.unqual} +\change +Change move-eligible \grammarterm{id-expression}s from lvalues to xvalues. +\rationale +Simplify the rules for implicit move. +\effect +Valid \CppXX{} code that relies on a returned \grammarterm{id-expression}'s +being an lvalue may change behavior or fail to compile. +\begin{example} \begin{codeblock} -class name { /*...*/ }; -name i; // \tcode{i} has type \tcode{class name} +decltype(auto) f(int&& x) { return (x); } // returns \tcode{int\&\&}; previously returned \tcode{int\&} +int& g(int&& x) { return x; } // ill-formed; previously well-formed \end{codeblock} +\end{example} +\diffref{expr.sub} +\change +Change the meaning of comma in subscript expressions. +\rationale +Enable repurposing a deprecated syntax to support multidimensional indexing. \effect -Deletion of semantically well-defined feature. -\difficulty -Semantic transformation. -One of the 2 types has to be renamed. -\howwide -Seldom. +Valid \CppXX{} code that uses a comma expression within a +subscript expression may fail to compile. +\begin{example} +\begin{codeblock} +arr[1, 2] // was equivalent to \tcode{arr[(1, 2)]}, + // now equivalent to \tcode{arr.operator[](1, 2)} or ill-formed +\end{codeblock} +\end{example} + +\rSec2[diff.cpp20.stmt]{\ref{stmt}: statements} -\ref{dcl.type} [see also \ref{basic.link}] -\change const objects must be initialized in \Cpp but can be left uninitialized in C +\diffref{stmt.ranged} +\change +The lifetime of temporary objects in the \grammarterm{for-range-initializer} +is extended until the end of the loop\iref{class.temporary}. \rationale -A const object cannot be assigned to so it must be initialized -to hold a useful value. +Improve usability of the range-based \keyword{for} statement. \effect -Deletion of semantically well-defined feature. -\difficulty -Semantic transformation. -\howwide -Seldom. +Destructors of some temporary objects are invoked later. +\begin{example} +\begin{codeblock} +void f() { + std::vector v = { 42, 17, 13 }; + std::mutex m; -\ref{dcl.type} -\change Banning implicit int + for (int x : + static_cast(std::lock_guard(m)), v) { // lock released in \CppXX + std::lock_guard guard(m); // OK in \CppXX, now deadlocks + } +} +\end{codeblock} +\end{example} -In \Cpp a -\grammarterm{decl-specifier-seq} -must contain a -\grammarterm{type-specifier}{}, unless -it is followed by a declarator for a constructor, a destructor, or a -conversion function. -In the following example, the -left-hand column presents valid C; -the right-hand column presents -equivalent \Cpp : +\rSec2[diff.cpp20.dcl]{\ref{dcl}: declarations} +\diffref{dcl.init.string} +\change +UTF-8 string literals may initialize arrays of \keyword{char} or +\tcode{\keyword{unsigned} \keyword{char}}. +\rationale +Compatibility with previously written code that conformed to previous versions of this document. +\effect +Arrays of \keyword{char} or \tcode{\keyword{unsigned} \keyword{char}} +may now be initialized with a UTF-8 string literal. +This can affect initialization that includes arrays +that are directly initialized within class types, typically aggregates. +\begin{example} \begin{codeblock} -void f(const parm); void f(const int parm); -const n = 3; const int n = 3; -main() int main() - /* ... */ /* ... */ +struct A { + char8_t s[10]; +}; +struct B { + char s[10]; +}; + +void f(A); +void f(B); + +int main() { + f({u8""}); // ambiguous +} \end{codeblock} +\end{example} + +\rSec2[diff.cpp20.temp]{\ref{temp}: templates} +\diffref{temp.deduct.type} +\change +Deducing template arguments from exception specifications. \rationale -In \Cpp, implicit int creates several opportunities for -ambiguity between expressions involving function-like -casts and declarations. -Explicit declaration is increasingly considered -to be proper style. -Liaison with WG14 (C) indicated support for (at least) -deprecating implicit int in the next revision of C. +Facilitate generic handling of throwing and non-throwing functions. \effect -Deletion of semantically well-defined feature. -\difficulty -Syntactic transformation. -Could be automated. -\howwide -Common. +Valid ISO \CppXX{} code may be ill-formed in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +template struct A { }; +template void f(void (*)(A) noexcept(B)); +void g(A) noexcept; +void h() { + f(g); // ill-formed; previously well-formed +} +\end{codeblock} +\end{example} -\ref{dcl.spec.auto} -\change -The keyword \tcode{auto} cannot be used as a storage class specifier. +\rSec2[diff.cpp20.library]{\ref{library}: library introduction} +\diffref{headers} +\change +New headers. +\rationale +New functionality. +\effect +The following \Cpp{} headers are new: +\libheaderref{expected}, +\libheaderrefx{flat_map}{flat.map.syn}, +\libheaderrefx{flat_set}{flat.set.syn}, +\libheaderref{generator}, +\libheaderref{mdspan}, +\libheaderref{print}, +\libheaderref{spanstream}, +\libheaderref{stacktrace}, +\libheaderref{stdatomic.h}, and +\libheaderref{stdfloat}. +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} + +\diffref{cmp.concept,concept.equalitycomparable,concept.totallyordered} +\change +Replace \tcode{common_reference_with} in \tcode{three_way_comparable_with}, +\tcode{equality_comparable_with}, and \tcode{totally_ordered_with} +with an exposition-only concept. +\rationale +Allow uncopyable, but movable, types to model these concepts. +\effect +Valid \CppXX{} code relying on subsumption +with \tcode{common_reference_with} +may fail to compile in this revision of \Cpp{}. +\begin{example} \begin{codeblock} -void f() { - auto int x; // valid C, invalid C++ +template + requires @\libconcept{equality_comparable_with}@ +bool attempted_equals(const T&, const U& u); // previously selected overload + +template + requires @\libconcept{common_reference_with}@&, const remove_reference_t&> +bool attempted_equals(const T& t, const U& u); // ambiguous overload; previously + // rejected by partial ordering +bool test(shared_ptr p) { + return attempted_equals(p, nullptr); // ill-formed; previously well-formed } \end{codeblock} +\end{example} -\rationale Allowing the use of \tcode{auto} to deduce the type -of a variable from its initializer results in undesired interpretations of -\tcode{auto} as a storage class specifier in certain contexts. -\effect Deletion of semantically well-defined feature. -\difficulty Syntactic transformation. -\howwide Rare. +\rSec2[diff.cpp20.memory]{\ref{mem}: memory management library} + +\diffref{allocator.traits.general} +\change +Forbid partial and explicit program-defined specializations +of \tcode{allocator_traits}. +\rationale +Allow addition of \tcode{allocate_at_least} to \tcode{allocator_traits}, +and potentially other members in the future. +\effect +Valid \CppXX{} code +that partially or explicitly specializes \tcode{allocator_traits} +is ill-formed with no diagnostic required in this revision of \Cpp{}. -\ref{dcl.enum} -\change \Cpp objects of enumeration type can only be assigned values of the same enumeration type. -In C, objects of enumeration type can be assigned values of any integral type +\rSec2[diff.cpp20.utilities]{\ref{utilities}: general utilities library} -Example: +\diffref{format} +\change +Signature changes: \tcode{format}, \tcode{format_to}, \tcode{vformat_to}, +\tcode{format_to_n}, \tcode{formatted_size}. +Removal of \tcode{format_args_t}. +\rationale +Improve safety via compile-time format string checks, +avoid unnecessary template instantiations. +\effect +Valid \CppXX{} code that +contained errors in format strings or +relied on previous format string signatures or +\tcode{format_args_t} may become ill-formed. +\begin{example} \begin{codeblock} -enum color { red, blue, green }; -enum color c = 1; // valid C, invalid \Cpp +auto s = std::format("{:d}", "I am not a number"); // ill-formed, + // previously threw \tcode{format_error} \end{codeblock} +\end{example} +\diffref{format} +\change +Signature changes: \tcode{format}, \tcode{format_to}, \tcode{format_to_n}, +\tcode{formatted_size}. \rationale -The type-safe nature of \Cpp. +Enable formatting of views +that do not support iteration when const-qualified and +that are not copyable. \effect -Deletion of semantically well-defined feature. -\difficulty -Syntactic transformation. -(The type error produced by the assignment can be automatically -corrected by applying an explicit cast.) -\howwide -Common. - -\ref{dcl.enum} -\change In \Cpp, the type of an enumerator is its enumeration. In C, the type of an enumerator is \tcode{int}. +Valid \CppXX{} code that passes bit-fields to formatting functions +may become ill-formed. +\begin{example} +\begin{codeblock} +struct tiny { + int bit: 1; +}; -Example: +auto t = tiny(); +std::format("{}", t.bit); // ill-formed, previously returned \tcode{"0"} +\end{codeblock} +\end{example} +\diffref{format.string.std} +\change +Restrict types of formatting arguments +used as \fmtgrammarterm{width} or \fmtgrammarterm{precision} in +a \fmtgrammarterm{std-format-spec}. +\rationale +Disallow types that do not have useful or portable semantics as +a formatting width or precision. +\effect +Valid \CppXX{} code that passes a boolean or character type as +\fmtgrammarterm{arg-id} becomes invalid. +\begin{example} \begin{codeblock} -enum e { A }; -sizeof(A) == sizeof(int) // in C -sizeof(A) == sizeof(e) // in \Cpp -/* @\textit{\textrm{and \tcode{sizeof(int)} is not necessarily equal to \tcode{sizeof(e)}}}@ */ +std::format("{:*^{}}", "", true); // ill-formed, previously returned \tcode{"*"} +std::format("{:*^{}}", "", '1'); // ill-formed, previously returned an + // implementation-defined number of \tcode{'*'} characters \end{codeblock} +\end{example} +\diffref{format.formatter.spec} +\change +Removed the \tcode{formatter} specialization: +\begin{codeblock} +template struct formatter; +\end{codeblock} \rationale -In \Cpp, an enumeration is a distinct type. +The specialization is inconsistent with the design of \tcode{formatter}, +which is intended to be instantiated only with cv-unqualified object types. \effect -Change to semantics of well-defined feature. -\difficulty -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. - -\rSec2[diff.decl]{Clause \ref{dcl.decl}: declarators} - -\ref{dcl.fct} -\change In \Cpp, a function declared with an empty parameter list takes no arguments. -In C, an empty parameter list means that the number and type of the function arguments are unknown. +Valid \CppXX{} code that instantiated the removed specialization +can become ill-formed. -Example: +\rSec2[diff.cpp20.strings]{\ref{strings}: strings library} +\diffref{string.classes} +\change +Additional rvalue overload for the \tcode{substr} member function and +the corresponding constructor. +\rationale +Improve efficiency of operations on rvalues. +\effect +Valid \CppXX{} code that created a substring +by calling \tcode{substr} (or the corresponding constructor) +on an xvalue expression with type \tcode{S} +that is a specialization of \tcode{basic_string} +may change meaning in this revision of \Cpp{}. +\begin{example} \begin{codeblock} -int f(); // means \tcode{int f(void)} in \Cpp - // \tcode{int f(} unknown \tcode{)} in C +std::string s1 = "some long string that forces allocation", s2 = s1; +std::move(s1).substr(10, 5); +assert(s1 == s2); // unspecified, previously guaranteed to be \tcode{true} +std::string s3(std::move(s2), 10, 5); +assert(s1 == s2); // unspecified, previously guaranteed to be \tcode{true} \end{codeblock} +\end{example} +\rSec2[diff.cpp20.containers]{\ref{containers}: containers library} + +\diffref{associative.reqmts,unord.req} +\change +Heterogeneous \tcode{extract} and \tcode{erase} overloads +for associative containers. \rationale -This is to avoid erroneous function calls (i.e., function calls -with the wrong number or type of arguments). +Improve efficiency of erasing elements from associative containers. \effect -Change to semantics of well-defined feature. -This feature was marked as ``obsolescent'' in C. -\difficulty -Syntactic transformation. -The function declarations using C incomplete declaration style must -be completed to become full prototype declarations. -A program may need to be updated further if different calls to the -same (non-prototype) function have different numbers of arguments or -if the type of corresponding arguments differed. -\howwide -Common. +Valid \CppXX{} code may fail to compile in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +struct B { + auto operator<=>(const B&) const = default; +}; -\ref{dcl.fct} [see \ref{expr.sizeof}] -\change In \Cpp, types may not be defined in return or parameter types. In C, these type definitions are allowed +struct D : private B { + void f(std::set>& s) { + s.erase(*this); // ill-formed; previously well-formed + } +}; +\end{codeblock} +\end{example} -Example: +\rSec2[diff.cpp20.thread]{\ref{thread}: concurrency support library} +\diffref{thread.barrier} +\change +In this revision of \Cpp{}, +it is implementation-defined whether a barrier's phase completion step runs +if no thread calls \tcode{wait}. +Previously the phase completion step was guaranteed to run on the last thread that calls \tcode{arrive} or \tcode{arrive_and_drop} during the phase. +In this revision of \Cpp{}, +it can run on any of the threads that arrived or waited at the barrier +during the phase. +\rationale +Correct contradictory wording and +improve implementation flexibility for performance. +\effect +Valid \CppXX{} code using a barrier might have +different semantics in this revision of \Cpp{} +if it depends on a completion function's side effects occurring exactly once, +on a specific thread running the phase completion step, or +on a completion function's side effects occurring +without \tcode{wait} having been called. +\begin{example} \begin{codeblock} -void f( struct S { int a; } arg ) {} // valid C, invalid \Cpp -enum E { A, B, C } f() {} // valid C, invalid \Cpp +auto b0 = std::barrier(1); +b0.arrive(); +b0.arrive(); // implementation-defined; previously well-defined + +int data = 0; +auto b1 = std::barrier(1, [&] { data++; }); +b1.arrive(); +assert(data == 1); // implementation-defined; previously well-defined +b1.arrive(); // implementation-defined; previously well-defined \end{codeblock} +\end{example} -\rationale -When comparing types in different compilation units, \Cpp relies -on name equivalence when C relies on structural equivalence. -Regarding parameter types: since the type defined in an parameter list -would be in the scope of the function, the only legal calls in \Cpp -would be from within the function itself. -\effect -Deletion of semantically well-defined feature. -\difficulty -Semantic transformation. -The type definitions must be moved to file scope, or in header files. -\howwide -Seldom. -This style of type definitions is seen as poor coding style. +\rSec1[diff.cpp17]{\Cpp{} and ISO \CppXVII{}} + +\rSec2[diff.cpp17.general]{General} + +\pnum +\indextext{summary!compatibility with ISO \CppXVII{}}% +Subclause \ref{diff.cpp17} lists the differences between \Cpp{} and +ISO \CppXVII{}, +in addition to those listed above, +by the chapters of this document. + +\rSec2[diff.cpp17.lex]{\ref{lex}: lexical conventions} -\ref{dcl.fct.def} -\change In \Cpp, the syntax for function definition excludes the ``old-style'' C function. -In C, ``old-style'' syntax is allowed, but deprecated as ``obsolescent.'' +\diffref{lex.pptoken,module.unit,module.import,cpp.pre,cpp.module,cpp.import} +\change +New identifiers with special meaning. \rationale -Prototypes are essential to type safety. +Required for new features. \effect -Deletion of semantically well-defined feature. -\difficulty -Syntactic transformation. -\howwide -Common in old programs, but already known to be obsolescent. - -\ref{dcl.init.string} -\change In \Cpp, when initializing an array of character with a string, the number of -characters in the string (including the terminating \tcode{'\textbackslash 0'}) must not exceed the -number of elements in the array. In C, an array can be initialized with a string even if -the array is not large enough to contain the string-terminating \tcode{'\textbackslash 0'} +Logical lines beginning with +\tcode{module} or \tcode{import} may +be interpreted differently +in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +class module {}; +module m1; // was variable declaration; now \grammarterm{module-declaration} +module *m2; // variable declaration -Example: +class import {}; +import j1; // was variable declaration; now \grammarterm{module-import-declaration} +::import j2; // variable declaration +\end{codeblock} +\end{example} +\diffref{lex.header} +\change +\grammarterm{header-name} tokens are formed in more contexts. +\rationale +Required for new features. +\effect +When the identifier \tcode{import} +is followed by a \tcode{<} character, +a \grammarterm{header-name} token may be formed. +\begin{example} \begin{codeblock} -char array[4] = "abcd"; // valid C, invalid \Cpp +template class import {}; +import f(); // ill-formed; previously well-formed +::import g(); // OK \end{codeblock} +\end{example} + +\diffref{lex.key} +\change +New keywords. \rationale -When these non-terminated arrays are manipulated by standard -string routines, there is potential for major catastrophe. +Required for new features. +\begin{itemize} +\item +\indextext{UTF-8}% +The \keyword{char8_t} keyword is added to differentiate +the types of ordinary and UTF-8 literals\iref{lex.string}. +\item +The \tcode{concept} keyword is +added to enable the definition of concepts\iref{temp.concept}. +\item +The \keyword{consteval} keyword is added to +declare immediate functions\iref{dcl.constexpr}. +\item +The \keyword{constinit} keyword is added to +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}. +\item +The \tcode{requires} keyword is added +to introduce constraints through a \grammarterm{requires-clause}\iref{temp.pre} +or a \grammarterm{requires-expression}\iref{expr.prim.req}. +\end{itemize} +\effectafteritemize +Valid \CppXVII{} code using +\keyword{char8_t}, +\tcode{concept}, +\keyword{consteval}, +\keyword{constinit}, +\keyword{co_await}, \keyword{co_yield}, \keyword{co_return}, +or \tcode{requires} +as an identifier is not valid in this revision of \Cpp{}. + +\diffref{lex.operators} +\change +New operator \tcode{<=>}. +\rationale +Necessary for new functionality. \effect -Deletion of semantically well-defined feature. -\difficulty -Semantic transformation. -The arrays must be declared one element bigger to contain the -string terminating \tcode{'\textbackslash 0'}. -\howwide -Seldom. -This style of array initialization is seen as poor coding style. +Valid \CppXVII{} code that contains a \tcode{<=} token +immediately followed by a \tcode{>} token +may be ill-formed or have different semantics in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +namespace N { + struct X {}; + bool operator<=(X, X); + template struct Y {}; + Y y; // ill-formed; previously well-formed +} +\end{codeblock} +\end{example} + +\diffref{lex.literal} +\indextext{UTF-8}% +\change +Type of UTF-8 string and character literals. +\rationale +Required for new features. +The changed types enable function overloading, template specialization, and +type deduction to distinguish ordinary and UTF-8 string and character literals. +\effect +Valid \CppXVII{} code that depends on +UTF-8 string literals having type ``array of \tcode{const char}'' and +UTF-8 character literals having type ``\tcode{char}'' +is not valid in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +const auto *u8s = u8"text"; // \tcode{u8s} previously deduced as \tcode{const char*}; now deduced as \tcode{const char8_t*} +const char *ps = u8s; // ill-formed; previously well-formed -\rSec2[diff.class]{Clause \ref{class}: classes} +auto u8c = u8'c'; // \tcode{u8c} previously deduced as \tcode{char}; now deduced as \keyword{char8_t} +char *pc = &u8c; // ill-formed; previously well-formed -\ref{class.name} [see also \ref{dcl.typedef}] -\change In \Cpp, a class declaration introduces the class name into the scope where it is -declared and hides any object, function or other declaration of that name in an enclosing -scope. In C, an inner scope declaration of a struct tag name never hides the name of an -object or function in an outer scope +std::string s = u8"text"; // ill-formed; previously well-formed + +void f(const char *s); +f(u8"text"); // ill-formed; previously well-formed -Example: +template struct ct; +template<> struct ct { + using type = char; +}; +ct::type x; // ill-formed; previously well-formed. +\end{codeblock} +\end{example} +\rSec2[diff.cpp17.basic]{\ref{basic}: basics} + +\diffref{basic.life} +\change +A pseudo-destructor call ends the lifetime of +the object to which it is applied. +\rationale +Increase consistency of the language model. +\effect +Valid ISO \CppXVII{} code may be ill-formed or +have undefined behavior in this revision of \Cpp{}. +\begin{example} \begin{codeblock} -int x[99]; -void f() { - struct x { int a; }; - sizeof(x); /* @\textit{\textrm{size of the array in C}}@ */ - /* @\textit{\textrm{size of the struct in \Cpp}}@ */ +int f() { + int a = 123; + using T = int; + a.~T(); + return a; // undefined behavior; previously returned 123 } \end{codeblock} +\end{example} + +\diffref{intro.races} +\change +Except for the initial release operation, +a release sequence consists solely of atomic read-modify-write operations. \rationale -This is one of the few incompatibilities between C and \Cpp that -can be attributed to the new \Cpp name space definition where a -name can be declared as a type and as a non-type in a single scope -causing the non-type name to hide the type name and requiring that -the keywords \tcode{class}, \tcode{struct}, \tcode{union} or \tcode{enum} be used to refer to the type name. -This new name space definition provides important notational -conveniences to \Cpp programmers and helps making the use of the -user-defined types as similar as possible to the use of fundamental -types. -The advantages of the new name space definition were judged to -outweigh by far the incompatibility with C described above. +Removal of rarely used and confusing feature. \effect -Change to semantics of well-defined feature. -\difficulty -Semantic transformation. -If the hidden name that needs to be accessed is at global scope, -the \tcode{::} \Cpp operator can be used. -If the hidden name is at block scope, either the type or the struct -tag has to be renamed. -\howwide -Seldom. +If a \tcode{memory_order_release} atomic store is followed +by a \tcode{memory_order_relaxed} store to the same variable by the same thread, +then reading the latter value with a \tcode{memory_order_acquire} load +no longer provides any ``happens before'' guarantees, +even in the absence of intervening stores by another thread. -\ref{class.bit} +\rSec2[diff.cpp17.expr]{\ref{expr}: expressions} + +\diffref{expr.prim.lambda.capture} \change -\indextext{bit-field!implementation-defined sign~of}% -Bit-fields of type plain \tcode{int} are signed. +Implicit lambda capture may capture additional entities. \rationale -Leaving the choice of signedness to implementations could lead to -inconsistent definitions of template specializations. For consistency, -the implementation freedom was eliminated for non-dependent types, -too. +Rule simplification, necessary to resolve interactions with constexpr if. \effect -The choise is implementation-defined in C, but not so in C++. -\difficulty -Syntactic transformation. -\howwide -Seldom. - -\ref{class.nest} -\change In \Cpp, the name of a nested class is local to its enclosing class. In C -the name of the nested class belongs to the same scope as the name of the outermost enclosing class. +Lambdas with a \grammarterm{capture-default} +may capture local entities +that were not captured in \CppXVII{} +if those entities are only referenced in contexts +that do not result in an odr-use. -Example: +\rSec2[diff.cpp17.dcl.dcl]{\ref{dcl}: declarations} +\diffref{dcl.typedef} +\change +Unnamed classes with a typedef name for linkage purposes +can contain only C-compatible constructs. +\rationale +Necessary for implementability. +\effect +Valid \CppXVII{} code may be ill-formed in this revision of \Cpp{}. +\begin{example} \begin{codeblock} -struct X { - struct Y { /* ... */ } y; -}; -struct Y yy; // valid C, invalid \Cpp +typedef struct { + void f() {} // ill-formed; previously well-formed +} S; \end{codeblock} +\end{example} + +\diffref{dcl.fct.default} +\change +A function cannot have different default arguments +in different translation units. \rationale -\Cpp classes have member functions which require that classes -establish scopes. -The C rule would leave classes as an incomplete scope mechanism -which would prevent \Cpp programmers from maintaining locality -within a class. -A coherent set of scope rules for \Cpp based on the C rule would -be very complicated and \Cpp programmers would be unable to predict -reliably the meanings of nontrivial examples involving nested or -local functions. +Required for modules support. \effect -Change of semantics of well-defined feature. -\difficulty -Semantic transformation. -To make the struct type name visible in the scope of the enclosing -struct, the struct tag could be declared in the scope of the -enclosing struct, before the enclosing struct is defined. -Example: +Valid \CppXVII{} code may be ill-formed in this revision of \Cpp{}, +with no diagnostic required. +\begin{example} +\begin{codeblock} +// Translation unit 1 +int f(int a = 42); +int g() { return f(); } + +// Translation unit 2 +int f(int a = 76) { return a; } // ill-formed, no diagnostic required; previously well-formed +int g(); +int main() { return g(); } // used to return 42 +\end{codeblock} +\end{example} +\diffref{dcl.init.aggr} +\change +A class that has user-declared constructors is never an aggregate. +\rationale +Remove potentially error-prone aggregate initialization +which may apply notwithstanding the declared constructors of a class. +\effect +Valid \CppXVII{} code that aggregate-initializes +a type with a user-declared constructor +may be ill-formed or have different semantics +in this revision of \Cpp{}. +\begin{example} \begin{codeblock} -struct Y; // \tcode{struct Y} and \tcode{struct X} are at the same scope +struct A { // not an aggregate; previously an aggregate + A() = delete; +}; + +struct B { // not an aggregate; previously an aggregate + B() = default; + int i = 0; +}; + +struct C { // not an aggregate; previously an aggregate + C(C&&) = default; + int a, b; +}; + +A a{}; // ill-formed; previously well-formed +B b = {1}; // ill-formed; previously well-formed +auto* c = new C{2, 3}; // ill-formed; previously well-formed + +struct Y; + struct X { - struct Y { /* ... */ } y; + operator Y(); }; -\end{codeblock} -All the definitions of C struct types enclosed in other struct -definitions and accessed outside the scope of the enclosing -struct could be exported to the scope of the enclosing struct. -Note: this is a consequence of the difference in scope rules, -which is documented in \ref{basic.scope}. -\howwide -Seldom. +struct Y { // not an aggregate; previously an aggregate + Y(const Y&) = default; + X x; +}; -\ref{class.nested.type} -\change In \Cpp, a typedef name may not be redeclared in a class definition after being used in that definition +Y y{X{}}; // copy constructor call; previously aggregate-initialization +\end{codeblock} +\end{example} + +\diffref{dcl.init.list} +\change +Boolean conversion from a pointer or pointer-to-member type +is now a narrowing conversion. +\rationale +Catches bugs. +\effect +Valid \CppXVII{} code may fail to compile +in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +bool y[] = { "bc" }; // ill-formed; previously well-formed +\end{codeblock} +\end{example} -Example: +\rSec2[diff.cpp17.class]{\ref{class}: classes} +\diffref{class.ctor,class.conv.fct} +\change +The class name can no longer be used parenthesized +immediately after an \keyword{explicit} \grammarterm{decl-specifier} +in a constructor declaration. +The \grammarterm{conversion-function-id} can no longer be used parenthesized +immediately after an \keyword{explicit} \grammarterm{decl-specifier} +in a conversion function declaration. +\rationale +Necessary for new functionality. +\effect +Valid \CppXVII{} code may fail to compile +in this revision of \Cpp{}. +\begin{example} \begin{codeblock} -typedef int I; struct S { - I i; - int I; // valid C, invalid \Cpp + explicit (S)(const S&); // ill-formed; previously well-formed + explicit (operator int)(); // ill-formed; previously well-formed + explicit(true) (S)(int); // OK }; \end{codeblock} +\end{example} + +\diffref{class.ctor,class.dtor} +\change +A \grammarterm{simple-template-id} +is no longer valid as the \grammarterm{declarator-id} of a constructor or destructor. \rationale -When classes become complicated, allowing such a redefinition -after the type has been used can create confusion for \Cpp -programmers as to what the meaning of 'I' really is. +Remove potentially error-prone option for redundancy. \effect -Deletion of semantically well-defined feature. -\difficulty -Semantic transformation. -Either the type or the struct member has to be renamed. -\howwide -Seldom. - -\rSec2[diff.special]{Clause \ref{special}: special member functions} - -\ref{class.copy} -\change Copying volatile objects - -The implicitly-declared copy constructor and -implicitly-declared copy assignment operator -cannot make a copy of a volatile lvalue. -For example, the following is valid in ISO C: - +Valid \CppXVII{} code may fail to compile +in this revision of \Cpp{}. +\begin{example} \begin{codeblock} -struct X { int i; }; -volatile struct X x1 = {0}; -struct X x2(x1); // invalid \Cpp -struct X x3; -x3 = x1; // also invalid \Cpp +template +struct A { + A(); // error: \grammarterm{simple-template-id} not allowed for constructor + A(int); // OK, injected-class-name used + ~A(); // error: \grammarterm{simple-template-id} not allowed for destructor +}; \end{codeblock} +\end{example} +\diffref{class.copy.elision} +\change +A function returning an implicitly movable entity +may invoke a constructor taking an rvalue reference to a type +different from that of the returned expression. +Function and catch-clause parameters can be thrown using move constructors. \rationale -Several alternatives were debated at length. -Changing the parameter to -\tcode{volatile} -\tcode{const} -\tcode{X\&} -would greatly complicate the generation of -efficient code for class objects. -Discussion of -providing two alternative signatures for these -implicitly-defined operations raised -unanswered concerns about creating -ambiguities and complicating -the rules that specify the formation of -these operators according to the bases and -members. +Side effect of making it easier to write +more efficient code that takes advantage of moves. \effect -Deletion of semantically well-defined feature. -\difficulty -Semantic transformation. -If volatile semantics are required for the copy, -a user-declared constructor or assignment must -be provided. \enternote This user-declared -constructor may be explicitly defaulted. \exitnote -If non-volatile semantics are required, -an explicit -\tcode{const_cast} -can be used. -\howwide -Seldom. +Valid \CppXVII{} code may fail to compile or have different semantics +in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +struct base { + base(); + base(base const &); +private: + base(base &&); +}; -\rSec2[diff.cpp]{Clause \ref{cpp}: preprocessing directives} +struct derived : base {}; -\ref{cpp.predefined} -\change Whether \mname{STDC} is defined and if so, what its value is, are -implementation-defined -\rationale -\Cpp is not identical to ISO C\@. -Mandating that \mname{STDC} -be defined would require that translators make an incorrect claim. -Each implementation must choose the behavior that will be most -useful to its marketplace. -\effect -Change to semantics of well-defined feature. -\difficulty -Semantic transformation. -\howwide -Programs and headers that reference \mname{STDC} are -quite common. +base f(base b) { + throw b; // error: \tcode{base(base \&\&)} is private + derived d; + return d; // error: \tcode{base(base \&\&)} is private +} -\rSec1[diff.cpp03]{\Cpp and ISO \CppIII} +struct S { + S(const char *s) : m(s) { } + S(const S&) = default; + S(S&& other) : m(other.m) { other.m = nullptr; } + const char * m; +}; -\pnum -\indextext{summary!compatibility~with ISO \CppIII}% -This subclause lists the differences between \Cpp and -ISO \CppIII (ISO/IEC 14882:2003, \doccite{Programming Languages --- \Cpp}), -by the chapters of this document. +S consume(S&& s) { return s; } -\rSec2[diff.cpp03.lex]{Clause \ref{lex}: lexical conventions} +void g() { + S s("text"); + consume(static_cast(s)); + char c = *s.m; // undefined behavior; previously ok +} +\end{codeblock} +\end{example} -\ref{lex.pptoken} -\change New kinds of string literals -\rationale Required for new features. -\effect -Valid \CppIII code may fail to compile or produce different results in -this International Standard. Specifically, macros named \tcode{R}, \tcode{u8}, -\tcode{u8R}, \tcode{u}, \tcode{uR}, \tcode{U}, \tcode{UR}, or \tcode{LR} will -not be expanded when adjacent to a string literal but will be interpreted as -part of the string literal. For example, +\rSec2[diff.cpp17.over]{\ref{over}: overloading} +\diffref{over.match.oper} +\change +Equality and inequality expressions can now find +reversed and rewritten candidates. +\rationale +Improve consistency of equality with three-way comparison +and make it easier to write the full complement of equality operations. +\effect +For certain pairs of types where one is convertible to the other, +equality or inequality expressions between an object of one type +and an object of the other type invoke a different operator. +Also, for certain types, equality or inequality expressions +between two objects of that type become ambiguous. +\begin{example} \begin{codeblock} -#define u8 "abc" -const char* s = u8"def"; // Previously \tcode{"abcdef"}, now \tcode{"def"} -\end{codeblock} +struct A { + operator int() const; +}; -\ref{lex.pptoken} -\change User-defined literal string support -\rationale Required for new features. -\effect -Valid \CppIII code may fail to compile or produce different results in -this International Standard, as the following example illustrates. +bool operator==(A, int); // \#1 +// \#2 is built-in candidate: \tcode{bool operator==(int, int);} +// \#3 is built-in candidate: \tcode{bool operator!=(int, int);} -\begin{codeblock} -#define _x "there" -"hello"_x // \#1 +int check(A x, A y) { + return (x == y) + // ill-formed; previously well-formed + (10 == x) + // calls \#1, previously selected \#2 + (10 != x); // calls \#1, previously selected \#3 +} \end{codeblock} +\end{example} -Previously, \#1 would have consisted of two separate preprocessing tokens and -the macro \tcode{_x} would have been expanded. In this International Standard, -\#1 consists of a single preprocessing tokens, so the macro is not expanded. - -\ref{lex.key} -\change New keywords -\rationale Required for new features. +\diffref{over.match.oper} +\change +Overload resolution may change for equality operators\iref{expr.eq}. +\rationale +Support calling \tcode{operator==} with reversed order of arguments. \effect -Added to Table~\ref{tab:keywords}, the following identifiers are new keywords: -\tcode{alignas}, -\tcode{alignof}, -\tcode{char16_t}, -\tcode{char32_t}, -\tcode{constexpr}, -\tcode{decltype}, -\tcode{noexcept}, -\tcode{nullptr}, -\tcode{static_assert}, -and -\tcode{thread_local}. -Valid \CppIII code using these identifiers is invalid in this International -Standard. +Valid \CppXVII{} code that uses equality operators with conversion functions +may be ill-formed or have different semantics in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +struct A { + operator int() const { return 10; } +}; -\ref{lex.icon} -\change Type of integer literals -\rationale C99 compatibility. -\effect -Certain integer literals larger than can be represented by \tcode{long} could -change from an unsigned integer type to \tcode{signed long long}. +bool operator==(A, int); // \#1 +// \#2 is built-in candidate: \tcode{bool operator==(int, int);} +bool b = 10 == A(); // calls \#1 with reversed order of arguments; previously selected \#2 -\rSec2[diff.cpp03.conv]{Clause~\ref{conv}: standard conversions} +struct B { + bool operator==(const B&); // member function with no cv-qualifier +}; +B b1; +bool eq = (b1 == b1); // ambiguous; previously well-formed +\end{codeblock} +\end{example} -\ref{conv.ptr} -\change Only literals are integer null pointer constants -\rationale Removing surprising interactions with templates and constant -expressions -\effect Valid \CppIII code may fail to compile or produce different results in -this International Standard, as the following example illustrates: +\rSec2[diff.cpp17.temp]{\ref{temp}: templates} +\diffref{temp.names} +\change +An \grammarterm{unqualified-id} +that is followed by a \tcode{<} +and for which name lookup +finds nothing or finds a function +will be treated as a \grammarterm{template-name} +in order to potentially cause argument-dependent lookup to be performed. +\rationale +It was problematic to call a function template +with an explicit template argument list +via argument-dependent lookup +because of the need to have a template with the same name +visible via normal lookup. +\effect +Previously valid code that uses a function name +as the left operand of a \tcode{<} operator +would become ill-formed. +\begin{example} \begin{codeblock} -void f(void *); // \#1 -void f(...); // \#2 -template void g() { - f(0*N); // calls \#2; used to call \#1 +struct A {}; +bool operator<(void (*fp)(), A); +void f() {} +int main() { + A a; + f < a; // ill-formed; previously well-formed + (f) < a; // still well-formed } \end{codeblock} +\end{example} -\rSec2[diff.cpp03.expr]{Clause \ref{expr}: expressions} +\rSec2[diff.cpp17.except]{\ref{except}: exception handling} -\ref{expr.mul} -\change Specify rounding for results of integer \tcode{/} and \tcode{\%} -\rationale Increase portability, C99 compatibility. -\effect -Valid \CppIII code that uses integer division rounds the result toward 0 or -toward negative infinity, whereas this International Standard always rounds -the result toward 0. +\diffref{except.spec} +\change +Remove \tcode{throw()} exception specification. +\rationale +Removal of obsolete feature that has been replaced by \keyword{noexcept}. +\effect +A valid \CppXVII{} function declaration, member function declaration, function +pointer declaration, or function reference declaration that uses \tcode{throw()} +for its exception specification will be rejected as ill-formed in this +revision of \Cpp{}. It should simply be replaced with \keyword{noexcept} for no +change of meaning since \CppXVII{}. +\begin{note} +There is no way to write a function declaration +that is non-throwing in this revision of \Cpp{} +and is also non-throwing in \CppIII{} +except by using the preprocessor to generate +a different token sequence in each case. +\end{note} + +\rSec2[diff.cpp17.library]{\ref{library}: library introduction} + +\diffref{headers} +\change +New headers. +\rationale +New functionality. +\effect +The following \Cpp{} headers are new: +\libheaderref{barrier}, +\libheaderref{bit}, +\libheaderref{charconv}, +\libheaderref{compare}, +\libheaderref{concepts}, +\libheaderref{coroutine}, +\libheaderref{format}, +\libheaderref{latch}, +\libheaderref{numbers}, +\libheaderref{ranges}, +\libheaderref{semaphore}, +\libheaderrefx{source_location}{source.location.syn}, +\libheaderref{span}, +\libheaderrefx{stop_token}{thread.stoptoken.syn}, +\libheaderref{syncstream}, and +\libheaderrefx{version}{support.limits.general}. +Valid \CppXVII{} code that \tcode{\#include}{s} headers with these names may be +invalid in this revision of \Cpp{}. + +\diffref{headers} +\change +Remove vacuous \Cpp{} header files. +\rationale +The empty headers implied a false requirement to achieve C compatibility with the \Cpp{} headers. +\effect +A valid \CppXVII{} program that \tcode{\#include}{s} any of the following headers may fail to compile: +\libnoheader{ccomplex}, +\libnoheader{ciso646}, +\libnoheader{cstdalign}, +\libnoheader{cstdbool}, and +\libnoheader{ctgmath}. +To retain the same behavior: +\begin{itemize} +\item +a \tcode{\#include} of \libnoheader{ccomplex} can be replaced by +a \tcode{\#include} of \libheaderref{complex}, +\item +a \tcode{\#include} of \libnoheader{ctgmath} can be replaced by +a \tcode{\#include} of \libheaderref{cmath} and +a \tcode{\#include} of \libheader{complex}, +and +\item +a \tcode{\#include} of +\libnoheader{ciso646}, +\libnoheader{cstdalign}, or +\libnoheader{cstdbool} +can simply be removed. +\end{itemize} -\rSec2[diff.cpp03.dcl.dcl]{Clause \ref{dcl.dcl}: declarations} +\rSec2[diff.cpp17.containers]{\ref{containers}: containers library} -\ref{dcl.spec} -\change Remove \tcode{auto} as a storage class specifier -\rationale New feature. +\diffref{forward.list,list} +\change +Return types of \tcode{remove}, \tcode{remove_if}, and \tcode{unique} +changed from \keyword{void} to \tcode{container::size_type}. +\rationale +Improve efficiency and convenience of finding number of removed elements. \effect -Valid \CppIII code that uses the keyword \tcode{auto} as a storage class -specifier may be invalid in this International Standard. In this International -Standard, \tcode{auto} indicates that the type of a variable is to be deduced -from its initializer expression. +Code that depends on the return types might have different semantics in this revision of \Cpp{}. +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.cpp03.dcl.decl]{Clause \ref{dcl.decl}: declarators} +\rSec2[diff.cpp17.iterators]{\ref{iterators}: iterators library} -\ref{dcl.init.list} -\change Narrowing restrictions in aggregate initializers -\rationale Catches bugs. +\diffref{iterator.traits} +\change +The specialization of \tcode{iterator_traits} for \tcode{void*} and +for function pointer types no longer contains any nested typedefs. +\rationale +Corrects an issue misidentifying pointer types that are not incrementable +as iterator types. \effect -Valid \CppIII code may fail to compile in this International Standard. For -example, the following code is valid in \CppIII but invalid in this -International Standard because \tcode{double} to \tcode{int} is a narrowing -conversion: +A valid \CppXVII{} program that relies on the presence of the typedefs +may fail to compile, or have different behavior. -\begin{codeblock} -int x[] = { 2.0 }; -\end{codeblock} - -\rSec2[diff.cpp03.special]{Clause \ref{special}: special member functions} - -\ref{class.ctor}, \ref{class.dtor}, \ref{class.copy} -\change Implicitly-declared special member functions are defined as deleted -when the implicit definition would have been ill-formed. -\rationale Improves template argument deduction failure. -\effect -A valid \CppIII program that uses one of these special member functions in a -context where the definition is not required (e.g., in an expression that is -not potentially evaluated) becomes ill-formed. +\rSec2[diff.cpp17.alg.reqs]{\ref{algorithms}: algorithms library} -\ref{class.dtor} (destructors) -\change User-declared destructors have an implicit exception specification. -\rationale Clarification of destructor requirements. +\diffref{algorithms.requirements} +\change +The number and order of deducible template parameters for algorithm declarations +is now unspecified, instead of being as-declared. +\rationale +Increase implementor freedom and allow some function templates +to be implemented as function objects with templated call operators. \effect -Valid \CppIII code may execute differently in this International Standard. In -particular, destructors that throw exceptions will call \tcode{std::terminate()} -(without calling \tcode{std::unexpected()}) if their exception specification is -\tcode{noexcept} or \tcode{noexcept(true)}. For a throwing virtual destructor -of a derived class, \tcode{std::terminate()} can be avoided only if the base class -virtual destructor has an exception specification that is not \tcode{noexcept} -and not \tcode{noexcept(true)}. +A valid \CppXVII{} program that passes explicit template arguments to +algorithms not explicitly specified to allow such in this version of \Cpp{} +may fail to compile or have undefined behavior. -\rSec2[diff.cpp03.temp]{Clause \ref{temp}: templates} +\rSec2[diff.cpp17.input.output]{\ref{input.output}: input/output library} -\ref{temp.param} -\change Remove \tcode{export} -\rationale No implementation consensus. +\diffref{istream.extractors} +\change +Character array extraction only takes array types. +\rationale +Increase safety via preventing buffer overflow at compile time. \effect -A valid \CppIII declaration containing \tcode{export} is ill-formed in this -International Standard. +Valid \CppXVII{} code may fail to compile in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +auto p = new char[100]; +char q[100]; +std::cin >> std::setw(20) >> p; // ill-formed; previously well-formed +std::cin >> std::setw(20) >> q; // OK +\end{codeblock} +\end{example} -\ref{temp.arg} -\change Remove whitespace requirement for nested closing template right angle -brackets -\rationale Considered a persistent but minor annoyance. Template aliases -representing nonclass types would exacerbate whitespace issues. +\diffref{ostream.inserters.character} +\indextext{UTF-8}% +\change +Overload resolution for ostream inserters used with UTF-8 literals. +\rationale +Required for new features. \effect -Change to semantics of well-defined expression. A valid \CppIII expression -containing a right angle bracket (``\tcode{>}'') followed immediately by -another right angle bracket may now be treated as closing two templates. -For example, the following code is valid in \CppIII because ``\tcode{\shr}'' -is a right-shift operator, but invalid in this International Standard because -``\tcode{\shr}'' closes two templates. +Valid \CppXVII{} code that passes UTF-8 literals to +\tcode{basic_ostream::operator<<} or +\tcode{basic_ostream::operator<<} is now ill-formed. +\begin{example} +\begin{codeblock} +std::cout << u8"text"; // previously called \tcode{operator<<(const char*)} and printed a string; + // now ill-formed +std::cout << u8'X'; // previously called \tcode{operator<<(char)} and printed a character; + // now ill-formed +\end{codeblock} +\end{example} +\diffref{ostream.inserters.character} +\change +Overload resolution for ostream inserters +used with \keyword{wchar_t}, \keyword{char16_t}, or \keyword{char32_t} types. +\rationale +Removal of surprising behavior. +\effect +Valid \CppXVII{} code that passes +\keyword{wchar_t}, \keyword{char16_t}, or \keyword{char32_t} characters or strings +to \tcode{basic_ostream::operator<<} or +that passes \keyword{char16_t} or \keyword{char32_t} characters or strings +to \tcode{basic_ostream::operator<<} is now ill-formed. +\begin{example} \begin{codeblock} -template struct X { }; -template struct Y { }; -X< Y< 1 >> 2 > > x; +std::cout << u"text"; // previously formatted the string as a pointer value; + // now ill-formed +std::cout << u'X'; // previously formatted the character as an integer value; + // now ill-formed \end{codeblock} +\end{example} -\ref{temp.dep.candidate} -\change Allow dependent calls of functions with internal linkage -\rationale Overly constrained, simplify overload resolution rules. -\effect -A valid \CppIII program could get a different result than this -International Standard. - -\rSec2[diff.cpp03.library]{Clause \ref{library}: library introduction} - -\ref{library} -- \ref{\lastlibchapter} -\change New reserved identifiers -\rationale Required by new features. -\effect -Valid \CppIII code that uses any identifiers added to the \Cpp standard -library by this International Standard may fail to compile or produce different -results in This International Standard. A comprehensive list of identifiers used -by the \Cpp standard library can be found in the Index of Library Names in this -International Standard. - -\ref{headers} -\change New headers -\rationale New functionality. -\effect -The following \Cpp headers are new: -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{},\\ -\tcode{}, -and -\tcode{}. -In addition the following C compatibility headers are new: -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -\tcode{}, -and -\tcode{}. -Valid \CppIII code that \tcode{\#include}{s} headers with these names may be -invalid in this International Standard. +\diffref{fs.class.path} +\change +Return type of filesystem path format observer member functions. +\rationale +Required for new features. +\effect +Valid \CppXVII{} code that depends on the \tcode{u8string()} and +\tcode{generic_u8string()} member functions of \tcode{std::filesystem::path} +returning \tcode{std::string} is not valid in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +std::filesystem::path p; +std::string s1 = p.u8string(); // ill-formed; previously well-formed +std::string s2 = p.generic_u8string(); // ill-formed; previously well-formed +\end{codeblock} +\end{example} -\ref{swappable.requirements} -\effect Function \tcode{swap} moved to a different header -\rationale Remove dependency on \tcode{} for \tcode{swap}. -\effect Valid \CppIII code that has been compiled expecting swap to be in -\tcode{} may have to instead include \tcode{}. +\rSec2[diff.cpp17.depr]{\ref{depr}: compatibility features} -\ref{namespace.posix} -\change New reserved namespace -\rationale New functionality. +\nodiffref +\change +Remove \tcode{uncaught_exception}. +\rationale +The function did not have a clear specification when multiple exceptions were +active, and has been superseded by \tcode{uncaught_exceptions}. \effect -The global namespace \tcode{posix} is now reserved for standardization. Valid -\CppIII code that uses a top-level namespace \tcode{posix} may be invalid in -this International Standard. +A valid \CppXVII{} program that calls \tcode{std::uncaught_exception} may fail +to compile. It can be revised to use \tcode{std::uncaught_exceptions} instead, +for clear and portable semantics. -\ref{res.on.macro.definitions} -\change Additional restrictions on macro names -\rationale Avoid hard to diagnose or non-portable constructs. +\nodiffref +\change +Remove support for adaptable function API. +\rationale +The deprecated support relied on a limited convention that could not be +extended to support the general case or new language features. It has been +superseded by direct language support with \keyword{decltype}, and by the +\tcode{std::bind} and \tcode{std::not_fn} function templates. +\effect +A valid \CppXVII{} program that relies on the presence of \tcode{result_type}, +\tcode{argument_type}, \tcode{first_argument_type}, or +\tcode{second_argument_type} in a standard library class may fail to compile. A +valid \CppXVII{} program that calls \tcode{not1} or \tcode{not2}, or uses the +class templates \tcode{unary_negate} or \tcode{binary_negate}, may fail to +compile. + +\nodiffref +\change +Remove redundant members from \tcode{std::allocator}. +\rationale +\tcode{std::allocator} was overspecified, encouraging direct usage in user containers +rather than relying on \tcode{std::allocator_traits}, leading to poor containers. \effect -Names of attribute identifiers may not be used as macro names. Valid \Cpp -2003 code that defines \tcode{override}, \tcode{final}, -\tcode{carries_dependency}, or \tcode{noreturn} as macros is invalid in this -International Standard. - -\rSec2[diff.cpp03.language.support]{Clause \ref{language.support}: -language support library} +A valid \CppXVII{} program that directly makes use of the \tcode{pointer}, +\tcode{const_pointer}, \tcode{reference}, \tcode{const_reference}, +\tcode{rebind}, \tcode{address}, \tcode{construct}, \tcode{destroy}, or +\tcode{max_size} members of \tcode{std::allocator}, or that directly calls +\tcode{allocate} with an additional hint argument, may fail to compile. -\ref{new.delete.single} -\change Linking \tcode{new} and \tcode{delete} operators -\rationale The two throwing single-object signatures of \tcode{operator new} and -\tcode{operator delete} are now specified to form the base functionality for -the other operators. This clarifies that replacing just these two signatures -changes others, even if they are not explicitly changed. +\nodiffref +\change +Remove \tcode{raw_storage_iterator}. +\rationale +The iterator encouraged use of potentially-throwing algorithms, but did +not return the number of elements successfully constructed, +as would be necessary to destroy them. \effect -Valid \CppIII code that replaces global \tcode{new} or \tcode{delete} -operators may execute differently in this International Standard. For -example, the following program should write \tcode{"custom deallocation"} twice, -once for the single-object delete and once for the array delete. - -\begin{codeblock} -#include -#include -#include - -void* operator new(std::size_t size) throw(std::bad_alloc) { - return std::malloc(size); -} +A valid \CppXVII{} program that uses this iterator class may fail to compile. -void operator delete(void* ptr) throw() { - std::puts("custom deallocation"); - std::free(ptr); -} +\nodiffref +\change +Remove temporary buffers API. +\rationale +The temporary buffer facility was intended to provide an efficient optimization +for small memory requests, but there is little evidence this was achieved in +practice, while requiring the user to provide their own exception-safe wrappers +to guard use of the facility in many cases. +\effect +A valid \CppXVII{} program that calls \tcode{get_temporary_buffer} or +\tcode{return_temporary_buffer} may fail to compile. -int main() { - int* i = new int; - delete i; // single-object delete - int* a = new int[3]; - delete [] a; // array delete - return 0; -} -\end{codeblock} +\nodiffref +\change +Remove \tcode{shared_ptr::unique}. +\rationale +The result of a call to this member function is not reliable in the presence of +multiple threads and weak pointers. The member function \tcode{use_count} is +similarly unreliable, but has a clearer contract in such cases, and remains +available for well-defined use in single-threaded cases. +\effect +A valid \CppXVII{} program that calls \tcode{unique} on a \tcode{shared_ptr} +object may fail to compile. -\ref{new.delete.single} -\change \tcode{operator new} may throw exceptions other than -\tcode{std::bad_alloc} -\rationale Consistent application of \tcode{noexcept}. +\diffref{depr.meta.types} +\change +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 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. \effect -Valid \CppIII code that assumes that global \tcode{operator new} only -throws \tcode{std::bad_alloc} may execute differently in this International -Standard. +A valid \CppXVII{} program that relies on the \tcode{is_literal_type} or +\tcode{result_of} type traits, on the \tcode{is_literal_type_v} variable template, +or on the \tcode{result_of_t} alias template may fail to compile. -\rSec2[diff.cpp03.diagnostics]{Clause \ref{diagnostics}: diagnostics library} +\rSec1[diff.cpp14]{\Cpp{} and ISO \CppXIV{}} -\ref{errno} -\change Thread-local error numbers -\rationale Support for new thread facilities. -\effect Valid but implementation-specific \CppIII code that relies on -\tcode{errno} being the same across threads may change behavior in this -International Standard. +\rSec2[diff.cpp14.general]{General} + +\pnum +\indextext{summary!compatibility with ISO \CppXIV{}}% +Subclause \ref{diff.cpp14} lists the differences between \Cpp{} and +ISO \CppXIV{}, +in addition to those listed above, +by the chapters of this document. -\rSec2[diff.cpp03.utilities]{Clause \ref{utilities}: general utilities library} +\rSec2[diff.cpp14.lex]{\ref{lex}: lexical conventions} -\ref{util.dynamic.safety} -\change Minimal support for garbage-collected regions -\rationale Required by new feature. +\diffref{lex.phases} +\indextext{trigraph sequence}% +\change +Removal of trigraph support as a required feature. +\rationale +Prevents accidental uses of trigraphs in non-raw string literals and comments. \effect -Valid \CppIII code, compiled without traceable pointer support, -that interacts with newer \Cpp code using regions declared reachable may -have different runtime behavior. +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 file characters to translation character set} +mapping from input source file characters to +the translation character set. -\ref{refwrap}, \ref{arithmetic.operations}, \ref{comparisons}, -\ref{logical.operations}, \ref{bitwise.operations}, \ref{negators} -\change Standard function object types no longer derived from -\tcode{std::unary_function} or \tcode{std::binary_function} -\rationale Superseded by new feature; \tcode{unary_function} and -\tcode{binary_function} are no longer defined. +\diffref{lex.ppnumber} +\change +\grammarterm{pp-number} can contain \tcode{p} \grammarterm{sign} and +\tcode{P} \grammarterm{sign}. +\rationale +Necessary to enable \grammarterm{hexadecimal-floating-point-literal}s. \effect -Valid \CppIII code that depends on function object types being derived from -\tcode{unary_function} or \tcode{binary_function} may fail to compile -in this International Standard. +Valid \CppXIV{} code may fail to compile or produce different results in +this revision of \Cpp{}. Specifically, character sequences like \tcode{0p+0} +and \tcode{0e1_p+0} are three separate tokens each in \CppXIV{}, but one single token +in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +#define F(a) b ## a +int b0p = F(0p+0); // ill-formed; equivalent to ``\tcode{int b0p = b0p + 0;}\!'' in \CppXIV{} +\end{codeblock} +\end{example} -\rSec2[diff.cpp03.strings]{Clause \ref{strings}: strings library} +\rSec2[diff.cpp14.expr]{\ref{expr}: expressions} -\ref{string.classes} -\change \tcode{basic_string} requirements no longer allow reference-counted -strings -\rationale Invalidation is subtly different with reference-counted strings. -This change regularizes behavior for this International Standard. +\diffref{expr.post.incr,expr.pre.incr} +\change +Remove increment operator with \tcode{bool} operand. +\rationale +Obsolete feature with occasionally surprising semantics. \effect -Valid \CppIII code may execute differently in this International Standard. +A valid \CppXIV{} expression utilizing the increment operator on +a \tcode{bool} lvalue is ill-formed in this revision of \Cpp{}. -\ref{string.require} -\change Loosen \tcode{basic_string} invalidation rules -\rationale Allow small-string optimization. +\diffref{expr.new,expr.delete} +\change +Dynamic allocation mechanism for over-aligned types. +\rationale +Simplify use of over-aligned types. \effect -Valid \CppIII code may execute differently in this International Standard. -Some \tcode{const} member functions, such as \tcode{data} and \tcode{c_str}, -no longer invalidate iterators. +In \CppXIV{} code that uses a \grammarterm{new-expression} +to allocate an object with an over-aligned class type, +where that class has no allocation functions of its own, +\tcode{::operator new(std::size_t)} +is used to allocate the memory. +In this revision of \Cpp{}, +\tcode{::operator new(std::size_t, std::align_val_t)} +is used instead. -\rSec2[diff.cpp03.containers]{Clause \ref{containers}: containers library} +\rSec2[diff.cpp14.dcl.dcl]{\ref{dcl}: declarations} -\ref{container.requirements} -\change Complexity of \tcode{size()} member functions now constant -\rationale Lack of specification of complexity of \tcode{size()} resulted in -divergent implementations with inconsistent performance characteristics. +\diffref{dcl.stc} +\indextext{\idxcode{register} storage class}% +\change +Removal of \keyword{register} \grammarterm{storage-class-specifier}. +\rationale +Enable repurposing of deprecated keyword in future revisions of \Cpp{}. \effect -Some container implementations that conform to \CppIII may not conform to the -specified \tcode{size()} requirements in this International Standard. Adjusting -containers such as \tcode{std::list} to the stricter requirements may require -incompatible changes. +A valid \CppXIV{} declaration utilizing the \keyword{register} +\grammarterm{storage-class-specifier} is ill-formed in this revision of \Cpp{}. +The specifier can simply be removed to retain the original meaning. -\ref{container.requirements} -\change Requirements change: relaxation -\rationale Clarification. +\diffref{dcl.spec.auto} +\change +\keyword{auto} deduction from \grammarterm{braced-init-list}. +\rationale +More intuitive deduction behavior. \effect -Valid \CppIII code that attempts to meet the specified container requirements -may now be over-specified. Code that attempted to be portable across containers -may need to be adjusted as follows: -\begin{itemize} -\item not all containers provide \tcode{size()}; use \tcode{empty()} instead -of \tcode{size() == 0}; -\item not all containers are empty after construction (\tcode{array}); -\item not all containers have constant complexity for \tcode{swap()} (\tcode{array}). -\end{itemize} +Valid \CppXIV{} code may fail to compile or may change meaning +in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +auto x1{1}; // was \tcode{std::initializer_list}, now \tcode{int} +auto x2{1, 2}; // was \tcode{std::initializer_list}, now ill-formed +\end{codeblock} +\end{example} -\ref{container.requirements} -\change Requirements change: default constructible -\rationale Clarification of container requirements. +\diffref{dcl.fct} +\change +Make exception specifications be part of the type system. +\rationale +Improve type-safety. \effect -Valid \CppIII code that attempts to explicitly instantiate a container using -a user-defined type with no default constructor may fail to compile. +Valid \CppXIV{} code may fail to compile or change meaning in this +revision of \Cpp{}. +\begin{example} +\begin{codeblock} +void g1() noexcept; +void g2(); +template int f(T *, T *); +int x = f(g1, g2); // ill-formed; previously well-formed +\end{codeblock} +\end{example} -\ref{sequence.reqmts}, \ref{associative.reqmts} -\change Signature changes: from \tcode{void} return types -\rationale Old signature threw away useful information that may be expensive -to recalculate. +\diffref{dcl.init.aggr} +\change +Definition of an aggregate is extended +to apply to user-defined types with base classes. +\rationale +To increase convenience of aggregate initialization. \effect -The following member functions have changed: -\begin{itemize} -\item \tcode{erase(iter)} for \tcode{set}, \tcode{multiset}, \tcode{map}, \tcode{multimap} -\item \tcode{erase(begin, end)} for \tcode{set}, \tcode{multiset}, \tcode{map}, \tcode{multimap} -\item \tcode{insert(pos, num, val)} for \tcode{vector}, \tcode{deque}, \tcode{list}, \tcode{forward_list} -\item \tcode{insert(pos, beg, end)} for \tcode{vector}, \tcode{deque}, \tcode{list}, \tcode{forward_list} -\end{itemize} - -Valid \CppIII code that relies on these functions returning \tcode{void} -(e.g., code that creates a pointer to member function that points to one -of these functions) will fail to compile with this International Standard. +Valid \CppXIV{} code may fail to compile or produce different results in this +revision of \Cpp{}; initialization from an empty initializer list will +perform aggregate initialization instead of invoking a default constructor +for the affected types. +\begin{example} +\begin{codeblock} +struct derived; +struct base { + friend struct derived; +private: + base(); +}; +struct derived : base {}; -\ref{sequence.reqmts}, \ref{associative.reqmts} -\change Signature changes: from \tcode{iterator} to \tcode{const_iterator} -parameters -\rationale Overspecification. -\effects -The signatures of the following member functions changed from taking an -\tcode{iterator} to taking a \tcode{const_iterator}: +derived d1{}; // error; the code was well-formed in \CppXIV{} +derived d2; // still OK +\end{codeblock} +\end{example} -\begin{itemize} -\item \tcode{insert(iter, val)} for \tcode{vector}, \tcode{deque}, \tcode{list}, -\tcode{set}, \tcode{multiset}, \tcode{map}, \tcode{multimap} -\item \tcode{insert(pos, beg, end)} for \tcode{vector}, \tcode{deque}, \tcode{list}, -\tcode{forward_list} -\item \tcode{erase(iter)} for \tcode{set}, \tcode{multiset}, \tcode{map}, \tcode{multimap} -\item \tcode{erase(begin, end)} for \tcode{set}, \tcode{multiset}, \tcode{map}, \tcode{multimap} -\item all forms of \tcode{list::splice} -\item all forms of \tcode{list::merge} -\end{itemize} +\rSec2[diff.cpp14.class]{\ref{class}: classes} -Valid \CppIII code that uses these functions may fail to compile with this -International Standard. +\diffref{class.inhctor.init} +\change +Inheriting a constructor no longer injects a constructor into the derived class. +\rationale +Better interaction with other language features. +\effect +Valid \CppXIV{} code that uses inheriting constructors may not be valid +or may have different semantics. A \grammarterm{using-declaration} +that names a constructor now makes the corresponding base class constructors +visible to initializations of the derived class +rather than declaring additional derived class constructors. +\begin{example} +\begin{codeblock} +struct A { + template A(T, typename T::type = 0); + A(int); +}; +struct B : A { + using A::A; + B(int); +}; +B b(42L); // now calls \tcode{B(int)}, used to call \tcode{B(long)}, + // which called \tcode{A(int)} due to substitution failure + // in \tcode{A(long)}. +\end{codeblock} +\end{example} -\ref{sequence.reqmts}, \ref{associative.reqmts} -\change Signature changes: \tcode{resize} -\rationale Performance, compatibility with move semantics. -\effect -For \tcode{vector}, \tcode{deque}, and \tcode{list} -the fill value passed to \tcode{resize} is now passed by reference instead of -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 International -Standard. +\rSec2[diff.cpp14.temp]{\ref{temp}: templates} -\rSec2[diff.cpp03.algorithms]{Clause \ref{algorithms}: algorithms library} +\diffref{temp.deduct.type} +\change +Allowance to deduce from the type of a constant template argument. +\rationale +In combination with the ability to declare +constant template arguments with placeholder types, +allows partial specializations to decompose +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{}. +\begin{example} +\begin{codeblock} +template struct A; +template int foo(A *) = delete; +void foo(void *); +void bar(A<0> *p) { + foo(p); // ill-formed; previously well-formed +} +\end{codeblock} +\end{example} -\ref{algorithms.general} -\change Result state of inputs after application of some algorithms -\rationale Required by new feature. -\effect -A valid \CppIII program may detect that an object with a valid but -unspecified state has a different valid but unspecified state with this -International Standard. For example, \tcode{std::remove} and -\tcode{std::remove_if} may leave the tail of the input sequence with a -different set of values than previously. +\rSec2[diff.cpp14.except]{\ref{except}: exception handling} -\rSec2[diff.cpp03.numerics]{Clause \ref{numerics}: numerics library} +\diffref{except.spec} +\change +Remove dynamic exception specifications. +\rationale +Dynamic exception specifications were a deprecated feature +that was complex and brittle in use. +They interacted badly with the type system, +which became a more significant issue in this revision of \Cpp{} +where (non-dynamic) exception specifications are part of the function type. +\effect +A valid \CppXIV{} function declaration, +member function declaration, +function pointer declaration, +or function reference declaration, +if it has a potentially throwing dynamic exception specification, +is rejected as ill-formed in this revision of \Cpp{}. +Violating a non-throwing dynamic exception specification +calls \tcode{terminate} rather than \tcode{unexpected}, +and it is unspecified whether stack unwinding is performed +prior to such a call. + +\rSec2[diff.cpp14.library]{\ref{library}: library introduction} + +\diffref{headers} +\change +New headers. +\rationale +New functionality. +\effect +The following \Cpp{} headers are new: +\libheaderrefx{any}{any.synop}, +\libheaderref{charconv}, +\libheaderref{execution}, +\libheaderrefx{filesystem}{fs.filesystem.syn}, +\libheaderrefx{memory_resource}{mem.res.syn}, +\libheaderref{optional},\\ +\libheaderrefx{string_view}{string.view.synop}, +and +\libheaderref{variant}. +Valid \CppXIV{} code that \tcode{\#include}{s} headers with these names may be +invalid in this revision of \Cpp{}. -\ref{complex.numbers} -\change Specified representation of complex numbers -\rationale Compatibility with C99. +\diffref{namespace.future} +\change +New reserved namespaces. +\rationale +Reserve namespaces for future revisions of the standard library +that might otherwise be incompatible with existing programs. +\effect +The global namespaces \tcode{std} +followed by an arbitrary sequence of \grammarterm{digit}{s}\iref{lex.name} +are reserved for future standardization. +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} + +\diffref{func.wrap} +\change +Constructors taking allocators removed. +\rationale +No implementation consensus. +\effect +Valid \CppXIV{} code may fail to compile or may change meaning in this +revision of \Cpp{}. Specifically, constructing a \tcode{std::function} with +an allocator is ill-formed and uses-allocator construction will not pass an +allocator to \tcode{std::function} constructors in this revision of \Cpp{}. + +\diffref{util.smartptr.shared} +\change +Different constraint on conversions from \tcode{unique_ptr}. +\rationale +Adding array support to \tcode{shared_ptr}, +via the syntax \tcode{shared_ptr} and \tcode{shared_ptr}. +\effect +Valid \CppXIV{} code may fail to compile or may change meaning in this +revision of \Cpp{}. +\begin{example} +\begin{codeblock} +#include +std::unique_ptr arr(new int[1]); +std::shared_ptr ptr(std::move(arr)); // error: \tcode{int(*)[]} is not compatible with \tcode{int*} +\end{codeblock} +\end{example} + +\rSec2[diff.cpp14.string]{\ref{strings}: strings library} + +\diffref{basic.string} +\change +Non-const \tcode{.data()} member added. +\rationale +The lack of a non-const \tcode{.data()} +differed from the similar member of \tcode{std::vector}. +This change regularizes behavior. +\effect +Overloaded functions which have differing code paths +for \tcode{char*} and \tcode{const char*} arguments +will execute differently +when called with a non-const string's \tcode{.data()} member +in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +int f(char *) = delete; +int f(const char *); +string s; +int x = f(s.data()); // ill-formed; previously well-formed +\end{codeblock} +\end{example} + +\rSec2[diff.cpp14.containers]{\ref{containers}: containers library} + +\diffref{associative.reqmts} +\change +Requirements change: +\rationale +Increase portability, clarification of associative container requirements. +\effect +Valid \CppXIV{} code that attempts to use associative containers +having a comparison object with non-const function call operator +may fail to compile in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +#include + +struct compare +{ + bool operator()(int a, int b) + { + return a < b; + } +}; + +int main() { + const std::set s; + s.find(0); +} +\end{codeblock} +\end{example} + +\rSec2[diff.cpp14.depr]{\ref{depr}: compatibility features} + +\nodiffref +\change +The class templates +\tcode{auto_ptr}, +\tcode{unary_function}, and +\tcode{binary_function}, +the function templates +\tcode{random_shuffle}, +and the function templates (and their return types) +\tcode{ptr_fun}, +\tcode{mem_fun}, +\tcode{mem_fun_ref}, +\tcode{bind1st}, and +\tcode{bind2nd} +are not defined. +\rationale +Superseded by new features. +\effect +Valid \CppXIV{} code that uses these class templates +and function templates may fail to compile in this revision of \Cpp{}. + +\nodiffref +\change +Remove old iostreams members [depr.ios.members]. +\rationale +Redundant feature for compatibility with pre-standard code +has served its time. +\effect +A valid \CppXIV{} program using these identifiers +may be ill-formed in this revision of \Cpp{}. + +\rSec1[diff.cpp11]{\Cpp{} and ISO \CppXI{}} + +\rSec2[diff.cpp11.general]{General} + +\pnum +\indextext{summary!compatibility with ISO \CppXI{}}% +Subclause \ref{diff.cpp11} lists the differences between \Cpp{} and +ISO \CppXI{}, +in addition to those listed above, +by the chapters of this document. + +\rSec2[diff.cpp11.lex]{\ref{lex}: lexical conventions} + +\diffref{lex.ppnumber} +\change +\grammarterm{pp-number} can contain one or more single quotes. +\rationale +Necessary to enable single quotes as digit separators. +\effect +Valid \CppXI{} code may fail to compile or may change meaning in this +revision of \Cpp{}. For example, the following code is valid both in \CppXI{} and in +this revision of \Cpp{}, but the macro invocation produces different outcomes +because the single quotes delimit a \grammarterm{character-literal} in \CppXI{}, whereas they are digit +separators in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +#define M(x, ...) __VA_ARGS__ +int x[2] = { M(1'2,3'4, 5) }; +// \tcode{int x[2] = \{ 5 \};\ \ \ \ \ } --- \CppXI{} +// \tcode{int x[2] = \{ 3'4, 5 \};} --- this revision of \Cpp{} +\end{codeblock} +\end{example} + +\rSec2[diff.cpp11.basic]{\ref{basic}: basics} + +\diffref{basic.stc.dynamic.deallocation} +\change +New usual (non-placement) deallocator. +\rationale +Required for sized deallocation. +\effect +Valid \CppXI{} code can declare a global placement allocation function and +deallocation function as follows: +\begin{codeblock} +void* operator new(std::size_t, std::size_t); +void operator delete(void*, std::size_t) noexcept; +\end{codeblock} +In this revision of \Cpp{}, however, the declaration of \tcode{operator delete} +might match a predefined usual (non-placement) +\tcode{operator delete}\iref{basic.stc.dynamic}. If so, the +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} + +\diffref{expr.cond} +\change +A conditional expression with a throw expression as its second or third +operand keeps the type and value category of the other operand. +\rationale +Formerly mandated conversions (lvalue-to-rvalue\iref{conv.lval}, +array-to-pointer\iref{conv.array}, and function-to-pointer\iref{conv.func} +standard conversions), especially the creation of the temporary due to +lvalue-to-rvalue conversion, were considered gratuitous and surprising. +\effect +Valid \CppXI{} code that relies on the conversions may behave differently +in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +struct S { + int x = 1; + void mf() { x = 2; } +}; +int f(bool cond) { + S s; + (cond ? s : throw 0).mf(); + return s.x; +} +\end{codeblock} +In \CppXI{}, \tcode{f(true)} returns \tcode{1}. In this revision of \Cpp{}, +it returns \tcode{2}. +\begin{codeblock} +sizeof(true ? "" : throw 0) +\end{codeblock} +In \CppXI{}, the expression yields \tcode{sizeof(const char*)}. In this +revision of \Cpp{}, it yields \tcode{sizeof(const char[1])}. +\end{example} + +\rSec2[diff.cpp11.dcl.dcl]{\ref{dcl}: declarations} + +\diffref{dcl.constexpr} +\change +\keyword{constexpr} non-static member functions are not implicitly +\keyword{const} member functions. +\rationale +Necessary to allow \keyword{constexpr} member functions to mutate +the object. +\effect +Valid \CppXI{} code may fail to compile in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +struct S { + constexpr const int &f(); + int &f(); +}; +\end{codeblock} +This code is valid in \CppXI{} +but invalid in this revision of \Cpp{} because it declares the same member +function twice with different return types. +\end{example} + +\diffref{dcl.init.aggr} +\change +Classes with default member initializers can be aggregates. +\rationale +Necessary to allow default member initializers to be used +by aggregate initialization. +\effect +Valid \CppXI{} code may fail to compile or may change meaning in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +struct S { // Aggregate in \CppXIV{} onwards. + int m = 1; +}; +struct X { + operator int(); + operator S(); +}; +X a{}; +S b{a}; // uses copy constructor in \CppXI{}, + // performs aggregate initialization in this revision of \Cpp{} +\end{codeblock} +\end{example} + +\rSec2[diff.cpp11.library]{\ref{library}: library introduction} + +\diffref{headers} +\change +New header. +\rationale +New functionality. +\effect +The \Cpp{} header \libheaderrefx{shared_mutex}{shared.mutex.syn} is new. +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} + +\diffref{c.files} +\change +\tcode{gets} is not defined. +\rationale +Use of \tcode{gets} is considered dangerous. +\effect +Valid \CppXI{} code that uses the \tcode{gets} function may fail to compile +in this revision of \Cpp{}. + +\rSec1[diff.cpp03]{\Cpp{} and ISO \CppIII{}} + +\rSec2[diff.cpp03.general]{General} + +\pnum +\indextext{summary!compatibility with ISO \CppIII{}}% +Subclause \ref{diff.cpp03} lists the differences between \Cpp{} and +ISO \CppIII{}, +in addition to those listed above, +by the chapters of this document. + +\rSec2[diff.cpp03.lex]{\ref{lex}: lexical conventions} + +\diffref{lex.pptoken} +\change +New kinds of \grammarterm{string-literal}s. +\rationale +Required for new features. +\effect +Valid \CppIII{} code may fail to compile or produce different results in +this revision of \Cpp{}. Specifically, macros named \tcode{R}, \tcode{u8}, +\tcode{u8R}, \tcode{u}, \tcode{uR}, \tcode{U}, \tcode{UR}, or \tcode{LR} will +not be expanded when adjacent to a \grammarterm{string-literal} but will be interpreted as +part of the \grammarterm{string-literal}. +\begin{example} +\begin{codeblock} +#define u8 "abc" +const char* s = u8"def"; // Previously \tcode{"abcdef"}, now \tcode{"def"} +\end{codeblock} +\end{example} + +\diffref{lex.pptoken} +\change +User-defined literal string support. +\rationale +Required for new features. +\effect +Valid \CppIII{} code may fail to compile or produce different results in +this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +#define _x "there" +"hello"_x // \#1 +\end{codeblock} + +Previously, \#1 would have consisted of two separate preprocessing tokens and +the macro \tcode{_x} would have been expanded. In this revision of \Cpp{}, +\#1 consists of a single preprocessing token, so the macro is not expanded. +\end{example} + +\diffref{lex.key} +\change +New keywords. +\rationale +Required for new features. +\effect +Added to \tref{lex.key}, the following identifiers are new keywords: +\tcode{alignas}, +\tcode{alignof}, +\keyword{char16_t}, +\keyword{char32_t}, +\keyword{constexpr}, +\keyword{decltype}, +\keyword{noexcept}, +\keyword{nullptr}, +\keyword{static_assert}, +and +\keyword{thread_local}. +Valid \CppIII{} code using these identifiers is invalid in this revision of \Cpp{}. + +\diffref{lex.icon} +\change +Type of integer literals. +\rationale +C99 compatibility. +\effect +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} + +\diffref{conv.ptr} +\change +Only literals are integer null pointer constants. +\rationale +Removing surprising interactions with templates and constant +expressions. +\effect +Valid \CppIII{} code may fail to compile or produce different results in +this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +void f(void *); // \#1 +void f(...); // \#2 +template void g() { + f(0*N); // calls \#2; used to call \#1 +} +\end{codeblock} +\end{example} + +\diffref{expr.typeid} +\change +Evaluation of operands in \keyword{typeid}. +\rationale +Introduce additional expression value categories. +\effect +Valid \CppIII{} code that uses xvalues as operands for \keyword{typeid} +may change behavior in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +void f() { + struct B { + B() {} + virtual ~B() { } + }; + + struct C { B b; }; + typeid(C().b); // unevaluated in \CppIII{}, evaluated in \CppXI{} +} +\end{codeblock} +\end{example} + +\diffref{expr.mul} +\change +Specify rounding for results of integer \tcode{/} and \tcode{\%}. +\rationale +Increase portability, C99 compatibility. +\effect +Valid \CppIII{} code that uses integer division rounds the result toward 0 or +toward negative infinity, whereas this revision of \Cpp{} always rounds +the result toward 0. + +\diffref{expr.log.and} +\change +\tcode{\&\&} is valid in a \grammarterm{type-name}. +\rationale +Required for new features. +\effect +Valid \CppIII{} code may fail to compile or produce different results in +this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +bool b1 = new int && false; // previously \tcode{false}, now ill-formed +struct S { operator int(); }; +bool b2 = &S::operator int && false; // previously \tcode{false}, now ill-formed +\end{codeblock} +\end{example} + +\diffref{expr.cond} +\change +Fewer copies in the conditional operator. +\rationale +Introduce additional expression value categories. +\effect +Valid \CppIII{} code that uses xvalues as operands for the conditional operator +may change behavior in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +void f() { + struct B { + B() {} + B(const B&) { } + }; + struct D : B {}; + + struct BB { B b; }; + struct DD { D d; }; + + true ? BB().b : DD().d; // additional copy in \CppIII{}, no copy or move in \CppXI{} +} +\end{codeblock} +\end{example} + +\rSec2[diff.cpp03.dcl.dcl]{\ref{dcl}: declarations} + +\diffref{dcl.spec} +\change +Remove \keyword{auto} as a storage class specifier. +\rationale +New feature. +\effect +Valid \CppIII{} code that uses the keyword \keyword{auto} as a storage class +specifier +may be invalid in this revision of \Cpp{}. +In this revision of \Cpp{}, +\keyword{auto} indicates that the type of a variable is to be deduced +from its initializer expression. + +\diffref{dcl.init.list} +\change +Narrowing restrictions in aggregate initializers. +\rationale +Catches bugs. +\effect +Valid \CppIII{} code may fail to compile in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +int x[] = { 2.0 }; +\end{codeblock} +This code is valid in \CppIII{} but invalid in this +revision of \Cpp{} because \tcode{double} to \tcode{int} is a narrowing +conversion. +\end{example} + +\diffref{dcl.link} +\change +Names declared in an anonymous namespace +changed from external linkage to internal linkage; +language linkage applies to names with external linkage only. +\rationale +Alignment with user expectations. +\effect +Valid \CppIII{} code may violate the one-definition rule\iref{basic.def.odr} +in this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +namespace { extern "C" { extern int x; } } // \#1, previously external linkage and C language linkage, + // now internal linkage and \Cpp{} language linkage +namespace A { extern "C" int x = 42; } // \#2, external linkage and C language linkage +int main(void) { return x; } +\end{codeblock} +This code is valid in \CppIII{}, +but \tcode{\#2} is not a definition for \tcode{\#1} +in this revision of \Cpp{}, violating the one-definition rule. +\end{example} + +\rSec2[diff.cpp03.class]{\ref{class}: classes} + +\diffref{class.default.ctor,class.dtor,class.copy.ctor,class.copy.assign} +\change +Implicitly-declared special member functions are defined as deleted +when the implicit definition would have been ill-formed. +\rationale +Improves template argument deduction failure. +\effect +A valid \CppIII{} program that uses one of these special member functions in a +context where the definition is not required (e.g., in an expression that is +not potentially evaluated) becomes ill-formed. + +\diffref{class.dtor} +\change +User-declared destructors have an implicit exception specification. +\rationale +Clarification of destructor requirements. +\effect +Valid \CppIII{} code may execute differently in this revision of \Cpp{}. In +particular, destructors that throw exceptions will call \tcode{std::terminate} +(without calling \tcode{std::unexpected}) if their exception specification is +non-throwing. + +\rSec2[diff.cpp03.temp]{\ref{temp}: templates} + +\diffref{temp.param} +\change +Repurpose \keyword{export} for modules\iref{module,cpp.module,cpp.import}. +\rationale +No implementation consensus for the \CppIII{} meaning of \keyword{export}. +\effect +A valid \CppIII{} program containing \tcode{export} is ill-formed in this +revision of \Cpp{}. + +\diffref{temp.arg} +\change +Remove whitespace requirement for nested closing template right angle +brackets. +\rationale +Considered a persistent but minor annoyance. Template aliases +representing non-class types would exacerbate whitespace issues. +\effect +Change to semantics of well-defined expression. A valid \CppIII{} expression +containing a right angle bracket (``\tcode{>}'') followed immediately by +another right angle bracket may now be treated as closing two templates. +\begin{example} +\begin{codeblock} +template struct X { }; +template struct Y { }; +X< Y< 1 >> 2 > > x; +\end{codeblock} +This code is valid in \CppIII{} because ``\tcode{>>}'' +is a right-shift operator, but invalid in this revision of \Cpp{} because +``\tcode{>>}'' closes two templates. +\end{example} + +\diffref{temp.dep.candidate} +\change +Allow dependent calls of functions with internal linkage. +\rationale +Overly constrained, simplify overload resolution rules. +\effect +A valid \CppIII{} program can get a different result in this +revision of \Cpp{}. + +\rSec2[diff.cpp03.library]{\ref{library}: library introduction} + +\pnum +\textbf{Affected:} \ref{library} -- \ref{\lastlibchapter} +\change +New reserved identifiers. +\rationale +Required by new features. +\effect +Valid \CppIII{} code that uses any identifiers added to the \Cpp{} standard +library by later revisions of \Cpp{} may fail to compile or produce different +results in this revision of \Cpp{}. A comprehensive list of identifiers used +by the \Cpp{} standard library can be found in the Index of Library Names in this +document. + +\diffref{headers} +\change +New headers. +\rationale +New functionality. +\effect +The following \Cpp{} headers are new: +\libheaderref{array}, +\libheaderrefx{atomic}{atomics.syn}, +\libheaderrefx{chrono}{time.syn}, +\libheaderrefx{condition_variable}{condition.variable.syn}, +\libheaderrefx{forward_list}{forward.list.syn}, +\libheaderref{future}, +\libheaderrefxx{initializer_list}{initiali\-zer_list}{initializer.list.syn}, +\libheaderref{mutex}, +\libheaderrefx{random}{rand.synopsis}, +\libheaderref{ratio}, +\libheaderrefx{regex}{re.syn}, +\libheaderrefx{scoped_allocator}{allocator.adaptor.syn}, +\libheaderrefx{system_error}{system.error.syn}, +\libheaderref{thread}, +\libheaderref{tuple}, +\libheaderrefxx{typeindex}{type\-index}{type.index.synopsis}, +\libheaderrefx{type_traits}{meta.type.synop}, +\libheaderrefx{unordered_map}{unord.map.syn}, +and +\libheaderrefx{unordered_set}{unord.set.syn}. +In addition the following C compatibility headers are new: +\libheaderref{cfenv}, +\libheaderref{cinttypes}, +\libheaderref{cstdint}, +and +\libheaderref{cuchar}. +Valid \CppIII{} code that \tcode{\#include}{s} headers with these names may be +invalid in this revision of \Cpp{}. + +\diffref{swappable.requirements} +\change +Function \tcode{swap} moved to a different header. +\rationale +Remove dependency on \libheaderref{algorithm} for \tcode{swap}. +\effect +Valid \CppIII{} code that has been compiled expecting \tcode{swap} to be in +\libheaderref{algorithm} may have to instead include \libheaderref{utility}. + +\diffref{namespace.posix} +\change +New reserved namespace. +\rationale +New functionality. +\effect +The global namespace \tcode{posix} is now reserved for standardization. Valid +\CppIII{} code that uses a top-level namespace \tcode{posix} may be invalid in +this revision of \Cpp{}. + +\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}, or +\tcode{noreturn} as macros is invalid in this +revision of \Cpp{}. + +\rSec2[diff.cpp03.language.support]{\ref{support}: +language support library} + +\diffref{new.delete.single} +\change +\tcode{operator new} may throw exceptions other than +\tcode{std::bad_alloc}. +\rationale +Consistent application of \keyword{noexcept}. +\effect +Valid \CppIII{} code that assumes that global \tcode{operator new} only +throws \tcode{std::bad_alloc} may execute differently in this revision of \Cpp{}. +Valid \CppIII{} code that replaces the global replaceable \tcode{operator new} +is ill-formed in this revision of \Cpp{}, +because the exception specification of \tcode{throw(std::bad_alloc)} +was removed. + +\rSec2[diff.cpp03.diagnostics]{\ref{diagnostics}: diagnostics library} + +\diffref{errno} +\change +Thread-local error numbers. +\rationale +Support for new thread facilities. +\effect +Valid but implementation-specific \CppIII{} code that relies on +\tcode{errno} being the same across threads may change behavior in this +revision of \Cpp{}. + +\rSec2[diff.cpp03.utilities]{\ref{utilities}: general utilities library} + +\diffref{refwrap,arithmetic.operations,comparisons,logical.operations,bitwise.operations} +\change +Standard function object types no longer derived from +\tcode{std::unary_function} or \tcode{std::binary_function}. +\rationale +Superseded by new feature; \tcode{unary_function} and +\tcode{binary_function} are no longer defined. +\effect +Valid \CppIII{} code that depends on function object types being derived from +\tcode{unary_function} or \tcode{binary_function} may fail to compile +in this revision of \Cpp{}. + +\rSec2[diff.cpp03.strings]{\ref{strings}: strings library} + +\diffref{string.classes} +\change +\tcode{basic_string} requirements no longer allow reference-counted +strings. +\rationale +Invalidation is subtly different with reference-counted strings. +This change regularizes behavior. +\effect +Valid \CppIII{} code may execute differently in this revision of \Cpp{}. + +\diffref{string.require} +\change +Loosen \tcode{basic_string} invalidation rules. +\rationale +Allow small-string optimization. +\effect +Valid \CppIII{} code may execute differently in this revision of \Cpp{}. +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} + +\diffref{container.requirements} +\change +Complexity of \tcode{size()} member functions now constant. +\rationale +Lack of specification of complexity of \tcode{size()} resulted in +divergent implementations with inconsistent performance characteristics. +\effect +Some container implementations that conform to \CppIII{} may not conform to the +specified \tcode{size()} requirements in this revision of \Cpp{}. Adjusting +containers such as \tcode{std::list} to the stricter requirements may require +incompatible changes. + +\diffref{container.requirements} +\change +Requirements change: relaxation. +\rationale +Clarification. +\effect +Valid \CppIII{} code that attempts to meet the specified container requirements +may now be over-specified. Code that attempted to be portable across containers +may need to be adjusted as follows: +\begin{itemize} +\item not all containers provide \tcode{size()}; use \tcode{empty()} instead +of \tcode{size() == 0}; +\item not all containers are empty after construction (\tcode{array}); +\item not all containers have constant complexity for \tcode{swap()} (\tcode{array}). +\end{itemize} + +\diffref{container.requirements} +\change +Requirements change: default constructible. +\rationale +Clarification of container requirements. +\effect +Valid \CppIII{} code that attempts to explicitly instantiate a container using +a user-defined type with no default constructor may fail to compile. + +\diffref{sequence.reqmts,associative.reqmts} +\change +Signature changes: from \keyword{void} return types. +\rationale +Old signature threw away useful information that may be expensive +to recalculate. +\effect +The following member functions have changed: +\begin{itemize} +\item \tcode{erase(iter)} for \tcode{set}, \tcode{multiset}, \tcode{map}, \tcode{multimap} +\item \tcode{erase(begin, end)} for \tcode{set}, \tcode{multiset}, \tcode{map}, \tcode{multimap} +\item \tcode{insert(pos, num, val)} for \tcode{vector}, \tcode{deque}, \tcode{list}, \tcode{forward_list} +\item \tcode{insert(pos, beg, end)} for \tcode{vector}, \tcode{deque}, \tcode{list}, \tcode{forward_list} +\end{itemize} + +Valid \CppIII{} code that relies on these functions returning \keyword{void} +(e.g., code that creates a pointer to member function that points to one +of these functions) will fail to compile with this revision of \Cpp{}. + +\diffref{sequence.reqmts,associative.reqmts} +\change +Signature changes: from \tcode{iterator} to \tcode{const_iterator} +parameters. +\rationale +Overspecification. +\effect +The signatures of the following member functions changed from taking an +\tcode{iterator} to taking a \tcode{const_iterator}: + +\begin{itemize} +\item \tcode{insert(iter, val)} for \tcode{vector}, \tcode{deque}, \tcode{list}, +\tcode{set}, \tcode{multiset}, \tcode{map}, \tcode{multimap} +\item \tcode{insert(pos, beg, end)} for \tcode{vector}, \tcode{deque}, \tcode{list}, +\tcode{forward_list} +\item \tcode{erase(begin, end)} for \tcode{set}, \tcode{multiset}, \tcode{map}, \tcode{multimap} +\item all forms of \tcode{list::splice} +\item all forms of \tcode{list::merge} +\end{itemize} + +Valid \CppIII{} code that uses these functions may fail to compile with this +revision of \Cpp{}. + +\diffref{sequence.reqmts,associative.reqmts} +\change +Signature changes: \tcode{resize}. +\rationale +Performance, compatibility with move semantics. +\effect +For \tcode{vector}, \tcode{deque}, and \tcode{list} +the fill value passed to \tcode{resize} is now passed by reference instead of +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} + +\diffref{algorithms.general} +\change +Result state of inputs after application of some algorithms. +\rationale +Required by new feature. +\effect +A valid \CppIII{} program may detect that an object with a valid but +unspecified state has a different valid but unspecified state with this +revision of \Cpp{}. For example, \tcode{std::remove} and +\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} + +\diffref{complex.numbers} +\change +Specified representation of complex numbers. +\rationale +Compatibility with C99. +\effect +Valid \CppIII{} code that uses implementation-specific knowledge about the +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} + +\diffref{facet.num.get.virtuals} +\change +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} + +\diffref{istream.sentry,ostream.sentry,iostate.flags} +\change +Specify use of \keyword{explicit} in existing boolean conversion functions. +\rationale +Clarify intentions, avoid workarounds. +\effect +Valid \CppIII{} code that relies on implicit boolean conversions will fail to +compile with this revision of \Cpp{}. Such conversions occur in the +following conditions: + +\begin{itemize} +\item passing a value to a function that takes an argument of type \tcode{bool}; +\item using \tcode{operator==} to compare to \tcode{false} or \tcode{true}; +\item returning a value from a function with a return type of \tcode{bool}; +\item initializing members of type \tcode{bool} via aggregate initialization; +\item initializing a \tcode{const bool\&} which would bind to a temporary object. +\end{itemize} + +\diffref{ios.failure} +\change +Change base class of \tcode{std::ios_base::failure}. +\rationale +More detailed error messages. +\effect +\tcode{std::ios_base::failure} is no longer derived directly from +\tcode{std::exception}, but is now derived from \tcode{std::system_error}, +which in turn is derived from \tcode{std::runtime_error}. Valid \CppIII{} code +that assumes that \tcode{std::ios_base::failure} is derived directly from +\tcode{std::exception} may execute differently in this revision of \Cpp{}. + +\diffref{ios.base} +\change +Flag types in \tcode{std::ios_base} are now bitmasks with values +defined as constexpr static members. +\rationale +Required for new features. +\effect +Valid \CppIII{} code that relies on \tcode{std::ios_base} flag types being +represented as \tcode{std::bitset} or as an integer type may fail to compile +with this revision of \Cpp{}. +\begin{example} +\begin{codeblock} +#include + +int main() { + int flag = std::ios_base::hex; + std::cout.setf(flag); // error: \tcode{setf} does not take argument of type \tcode{int} +} +\end{codeblock} +\end{example} + +\rSec1[diff.iso]{\Cpp{} and C} + +\rSec2[diff.iso.general]{General} + +\pnum +\indextext{summary!compatibility with C}% +Subclause \ref{diff.iso} lists the differences between \Cpp{} and C, +in addition to those listed above, +by the chapters of this document. + +\rSec2[diff.lex]{\ref{lex}: lexical conventions} + +\diffref{lex.key} +\change +New Keywords.\\ +New keywords are added to \Cpp{}; +see \ref{lex.key}. +\rationale +These keywords were added in order to implement the new +semantics of \Cpp{}. +\effect +Change to semantics of well-defined feature. +Any C programs that used any of these keywords as identifiers +are not valid \Cpp{} programs. +\difficulty +Syntactic transformation. +Converting one specific program is easy. +Converting a large collection +of related programs takes more work. +\howwide +Common. + +\diffref{lex.ccon} +\change +Type of \grammarterm{character-literal} is changed from \tcode{int} to \tcode{char}. +\rationale +This is needed for improved overloaded function argument type +matching. +\begin{example} +\begin{codeblock} +int function( int i ); +int function( char c ); + +function( 'x' ); +\end{codeblock} +It is preferable that this call match the second version of +function rather than the first. +\end{example} +\effect +Change to semantics of well-defined feature. +C programs which depend on +\begin{codeblock} +sizeof('x') == sizeof(int) +\end{codeblock} +will not work the same as \Cpp{} programs. +\difficulty +Simple. +\howwide +Programs which depend upon \tcode{sizeof('x')} are probably rare. + +\diffref{lex.string} +\change +Concatenated \grammarterm{string-literal}s can no longer have +conflicting \grammarterm{encoding-prefix}es. +\rationale +Removal of non-portable feature. +\effect +Concatenation of \grammarterm{string-literal}s +with different \grammarterm{encoding-prefix}es +is now ill-formed. +\difficulty +Syntactic transformation. +\howwide +Seldom. + +\diffref{lex.string} +\change +String literals made const.\\ +The type of a \grammarterm{string-literal} is changed +from ``array of \tcode{char}'' +to ``array of \tcode{const char}''. +\indextext{UTF-8}% +The type of a UTF-8 string literal is changed +from ``array of \tcode{char}'' +to ``array of \tcode{const char8_t}''. +\indextext{UTF-16}% +The type of a UTF-16 string literal is changed +from ``array of \textit{some-integer-type}'' +to ``array of \tcode{const char16_t}''. +\indextext{UTF-32}% +The type of a UTF-32 string literal is changed +from ``array of \textit{some-integer-type}'' +to ``array of \tcode{const char32_t}''. +The type of a wide string literal is changed +from ``array of \keyword{wchar_t}'' +to ``array of \tcode{const wchar_t}''. +\rationale +This avoids calling an inappropriate overloaded function, +which might expect to be able to modify its argument. +\effect +Change to semantics of well-defined feature. +\difficulty +Syntactic transformation. The fix is to add a cast: +\begin{codeblock} +char* p = "abc"; // valid in C, invalid in \Cpp{} +void f(char*) { + char* p = (char*)"abc"; // OK, cast added + f(p); + f((char*)"def"); // OK, cast added +} +\end{codeblock} +\howwide +Programs that have a legitimate reason to treat string literal objects +as potentially modifiable memory are probably rare. + +\rSec2[diff.basic]{\ref{basic}: basics} + +\diffref{basic.def} +\change +\Cpp{} does not have ``tentative definitions'' as in C. +\begin{example} +At file scope, +\begin{codeblock} +int i; +int i; +\end{codeblock} +is valid in C, invalid in \Cpp{}. +\end{example} +This makes it impossible to define +mutually referential file-local objects with static storage duration, +if initializers are restricted to the syntactic forms of C\@. +\begin{example} +\begin{codeblock} +struct X { int i; struct X* next; }; + +static struct X a; +static struct X b = { 0, &a }; +static struct X a = { 1, &b }; +\end{codeblock} +\end{example} +\rationale +This avoids having different initialization rules for +fundamental types and user-defined types. +\effect +Deletion of semantically well-defined feature. +\difficulty +Semantic transformation. +In \Cpp{}, the initializer for one of a set of +mutually-referential file-local objects with static storage +duration must invoke a function +call to achieve the initialization. +\howwide +Seldom. + +\diffref{basic.scope} +\change +A \keyword{struct} is a scope in \Cpp{}, not in C. +\begin{example} +\begin{codeblock} +struct X { + struct Y { int a; } b; +}; +struct Y c; +\end{codeblock} +is valid in C but not in \Cpp{}, which would require \tcode{X::Y c;}. +\end{example} +\rationale +Class scope is crucial to \Cpp{}, and a struct is a class. +\effect +Change to semantics of well-defined feature. +\difficulty +Semantic transformation. +\howwide +C programs use \keyword{struct} extremely frequently, but the +change is only noticeable when \keyword{struct}, enumeration, or enumerator +names are referred to outside the \keyword{struct}. +The latter is probably rare. + +\diffref{basic.link} [also \ref{dcl.type}] +\change +A name of file scope that is explicitly declared \keyword{const}, and not explicitly +declared \keyword{extern}, has internal linkage, while in C it would have external linkage. +\rationale +Because const objects may be used as values during translation in +\Cpp{}, this feature urges programmers to provide an explicit initializer +for each const object. +This feature allows the user to put const objects in source files that are included +in more than one translation unit. +\effect +Change to semantics of well-defined feature. +\difficulty +Semantic transformation. +\howwide +Seldom. + +\diffref{basic.start.main} +\change +The \tcode{main} function cannot be called recursively and cannot have its address taken. +\rationale +The \tcode{main} function may require special actions. +\effect +Deletion of semantically well-defined feature. +\difficulty +Trivial: create an intermediary function such as +\tcode{mymain(argc, argv)}. +\howwide +Seldom. + +\diffref{basic.types} +\change +C allows mixing between ``compatible types'' in several places where \Cpp{} does not.\\ +For example, +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 +Deletion of semantically well-defined feature. +\difficulty +Semantic transformation. +The ``typesafe linkage'' mechanism will find many, but not all, +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} + +\diffref{conv.ptr} +\change +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]; +void* b=a; +void foo() { + char* c=b; +} +\end{codeblock} + +C accepts this usage of ``pointer to \keyword{void}'' being assigned +to a pointer to object type. +\Cpp{} does not. +\end{example} +\rationale +\Cpp{} tries harder than C to enforce compile-time type safety. +\effect +Deletion of semantically well-defined feature. +\difficulty +Can be automated. +Violations will be diagnosed by the \Cpp{} translator. +The fix is to add a cast. +\begin{example} +\begin{codeblock} +char* c = (char*) b; +\end{codeblock} +\end{example} + +\howwide +Common. + +\diffref{expr.arith.conv} +\change +Operations mixing a value of an enumeration type and a value of a different +enumeration type or of a floating-point type are not valid. +\begin{example} +\begin{codeblock} +enum E1 { e }; +enum E2 { f }; +int b = e <= 3.7; // valid in C; ill-formed in \Cpp{} +int k = f - e; // valid in C; ill-formed in \Cpp{} +int x = 1 ? e : f; // valid in C; ill-formed in \Cpp{} +\end{codeblock} +\end{example} +\rationale +Reinforcing type safety in \Cpp{}. +\effect +Well-formed C code will not compile with this International Standard. +\difficulty +Violations will be diagnosed by the \Cpp{} translator. +The original behavior can be restored with a cast or integral promotion. +\begin{example} +\begin{codeblock} +enum E1 { e }; +enum E2 { f }; +int b = (int)e <= 3.7; +int k = +f - e; +\end{codeblock} +\end{example} +\howwide +Uncommon. + +\diffref{expr.post.incr,expr.pre.incr} +\change +Decrement operator is not allowed with \keyword{bool} operand. +\rationale +Feature with surprising semantics. +\effect +A valid C expression utilizing the decrement operator on +a \keyword{bool} lvalue +(for instance, via the C typedef in \libheaderref{stdbool.h}) +is ill-formed in \Cpp{}. + +\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.\\ +In C, a \keyword{sizeof} expression or cast expression may define a new type. +\begin{example} +\begin{codeblock} +p = (void*)(struct x {int i;} *)0; +\end{codeblock} +defines a new type, struct \tcode{x}. +\end{example} +\rationale +This prohibition helps to clarify the location of +definitions in the source code. +\effect +Deletion of semantically well-defined feature. +\difficulty +Syntactic transformation. +\howwide +Seldom. + +\diffref{expr.rel,expr.eq} +\change +C allows directly comparing two objects of array type; \Cpp{} does not. +\rationale +The behavior is confusing because it compares not the contents of the two +arrays, but their addresses. +\effect +Deletion of semantically well-defined feature that had unspecified behavior +in common use cases. +\difficulty +Violations will be diagnosed by the \Cpp{} translator. The original behavior +can be replicated by explicitly casting either array to a pointer, such as by +using a unary \tcode{+}. +\begin{example} +\begin{codeblock} +int arr1[5]; +int arr2[5]; +int same = arr1 == arr2; // valid C, ill-formed \Cpp{} +int idem = arr1 == +arr2; // valid \Cpp{}, constraint violation in C +\end{codeblock} +\end{example} +\howwide +Rare. + +\diffref{expr.cond,expr.assign,expr.comma} +\indextext{conversion!lvalue-to-rvalue}% +\indextext{rvalue!lvalue conversion to}% +\indextext{lvalue}% +\change +The result of a conditional expression, an assignment expression, or a comma expression may be an lvalue. +\rationale +\Cpp{} is an object-oriented language, placing relatively +more emphasis on lvalues. For example, function calls may +yield lvalues. +\effect +Change to semantics of well-defined feature. Some C +expressions that implicitly rely on lvalue-to-rvalue +conversions will yield different results. +\begin{example} +\begin{codeblock} +char arr[100]; +sizeof(0, arr) +\end{codeblock} +yields +\tcode{100} +in \Cpp{} and +\tcode{sizeof(char*)} +in C. +\end{example} +\difficulty +Programs must add explicit casts to the appropriate rvalue. +\howwide +Rare. + +\rSec2[diff.stat]{\ref{stmt}: statements} + +\diffref{stmt.switch,stmt.goto} +\change +It is now invalid to jump past a declaration with explicit or implicit initializer (except across entire block not entered). +\rationale +Constructors used in initializers may allocate +resources which need to be de-allocated upon leaving the +block. +Allowing jump past initializers would require +complicated runtime determination of allocation. +Furthermore, many operations on such an uninitialized object +have undefined behavior. +With this simple compile-time rule, \Cpp{} assures that +if an initialized variable is in scope, then it has assuredly been +initialized. +\effect +Deletion of semantically well-defined feature. +\difficulty +Semantic transformation. +\howwide +Seldom. + +\diffref{stmt.return} +\change +It is now invalid to return (explicitly or implicitly) from a function which is +declared to return a value without actually returning a value. +\rationale +The caller and callee may assume fairly elaborate +return-value mechanisms for the return of class objects. +If +some flow paths execute a return without specifying any value, +the implementation must embody many more complications. +Besides, +promising to return a value of a given type, and then not returning +such a value, has always been recognized to be a questionable +practice, tolerated only because very-old C had no distinction between +functions with \keyword{void} and \keyword{int} return types. +\effect +Deletion of semantically well-defined feature. +\difficulty +Semantic transformation. +Add an appropriate return value to the source code, such as zero. +\howwide +Seldom. +For several years, many existing C implementations have produced warnings in +this case. + +\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 +In \Cpp{}, the \keyword{static} or \keyword{extern} specifiers can only be applied to names of objects or functions.\\ +Using these specifiers with type declarations is illegal in \Cpp{}. +In C, these specifiers are ignored when used on type declarations. + +\begin{example} +\begin{codeblock} +static struct S { // valid C, invalid in \Cpp{} + int i; +}; +\end{codeblock} +\end{example} + +\rationale +Storage class specifiers don't have any meaning when associated +with a type. +In \Cpp{}, class members can be declared with the \keyword{static} storage +class specifier. +Storage class specifiers on type +declarations can be confusing for users. +\effect +Deletion of semantically well-defined feature. +\difficulty +Syntactic transformation. +\howwide +Seldom. + +\diffref{dcl.stc} +\change +In \Cpp{}, \keyword{register} is not a storage class specifier. +\rationale +The storage class specifier had no effect in \Cpp{}. +\effect +Deletion of semantically well-defined feature. +\difficulty +Syntactic transformation. +\howwide +Common. + +\diffref{dcl.typedef} +\change +A \Cpp{} \grammarterm{typedef-name} must be different from any class type name declared +in the same scope (except if the typedef is a synonym of the class name with the +same name). In C, a \grammarterm{typedef-name} and a struct tag name declared in the same scope +can have the same name (because they have different name spaces). + +\begin{example} +\begin{codeblock} +typedef struct name1 { @\commentellip@ } name1; // valid C and \Cpp{} +struct name { @\commentellip@ }; +typedef int name; // valid C, invalid \Cpp{} +\end{codeblock} +\end{example} + +\rationale +For ease of use, \Cpp{} doesn't require that a type name be prefixed +with the keywords \keyword{class}, \keyword{struct} or \keyword{union} when used in object +declarations or type casts. + +\begin{example} +\begin{codeblock} +class name { @\commentellip@ }; +name i; // \tcode{i} has type \tcode{class name} +\end{codeblock} +\end{example} + +\effect +Deletion of semantically well-defined feature. +\difficulty +Semantic transformation. +One of the 2 types has to be renamed. +\howwide +Seldom. + +\diffref{dcl.type} [see also \ref{basic.link}] +\change +Const objects must be initialized in \Cpp{} but can be left uninitialized in C. +\rationale +A const object cannot be assigned to so it must be initialized +to hold a useful value. +\effect +Deletion of semantically well-defined feature. +\difficulty +Semantic transformation. +\howwide +Seldom. + +\diffref{dcl.spec.auto} +\change +The keyword \keyword{auto} cannot be used as a storage class specifier. + +\begin{example} +\begin{codeblock} +void f() { + auto int x; // valid C, invalid \Cpp{} +} +\end{codeblock} +\end{example} + +\rationale +Allowing the use of \keyword{auto} to deduce the type +of a variable from its initializer results in undesired interpretations of +\keyword{auto} as a storage class specifier in certain contexts. +\effect +Deletion of semantically well-defined feature. +\difficulty +Syntactic transformation. +\howwide +Rare. + +\diffref{dcl.fct} +\change +In \Cpp{}, a function declared with an empty parameter list takes no arguments. +In C, an empty parameter list means that the number and type of the function arguments are unknown. + +\begin{example} +\begin{codeblock} +int f(); // means \tcode{int f(void)} in \Cpp{} + // \tcode{int f(} unknown \tcode{)} in C +\end{codeblock} +\end{example} + +\rationale +This is to avoid function calls +with the wrong number or type of arguments. +\effect +Change to semantics of well-defined feature. +This feature was marked as ``obsolescent'' in C. +\difficulty +Syntactic transformation. +The function declarations using C incomplete declaration style must +be completed to become full prototype declarations. +A program may need to be updated further if different calls to the +same (non-prototype) function have different numbers of arguments or +if the type of corresponding arguments differed. +\howwide +Common. + +\diffref{dcl.fct} [see \ref{expr.sizeof}] +\change +In \Cpp{}, types may not be defined in return or parameter types. +In C, these type definitions are allowed. + +\begin{example} +\begin{codeblock} +void f( struct S { int a; } arg ) {} // valid C, invalid \Cpp{} +enum E { A, B, C } f() {} // valid C, invalid \Cpp{} +\end{codeblock} +\end{example} + +\rationale +When comparing types in different translation units, \Cpp{} relies +on name equivalence when C relies on structural equivalence. +Regarding parameter types: since the type defined in a parameter list +would be in the scope of the function, the only legal calls in \Cpp{} +would be from within the function itself. +\effect +Deletion of semantically well-defined feature. +\difficulty +Semantic transformation. +The type definitions must be moved to file scope, or in header files. +\howwide +Seldom. +This style of type definition is seen as poor coding style. + +\diffref{dcl.fct.def} +\change +In \Cpp{}, the syntax for function definition excludes the ``old-style'' C function. +In C, ``old-style'' syntax is allowed, but deprecated as ``obsolescent''. +\rationale +Prototypes are essential to type safety. +\effect +Deletion of semantically well-defined feature. +\difficulty +Syntactic transformation. +\howwide +Common in old programs, but already known to be obsolescent. + +\diffref{dcl.init.aggr} +\change +In \Cpp{}, designated initialization support is restricted +compared to the corresponding functionality in C\@. +In \Cpp{}, +designators for non-static data members +must be specified in declaration order, +designators for array elements and nested designators +are not supported, +and +designated and non-designated initializers +cannot be mixed in the same initializer list. + +\begin{example} +\begin{codeblock} +struct A { int x, y; }; +struct B { struct A a; }; +struct A a = {.y = 1, .x = 2}; // valid C, invalid \Cpp{} +int arr[3] = {[1] = 5}; // valid C, invalid \Cpp{} +struct B b = {.a.x = 0}; // valid C, invalid \Cpp{} +struct A c = {.x = 1, 2}; // valid C, invalid \Cpp{} +\end{codeblock} +\end{example} +\rationale +In \Cpp{}, members are destroyed in reverse construction order +and the elements of an initializer list are evaluated in lexical order, +so member initializers must be specified in order. +Array designators conflict with \grammarterm{lambda-expression} syntax. +Nested designators are seldom used. \effect -Valid \CppIII code that uses implementation-specific knowledge about the -binary representation of the required template specializations of -\tcode{std::complex} may not be compatible with this International Standard. +Deletion of feature that is incompatible with \Cpp{}. +\difficulty +Syntactic transformation. +\howwide +Out-of-order initializers are common. +The other features are seldom used. -\rSec2[diff.cpp03.input.output]{Clause \ref{input.output}: Input/output library} +\diffref{dcl.init.string} +\change +In \Cpp{}, when initializing an array of character with a string, the number of +characters in the string (including the terminating \tcode{'\textbackslash 0'}) must not exceed the +number of elements in the array. In C, an array can be initialized with a string even if +the array is not large enough to contain the string-terminating \tcode{'\textbackslash 0'}. -\ref{istream::sentry}, -\ref{ostream::sentry}, -\ref{iostate.flags} -\change Specify use of explicit in existing boolean conversion operators -\rationale Clarify intentions, avoid workarounds. +\begin{example} +\begin{codeblock} +char array[4] = "abcd"; // valid C, invalid \Cpp{} +\end{codeblock} +\end{example} +\rationale +When these non-terminated arrays are manipulated by standard +string functions, there is potential for major catastrophe. \effect -Valid \CppIII code that relies on implicit boolean conversions will fail to -compile with this International Standard. Such conversions occur in the -following conditions: +Deletion of semantically well-defined feature. +\difficulty +Semantic transformation. +The arrays must be declared one element bigger to contain the +string terminating \tcode{'\textbackslash 0'}. +\howwide +Seldom. +This style of array initialization is seen as poor coding style. -\begin{itemize} -\item passing a value to a function that takes an argument of type \tcode{bool}; -\item using \tcode{operator==} to compare to \tcode{false} or \tcode{true}; -\item returning a value from a function with a return type of \tcode{bool}; -\item initializing members of type \tcode{bool} via aggregate initialization; -\item initializing a \tcode{const bool\&} which would bind to a temporary. -\end{itemize} +\diffref{dcl.enum} +\change +\Cpp{} objects of enumeration type can only be assigned values of the same enumeration type. +In C, objects of enumeration type can be assigned values of any integral type. -\ref{ios::failure} -\change Change base class of \tcode{std::ios_base::failure} -\rationale More detailed error messages. -\effect -\tcode{std::ios_base::failure} is no longer derived directly from -\tcode{std::exception}, but is now derived from \tcode{std::system_error}, -which in turn is derived from \tcode{std::runtime_error}. Valid \CppIII code -that assumes that \tcode{std::ios_base::failure} is derived directly from -\tcode{std::exception} may execute differently in this International Standard. +\begin{example} +\begin{codeblock} +enum color { red, blue, green }; +enum color c = 1; // valid C, invalid \Cpp{} +\end{codeblock} +\end{example} -\ref{ios.base} -\change Flag types in \tcode{std::ios_base} are now bitmasks with values -defined as constexpr static members -\rationale Required for new features. +\rationale +The type-safe nature of \Cpp{}. \effect -Valid \CppIII code that relies on \tcode{std::ios_base} flag types being -represented as \tcode{std::bitset} or as an integer type may fail to compile -with this International Standard. For example: +Deletion of semantically well-defined feature. +\difficulty +Syntactic transformation. +(The type error produced by the assignment can be automatically +corrected by applying an explicit cast.) +\howwide +Common. -\begin{codeblock} -#include +\diffref{dcl.enum} +\change +In \Cpp{}, the type of an enumerator is its enumeration. In C, the type of an enumerator is an integer type. -int main() { - int flag = std::ios_base::hex; - std::cout.setf(flag); // error: \tcode{setf} does not take argument of type \tcode{int} - return 0; +\begin{example} +\begin{codeblock} +enum e { A }; +void f() { + auto x = A; + int *p = &x; // valid C, invalid \Cpp{} } \end{codeblock} +\end{example} -\rSec1[diff.cpp11]{\Cpp and ISO \CppXI} - -\pnum -\indextext{summary!compatibility~with ISO \CppXI}% -This subclause lists the differences between \Cpp and -ISO \CppXI (ISO/IEC 14882:2011, \doccite{Programming Languages --- \Cpp}), -by the chapters of this document. - -\rSec2[diff.cpp11.lex]{Clause \ref{lex}: lexical conventions} +\rationale +In \Cpp{}, an enumeration is a distinct type. +\effect +Change to semantics of well-defined feature. +\difficulty +Semantic transformation. +\howwide +Seldom. -\ref{lex.ppnumber} -\change \grammarterm{pp-number} can contain one or more single quotes. -\rationale Necessary to enable single quotes as digit separators. -\effect Valid \CppXI code may fail to compile or may change meaning in this -International Standard. For example, the following code is valid both in \CppXI and in -this International Standard, but the macro invocation produces different outcomes -because the single quotes delimit a character literal in \CppXI, whereas they are digit -separators in this International Standard: +\diffref{dcl.align} +\change +In \Cpp{}, +an \grammarterm{alignment-specifier} is an \grammarterm{attribute-specifier}. +In C, an \grammarterm{alignment-specifier} is a \gterm{declaration-specifier}. +\begin{example} \begin{codeblock} -#define M(x, ...) __VA_ARGS__ -int x[2] = { M(1'2,3'4) }; -// \tcode{int x[2] = \{\};\ \ \ \ \ } --- \CppXI -// \tcode{int x[2] = \{ 3'4 \};} --- this International Standard +#include +unsigned alignas(8) int x; // valid C, invalid \Cpp{} +unsigned int y alignas(8); // valid \Cpp{}, invalid C \end{codeblock} +\end{example} + +\rationale +\Cpp{} requires unambiguous placement of the \grammarterm{alignment-specifier}. +\effect +Deletion of semantically well-defined feature. +\difficulty +Syntactic transformation. +\howwide +Seldom. -\rSec2[diff.cpp11.basic]{Clause \ref{basic}: basic concepts} +\rSec2[diff.class]{\ref{class}: classes} -\ref{basic.stc.dynamic.deallocation} -\change New usual (non-placement) deallocator -\rationale Required for sized deallocation. -\effect Valid \CppXI code could declare a global placement allocation function and -deallocation function as follows: +\diffref{class.name} [see also \ref{dcl.typedef}] +\change +In \Cpp{}, a class declaration introduces the class name into the scope where it is +declared and hides any object, function or other declaration of that name in an enclosing +scope. In C, an inner scope declaration of a struct tag name never hides the name of an +object or function in an outer scope. +\begin{example} \begin{codeblock} -void operator new(std::size_t, std::size_t); -void operator delete(void*, std::size_t) noexcept; +int x[99]; +void f() { + struct x { int a; }; + sizeof(x); /* size of the array in C */ + /* size of the struct in @\textit{\textrm{\Cpp{}}}@ */ +} \end{codeblock} +\end{example} +\rationale +This is one of the few incompatibilities between C and \Cpp{} that +can be attributed to the new \Cpp{} name space definition where a +name can be declared as a type and as a non-type in a single scope +causing the non-type name to hide the type name and requiring that +the keywords \keyword{class}, \keyword{struct}, \keyword{union} or \keyword{enum} be used to refer to the type name. +This new name space definition provides important notational +conveniences to \Cpp{} programmers and helps making the use of the +user-defined types as similar as possible to the use of fundamental +types. +The advantages of the new name space definition were judged to +outweigh by far the incompatibility with C described above. +\effect +Change to semantics of well-defined feature. +\difficulty +Semantic transformation. +If the hidden name that needs to be accessed is at global scope, +the \tcode{::} \Cpp{} operator can be used. +If the hidden name is at block scope, either the type or the struct +tag has to be renamed. +\howwide +Seldom. -In this International Standard, however, the declaration of \tcode{operator delete} -might match a predefined usual (non-placement) -\tcode{operator delete}~(\ref{basic.stc.dynamic}). If so, the -program is ill-formed, as it was for class member allocation functions and -deallocation functions~(\ref{expr.new}). +\diffref{class.copy.ctor} +\change +Copying volatile objects. -\rSec2[diff.cpp11.dcl.dcl]{Clause \ref{dcl.dcl}: declarations} +The implicitly-declared copy constructor and +implicitly-declared copy assignment operator +cannot make a copy of a volatile lvalue. +\begin{example} +The following is valid in C: +\begin{codeblock} +struct X { int i; }; +volatile struct X x1 = {0}; +struct X x2 = x1; // invalid \Cpp{} +struct X x3; +x3 = x1; // also invalid \Cpp{} +\end{codeblock} +\end{example} -\ref{dcl.constexpr} -\change \tcode{constexpr} non-static member functions are not implicitly -\tcode{const} member functions. -\rationale Necessary to allow \tcode{constexpr} member functions to mutate -the object. +\rationale +Several alternatives were debated at length. +Changing the parameter to +\keyword{volatile} +\keyword{const} +\tcode{X\&} +would greatly complicate the generation of +efficient code for class objects. +Discussion of +providing two alternative signatures for these +implicitly-defined operations raised +unanswered concerns about creating +ambiguities and complicating +the rules that specify the formation of +these operators according to the bases and +members. +\effect +Deletion of semantically well-defined feature. +\difficulty +Semantic transformation. +If volatile semantics are required for the copy, +a user-declared constructor or assignment must +be provided. +If non-volatile semantics are required, +an explicit +\keyword{const_cast} +can be used. +\howwide +Seldom. + +\diffref{class.bit} +\change +\indextext{bit-field!implementation-defined sign of}% +Bit-fields of type plain \keyword{int} are signed. +\rationale +The signedness needs to be consistent among template specializations. +For consistency, +the implementation freedom was eliminated for non-dependent types, +too. \effect -Valid \CppXI code may fail to compile in this International Standard. -For example, the following code is valid in \CppXI -but invalid in this International Standard because it declares the same member -function twice with different return types: +The choice is implementation-defined in C, but not so in \Cpp{}. +\difficulty +Syntactic transformation. +\howwide +Seldom. + +\diffref{class.nest} +\change +In \Cpp{}, the name of a nested class is local to its enclosing class. In C +the name of the nested class belongs to the same scope as the name of the outermost enclosing class. +\begin{example} \begin{codeblock} -struct S { - constexpr const int &f(); - int &f(); +struct X { + struct Y { @\commentellip@ } y; }; +struct Y yy; // valid C, invalid \Cpp{} \end{codeblock} - -\rSec2[diff.cpp11.input.output]{Clause \ref{input.output}: input/output library} - -\ref{c.files} -\change \tcode{gets} is not defined. -\rationale Use of \tcode{gets} is considered dangerous. +\end{example} +\rationale +\Cpp{} classes have member functions which require that classes +establish scopes. +The C rule would leave classes as an incomplete scope mechanism +which would prevent \Cpp{} programmers from maintaining locality +within a class. +A coherent set of scope rules for \Cpp{} based on the C rule would +be very complicated and \Cpp{} programmers would be unable to predict +reliably the meanings of nontrivial examples involving nested or +local functions. \effect -Valid \CppXI code that uses the \tcode{gets} function may fail to compile -in this International Standard. - -\rSec1[diff.cpp14]{\Cpp and ISO \CppXIV} +Change to semantics of well-defined feature. +\difficulty +Semantic transformation. +To make the struct type name visible in the scope of the enclosing +struct, the struct tag can be declared in the scope of the +enclosing struct, before the enclosing struct is defined. +\begin{example} +\begin{codeblock} +struct Y; // \tcode{struct Y} and \tcode{struct X} are at the same scope +struct X { + struct Y { @\commentellip@ } y; +}; +\end{codeblock} +\end{example} -\pnum -\indextext{summary!compatibility~with ISO \CppXIV}% -This subclause lists the differences between \Cpp and -ISO \CppXIV (ISO/IEC 14882:2014, \doccite{Programming Languages --- \Cpp}), -by the chapters of this document. +All the definitions of C struct types enclosed in other struct +definitions and accessed outside the scope of the enclosing +struct can be exported to the scope of the enclosing struct. +Note: this is a consequence of the difference in scope rules, +which is documented in \ref{basic.scope}. +\howwide +Seldom. -\rSec2[diff.cpp14.lex]{Clause \ref{lex}: lexical conventions} +\diffref{class.member.lookup} +\change +In \Cpp{}, a \grammarterm{typedef-name} may not be redeclared in a class definition after being used in that definition. -\ref{lex.phases} -\indextext{trigraph sequence}% -\change Removal of trigraph support as a required feature. -\rationale Prevents accidental uses of trigraphs in non-raw string literals and comments. +\begin{example} +\begin{codeblock} +typedef int I; +struct S { + I i; + int I; // valid C, invalid \Cpp{} +}; +\end{codeblock} +\end{example} +\rationale +When classes become complicated, allowing such a redefinition +after the type has been used can create confusion for \Cpp{} +programmers as to what the meaning of \tcode{I} really is. \effect -Valid \CppXIV code that uses trigraphs may not be valid or may have different -semantics in this International Standard. Implementations may choose to -translate trigraphs as specified in \CppXIV if they appear outside of a raw -string literal, as part of the implementation-defined mapping from physical -source file characters to the basic source character set. +Deletion of semantically well-defined feature. +\difficulty +Semantic transformation. +Either the type or the struct member has to be renamed. +\howwide +Seldom. -\rSec2[diff.cpp14.depr]{Annex D: compatibility features} +\rSec2[diff.cpp]{\ref{cpp}: preprocessing directives} +\diffref{cpp.predefined} \change -The class templates -\tcode{auto_ptr}, -\tcode{unary_function}, and -\tcode{binary_function}, -the function templates -\tcode{random_shuffle}, -and the function templates (and their return types) -\tcode{ptr_fun}, -\tcode{mem_fun}, -\tcode{mem_fun_ref}, -\tcode{bind1st}, and -\tcode{bind2nd} -are not defined. -\rationale Superseded by new features. -\effect Valid \CppXIV code that uses these class templates -and function templates may fail to compile in this International Standard. - +Whether \mname{STDC} is defined and if so, what its value is, are +\impldef{definition and meaning of \mname{STDC}}. +\rationale +\Cpp{} is not identical to C\@. +Mandating that \mname{STDC} +be defined would require that translators make an incorrect claim. +\effect +Change to semantics of well-defined feature. +\difficulty +Semantic transformation. +\howwide +Programs and headers that reference \mname{STDC} are +quite common. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \rSec1[diff.library]{C standard library} -\indextext{library!C standard}% - -\pnum -This subclause summarizes the contents of the \Cpp standard library -included from the Standard C library. -It also summarizes the explicit changes in definitions, -declarations, or behavior from the Standard C library -noted in other subclauses (\ref{headers}, \ref{support.types}, \ref{c.strings}). - -\pnum -The \Cpp standard library provides 57 standard macros from the C library, -as shown in Table~\ref{tab:diff.standard.macros}. -\pnum -The header names (enclosed in -\tcode{<} -and -\tcode{>}) -indicate that the macro may be defined in more than one header. -All such definitions are equivalent (\ref{basic.def.odr}). - -\begin{floattable}{Standard macros}{tab:diff.standard.macros} -{lllll} -\hline - -\tcode{assert} & -\tcode{HUGE_VAL} & -\tcode{NULL } & -\tcode{SIGINT} & -\tcode{va_end} \\ - -\tcode{BUFSIZ} & -\tcode{LC_ALL} & -\tcode{NULL } & -\tcode{SIGSEGV} & -\tcode{va_start} \\ - -\tcode{CLOCKS_PER_SEC} & -\tcode{LC_COLLATE} & -\tcode{NULL } & -\tcode{SIGTERM} & -\tcode{WCHAR_MAX} \\ - -\tcode{EDOM} & -\tcode{LC_CTYPE} & -\tcode{offsetof} & -\tcode{SIG_DFL} & -\tcode{WCHAR_MIN} \\ - -\tcode{EILSEQ} & -\tcode{LC_MONETARY} & -\tcode{RAND_MAX} & -\tcode{SIG_ERR} & -\tcode{WEOF } \\ - -\tcode{EOF} & -\tcode{LC_NUMERIC} & -\tcode{SEEK_CUR} & -\tcode{SIG_IGN} & -\tcode{WEOF } \\ - -\tcode{ERANGE} & -\tcode{LC_TIME} & -\tcode{SEEK_END} & -\tcode{stderr} & -\tcode{_IOFBF} \\ - -\tcode{errno} & -\tcode{L_tmpnam} & -\tcode{SEEK_SET} & -\tcode{stdin} & -\tcode{_IOLBF} \\ - -\tcode{EXIT_FAILURE} & -\tcode{MB_CUR_MAX} & -\tcode{setjmp} & -\tcode{stdout} & -\tcode{_IONBF} \\ - -\tcode{EXIT_SUCCESS} & -\tcode{NULL } & -\tcode{SIGABRT} & -\tcode{TMP_MAX} & \\ - -\tcode{FILENAME_MAX} & -\tcode{NULL } & -\tcode{SIGFPE} & -\tcode{va_arg} & \\ - -\tcode{FOPEN_MAX} & -\tcode{NULL } & -\tcode{SIGILL} & -\tcode{va_copy} & \\ - - -\end{floattable} - -\pnum -The \Cpp standard library provides 57 standard values from the C library, -as shown in Table~\ref{tab:diff.standard.values}. - -\begin{floattable}{Standard values}{tab:diff.standard.values} -{llll} -\hline -\tcode{CHAR_BIT} & - \tcode{FLT_DIG} & - \tcode{INT_MIN} & - \tcode{MB_LEN_MAX} \\ -\tcode{CHAR_MAX} & - \tcode{FLT_EPSILON} & - \tcode{LDBL_DIG} & - \tcode{SCHAR_MAX} \\ -\tcode{CHAR_MIN} & - \tcode{FLT_MANT_DIG} & - \tcode{LDBL_EPSILON} & - \tcode{SCHAR_MIN} \\ -\tcode{DBL_DIG} & - \tcode{FLT_MAX} & - \tcode{LDBL_MANT_DIG} & - \tcode{SHRT_MAX} \\ -\tcode{DBL_EPSILON} & - \tcode{FLT_MAX_10_EXP} & - \tcode{LDBL_MAX} & - \tcode{SHRT_MIN} \\ -\tcode{DBL_MANT_DIG} & - \tcode{FLT_MAX_EXP} & - \tcode{LDBL_MAX_10_EXP} & - \tcode{UCHAR_MAX} \\ -\tcode{DBL_MAX} & - \tcode{FLT_MIN} & - \tcode{LDBL_MAX_EXP} & - \tcode{UINT_MAX} \\ -\tcode{DBL_MAX_10_EXP} & - \tcode{FLT_MIN_10_EXP} & - \tcode{LDBL_MIN} & - \tcode{ULONG_MAX} \\ -\tcode{DBL_MAX_EXP} & - \tcode{FLT_MIN_EXP} & - \tcode{LDBL_MIN_10_EXP}& - \tcode{USHRT_MAX} \\ -\tcode{DBL_MIN} & - \tcode{FLT_RADIX} & - \tcode{LDBL_MIN_EXP} & \\ -\tcode{DBL_MIN_10_EXP} & - \tcode{FLT_ROUNDS} & - \tcode{LONG_MAX} & \\ -\tcode{DBL_MIN_EXP} & - \tcode{INT_MAX} & - \tcode{LONG_MIN} & \\ \hline -\end{floattable} +\rSec2[diff.library.general]{General} +\indextext{library!C standard}% \pnum -The \Cpp standard library provides 20 standard types from the C library, -as shown in Table~\ref{tab:diff.standard.types}. - -\begin{floattable}{Standard types}{tab:diff.standard.types} -{llll} -\hline -\tcode{clock_t} & - \tcode{ldiv_t} & - \tcode{size_t } & - \tcode{va_list} \\ -\tcode{div_t} & - \tcode{mbstate_t} & - \tcode{size_t } & - \tcode{wctrans_t} \\ -\tcode{FILE} & - \tcode{ptrdiff_t} & - \tcode{size_t } & - \tcode{wctype_t} \\ -\tcode{fpos_t} & - \tcode{sig_atomic_t} & - \tcode{size_t } & - \tcode{wint_t } \\ -\tcode{jmp_buf} & - \tcode{size_t } & - \tcode{time_t} & - \tcode{wint_t } \\ \hline -\end{floattable} +Subclause \ref{diff.library} summarizes the explicit changes in headers, +definitions, declarations, or behavior between the C standard library +in the C standard and the parts of the \Cpp{} standard library that were +included from the C standard library. +\rSec2[diff.mods.to.headers]{Modifications to headers} \pnum -The \Cpp standard library provides 2 standard -\tcode{struct}s -from the C library, -as shown in Table~\ref{tab:diff.standard.structs}. - -\begin{floattable}{Standard structs}{tab:diff.standard.structs} -{ll} -\hline -\tcode{lconv} & \tcode{tm} \\ \hline -\end{floattable} +For compatibility with the C standard library\indextext{library!C standard}, +the \Cpp{} standard library provides the C headers enumerated +in~\ref{support.c.headers}. \pnum -The \Cpp standard library provides 209 standard functions from the C library, -as shown in Table~\ref{tab:diff.standard.functions}. - -\begin{floattable}{Standard functions}{tab:diff.standard.functions} -{llllll} -\hline -\tcode{abort} & -\tcode{fmod} & -\tcode{iswalnum} & -\tcode{modf} & -\tcode{strlen} & -\tcode{wcscat} \\ -\tcode{abs} & -\tcode{fopen} & -\tcode{iswalpha} & -\tcode{perror} & -\tcode{strncat} & -\tcode{wcschr} \\ -\tcode{acos} & -\tcode{fprintf} & -\tcode{iswcntrl} & -\tcode{pow} & -\tcode{strncmp} & -\tcode{wcscmp} \\ -\tcode{asctime} & -\tcode{fputc} & -\tcode{iswctype} & -\tcode{printf} & -\tcode{strncpy} & -\tcode{wcscoll} \\ -\tcode{asin} & -\tcode{fputs} & -\tcode{iswdigit} & -\tcode{putc} & -\tcode{strpbrk} & -\tcode{wcscpy} \\ -\tcode{atan} & -\tcode{fputwc} & -\tcode{iswgraph} & -\tcode{putchar} & -\tcode{strrchr} & -\tcode{wcscspn} \\ -\tcode{atan2} & -\tcode{fputws} & -\tcode{iswlower} & -\tcode{puts} & -\tcode{strspn} & -\tcode{wcsftime} \\ -\tcode{atexit} & -\tcode{fread} & -\tcode{iswprint} & -\tcode{putwc} & -\tcode{strstr} & -\tcode{wcslen} \\ -\tcode{atof} & -\tcode{free} & -\tcode{iswpunct} & -\tcode{putwchar} & -\tcode{strtod} & -\tcode{wcsncat} \\ -\tcode{atoi} & -\tcode{freopen} & -\tcode{iswspace} & -\tcode{qsort} & -\tcode{strtok} & -\tcode{wcsncmp} \\ -\tcode{atol} & -\tcode{frexp} & -\tcode{iswupper} & -\tcode{raise} & -\tcode{strtol} & -\tcode{wcsncpy} \\ -\tcode{bsearch} & -\tcode{fscanf} & -\tcode{iswxdigit} & -\tcode{rand} & -\tcode{strtoul} & -\tcode{wcspbrk} \\ -\tcode{btowc} & -\tcode{fseek} & -\tcode{isxdigit} & -\tcode{realloc} & -\tcode{strxfrm} & -\tcode{wcsrchr} \\ -\tcode{calloc} & -\tcode{fsetpos} & -\tcode{labs} & -\tcode{remove} & -\tcode{swprintf} & -\tcode{wcsrtombs} \\ -\tcode{ceil} & -\tcode{ftell} & -\tcode{ldexp} & -\tcode{rename} & -\tcode{swscanf} & -\tcode{wcsspn} \\ -\tcode{clearerr} & -\tcode{fwide} & -\tcode{ldiv} & -\tcode{rewind} & -\tcode{system} & -\tcode{wcsstr} \\ -\tcode{clock} & -\tcode{fwprintf} & -\tcode{localeconv} & -\tcode{scanf} & -\tcode{tan} & -\tcode{wcstod} \\ -\tcode{cos} & -\tcode{fwrite} & -\tcode{localtime} & -\tcode{setbuf} & -\tcode{tanh} & -\tcode{wcstok} \\ -\tcode{cosh} & -\tcode{fwscanf} & -\tcode{log} & -\tcode{setlocale} & -\tcode{time} & -\tcode{wcstol} \\ -\tcode{ctime} & -\tcode{getc} & -\tcode{log10} & -\tcode{setvbuf} & -\tcode{tmpfile} & -\tcode{wcstombs} \\ -\tcode{difftime} & -\tcode{getchar} & -\tcode{longjmp} & -\tcode{signal} & -\tcode{tmpnam} & -\tcode{wcstoul} \\ -\tcode{div} & -\tcode{getenv} & -\tcode{malloc} & -\tcode{sin} & -\tcode{tolower} & -\tcode{wcsxfrm} \\ -\tcode{exit} & -\tcode{getwc} & -\tcode{mblen} & -\tcode{sinh} & -\tcode{toupper} & -\tcode{wctob} \\ -\tcode{exp} & -\tcode{getwchar} & -\tcode{mbrlen} & -\tcode{sprintf} & -\tcode{towctrans} & -\tcode{wctomb} \\ -\tcode{fabs} & -\tcode{gmtime} & -\tcode{mbrtowc} & -\tcode{sqrt} & -\tcode{towlower} & -\tcode{wctrans} \\ -\tcode{fclose} & -\tcode{isalnum} & -\tcode{mbsinit} & -\tcode{srand} & -\tcode{towupper} & -\tcode{wctype} \\ -\tcode{feof} & -\tcode{isalpha} & -\tcode{mbsrtowcs} & -\tcode{sscanf} & -\tcode{ungetc} & -\tcode{wmemchr} \\ -\tcode{ferror} & -\tcode{iscntrl} & -\tcode{mbstowcs} & -\tcode{strcat} & -\tcode{ungetwc} & -\tcode{wmemcmp} \\ -\tcode{fflush} & -\tcode{isdigit} & -\tcode{mbtowc} & -\tcode{strchr} & -\tcode{vfprintf} & -\tcode{wmemcpy} \\ -\tcode{fgetc} & -\tcode{isgraph} & -\tcode{memchr} & -\tcode{strcmp} & -\tcode{vfwprintf} & -\tcode{wmemmove} \\ -\tcode{fgetpos} & -\tcode{islower} & -\tcode{memcmp} & -\tcode{strcoll} & -\tcode{vprintf} & -\tcode{wmemset} \\ -\tcode{fgets} & -\tcode{isprint} & -\tcode{memcpy} & -\tcode{strcpy} & -\tcode{vsprintf} & -\tcode{wprintf} \\ -\tcode{fgetwc} & -\tcode{ispunct} & -\tcode{memmove} & -\tcode{strcspn} & -\tcode{vswprintf} & -\tcode{wscanf} \\ -\tcode{fgetws} & -\tcode{isspace} & -\tcode{memset} & -\tcode{strerror} & -\tcode{vwprintf} &\\ -\tcode{floor} & -\tcode{isupper} & -\tcode{mktime} & -\tcode{strftime} & -\tcode{wcrtomb} &\\ \hline -\end{floattable} - -\rSec2[diff.mods.to.headers]{Modifications to headers} +There are no \Cpp{} headers for the C standard library's headers +\libnoheader{stdnoreturn.h} and \libnoheader{threads.h}, +nor are these headers from the C standard library headers themselves part of \Cpp{}. \pnum -For compatibility with the Standard C library, -\indextext{library!C standard}% -the \Cpp standard library provides the C headers enumerated -in~\ref{depr.c.headers}, but their use is deprecated in \Cpp. +The C headers \libheader{complex.h} and +\libheader{tgmath.h} do not contain any of the content from +the C standard library and instead merely include other headers from the \Cpp{} +standard library. \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 \tcode{char16_t} and \tcode{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{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}. \rSec3[diff.wchar.t]{Type \tcode{wchar_t}} \pnum -\tcode{wchar_t} -is a keyword in this International Standard (\ref{lex.key}). -It does not appear as a type name defined in any of -\tcode{}, -\indexlibrary{\idxhdr{cstddef}}% -\tcode{}, -\indexlibrary{\idxhdr{cstdlib}}% -or -\tcode{} -\indexlibrary{\idxhdr{cwchar}}% -(\ref{c.strings}). +The type \keyword{wchar_t} is a distinct type rather than a typedef to an +existing integral type. +The token \keyword{wchar_t} +is a keyword in \Cpp{}\iref{lex.key}. +It does not appear as a macro or type name defined in any of +\libheaderref{cstddef}, +\libheaderref{cstdlib}, +or \libheaderref{cwchar}. \rSec3[diff.header.iso646.h]{Header \tcode{}} -\indexlibrary{\idxhdr{iso646.h}}% \pnum The tokens -\tcode{and}, -\tcode{and_eq}, -\tcode{bitand}, -\tcode{bitor}, -\tcode{compl}, -\tcode{not_eq}, -\tcode{not}, -\tcode{or}, -\tcode{or_eq}, -\tcode{xor}, +\keyword{and}, +\keyword{and_eq}, +\keyword{bitand}, +\keyword{bitor}, +\keyword{compl}, +\keyword{not}, +\keyword{not_eq}, +\keyword{or}, +\keyword{or_eq}, +\keyword{xor}, and -\tcode{xor_eq} -are keywords in this International -Standard (\ref{lex.key}). -They do not appear as macro names defined in -\tcode{}. -\indexlibrary{\idxhdr{ciso646}}% +\keyword{xor_eq} +are keywords in \Cpp{}\iref{lex.key}, +and are not introduced as macros +by \libheaderref{iso646.h}. \rSec3[diff.null]{Macro \tcode{NULL}} @@ -1889,97 +3758,95 @@ The macro \tcode{NULL}, defined in any of -\indexlibrary{\idxhdr{clocale}}% -\tcode{}, -\indexlibrary{\idxhdr{cstddef}}% -\tcode{}, -\indexlibrary{\idxhdr{cstdio}}% -\tcode{}, -\indexlibrary{\idxhdr{cstdlib}}% -\tcode{}, -\indexlibrary{\idxhdr{cstring}}% -\tcode{}, -\indexlibrary{\idxhdr{ctime}}% -\tcode{}, -or -\tcode{}, -\indexlibrary{\idxhdr{cwchar}}% -is an implementation-defined \Cpp null pointer constant in -\indextext{implementation-defined}% -this International Standard (\ref{support.types}). +\libheaderref{clocale}, +\libheaderref{cstddef}, +\libheaderref{cstdio}, +\libheaderref{cstdlib}, +\libheaderref{cstring}, +\libheaderref{ctime}, +or \libheaderref{cwchar}, +is an \impldef{definition of \tcode{NULL}} null pointer constant in +\Cpp{}\iref{support.types}. \rSec2[diff.mods.to.declarations]{Modifications to declarations} \pnum -Header -\tcode{}: -\indexlibrary{\idxhdr{cstring}}% +Header \libheaderref{cstring}: The following functions have different declarations: + \begin{itemize} -\item -\tcode{strchr} -\item -\tcode{strpbrk} -\item -\tcode{strrchr} -\item -\tcode{strstr} -\item -\tcode{memchr} +\item \tcode{strchr} +\item \tcode{strpbrk} +\item \tcode{strrchr} +\item \tcode{strstr} +\item \tcode{memchr} \end{itemize} -\ref{c.strings} describes the changes. +Subclause \ref{cstring.syn} describes the changes. + +\pnum +Header \libheaderref{cwchar}: +The following functions have different declarations: + +\begin{itemize} +\item \tcode{wcschr} +\item \tcode{wcspbrk} +\item \tcode{wcsrchr} +\item \tcode{wcsstr} +\item \tcode{wmemchr} +\end{itemize} + +Subclause \ref{cwchar.syn} describes the changes. + +\pnum +Header \libheaderref{cstddef} +declares the names \tcode{nullptr_t}, \tcode{byte}, and \tcode{to_integer}, +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. \rSec2[diff.mods.to.behavior]{Modifications to behavior} +\rSec3[diff.mods.to.behavior.general]{General} + \pnum -Header -\tcode{}: +Header \libheaderref{cstdlib}: The following functions have different behavior: + \begin{itemize} -\item -\tcode{atexit} -\item -\tcode{exit} -\item -\tcode{abort} +\item \tcode{atexit} +\item \tcode{exit} +\item \tcode{abort} \end{itemize} -\ref{support.start.term} describes the changes. +Subclause \ref{support.start.term} describes the changes. \pnum -Header -\tcode{}: +Header \libheaderref{csetjmp}: The following functions have different behavior: \begin{itemize} -\item -\tcode{longjmp} +\item \tcode{longjmp} \end{itemize} -\ref{support.runtime} describes the changes. +Subclause \ref{csetjmp.syn} describes the changes. -\rSec3[diff.offsetof]{Macro \tcode{offsetof(type, member-designator)}} -\indexlibrary{\idxcode{offsetof}}% +\rSec3[diff.offsetof]{Macro \tcode{offsetof(\placeholder{type}, \placeholder{member-designator})}} +\indexlibraryglobal{offsetof}% \pnum -The macro -\tcode{offsetof}, -defined in -\indexlibrary{\idxhdr{cstddef}}% -\tcode{}, -accepts a restricted set of \tcode{type} arguments in this International Standard. -\ref{support.types} describes the change. +The macro \tcode{offsetof}, defined in +\libheaderref{cstddef}, +accepts a restricted set of \tcode{\placeholder{type}} arguments in \Cpp{}. +Subclause \ref{support.types.layout} describes the change. \rSec3[diff.malloc]{Memory allocation functions} \pnum The functions -\indexlibrary{\idxcode{calloc}}% -\tcode{calloc}, -\indexlibrary{\idxcode{malloc}}% -\tcode{malloc}, +\indexlibraryglobal{aligned_alloc}\tcode{aligned_alloc}, +\indexlibraryglobal{calloc}\tcode{calloc}, +\indexlibraryglobal{malloc}\tcode{malloc}, and -\indexlibrary{\idxcode{realloc}}% -\tcode{realloc} -are restricted in this International Standard. -\ref{c.malloc} describes the changes. +\indexlibraryglobal{realloc}\tcode{realloc} +are restricted in \Cpp{}. +Subclause \ref{c.malloc} describes the changes. diff --git a/source/concepts.tex b/source/concepts.tex new file mode 100644 index 0000000000..d1e15a6e1a --- /dev/null +++ b/source/concepts.tex @@ -0,0 +1,1370 @@ +%!TEX root = std.tex +\rSec0[concepts]{Concepts library} + +\rSec1[concepts.general]{General} + +\pnum +This Clause describes library components that \Cpp{} programs may use to perform +compile-time validation of template arguments and perform function dispatch +based on properties of types. The purpose of these concepts is to establish +a foundation for equational reasoning in programs. + +\pnum +The following subclauses describe language-related concepts, comparison +concepts, object concepts, and callable concepts as summarized in +\tref{concepts.summary}. + +\begin{libsumtab}{Fundamental concepts library summary}{concepts.summary} +\ref{concepts.equality} & Equality preservation & \\ \hline +\ref{concepts.lang} & Language-related concepts & \tcode{} \\ +\ref{concepts.compare} & Comparison concepts & \\ +\ref{concepts.object} & Object concepts & \\ +\ref{concepts.callable} & Callable concepts & \\ +\end{libsumtab} + +\rSec1[concepts.equality]{Equality preservation} + +\pnum +An expression is \defnx{equality-preserving}{expression!equality-preserving} if, +given equal inputs, the expression results in equal outputs. The inputs to an +expression are the set of the expression's operands. The output of an expression +is the expression's result and all operands modified by the expression. +For the purposes of this subclause, +the operands of an expression are the largest subexpressions that include only: +\begin{itemize} +\item +an \grammarterm{id-expression}\iref{expr.prim.id}, and +\item +invocations of the library function templates +\tcode{std::move}, +\tcode{std::forward}, and +\tcode{std::declval}\iref{forward,declval}. +\end{itemize} +\begin{example} +The operands of the expression \tcode{a = std::move(b)} are +\tcode{a} and \tcode{std::move(b)}. +\end{example} + +\pnum +Not all input values need be valid for a given expression. +\begin{example} +For integers \tcode{a} and \tcode{b}, +the expression \tcode{a / b} is not well-defined +when \tcode{b} is \tcode{0}. +This does not preclude the expression \tcode{a / b} being equality-preserving. +\end{example} +The \defnx{domain}{expression!domain} of an expression is the set of +input values for which the expression is required to be well-defined. + +\pnum +Expressions required to be equality-preserving are further +required to be stable: two evaluations of such an expression with the same input +objects are required to have equal outputs absent any explicit intervening +modification of those input objects. +\begin{note} +This requirement allows generic code to reason about the current values of +objects based on knowledge of the prior values as observed via +equality-preserving expressions. It effectively forbids spontaneous changes to +an object, changes to an object from another thread of execution, changes to an +object as side effects of non-modifying expressions, and changes to an object as +side effects of modifying a distinct object if those changes could be observable +to a library function via an equality-preserving expression that is required to +be valid for that object. +\end{note} + +\pnum +Expressions declared in a \grammarterm{requires-expression} in the library clauses are +required to be equality-preserving, except for those annotated with the comment +``not required to be equality-preserving.'' An expression so annotated +may be equality-preserving, but is not required to be so. + +\pnum +An expression that may alter the value of one or more of its inputs in a manner +observable to equality-preserving expressions is said to modify those inputs. +The library clauses use a notational convention to specify which expressions declared +in a \grammarterm{requires-expression} modify which inputs: except where +otherwise specified, an expression operand that is a non-constant lvalue or +rvalue may be modified. Operands that are constant lvalues or rvalues are +required to not be modified. +For the purposes of this subclause, +the cv-qualification and value category of each operand +are determined by assuming +that each template type parameter +denotes a cv-unqualified complete non-array object type. + +\pnum +Where a \grammarterm{requires-expression} declares an expression that is +non-modifying for some constant lvalue operand, additional variations of that +expression that accept a non-constant lvalue or (possibly constant) rvalue for +the given operand are also required except where such an expression variation is +explicitly required with differing semantics. These +\term{implicit expression variations} are required to meet the semantic +requirements of the declared expression. The extent to which an implementation +validates the syntax of the variations is unspecified. + +\pnum +\begin{example} +\begin{codeblock} +template concept C = requires(T a, T b, const T c, const T d) { + c == d; // \#1 + a = std::move(b); // \#2 + a = c; // \#3 +}; +\end{codeblock} + +For the above example: +\begin{itemize} +\item +Expression \#1 does not modify either of its operands, \#2 modifies both of its +operands, and \#3 modifies only its first operand \tcode{a}. + +\item +Expression \#1 implicitly requires additional expression variations that meet +the requirements for \tcode{c == d} (including non-modification), as if the +expressions +\begin{codeblock} + c == b; + c == std::move(d); c == std::move(b); +std::move(c) == d; std::move(c) == b; +std::move(c) == std::move(d); std::move(c) == std::move(b); + + a == d; a == b; + a == std::move(d); a == std::move(b); +std::move(a) == d; std::move(a) == b; +std::move(a) == std::move(d); std::move(a) == std::move(b); +\end{codeblock} +had been declared as well. + +\item +Expression \#3 implicitly requires additional expression variations that meet +the requirements for \tcode{a = c} (including non-modification of the second +operand), as if the expressions \tcode{a = b} and \tcode{a = std::move(c)} had +been declared. Expression \#3 does not implicitly require an expression +variation with a non-constant rvalue second operand, since expression \#2 +already specifies exactly such an expression explicitly. +\end{itemize} +\end{example} + +\pnum +\begin{example} +The following type \tcode{T} meets the explicitly stated syntactic requirements +of concept \tcode{C} above but does not meet the additional implicit +requirements: + +\begin{codeblock} +struct T { + bool operator==(const T&) const { return true; } + bool operator==(T&) = delete; +}; +\end{codeblock} + +\tcode{T} fails to meet the implicit requirements of \tcode{C}, +so \tcode{T} satisfies but does not model \tcode{C}. +Since implementations are not required to validate the syntax +of implicit requirements, it is unspecified whether an implementation diagnoses +as ill-formed a program that requires \tcode{C}. +\end{example} + +\rSec1[concepts.syn]{Header \tcode{} synopsis} + +\indexheader{concepts}% +\begin{codeblock} +// all freestanding +namespace std { + // \ref{concepts.lang}, language-related concepts + // \ref{concept.same}, concept \libconcept{same_as} + template + concept same_as = @\seebelow@; + + // \ref{concept.derived}, concept \libconcept{derived_from} + template + concept derived_from = @\seebelow@; + + // \ref{concept.convertible}, concept \libconcept{convertible_to} + template + concept convertible_to = @\seebelow@; + + // \ref{concept.commonref}, concept \libconcept{common_reference_with} + template + concept common_reference_with = @\seebelow@; + + // \ref{concept.common}, concept \libconcept{common_with} + template + concept common_with = @\seebelow@; + + // \ref{concepts.arithmetic}, arithmetic concepts + template + concept integral = @\seebelow@; + template + concept signed_integral = @\seebelow@; + template + concept unsigned_integral = @\seebelow@; + template + concept floating_point = @\seebelow@; + + // \ref{concept.assignable}, concept \libconcept{assignable_from} + template + concept assignable_from = @\seebelow@; + + // \ref{concept.swappable}, concept \libconcept{swappable} + namespace ranges { + inline namespace @\unspec@ { + inline constexpr @\unspec@ swap = @\unspec@; + } + } + template + concept swappable = @\seebelow@; + template + concept swappable_with = @\seebelow@; + + // \ref{concept.destructible}, concept \libconcept{destructible} + template + concept destructible = @\seebelow@; + + // \ref{concept.constructible}, concept \libconcept{constructible_from} + template + concept constructible_from = @\seebelow@; + + // \ref{concept.default.init}, concept \libconcept{default_initializable} + template + concept default_initializable = @\seebelow@; + + // \ref{concept.moveconstructible}, concept \libconcept{move_constructible} + template + concept move_constructible = @\seebelow@; + + // \ref{concept.copyconstructible}, concept \libconcept{copy_constructible} + template + concept copy_constructible = @\seebelow@; + + // \ref{concepts.compare}, comparison concepts + // \ref{concept.equalitycomparable}, concept \libconcept{equality_comparable} + template + concept equality_comparable = @\seebelow@; + template + concept equality_comparable_with = @\seebelow@; + + // \ref{concept.totallyordered}, concept \libconcept{totally_ordered} + template + concept totally_ordered = @\seebelow@; + template + concept totally_ordered_with = @\seebelow@; + + // \ref{concepts.object}, object concepts + template + concept movable = @\seebelow@; + template + concept copyable = @\seebelow@; + template + concept semiregular = @\seebelow@; + template + concept regular = @\seebelow@; + + // \ref{concepts.callable}, callable concepts + // \ref{concept.invocable}, concept \libconcept{invocable} + template + concept invocable = @\seebelow@; + + // \ref{concept.regularinvocable}, concept \libconcept{regular_invocable} + template + concept regular_invocable = @\seebelow@; + + // \ref{concept.predicate}, concept \libconcept{predicate} + template + concept predicate = @\seebelow@; + + // \ref{concept.relation}, concept \libconcept{relation} + template + concept relation = @\seebelow@; + + // \ref{concept.equiv}, concept \libconcept{equivalence_relation} + template + concept equivalence_relation = @\seebelow@; + + // \ref{concept.strictweakorder}, concept \libconcept{strict_weak_order} + template + concept strict_weak_order = @\seebelow@; +} +\end{codeblock} + +\rSec1[concepts.lang]{Language-related concepts} + +\rSec2[concepts.lang.general]{General} + +\pnum +Subclause \ref{concepts.lang} contains the definition of concepts corresponding to language +features. These concepts express relationships between types, type +classifications, and fundamental type properties. + +\rSec2[concept.same]{Concept \cname{same_as}} + +\begin{itemdecl} +template + concept @\defexposconcept{same-as-impl}@ = is_same_v; // \expos + +template + concept @\deflibconcept{same_as}@ = @\exposconcept{same-as-impl}@ && @\exposconcept{same-as-impl}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{note} +\tcode{\libconcept{same_as}} subsumes \tcode{\libconcept{same_as}} and +vice versa. +\end{note} +\end{itemdescr} + +\rSec2[concept.derived]{Concept \cname{derived_from}} + +\begin{itemdecl} +template + concept @\deflibconcept{derived_from}@ = + is_base_of_v && + is_convertible_v; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{note} +\tcode{\libconcept{derived_from}} is satisfied if and only if +\tcode{Derived} is publicly and unambiguously derived from \tcode{Base}, or +\tcode{Derived} and \tcode{Base} are the same class type ignoring cv-qualifiers. +\end{note} +\end{itemdescr} + +\rSec2[concept.convertible]{Concept \cname{convertible_to}} + +\pnum +Given types \tcode{From} and \tcode{To} and +an expression \tcode{E} +whose type and value category are the same as those of \tcode{declval()}, +\tcode{\libconcept{convertible_to}} requires \tcode{E} +to be both implicitly and explicitly convertible to type \tcode{To}. +The implicit and explicit conversions are required to produce equal +results. + +\begin{itemdecl} +template + concept @\deflibconcept{convertible_to}@ = + is_convertible_v && + requires { + static_cast(declval()); + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{FromR} be \tcode{add_rvalue_reference_t} and +\tcode{test} be the invented function: +\begin{codeblock} +To test(FromR (&f)()) { + return f(); +} +\end{codeblock} +and let \tcode{f} be a function with no arguments and return type \tcode{FromR} +such that \tcode{f()} is equality-preserving. +Types \tcode{From} and \tcode{To} model \tcode{\libconcept{convertible_to}} +only if: + +\begin{itemize} +\item +\tcode{To} is not an object or reference-to-object type, or +\tcode{static_cast(f())} is equal to \tcode{test(f)}. + +\item +\tcode{FromR} is not a reference-to-object type, or + +\begin{itemize} +\item +If \tcode{FromR} is an rvalue reference to a non const-qualified type, the +resulting state of the object referenced by \tcode{f()} after either above +expression is valid but unspecified\iref{lib.types.movedfrom}. + +\item +Otherwise, the object referred to by \tcode{f()} is not modified by either above +expression. +\end{itemize} +\end{itemize} +\end{itemdescr} + + +\rSec2[concept.commonref]{Concept \cname{common_reference_with}} + +\pnum +For two types \tcode{T} and \tcode{U}, if \tcode{common_reference_t} +is well-formed and denotes a type \tcode{C} such that both +\tcode{\libconcept{convertible_to}} +and +\tcode{\libconcept{convertible_to}} +are modeled, then \tcode{T} and \tcode{U} share a +\term{common reference type}, \tcode{C}. +\begin{note} +\tcode{C} can be the same as \tcode{T} or \tcode{U}, or can be a +different type. \tcode{C} can be a reference type. +\end{note} + +\begin{itemdecl} +template + concept @\deflibconcept{common_reference_with}@ = + @\libconcept{same_as}@, common_reference_t> && + @\libconcept{convertible_to}@> && + @\libconcept{convertible_to}@>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{C} be \tcode{common_reference_t}. +Let \tcode{t1} and \tcode{t2} be equality-preserving +expressions\iref{concepts.equality} such that +\tcode{decltype((t1))} and \tcode{decltype((t2))} are each \tcode{T}, and +let \tcode{u1} and \tcode{u2} be equality-preserving expressions such that +\tcode{decltype((u1))} and \tcode{decltype((u2))} are each \tcode{U}. +\tcode{T} and \tcode{U} model \tcode{\libconcept{common_reference_with}} +only if +\begin{itemize} +\item \tcode{C(t1)} equals \tcode{C(t2)} if and only if + \tcode{t1} equals \tcode{t2}, and +\item \tcode{C(u1)} equals \tcode{C(u2)} if and only if + \tcode{u1} equals \tcode{u2}. +\end{itemize} + +\pnum +\begin{note} +Users can customize the behavior of \libconcept{common_reference_with} by specializing +the \tcode{basic_common_reference} class template\iref{meta.trans.other}. +\end{note} +\end{itemdescr} + +\rSec2[concept.common]{Concept \cname{common_with}} + +\pnum +If \tcode{T} and \tcode{U} can both be explicitly converted to some third type, +\tcode{C}, then \tcode{T} and \tcode{U} share a \term{common type}, +\tcode{C}. +\begin{note} +\tcode{C} can be the same as \tcode{T} or \tcode{U}, or can be a +different type. \tcode{C} is not necessarily unique. +\end{note} + +\begin{itemdecl} +template + concept @\deflibconcept{common_with}@ = + @\libconcept{same_as}@, common_type_t> && + requires { + static_cast>(declval()); + static_cast>(declval()); + } && + @\libconcept{common_reference_with}@< + add_lvalue_reference_t, + add_lvalue_reference_t> && + @\libconcept{common_reference_with}@< + add_lvalue_reference_t>, + common_reference_t< + add_lvalue_reference_t, + add_lvalue_reference_t>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{C} be \tcode{common_type_t}. +Let \tcode{t1} and \tcode{t2} be +equality-preserving expressions\iref{concepts.equality} such that +\tcode{decltype((t1))} and \tcode{decltype((t2))} are each \tcode{T}, and +let \tcode{u1} and \tcode{u2} be equality-preserving expressions such that +\tcode{decltype((u1))} and \tcode{decltype((u2))} are each \tcode{U}. +\tcode{T} and \tcode{U} model \tcode{\libconcept{common_with}} +only if +\begin{itemize} +\item \tcode{C(t1)} equals \tcode{C(t2)} if and only if + \tcode{t1} equals \tcode{t2}, and +\item \tcode{C(u1)} equals \tcode{C(u2)} if and only if + \tcode{u1} equals \tcode{u2}. +\end{itemize} + +\pnum +\begin{note} +Users can customize the behavior of \libconcept{common_with} by specializing the +\tcode{common_type} class template\iref{meta.trans.other}. +\end{note} + +\end{itemdescr} + +\rSec2[concepts.arithmetic]{Arithmetic concepts} + +\begin{itemdecl} +template + concept @\deflibconcept{integral}@ = is_integral_v; +template + concept @\deflibconcept{signed_integral}@ = @\libconcept{integral}@ && is_signed_v; +template + concept @\deflibconcept{unsigned_integral}@ = @\libconcept{integral}@ && !@\libconcept{signed_integral}@; +template + concept @\deflibconcept{floating_point}@ = is_floating_point_v; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{note} +\libconcept{signed_integral} can be modeled even by types that are +not signed integer types\iref{basic.fundamental}; for example, \tcode{char}. +\end{note} + +\pnum +\begin{note} +\libconcept{unsigned_integral} can be modeled even by types that are +not unsigned integer types\iref{basic.fundamental}; for example, \tcode{bool}. +\end{note} +\end{itemdescr} + +\rSec2[concept.assignable]{Concept \cname{assignable_from}} + +\begin{itemdecl} +template + concept @\deflibconcept{assignable_from}@ = + is_lvalue_reference_v && + @\libconcept{common_reference_with}@&, const remove_reference_t&> && + requires(LHS lhs, RHS&& rhs) { + { lhs = std::forward(rhs) } -> @\libconcept{same_as}@; + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let: +\begin{itemize} +\item \tcode{lhs} be an lvalue that refers to an object \tcode{lcopy} such that + \tcode{decltype((lhs))} is \tcode{LHS}, +\item \tcode{rhs} be an expression such that \tcode{decltype((rhs))} is + \tcode{RHS}, and +\item \tcode{rcopy} be a distinct object that is equal to \tcode{rhs}. +\end{itemize} +\tcode{LHS} and \tcode{RHS} model +\tcode{\libconcept{assignable_from}} only if + +\begin{itemize} +\item \tcode{addressof(lhs = rhs) == addressof(lcopy)}. + +\item After evaluating \tcode{lhs = rhs}: + +\begin{itemize} +\item \tcode{lhs} is equal to \tcode{rcopy}, unless \tcode{rhs} is a non-const +xvalue that refers to \tcode{lcopy}. + +\item If \tcode{rhs} is a non-\keyword{const} xvalue, the resulting state of the +object to which it refers is valid but unspecified\iref{lib.types.movedfrom}. + +\item Otherwise, if \tcode{rhs} is a glvalue, the object to which it refers is + not modified. +\end{itemize} +\end{itemize} + +\pnum +\begin{note} +Assignment need not be a total function\iref{structure.requirements}; +in particular, if assignment to an object \tcode{x} can result in a modification +of some other object \tcode{y}, then \tcode{x = y} is likely not in the domain +of \tcode{=}. +\end{note} +\end{itemdescr} + +\rSec2[concept.swappable]{Concept \cname{swappable}} + +\pnum +Let \tcode{t1} and \tcode{t2} be equality-preserving expressions that denote +distinct equal objects of type \tcode{T}, and let \tcode{u1} and \tcode{u2} +similarly denote distinct equal objects of type \tcode{U}. +\begin{note} +\tcode{t1} and \tcode{u1} can denote distinct objects, or the same object. +\end{note} +An operation +\term{exchanges the values} denoted by \tcode{t1} and \tcode{u1} if and only +if the operation modifies neither \tcode{t2} nor \tcode{u2} and: +\begin{itemize} +\item If \tcode{T} and \tcode{U} are the same type, the result of the operation + is that \tcode{t1} equals \tcode{u2} and \tcode{u1} equals \tcode{t2}. + +\item If \tcode{T} and \tcode{U} are different types and + \tcode{\libconcept{common_reference_with}} + is modeled, + the result of the operation is that + \tcode{C(t1)} equals \tcode{C(u2)} + and + \tcode{C(u1)} equals \tcode{C(t2)} + where \tcode{C} is \tcode{common_reference_t}. +\end{itemize} + +\pnum +\indexlibraryglobal{swap}% +The name \tcode{ranges::swap} denotes a customization point +object\iref{customization.point.object}. The expression +\tcode{ranges::swap(E1, E2)} for subexpressions \tcode{E1} +and \tcode{E2} is expression-equivalent to an expression +\tcode{S} determined as follows: + +\begin{itemize} +\item + \tcode{S} is \tcode{(void)swap(E1, E2)} +\begin{footnote} +The name \tcode{swap} is used + here unqualified. +\end{footnote} +if \tcode{E1} or \tcode{E2} + has class or enumeration type\iref{basic.compound} and that expression is valid, with + overload resolution performed in a context that includes the declaration +\begin{codeblock} +template + void swap(T&, T&) = delete; +\end{codeblock} + and does not include a declaration of \tcode{ranges::swap}. + If the function selected by overload resolution does not + exchange the values denoted by + \tcode{E1} and \tcode{E2}, + the program is ill-formed, no diagnostic required. + \begin{note} + This precludes calling unconstrained program-defined overloads of + \tcode{swap}. When the deleted overload is viable, program-defined overloads + need to be more specialized\iref{temp.func.order} to be selected. + \end{note} + +\item + Otherwise, if \tcode{E1} and \tcode{E2} + are lvalues of array types\iref{basic.compound} + with equal extent and \tcode{ranges::swap(*E1, *E2)} + is a valid expression, + \tcode{S} is \tcode{(void)ranges::swap_ranges(E1, E2)}, + except that + \tcode{noexcept(S)} is equal to + \tcode{noexcept(\brk{}ranges::swap(*E1, *E2))}. + +\item + Otherwise, if \tcode{E1} and \tcode{E2} are lvalues of the + same type \tcode{T} that models \tcode{\libconcept{move_constructible}} and + \tcode{\libconcept{assignable_from}}, + \tcode{S} is an expression that exchanges the denoted values. + \tcode{S} is a constant expression if + \begin{itemize} + \item \tcode{T} is a literal type\iref{term.literal.type}, + \item both \tcode{E1 = std::move(E2)} and \tcode{E2 = std::move(E1)} are + constant subexpressions\iref{defns.const.subexpr}, and + \item the full-expressions of the initializers in the declarations +\begin{codeblock} +T t1(std::move(E1)); +T t2(std::move(E2)); +\end{codeblock} +are constant subexpressions. + \end{itemize} + \tcode{noexcept(S)} is equal to + \tcode{is_nothrow_move_constructible_v \&\& is_nothrow_move_assignable\-_v}. + +\item + Otherwise, \tcode{ranges::swap(E1, E2)} is ill-formed. + \begin{note} + This case can result in substitution failure when \tcode{ranges::swap(E1, E2)} + appears in the immediate context of a template instantiation. + \end{note} +\end{itemize} + +\pnum +\begin{note} +Whenever \tcode{ranges::swap(E1, E2)} is a valid expression, it +exchanges the values denoted by +\tcode{E1} and \tcode{E2} and has type \keyword{void}. +\end{note} + +\begin{itemdecl} +template + concept @\deflibconcept{swappable}@ = requires(T& a, T& b) { ranges::swap(a, b); }; +\end{itemdecl} + +\begin{itemdecl} +template + concept @\deflibconcept{swappable_with}@ = + @\libconcept{common_reference_with}@ && + requires(T&& t, U&& u) { + ranges::swap(std::forward(t), std::forward(t)); + ranges::swap(std::forward(u), std::forward(u)); + ranges::swap(std::forward(t), std::forward(u)); + ranges::swap(std::forward(u), std::forward(t)); + }; +\end{itemdecl} + +\pnum +\begin{note} +The semantics of the \libconcept{swappable} and \libconcept{swappable_with} +concepts are fully defined by the \tcode{ranges::swap} customization point object. +\end{note} + +\pnum +\begin{example} +User code can ensure that the evaluation of \tcode{swap} calls +is performed in an appropriate context under the various conditions as follows: +\begin{codeblock} +#include +#include +#include + +namespace ranges = std::ranges; + +template U> +void value_swap(T&& t, U&& u) { + ranges::swap(std::forward(t), std::forward(u)); +} + +template +void lv_swap(T& t1, T& t2) { + ranges::swap(t1, t2); +} + +namespace N { + struct A { int m; }; + struct Proxy { + A* a; + Proxy(A& a) : a{&a} {} + friend void swap(Proxy x, Proxy y) { + ranges::swap(*x.a, *y.a); + } + }; + Proxy proxy(A& a) { return Proxy{ a }; } +} + +int main() { + int i = 1, j = 2; + lv_swap(i, j); + assert(i == 2 && j == 1); + + N::A a1 = { 5 }, a2 = { -5 }; + value_swap(a1, proxy(a2)); + assert(a1.m == -5 && a2.m == 5); +} +\end{codeblock} +\end{example} + +\rSec2[concept.destructible]{Concept \cname{destructible}} + +\pnum +The \libconcept{destructible} concept specifies properties of all types, +instances of which can be destroyed at the end of their lifetime, or reference +types. + +\begin{itemdecl} +template + concept @\deflibconcept{destructible}@ = is_nothrow_destructible_v; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{note} +Unlike the \oldconcept{Destructible} requirements~(\tref{cpp17.destructible}), this +concept forbids destructors that are potentially throwing, even if a particular +invocation of the destructor does not actually throw. +\end{note} +\end{itemdescr} + +\rSec2[concept.constructible]{Concept \cname{constructible_from}} + +\pnum +The \libconcept{constructible_from} concept constrains the initialization of a +variable of a given type with a particular set of argument types. + +\begin{itemdecl} +template + concept @\deflibconcept{constructible_from}@ = @\libconcept{destructible}@ && is_constructible_v; +\end{itemdecl} + +\rSec2[concept.default.init]{Concept \cname{default_initializable}} + +\begin{itemdecl} +template + constexpr bool @\exposid{is-default-initializable}@ = @\seebelow@; // \expos + +template + concept @\deflibconcept{default_initializable}@ = @\libconcept{constructible_from}@ && + requires { T{}; } && + @\exposid{is-default-initializable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +For a type \tcode{T}, \tcode{\exposid{is-default-initializable}} is \tcode{true} +if and only if the variable definition +\begin{codeblock} +T t; +\end{codeblock} +is well-formed for some invented variable \tcode{t}; +otherwise it is \tcode{false}. +Access checking is performed as if in a context unrelated to \tcode{T}. +Only the validity of the immediate context of the variable initialization is considered. +\end{itemdescr} + +\rSec2[concept.moveconstructible]{Concept \cname{move_constructible}} + +\begin{itemdecl} +template + concept @\deflibconcept{move_constructible}@ = @\libconcept{constructible_from}@ && @\libconcept{convertible_to}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +If \tcode{T} is an object type, then let \tcode{rv} be an rvalue of type +\tcode{T} and \tcode{u2} a distinct object of type \tcode{T} equal to +\tcode{rv}. \tcode{T} models \libconcept{move_constructible} only if + +\begin{itemize} +\item After the definition \tcode{T u = rv;}, \tcode{u} is equal to \tcode{u2}. + +\item \tcode{T(rv)} is equal to \tcode{u2}. + +\item If \tcode{T} is not \keyword{const}, \tcode{rv}'s resulting state is valid +but unspecified\iref{lib.types.movedfrom}; otherwise, it is unchanged. +\end{itemize} +\end{itemdescr} + +\rSec2[concept.copyconstructible]{Concept \cname{copy_constructible}} + +\begin{itemdecl} +template + concept @\deflibconcept{copy_constructible}@ = + @\libconcept{move_constructible}@ && + @\libconcept{constructible_from}@ && @\libconcept{convertible_to}@ && + @\libconcept{constructible_from}@ && @\libconcept{convertible_to}@ && + @\libconcept{constructible_from}@ && @\libconcept{convertible_to}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +If \tcode{T} is an object type, then let \tcode{v} be an lvalue of type +\tcode{T} or \tcode{\keyword{const} T} or an rvalue of type \tcode{\keyword{const} T}. +\tcode{T} models \libconcept{copy_constructible} only if + +\begin{itemize} +\item After the definition \tcode{T u = v;}, +\tcode{u} is equal to \tcode{v}\iref{concepts.equality} and +\tcode{v} is not modified. + +\item \tcode{T(v)} is equal to \tcode{v} and does not modify \tcode{v}. +\end{itemize} + +\end{itemdescr} + +\rSec1[concepts.compare]{Comparison concepts} + +\rSec2[concepts.compare.general]{General} + +\pnum +Subclause \ref{concepts.compare} describes concepts that establish relationships and orderings +on values of possibly differing object types. + +\pnum +Given an expression \tcode{E} and a type \tcode{C}, +let \tcode{\exposid{CONVERT_TO_LVALUE}(E)} be: +\begin{itemize} +\item +\tcode{static_cast(as_const(E))} if that is a valid expression, and +\item +\tcode{static_cast(std::move(E))} otherwise. +\end{itemize} + +\rSec2[concept.booleantestable]{Boolean testability} + +\pnum +The exposition-only \exposconcept{boolean-testable} concept +specifies the requirements on expressions +that are convertible to \tcode{bool} and +for which the logical operators\iref{expr.log.and,expr.log.or,expr.unary.op} +have the conventional semantics. + +\begin{itemdecl} +template + concept @\defexposconcept{boolean-testable-impl}@ = @\libconcept{convertible_to}@; // \expos +\end{itemdecl} + +\pnum +Let \tcode{e} be an expression such that +\tcode{decltype((e))} is \tcode{T}. +\tcode{T} models \exposconcept{boolean-testable-impl} only if + +\begin{itemize} +\item +either \tcode{remove_cvref_t} is not a class type, or +a search for the names \tcode{operator\&\&} and \tcode{operator||} +in the scope of \tcode{remove_cvref_t} +finds nothing; and + +\item +argument-dependent lookup\iref{basic.lookup.argdep} +for the names \tcode{operator\&\&} and \tcode{operator||} +with \tcode{T} as the only argument type +finds no disqualifying declaration (defined below). +\end{itemize} + +\pnum +A \defnadj{disqualifying}{parameter} +is a function parameter whose declared type \tcode{P} + +\begin{itemize} +\item +is not dependent on a template parameter, and +there exists an implicit conversion sequence\iref{over.best.ics} +from \tcode{e} to \tcode{P}; or + +\item +is dependent on one or more template parameters, and either +\begin{itemize} +\item +\tcode{P} contains no template parameter that +participates in template argument deduction\iref{temp.deduct.type}, or +\item +template argument deduction +using the rules for deducing template arguments +in a function call\iref{temp.deduct.call} and +\tcode{e} as the argument succeeds. +\end{itemize} +\end{itemize} + +\pnum +\indextext{template!function!key parameter of}% +A \defnadj{key}{parameter} of a function template \tcode{D} +is a function parameter of type \cv{} \tcode{X} or reference thereto, +where \tcode{X} names a specialization of a class template that +has the same innermost enclosing non-inline namespace as \tcode{D}, and +\tcode{X} contains at least one template parameter that +participates in template argument deduction. +\begin{example} +In +\begin{codeblock} +namespace Z { + template struct C {}; + template + void operator&&(C x, T y); + template + void operator||(C> x, T y); +} +\end{codeblock} +the declaration of \tcode{Z::operator\&\&} +contains one key parameter, \tcode{C x}, and +the declaration of \tcode{Z::operator||} +contains no key parameters. +\end{example} + +\pnum +A \defnadj{disqualifying}{declaration} is + +\begin{itemize} +\item +a (non-template) function declaration that +contains at least one disqualifying parameter; or + +\item +a function template declaration that +contains at least one disqualifying parameter, where +\begin{itemize} +\item at least one disqualifying parameter is a key parameter; or +\item the declaration contains no key parameters; or +\item the declaration declares a function template +to which no name is bound\iref{dcl.meaning}. +\end{itemize} +\end{itemize} + +\pnum +\begin{note} +The intention is to ensure that +given two types \tcode{T1} and \tcode{T2} +that each model \exposconcept{boolean-testable-impl}, +the \tcode{\&\&} and \tcode{||} operators within the expressions +\tcode{declval() \&\& declval()} and +\tcode{declval() || declval()} +resolve to the corresponding built-in operators. +\end{note} + +\begin{itemdecl} +template + concept @\defexposconcept{boolean-testable}@ = // \expos + @\exposconcept{boolean-testable-impl}@ && requires(T&& t) { + { !std::forward(t) } -> @\exposconcept{boolean-testable-impl}@; + }; +\end{itemdecl} + +\pnum +Let \tcode{e} be an expression such that +\tcode{decltype((e))} is \tcode{T}. +\tcode{T} models \exposconcept{boolean-testable} only if +\tcode{bool(e) == !bool(!e)}. + +\pnum +\begin{example} +The types +\tcode{bool}, +\tcode{true_type}\iref{meta.type.synop}, +\tcode{int*}, and +\tcode{bitset::reference}\iref{template.bitset} +model \exposconcept{boolean-testable}. +\end{example} + +\rSec2[concept.comparisoncommontype]{Comparison common types} + +\begin{itemdecl} +template> + concept @\defexposconcept{comparison-common-type-with-impl}@ = // \expos + @\libconcept{same_as}@, + common_reference_t> && + requires { + requires @\libconcept{convertible_to}@ || @\libconcept{convertible_to}@; + requires @\libconcept{convertible_to}@ || @\libconcept{convertible_to}@; + }; + +template + concept @\defexposconcept{comparison-common-type-with}@ = // \expos + @\exposconcept{comparison-common-type-with-impl}@, remove_cvref_t>; +\end{itemdecl} + +\pnum +Let \tcode{C} be \tcode{common_reference_t}. +Let \tcode{t1} and \tcode{t2} be equality-preserving expressions +that are lvalues of type \tcode{remove_cvref_t}, and +let \tcode{u1} and \tcode{u2} be equality-preserving expressions +that are lvalues of type \tcode{remove_cvref_t}. +\tcode{T} and \tcode{U} model +\tcode{\exposconcept{comparison-common-type-with}} only if +\begin{itemize} +\item +\tcode{\exposid{CONVERT_TO_LVALUE}(t1)} equals +\tcode{\exposid{CONVERT_TO_LVALUE}(t2)} +if and only if \tcode{t1} equals \tcode{t2}, and +\item +\tcode{\exposid{CONVERT_TO_LVALUE}(u1)} equals +\tcode{\exposid{CONVERT_TO_LVALUE}(u2)} +if and only if \tcode{u1} equals \tcode{u2}. +\end{itemize} + +\rSec2[concept.equalitycomparable]{Concept \cname{equality_comparable}} + +\begin{itemdecl} +template + concept @\defexposconcept{weakly-equality-comparable-with}@ = // \expos + requires(const remove_reference_t& t, + const remove_reference_t& u) { + { t == u } -> @\exposconcept{boolean-testable}@; + { t != u } -> @\exposconcept{boolean-testable}@; + { u == t } -> @\exposconcept{boolean-testable}@; + { u != t } -> @\exposconcept{boolean-testable}@; + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Given types \tcode{T} and \tcode{U}, +let \tcode{t} and \tcode{u} be lvalues of types +\tcode{const remove_reference_t} and +\tcode{const remove_reference_t} respectively. +\tcode{T} and \tcode{U} model +\tcode{\exposconcept{weakly-equality-comparable-with}} only if +\begin{itemize} +\item \tcode{t == u}, \tcode{u == t}, \tcode{t != u}, and \tcode{u != t} + have the same domain. +\item \tcode{bool(u == t) == bool(t == u)}. +\item \tcode{bool(t != u) == !bool(t == u)}. +\item \tcode{bool(u != t) == bool(t != u)}. +\end{itemize} +\end{itemdescr} + +\begin{itemdecl} +template + concept @\deflibconcept{equality_comparable}@ = @\exposconcept{weakly-equality-comparable-with}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{a} and \tcode{b} be objects of type \tcode{T}. +\tcode{T} models \libconcept{equality_comparable} only if +\tcode{bool(a == b)} is \tcode{true} when \tcode{a} is equal to +\tcode{b}\iref{concepts.equality}, and \tcode{false} otherwise. + +\pnum +\begin{note} +The requirement that the expression \tcode{a == b} is equality-preserving +implies that \tcode{==} is transitive and symmetric. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +template + concept @\deflibconcept{equality_comparable_with}@ = + @\libconcept{equality_comparable}@ && @\libconcept{equality_comparable}@ && + @\exposconcept{comparison-common-type-with}@ && + @\libconcept{equality_comparable}@< + common_reference_t< + const remove_reference_t&, + const remove_reference_t&>> && + @\exposconcept{weakly-equality-comparable-with}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Given types \tcode{T} and \tcode{U}, +let \tcode{t} and \tcode{t2} be lvalues +denoting distinct equal objects of types \tcode{const remove_reference_t} and +\tcode{remove_cvref_t}, respectively, +let \tcode{u} and \tcode{u2} be lvalues +denoting distinct equal objects of types \tcode{const remove_reference_t} and +\tcode{remove_cvref_t}, respectively, and +let \tcode{C} be: +\begin{codeblock} +common_reference_t&, const remove_reference_t&> +\end{codeblock} +\tcode{T} and \tcode{U} model +\tcode{\libconcept{equality_comparable_with}} only if +\begin{codeblock} +bool(t == u) == bool(@\exposid{CONVERT_TO_LVALUE}@(t2) == @\exposid{CONVERT_TO_LVALUE}@(u2)) +\end{codeblock} +\end{itemdescr} + +\rSec2[concept.totallyordered]{Concept \cname{totally_ordered}} + +\begin{itemdecl} +template + concept @\deflibconcept{totally_ordered}@ = + @\libconcept{equality_comparable}@ && @\exposconcept{partially-ordered-with}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Given a type \tcode{T}, let \tcode{a}, \tcode{b}, and \tcode{c} be +lvalues of type \tcode{const remove_reference_t}. +\tcode{T} models \libconcept{totally_ordered} only if + +\begin{itemize} +\item Exactly one of \tcode{bool(a < b)}, \tcode{bool(a > b)}, or + \tcode{bool(a == b)} is \tcode{true}. +\item If \tcode{bool(a < b)} and \tcode{bool(b < c)}, then + \tcode{bool(a < c)}. +\item \tcode{bool(a <= b) == !bool(b < a)}. +\item \tcode{bool(a >= b) == !bool(a < b)}. +\end{itemize} + +\end{itemdescr} + +\begin{itemdecl} +template + concept @\deflibconcept{totally_ordered_with}@ = + @\libconcept{totally_ordered}@ && @\libconcept{totally_ordered}@ && + @\libconcept{equality_comparable_with}@ && + @\libconcept{totally_ordered}@< + common_reference_t< + const remove_reference_t&, + const remove_reference_t&>> && + @\exposconcept{partially-ordered-with}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Given types \tcode{T} and \tcode{U}, +let \tcode{t} and \tcode{t2} be lvalues +denoting distinct equal objects of types \tcode{const remove_reference_t} and +\tcode{remove_cvref_t}, respectively, +let \tcode{u} and \tcode{u2} be lvalues +denoting distinct equal objects of types \tcode{const remove_reference_t} and +\tcode{remove_cvref_t}, respectively, and +let \tcode{C} be: +\begin{codeblock} +common_reference_t&, const remove_reference_t&> +\end{codeblock} +\tcode{T} and \tcode{U} model +\tcode{\libconcept{totally_ordered_with}} only if +\begin{itemize} +\item \tcode{bool(t < u) == bool(\exposid{CONVERT_TO_LVALUE}(t2) < \exposid{CONVERT_TO_LVALUE}(u2))}. +\item \tcode{bool(t > u) == bool(\exposid{CONVERT_TO_LVALUE}(t2) > \exposid{CONVERT_TO_LVALUE}(u2))}. +\item \tcode{bool(t <= u) == bool(\exposid{CONVERT_TO_LVALUE}(t2) <= \exposid{CONVERT_TO_LVALUE}(u2))}. +\item \tcode{bool(t >= u) == bool(\exposid{CONVERT_TO_LVALUE}(t2) >= \exposid{CONVERT_TO_LVALUE}(u2))}. +\item \tcode{bool(u < t) == bool(\exposid{CONVERT_TO_LVALUE}(u2) < \exposid{CONVERT_TO_LVALUE}(t2))}. +\item \tcode{bool(u > t) == bool(\exposid{CONVERT_TO_LVALUE}(u2) > \exposid{CONVERT_TO_LVALUE}(t2))}. +\item \tcode{bool(u <= t) == bool(\exposid{CONVERT_TO_LVALUE}(u2) <= \exposid{CONVERT_TO_LVALUE}(t2))}. +\item \tcode{bool(u >= t) == bool(\exposid{CONVERT_TO_LVALUE}(u2) >= \exposid{CONVERT_TO_LVALUE}(t2))}. +\end{itemize} +\end{itemdescr} + +\rSec1[concepts.object]{Object concepts} + +\pnum +This subclause describes concepts that specify the basis of the +value-oriented programming style on which the library is based. + +\begin{itemdecl} +template + concept @\deflibconcept{movable}@ = is_object_v && @\libconcept{move_constructible}@ && + @\libconcept{assignable_from}@ && @\libconcept{swappable}@; +template + concept @\deflibconcept{copyable}@ = @\libconcept{copy_constructible}@ && @\libconcept{movable}@ && @\libconcept{assignable_from}@ && + @\libconcept{assignable_from}@ && @\libconcept{assignable_from}@; +template + concept @\deflibconcept{semiregular}@ = @\libconcept{copyable}@ && @\libconcept{default_initializable}@; +template + concept @\deflibconcept{regular}@ = @\libconcept{semiregular}@ && @\libconcept{equality_comparable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{note} +The \libconcept{semiregular} concept is modeled by types that behave similarly +to fundamental types like \tcode{int}, except that they need not +be comparable with \tcode{==}. +\end{note} + +\pnum +\begin{note} +The \libconcept{regular} concept is modeled by types that behave similarly to +fundamental types like \tcode{int} and that are comparable with +\tcode{==}. +\end{note} +\end{itemdescr} + +\rSec1[concepts.callable]{Callable concepts} + +\rSec2[concepts.callable.general]{General} + +\pnum +The concepts in \ref{concepts.callable} describe the requirements on +callable types\iref{func.def} and their arguments. + +\rSec2[concept.invocable]{Concept \cname{invocable}} + +\pnum +The \libconcept{invocable} concept specifies a relationship between a callable +type\iref{func.def} \tcode{F} and a set of argument types \tcode{Args...} which +can be evaluated by the library function \tcode{invoke}\iref{func.invoke}. + +\begin{itemdecl} +template + concept @\deflibconcept{invocable}@ = requires(F&& f, Args&&... args) { + invoke(std::forward(f), std::forward(args)...); // not required to be equality-preserving + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{example} +A function that generates random numbers can model \libconcept{invocable}, +since the \tcode{invoke} function call expression is not required to be +equality-preserving\iref{concepts.equality}. +\end{example} +\end{itemdescr} + +\rSec2[concept.regularinvocable]{Concept \cname{regular_invocable}} + +\begin{itemdecl} +template + concept @\deflibconcept{regular_invocable}@ = @\libconcept{invocable}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The \tcode{invoke} function call expression shall be +equality-preserving\iref{concepts.equality} and +shall not modify the function object or the arguments. +\begin{note} +This requirement supersedes the ``not required to be equality-preserving'' comment +in the definition of \libconcept{invocable}. +\end{note} + +\pnum +\begin{example} +A random number generator does not model \libconcept{regular_invocable}. +\end{example} + +\pnum +\begin{note} +The distinction between \libconcept{invocable} and \libconcept{regular_invocable} +is purely semantic. +\end{note} +\end{itemdescr} + +\rSec2[concept.predicate]{Concept \cname{predicate}} + +\begin{itemdecl} +template + concept @\deflibconcept{predicate}@ = + @\libconcept{regular_invocable}@ && @\exposconcept{boolean-testable}@>; +\end{itemdecl} + +\rSec2[concept.relation]{Concept \cname{relation}} + +\begin{itemdecl} +template + concept @\deflibconcept{relation}@ = + @\libconcept{predicate}@ && @\libconcept{predicate}@ && + @\libconcept{predicate}@ && @\libconcept{predicate}@; +\end{itemdecl} + +\rSec2[concept.equiv]{Concept \cname{equivalence_relation}} + +\begin{itemdecl} +template + concept @\deflibconcept{equivalence_relation}@ = @\libconcept{relation}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +A \libconcept{relation} models \libconcept{equivalence_relation} only if +it imposes an equivalence relation on its arguments. +\end{itemdescr} + +\rSec2[concept.strictweakorder]{Concept \cname{strict_weak_order}} + +\begin{itemdecl} +template + concept @\deflibconcept{strict_weak_order}@ = @\libconcept{relation}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +A \libconcept{relation} models \libconcept{strict_weak_order} only if +it imposes a \term{strict weak ordering} on its arguments. + +\pnum +The term +\term{strict} +refers to the +requirement of an irreflexive relation (\tcode{!comp(x, x)} for all \tcode{x}), +and the term +\term{weak} +to requirements that are not as strong as +those for a total ordering, +but stronger than those for a partial +ordering. +If we define +\tcode{equiv(a, b)} +as +\tcode{!comp(a, b) \&\& !comp(b, a)}, +then the requirements are that +\tcode{comp} +and +\tcode{equiv} +both be transitive relations: + +\begin{itemize} +\item +\tcode{comp(a, b) \&\& comp(b, c)} +implies +\tcode{comp(a, c)} +\item +\tcode{equiv(a, b) \&\& equiv(b, c)} +implies +\tcode{equiv(a, c)} +\end{itemize} + +\pnum +\begin{note} +Under these conditions, it can be shown that +\begin{itemize} +\item +\tcode{equiv} +is an equivalence relation, +\item +\tcode{comp} +induces a well-defined relation on the equivalence +classes determined by +\tcode{equiv}, and +\item +the induced relation is a strict total ordering. +\end{itemize} +\end{note} +\end{itemdescr} diff --git a/source/config.tex b/source/config.tex index a6d7c05849..bea140ce5b 100644 --- a/source/config.tex +++ b/source/config.tex @@ -2,12 +2,15 @@ %%-------------------------------------------------- %% Version numbers \newcommand{\docno}{Dxxxx} -\newcommand{\prevdocno}{N4296} -\newcommand{\cppver}{201402L} +\newcommand{\prevdocno}{N5046} +\newcommand{\cppver}{2026WIP} %% Release date \newcommand{\reldate}{\today} +%% Core chapters +\newcommand{\lastcorechapter}{cpp} + %% Library chapters -\newcommand{\firstlibchapter}{language.support} -\newcommand{\lastlibchapter}{thread} +\newcommand{\firstlibchapter}{support} +\newcommand{\lastlibchapter}{exec} diff --git a/source/containers.tex b/source/containers.tex index 9f0cf13229..a0095c2664 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -4,7 +4,7 @@ \rSec1[containers.general]{General} \pnum -This Clause describes components that \Cpp programs may use to +This Clause describes components that \Cpp{} programs may use to organize collections of information. \pnum @@ -14,27 +14,28 @@ sequence containers and associative containers, as summarized in -Table~\ref{tab:containers.lib.summary}. +\tref{containers.summary}. -\begin{libsumtab}{Containers library summary}{tab:containers.lib.summary} +\begin{libsumtab}{Containers library summary}{containers.summary} \ref{container.requirements} & Requirements & \\ \rowsep -\ref{sequences} & Sequence containers & \tcode{} \\ - & & \tcode{} \\ - & & \tcode{} \\ - & & \tcode{} \\ - & & \tcode{} \\ \rowsep -\ref{associative} & Associative containers & \tcode{} \\ - & & \tcode{} \\ \rowsep -\ref{unord} & Unordered associative containers & \tcode{} \\ - & & \tcode{} \\ \rowsep -\ref{container.adaptors} & Container adaptors & \tcode{} \\ - & & \tcode{} \\ \rowsep +\ref{sequences} & Sequence containers & + \tcode{}, \tcode{}, \tcode{}, + \tcode{}, \\ & & + \tcode{}, \tcode{}, \tcode{} \\ \rowsep +\ref{associative} & Associative containers & + \tcode{}, \tcode{} \\ \rowsep +\ref{unord} & Unordered associative containers & + \tcode{}, \tcode{} \\ \rowsep +\ref{container.adaptors} & Container adaptors & + \tcode{}, \tcode{}, \tcode{}, \tcode{} \\ \rowsep +\ref{views} & Views & + \tcode{}, \tcode{} \\ \end{libsumtab} -\rSec1[container.requirements]{Container requirements}% +\rSec1[container.requirements]{Requirements}% \indextext{requirements!container} -\rSec2[container.requirements.general]{General container requirements} +\rSec2[container.requirements.pre]{Preamble} \pnum Containers are objects that store other objects. @@ -44,8897 +45,26643 @@ \pnum All of the complexity requirements in this Clause are stated solely in terms of the number of operations on the contained objects. -\enterexample -the copy constructor of type -\tcode{vector >} +\begin{example} +The copy constructor of type +\tcode{vector>} has linear complexity, even though the complexity of copying each contained \tcode{vector} is itself linear. -\exitexample - -\pnum -For the components affected by this subclause that declare an \tcode{allocator_type}, objects -stored in these components shall be constructed using -the \tcode{allocator_traits::construct} function and destroyed using the -\tcode{allocator_traits::destroy} -function~(\ref{allocator.traits.members}). These functions are called only for the -container's element type, not for internal types used by the container. \enternote This -means, for example, that a node-based container might need to construct nodes containing +\end{example} + +\pnum +Allocator-aware containers\iref{container.alloc.reqmts} +other than \tcode{basic_string} construct elements using the function +\tcode{allocator_traits::rebind_traits::\brk{}construct} +and destroy elements using the function +\tcode{allocator_traits::rebind_traits::\brk{}destroy}\iref{allocator.traits.members}, +where \tcode{U} is either \tcode{allocator_type::value_type} or +an internal type used by the container. +These functions are called only for the +container's element type, not for internal types used by the container. +\begin{note} +This +means, for example, that a node-based container would need to construct nodes containing aligned buffers and call \tcode{construct} to place the element into the buffer. -\exitnote - -\pnum -In Tables~\ref{tab:containers.container.requirements}, -\ref{tab:containers.reversible.requirements}, and -\ref{tab:containers.optional.operations} -\tcode{X} denotes a container class containing objects of type -\tcode{T}, \tcode{a} and \tcode{b} -denote values of type \tcode{X}, \tcode{u} -denotes an identifier, \tcode{r} denotes -a non-const value of type \tcode{X}, and \tcode{rv} -denotes a non-const rvalue of type \tcode{X}. - -\begin{libreqtab5} -{Container requirements} -{tab:containers.container.requirements} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & -\chdr{Assertion/note} & \rhdr{Complexity} \\ - & & \chdr{semantics} & \chdr{pre-/post-condition} & \\ \capsep -\endfirsthead -\continuedcaption\\ -\topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & -\chdr{Assertion/note} & \rhdr{Complexity} \\ - & & \chdr{semantics} & \chdr{pre-/post-condition} & \\ \capsep -\endhead - -\tcode{X::value_type} & - \tcode{T} & - & - \requires\ \tcode{T} is \tcode{Erasable} from \tcode{X} (see~\ref{container.requirements.general}, below) & - compile time \\ \rowsep - -\tcode{X::reference} & - \tcode{T\&} & - & - & - compile time \\ \rowsep - -\tcode{X::const_reference} & - \tcode{const T\&} & - & - & - compile time \\ \rowsep - -\tcode{X::iterator} & - iterator type whose value type is \tcode{T} & - & - any iterator category - that meets the forward iterator requirements. - convertible to \tcode{X::const_iterator}. & - compile time \\ \rowsep - -\tcode{X::const_iterator} & - constant iterator type whose value type is \tcode{T} & - & - any iterator category - that meets the forward iterator requirements. & - compile time \\ \rowsep - -\tcode{X::dif\-ference_type} & - signed integer type & - & - is identical to the difference type of \tcode{X::iterator} and \tcode{X::const_iterator} & - compile time \\ \rowsep - -\tcode{X::size_type} & - unsigned integer type & - & - \tcode{size_type} can represent any non-negative value of \tcode{difference_type} & - compile time \\ \rowsep - -\tcode{X u;} & - & - & - post: \tcode{u.empty()} & - constant \\ \rowsep - -\tcode{X()} & - & - & - post: \tcode{X().empty()} & - constant \\ \rowsep - -\tcode{X(a)} & - & - & - \requires \tcode{T} is \tcode{CopyInsertable} - into \tcode{X} (see below).\br post: \tcode{a == X(a)}. & - linear \\ \rowsep - -\tcode{X u(a)}\br -\tcode{X u = a;} & - & - & - \requires \tcode{T} is \tcode{CopyInsertable} - into \tcode{X} (see below).\br - post: \tcode{u == a} & - linear \\ \rowsep - -\tcode{X u(rv)}\br -\tcode{X u = rv} & - & - & - post: \tcode{u} shall be equal to the value that \tcode{rv} had before this construction - & - (Note B) \\ \rowsep - -\tcode{a = rv} & - \tcode{X\&} & - All existing elements of \tcode{a} are either move assigned to or destroyed & - \tcode{a} shall be equal to the value that \tcode{rv} - had before this assignment & - linear \\ \rowsep - -\tcode{(\&a)->\~X()} & - \tcode{void} & - & - note: the destructor is applied to every element of \tcode{a}; any memory obtained is deallocated. & - linear \\ \rowsep - -\tcode{a.begin()} & - \tcode{iterator}; \tcode{const_iterator} for constant \tcode{a} & - & - & - constant \\ \rowsep - -\tcode{a.end()} & - \tcode{iterator}; \tcode{const_iterator} for constant \tcode{a} & - & - & - constant \\ \rowsep - -\tcode{a.cbegin()} & - \tcode{const_iterator} & - \tcode{const_cast(a).begin();} & - & - constant \\ \rowsep - -\tcode{a.cend()} & - \tcode{const_iterator} & - \tcode{const_cast(a).end();} & - & - constant \\ \rowsep - -\tcode{a == b} & - convertible to \tcode{bool} & - \tcode{==} is an equivalence relation. - - \tcode{equal(a.begin(),} - \tcode{a.end(), b.begin(),} - \tcode{b.end())} & - \requires\ \tcode{T} is \tcode{EqualityComparable} & - Constant if \tcode{a.size() != b.size()}, - linear otherwise \\ \rowsep - -\tcode{a != b} & - convertible to \tcode{bool} & - Equivalent to: \tcode{!(a == b)} & - & - linear \\ \rowsep - -\tcode{a.swap(b)} & - \tcode{void} & - & - exchanges the contents of \tcode{a} and \tcode{b} & - (Note A) \\ \rowsep - -\tcode{swap(a, b)} & - \tcode{void} & - \tcode{a.swap(b)} & - & - (Note A) \\ \rowsep - -\tcode{r = a} & - \tcode{X\&} & - & - post: \tcode{r == a}. & - linear \\ \rowsep - -\tcode{a.size()} & - \tcode{size_type} & - \tcode{distance(a.begin(),} - \tcode{a.end())} & - & - constant \\ \rowsep - -\tcode{a.max_size()} & - \tcode{size_type} & - \tcode{distance(begin(),} - \tcode{end())} - for the largest possible container & - & - constant \\ \rowsep - -\tcode{a.empty()} & - convertible to \tcode{bool} & - \tcode{a.begin() ==} - \tcode{a.end()} & - & -constant \\ - -\end{libreqtab5} - -Notes: the algorithm -\tcode{equal()} -is defined in Clause~\ref{algorithms}. -Those entries marked ``(Note A)'' or ``(Note B)'' -have linear complexity for \tcode{array} and have constant complexity -for all other standard containers. - -\pnum -The member function \tcode{size()} returns the number of elements in the container. -The number of elements is defined by the rules of -constructors, inserts, and erases. - -\pnum -\tcode{begin()} -returns an iterator referring to the first element in the container. -\tcode{end()} -returns an iterator which is the past-the-end value for the container. -If the container is empty, then -\tcode{begin() == end()}; - -\pnum -In the expressions -\begin{codeblock} -i == j -i != j -i < j -i <= j -i >= j -i > j -i - j -\end{codeblock} -where \tcode{i} and \tcode{j} denote objects of a container's \tcode{iterator} -type, either or both may be replaced by an object of the container's -\tcode{const_iterator} type referring to the same element with no change in semantics. +\end{note} -\pnum -Unless otherwise specified, all containers defined in this clause obtain memory -using an allocator (see~\ref{allocator.requirements}). -Copy constructors for these container types obtain an allocator by calling -\tcode{allocator_traits::select_on_container_copy_construction} -on the allocator belonging to the container being copied. -Move constructors obtain an allocator by move construction from the allocator belonging to -the container being moved. Such move construction of the allocator shall not exit via an -exception. -All other constructors for these container types take a -\tcode{const allocator_type\&} argument. -\enternote If an invocation of a constructor uses the default value of an optional -allocator argument, then the \tcode{Allocator} type must support value initialization. -\exitnote -A copy of this allocator is used for any memory allocation performed, by these -constructors and by all 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 -copy assignment, move assignment, or swapping of the allocator only if -\tcode{allocator_traits::propagate_on_container_copy_assignment::value}, -\tcode{allocator_traits::propagate_on_container_move_assignment::value}, -or \tcode{alloca\-tor_traits::propagate_on_container_swap::value} is true -within the implementation of the corresponding container operation. -In all container types defined in this Clause, the member \tcode{get_allocator()} -returns a copy of the allocator used to construct the container or, if that allocator -has been replaced, a copy of the most recent replacement. +\rSec2[container.requirements.general]{General containers} -\pnum -The expression \tcode{a.swap(b)}, for containers \tcode{a} and \tcode{b} of a standard -container type other than \tcode{array}, shall exchange the values of \tcode{a} and -\tcode{b} without invoking any move, copy, or swap operations on the individual -container elements. -Lvalues of any \tcode{Compare}, \tcode{Pred}, or \tcode{Hash} types -belonging to \tcode{a} and \tcode{b} shall be swappable -and shall be exchanged by calling \tcode{swap} -as described in~\ref{swappable.requirements}. If -\tcode{allocator_traits::propagate_on_container_swap::value} is -\tcode{true}, then -lvalues of type \tcode{allocator_type} shall be swappable and -the allocators of \tcode{a} and \tcode{b} shall also be exchanged -by calling \tcode{swap} as described in~\ref{swappable.requirements}. -Otherwise, the allocators shall not be swapped, and the behavior is -undefined unless \tcode{a.get_allocator() == b.get_allocator()}. Every iterator -referring to an element in one container before the swap shall refer to the same -element in the other container after the swap. It is unspecified whether an iterator -with value \tcode{a.end()} before the swap will have value \tcode{b.end()} after the -swap. +\rSec3[container.intro.reqmts]{Introduction} \pnum -If the iterator type of a container belongs to the bidirectional or -random access iterator categories~(\ref{iterator.requirements}), -the container is called -\term{reversible} -and satisfies the additional requirements -in Table~\ref{tab:containers.reversible.requirements}. - -\begin{libreqtab4a} -{Reversible container requirements} -{tab:containers.reversible.requirements} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & -\chdr{Assertion/note} & \rhdr{Complexity} \\ - & & \chdr{pre-/post-condition} & \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & -\chdr{Assertion/note} & \rhdr{Complexity} \\ - & & \chdr{pre-/post-condition} & \\ \capsep -\endhead -\tcode{X::reverse_iterator} & -iterator type whose value type is \tcode{T} & - \tcode{reverse_iterator} & - compile time \\ \rowsep -\tcode{X::const_reverse_iterator} & - constant iterator type whose value type is \tcode{T} & - \tcode{reverse_iterator} & - compile time \\ \rowsep -\tcode{a.rbegin()} & - \tcode{reverse_iterator; const_reverse_iterator} for constant \tcode{a} & - \tcode{reverse_iterator(end())} & - constant \\ \rowsep -\tcode{a.rend()} & - \tcode{reverse_iterator; const_reverse_iterator} for constant \tcode{a} & - \tcode{reverse_iterator(begin())} & - constant \\ \rowsep -\tcode{a.crbegin()} & - \tcode{const_reverse_iterator} & - \tcode{const_cast(a).rbegin()} & - constant \\ \rowsep -\tcode{a.crend()} & - \tcode{const_reverse_iterator} & - \tcode{const_cast(a).rend()} & - constant \\ \rowsep -\end{libreqtab4a} - -\pnum -Unless otherwise specified (see~\ref{associative.reqmts.except}, \ref{unord.req.except}, \ref{deque.modifiers}, and -\ref{vector.modifiers}) -all container types defined in this Clause meet -the following additional requirements: - +In \ref{container.requirements.general}, \begin{itemize} \item -if an exception is thrown by an -\tcode{insert()} or \tcode{emplace()} -function while inserting a single element, that -function has no effects. +\tcode{X} denotes a container class containing objects of type \tcode{T}, \item -if an exception is thrown by a -\tcode{push_back()}, -\tcode{push_front()}, -\tcode{emplace_back()}, or \tcode{emplace_front()} -function, that function has no effects. +\tcode{a} denotes a value of type \tcode{X}, \item -no -\tcode{erase()}, -\tcode{clear()}, -\tcode{pop_back()} -or -\tcode{pop_front()} -function throws an exception. +\tcode{b} and \tcode{c} denote values of type (possibly const) \tcode{X}, \item -no copy constructor or assignment operator of a returned iterator -throws an exception. +\tcode{i} and \tcode{j} denote values of type (possibly const) \tcode{X::iterator}, \item -no -\tcode{swap()} -function throws an exception. +\tcode{u} denotes an identifier, \item -no -\tcode{swap()} -function invalidates any references, -pointers, or iterators referring to the elements -of the containers being swapped. \enternote The \tcode{end()} iterator does not refer to any element, so it may be invalidated. \exitnote +\tcode{v} denotes an lvalue of type (possibly const) \tcode{X} or +an rvalue of type \tcode{const X}, +\item +\tcode{s} and \tcode{t} denote non-const lvalues of type \tcode{X}, and +\item +\tcode{rv} denotes a non-const rvalue of type \tcode{X}. \end{itemize} \pnum -Unless otherwise specified (either explicitly or by defining a -function in terms of other functions), invoking a container member -function or passing a container as an argument to a library function -shall not invalidate iterators to, or change the values of, objects -within that container. - -\pnum -\indextext{container!contiguous}% -A \defn{contiguous container} -is a container that supports random access iterators~(\ref{random.access.iterators}) -and whose member types \tcode{iterator} and \tcode{const_iterator} -are contiguous iterators~(\ref{iterator.requirements.general}). - -\pnum -Table~\ref{tab:containers.optional.operations} lists operations that are provided -for some types of containers but not others. Those containers for which the -listed operations are provided shall implement the semantics described in -Table~\ref{tab:containers.optional.operations} unless otherwise stated. - -\begin{libreqtab5} -{Optional container operations} -{tab:containers.optional.operations} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & -\chdr{Assertion/note} & \rhdr{Complexity} \\ - & & \chdr{semantics} & \chdr{pre-/post-condition} & \\ \capsep -\endfirsthead -\continuedcaption\\ -\topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & -\chdr{Assertion/note} & \rhdr{Complexity} \\ - & & \chdr{semantics} & \chdr{pre-/post-condition} & \\ \capsep -\endhead - -\tcode{a < b} & - convertible to \tcode{bool} & - \tcode{lexicographical_compare( a.begin(), a.end(), b.begin(), b.end())} & - pre: \tcode{<} is defined for values of \tcode{T}. \tcode{<} is a total ordering relationship. & - linear \\ \rowsep - -\tcode{a > b} & - convertible to \tcode{bool} & - \tcode{b < a} & - & - linear \\ \rowsep - -\tcode{a <= b} & - convertible to \tcode{bool} & - \tcode{!(a > b)} & - & - linear \\ \rowsep - -\tcode{a >= b} & - convertible to \tcode{bool} & - \tcode{!(a < b)} & - & - linear \\ -\end{libreqtab5} - -Note: the algorithm -\tcode{lexicographical_compare()} -is defined in Clause~\ref{algorithms}. - -\pnum -All of the containers defined in this Clause and in~(\ref{basic.string}) except \tcode{array} -meet the additional requirements of an allocator-aware container, as described in -Table~\ref{tab:containers.allocatoraware}. - -Given a container type \tcode{X} having an \tcode{allocator_type} -identical to \tcode{A} and a -\tcode{value_type} identical to \tcode{T} and given -an lvalue \tcode{m} of type \tcode{A}, a -pointer \tcode{p} of type \tcode{T*}, -an expression \tcode{v} of type (possibly const) \tcode{T}, and -an rvalue \tcode{rv} of type -\tcode{T}, the following terms are defined. If \tcode{X} -is not allocator-aware, the terms below are defined as if \tcode{A} were -\tcode{std::allocator} --- no allocator object needs to be created -and user specializations of \tcode{std::allocator} are not instantiated: - -\begin{itemize} -\item -\tcode{T} is \defnx{\tcode{DefaultInsertable} into \tcode{X}} -{DefaultInsertable into X@\tcode{DefaultInsertable} into \tcode{X}} -means that the following expression is well-formed: -\begin{codeblock} -allocator_traits::construct(m, p) -\end{codeblock} - -\item -An element of \tcode{X} is \defn{default-inserted} if it is initialized -by evaluation of the expression -\begin{codeblock} -allocator_traits::construct(m, p) -\end{codeblock} -where \tcode{p} is the address of the uninitialized storage for the element -allocated within \tcode{X}. - -\item -\tcode{T} is \defnx{\tcode{MoveInsertable} into \tcode{X}} -{MoveInsertable into X@\tcode{MoveInsertable} into \tcode{X}} -means that the following expression -is well-formed: +The following exposition-only concept is used in the definition of containers: \begin{codeblock} -allocator_traits::construct(m, p, rv) +template +concept @\defexposconcept{container-compatible-range}@ = // \expos + ranges::@\libconcept{input_range}@ && @\libconcept{convertible_to}@, T>; \end{codeblock} -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. -\enternote rv remains a valid object. Its state is unspecified \exitnote -\item -\tcode{T} is \defnx{\tcode{CopyInsertable} into \tcode{X}} -{CopyInsertable into X@\tcode{CopyInsertable} into \tcode{X}} -means that, in addition to \tcode{T} being \tcode{MoveInsertable} into -\tcode{X}, the following expression is well-formed: -\begin{codeblock} -allocator_traits::construct(m, p, v) -\end{codeblock} -and its evaluation causes the following postcondition to hold: -The value of \tcode{v} is unchanged and is equivalent to \tcode{*p}. +\rSec3[container.reqmts]{Container requirements} + +% Local command to index names as members of all containers. +\newcommand{\indexcont}[1]{% +\indexlibrarymisc{\idxcode{#1}}{containers}% +\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}% +\indexlibrarymemberx{multimap}{#1}% +\indexlibrarymemberx{unordered_map}{#1}% +\indexlibrarymemberx{unordered_set}{#1}% +\indexlibrarymemberx{unordered_multiset}{#1}% +\indexlibrarymemberx{unordered_multimap}{#1}% +\indexlibrarymemberx{flat_map}{#1}% +\indexlibrarymemberx{flat_set}{#1}% +\indexlibrarymemberx{flat_multiset}{#1}% +\indexlibrarymemberx{flat_multimap}{#1}% +} -\item -\tcode{T} is -\defnx{\tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}} -{EmplaceConstructible into X from args@\tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}}, -for zero -or more arguments \tcode{args}, means that the following expression is well-formed: -\begin{codeblock} -allocator_traits::construct(m, p, args) -\end{codeblock} +\pnum +A type \tcode{X} meets the \defn{container} requirements +if the following types, statements, and expressions are well-formed and +have the specified semantics. -\item -\tcode{T} is -\defnx{\tcode{Erasable} from \tcode{X}} -{Erasable from X@\tcode{Erasable} from \tcode{X}} -means that the following expression is well-formed: -\begin{codeblock} -allocator_traits::destroy(m, p) -\end{codeblock} -\end{itemize} +\indexcont{value_type}% +\begin{itemdecl} +typename X::value_type +\end{itemdecl} -\enternote -A container calls \tcode{allocator_traits::construct(m, p, args)} to construct an element -at \tcode{p} using \tcode{args}. The default \tcode{construct} in \tcode{std::allocator} will -call \tcode{::new((void*)p) T(args)}, but specialized allocators may choose a different -definition. -\exitnote +\begin{itemdescr} +\pnum +\result +\tcode{T} \pnum -In Table~\ref{tab:containers.allocatoraware}, \tcode{X} denotes an allocator-aware container class -with a \tcode{value_type} of \tcode{T} using allocator of type \tcode{A}, \tcode{u} denotes a -variable, -\tcode{a} and \tcode{b} denote non-const lvalues of type \tcode{X}, -\tcode{t} denotes an lvalue or a const rvalue of type \tcode{X}, \tcode{rv} denotes a -non-const rvalue of type \tcode{X}, and \tcode{m} is a value of type \tcode{A}. - -\begin{libreqtab4a} -{Allocator-aware container requirements} -{tab:containers.allocatoraware} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & -\chdr{Assertion/note} & \rhdr{Complexity} \\ - & & \chdr{pre-/post-condition} & \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline - -\lhdr{Expression} & \chdr{Return type} & -\chdr{Assertion/note} & \rhdr{Complexity} \\ - & & \chdr{pre-/post-condition} & \\ \capsep -\endhead - -\tcode{allocator_type} & - \tcode{A} & - \requires \tcode{allocator_type::value_type} is the same as \tcode{X::value_type}. & - compile time \\ \rowsep - -\tcode{get_-} \tcode{allocator()} & - \tcode{A} & - & - constant \\ \rowsep - -\tcode{X()}\br -\tcode{X u;} & - & - \requires\ \tcode{A} is \tcode{DefaultConstructible}.\br - post: \tcode{u.empty()} returns \tcode{true}, - \tcode{u.get_allocator() == A()} & - constant \\ \rowsep - -\tcode{X(m)} & - & -post: \tcode{u.empty()} returns \tcode{true}, & -constant \\ -\tcode{X u(m);} & - & -\tcode{u.get_allocator() == m} & - \\ \rowsep - -\tcode{X(t, m)}\br -\tcode{X u(t, m);} & - & -\requires\ \tcode{T} is \tcode{CopyInsertable} into \tcode{X}.\br -post: \tcode{u == t}, \tcode{u.get_allocator() == m} & -linear \\ \rowsep - -\tcode{X(rv)}\br -\tcode{X u(rv)} - & - & - \requires move construction of \tcode{A} shall not exit via an exception.\br - post: \tcode{u} shall have the same elements as \tcode{rv} had before this - construction; the value of \tcode{u.get_allocator()} shall be the same as the - value of \tcode{rv.get_allocator()} before this construction. & - constant \\ \rowsep - -\tcode{X(rv, m)}\br -\tcode{X u(rv, m);} & - & - \requires\ \tcode{T} is - \tcode{MoveInsertable} into \tcode{X}.\br - post: \tcode{u} shall have the same elements, - or copies of the elements, that \tcode{rv} had before - this construction, \tcode{u.get_allocator() == m} & - constant if \tcode{m ==} \tcode{rv.get_allocator()}, otherwise linear \\ \rowsep - -\tcode{a = t} & - \tcode{X\&} & - \requires\ \tcode{T} is - \tcode{CopyInsertable} into \tcode{X} - and \tcode{CopyAssignable}.\br - post: \tcode{a == t} & - linear \\ \rowsep - -\tcode{a = rv} & - \tcode{X\&} & - \requires\ If \tcode{allocator_-}\br - \tcode{traits}\br - \tcode{::propagate_on_container_-}\br - \tcode{move_assignment::value} is\br - \tcode{false}, \tcode{T} is - \tcode{MoveInsertable} into \tcode{X} and - \tcode{MoveAssignable}. All existing elements of \tcode{a} - are either move assigned to or destroyed.\br - post: \tcode{a} shall be equal to the value that \tcode{rv} had before - this assignment. & - linear \\ \rowsep - -\tcode{a.swap(b)} & - \tcode{void} & - exchanges the contents of \tcode{a} and \tcode{b} & - constant \\ \rowsep - -\end{libreqtab4a} +\expects +\tcode{T} is \oldconcept{Erasable} from \tcode{X} +(see~\ref{container.alloc.reqmts}, below). +\end{itemdescr} -\rSec2[container.requirements.dataraces]{Container data races} +\indexcont{reference}% +\begin{itemdecl} +typename X::reference +\end{itemdecl} +\begin{itemdescr} \pnum -For purposes of avoiding data races~(\ref{res.on.data.races}), implementations shall -consider the following functions to be \tcode{const}: \tcode{begin}, \tcode{end}, -\tcode{rbegin}, \tcode{rend}, \tcode{front}, \tcode{back}, \tcode{data}, \tcode{find}, -\tcode{lower_bound}, \tcode{upper_bound}, \tcode{equal_range}, \tcode{at} and, except in -associative or unordered associative containers, \tcode{operator[]}. +\result +\tcode{T\&} +\end{itemdescr} -\pnum -Notwithstanding~(\ref{res.on.data.races}), implementations are required to avoid data -races when the contents of the contained object in different elements in the same -container, excepting \tcode{vector}, are modified concurrently. +\indexcont{const_reference}% +\begin{itemdecl} +typename X::const_reference +\end{itemdecl} +\begin{itemdescr} \pnum -\enternote For a \tcode{vector x} with a size greater than one, \tcode{x[1] = 5} -and \tcode{*x.begin() = 10} can be executed concurrently without a data race, but -\tcode{x[0] = 5} and \tcode{*x.begin() = 10} executed concurrently may result in a data -race. -As an exception to the general rule, for a \tcode{vector y}, \tcode{y[0] = true} -may race with \tcode{y[1] = true}. -\exitnote +\result +\tcode{const T\&} +\end{itemdescr} -\rSec2[sequence.reqmts]{Sequence containers} +\indexcont{iterator}% +\begin{itemdecl} +typename X::iterator +\end{itemdecl} +\begin{itemdescr} \pnum -A sequence container organizes a finite set of objects, all of the same type, into a strictly -linear arrangement. The library provides four basic kinds of sequence containers: -\tcode{vector}, \tcode{forward_list}, \tcode{list}, and \tcode{deque}. In addition, -\tcode{array} is provided as a sequence container which provides limited sequence operations -because it has a fixed number of elements. The library also provides container adaptors that -make it easy to construct abstract data types, such as \tcode{stack}s or \tcode{queue}s, out of -the basic sequence container kinds (or out of other kinds of sequence containers that the user -might define). - -\pnum -The sequence containers -offer the programmer different complexity trade-offs and should be used -accordingly. -\tcode{vector} or \tcode{array} -is the type of sequence container that should be used by default. -\tcode{list} or \tcode{forward_list} -should be used when there are frequent insertions and deletions from the -middle of the sequence. -\tcode{deque} -is the data structure of choice -when most insertions and deletions take place at the beginning or at the -end of the sequence. +\result +A type that meets the forward iterator requirements\iref{forward.iterators} +with value type \tcode{T}. +The type \tcode{X::iterator} is convertible to \tcode{X::const_iterator}. +\end{itemdescr} -\pnum -In Tables~\ref{tab:containers.sequence.requirements} -and \ref{tab:containers.sequence.optional}, -\tcode{X} denotes a sequence container class, -\tcode{a} denotes a value of \tcode{X} containing elements of type \tcode{T}, -\tcode{A} denotes \tcode{X::allocator_type} if -the \grammarterm{qualified-id} \tcode{X::allocator_type} is valid and denotes a -type~(\ref{temp.deduct}) and -\tcode{std::allocator} if it doesn't, -\tcode{i} and \tcode{j} -denote iterators satisfying input iterator requirements -and refer to elements implicitly convertible to \tcode{value_type}, -\tcode{[i, j)} -denotes a valid range, -\tcode{il} designates an object of type \tcode{initializer_list}, -\tcode{n} -denotes a value of \tcode{X::size_type}, -\tcode{p} denotes a valid const iterator to -\tcode{a}, \tcode{q} -denotes a valid dereferenceable const iterator to -\tcode{a}, \tcode{[q1, q2)} -denotes a valid range of const iterators in -\tcode{a}, \tcode{t} -denotes an lvalue or a const rvalue of -\tcode{X::value_type}, and \tcode{rv} denotes -a non-const rvalue of \tcode{X::value_type}. -\tcode{Args} denotes a template parameter pack; -\tcode{args} denotes a function parameter pack with the pattern \tcode{Args\&\&}. +\indexcont{const_iterator}% +\begin{itemdecl} +typename X::const_iterator +\end{itemdecl} +\begin{itemdescr} \pnum -The complexities of the expressions are sequence dependent. +\result +A type that meets the requirements of a constant iterator and +those of a forward iterator with value type \tcode{T}. +\end{itemdescr} -\begin{libreqtab3} -{Sequence container requirements (in addition to container)} -{tab:containers.sequence.requirements} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \rhdr{Assertion/note} \\ - & & \rhdr{pre-/post-condition} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \rhdr{Assertion/note} \\ - & & \rhdr{pre-/post-condition} \\ \capsep -\endhead -\tcode{X(n, t)}\br -\tcode{X a(n, t)} & - & - \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X}.\br - post: \tcode{distance(begin(), end()) == n}\br - Constructs a sequence container with \tcode{n} copies of \tcode{t} \\ \rowsep - -\tcode{X(i, j)}\br -\tcode{X a(i, j)} & - & - \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}. - For \tcode{vector}, if the iterator does - not meet the forward iterator requirements~(\ref{forward.iterators}), \tcode{T} - shall also be - \tcode{MoveInsertable} into \tcode{X}. - Each iterator in the range \range{i}{j} shall be dereferenced exactly once.\br - post: \tcode{distance(begin(), end()) ==} - \tcode{distance(i, j)}\br - Constructs a sequence container equal to the range \tcode{[i, j)} \\ \rowsep - -\tcode{X(il);} & - & - Equivalent to \tcode{X(il.begin(), il.end())} \\ \rowsep - -\tcode{a = il;} & - \tcode{X\&} & - \requires\ \tcode{T} is - \tcode{CopyInsertable} into \tcode{X} - and \tcode{CopyAssignable}. - Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. All existing - elements of \tcode{a} are either assigned to or destroyed.\br - \returns\ \tcode{*this}. - \\ \rowsep - -\tcode{a.emplace(p, args);} & - \tcode{iterator} & - \requires\ \tcode{T} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}. For \tcode{vector} and \tcode{deque}, - T is also - \tcode{MoveInsertable} into \tcode{X} and \tcode{MoveAssignable}. - \effects\ Inserts an object of type \tcode{T} constructed with - \tcode{std::forward(args)...} before \tcode{p}. \\ \rowsep - -\tcode{a.insert(p,t)} & - \tcode{iterator} & - \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X}. For \tcode{vector} and \tcode{deque}, - \tcode{T} shall also be \tcode{CopyAssignable}.\br - \effects\ Inserts a copy of \tcode{t} before \tcode{p}. \\ \rowsep - -\tcode{a.insert(p,rv)} & - \tcode{iterator} & - \requires\ \tcode{T} shall be - \tcode{MoveInsertable} into \tcode{X}. For \tcode{vector} and \tcode{deque}, - \tcode{T} shall also be \tcode{MoveAssignable}.\br - \effects\ Inserts a copy of \tcode{rv} before \tcode{p}. \\ \rowsep - -\tcode{a.insert(p,n,t)} & - \tcode{iterator} & - \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X} - and \tcode{CopyAssignable}.\br - Inserts \tcode{n} copies of \tcode{t} before \tcode{p}. \\ \rowsep - -\tcode{a.insert(p,i,j)} & - \tcode{iterator} & - \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}. - For \tcode{vector} and \tcode{deque}, \tcode{T} shall also be - \tcode{MoveInsertable} into \tcode{X}, \tcode{MoveConstructible}, \tcode{MoveAssignable}, - and swappable~(\ref{swappable.requirements}). - Each iterator in the range \range{i}{j} shall be dereferenced exactly once.\br - pre: \tcode{i} and \tcode{j} are not iterators into \tcode{a}.\br - Inserts copies of elements in \tcode{[i, j)} before \tcode{p} \\ \rowsep - -\tcode{a.insert(p, il);} & - \tcode{iterator} & - \tcode{a.insert(p, il.begin(), il.end())}. \\ \rowsep - -\tcode{a.erase(q)} & - \tcode{iterator} & - \requires\ For \tcode{vector} and \tcode{deque}, - \tcode{T} shall be \tcode{MoveAssignable}.\br - \effects\ Erases the element pointed to by \tcode{q} \\ \rowsep - -\tcode{a.erase(q1,q2)} & - \tcode{iterator} & - \requires\ For \tcode{vector} and \tcode{deque}, - \tcode{T} shall be \tcode{MoveAssignable}.\br - \effects\ Erases the elements in the range \tcode{[q1, q2)}. \\ \rowsep - -\tcode{a.clear()} & - \tcode{void} & - Destroys all elements in \tcode{a}. Invalidates all references, pointers, and - iterators referring to the elements of \tcode{a} and may invalidate the past-the-end iterator.\br - post: \tcode{a.empty()} returns \tcode{true}.\br - \complexity Linear. \\ \rowsep - -\tcode{a.assign(i,j)} & - \tcode{void} & - \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i} - and assignable from \tcode{*i}. For \tcode{vector}, if the iterator does not - meet the forward iterator requirements~(\ref{forward.iterators}), \tcode{T} - shall also be - \tcode{MoveInsertable} into \tcode{X}.\br - Each iterator in the range \range{i}{j} shall be dereferenced exactly once.\br - pre: \tcode{i}, \tcode{j} are not iterators into \tcode{a}.\br - Replaces elements in \tcode{a} with a copy of \tcode{[i, j)}. \\ \rowsep - -\tcode{a.assign(il)} & - \tcode{void} & - \tcode{a.assign(il.begin(), il.end())}. \\ \rowsep - -\tcode{a.assign(n,t)} & - \tcode{void} & - \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X} - and \tcode{CopyAssignable}.\br - pre: \tcode{t} is not a reference into \tcode{a}.\br - Replaces elements in \tcode{a} with \tcode{n} copies of \tcode{t}. \\ -\end{libreqtab3} +\indexcont{difference_type}% +\begin{itemdecl} +typename X::difference_type +\end{itemdecl} +\begin{itemdescr} \pnum -\tcode{iterator} -and -\tcode{const_iterator} -types for sequence containers shall be at least of the forward iterator category. +\result +A signed integer type, +identical to the difference type of +\tcode{X::iterator} and \tcode{X::const_iterator}. +\end{itemdescr} -\pnum -The iterator returned from -\tcode{a.insert(p, t)} -points to the copy of -\tcode{t} -inserted into -\tcode{a}. +\indexcont{size_type}% +\begin{itemdecl} +typename X::size_type +\end{itemdecl} +\begin{itemdescr} \pnum -The iterator returned from \tcode{a.insert(p, rv)} points to the copy of \tcode{rv} -inserted into \tcode{a}. +\result +An unsigned integer type +that can represent any non-negative value of \tcode{X::difference_type}. +\end{itemdescr} +\begin{itemdecl} +X u; +X u = X(); +\end{itemdecl} + +\begin{itemdescr} \pnum -The iterator returned from \tcode{a.insert(p, n, t)} points to the copy of the first -element inserted into \tcode{a}, or \tcode{p} if \tcode{n == 0}. +\ensures +\tcode{u.empty()} \pnum -The iterator returned from \tcode{a.insert(p, i, j)} points to the copy of the first -element inserted into \tcode{a}, or \tcode{p} if \tcode{i == j}. +\complexity +Constant. +\end{itemdescr} + +\begin{itemdecl} +X u(v); +X u = v; +\end{itemdecl} +\begin{itemdescr} \pnum -The iterator returned from \tcode{a.insert(p, il)} points to the copy of the first -element inserted into \tcode{a}, or \tcode{p} if \tcode{il} is empty. +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} (see below). \pnum -The iterator returned from \tcode{a.emplace(p, args)} points to the new element -constructed from \tcode{args} into \tcode{a}. +\ensures +\tcode{u == v}. \pnum -The iterator returned from -\tcode{a.erase(q)} -points to the element immediately following -\tcode{q} -prior to the element being erased. -If no such element exists, -\tcode{a.end()} -is returned. +\complexity +Linear. +\end{itemdescr} + +\begin{itemdecl} +X u(rv); +X u = rv; +\end{itemdecl} +\begin{itemdescr} \pnum -The iterator returned by -\tcode{a.erase(q1,q2)} -points to the element pointed to by -\tcode{q2} -prior to any elements being erased. -If no such element exists, -\tcode{a.end()} -is returned. +\ensures +\tcode{u} is equal to the value that \tcode{rv} had before this construction. \pnum -For every sequence container defined in this Clause and in Clause~\ref{strings}: +\complexity +Linear for \tcode{array} and \tcode{inplace_vector} and constant for all other standard containers. +\end{itemdescr} -\begin{itemize} -\item If the constructor +\indexcont{operator=}% +\begin{itemdecl} +t = v +\end{itemdecl} -\begin{codeblock} -template -X(InputIterator first, InputIterator last, - const allocator_type& alloc = allocator_type()) -\end{codeblock} +\begin{itemdescr} +\pnum +\result +\tcode{X\&}. -is called with a type \tcode{InputIterator} that does not qualify as an input -iterator, then the constructor -shall not participate in overload resolution. +\pnum +\ensures +\tcode{t == v}. -\item If the member functions of the forms: +\pnum +\complexity +Linear. +\end{itemdescr} -\begin{codeblock} -template // such as insert() -rt fx1(const_iterator p, InputIterator first, InputIterator last); +\begin{itemdecl} +t = rv +\end{itemdecl} -template // such as append(), assign() -rt fx2(InputIterator first, InputIterator last); +\begin{itemdescr} +\pnum +\result +\tcode{X\&}. -template // such as replace() -rt fx3(const_iterator i1, const_iterator i2, InputIterator first, InputIterator last); -\end{codeblock} +\pnum +\effects +All existing elements of \tcode{t} are either move assigned to or destroyed. -are called with a type \tcode{InputIterator} that does not qualify as an input -iterator, then these functions -shall not participate in overload resolution. -\end{itemize} +\pnum +\ensures +If \tcode{t} and \tcode{rv} do not refer to the same object, +\tcode{t} is equal to the value that \tcode{rv} had before this assignment. \pnum -The extent to which an implementation determines that a type cannot be an input -iterator is unspecified, except that as a minimum integral types shall not qualify -as input iterators. +\complexity +Linear. +\end{itemdescr} + +\begin{itemdecl} +a.~X() +\end{itemdecl} +\begin{itemdescr} \pnum -Table~\ref{tab:containers.sequence.optional} lists operations -that are provided for some types of -sequence containers but not others. -An implementation shall provide -these operations for all container types shown in the ``container'' -column, and shall implement them so as to take amortized constant -time. - -\begin{libreqtab4a} -{Optional sequence container operations} -{tab:containers.sequence.optional} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational semantics} & \rhdr{Container} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \chdr{Operational semantics} & \rhdr{Container} \\ \capsep -\endhead - -\tcode{a.front()} & - \tcode{reference; const_reference} for constant \tcode{a} & - \tcode{*a.begin()} & - \tcode{basic_string}, - \tcode{array}, - \tcode{deque}, - \tcode{forward_list}, - \tcode{list}, - \tcode{vector} - \\ \rowsep - -\tcode{a.back()} & - \tcode{reference; const_reference} for constant \tcode{a} & - \tcode{\{ auto tmp = a.end();}\br - \tcode{ \dcr tmp;}\br - \tcode{ return *tmp; \}} & - \tcode{basic_string}, - \tcode{array}, - \tcode{deque}, - \tcode{list}, - \tcode{vector} - \\ \rowsep - -\tcode{a.emplace_-} \tcode{front(args)} & - \tcode{void} & - Prepends an object of type \tcode{T} constructed with \tcode{std::forward(args)...}.\br - \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}. & - \tcode{deque}, - \tcode{forward_list}, - \tcode{list} - \\ \rowsep - -\tcode{a.emplace_-} \tcode{back(args)} & - \tcode{void} & - Appends an object of type \tcode{T} constructed with \tcode{std::forward(args)...}.\br - \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}. For \tcode{vector}, \tcode{T} - shall also be - \tcode{MoveInsertable} into \tcode{X}. - & - \tcode{deque}, - \tcode{list}, - \tcode{vector} - \\ \rowsep - -\tcode{a.push_front(t)} & - \tcode{void} & - Prepends a copy of \tcode{t}.\br - \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X}. - & - \tcode{deque}, - \tcode{forward_list}, - \tcode{list} - \\ \rowsep - -\tcode{a.push_front(rv)} & - \tcode{void} & - Prepends a copy of \tcode{rv}.\br - \requires\ \tcode{T} shall be - \tcode{MoveInsertable} into \tcode{X}. - & - \tcode{deque}, - \tcode{forward_list}, - \tcode{list} - \\ \rowsep - -\tcode{a.push_back(t)} & - \tcode{void} & - Appends a copy of \tcode{t}.\br - \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X}. - & - \tcode{basic_string}, - \tcode{deque}, - \tcode{list}, - \tcode{vector} - \\ \rowsep - -\tcode{a.push_back(rv)} & - \tcode{void} & - Appends a copy of \tcode{rv}.\br - \requires\ \tcode{T} shall be - \tcode{MoveInsertable} into \tcode{X}. - & - \tcode{basic_string}, - \tcode{deque}, - \tcode{list}, - \tcode{vector} - \\ \rowsep - -\tcode{a.pop_front()} & - \tcode{void} & - Destroys the first element.\br - \requires\ \tcode{a.empty()} shall be \tcode{false}. & - \tcode{deque}, - \tcode{forward_list}, - \tcode{list} - \\ \rowsep - -\tcode{a.pop_back()} & - \tcode{void} & - Destroys the last element.\br - \requires\ \tcode{a.empty()} shall be \tcode{false}. & - \tcode{basic_string}, - \tcode{deque}, - \tcode{list}, - \tcode{vector} - \\ \rowsep - -\tcode{a[n]} & - \tcode{reference; const_reference} for constant \tcode{a} & - \tcode{*(a.begin() + n)} & - \tcode{basic_string}, - \tcode{array}, - \tcode{deque}, - \tcode{vector} - \\ \rowsep - -\tcode{a.at(n)} & - \tcode{reference; const_reference} for constant \tcode{a} & - \tcode{*(a.begin() + n)} & - \tcode{basic_string}, - \tcode{array}, - \tcode{deque}, - \tcode{vector} - \\ - -\end{libreqtab4a} - -\pnum -The member function -\tcode{at()} -provides bounds-checked access to container elements. -\tcode{at()} -throws -\tcode{out_of_range} -if -\tcode{n >= a.size()}. +\result +\keyword{void}. -\rSec2[associative.reqmts]{Associative containers} +\pnum +\effects +Destroys every element of \tcode{a}; any memory obtained is deallocated. \pnum -Associative containers provide fast retrieval of data based on keys. +\complexity +Linear. +\end{itemdescr} + +\indexcont{begin}% +\begin{itemdecl} +b.begin() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}; +\tcode{const_iterator} for constant \tcode{b}. + +\pnum +\returns +An iterator referring to the first element in the container. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexcont{end}% +\begin{itemdecl} +b.end() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}; +\tcode{const_iterator} for constant \tcode{b}. + +\pnum +\returns +An iterator which is the past-the-end value for the container. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexcont{cbegin}% +\begin{itemdecl} +b.cbegin() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{const_iterator}. + +\pnum +\returns +\tcode{const_cast(b).begin()} + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexcont{cend}% +\begin{itemdecl} +b.cend() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{const_iterator}. + +\pnum +\returns +\tcode{const_cast(b).end()} + +\pnum +\complexity +Constant. +\end{itemdescr} + +\begin{itemdecl} +i <=> j +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{strong_ordering}. + +\pnum +\constraints +\tcode{X::iterator} meets the random access iterator requirements. + +\pnum +\complexity +Constant. +\end{itemdescr} + +% 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} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} meets the \oldconcept{EqualityComparable} requirements. + +\pnum +\result +\tcode{bool}. + +\pnum +\returns +\tcode{equal(c.begin(), c.end(), b.begin(), b.end())} + +\begin{note} +The algorithm \tcode{equal} is defined in \ref{alg.equal}. +\end{note} + +\pnum +\complexity +Constant if \tcode{c.size() != b.size()}, linear otherwise. + +\pnum +\remarks +\tcode{==} is an equivalence relation. +\end{itemdescr} + +% 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} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{!(c == b)}. +\end{itemdescr} + +\indexcont{swap}% +\begin{itemdecl} +t.swap(s) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void}. + +\pnum +\effects +Exchanges the contents of \tcode{t} and \tcode{s}. + +\pnum +\complexity +Linear for \tcode{array} and \tcode{inplace_vector}, and +constant for all other standard containers. +\end{itemdescr} + +\begin{itemdecl} +swap(t, s) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{t.swap(s)}. +\end{itemdescr} + +\indexcont{size}% +\begin{itemdecl} +c.size() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type}. + +\pnum +\returns +\tcode{distance(c.begin(), c.end())}, +i.e., the number of elements in the container. + +\pnum +\complexity +Constant. + +\pnum +\remarks +The number of elements is defined by the rules of +constructors, inserts, and erases. +\end{itemdescr} + +\indexcont{max_size}% +\begin{itemdecl} +c.max_size() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type}. + +\pnum +\returns +\tcode{distance(begin(), end())} for the largest possible container. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexcont{empty}% +\begin{itemdecl} +c.empty() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool}. + +\pnum +\returns +\tcode{c.begin() == c.end()} + +\pnum +\complexity +Constant. + +\pnum +\remarks +If the container is empty, then \tcode{c.empty()} is \tcode{true}. +\end{itemdescr} + +\pnum +In the expressions +\begin{codeblock} +i == j +i != j +i < j +i <= j +i >= j +i > j +i <=> j +i - j +\end{codeblock} +where \tcode{i} and \tcode{j} denote objects of a container's \tcode{iterator} +type, either or both may be replaced by an object of the container's +\tcode{const_iterator} type referring to the same element with no change in semantics. + +\pnum +Unless otherwise specified, all containers defined in this Clause obtain memory +using an allocator (see~\ref{allocator.requirements}). +\begin{note} +In particular, containers and iterators do not store references +to allocated elements other than through the allocator's pointer type, +i.e., as objects of type \tcode{P} or +\tcode{pointer_traits

::template re\-bind<\unspec>}, +where \tcode{P} is \tcode{allocator_traits::pointer}. +\end{note} +Copy constructors for these container types obtain an allocator by calling +\tcode{allocator_traits::select_on_container_copy_construction} +on the allocator belonging to the container being copied. +Move constructors obtain an allocator by move construction from the allocator belonging to +the container being moved. Such move construction of the allocator shall not exit via an +exception. +All other constructors for these container types take a +\tcode{const allocator_type\&} argument. +\begin{note} +If an invocation of a constructor uses the default value of an optional +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 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 +copy assignment, move assignment, or swapping of the allocator only if +\begin{itemize} +\item \tcode{allocator_traits::propagate_on_container_copy_assignment::value}, +\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 container operation. +In all container types defined in this Clause, the member \tcode{get_allocator()} +returns a copy of the allocator used to construct the container or, if that allocator +has been replaced, a copy of the most recent replacement. + +\pnum +The expression \tcode{a.swap(b)}, for containers \tcode{a} and \tcode{b} of a standard +container type other than \tcode{array} and \tcode{inplace_vector}, +shall exchange the values of \tcode{a} and +\tcode{b} without invoking any move, copy, or swap operations on the individual +container elements. +Any \tcode{Compare}, \tcode{Pred}, or \tcode{Hash} types +belonging to \tcode{a} and \tcode{b} shall meet the \oldconcept{Swappable} requirements +and shall be exchanged by calling \tcode{swap} +as described in~\ref{swappable.requirements}. If +\tcode{allocator_traits::propagate_on_container_swap::value} is +\tcode{true}, then +\tcode{allocator_type} shall meet the \oldconcept{Swap\-pable} requirements and +the allocators of \tcode{a} and \tcode{b} shall also be exchanged +by calling \tcode{swap} as described in~\ref{swappable.requirements}. +Otherwise, the allocators shall not be swapped, and the behavior is +undefined unless \tcode{a.get_allocator() == b.get_allocator()}. Every iterator +referring to an element in one container before the swap shall refer to the same +element in the other container after the swap. It is unspecified whether an iterator +with value \tcode{a.end()} before the swap will have value \tcode{b.end()} after the +swap. + +\pnum +Unless otherwise specified (see~\ref{associative.reqmts.except}, \ref{unord.req.except}, \ref{deque.modifiers}, \ref{inplace.vector.modifiers}, and +\ref{vector.modifiers}) +all container types defined in this Clause meet +the following additional requirements: + +\begin{itemize} +\item +If an exception is thrown by an +\tcode{insert()} or \tcode{emplace()} +function while inserting a single element, that +function has no effects. +\item +If an exception is thrown by a +\tcode{push_back()}, +\tcode{push_front()}, +\tcode{emplace_back()}, or \tcode{emplace_front()} +function, that function has no effects. +\item +No +\tcode{erase()}, +\tcode{clear()}, +\tcode{pop_back()} +or +\tcode{pop_front()} +function throws an exception. +\item +No copy constructor or assignment operator of a returned iterator +throws an exception. +\item +No +\tcode{swap()} +function throws an exception. +\item +No +\tcode{swap()} +function invalidates any references, +pointers, or iterators referring to the elements +of the containers being swapped. +\begin{note} +The \tcode{end()} iterator does not refer to any element, so it can be invalidated. +\end{note} +\end{itemize} + +\pnum +Unless otherwise specified (either explicitly or by defining a +function in terms of other functions), invoking a container member +function or passing a container as an argument to a library function +shall not invalidate iterators to, or change the values of, objects +within that container. + +\pnum +A \defnadj{contiguous}{container} +is a container +whose member types \tcode{iterator} and \tcode{const_iterator} +meet the +\oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} and +model \libconcept{contiguous_iterator}\iref{iterator.concept.contiguous}. + +\pnum +The behavior of certain container member functions and deduction guides +depends on whether types qualify as input iterators or allocators. +The extent to which an implementation determines that a type cannot be an input +iterator is unspecified, except that as a minimum integral types shall not qualify +as input iterators. +Likewise, the extent to which an implementation determines that a type cannot be +an allocator is unspecified, except that as a minimum a type \tcode{A} shall not qualify +as an allocator unless it meets both of the following conditions: + +\begin{itemize} +\item The \grammarterm{qualified-id} \tcode{A::value_type} +is valid and denotes a type\iref{temp.deduct}. + +\item The expression \tcode{declval().allocate(size_t\{\})} +is well-formed when treated as an unevaluated operand. +\end{itemize} + +\rSec3[container.rev.reqmts]{Reversible container requirements} + +% Local command to index names as members of all containers. +\renewcommand{\indexcont}[1]{% +\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}% +\indexlibrarymemberx{multimap}{#1}% +\indexlibrarymemberx{unordered_map}{#1}% +\indexlibrarymemberx{unordered_set}{#1}% +\indexlibrarymemberx{unordered_multiset}{#1}% +\indexlibrarymemberx{unordered_multimap}{#1}% +\indexlibrarymemberx{flat_map}{#1}% +\indexlibrarymemberx{flat_set}{#1}% +\indexlibrarymemberx{flat_multiset}{#1}% +\indexlibrarymemberx{flat_multimap}{#1}% +} + +\pnum +A type \tcode{X} meets the \defnadj{reversible}{container} requirements if +\tcode{X} meets the container requirements, +the iterator type of \tcode{X} belongs to the +bidirectional or random access iterator categories\iref{iterator.requirements}, +and +the following types and expressions are well-formed and have +the specified semantics. + +\indexcont{reverse_iterator}% +\begin{itemdecl} +typename X::reverse_iterator +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +The type \tcode{reverse_iterator}, +an iterator type whose value type is \tcode{T}. +\end{itemdescr} + +\indexcont{const_reverse_iterator}% +\begin{itemdecl} +typename X::const_reverse_iterator +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +The type \tcode{reverse_iterator}, +a constant iterator type whose value type is \tcode{T}. +\end{itemdescr} + +\indexcont{rbegin}% +\begin{itemdecl} +a.rbegin() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{reverse_iterator}; +\tcode{const_reverse_iterator} for constant \tcode{a}. + +\pnum +\returns +\tcode{reverse_iterator(end())} + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexcont{rend}% +\begin{itemdecl} +a.rend() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{reverse_iterator}; +\tcode{const_reverse_iterator} for constant \tcode{a}. + +\pnum +\returns +\tcode{reverse_iterator(begin())} + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexcont{crbegin}% +\begin{itemdecl} +a.crbegin() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{const_reverse_iterator}. + +\pnum +\returns +\tcode{\keyword{const_cast}(a).rbegin()} + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexcont{crend}% +\begin{itemdecl} +a.crend() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{const_reverse_iterator}. + +\pnum +\returns +\tcode{\keyword{const_cast}(a).rend()} + +\pnum +\complexity +Constant. +\end{itemdescr} + + +\rSec3[container.opt.reqmts]{Optional container requirements} + +\pnum +The following operations are provided +for some types of containers but not others. Those containers for which the +listed operations are provided shall implement the semantics as described +unless otherwise stated. +If the iterators passed to \tcode{lexicographical_compare_three_way} +meet the constexpr iterator requirements\iref{iterator.requirements.general} +then the operations described below +are implemented by constexpr functions. + +% Local command to index a name as a member of all containers. +\renewcommand{\indexcont}[1]{% +\indexlibrarymisc{\idxcode{#1}}{optional container requirements}% +\indexlibrarymemberx{array}{#1}% +\indexlibrarymemberx{deque}{#1}% +\indexlibrarymemberx{forward_list}{#1}% +\indexlibrarymemberx{list}{#1}% +\indexlibrarymemberx{vector}{#1}% +\indexlibrarymemberx{map}{#1}% +\indexlibrarymemberx{set}{#1}% +\indexlibrarymemberx{multiset}{#1}% +\indexlibrarymemberx{multimap}{#1}% +\indexlibrarymemberx{flat_map}{#1}% +\indexlibrarymemberx{flat_set}{#1}% +\indexlibrarymemberx{flat_multiset}{#1}% +\indexlibrarymemberx{flat_multimap}{#1}% +\indexlibrarymemberx{basic_string}{#1}% +} + +\indexcont{operator<=>}% +\begin{itemdecl} +a <=> b +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{\exposid{synth-three-way-result}}. + +\pnum +\expects +Either \tcode{T} models \libconcept{three_way_comparable}, +or \tcode{<} is defined for values of type (possibly const) \tcode{T} and +\tcode{<} is a total ordering relationship. + +\pnum +\returns +\tcode{lexicographical_compare_three_way(a.begin(), a.end(), +b.begin(), b.end(),\newline \exposidnc{synth-three-way})} +\begin{note} +The algorithm \tcode{lexicographical_compare_three_way} +is defined in \ref{algorithms}. +\end{note} + +\pnum +\complexity +Linear. +\end{itemdescr} + +\rSec3[container.alloc.reqmts]{Allocator-aware containers} + +\pnum +Except for \tcode{array} and \tcode{inplace_vector}, +all of the containers defined in \ref{containers}, +\ref{stacktrace.basic}, \ref{basic.string}, and \ref{re.results} +meet the additional requirements of an \defnadj{allocator-aware}{container}, +as described below. + +\pnum +Given an allocator type \tcode{A} +and given a container type \tcode{X} having a \tcode{value_type} identical to \tcode{T} +and an \tcode{allocator_type} identical to \tcode{allocator_traits::rebind_alloc} +and given an lvalue \tcode{m} of type \tcode{A}, +a pointer \tcode{p} of type \tcode{T*}, +an expression \tcode{v} that denotes +an lvalue of type \tcode{T} or \tcode{const T} or +an rvalue of type \tcode{const T}, +and an rvalue \tcode{rv} of type \tcode{T}, +the following terms are defined. If \tcode{X} +is not allocator-aware or is a specialization of \tcode{basic_string}, +the terms below are defined as if \tcode{A} were +\tcode{allocator} --- no allocator object needs to be created +and user specializations of \tcode{allocator} are not instantiated: + +\begin{itemize} +\item +\tcode{T} is \defnx{\oldconcept{DefaultInsertable} into \tcode{X}} +{\oldconceptname{DefaultInsertable} into X@\oldconcept{DefaultInsertable} into \tcode{X}} +means that the following expression is well-formed: +\begin{codeblock} +allocator_traits::construct(m, p) +\end{codeblock} + +\item +An element of \tcode{X} is \defn{default-inserted} if it is initialized +by evaluation of the expression +\begin{codeblock} +allocator_traits::construct(m, p) +\end{codeblock} +where \tcode{p} is the address of the uninitialized storage for the element +allocated within \tcode{X}. + +\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: +\begin{codeblock} +allocator_traits::construct(m, p, rv) +\end{codeblock} +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} +\tcode{rv} remains a valid object. Its state is unspecified. +\end{note} + +\item +\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: +\begin{codeblock} +allocator_traits::construct(m, p, v) +\end{codeblock} +and its evaluation causes the following postcondition to hold: +The value of \tcode{v} is unchanged and is equivalent to \tcode{*p}. + +\item +\tcode{T} is +\defnx{\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}} +{\oldconceptname{EmplaceConstructible} into X from args@\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}}, +for zero +or more arguments \tcode{args}, means that the following expression is well-formed: +\begin{codeblock} +allocator_traits::construct(m, p, args) +\end{codeblock} + +\item +\tcode{T} is +\defnx{\oldconcept{Erasable} from \tcode{X}} +{\oldconceptname{Erasable} from X@\oldconcept{Erasable} from \tcode{X}} +means that the following expression is well-formed: +\begin{codeblock} +allocator_traits::destroy(m, p) +\end{codeblock} +\end{itemize} + +\begin{note} +A container calls \tcode{allocator_traits::construct(m, p, args)} +to construct an element at \tcode{p} using \tcode{args}, +with \tcode{m == get_allocator()}. +The default \tcode{construct} in \tcode{allocator} will +call \tcode{::new((void*)p) T(args)}, +but specialized allocators can choose a different definition. +\end{note} + +\pnum +In this subclause, +\begin{itemize} +\item +\tcode{X} denotes an allocator-aware container class +with a \tcode{value_type} of \tcode{T} using an allocator of type \tcode{A}, +\item +\tcode{u} denotes a variable, +\item +\tcode{a} and \tcode{b} denote non-const lvalues of type \tcode{X}, +\item +\tcode{c} denotes an lvalue of type \tcode{\keyword{const} X}, +\item +\tcode{t} denotes an lvalue or a const rvalue of type \tcode{X}, +\item +\tcode{rv} denotes a non-const rvalue of type \tcode{X}, and +\item +\tcode{m} is a value of type \tcode{A}. +\end{itemize} + +% Local command to index names as members of all containers. +\renewcommand{\indexcont}[1]{% +\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}% +\indexlibrarymemberx{set}{#1}% +\indexlibrarymemberx{multiset}{#1}% +\indexlibrarymemberx{multimap}{#1}% +\indexlibrarymemberx{unordered_map}{#1}% +\indexlibrarymemberx{unordered_set}{#1}% +\indexlibrarymemberx{unordered_multiset}{#1}% +\indexlibrarymemberx{unordered_multimap}{#1}% +} + +A type \tcode{X} meets the allocator-aware container requirements +if \tcode{X} meets the container requirements and +the following types, statements, and expressions are well-formed and have +the specified semantics. + +\indexcont{allocator_type}% +\begin{itemdecl} +typename X::allocator_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{A} + +\pnum +\mandates +\tcode{allocator_type::value_type} is the same as \tcode{X::value_type}. +\end{itemdescr} + +\indexcont{get_allocator}% +\begin{itemdecl} +c.get_allocator() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{A} + +\pnum +\complexity +Constant. +\end{itemdescr} + +\begin{itemdecl} +X u; +X u = X(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{A} meets the \oldconcept{DefaultConstructible} requirements. + +\pnum +\ensures +\tcode{u.empty()} returns \tcode{true}, \tcode{u.get_allocator() == A()}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\begin{itemdecl} +X u(m); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{u.empty()} returns \tcode{true}, \tcode{u.get_allocator() == m}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\begin{itemdecl} +X u(t, m); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}. + +\pnum +\ensures +\tcode{u == t}, \tcode{u.get_allocator() == m}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\begin{itemdecl} +X u(rv); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{u} has the same elements as \tcode{rv} had before this construction; +the value of \tcode{u.get_allocator()} is the same as +the value of \tcode{rv.get_allocator()} before this construction. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\begin{itemdecl} +X u(rv, m); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{X}. + +\pnum +\ensures +\tcode{u} has the same elements, or copies of the elements, +that \tcode{rv} had before this construction, +\tcode{u.get_allocator() == m}. + +\pnum +\complexity +Constant if \tcode{m == rv.get_allocator()}, otherwise linear. +\end{itemdescr} + +\begin{itemdecl} +a = t +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X\&}. + +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} and +\oldconcept{CopyAssignable}. + +\pnum +\ensures +\tcode{a == t} is \tcode{true}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\indexcont{operator=}% +\begin{itemdecl} +a = rv +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X\&}. + +\pnum +\expects +If +\tcode{allocator_traits::propagate_on_container_move_assign\-ment::value} +is \tcode{false}, +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{X} and +\oldconcept{MoveAssignable}. + +\pnum +\effects +All existing elements of \tcode{a} are either move assigned to or destroyed. + +\pnum +\ensures +If \tcode{a} and \tcode{rv} do not refer to the same object, +\tcode{a} is equal to the value that \tcode{rv} had before this assignment. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\indexcont{swap}% +\begin{itemdecl} +a.swap(b) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\effects +Exchanges the contents of \tcode{a} and \tcode{b}. + +\pnum +\complexity +Constant. +\end{itemdescr} + + +\rSec2[container.requirements.dataraces]{Container data races} + +\pnum +For purposes of avoiding data races\iref{res.on.data.races}, implementations shall +consider the following functions to be \keyword{const}: \tcode{begin}, \tcode{end}, +\tcode{rbegin}, \tcode{rend}, \tcode{front}, \tcode{back}, \tcode{data}, \tcode{find}, +\tcode{lower_bound}, \tcode{upper_bound}, \tcode{equal_range}, \tcode{at} and, except in +associative or unordered associative containers, \tcode{operator[]}. + +\pnum +Notwithstanding~\ref{res.on.data.races}, implementations are required to avoid data +races when the contents of the contained object in different elements in the same +container, excepting \tcode{vector}, are modified concurrently. + +\pnum +\begin{note} +For a \tcode{vector x} with a size greater than one, \tcode{x[1] = 5} +and \tcode{*x.begin() = 10} can be executed concurrently without a data race, but +\tcode{x[0] = 5} and \tcode{*x.begin() = 10} executed concurrently can result in a data +race. +As an exception to the general rule, for a \tcode{vector y}, \tcode{y[0] = true} +can race with \tcode{y[1] = true}. +\end{note} + +\rSec2[sequence.reqmts]{Sequence containers} + +\pnum +A sequence container organizes a finite set of objects, all of the same type, into a strictly +linear arrangement. The library provides the following basic kinds of sequence containers: +\tcode{vector}, \tcode{inplace_vector}, +\tcode{forward_list}, \tcode{list}, and \tcode{deque}. +In addition, +\tcode{array} and \tcode{hive} are provided as sequence containers +which provide limited sequence operations, +in \tcode{array}'s case because it has a fixed number of elements, and +in \tcode{hive}'s case because insertion order is unspecified. +The library also provides container adaptors that +make it easy to construct abstract data types, +such as \tcode{stack}s, +\tcode{queue}s, +\tcode{flat_map}s, +\tcode{flat_multimap}s, +\tcode{flat_set}s, or +\tcode{flat_multiset}s, out of +the basic sequence container kinds (or out of other program-defined sequence containers). + +\pnum +In this subclause, +\begin{itemize} +\item +\tcode{X} denotes a sequence container class, +\item +\tcode{a} denotes a value of type \tcode{X} containing elements of type \tcode{T}, +\item +\tcode{u} denotes the name of a variable being declared, +\item +\tcode{A} denotes \tcode{X::allocator_type} if +the \grammarterm{qualified-id} \tcode{X::allocator_type} is valid and denotes a +type\iref{temp.deduct} and +\tcode{allocator} if it doesn't, +\item +\tcode{i} and \tcode{j} +denote iterators that meet the \oldconcept{InputIterator} requirements +and refer to elements implicitly convertible to \tcode{value_type}, +\item +\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}}, +\item +\tcode{il} designates an object of type \tcode{initializer_list}, +\item +\tcode{n} denotes a value of type \tcode{X::size_type}, +\item +\tcode{p} denotes a valid constant iterator to \tcode{a}, +\item +\tcode{q} denotes a valid dereferenceable constant iterator to \tcode{a}, +\item +\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 +\tcode{rv} denotes a non-const rvalue of \tcode{X::value_type}. +\item +\tcode{Args} denotes a template parameter pack; +\item +\tcode{args} denotes a function parameter pack with the pattern \tcode{Args\&\&}. +\end{itemize} + +\pnum +The complexities of the expressions are sequence dependent. + +% Local command to index names as members of all containers. +\renewcommand{\indexcont}[1]{% +\indexlibrarymisc{\idxcode{#1}}{sequence containers}% +\indexlibrarymemberx{deque}{#1}% +\indexlibrarymemberx{forward_list}{#1}% +\indexlibrarymemberx{list}{#1}% +\indexlibrarymemberx{vector}{#1}% +\indexlibrarymemberx{inplace_vector}{#1}% +} + +\pnum +A type \tcode{X} meets the \defnadj{sequence}{container} requirements +if \tcode{X} meets the container requirements and +the following statements and expressions are well-formed and have +the specified semantics. + +\begin{itemdecl} +X u(n, t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}. + +\pnum +\effects +Constructs a sequence container with \tcode{n} copies of \tcode{t}. + +\pnum +\ensures +\tcode{distance(u.begin(), u.end()) == n} is \tcode{true}. +\end{itemdescr} + +\begin{itemdecl} +X u(i, j); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. +For \tcode{vector}, +if the iterator does not meet +the \oldconcept{ForwardIterator} requirements\iref{forward.iterators}, +\tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X}. + +\pnum +\effects +Constructs a sequence container equal to the range \range{i}{j}. +Each iterator in the range \range{i}{j} is dereferenced exactly once. + +\pnum +\ensures +\tcode{distance(u.begin(), u.end()) == distance(i, j)} is \tcode{true}. +\end{itemdescr} + +\begin{itemdecl} +X(from_range, rg) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. +For \tcode{vector}, +if \tcode{R} models +\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 +\effects +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}. +\end{itemdescr} + +\begin{itemdecl} +X(il) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{X(il.begin(), il.end())}. +\end{itemdescr} + +\begin{itemdecl} +a = il +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X\&}. + +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} and +\oldconcept{CopyAssignable}. + +\pnum +\effects +Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. +All existing elements of \tcode{a} are either assigned to or destroyed. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + +\indexcont{emplace}% +\begin{itemdecl} +a.emplace(p, args) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}. + +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, +\tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X} and +\oldconcept{MoveAssignable}. + +\pnum +\effects +Inserts an object of type \tcode{T} +constructed with \tcode{std::forward(args)...} +before \tcode{p}. +\begin{note} +\tcode{args} can directly or indirectly refer to a value in \tcode{a}. +\end{note} + +\pnum +\returns +An iterator that points to the new element. +\end{itemdescr} + +\indexcont{insert}% +\begin{itemdecl} +a.insert(p, t) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}. + +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}. +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, +\tcode{T} is also \oldconcept{CopyAssignable}. + +\pnum +\effects +Inserts a copy of \tcode{t} before \tcode{p}. + +\pnum +\returns +An iterator that points to the copy of \tcode{t} inserted into \tcode{a}. +\end{itemdescr} + +\begin{itemdecl} +a.insert(p, rv) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}. + +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{X}. +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, +\tcode{T} is also \oldconcept{MoveAssignable}. + +\pnum +\effects +Inserts a copy of \tcode{rv} before \tcode{p}. + +\pnum +\returns +An iterator that points to the copy of \tcode{rv} inserted into \tcode{a}. +\end{itemdescr} + +\begin{itemdecl} +a.insert(p, n, t) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}. + +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} +and \oldconcept{CopyAssignable}. + +\pnum +\effects +Inserts \tcode{n} copies of \tcode{t} before \tcode{p}. + +\pnum +\returns +An iterator +that points to the copy of the first element inserted into \tcode{a}, or +\tcode{p} if \tcode{n == 0}. +\end{itemdescr} + +\begin{itemdecl} +a.insert(p, i, j) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}. + +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, +\tcode{T} is also +\oldconcept{MoveInsertable} into \tcode{X}, +and \tcode{T} meets the +\oldconcept{MoveConstructible}, +\oldconcept{MoveAs\-signable}, and +\oldconcept{Swappable}\iref{swappable.requirements} requirements. +Neither \tcode{i} nor \tcode{j} are iterators into \tcode{a}. + +\pnum +\effects +Inserts copies of elements in \range{i}{j} before \tcode{p}. +Each iterator in the range \range{i}{j} shall be dereferenced exactly once. + +\pnum +\returns +An iterator +that points to the copy of the first element inserted into \tcode{a}, or +\tcode{p} if \tcode{i == j}. +\end{itemdescr} + +\indexcont{insert_range}% +\begin{itemdecl} +a.insert_range(p, rg) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}. + +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, +\tcode{T} is also +\oldconcept{MoveInsertable} into \tcode{X}, +and \tcode{T} meets the +\oldconcept{Move\-Constructible}, +\oldconcept{MoveAssignable}, and +\oldconcept{Swappable}\iref{swappable.requirements} requirements. +\tcode{rg} and \tcode{a} do not overlap. + +\pnum +\effects +Inserts copies of elements in \tcode{rg} before \tcode{p}. +Each iterator in the range \tcode{rg} is dereferenced exactly once. + +\pnum +\returns +An iterator +that points to the copy of the first element inserted into \tcode{a}, or +\tcode{p} if \tcode{rg} is empty. +\end{itemdescr} + +\begin{itemdecl} +a.insert(p, il) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{a.insert(p, il.begin(), il.end())}. +\end{itemdescr} + +\indexcont{erase}% +\begin{itemdecl} +a.erase(q) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}. + +\pnum +\expects +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, +\tcode{T} is \oldconcept{MoveAssignable}. + +\pnum +\effects +Erases the element pointed to by \tcode{q}. + +\pnum +\returns +An iterator that points to the element immediately following \tcode{q} +prior to the element being erased. +If no such element exists, \tcode{a.end()} is returned. +\end{itemdescr} + +\begin{itemdecl} +a.erase(q1, q2) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}. + +\pnum +\expects +For \tcode{vector}, \tcode{inplace_vector}, and \tcode{deque}, +\tcode{T} is \oldconcept{MoveAssignable}. + +\pnum +\effects +Erases the elements in the range \range{q1}{q2}. + +\pnum +\returns +An iterator that points to the element pointed to by \tcode{q2} +prior to any elements being erased. +If no such element exists, \tcode{a.end()} is returned. +\end{itemdescr} + +\indexcont{clear}% +\begin{itemdecl} +a.clear() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\effects +Destroys all elements in \tcode{a}. +Invalidates all references, pointers, and iterators +referring to the elements of \tcode{a} and +may invalidate the past-the-end iterator. + +\pnum +\ensures +\tcode{a.empty()} is \tcode{true}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\indexcont{assign}% +\begin{itemdecl} +a.assign(i, j) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i} +and assignable from \tcode{*i}. +For \tcode{vector}, +if the iterator does not meet +the forward iterator requirements\iref{forward.iterators}, +\tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X}. +Neither \tcode{i} nor \tcode{j} are iterators into \tcode{a}. + +\pnum +\effects +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}, +also invalidates the past-the-end iterator. +Each iterator in the range \range{i}{j} is dereferenced exactly once. +\end{itemdescr} + +\indexcont{assign_range}% +\begin{itemdecl} +a.assign_range(rg) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\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 +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. +For \tcode{vector}, +if \tcode{R} models +\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. + +\pnum +\effects +Replaces elements in \tcode{a} with a copy of each element in \tcode{rg}. +Invalidates all references, pointers, and iterators +referring to the elements of \tcode{a}. +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} +a.assign(il) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{a.assign(il.begin(), il.end())}. +\end{itemdescr} + +\begin{itemdecl} +a.assign(n, t) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} +and \oldconcept{CopyAssignable}. +\tcode{t} is not a reference into \tcode{a}. + +\pnum +\effects +Replaces elements in \tcode{a} with \tcode{n} copies of \tcode{t}. +Invalidates all references, pointers and iterators +referring to the elements of \tcode{a}. +For \tcode{vector} and \tcode{deque}, +also invalidates the past-the-end iterator. +\end{itemdescr} + +\pnum +For every sequence container defined in this Clause and in \ref{strings}: +\begin{itemize} +\item If the constructor +\begin{codeblock} +template + X(InputIterator first, InputIterator last, + const allocator_type& alloc = allocator_type()); +\end{codeblock} +is called with a type \tcode{InputIterator} that does not qualify as an input +iterator, then the constructor +shall not participate in overload resolution. + +\item If the member functions of the forms: +\begin{codeblock} +template + @\placeholdernc{return-type}@ @\placeholdernc{F}@(const_iterator p, + InputIterator first, InputIterator last); // such as \tcode{insert} + +template + @\placeholdernc{return-type}@ @\placeholdernc{F}@(InputIterator first, InputIterator last); // such as \tcode{append}, \tcode{assign} + +template + @\placeholdernc{return-type}@ @\placeholdernc{F}@(const_iterator i1, const_iterator i2, + InputIterator first, InputIterator last); // such as \tcode{replace} +\end{codeblock} +are called with a type \tcode{InputIterator} that does not qualify as an input +iterator, then these functions +shall not participate in overload resolution. + +\item A deduction guide for a sequence container shall not participate in overload resolution +if it has an \tcode{InputIterator} template parameter and a type that does not +qualify as an input iterator is deduced for that parameter, +or if it has an \tcode{Allocator} template parameter and a type that does not +qualify as an allocator is deduced for that parameter. +\end{itemize} + +\pnum +The following operations are provided for +some types of sequence containers but not others. +Operations other than \tcode{prepend_range} and \tcode{append_range} +are implemented so as to take amortized constant time. + +\begin{itemdecl} +a.front() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{reference; const_reference} for constant \tcode{a}. + +\pnum +\hardexpects +\tcode{a.empty()} is \tcode{false}. + +\pnum +\returns +\tcode{*a.begin()} + +\pnum +\remarks +Required for +\tcode{basic_string}, +\tcode{array}, +\tcode{deque}, +\tcode{forward_list}, +\tcode{inplace_vector}, +\tcode{list}, and +\tcode{vector}. +\end{itemdescr} + +\begin{itemdecl} +a.back() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{reference; const_reference} for constant \tcode{a}. + +\pnum +\hardexpects +\tcode{a.empty()} is \tcode{false}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto tmp = a.end(); +--tmp; +return *tmp; +\end{codeblock} + +\pnum +\remarks +Required for +\tcode{basic_string}, +\tcode{array}, +\tcode{deque}, +\tcode{inplace_vector}, +\tcode{list}, and +\tcode{vector}. +\end{itemdescr} + +\begin{itemdecl} +a.emplace_front(args) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{reference} + +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. + +\pnum +\effects +Prepends an object of type \tcode{T} +constructed with \tcode{std::forward(args)...}. + +\pnum +\returns +\tcode{a.front()}. + +\pnum +\remarks +Required for +\tcode{deque}, +\tcode{forward_list}, and +\tcode{list}. +\end{itemdescr} + +\begin{itemdecl} +a.emplace_back(args) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{reference} + +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. +For \tcode{vector}, +\tcode{T} is also \oldconcept{MoveIn\-sert\-able} into \tcode{X}. + +\pnum +\effects +Appends an object of type \tcode{T} +constructed with \tcode{std::forward(args)...}. + +\pnum +\returns +\tcode{a.back()}. + +\pnum +\remarks +Required for +\tcode{deque}, +\tcode{inplace_vector}, +\tcode{list}, and +\tcode{vector}. +\end{itemdescr} + +\begin{itemdecl} +a.push_front(t) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}. + +\pnum +\effects +Prepends a copy of \tcode{t}. + +\pnum +\remarks +Required for +\tcode{deque}, +\tcode{forward_list}, and +\tcode{list}. +\end{itemdescr} + +\begin{itemdecl} +a.push_front(rv) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{X}. + +\pnum +\effects +Prepends a copy of \tcode{rv}. + +\pnum +\remarks +Required for +\tcode{deque}, +\tcode{forward_list}, and +\tcode{list}. +\end{itemdescr} + +\begin{itemdecl} +a.prepend_range(rg) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. +For \tcode{deque}, +\tcode{T} is also \oldconcept{MoveInsertable} into \tcode{X}, and +\tcode{T} meets the +\oldconcept{MoveConstructible}, +\oldconcept{MoveAssignable}, and +\oldconcept{Swappable}\iref{swappable.requirements} requirements. + +\pnum +\effects +Inserts copies of elements in \tcode{rg} before \tcode{begin()}. +Each iterator in the range \tcode{rg} is dereferenced exactly once. +\begin{note} +The order of elements in \tcode{rg} is not reversed. +\end{note} + +\pnum +\remarks +Required for +\tcode{deque}, +\tcode{forward_list}, and +\tcode{list}. +\end{itemdescr} + +\begin{itemdecl} +a.push_back(t) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}. + +\pnum +\effects +Appends a copy of \tcode{t}. + +\pnum +\remarks +Required for +\tcode{basic_string}, +\tcode{deque}, +\tcode{inplace_vector}, +\tcode{list}, and +\tcode{vector}. +\end{itemdescr} + +\begin{itemdecl} +a.push_back(rv) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{X}. + +\pnum +\effects +Appends a copy of \tcode{rv}. + +\pnum +\remarks +Required for +\tcode{basic_string}, +\tcode{deque}, +\tcode{inplace_vector}, +\tcode{list}, and +\tcode{vector}. +\end{itemdescr} + +\begin{itemdecl} +a.append_range(rg) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. +For \tcode{vector}, +\tcode{T} is also +\oldconcept{MoveInsertable} into \tcode{X}. + +\pnum +\effects +Inserts copies of elements in \tcode{rg} before \tcode{end()}. +Each iterator in the range \tcode{rg} is dereferenced exactly once. + +\pnum +\remarks +Required for +\tcode{deque}, +\tcode{inplace_vector}, +\tcode{list}, and +\tcode{vector}. +\end{itemdescr} + +\begin{itemdecl} +a.pop_front() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\hardexpects +\tcode{a.empty()} is \tcode{false}. + +\pnum +\effects +Destroys the first element. + +\pnum +\remarks +Required for +\tcode{deque}, +\tcode{forward_list}, and +\tcode{list}. +\end{itemdescr} + +\begin{itemdecl} +a.pop_back() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\hardexpects +\tcode{a.empty()} is \tcode{false}. + +\pnum +\effects +Destroys the last element. + +\pnum +\remarks +Required for +\tcode{basic_string}, +\tcode{deque}, +\tcode{inplace_vector}, +\tcode{list}, and +\tcode{vector}. +\end{itemdescr} + +\begin{itemdecl} +a[n] +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{reference; const_reference} for constant \tcode{a}. + +\pnum +\hardexpects +\tcode{n < a.size()} is \tcode{true}. + +\pnum +\effects +Equivalent to: \tcode{return *(a.begin() + n);} + +\pnum +\remarks +Required for +\tcode{basic_string}, +\tcode{array}, +\tcode{deque}, +\tcode{inplace_vector}, and +\tcode{vector}. +\end{itemdescr} + +\begin{itemdecl} +a.at(n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{reference; const_reference} for constant \tcode{a}. + +\pnum +\returns +\tcode{*(a.begin() + n)} + +\pnum +\throws +\tcode{out_of_range} if \tcode{n >= a.size()}. + +\pnum +\remarks +Required for +\tcode{basic_string}, +\tcode{array}, +\tcode{deque}, +\tcode{inplace_vector}, and +\tcode{vector}. +\end{itemdescr} + +\rSec2[container.node]{Node handles} + +\rSec3[container.node.overview]{Overview} + +\pnum +A \defn{node handle} is an object that accepts ownership of a single element +from an associative container\iref{associative.reqmts} or an unordered +associative container\iref{unord.req}. It may be used to transfer that +ownership to another container with compatible nodes. Containers with +compatible nodes have the same node handle type. Elements may be transferred in +either direction between container types in the same row of +\tref{container.node.compat}. + +\begin{floattable}{Container types with compatible nodes}{container.node.compat} +{ll} +\topline +\tcode{map} & \tcode{map} \\ +\rowsep +\tcode{map} & \tcode{multimap} \\ +\rowsep +\tcode{set} & \tcode{set} \\ +\rowsep +\tcode{set} & \tcode{multiset} \\ +\rowsep +\tcode{unordered_map} & \tcode{unordered_map} \\ +\rowsep +\tcode{unordered_map} & \tcode{unordered_multimap} \\ +\rowsep +\tcode{unordered_set} & \tcode{unordered_set} \\ +\rowsep +\tcode{unordered_set} & \tcode{unordered_multiset} \\ +\end{floattable} + +\pnum +If a node handle is not empty, then it contains an allocator that is equal to +the allocator of the container when the element was extracted. If a node handle +is empty, it contains no allocator. + +\pnum +Class \exposid{node-handle} is for exposition only. + +\pnum +If a user-defined specialization of \tcode{pair} exists for +\tcode{pair} or \tcode{pair}, where \tcode{Key} is the +container's \tcode{key_type} and \tcode{T} is the container's +\tcode{mapped_type}, the behavior of operations involving node handles is +undefined. + +\begin{codeblock} +template<@\unspecnc@> +class @\placeholder{node-handle}@ { +public: + // These type declarations are described in \ref{associative.reqmts} and \ref{unord.req}. + using value_type = @\seebelownc{}@; // not present for map containers + using key_type = @\seebelownc{}@; // not present for set containers + using mapped_type = @\seebelownc{}@; // not present for set containers + using allocator_type = @\seebelownc{}@; + +private: + using @\exposid{container-node-type}@ = @\unspecnc@; // \expos + using @\exposid{ator-traits}@ = allocator_traits; // \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 : @\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 + constexpr ~@\placeholdernc{node-handle}@(); + + // \ref{container.node.observers}, observers + 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 + + constexpr allocator_type get_allocator() const; + constexpr explicit operator bool() const noexcept; + constexpr bool empty() const noexcept; + + // \ref{container.node.modifiers}, modifiers + constexpr void swap(@\placeholdernc{node-handle}@&) + noexcept(@\exposid{ator-traits}@::propagate_on_container_swap::value || + @\exposid{ator-traits}@::is_always_equal::value); + + friend constexpr void swap(@\placeholdernc{node-handle}@& x, @\placeholdernc{node-handle}@& y) noexcept(noexcept(x.swap(y))) { + x.swap(y); + } +}; +\end{codeblock} + +\rSec3[container.node.cons]{Constructors, copy, and assignment} + +\begin{itemdecl} +constexpr @\placeholdernc{node-handle}@(@\placeholdernc{node-handle}@&& nh) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \exposid{node-handle} object initializing +\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} +constexpr @\placeholdernc{node-handle}@& operator=(@\placeholdernc{node-handle}@&& nh); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +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{\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.\exposid{ptr_}} to \exposid{ptr_}. +\item +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.\exposid{alloc_}} to \exposid{alloc_}. +\item +Assigns +\keyword{nullptr} to \tcode{nh.\exposid{ptr_}} and assigns \tcode{nullopt} to +\tcode{nh.\exposid{alloc_}}. +\end{itemize} + +\pnum +\returns +\tcode{*this}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\rSec3[container.node.dtor]{Destructor} + +\begin{itemdecl} +constexpr ~@\placeholdernc{node-handle}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +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} +constexpr value_type& value() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{empty() == false}. + +\pnum +\returns +A reference to the \tcode{value_type} subobject in the +\exposid{container-node-type} object pointed to by \exposid{ptr_}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\begin{itemdecl} +key_type& key() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{empty() == false}. + +\pnum +\returns +A non-const reference to the \tcode{key_type} member of the +\tcode{value_type} subobject in the \exposid{contain\-er-node-type} object +pointed to by \exposid{ptr_}. + +\pnum +\throws +Nothing. + +\pnum +\remarks +Modifying the key through the returned reference is permitted. +\end{itemdescr} + +\begin{itemdecl} +constexpr mapped_type& mapped() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{empty() == false}. + +\pnum +\returns +A reference to the \tcode{mapped_type} member of the +\tcode{value_type} subobject in the \exposid{container-\-node-type} object +pointed to by \exposid{ptr_}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\begin{itemdecl} +constexpr allocator_type get_allocator() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{empty() == false}. + +\pnum +\returns +\tcode{*\exposid{alloc_}}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\begin{itemdecl} +constexpr explicit operator bool() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{ptr_} != nullptr}. +\end{itemdescr} + +\begin{itemdecl} +constexpr bool empty() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{ptr_} == nullptr}. +\end{itemdescr} + +\rSec3[container.node.modifiers]{Modifiers} + +\begin{itemdecl} +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{!\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(\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} + +\pnum +The associative containers with unique keys and the unordered containers with unique keys +have a member function \tcode{insert} that returns a nested type \tcode{insert_return_type}. +That return type is a specialization of the template specified in this subclause. + +\begin{codeblock} +template +struct @\placeholder{insert-return-type}@ +{ + Iterator position; + bool inserted; + NodeType node; +}; +\end{codeblock} + +\pnum +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. + +\rSec2[associative.reqmts]{Associative containers} + +\rSec3[associative.reqmts.general]{General} + +\pnum +Associative containers provide fast retrieval of data based on keys. The library provides four basic kinds of associative containers: \tcode{set}, \tcode{multiset}, \tcode{map} and -\tcode{multimap}. +\tcode{multimap}. +The library also provides container adaptors +that make it easy to construct abstract data types, +such as \tcode{flat_map}s, \tcode{flat_multimap}s, +\tcode{flat_set}s, or \tcode{flat_multiset}s, +out of the basic sequence container kinds +(or out of other program-defined sequence containers). + +\pnum +Each associative container is parameterized on +\tcode{Key} +and an ordering relation +\tcode{Compare} +that induces a strict weak ordering\iref{alg.sorting} on +elements of +\tcode{Key}. +In addition, +\tcode{map} +and +\tcode{multimap} +associate an arbitrary \term{mapped type} +\tcode{T} +with the +\tcode{Key}. +The object of type +\tcode{Compare} +is called the +\term{comparison object} +of a container. + +\pnum +The phrase ``equivalence of keys'' means the equivalence relation imposed by the +comparison object. +That is, two keys +\tcode{k1} +and +\tcode{k2} +are considered to be equivalent if for the +comparison object +\tcode{comp}, +\tcode{comp(k1, k2) == false \&\& comp(k2, k1) == false}. +\begin{note} +This is not necessarily the same as the result of \tcode{k1 == k2}. +\end{note} +For any two keys +\tcode{k1} +and +\tcode{k2} +in the same container, calling +\tcode{comp(k1, k2)} +shall always return the same value. + +\pnum +An associative container supports \term{unique keys} if it may contain at +most one element for each key. Otherwise, it supports \term{equivalent keys}. +The \tcode{set} and \tcode{map} classes support unique keys; the \tcode{multiset} +and \tcode{multimap} classes support equivalent keys. +For \tcode{multiset} and \tcode{multimap}, +\tcode{insert}, \tcode{emplace}, and \tcode{erase} preserve the relative ordering +of equivalent elements. + +\pnum +For \tcode{set} and \tcode{multiset} the value type is the same as the key type. +For \tcode{map} and \tcode{multimap} it is equal to \tcode{pair}. + +\pnum +\tcode{iterator} +of an associative container is of the bidirectional iterator category. +For associative containers where the value type is the same as the key type, both +\tcode{iterator} +and +\tcode{const_iterator} +are constant iterators. It is unspecified whether or not +\tcode{iterator} +and +\tcode{const_iterator} +are the same type. +\begin{note} +\tcode{iterator} and \tcode{const_iterator} have identical semantics in this case, and \tcode{iterator} is convertible to \tcode{const_iterator}. Users can avoid violating the one-definition rule by always using \tcode{const_iterator} in their function parameter lists. +\end{note} + +\pnum +In this subclause, +\begin{itemize} +\item +\tcode{X} denotes an associative container class, +\item +\tcode{a} denotes a value of type \tcode{X}, +\item +\tcode{a2} denotes a value of a type with nodes compatible with type +\tcode{X} (\tref{container.node.compat}), +\item +\tcode{b} denotes a value of type \tcode{X} or \tcode{const X}, +\item +\tcode{u} denotes the name of a variable being declared, +\item +\tcode{a_uniq} denotes a value of type \tcode{X} +when \tcode{X} supports unique keys, +\item +\tcode{a_eq} denotes a value of type \tcode{X} +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} +\tcode{X::key_compare::is_transparent} is valid +and denotes a type\iref{temp.deduct}, +\item +\tcode{i} and \tcode{j} +meet the \oldconcept{InputIterator} requirements and refer to elements +implicitly convertible to +\tcode{value_type}, +\item +\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}}, +\item +\tcode{p} denotes a valid constant iterator to \tcode{a}, +\item +\tcode{q} denotes a valid dereferenceable constant iterator to \tcode{a}, +\item +\tcode{r} denotes a valid dereferenceable iterator to \tcode{a}, +\item +\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 +\tcode{t} denotes a value of type \tcode{X::value_type}, +\item +\tcode{k} denotes a value of type \tcode{X::key_type}, and +\item +\tcode{c} denotes a value of type \tcode{X::key_compare} or \tcode{const X::key_compare}; +\item +\tcode{kl} is a value such that \tcode{a} is partitioned\iref{alg.sorting} +with respect to \tcode{c(x, kl)}, +with \tcode{x} the key value of \tcode{e} and \tcode{e} in \tcode{a}; +\item +\tcode{ku} is a value such that \tcode{a} is partitioned with respect to +\tcode{!c(ku, x)}, +with \tcode{x} the key value of \tcode{e} and \tcode{e} in \tcode{a}; +\item +\tcode{ke} is a value such that \tcode{a} is partitioned with respect to +\tcode{c(x, ke)} and \tcode{!c(ke, x)}, with \tcode{c(x, ke)} implying +\tcode{!c(ke, x)} and +with \tcode{x} the key value of \tcode{e} and \tcode{e} in \tcode{a}; +\item +\tcode{kx} is a value such that +\begin{itemize} +\item +\tcode{a} is partitioned with respect to \tcode{c(x, kx)} and \tcode{!c(kx, x)}, +with \tcode{c(x, kx)} implying \tcode{!c(kx, x)} and +with \tcode{x} the key value of \tcode{e} and \tcode{e} in \tcode{a}, and +\item +\tcode{kx} is not convertible to +either \tcode{iterator} or \tcode{const_iterator}; and +\end{itemize} +\item +\tcode{A} denotes the storage allocator used by \tcode{X}, if any, or \tcode{allocator} otherwise, +\item +\tcode{m} denotes an allocator of a type convertible to \tcode{A}, +and \tcode{nh} denotes a non-const rvalue of type \tcode{X::node_type}. +\end{itemize} + +\pnum +A type \tcode{X} meets the \defnadj{associative}{container} requirements +if \tcode{X} meets all the requirements of an allocator-aware +container\iref{container.alloc.reqmts} and +the following types, statements, and expressions are well-formed and +have the specified semantics, +except that for +\tcode{map} and \tcode{multimap}, the requirements placed on \tcode{value_type} +in \ref{container.reqmts} apply instead to \tcode{key_type} +and \tcode{mapped_type}. +\begin{note} +For example, in some cases \tcode{key_type} and \tcode{mapped_type} +need to be \oldconcept{CopyAssignable} even though the associated +\tcode{value_type}, \tcode{pair}, is not +\oldconcept{CopyAssignable}. +\end{note} + +% Local command to index names as members of all ordered containers. +\newcommand{\indexordmem}[1]{% +\indexlibrary{\idxcode{#1}!ordered associative containers}% +\indexlibrary{\idxcode{set}!\idxcode{#1}}% +\indexlibrary{\idxcode{map}!\idxcode{#1}}% +\indexlibrary{\idxcode{multiset}!\idxcode{#1}}% +\indexlibrary{\idxcode{multimap}!\idxcode{#1}}% +\indexlibrary{\idxcode{flat_set}!\idxcode{#1}}% +\indexlibrary{\idxcode{flat_map}!\idxcode{#1}}% +\indexlibrary{\idxcode{flat_multiset}!\idxcode{#1}}% +\indexlibrary{\idxcode{flat_multimap}!\idxcode{#1}}% +} + +\indexordmem{key_type}% +\begin{itemdecl} +typename X::key_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{Key}. +\end{itemdescr} + +\indexordmem{mapped_type}% +\begin{itemdecl} +typename X::mapped_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{T}. + +\pnum +\remarks +For \tcode{map} and \tcode{multimap} only. +\end{itemdescr} + +\indexordmem{value_type}% +\begin{itemdecl} +typename X::value_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{Key} for \tcode{set} and \tcode{multiset} only; +\tcode{pair} for \tcode{map} and \tcode{multimap} only. + +\pnum +\expects +\tcode{X::value_type} is \oldconcept{Erasable} from \tcode{X}. +\end{itemdescr} + +\indexordmem{key_compare}% +\begin{itemdecl} +typename X::key_compare +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{Compare}. + +\pnum +\expects +\tcode{key_compare} is \oldconcept{CopyConstructible}. +\end{itemdescr} + +\indexordmem{value_compare}% +\begin{itemdecl} +typename X::value_compare +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A binary predicate type. +It is the same as \tcode{key_compare} for \tcode{set} and +\tcode{multiset}; is an ordering relation on pairs induced by the +first component (i.e., \tcode{Key}) for \tcode{map} and \tcode{multimap}. +\end{itemdescr} + +\indexordmem{node_type}% +\begin{itemdecl} +typename X::node_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A specialization of +the \exposid{node-handle} class template\iref{container.node}, +such that the public nested types are +the same types as the corresponding types in \tcode{X}. +\end{itemdescr} + +\indexlibraryctor{set}% +\indexlibraryctor{map}% +\indexlibraryctor{multiset}% +\indexlibraryctor{multimap}% +\begin{itemdecl} +X(c) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty container. +Uses a copy of \tcode{c} as a comparison object. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{set}% +\indexlibraryctor{map}% +\indexlibraryctor{multiset}% +\indexlibraryctor{multimap}% +\begin{itemdecl} +X u = X(); +X u; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{key_compare} meets the \oldconcept{DefaultConstructible} requirements. + +\pnum +\effects +Constructs an empty container. +Uses \tcode{Compare()} as a comparison object. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{set}% +\indexlibraryctor{map}% +\indexlibraryctor{multiset}% +\indexlibraryctor{multimap}% +\begin{itemdecl} +X(i, j, c) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. + +\pnum +\effects +Constructs an empty container and +inserts elements from the range \range{i}{j} into it; +uses \tcode{c} as a comparison object. + +\pnum +\complexity +$N \log N$ in general, where $N$ has the value \tcode{distance(i, j)}; +linear if \range{i}{j} is sorted with respect to \tcode{value_comp()}. +\end{itemdescr} + +\indexlibraryctor{set}% +\indexlibraryctor{map}% +\indexlibraryctor{multiset}% +\indexlibraryctor{multimap}% +\begin{itemdecl} +X(i, j) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{key_compare} meets the \oldconcept{DefaultConstructible} requirements. +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. + +\pnum +\effects +Constructs an empty container and +inserts elements from the range \range{i}{j} into it; +uses \tcode{Compare()} as a comparison object. + +\pnum +\complexity +$N \log N$ in general, where $N$ has the value \tcode{distance(i, j)}; +linear if \range{i}{j} is sorted with respect to \tcode{value_comp()}. +\end{itemdescr} + +\indexlibraryctor{set}% +\indexlibraryctor{map}% +\indexlibraryctor{multiset}% +\indexlibraryctor{multimap}% +\begin{itemdecl} +X(from_range, rg, c) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. + +\pnum +\effects +Constructs an empty container and +inserts each element from \tcode{rg} into it. +Uses \tcode{c} as the comparison object. + +\pnum +\complexity +$N \log N$ in general, where $N$ has the value \tcode{ranges::distance(rg)}; +linear if \tcode{rg} is sorted with respect to \tcode{value_comp()}. +\end{itemdescr} + +\indexlibraryctor{set}% +\indexlibraryctor{map}% +\indexlibraryctor{multiset}% +\indexlibraryctor{multimap}% +\begin{itemdecl} +X(from_range, rg) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{key_compare} meets the \oldconcept{DefaultConstructible} requirements. +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. + +\pnum +\effects +Constructs an empty container and +inserts each element from \tcode{rg} into it. +Uses \tcode{Compare()} as the comparison object. + +\pnum +\complexity +Same as \tcode{X(from_range, rg, c)}. +\end{itemdescr} + +\indexlibraryctor{set}% +\indexlibraryctor{map}% +\indexlibraryctor{multiset}% +\indexlibraryctor{multimap}% +\begin{itemdecl} +X(il, c) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{X(il.begin(), il.end(), c)}. +\end{itemdescr} + +\indexlibraryctor{set}% +\indexlibraryctor{map}% +\indexlibraryctor{multiset}% +\indexlibraryctor{multimap}% +\begin{itemdecl} +X(il) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{X(il.begin(), il.end())}. +\end{itemdescr} + +\begin{itemdecl} +a = il +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X\&} + +\pnum +\expects +\tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X} +and \oldconcept{CopyAssignable}. + +\pnum +\effects +Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. +All existing elements of \tcode{a} are either assigned to or destroyed. + +\pnum +\complexity +$N \log N$ in general, where $N$ has the value \tcode{il.size() + a.size()}; +linear if \range{il.begin()}{il.end()} is sorted with respect to \tcode{value_comp()}. +\end{itemdescr} + +\indexordmem{key_comp}% +\begin{itemdecl} +b.key_comp() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::key_compare} + +\pnum +\returns +The comparison object out of which \tcode{b} was constructed. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexordmem{value_comp}% +\begin{itemdecl} +b.value_comp() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::value_compare} + +\pnum +\returns +An object of \tcode{value_compare} constructed out of the comparison object. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexordmem{emplace}% +\begin{itemdecl} +a_uniq.emplace(args) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{pair} + +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. + +\pnum +\effects +Inserts a \tcode{value_type} object \tcode{t} +constructed with \tcode{std::forward(args)...} +if and only if there is no element in the container +with key equivalent to the key of \tcode{t}. + +\pnum +\returns +The \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion takes place, and +the iterator component of the pair points to +the element with key equivalent to the key of \tcode{t}. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{emplace}% +\begin{itemdecl} +a_eq.emplace(args) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. + +\pnum +\effects +Inserts a \tcode{value_type} object \tcode{t} +constructed with \tcode{std::forward(args)...}. +If a range containing elements equivalent to \tcode{t} exists in \tcode{a_eq}, +\tcode{t} is inserted at the end of that range. + +\pnum +\returns +An iterator pointing to the newly inserted element. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{emplace_hint}% +\begin{itemdecl} +a.emplace_hint(p, args) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\effects +Equivalent to \tcode{a.emplace(std::forward(args)...)}, +except that the element is inserted as close as possible to +the position just prior to \tcode{p}. + +\pnum +\returns +The iterator returned by \tcode{emplace}. + +\pnum +\complexity +Logarithmic in general, but +amortized constant if the element is inserted right before \tcode{p}. +\end{itemdescr} + +\indexordmem{insert}% +\begin{itemdecl} +a_uniq.insert(t) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{pair} + +\pnum +\expects +If \tcode{t} is a non-const rvalue, +\tcode{value_type} is \oldconcept{MoveInsertable} into \tcode{X}; +otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}. + +\pnum +\effects +Inserts \tcode{t} if and only if there is no element in the container +with key equivalent to the key of \tcode{t}. + +\pnum +\returns +The \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion takes place, and +the \tcode{iterator} component of the pair points to +the element with key equivalent to the key of \tcode{t}. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{insert}% +\begin{itemdecl} +a_eq.insert(t) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\expects +If \tcode{t} is a non-const rvalue, +\tcode{value_type} is \oldconcept{MoveInsertable} into \tcode{X}; +otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}. + +\pnum +\effects +Inserts \tcode{t} and returns the iterator pointing to +the newly inserted element. +If a range containing elements equivalent to \tcode{t} exists in \tcode{a_eq}, +\tcode{t} is inserted at the end of that range. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{insert}% +\begin{itemdecl} +a.insert(p, t) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\expects +If \tcode{t} is a non-const rvalue, +\tcode{value_type} is \oldconcept{MoveInsertable} into \tcode{X}; +otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}. + +\pnum +\effects +Inserts \tcode{t} if and only if there is no element +with key equivalent to the key of \tcode{t} in containers with unique keys; +always inserts \tcode{t} in containers with equivalent keys. +\tcode{t} is inserted as close as possible to +the position just prior to \tcode{p}. + +\pnum +\returns +An iterator pointing to the element with key equivalent to the key of \tcode{t}. + +\pnum +\complexity +Logarithmic in general, but +amortized constant if \tcode{t} is inserted right before \tcode{p}. +\end{itemdescr} + +\indexordmem{insert}% +\begin{itemdecl} +a.insert(i, j) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. +Neither \tcode{i} nor \tcode{j} are iterators into \tcode{a}. + +\pnum +\effects +Inserts each element from the range \range{i}{j} +if and only if there is no element +with key equivalent to the key of that element in containers with unique keys; +always inserts that element in containers with equivalent keys. + +\pnum +\complexity +$N \log (\tcode{a.size()} + N)$, where $N$ has the value \tcode{distance(i, j)}. +\end{itemdescr} + +\indexordmem{insert}% +\begin{itemdecl} +a.insert_range(rg) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. +\tcode{rg} and \tcode{a} do not overlap. + +\pnum +\effects +Inserts each element from \tcode{rg} if and only if +there is no element with key equivalent to the key of that element +in containers with unique keys; +always inserts that element in containers with equivalent keys. + +\pnum +\complexity +$N \log (\tcode{a.size()} + N)$, +where $N$ has the value \tcode{ranges::distance(rg)}. +\end{itemdescr} + +\indexordmem{insert}% +\begin{itemdecl} +a.insert(il) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{a.insert(il.begin(), il.end())}. +\end{itemdescr} + +\indexordmem{insert}% +\begin{itemdecl} +a_uniq.insert(nh) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{insert_return_type} + +\pnum +\expects +\tcode{nh} is empty or +\tcode{a_uniq.get_allocator() == nh.get_allocator()} is \tcode{true}. + +\pnum +\effects +If \tcode{nh} is empty, has no effect. +Otherwise, inserts the element owned by \tcode{nh} if and only if +there is no element in the container with a key equivalent to \tcode{nh.key()}. + +\pnum +\returns +If \tcode{nh} is empty, \tcode{inserted} is \tcode{false}, +\tcode{position} is \tcode{end()}, and \tcode{node} is empty. +Otherwise if the insertion took place, \tcode{inserted} is \tcode{true}, +\tcode{position} points to the inserted element, and \tcode{node} is empty; +if the insertion failed, \tcode{inserted} is \tcode{false}, +\tcode{node} has the previous value of \tcode{nh}, and +\tcode{position} points to an element with a key equivalent to \tcode{nh.key()}. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{insert}% +\begin{itemdecl} +a_eq.insert(nh) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\expects +\tcode{nh} is empty or +\tcode{a_eq.get_allocator() == nh.get_allocator()} is \tcode{true}. + +\pnum +\effects +If \tcode{nh} is empty, has no effect and returns \tcode{a_eq.end()}. +Otherwise, inserts the element owned by \tcode{nh} and +returns an iterator pointing to the newly inserted element. +If a range containing elements with keys equivalent to \tcode{nh.key()} +exists in \tcode{a_eq}, +the element is inserted at the end of that range. + +\pnum +\ensures +\tcode{nh} is empty. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{insert}% +\begin{itemdecl} +a.insert(p, nh) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\expects +\tcode{nh} is empty or +\tcode{a.get_allocator() == nh.get_allocator()} is \tcode{true}. + +\pnum +\effects +If \tcode{nh} is empty, has no effect and returns \tcode{a.end()}. +Otherwise, inserts the element owned by \tcode{nh} if and only if +there is no element with key equivalent to \tcode{nh.key()} +in containers with unique keys; +always inserts the element owned by \tcode{nh} +in containers with equivalent keys. +The element is inserted as close as possible to +the position just prior to \tcode{p}. + +\pnum +\ensures +\tcode{nh} is empty if insertion succeeds, unchanged if insertion fails. + +\pnum +\returns +An iterator pointing to the element with key equivalent to \tcode{nh.key()}. + +\pnum +\complexity +Logarithmic in general, but +amortized constant if the element is inserted right before \tcode{p}. +\end{itemdescr} + + +\indexordmem{extract}% +\begin{itemdecl} +a.extract(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{node_type} + +\pnum +\effects +Removes the first element in the container with key equivalent to \tcode{k}. + +\pnum +\returns +A \tcode{node_type} owning the element if found, +otherwise an empty \tcode{node_type}. + +\pnum +\complexity +$\log (\tcode{a.size()})$ +\end{itemdescr} + +\indexordmem{extract}% +\begin{itemdecl} +a_tran.extract(kx) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{node_type} + +\pnum +\effects +Removes the first element in the container with key \tcode{r} +such that \tcode{!c(r, kx) \&\& !c(kx, r)} is \tcode{true}. + +\pnum +\returns +A \tcode{node_type} owning the element if found, +otherwise an empty \tcode{node_type}. + +\pnum +\complexity +$\log(\tcode{a_tran.size()})$ +\end{itemdescr} + +\indexordmem{extract}% +\begin{itemdecl} +a.extract(q) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{node_type} + +\pnum +\effects +Removes the element pointed to by \tcode{q}. + +\pnum +\returns +A \tcode{node_type} owning that element. + +\pnum +\complexity +Amortized constant. +\end{itemdescr} + +\indexordmem{merge}% +\begin{itemdecl} +a.merge(a2) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{a.get_allocator() == a2.get_allocator()} is \tcode{true}. + +\pnum +\effects +Attempts to extract each element in \tcode{a2} and insert it into \tcode{a} +using the comparison object of \tcode{a}. +In containers with unique keys, +if there is an element in \tcode{a} with key equivalent to +the key of an element from \tcode{a2}, +then that element is not extracted from \tcode{a2}. + +\pnum +\ensures +Pointers and references to the transferred elements of \tcode{a2} +refer to those same elements but as members of \tcode{a}. +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}. + +\pnum +\throws +Nothing unless the comparison object throws. + +\pnum +\complexity +$N \log(\tcode{a.size()+} N)$, where $N$ has the value \tcode{a2.size()}. +\end{itemdescr} + +\indexordmem{erase}% +\begin{itemdecl} +a.erase(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\effects +Erases all elements in the container with key equivalent to \tcode{k}. + +\pnum +\returns +The number of erased elements. + +\pnum +\complexity +$\log (\tcode{a.size()}) + \tcode{a.count(k)}$ +\end{itemdescr} + +\indexordmem{erase}% +\begin{itemdecl} +a_tran.erase(kx) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\effects +Erases all elements in the container with key \tcode{r} +such that \tcode{!c(r, kx) \&\& !c(kx, r)} is \tcode{true}. + +\pnum +\returns +The number of erased elements. + +\pnum +\complexity +$\log(\tcode{a_tran.size())} + \tcode{a_tran.count(kx)}$ +\end{itemdescr} + +\indexordmem{erase}% +\begin{itemdecl} +a.erase(q) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\effects +Erases the element pointed to by \tcode{q}. + +\pnum +\returns +An iterator pointing to the element immediately following \tcode{q} +prior to the element being erased. +If no such element exists, returns \tcode{a.end()}. + +\pnum +\complexity +Amortized constant. +\end{itemdescr} + +\indexordmem{erase}% +\begin{itemdecl} +a.erase(r) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\effects +Erases the element pointed to by \tcode{r}. + +\pnum +\returns +An iterator pointing to the element immediately following \tcode{r} +prior to the element being erased. +If no such element exists, returns \tcode{a.end()}. + +\pnum +\complexity +Amortized constant. +\end{itemdescr} + +\indexordmem{erase}% +\begin{itemdecl} +a.erase(q1, q2) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\effects +Erases all the elements in the range \range{q1}{q2}. + +\pnum +\returns +An iterator pointing to the element pointed to by \tcode{q2} +prior to any elements being erased. +If no such element exists, \tcode{a.end()} is returned. + +\pnum +\complexity +$\log(\tcode{a.size()}) + N$, where $N$ has the value \tcode{distance(q1, q2)}. +\end{itemdescr} + +\indexordmem{clear}% +\begin{itemdecl} +a.clear() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{a.erase(a.begin(), a.end())}. + +\pnum +\ensures +\tcode{a.empty()} is \tcode{true}. + +\pnum +\complexity +Linear in \tcode{a.size()}. +\end{itemdescr} + +\indexordmem{find}% +\begin{itemdecl} +b.find(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. + +\pnum +\returns +An iterator pointing to an element with the key equivalent to \tcode{k}, or +\tcode{b.end()} if such an element is not found. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{find}% +\begin{itemdecl} +a_tran.find(ke) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. + +\pnum +\returns +An iterator pointing to an element with key \tcode{r} +such that \tcode{!c(r, ke) \&\& !c(ke, r)} is \tcode{true}, or +\tcode{a_tran.end()} if such an element is not found. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{count}% +\begin{itemdecl} +b.count(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\returns +The number of elements with key equivalent to \tcode{k}. + +\pnum +\complexity +$\log (\tcode{b.size()}) + \tcode{b.count(k)}$ +\end{itemdescr} + +\indexordmem{count}% +\begin{itemdecl} +a_tran.count(ke) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\returns +The number of elements with key \tcode{r} +such that \tcode{!c(r, ke) \&\& !c(ke, r)}. + +\pnum +\complexity +$\log (\tcode{a_tran.size()}) + \tcode{a_tran.count(ke)}$ +\end{itemdescr} + +\indexordmem{contains}% +\begin{itemdecl} +b.contains(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool} + +\pnum +\effects +Equivalent to: \tcode{return b.find(k) != b.end();} +\end{itemdescr} + +\indexordmem{contains}% +\begin{itemdecl} +a_tran.contains(ke) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool} + +\pnum +\effects +Equivalent to: \tcode{return a_tran.find(ke) != a_tran.end();} +\end{itemdescr} + +\indexordmem{lower_bound}% +\begin{itemdecl} +b.lower_bound(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. + +\pnum +\returns +An iterator pointing to the first element with key not less than \tcode{k}, +or \tcode{b.end()} if such an element is not found. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{lower_bound}% +\begin{itemdecl} +a_tran.lower_bound(kl) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. + +\pnum +\returns +An iterator pointing to the first element with key \tcode{r} +such that \tcode{!c(r, kl)}, +or \tcode{a_tran.end()} if such an element is not found. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{upper_bound}% +\begin{itemdecl} +b.upper_bound(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. + +\pnum +\returns +An iterator pointing to the first element with key greater than \tcode{k}, +or \tcode{b.end()} if such an element is not found. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{upper_bound}% +\begin{itemdecl} +a_tran.upper_bound(ku) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. + +\pnum +\returns +An iterator pointing to the first element with key \tcode{r} +such that \tcode{c(ku, r)}, +or \tcode{a_tran.end()} if such an element is not found. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{equal_range}% +\begin{itemdecl} +b.equal_range(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{pair}; +\tcode{pair} for constant \tcode{b}. + +\pnum +\effects +Equivalent to: \tcode{return make_pair(b.lower_bound(k), b.upper_bound(k));} + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexordmem{equal_range}% +\begin{itemdecl} +a_tran.equal_range(ke) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{pair}; +\tcode{pair} for constant \tcode{a_tran}. + +\pnum +\effects +Equivalent to: +\tcode{return make_pair(a_tran.lower_bound(ke), a_tran.upper_bound(ke));} + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\pnum +The \tcode{insert}, \tcode{insert_range}, and \tcode{emplace} members +shall not affect the validity of +iterators and references to the container, +and the \tcode{erase} members shall invalidate only iterators and +references to the erased elements. + +\pnum +The \tcode{extract} members invalidate only iterators to the removed element; +pointers and references to the removed element remain valid. However, accessing +the element through such pointers and references while the element is owned by +a \tcode{node_type} is undefined behavior. References and pointers to an element +obtained while it is owned by a \tcode{node_type} are invalidated if the element +is successfully inserted. + +\pnum +The fundamental property of iterators of associative containers is that they iterate through the containers +in the non-descending order of keys where non-descending is defined by the comparison that was used to +construct them. +For any two dereferenceable iterators +\tcode{i} +and +\tcode{j} +such that distance from +\tcode{i} +to +\tcode{j} +is positive, the following condition holds: + +\begin{codeblock} +value_comp(*j, *i) == false +\end{codeblock} + +\pnum +For associative containers with unique keys the stronger condition holds: + +\begin{codeblock} +value_comp(*i, *j) != false +\end{codeblock} + +\pnum +When an associative container is constructed by passing a comparison object the +container shall not store a pointer or reference to the passed object, +even if that object is passed by reference. +When an associative container is copied, through either a copy constructor +or an assignment operator, +the target container shall then use the comparison object from the container +being copied, +as if that comparison object had been passed to the target container in +its constructor. + +\pnum +The member function templates +\tcode{find}, \tcode{count}, \tcode{contains}, +\tcode{lower_bound}, \tcode{upper_bound}, \tcode{equal_range}, +\tcode{erase}, and \tcode{extract} +shall not participate in overload resolution unless +the \grammarterm{qualified-id} \tcode{Compare::is_transparent} is valid +and denotes a type\iref{temp.deduct}. +Additionally, the member function templates \tcode{extract} and \tcode{erase} +shall not participate in overload resolution if +\tcode{is_convertible_v || is_convertible_v} +is \tcode{true}, +where \tcode{K} is the type substituted as the first template argument. + +\pnum +A deduction guide for an associative container shall not participate in overload resolution +if any of the following are true: +\begin{itemize} +\item It has an \tcode{InputIterator} template parameter +and a type that does not qualify as an input iterator is deduced for that parameter. + +\item It has an \tcode{Allocator} template parameter +and a type that does not qualify as an allocator is deduced for that parameter. + +\item It has a \tcode{Compare} template parameter +and a type that qualifies as an allocator is deduced for that parameter. +\end{itemize} + +\rSec3[associative.reqmts.except]{Exception safety guarantees}% +\indextext{associative containers!exception safety}% +\indextext{associative containers!requirements}% + +\pnum +For associative containers, no \tcode{clear()} function throws an exception. +\tcode{erase(k)} does not throw an exception unless that exception is thrown +by the container's \tcode{Compare} object (if any). + +\pnum +For associative containers, if an exception is thrown by any operation from +within an \tcode{insert} or \tcode{emplace} function inserting a single element, the +insertion has no effect. + +\pnum +For associative containers, no \tcode{swap} function throws an exception unless +that exception is thrown by the +swap of the container's \tcode{Compare} object (if any). + +\rSec2[unord.req]{Unordered associative containers}% +\indextext{associative containers!unordered|see{unordered associative containers}} +\indextext{hash tables|see{unordered associative containers}} + +\rSec3[unord.req.general]{General} + +\pnum +\indextext{unordered associative containers!complexity}% +Unordered associative containers provide an ability for fast retrieval +of data based on keys. The worst-case complexity for most operations +is linear, but the average case is much faster. The library provides +four unordered associative containers: \tcode{unordered_set}, +\tcode{unordered_map}, \tcode{unordered_multiset}, and +\tcode{unordered_multimap}. + +\pnum +\indextext{unordered associative containers!lack of comparison functions}% +\indextext{unordered associative containers!requirements}% +\indextext{requirements!container!not required for unordered associated containers}% +Unordered associative containers conform to the requirements for +Containers\iref{container.requirements}, except that +the expressions +\tcode{a == b} and \tcode{a != b} have different semantics than for the other +container types. + +\pnum +Each unordered associative container is parameterized by \tcode{Key}, +by a function object type \tcode{Hash} that meets the \oldconcept{Hash} +requirements\iref{hash.requirements} and acts as a hash function for +argument values of type \tcode{Key}, and by a binary predicate \tcode{Pred} +that induces an equivalence relation on values of type \tcode{Key}. +Additionally, \tcode{unordered_map} and \tcode{unordered_multimap} associate +an arbitrary \textit{mapped type} \tcode{T} with the \tcode{Key}. + +\pnum +\indextext{unordered associative containers!hash function}% +\indextext{hash function}% +The container's object of type \tcode{Hash} --- denoted by +\tcode{hash} --- is called the \term{hash function} of the +container. The container's object of type \tcode{Pred} --- +denoted by \tcode{pred} --- is called the +\term{key equality predicate} of the container. + +\pnum +\indextext{unordered associative containers!equality function}% +Two values \tcode{k1} and \tcode{k2} are +considered equivalent if the container's +key equality predicate +\tcode{pred(k1, k2)} is valid and returns +\tcode{true} when passed those values. If \tcode{k1} and +\tcode{k2} are equivalent, the container's hash function shall +return the same value for both. +\begin{note} +Thus, when an unordered associative container is instantiated with +a non-default \tcode{Pred} parameter it usually needs a non-default \tcode{Hash} +parameter as well. +\end{note} +For any two keys \tcode{k1} and \tcode{k2} in the same container, +calling \tcode{pred(k1, k2)} shall always return the same value. +For any key \tcode{k} in a container, calling \tcode{hash(k)} +shall always return the same value. + +\pnum +\indextext{unordered associative containers!unique keys}% +\indextext{unordered associative containers!equivalent keys}% +An unordered associative container supports \textit{unique keys} if it +may contain at most one element for each key. Otherwise, it supports +\textit{equivalent keys}. \tcode{unordered_set} and \tcode{unordered_map} +support unique keys. \tcode{unordered_multiset} and \tcode{unordered_multimap} +support equivalent keys. In containers that support equivalent keys, +elements with equivalent keys are adjacent to each other +in the iteration order of the container. Thus, although the absolute order +of elements in an unordered container is not specified, its elements are +grouped into \defnx{equivalent-key groups}{equivalent-key group} such that all elements of each +group have equivalent keys. Mutating operations on unordered containers shall +preserve the relative order of elements within each equivalent-key group +unless otherwise specified. + +\pnum +For \tcode{unordered_set} and \tcode{unordered_multiset} the value type is +the same as the key type. For \tcode{unordered_map} and +\tcode{unordered_multimap} it is \tcode{pair}. + +\pnum +For unordered containers where the value type is the same as the key +type, both \tcode{iterator} and \tcode{const_iterator} are constant +iterators. It is unspecified whether or not \tcode{iterator} and +\tcode{const_iterator} are the same type. +\begin{note} +\tcode{iterator} and \tcode{const_iterator} have identical +semantics in this case, and \tcode{iterator} is convertible to +\tcode{const_iterator}. Users can avoid violating the one-definition rule +by always using \tcode{const_iterator} in their function parameter lists. +\end{note} + +\pnum +\indextext{buckets}% +\indextext{hash code}% +The elements of an unordered associative container are organized into +\textit{buckets}. Keys with the same hash code appear in the same +bucket. The number of buckets is automatically increased as elements +are added to an unordered associative container, so that the average +number of elements per bucket is kept below a bound. Rehashing +invalidates iterators, changes ordering between elements, and changes +which buckets elements appear in, but does not invalidate pointers or +references to elements. For \tcode{unordered_multiset} and +\tcode{unordered_multimap}, rehashing preserves the relative ordering of +equivalent elements. + +\pnum +\indextext{unordered associative containers}% +\indextext{unordered associative containers!requirements}% +\indextext{requirements!unordered associative container}% +\indextext{unordered associative containers!unique keys}% +\indextext{unordered associative containers!equivalent keys}% +\indextext{requirements!container}% +In this subclause, +\begin{itemize} +\item +\tcode{X} denotes an unordered associative container class, +\item +\tcode{a} denotes a value of type \tcode{X}, +\item +\tcode{a2} denotes a value of a type with nodes compatible + with type \tcode{X} (\tref{container.node.compat}), +\item +\tcode{b} denotes a value of type \tcode{X} or \tcode{const X}, +\item +\tcode{a_uniq} denotes a value of type \tcode{X} + when \tcode{X} supports unique keys, +\item +\tcode{a_eq} denotes a value of type \tcode{X} + 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}s + \tcode{X::key_equal::is_transparent} and + \tcode{X::hasher::is_transparent} + are both valid and denote types\iref{temp.deduct}, +\item +\tcode{i} and \tcode{j} denote input iterators + that refer to \tcode{value_type}, +\item +\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}}, +\item +\tcode{p} and \tcode{q2} denote valid constant iterators to \tcode{a}, +\item +\tcode{q} and \tcode{q1} denote + valid dereferenceable constant iterators to \tcode{a}, +\item +\tcode{r} denotes a valid dereferenceable iterator to \tcode{a}, +\item +\range{q1}{q2} denotes a valid range in \tcode{a}, +\item +\tcode{il} denotes a value of type \tcode{initializer_list}, +\item +\tcode{t} denotes a value of type \tcode{X::value_type}, +\item +\tcode{k} denotes a value of type \tcode{key_type}, +\item +\tcode{hf} denotes a value of type \tcode{hasher} or \tcode{const hasher}, +\item +\tcode{eq} denotes a value of type \tcode{key_equal} or \tcode{const key_equal}, +\item +\tcode{ke} is a value such that + \begin{itemize} + \item \tcode{eq(r1, ke) == eq(ke, r1)}, + \item \tcode{hf(r1) == hf(ke)} if \tcode{eq(r1, ke)} is \tcode{true}, and + \item if any two of + \tcode{eq(r1, ke)}, \tcode{eq(r2, ke)}, and \tcode{eq(r1, r2)} + are \tcode{true}, then all three are \tcode{true}, + \end{itemize} + where \tcode{r1} and \tcode{r2} are keys of elements in \tcode{a_tran}, +\item +\tcode{kx} is a value such that + \begin{itemize} + \item \tcode{eq(r1, kx) == eq(kx, r1)}, + \item \tcode{hf(r1) == hf(kx)} if \tcode{eq(r1, kx)} is \tcode{true}, + \item if any two of + \tcode{eq(r1, kx)}, \tcode{eq(r2, kx)}, and \tcode{eq(r1, r2)} + are \tcode{true}, then all three are \tcode{true}, and + \item \tcode{kx} is not convertible to + either \tcode{iterator} or \tcode{const_iterator}, + \end{itemize} + where \tcode{r1} and \tcode{r2} are keys of elements in \tcode{a_tran}, +\item +\tcode{n} denotes a value of type \tcode{size_type}, +\item +\tcode{z} denotes a value of type \tcode{float}, and +\item +\tcode{nh} denotes an rvalue of type \tcode{X::node_type}. +\end{itemize} + +\pnum +A type \tcode{X} meets +the \defnadj{unordered associative}{container} requirements +if \tcode{X} meets all the requirements of +an allocator-aware container\iref{container.alloc.reqmts} and +the following types, statements, and expressions are well-formed and +have the specified semantics, +except that for \tcode{unordered_map} and \tcode{unordered_multimap}, +the requirements placed on \tcode{value_type} in \ref{container.reqmts} +apply instead to \tcode{key_type} and \tcode{mapped_type}. +\begin{note} +For example, \tcode{key_type} and \tcode{mapped_type} +sometimes need to be \oldconcept{CopyAssignable} +even though the associated \tcode{value_type}, +\tcode{pair}, +is not \oldconcept{CopyAssignable}. +\end{note} + +% Local command to index names as members of all unordered containers. +\newcommand{\indexunordmem}[1]{% +\indexlibrary{\idxcode{#1}!unordered associative containers}% +\indexlibrary{\idxcode{unordered_set}!\idxcode{#1}}% +\indexlibrary{\idxcode{unordered_map}!\idxcode{#1}}% +\indexlibrary{\idxcode{unordered_multiset}!\idxcode{#1}}% +\indexlibrary{\idxcode{unordered_multimap}!\idxcode{#1}}% +} + +\indexunordmem{key_type}% +\begin{itemdecl} +typename X::key_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{Key}. +\end{itemdescr} + +\indexunordmem{mapped_type}% +\begin{itemdecl} +typename X::mapped_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{T}. + +\pnum +\remarks +For \tcode{unordered_map} and \tcode{unordered_multimap} only. +\end{itemdescr} + +\indexunordmem{value_type}% +\begin{itemdecl} +typename X::value_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{Key} for \tcode{unordered_set} and \tcode{unordered_multiset} only; +\tcode{pair} +for \tcode{unordered_map} and \tcode{unordered_multimap} only. + +\pnum +\expects +\tcode{value_type} is \oldconcept{Erasable} from \tcode{X}. +\end{itemdescr} + +\indexunordmem{hasher}% +\begin{itemdecl} +typename X::hasher +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{Hash}. + +\pnum +\expects +\tcode{Hash} is a unary function object type +such that the expression \tcode{hf(k)} has type \tcode{size_t}. +\end{itemdescr} + +\indexunordmem{key_equal}% +\begin{itemdecl} +typename X::key_equal +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{Pred}. + +\pnum +\expects +\tcode{Pred} meets the \oldconcept{CopyConstructible} requirements. +\tcode{Pred} is a binary predicate that takes two arguments of type \tcode{Key}. +\tcode{Pred} is an equivalence relation. +\end{itemdescr} + +\indexunordmem{local_iterator}% +\begin{itemdecl} +typename X::local_iterator +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +An iterator type +whose category, value type, difference type, and pointer and reference types +are the same as \tcode{X::iterator}'s. +\begin{note} +A \tcode{local_iterator} object can be used to iterate through a single bucket, +but cannot be used to iterate across buckets. +\end{note} +\end{itemdescr} + +\indexunordmem{const_local_iterator}% +\begin{itemdecl} +typename X::const_local_iterator +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +An iterator type +whose category, value type, difference type, and pointer and reference types +are the same as \tcode{X::const_iterator}'s. +\begin{note} +A \tcode{const_local_iterator} object can be used to iterate +through a single bucket, +but cannot be used to iterate across buckets. +\end{note} +\end{itemdescr} + +\indexunordmem{node_type}% +\begin{itemdecl} +typename X::node_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A specialization of a \exposid{node-handle} class template\iref{container.node}, +such that the public nested types are the same types +as the corresponding types in \tcode{X}. +\end{itemdescr} + +\indexlibraryctor{unordered_set}% +\indexlibraryctor{unordered_map}% +\indexlibraryctor{unordered_multiset}% +\indexlibraryctor{unordered_multimap}% +\begin{itemdecl} +X(n, hf, eq) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty container with at least \tcode{n} buckets, +using \tcode{hf} as the hash function and +\tcode{eq} as the key equality predicate. + +\pnum +\complexity +\bigoh{\tcode{n}} +\end{itemdescr} + +\begin{itemdecl} +X(n, hf) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{key_equal} meets the \oldconcept{DefaultConstructible} requirements. + +\pnum +\effects +Constructs an empty container with at least \tcode{n} buckets, +using \tcode{hf} as the hash function and +\tcode{key_equal()} as the key equality predicate. + +\pnum +\complexity +\bigoh{\tcode{n}} +\end{itemdescr} + +\begin{itemdecl} +X(n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{hasher} and \tcode{key_equal} +meet the \oldconcept{DefaultConstructible} requirements. + +\pnum +\effects +Constructs an empty container with at least \tcode{n} buckets, +using \tcode{hasher()} as the hash function and +\tcode{key_equal()} as the key equality predicate. + +\pnum +\complexity +\bigoh{\tcode{n}} +\end{itemdescr} + +\begin{itemdecl} +X a = X(); +X a; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{hasher} and \tcode{key_equal} meet +the \oldconcept{DefaultConstructible} requirements. + +\pnum +\effects +Constructs an empty container with an unspecified number of buckets, +using \tcode{hasher()} as the hash function and +\tcode{key_equal()} as the key equality predicate. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\begin{itemdecl} +X(i, j, n, hf, eq) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. + +\pnum +\effects +Constructs an empty container with at least \tcode{n} buckets, +using \tcode{hf} as the hash function and +\tcode{eq} as the key equality predicate, and +inserts elements from \range{i}{j} into it. + +\pnum +\complexity +Average case \bigoh{N} ($N$ is \tcode{distance(i, j)}), worst case \bigoh{N^2}. +\end{itemdescr} + +\begin{itemdecl} +X(i, j, n, hf) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{key_equal} meets the \oldconcept{DefaultConstructible} requirements. +\tcode{value_type} is +\oldconcept{\-EmplaceConstructible} into \tcode{X} from \tcode{*i}. + +\pnum +\effects +Constructs an empty container with at least \tcode{n} buckets, +using \tcode{hf} as the hash function and +\tcode{key_equal()} as the key equality predicate, and +inserts elements from \range{i}{j} into it. + +\pnum +\complexity +Average case \bigoh{N} ($N$ is \tcode{distance(i, j)}), worst case \bigoh{N^2}. +\end{itemdescr} + +\begin{itemdecl} +X(i, j, n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{hasher} and \tcode{key_equal} meet +the \oldconcept{DefaultConstructible} requirements. +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. + +\pnum +\effects +Constructs an empty container with at least \tcode{n} buckets, +using \tcode{hasher()} as the hash function and +\tcode{key_equal()} as the key equality predicate, and +inserts elements from \range{i}{j} into it. + +\pnum +\complexity +Average case \bigoh{N} ($N$ is \tcode{distance(i, j)}), worst case \bigoh{N^2}. +\end{itemdescr} + +\begin{itemdecl} +X(i, j) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{hasher} and \tcode{key_equal} meet +the \oldconcept{DefaultConstructible} requirements. +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. + +\pnum +\effects +Constructs an empty container with an unspecified number of buckets, +using \tcode{hasher()} as the hash function and +\tcode{key_equal()} as the key equality predicate, and +inserts elements from \range{i}{j} into it. + +\pnum +\complexity +Average case \bigoh{N} ($N$ is \tcode{distance(i, j)}), worst case \bigoh{N^2}. +\end{itemdescr} + +\begin{itemdecl} +X(from_range, rg, n, hf, eq) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. + +\pnum +\effects +Constructs an empty container with at least \tcode{n} buckets, +using \tcode{hf} as the hash function and +\tcode{eq} as the key equality predicate, and +inserts elements from \tcode{rg} into it. + +\pnum +\complexity +Average case \bigoh{N} ($N$ is \tcode{ranges::distance(rg)}), +worst case \bigoh{N^2}. +\end{itemdescr} + +\begin{itemdecl} +X(from_range, rg, n, hf) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{key_equal} meets the \oldconcept{DefaultConstructible} requirements. +\tcode{value_type} is +\oldconcept{\-EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. + +\pnum +\effects +Constructs an empty container with at least \tcode{n} buckets, +using \tcode{hf} as the hash function and +\tcode{key_equal()} as the key equality predicate, and +inserts elements from \tcode{rg} into it. + +\pnum +\complexity +Average case \bigoh{N} ($N$ is \tcode{ranges::distance(rg)}), +worst case \bigoh{N^2}. +\end{itemdescr} + +\begin{itemdecl} +X(from_range, rg, n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{hasher} and \tcode{key_equal} meet +the \oldconcept{DefaultConstructible} requirements. +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. + +\pnum +\effects +Constructs an empty container with at least \tcode{n} buckets, +using \tcode{hasher()} as the hash function and +\tcode{key_equal()} as the key equality predicate, and +inserts elements from \tcode{rg} into it. + +\pnum +\complexity +Average case \bigoh{N} ($N$ is \tcode{ranges::distance(rg)}), +worst case \bigoh{N^2}. +\end{itemdescr} + +\begin{itemdecl} +X(from_range, rg) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{hasher} and \tcode{key_equal} meet +the \oldconcept{DefaultConstructible} requirements. +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. + +\pnum +\effects +Constructs an empty container with an unspecified number of buckets, +using \tcode{hasher()} as the hash function and +\tcode{key_equal()} as the key equality predicate, and +inserts elements from \tcode{rg} into it. + +\pnum +\complexity +Average case \bigoh{N} ($N$ is \tcode{ranges::distance(rg)}), +worst case \bigoh{N^2}. +\end{itemdescr} + +\begin{itemdecl} +X(il) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{X(il.begin(), il.end())}. +\end{itemdescr} + +\begin{itemdecl} +X(il, n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{X(il.begin(), il.end(), n)}. +\end{itemdescr} + +\begin{itemdecl} +X(il, n, hf) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{X(il.begin(), il.end(), n, hf)}. +\end{itemdescr} + +\begin{itemdecl} +X(il, n, hf, eq) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{X(il.begin(), il.end(), n, hf, eq)}. +\end{itemdescr} + +\begin{itemdecl} +X(b) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +In addition to the container requirements\iref{container.reqmts}, +copies the hash function, predicate, and maximum load factor. + +\pnum +\complexity +Average case linear in \tcode{b.size()}, worst case quadratic. +\end{itemdescr} + +\begin{itemdecl} +a = b +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X\&} + +\pnum +\effects +In addition to the container requirements, +copies the hash function, predicate, and maximum load factor. + +\pnum +\complexity +Average case linear in \tcode{b.size()}, worst case quadratic. +\end{itemdescr} + +\begin{itemdecl} +a = il +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X\&} + +\pnum +\expects +\tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X} +and \oldconcept{CopyAssignable}. + +\pnum +\effects +Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. +All existing elements of \tcode{a} are either assigned to or destroyed. + +\pnum +\complexity +Average case linear in \tcode{il.size()}, worst case quadratic. +\end{itemdescr} + +\indexunordmem{hash_function}% +\begin{itemdecl} +b.hash_function() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{hasher} + +\pnum +\returns +\tcode{b}'s hash function. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{key_eq}% +\begin{itemdecl} +b.key_eq() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{key_equal} + +\pnum +\returns +\tcode{b}'s key equality predicate. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{emplace}% +\begin{itemdecl} +a_uniq.emplace(args) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{pair} + +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. + +\pnum +\effects +Inserts a \tcode{value_type} object \tcode{t} +constructed with \tcode{std::forward(args)...} if and only if +there is no element in the container +with key equivalent to the key of \tcode{t}. + +\pnum +\returns +The \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion takes place, and +the iterator component of the pair points to +the element with key equivalent to the key of \tcode{t}. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a_uniq.size()}}. +\end{itemdescr} + +\indexunordmem{emplace}% +\begin{itemdecl} +a_eq.emplace(args) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. + +\pnum +\effects +Inserts a \tcode{value_type} object \tcode{t} +constructed with \tcode{std::forward(args)...}. + +\pnum +\returns +An iterator pointing to the newly inserted element. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a_eq.size()}}. +\end{itemdescr} + +\indexunordmem{emplace_hint}% +\begin{itemdecl} +a.emplace_hint(p, args) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\effects +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 +\returns +The iterator returned by \tcode{emplace}. +\end{itemdescr} + +\indexunordmem{insert}% +\begin{itemdecl} +a_uniq.insert(t) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{pair} + +\pnum +\expects +If \tcode{t} is a non-const rvalue, +\tcode{value_type} is \oldconcept{MoveInsertable} into \tcode{X}; +otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}. + +\pnum +\effects +Inserts \tcode{t} if and only if there is no element in the container +with key equivalent to the key of \tcode{t}. + +\pnum +\returns +The \tcode{bool} component of the returned pair indicates +whether the insertion takes place, and +the \tcode{iterator} component points to +the element with key equivalent to the key of \tcode{t}. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a_uniq.size()}}. +\end{itemdescr} + +\indexunordmem{insert}% +\begin{itemdecl} +a_eq.insert(t) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\expects +If \tcode{t} is a non-const rvalue, +\tcode{value_type} is \oldconcept{MoveInsertable} into \tcode{X}; +otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}. + +\pnum +\effects +Inserts \tcode{t}. + +\pnum +\returns +An iterator pointing to the newly inserted element. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a_eq.size()}}. +\end{itemdescr} + +\indexunordmem{insert}% +\begin{itemdecl} +a.insert(p, t) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\expects +If \tcode{t} is a non-const rvalue, +\tcode{value_type} is \oldconcept{MoveInsertable} into \tcode{X}; +otherwise, \tcode{value_type} is \oldconcept{CopyInsertable} into \tcode{X}. + +\pnum +\effects +Equivalent to \tcode{a.insert(t)}. +The iterator \tcode{p} is a hint pointing to where the search should start. +Implementations are permitted to ignore the hint. + +\pnum +\returns +An iterator pointing to +the element with the key equivalent to that of \tcode{t}. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. +\end{itemdescr} + +\indexunordmem{insert}% +\begin{itemdecl} +a.insert(i, j) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. +Neither \tcode{i} nor \tcode{j} are iterators into \tcode{a}. + +\pnum +\effects +Equivalent to \tcode{a.insert(t)} for each element in \range{i}{j}. + +\pnum +\complexity +Average case \bigoh{N}, where $N$ is \tcode{distance(i, j)}, +worst case \bigoh{N(\tcode{a.size()} + 1)}. +\end{itemdescr} + +\indexunordmem{insert_range}% +\begin{itemdecl} +a.insert_range(rg) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{value_type} is +\oldconcept{EmplaceConstructible} into \tcode{X} +from \tcode{*ranges::begin(rg)}. +\tcode{rg} and \tcode{a} do not overlap. + +\pnum +\effects +Equivalent to \tcode{a.insert(t)} for each element \tcode{t} in \tcode{rg}. + +\pnum +\complexity +Average case \bigoh{N}, where $N$ is \tcode{ranges::distance(rg)}, +worst case \bigoh{N(\tcode{a.size()} + 1)}. +\end{itemdescr} + +\indexunordmem{insert}% +\begin{itemdecl} +a.insert(il) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{a.insert(il.begin(), il.end())}. +\end{itemdescr} + +\indexunordmem{insert}% +\begin{itemdecl} +a_uniq.insert(nh) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{insert_return_type} + +\pnum +\expects +\tcode{nh} is empty or +\tcode{a_uniq.get_allocator() == nh.get_allocator()} is \tcode{true}. + +\pnum +\effects +If \tcode{nh} is empty, has no effect. +Otherwise, inserts the element owned by \tcode{nh} if and only if +there is no element in the container with a key equivalent to \tcode{nh.key()}. + +\pnum +\ensures +If \tcode{nh} is empty, \tcode{inserted} is \tcode{false}, +\tcode{position} is \tcode{end()}, and \tcode{node} is empty. +Otherwise if the insertion took place, \tcode{inserted} is \tcode{true}, +\tcode{position} points to the inserted element, and \tcode{node} is empty; +if the insertion failed, \tcode{inserted} is \tcode{false}, +\tcode{node} has the previous value of \tcode{nh}, and \tcode{position} +points to an element with a key equivalent to \tcode{nh.key()}. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a_uniq.size()}}. +\end{itemdescr} + +\indexunordmem{insert}% +\begin{itemdecl} +a_eq.insert(nh) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\expects +\tcode{nh} is empty or +\tcode{a_eq.get_allocator() == nh.get_allocator()} is \tcode{true}. + +\pnum +\effects +If \tcode{nh} is empty, has no effect and returns \tcode{a_eq.end()}. +Otherwise, inserts the element owned by \tcode{nh} and +returns an iterator pointing to the newly inserted element. + +\pnum +\ensures +\tcode{nh} is empty. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a_eq.size()}}. +\end{itemdescr} + +\indexunordmem{insert}% +\begin{itemdecl} +a.insert(q, nh) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\expects +\tcode{nh} is empty or +\tcode{a.get_allocator() == nh.get_allocator()} is \tcode{true}. + +\pnum +\effects +If \tcode{nh} is empty, has no effect and returns \tcode{a.end()}. +Otherwise, inserts the element owned by \tcode{nh} if and only if +there is no element with key equivalent to \tcode{nh.key()} +in containers with unique keys; +always inserts the element owned by \tcode{nh} +in containers with equivalent keys. +The iterator \tcode{q} is a hint pointing to where the search should start. +Implementations are permitted to ignore the hint. + +\pnum +\ensures +\tcode{nh} is empty if insertion succeeds, unchanged if insertion fails. + +\pnum +\returns +An iterator pointing to the element with key equivalent to \tcode{nh.key()}. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. +\end{itemdescr} + +\indexunordmem{extract}% +\begin{itemdecl} +a.extract(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{node_type} + +\pnum +\effects +Removes an element in the container with key equivalent to \tcode{k}. + +\pnum +\returns +A \tcode{node_type} owning the element if found, +otherwise an empty \tcode{node_type}. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. +\end{itemdescr} + +\indexunordmem{extract}% +\begin{itemdecl} +a_tran.extract(kx) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{node_type} + +\pnum +\effects +Removes an element in the container with key equivalent to \tcode{kx}. + +\pnum +\returns +A \tcode{node_type} owning the element if found, +otherwise an empty \tcode{node_type}. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a_tran.size()}}. +\end{itemdescr} + +\indexunordmem{extract}% +\begin{itemdecl} +a.extract(q) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{node_type} + +\pnum +\effects +Removes the element pointed to by \tcode{q}. + +\pnum +\returns +A \tcode{node_type} owning that element. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. +\end{itemdescr} + +\indexunordmem{merge}% +\begin{itemdecl} +a.merge(a2) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{a.get_allocator() == a2.get_allocator()}. + +\pnum +\effects +Attempts to extract each element in \tcode{a2} and insert it into \tcode{a} +using the hash function and key equality predicate of \tcode{a}. +In containers with unique keys, if there is an element in \tcode{a} +with key equivalent to the key of an element from \tcode{a2}, +then that element is not extracted from \tcode{a2}. + +\pnum +\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 and +all iterators referring to \tcode{a} will be invalidated, +but iterators to elements remaining in \tcode{a2} will remain valid. + +\pnum +\complexity +Average case \bigoh{N}, where $N$ is \tcode{a2.size()}, +worst case \bigoh{N\tcode{*a.size() + N}}. +\end{itemdescr} + +\indexunordmem{erase}% +\begin{itemdecl} +a.erase(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\effects +Erases all elements with key equivalent to \tcode{k}. + +\pnum +\returns +The number of elements erased. + +\pnum +\complexity +Average case \bigoh{\tcode{a.count(k)}}, worst case \bigoh{\tcode{a.size()}}. +\end{itemdescr} + +\indexunordmem{erase}% +\begin{itemdecl} +a_tran.erase(kx) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\effects +Erases all elements with key equivalent to \tcode{kx}. + +\pnum +\returns +The number of elements erased. + +\pnum +\complexity +Average case \bigoh{\tcode{a_tran.count(kx)}}, +worst case \bigoh{\tcode{a_tran.size()}}. +\end{itemdescr} + +\indexunordmem{erase}% +\begin{itemdecl} +a.erase(q) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\effects +Erases the element pointed to by \tcode{q}. + +\pnum +\returns +The iterator immediately following \tcode{q} prior to the erasure. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. +\end{itemdescr} + +\indexunordmem{erase}% +\begin{itemdecl} +a.erase(r) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\effects +Erases the element pointed to by \tcode{r}. + +\pnum +\returns +The iterator immediately following \tcode{r} prior to the erasure. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. +\end{itemdescr} + +\indexunordmem{erase}% +\begin{itemdecl} +a.erase(q1, q2) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator} + +\pnum +\effects +Erases all elements in the range \range{q1}{q2}. + +\pnum +\returns +The iterator immediately following the erased elements prior to the erasure. + +\pnum +\complexity +Average case linear in \tcode{distance(q1, q2)}, +worst case \bigoh{\tcode{a.size()}}. +\end{itemdescr} + +\indexunordmem{clear}% +\begin{itemdecl} +a.clear() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\effects +Erases all elements in the container. + +\pnum +\ensures +\tcode{a.empty()} is \tcode{true}. + +\pnum +\complexity +Linear in \tcode{a.size()}. +\end{itemdescr} + +\indexunordmem{find}% +\begin{itemdecl} +b.find(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. + +\pnum +\returns +An iterator pointing to an element with key equivalent to \tcode{k}, or +\tcode{b.end()} if no such element exists. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{b.size()}}. +\end{itemdescr} + +\indexunordmem{find}% +\begin{itemdecl} +a_tran.find(ke) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. + +\pnum +\returns +An iterator pointing to an element with key equivalent to \tcode{ke}, or +\tcode{a_tran.end()} if no such element exists. + +\pnum +\complexity +Average case \bigoh{1}, worst case \bigoh{\tcode{a_tran.size()}}. +\end{itemdescr} + +\indexunordmem{count}% +\begin{itemdecl} +b.count(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\returns +The number of elements with key equivalent to \tcode{k}. + +\pnum +\complexity +Average case \bigoh{\tcode{b.count(k)}}, worst case \bigoh{\tcode{b.size()}}. +\end{itemdescr} + +\indexunordmem{count}% +\begin{itemdecl} +a_tran.count(ke) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\returns +The number of elements with key equivalent to \tcode{ke}. + +\pnum +\complexity +Average case \bigoh{\tcode{a_tran.count(ke)}}, +worst case \bigoh{\tcode{a_tran.size()}}. +\end{itemdescr} + +\indexunordmem{contains}% +\begin{itemdecl} +b.contains(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{b.find(k) != b.end()}. +\end{itemdescr} + +\indexunordmem{contains}% +\begin{itemdecl} +a_tran.contains(ke) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{a_tran.find(ke) != a_tran.end()}. +\end{itemdescr} + +\indexunordmem{equal_range}% +\begin{itemdecl} +b.equal_range(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{pair}; +\tcode{pair} for constant \tcode{b}. + +\pnum +\returns +A range containing all elements with keys equivalent to \tcode{k}. +Returns \tcode{make_pair(b.end(), b.end())} if no such elements exist. + +\pnum +\complexity +Average case \bigoh{\tcode{b.count(k)}}, worst case \bigoh{\tcode{b.size()}}. +\end{itemdescr} + +\indexunordmem{equal_range}% +\begin{itemdecl} +a_tran.equal_range(ke) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{pair}; +\tcode{pair} for constant \tcode{a_tran}. + +\pnum +\returns +A range containing all elements with keys equivalent to \tcode{ke}. +Returns \tcode{make_pair(a_tran.end(), a_tran.end())} if no such elements exist. + +\pnum +\complexity +Average case \bigoh{\tcode{a_tran.count(ke)}}, +worst case \bigoh{\tcode{a_tran.size()}}. +\end{itemdescr} + +\indexunordmem{bucket_count}% +\begin{itemdecl} +b.bucket_count() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\returns +The number of buckets that \tcode{b} contains. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{max_bucket_count}% +\begin{itemdecl} +b.max_bucket_count() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\returns +An upper bound on the number of buckets that \tcode{b} can ever contain. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{bucket}% +\begin{itemdecl} +b.bucket(k) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\expects +\tcode{b.bucket_count() > 0}. + +\pnum +\returns +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 \range{0}{b.bucket_count()}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{bucket}% +\begin{itemdecl} +a_tran.bucket(ke) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\expects +\tcode{a_tran.bucket_count() > 0}. + +\pnum +\ensures +The return value is in the range \range{0}{a_tran.bucket_count()}. + +\pnum +\returns +The index of the bucket +in which elements with keys equivalent to \tcode{ke} would be found, +if any such element existed. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{bucket_size}% +\begin{itemdecl} +b.bucket_size(n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{size_type} + +\pnum +\expects +\tcode{n} shall be in the range \range{0}{b.bucket_count()}. + +\pnum +\returns +The number of elements in the $\tcode{n}^\text{th}$ bucket. + +\pnum +\complexity +\bigoh{\tcode{b.bucket_size(n)}} +\end{itemdescr} + +\indexunordmem{begin}% +\begin{itemdecl} +b.begin(n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{local_iterator}; \tcode{const_local_iterator} for constant \tcode{b}. + +\pnum +\expects +\tcode{n} is in the range \range{0}{b.bucket_count()}. + +\pnum +\returns +An iterator referring to the first element in the bucket. +If the bucket is empty, then \tcode{b.begin(n) == b.end(n)}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{end}% +\begin{itemdecl} +b.end(n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{local_iterator}; \tcode{const_local_iterator} for constant \tcode{b}. + +\pnum +\expects +\tcode{n} is in the range \range{0}{b.bucket_count()}. + +\pnum +\returns +An iterator which is the past-the-end value for the bucket. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{cbegin}% +\begin{itemdecl} +b.cbegin(n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{const_local_iterator} + +\pnum +\expects +\tcode{n} shall be in the range \range{0}{b.bucket_count()}. + +\pnum +\returns +An iterator referring to the first element in the bucket. +If the bucket is empty, then \tcode{b.cbegin(n) == b.cend(n)}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{cend}% +\begin{itemdecl} +b.cend(n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{const_local_iterator} + +\pnum +\expects +\tcode{n} is in the range \range{0}{b.bucket_count()}. + +\pnum +\returns +An iterator which is the past-the-end value for the bucket. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{load_factor}% +\begin{itemdecl} +b.load_factor() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{float} + +\pnum +\returns +The average number of elements per bucket. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{max_load_factor}% +\begin{itemdecl} +b.max_load_factor() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{float} + +\pnum +\returns +A positive number +that the container attempts to keep the load factor less than or equal to. +The container automatically increases the number of buckets as necessary +to keep the load factor below this number. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{max_load_factor}% +\begin{itemdecl} +a.max_load_factor(z) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\expects +\tcode{z} is positive. +May change the container's maximum load factor, using \tcode{z} as a hint. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexunordmem{rehash}% +\begin{itemdecl} +a.rehash(n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\keyword{void} + +\pnum +\ensures +\tcode{a.bucket_count() >= a.size() / a.max_load_factor()} and +\tcode{a.bucket_count() >= n}.% + +\pnum +\complexity +Average case linear in \tcode{a.size()}, worst case quadratic. +\end{itemdescr} + +\indexunordmem{reserve}% +\begin{itemdecl} +a.reserve(n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{a.rehash(ceil(n / a.max_load_factor()))}. +\end{itemdescr} + +\pnum +Two unordered containers \tcode{a} and \tcode{b} compare equal if +\tcode{a.size() == b.size()} and, for every equivalent-key group +\range{Ea1}{Ea2} obtained from \tcode{a.equal_range(Ea1)}, there exists an +equivalent-key group \range{Eb1}{Eb2} obtained from \tcode{b.equal_range(Ea1)}, +such that +\tcode{is_permutation(Ea1, Ea2, Eb1, Eb2)} returns \tcode{true}. For +\tcode{unordered_set} and \tcode{unordered_map}, the complexity of +\tcode{operator==} (i.e., the number of calls to the \tcode{==} operator +of the \tcode{value_type}, to the predicate returned by \tcode{key_eq()}, +and to the hasher returned by \tcode{hash_function()}) is proportional to +$N$ in the average case and to $N^2$ in the worst case, where $N$ is +\tcode{a.size()}. For \tcode{unordered_multiset} and \tcode{unordered_multimap}, +the complexity of \tcode{operator==} is proportional to $\sum E_i^2$ +in the average case and to $N^2$ in the worst case, where $N$ is \tcode{a.size()}, +and $E_i$ is the size of the $i^\text{th}$ equivalent-key group in \tcode{a}. +However, if the respective elements of each corresponding pair of +equivalent-key groups $Ea_i$ and $Eb_i$ are arranged in the same order +(as is commonly the case, e.g., if \tcode{a} and \tcode{b} are unmodified copies +of the same container), then the average-case complexity for +\tcode{unordered_multiset} and \tcode{unordered_multimap} becomes +proportional to $N$ (but worst-case complexity remains \bigoh{N^2}, e.g., for +a pathologically bad hash function). The behavior of a program that uses +\tcode{operator==} or \tcode{operator!=} on unordered containers is undefined +unless the \tcode{Pred} function object has +the same behavior for both containers and the equality comparison function +for \tcode{Key} is a refinement +\begin{footnote} +Equality comparison is a refinement +of partitioning if no two objects that +compare equal fall into different partitions. +\end{footnote} +of the partition into equivalent-key groups produced by \tcode{Pred}. + +\pnum +\indextext{unordered associative containers!iterators}% +The iterator types \tcode{iterator} and \tcode{const_iterator} of +an unordered associative container are of at least the forward iterator +category. For unordered associative containers where the key type and +value type are the same, both \tcode{iterator} and +\tcode{const_iterator} are constant iterators. + +\pnum +\indextext{unordered associative containers!iterator invalidation}% +The \tcode{insert}, \tcode{insert_range}, and \tcode{emplace} members +shall not affect the validity of references to +container elements, but may invalidate all iterators to the +container. The \tcode{erase} members shall invalidate only iterators and +references to the erased elements, and preserve the relative order of the +elements that are not erased. + +\pnum +\indextext{unordered associative containers!iterator invalidation}% +\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 +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. + +\pnum +The \tcode{extract} members invalidate only iterators to the removed element, +and preserve the relative order of the elements that are not erased; pointers +and references to the removed element remain valid. However, accessing the +element through such pointers and references while the element is owned by a +\tcode{node_type} is undefined behavior. References and pointers to an element +obtained while it is owned by a \tcode{node_type} are invalidated if the +element is successfully inserted. + +\pnum +The member function templates +\tcode{find}, \tcode{count}, \tcode{equal_range}, \tcode{contains}, +\tcode{extract}, \tcode{erase}, and \tcode{bucket} +shall not participate in overload resolution unless +the \grammarterm{qualified-id}s +\tcode{Pred::is_transparent} and +\tcode{Hash::is_transparent} +are both valid and denote types\iref{temp.deduct}. +Additionally, the member function templates \tcode{extract} and \tcode{erase} +shall not participate in overload resolution if +\tcode{is_convertible_v || is_convertible_v} +is \tcode{true}, +where \tcode{K} is the type substituted as the first template argument. + +\pnum +A deduction guide for an unordered associative container shall not participate in overload resolution +if any of the following are true: +\begin{itemize} +\item It has an \tcode{InputIterator} template parameter +and a type that does not qualify as an input iterator is deduced for that parameter. + +\item It has an \tcode{Allocator} template parameter +and a type that does not qualify as an allocator is deduced for that parameter. + +\item It has a \tcode{Hash} template parameter +and an integral type or a type that qualifies as an allocator is deduced for that parameter. + +\item It has a \tcode{Pred} template parameter +and a type that qualifies as an allocator is deduced for that parameter. +\end{itemize} + +\rSec3[unord.req.except]{Exception safety guarantees} + +\pnum +\indextext{unordered associative containers!exception safety}% +\indextext{unordered associative containers!requirements}% +For unordered associative containers, no \tcode{clear()} function +throws an exception. \tcode{erase(k)} does not throw an +exception unless that exception is thrown by the container's \tcode{Hash} or +\tcode{Pred} object (if any). + +\pnum +For unordered associative containers, if an exception is thrown by any +operation other than the container's hash function from within an +\tcode{insert} or \tcode{emplace} function inserting a single element, +the insertion has no effect. + +\pnum +For unordered associative containers, no \tcode{swap} function throws +an exception unless that exception is thrown by the swap of the container's +\tcode{Hash} or \tcode{Pred} object (if any). + +\pnum +\indextext{unordered associative containers!exception safety}% +\indextext{unordered associative containers!requirements}% +For unordered associative containers, if an exception is thrown +from within a \tcode{rehash()} function other than by the container's hash +function or comparison function, the \tcode{rehash()} function has no effect. + +\rSec1[sequences]{Sequence containers} + +\rSec2[sequences.general]{General} + +\pnum +The headers +\libheaderref{array}, +\libheaderref{deque}, +\libheaderrefx{forward_list}{forward.list.syn}, +\libheaderref{hive}, +\libheaderrefx{inplace_vector}{inplace.vector.syn}, +\libheaderref{list}, and +\libheaderref{vector} +define class templates that meet the requirements for sequence containers. + +\pnum +The following exposition-only alias template may appear in deduction guides for sequence containers: + +\begin{codeblock} +template + using @\placeholdernc{iter-value-type}@ = iterator_traits::value_type; // \expos +\end{codeblock} + +\rSec2[array.syn]{Header \tcode{} synopsis} + +\indexheader{array}% +\begin{codeblock} +// mostly freestanding +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{array}, class template \tcode{array} + template struct array; // partially freestanding + + template + constexpr bool operator==(const array& x, const array& y); + template + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const array& x, const array& y); + + // \ref{array.special}, specialized algorithms + template + constexpr void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); + + // \ref{array.creation}, array creation functions + template + constexpr array, N> to_array(T (&a)[N]); + template + constexpr array, N> to_array(T (&&a)[N]); + + // \ref{array.tuple}, tuple interface + template struct tuple_size; + template struct tuple_element; + template + struct tuple_size>; + template + struct tuple_element>; + template + constexpr T& get(array&) noexcept; + template + constexpr T&& get(array&&) noexcept; + template + constexpr const T& get(const array&) noexcept; + template + constexpr const T&& get(const array&&) noexcept; +} +\end{codeblock} + +\rSec2[array]{Class template \tcode{array}} +\indexlibraryglobal{array}% + +\rSec3[array.overview]{Overview} + +\pnum +\indextext{\idxcode{array}!contiguous storage}% +The header \libheader{array} defines a class template for storing fixed-size +sequences of objects. +An \tcode{array} is a contiguous container\iref{container.reqmts}. +An instance of \tcode{array} stores \tcode{N} elements of type \tcode{T}, +so that \tcode{size() == N} is an invariant. + +\pnum +\indextext{\idxcode{array}!initialization}% +\indextext{\idxcode{array}!as aggregate}% +An \tcode{array} is an aggregate\iref{dcl.init.aggr} that can be +list-initialized with up +to \tcode{N} elements whose types are convertible to \tcode{T}. + +\pnum +\indextext{requirements!container}% +An \tcode{array} meets all of the requirements +of a container\iref{container.reqmts} and +of a reversible container\iref{container.rev.reqmts}, +except that a default +constructed \tcode{array} object is not empty if $\tcode{N} > 0$. +An \tcode{array} meets some of the requirements of a sequence +container\iref{sequence.reqmts}. +Descriptions are provided here +only for operations on \tcode{array} that are not described in +one of these tables and +for operations where there is additional semantic information. + +\pnum +\tcode{array} is a structural type\iref{term.structural.type} if +\tcode{T} is a structural type. +Two values \tcode{a1} and \tcode{a2} of type \tcode{array} +are template-argument-equivalent\iref{temp.type} if and only if +each pair of corresponding elements in \tcode{a1} and \tcode{a2} +are template-argument-equivalent. + +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + +\indexlibraryglobal{array}% +\indexlibrarymember{array}{begin}% +\indexlibrarymember{array}{end}% +\indexlibrarymember{array}{size}% +\indexlibrarymember{array}{max_size}% +\begin{codeblock} +namespace std { + template + struct array { + // types + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator = @\impdefx{type of \tcode{array::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{array::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // no explicit construct/copy/destroy for aggregate type + + constexpr void fill(const T& u); + constexpr void swap(array&) noexcept(is_nothrow_swappable_v); + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // element access + constexpr reference operator[](size_type n); + constexpr const_reference operator[](size_type n) const; + constexpr reference at(size_type n); // freestanding-deleted + constexpr const_reference at(size_type n) const; // freestanding-deleted + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; + + constexpr T* data() noexcept; + constexpr const T* data() const noexcept; + }; + + template + array(T, U...) -> array; +} +\end{codeblock} + +\rSec3[array.cons]{Constructors, copy, and assignment} + +\pnum +\indextext{\idxcode{array}!initialization}% +\indextext{requirements!container}% +An \tcode{array} relies on the implicitly-declared special +member functions\iref{class.default.ctor,class.dtor,class.copy.ctor} to +conform to the container requirements table in~\ref{container.requirements}. +In addition to the requirements specified in the container requirements table, +the implicitly-declared move constructor and move assignment operator for \tcode{array} +require that \tcode{T} be \oldconcept{MoveConstructible} or \oldconcept{MoveAssignable}, +respectively. + +\begin{itemdecl} +template + array(T, U...) -> array; +\end{itemdecl} +\begin{itemdescr} +\pnum +\mandates +\tcode{(is_same_v \&\& ...)} is \tcode{true}. +\end{itemdescr} + +\rSec3[array.members]{Member functions} + +\indexlibrarymember{array}{size}% +\begin{itemdecl} +constexpr size_type size() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{N}. +\end{itemdescr} + +\indexlibrarymember{array}{data}% +\begin{itemdecl} +constexpr T* data() noexcept; +constexpr const T* data() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A pointer such that \range{data()}{data() + size()} is a valid range. For a +non-empty array, \tcode{data() == addressof(front())} is \keyword{true}. +\end{itemdescr} + +\indexlibrarymember{array}{fill}% +\begin{itemdecl} +constexpr void fill(const T& u); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by \tcode{fill_n(begin(), N, u)}. +\end{itemdescr} + +\indexlibrarymember{array}{swap}% +\begin{itemdecl} +constexpr void swap(array& y) noexcept(is_nothrow_swappable_v); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{swap_ranges(begin(), end(), y.begin())}. + +\pnum +\begin{note} +Unlike the \tcode{swap} function for other containers, \tcode{array::swap} +takes linear time, can exit via an exception, and does not cause iterators to +become associated with the other container. +\end{note} +\end{itemdescr} + +\rSec3[array.special]{Specialized algorithms} + +\indexlibrarymember{array}{swap}% +\begin{itemdecl} +template + constexpr void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{N == 0} or \tcode{is_swappable_v} is \tcode{true}. + +\pnum +\effects +As if by \tcode{x.swap(y)}. + +\pnum +\complexity +Linear in \tcode{N}. +\end{itemdescr} + +\rSec3[array.zero]{Zero-sized arrays} + +\indextext{\idxcode{array}!zero sized}% +\pnum +\tcode{array} shall provide support for the special case \tcode{N == 0}. + +\pnum +In the case that \tcode{N == 0}, \tcode{begin() == end() ==} unique value. +The return value of \tcode{data()} is unspecified. + +\pnum +Member function \tcode{swap()} shall have a +non-throwing exception specification. + +\rSec3[array.creation]{Array creation functions} +\indextext{\idxcode{array}!creation}% + +\indexlibraryglobal{to_array}% +\begin{itemdecl} +template + constexpr array, N> to_array(T (&a)[N]); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_array_v} is \tcode{false} and +\tcode{is_constructible_v, T\&>} is \tcode{true}. + +\pnum +\expects +\tcode{T} meets the \oldconcept{CopyConstructible} requirements. + +\pnum +\returns +\tcode{\{\{ a[0], $\dotsc$, a[N - 1] \}\}}. +\end{itemdescr} + +\indexlibraryglobal{to_array}% +\begin{itemdecl} +template + constexpr array, N> to_array(T (&&a)[N]); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_array_v} is \tcode{false} and +\tcode{is_constructible_v, T>} is \tcode{true}. + +\pnum +\expects +\tcode{T} meets the \oldconcept{MoveConstructible} requirements. + +\pnum +\returns +\tcode{\{\{ std::move(a[0]), $\dotsc$, std::move(a[N - 1]) \}\}}. +\end{itemdescr} + +\rSec3[array.tuple]{Tuple interface} +\indexlibraryglobal{array}% +\indexlibraryglobal{tuple}% +\indextext{\idxcode{array}!tuple interface to}% +\indexlibraryglobal{tuple_size}% +\begin{itemdecl} +template + struct tuple_size> : integral_constant { }; +\end{itemdecl} + +\indexlibraryglobal{tuple_element}% +\begin{itemdecl} +template + struct tuple_element> { + using type = T; + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{I < N} is \tcode{true}. +\end{itemdescr} + +\indexlibrarymember{array}{get}% +\begin{itemdecl} +template + constexpr T& get(array& a) noexcept; +template + constexpr T&& get(array&& a) noexcept; +template + constexpr const T& get(const array& a) noexcept; +template + constexpr const T&& get(const array&& a) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{I < N} is \tcode{true}. + +\pnum +\returns +A reference to the $\tcode{I}^\text{th}$ element of \tcode{a}, +where indexing is zero-based. +\end{itemdescr} + +\rSec2[deque.syn]{Header \tcode{} synopsis} + +\indexheader{deque}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{deque}, class template \tcode{deque} + template> class deque; + + template + constexpr bool operator==(const deque& x, const deque& y); + template + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const deque& x, const deque& y); + + template + constexpr void swap(deque& x, deque& y) + noexcept(noexcept(x.swap(y))); + + // \ref{deque.erasure}, erasure + template + constexpr typename deque::size_type + erase(deque& c, const U& value); + template + constexpr typename deque::size_type + erase_if(deque& c, Predicate pred); + + namespace pmr { + template + using deque = std::deque>; + } +} +\end{codeblock} + +\rSec2[deque]{Class template \tcode{deque}} + +\rSec3[deque.overview]{Overview} + +\pnum +A +\indexlibraryglobal{deque}% +\tcode{deque} +is a sequence container that supports random access iterators\iref{random.access.iterators}. +In addition, it supports constant time insert and erase operations at the beginning or the end; +insert and erase in the middle take linear time. +That is, a deque is especially optimized for pushing and popping elements at the beginning and end. +Storage management is handled automatically. + +\pnum +A \tcode{deque} 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 the optional sequence container requirements\iref{sequence.reqmts}. +Descriptions are provided here only for operations on +\tcode{deque} +that are not described in one of these tables +or for operations where there is additional semantic information. + +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + +\begin{codeblock} +namespace std { + template> + class deque { + 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 = @\impdefx{type of \tcode{deque::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{deque::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{deque::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{deque::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // \ref{deque.cons}, construct/copy/destroy + 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 + constexpr deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + 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); + constexpr deque& operator=(initializer_list); + template + constexpr void assign(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const T& t); + constexpr void assign(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // \ref{deque.capacity}, capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr void resize(size_type sz); + constexpr void resize(size_type sz, const T& c); + constexpr void shrink_to_fit(); + + // element access + constexpr reference operator[](size_type n); + constexpr const_reference operator[](size_type n) const; + constexpr reference at(size_type n); + constexpr const_reference at(size_type n) const; + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; + + // \ref{deque.modifiers}, modifiers + template constexpr reference emplace_front(Args&&... args); + template constexpr reference emplace_back(Args&&... args); + template constexpr iterator emplace(const_iterator position, Args&&... args); + + constexpr void push_front(const T& x); + constexpr void push_front(T&& x); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void prepend_range(R&& rg); + constexpr void push_back(const T& x); + constexpr void push_back(T&& x); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); + + constexpr iterator insert(const_iterator position, const T& x); + constexpr iterator insert(const_iterator position, T&& x); + constexpr iterator insert(const_iterator position, size_type n, const T& x); + template + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); + constexpr iterator insert(const_iterator position, initializer_list); + + constexpr void pop_front(); + constexpr void pop_back(); + + 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); + constexpr void clear() noexcept; + }; + + template>> + deque(InputIterator, InputIterator, Allocator = Allocator()) + -> deque<@\placeholder{iter-value-type}@, Allocator>; + + template>> + deque(from_range_t, R&&, Allocator = Allocator()) + -> deque, Allocator>; +} +\end{codeblock} + +\rSec3[deque.cons]{Constructors, copy, and assignment} + +\indexlibraryctor{deque}% +\begin{itemdecl} +constexpr explicit deque(const Allocator&); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty +\tcode{deque}, +using the specified allocator. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{deque}% +\begin{itemdecl} +constexpr explicit deque(size_type n, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{deque}. + +\pnum +\effects +Constructs a \tcode{deque} with +\tcode{n} default-inserted elements using the specified allocator. + +\pnum +\complexity +Linear in \tcode{n}. +\end{itemdescr} + +\indexlibraryctor{deque}% +\begin{itemdecl} +constexpr deque(size_type n, const T& value, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{deque}. + +\pnum +\effects +Constructs a +\tcode{deque} +with \tcode{n} copies of \tcode{value}, +using the specified allocator. + +\pnum +\complexity +Linear in \tcode{n}. +\end{itemdescr} + +\indexlibraryctor{deque}% +\begin{itemdecl} +template + constexpr deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a +\tcode{deque} +equal to the range +\range{first}{last}, +using the specified allocator. + +\pnum +\complexity +Linear in \tcode{distance(first, last)}. +\end{itemdescr} + +\indexlibraryctor{deque}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr deque(from_range_t, R&& rg, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \tcode{deque} with the elements of the range \tcode{rg}, +using the specified allocator. + +\pnum +\complexity +Linear in \tcode{ranges::distance(rg)}. +\end{itemdescr} + +\rSec3[deque.capacity]{Capacity} + +\indexlibrarymember{resize}{deque}% +\begin{itemdecl} +constexpr void resize(size_type sz); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{deque}. + +\pnum +\effects +If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements +from the sequence. Otherwise, +appends \tcode{sz - size()} default-inserted elements to the sequence. +\end{itemdescr} + +\indexlibrarymember{resize}{deque}% +\begin{itemdecl} +constexpr void resize(size_type sz, const T& c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{deque}. + +\pnum +\effects +If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements +from the sequence. Otherwise, +appends \tcode{sz - size()} copies of \tcode{c} to the sequence. +\end{itemdescr} + +\indexlibrarymember{shrink_to_fit}{deque}% +\begin{itemdecl} +constexpr void shrink_to_fit(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{deque}. + +\pnum +\effects +\tcode{shrink_to_fit} is a non-binding request to reduce memory use +but does not change the size of the sequence. +\begin{note} +The request is non-binding to allow latitude for +implementation-specific optimizations. +\end{note} +If the size is equal to the old capacity, or +if an exception is thrown other than by the move constructor +of a non-\oldconcept{CopyInsertable} \tcode{T}, +then there are no effects. + +\pnum +\complexity +If the size is not equal to the old capacity, +linear in the size of the sequence; +otherwise constant. + +\pnum +\remarks +If the size is not equal to the old capacity, +then invalidates all the references, pointers, and iterators +referring to the elements in the sequence, +as well as the past-the-end iterator. +\end{itemdescr} + +\rSec3[deque.modifiers]{Modifiers} + +\indexlibrarymember{insert}{deque}% +\indexlibrarymember{push_front}{deque}% +\indexlibrarymember{push_back}{deque}% +\indexlibrarymember{emplace}{deque}% +\begin{itemdecl} +constexpr iterator insert(const_iterator position, const T& x); +constexpr iterator insert(const_iterator position, T&& x); +constexpr iterator insert(const_iterator position, size_type n, const T& x); +template + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); +template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); +constexpr iterator insert(const_iterator position, initializer_list); + +template constexpr reference emplace_front(Args&&... args); +template constexpr reference emplace_back(Args&&... args); +template constexpr iterator emplace(const_iterator position, Args&&... args); +constexpr void push_front(const T& x); +constexpr void push_front(T&& x); +template<@\exposconcept{container-compatible-range}@ R> + constexpr void prepend_range(R&& rg); +constexpr void push_back(const T& x); +constexpr void push_back(T&& x); +template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +An insertion in the middle of the deque invalidates all the iterators and +references to elements of the deque. +An insertion at either end of the +deque invalidates all the iterators to the deque, but has no effect on +the validity of references to elements of the deque. + +\pnum +\complexity +The complexity is linear in the number of elements inserted plus the lesser +of the distances to the beginning and end of the deque. +Inserting a single element at either the beginning or end of a deque always takes constant time +and causes a single call to a constructor of +\tcode{T}. + +\pnum +\remarks +If an exception is thrown other than by the +copy constructor, move constructor, +assignment operator, or move assignment operator of +\tcode{T}, +there are no effects. +If an exception is thrown while inserting a single element at either end, +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. +\end{itemdescr} + +\indexlibrarymember{erase}{deque}% +\begin{itemdecl} +constexpr iterator erase(const_iterator position); +constexpr iterator erase(const_iterator first, const_iterator last); +constexpr void pop_front(); +constexpr void pop_back(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +An erase operation that erases the last element of a deque invalidates only the past-the-end iterator +and all iterators and references to the erased elements. An erase operation that erases the first +element of a deque but not the last element invalidates only iterators +and references to the erased elements. An erase operation +that erases neither the first element nor the last element of a deque invalidates the past-the-end +iterator and all iterators and references to all the elements of the deque. +\begin{note} +\tcode{pop_front} and \tcode{pop_back} are erase operations. +\end{note} + +\pnum +\throws +Nothing unless an exception is thrown by the assignment operator of +\tcode{T}. + +\pnum +\complexity +The number of calls to the destructor of \tcode{T} is the same as the +number of elements erased, but the number of calls to the assignment operator of \tcode{T} is +no more than the lesser of the number of elements before the erased elements and the number of elements after the erased elements. +\end{itemdescr} + +\rSec3[deque.erasure]{Erasure} + +\indexlibrarymember{erase}{deque}% +\begin{itemdecl} +template + constexpr typename deque::size_type + erase(deque& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto it = remove(c.begin(), c.end(), value); +auto r = distance(it, c.end()); +c.erase(it, c.end()); +return r; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{erase_if}{deque}% +\begin{itemdecl} +template + constexpr typename deque::size_type + erase_if(deque& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto it = remove_if(c.begin(), c.end(), pred); +auto r = distance(it, c.end()); +c.erase(it, c.end()); +return r; +\end{codeblock} +\end{itemdescr} + +\rSec2[forward.list.syn]{Header \tcode{} synopsis} + +\indexheader{forward_list}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{forward.list}, class template \tcode{forward_list} + template> class forward_list; + + template + constexpr bool operator==(const forward_list& x, + const forward_list& y); + template + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const forward_list& x, + const forward_list& y); + + template + constexpr void swap(forward_list& x, forward_list& y) + noexcept(noexcept(x.swap(y))); + + // \ref{forward.list.erasure}, erasure + template + constexpr typename forward_list::size_type + erase(forward_list& c, const U& value); + template + constexpr typename forward_list::size_type + erase_if(forward_list& c, Predicate pred); + + namespace pmr { + template + using forward_list = std::forward_list>; + } +} +\end{codeblock} + +\rSec2[forward.list]{Class template \tcode{forward_list}} + +\rSec3[forward.list.overview]{Overview} + +\pnum +A \tcode{forward_list} is a container that supports forward iterators and allows +constant time insert and erase operations anywhere within the sequence, with storage +management handled automatically. Fast random access to list elements is not supported. +\begin{note} +It is intended that \tcode{forward_list} have zero space or time overhead +relative to a hand-written C-style singly linked list. Features that would conflict with +that goal have been omitted. +\end{note} + +\pnum +A \tcode{forward_list} meets all of the requirements +of a container\iref{container.reqmts}, +except that the \tcode{size()} member function is not provided and +\tcode{operator==} has linear complexity. +A \tcode{forward_list} also meets all of the requirements +for an allocator-aware container\iref{container.alloc.reqmts}. +In addition, a \tcode{forward_list} +provides the \tcode{assign} member functions and +several of the optional sequence container requirements\iref{sequence.reqmts}. +Descriptions are provided here only for operations on +\tcode{forward_list} that are not described in that table or for operations where there +is additional semantic information. + +\pnum +\begin{note} +Modifying any list requires access to the element preceding the first element +of interest, but in a \tcode{forward_list} there is no constant-time way to access a +preceding element. +For this reason, \tcode{erase_after} and \tcode{splice_after} +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> + class forward_list { + 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 = @\impdefx{type of \tcode{forward_list::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{forward_list::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{forward_list::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{forward_list::const_iterator}}@; // see \ref{container.requirements} + + // \ref{forward.list.cons}, construct/copy/destroy + 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 + constexpr forward_list(InputIterator first, InputIterator last, + const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + 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); + constexpr forward_list& operator=(initializer_list); + template + constexpr void assign(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const T& t); + constexpr void assign(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // \ref{forward.list.iter}, iterators + 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; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cbefore_begin() const noexcept; + constexpr const_iterator cend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type max_size() const noexcept; + + // \ref{forward.list.access}, element access + constexpr reference front(); + constexpr const_reference front() const; + + // \ref{forward.list.modifiers}, modifiers + 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> + constexpr void prepend_range(R&& rg); + constexpr void pop_front(); + + 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); + + constexpr iterator insert_after(const_iterator position, size_type n, const T& x); + template + 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> + constexpr iterator insert_range_after(const_iterator position, R&& rg); + + 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); + + 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 + 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>> + forward_list(InputIterator, InputIterator, Allocator = Allocator()) + -> forward_list<@\placeholder{iter-value-type}@, Allocator>; + + template>> + forward_list(from_range_t, R&&, Allocator = Allocator()) + -> forward_list, Allocator>; +} +\end{codeblock} + +\pnum +An incomplete type \tcode{T} may be used when instantiating \tcode{forward_list} +if the allocator meets the +allocator completeness requirements\iref{allocator.requirements.completeness}. +\tcode{T} shall be complete before any member of the resulting specialization +of \tcode{forward_list} is referenced. + +\rSec3[forward.list.cons]{Constructors, copy, and assignment} + +\indexlibraryctor{forward_list}% +\begin{itemdecl} +constexpr explicit forward_list(const Allocator&); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{forward_list} object using the specified allocator. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{forward_list}% +\begin{itemdecl} +constexpr explicit forward_list(size_type n, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{forward_list}. + +\pnum +\effects +Constructs a \tcode{forward_list} object with \tcode{n} +default-inserted elements using the specified allocator. + +\pnum +\complexity +Linear in \tcode{n}. +\end{itemdescr} + +\indexlibraryctor{forward_list}% +\begin{itemdecl} +constexpr forward_list(size_type n, const T& value, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{forward_list}. + +\pnum +\effects +Constructs a \tcode{forward_list} object with \tcode{n} copies of \tcode{value} using the specified allocator. + +\pnum +\complexity +Linear in \tcode{n}. +\end{itemdescr} + +\indexlibraryctor{forward_list}% +\begin{itemdecl} +template + constexpr forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \tcode{forward_list} object equal to the range \range{first}{last}. + +\pnum +\complexity +Linear in \tcode{distance(first, last)}. +\end{itemdescr} + +\indexlibraryctor{forward_list}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \tcode{forward_list} object +with the elements of the range \tcode{rg}. + +\pnum +\complexity +Linear in \tcode{ranges::distance(rg)}. +\end{itemdescr} + +\rSec3[forward.list.iter]{Iterators} + +\indexlibrarymember{before_begin}{forward_list}% +\indexlibrarymember{cbefore_begin}{forward_list}% +\begin{itemdecl} +constexpr iterator before_begin() noexcept; +constexpr const_iterator before_begin() const noexcept; +constexpr const_iterator cbefore_begin() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\tcode{cbefore_begin()} is equivalent to +\tcode{const_cast(*this).before_begin()}. + +\pnum +\returns +A non-dereferenceable iterator that, when incremented, is equal to the iterator +returned by \tcode{begin()}. + +\pnum +\remarks +\tcode{before_begin() == end()} shall equal \tcode{false}. +\end{itemdescr} + +\rSec3[forward.list.access]{Element access} + +\indexlibrarymember{front}{forward_list}% +\begin{itemdecl} +constexpr reference front(); +constexpr const_reference front() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{*begin()} +\end{itemdescr} + +\rSec3[forward.list.modifiers]{Modifiers} + +\pnum +The member functions in this subclause +do not affect the validity of iterators and references +when inserting elements, and when erasing elements +invalidate iterators and references to the erased elements only. +If an exception is thrown by any of these member functions +there is no effect on the container. +Inserting \tcode{n} elements into a \tcode{forward_list} is linear in +\tcode{n}, and the number of calls to the copy or move constructor of \tcode{T} is +exactly equal to \tcode{n}. Erasing \tcode{n} elements from a \tcode{forward_list} is +linear in \tcode{n} and the number of calls to the destructor of type \tcode{T} is +exactly equal to \tcode{n}. + +\indexlibrarymember{emplace_front}{forward_list}% +\begin{itemdecl} +template constexpr reference emplace_front(Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Inserts an object of type \tcode{value_type} constructed with +\tcode{value_type(std::forward(\brk{}args)...)} at the beginning of the list. +\end{itemdescr} + +\indexlibrarymember{push_front}{forward_list}% +\begin{itemdecl} +constexpr void push_front(const T& x); +constexpr void push_front(T&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Inserts a copy of \tcode{x} at the beginning of the list. +\end{itemdescr} + +\indexlibrarymember{prepend_range}{forward_list}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr void prepend_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Inserts a copy of each element of \tcode{rg} at the beginning of the list. +\begin{note} +The order of elements is not reversed. +\end{note} +\end{itemdescr} + +\indexlibrarymember{pop}{forward_list}% +\begin{itemdecl} +constexpr void pop_front(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by \tcode{erase_after(before_begin())}. +\end{itemdescr} + +\indexlibrarymember{insert_after}{forward_list}% +\begin{itemdecl} +constexpr iterator insert_after(const_iterator position, const T& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{forward_list}. +\tcode{position} is \tcode{before_begin()} or is a dereferenceable +iterator in the range \range{begin()}{end()}. + +\pnum +\effects +Inserts a copy of \tcode{x} after \tcode{position}. + +\pnum +\returns +An iterator pointing to the copy of \tcode{x}. +\end{itemdescr} + +\indexlibrarymember{insert_after}{forward_list}% +\begin{itemdecl} +constexpr iterator insert_after(const_iterator position, T&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{forward_list}. +\tcode{position} is \tcode{before_begin()} or is a dereferenceable +iterator in the range \range{begin()}{end()}. + +\pnum +\effects +Inserts a copy of \tcode{x} after \tcode{position}. + +\pnum +\returns +An iterator pointing to the copy of \tcode{x}. +\end{itemdescr} + +\indexlibrarymember{insert_after}{forward_list}% +\begin{itemdecl} +constexpr iterator insert_after(const_iterator position, size_type n, const T& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{forward_list}. +\tcode{position} is \tcode{before_begin()} or is a dereferenceable +iterator in the range \range{begin()}{end()}. + +\pnum +\effects +Inserts \tcode{n} copies of \tcode{x} after \tcode{position}. + +\pnum +\returns +An iterator pointing to the last inserted copy of \tcode{x}, or +\tcode{position} if \tcode{n == 0} is \tcode{true}. +\end{itemdescr} + +\indexlibrarymember{insert_after}{forward_list}% +\begin{itemdecl} +template + constexpr iterator insert_after(const_iterator position, + InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{forward_list} +from \tcode{*first}. +\tcode{position} is \tcode{before_begin()} or is a dereferenceable +iterator in the range \range{begin()}{end()}. +Neither \tcode{first} nor \tcode{last} are iterators in \tcode{*this}. + +\pnum +\effects +Inserts copies of elements in \range{first}{last} after \tcode{position}. + +\pnum +\returns +An iterator pointing to the last inserted element, or +\tcode{position} if \tcode{first == last} is \tcode{true}. +\end{itemdescr} + +\indexlibrarymember{insert_range_after}{forward_list}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range_after(const_iterator position, R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{forward_list} +from \tcode{*ranges::begin(rg)}. +\tcode{posi\-tion} is \tcode{before_begin()} or +is a dereferenceable iterator in the range \range{begin()}{end()}. +\tcode{rg} and \tcode{*this} do not overlap. + +\pnum +\effects +Inserts copies of elements in the range \tcode{rg} after \tcode{position}. + +\pnum +\returns +An iterator pointing to the last inserted element, +or \tcode{position} if \tcode{rg} is empty. +\end{itemdescr} + +\indexlibrarymember{insert_after}{forward_list}% +\begin{itemdecl} +constexpr iterator insert_after(const_iterator position, initializer_list il); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return insert_after(position, il.begin(), il.end());} +\end{itemdescr} + + +\indexlibrarymember{emplace_after}{forward_list}% +\begin{itemdecl} +template + constexpr iterator emplace_after(const_iterator position, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{forward_list} +from \tcode{std::forward(\linebreak args)...}. +\tcode{position} is \tcode{before_begin()} or is a dereferenceable +iterator in the range \range{begin()}{end()}. + +\pnum +\effects +Inserts an object of type \tcode{value_type} direct-non-list-initialized with +\tcode{std::forward(\linebreak args)...} after \tcode{position}. + +\pnum +\returns +An iterator pointing to the new object. +\end{itemdescr} + +\indexlibrarymember{erase_after}{forward_list}% +\begin{itemdecl} +constexpr iterator erase_after(const_iterator position); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +The iterator following \tcode{position} is dereferenceable. + +\pnum +\effects +Erases the element pointed to by the iterator following \tcode{position}. + +\pnum +\returns +An iterator pointing to the element following the one that was +erased, or \tcode{end()} if no such element exists. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\begin{itemdecl} +constexpr iterator erase_after(const_iterator position, const_iterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +All iterators in the range \orange{position}{last} are dereferenceable. + +\pnum +\effects +Erases the elements in the range \orange{position}{last}. + +\pnum +\returns +\tcode{last}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\indexlibrarymember{resize}{forward_list}% +\begin{itemdecl} +constexpr void resize(size_type sz); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{forward_list}. + +\pnum +\effects +If \tcode{sz < distance(begin(), end())}, erases the last \tcode{distance(begin(), +end()) - sz} elements from the list. Otherwise, inserts \tcode{sz - distance(begin(), end())} default-inserted +elements at the end of the list. +\end{itemdescr} + +\begin{itemdecl} +constexpr void resize(size_type sz, const value_type& c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{forward_list}. + +\pnum +\effects +If \tcode{sz < distance(begin(), end())}, erases the last \tcode{distance(begin(), +end()) - sz} elements from the list. Otherwise, inserts \tcode{sz - distance(begin(), end())} +copies of \tcode{c} at the end of the list. +\end{itemdescr} + + +\indexlibrarymember{clear}{forward_list}% +\begin{itemdecl} +constexpr void clear() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Erases all elements in the range \range{begin()}{end()}. + +\pnum +\remarks +Does not invalidate past-the-end iterators. +\end{itemdescr} + +\rSec3[forward.list.ops]{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}, +where \tcode{i} is an iterator into the list and \tcode{n} is an integer, +are the same as those of \tcode{next(i, n)}. +The expression \tcode{i - n}, +where \tcode{i} is an iterator into the list and \tcode{n} is an integer, +means an iterator \tcode{j} such that \tcode{j + n == i} is \tcode{true}. +For \tcode{merge} and \tcode{sort}, +the definitions and requirements in \ref{alg.sorting} apply. + +\indexlibrarymember{splice_after}{forward_list}% +\begin{itemdecl} +constexpr void splice_after(const_iterator position, forward_list& x); +constexpr void splice_after(const_iterator position, forward_list&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{position} is \tcode{before_begin()} or is a dereferenceable +iterator in the range \range{begin()}{end()}. +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. +\tcode{addressof(x) != this} is \tcode{true}. + +\pnum +\effects +Inserts the contents of \tcode{x} after +\tcode{position}, and \tcode{x} becomes empty. Pointers and references to the moved +elements of \tcode{x} now refer to those same elements but as members of \tcode{*this}. +Iterators referring to the moved elements will continue to refer to their elements, but +they now behave as iterators into \tcode{*this}, not into \tcode{x}. + +\pnum +\throws +Nothing. + +\pnum +\complexity +\bigoh{\tcode{distance(x.begin(), x.end())}} +\end{itemdescr} + +\indexlibrarymember{splice_after}{forward_list}% +\begin{itemdecl} +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} +\pnum +\expects +\tcode{position} is \tcode{before_begin()} or is a dereferenceable +iterator in the range \range{begin()}{end()}. +The iterator following \tcode{i} is a dereferenceable iterator in \tcode{x}. +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. + +\pnum +\effects +Inserts the element following \tcode{i} into \tcode{*this}, following +\tcode{position}, and removes it from \tcode{x}. +The result is unchanged if \tcode{position == i} or \tcode{position == ++i}. Pointers +and references to \tcode{*++i} continue to refer to the same element but as a member of +\tcode{*this}. Iterators to \tcode{*++i} continue to refer to +the same element, but now behave as iterators into \tcode{*this}, not into \tcode{x}. + +\pnum +\throws +Nothing. + +\pnum +\complexity +\bigoh{1} +\end{itemdescr} + +\indexlibrarymember{splice_after}{forward_list}% +\begin{itemdecl} +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} +\pnum +\expects +\tcode{position} is \tcode{before_begin()} or is a +dereferenceable iterator in the range \range{begin()}{end()}. \orange{first}{last} is a +valid range in \tcode{x}, and all iterators in the range \orange{first}{last} are +dereferenceable. \tcode{position} is not an iterator in the range \orange{first}{last}. +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. + +\pnum +\effects +Inserts elements in the range \orange{first}{last} after \tcode{position} and +removes the elements from \tcode{x}. Pointers and references to the moved elements of +\tcode{x} now refer to those same elements but as members of \tcode{*this}. Iterators +referring to the moved elements will continue to refer to their elements, but they now +behave as iterators into \tcode{*this}, not into \tcode{x}. + +\pnum +\complexity +\bigoh{\tcode{distance(first, last)}} +\end{itemdescr} + +\indexlibrarymember{remove}{forward_list}% +\indexlibrarymember{remove_if}{forward_list}% +\begin{itemdecl} +constexpr size_type remove(const T& value); +template constexpr size_type remove_if(Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Erases all the elements in the list referred to by a list iterator \tcode{i} for +which the following conditions hold: \tcode{*i == value} (for \tcode{remove()}), +\tcode{pred(*i)} is \tcode{true} (for \tcode{remove_if()}). +Invalidates only the iterators and references to the erased elements. + +\pnum +\returns +The number of elements erased. + +\pnum +\throws +Nothing unless an exception is thrown by the equality comparison or the +predicate. + +\pnum +\complexity +Exactly \tcode{distance(begin(), end())} applications of the corresponding +predicate. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} + +\indexlibrarymember{unique}{forward_list}% +\begin{itemdecl} +constexpr size_type unique(); +template constexpr size_type unique(BinaryPredicate binary_pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{binary_pred} be \tcode{equal_to<>\{\}} for the first overload. + +\pnum +\expects +\tcode{binary_pred} is an equivalence relation. + +\pnum +\effects +Erases all but the first element from every consecutive +group of equivalent elements. +That is, for a nonempty list, erases all elements referred to +by the iterator \tcode{i} in the range \range{begin() + 1}{end()} +for which \tcode{binary_pred(*i, *(i - 1))} is \tcode{true}. +Invalidates only the iterators and references to the erased elements. + +\pnum +\returns +The number of elements erased. + +\pnum +\throws +Nothing unless an exception is thrown by the predicate. + +\pnum +\complexity +If \tcode{empty()} is \tcode{false}, +exactly \tcode{distance(begin(), end()) - 1} applications of +the corresponding predicate, +otherwise no applications of the predicate. +\end{itemdescr} + +\indexlibrarymember{merge}{forward_list}% +\begin{itemdecl} +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} +\pnum +Let \tcode{comp} be \tcode{less<>{}} for the first two overloads. + +\pnum +\expects +\tcode{*this} and \tcode{x} are both sorted +with respect to the comparator \tcode{comp}, and +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. + +\pnum +\effects +If \tcode{addressof(x) == this}, there are no effects. +Otherwise, merges +the two sorted ranges \range{begin()}{end()} and \range{x.begin()}{x.end()}. +The result is a range +that is sorted with respect to the comparator \tcode{comp}. +Pointers and references to the moved elements of \tcode{x} now refer to those same elements +but as members of \tcode{*this}. Iterators referring to the moved elements will continue to +refer to their elements, but they now behave as iterators into \tcode{*this}, not into +\tcode{x}. + +\pnum +\complexity +At most \tcode{distance(begin(), +end()) + distance(x.begin(), x.end()) - 1} comparisons +if \tcode{addressof(x) != this}; otherwise, no comparisons are performed. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +If \tcode{addressof(x) != this}, \tcode{x} is empty after the merge. +No elements are copied by this operation. +If an exception is thrown other than by a comparison, there are no effects. +\end{itemdescr} + +\indexlibrarymember{sort}{forward_list}% +\begin{itemdecl} +constexpr void sort(); +template constexpr void sort(Compare comp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Sorts the list according to the \tcode{operator<} or the \tcode{comp} function object. +If an exception is thrown, the order of the elements in \tcode{*this} is unspecified. +Does not affect the validity of iterators and references. + +\pnum +\complexity +Approximately $N \log N$ comparisons, where $N$ is \tcode{distance(begin(), end())}. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} + +\indexlibrarymember{reverse}{forward_list}% +\begin{itemdecl} +constexpr void reverse() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Reverses the order of the elements in the list. +Does not affect the validity of iterators and references. + +\pnum +\complexity +Linear time. +\end{itemdescr} + +\rSec3[forward.list.erasure]{Erasure} + +\indexlibrarymember{erase}{forward_list}% +\begin{itemdecl} +template + constexpr typename forward_list::size_type + erase(forward_list& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return erase_if(c, [&](const auto& elem) -> bool { return elem == value; }); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{erase_if}{forward_list}% +\begin{itemdecl} +template + constexpr typename forward_list::size_type + erase_if(forward_list& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return c.remove_if(pred);} +\end{itemdescr} + +\rSec2[hive.syn]{Header \tcode{} synopsis} + +\indexheader{hive}% +\begin{codeblock} + +#include // see \ref{initializer.list.syn} +#include // see \ref{compare.syn} + +namespace std { + struct @\libglobal{hive_limits}@ { + size_t @\libmember{min}{hive_limits}@; + size_t @\libmember{max}{hive_limits}@; + constexpr hive_limits(size_t minimum, size_t maximum) noexcept + : min(minimum), max(maximum) {} + }; + + // \ref {hive}, class template \tcode{hive} + template> class hive; + + template + void swap(hive& x, hive& y) + noexcept(noexcept(x.swap(y))); + + template + typename hive::size_type + erase(hive& c, const U& value); + + template + typename hive::size_type + erase_if(hive& c, Predicate pred); + + namespace pmr { + template + using hive = std::hive>; + } +} +\end{codeblock} + +\rSec2[hive]{Class template \tcode{hive}} + +\rSec3[hive.overview]{Overview} + +\pnum +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 +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 +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 { + template> + class list { + 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 = @\impdefx{type of \tcode{list::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{list::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{list::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{list::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // \ref{list.cons}, construct/copy/destroy + constexpr list() : list(Allocator()) { } + constexpr explicit list(const Allocator&); + constexpr explicit list(size_type n, const Allocator& = Allocator()); + constexpr list(size_type n, const T& value, const Allocator& = Allocator()); + template + constexpr list(InputIterator first, InputIterator last, const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + constexpr list(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr list(const list& x); + constexpr list(list&& x); + constexpr list(const list&, const type_identity_t&); + constexpr list(list&&, const type_identity_t&); + constexpr list(initializer_list, const Allocator& = Allocator()); + constexpr ~list(); + constexpr list& operator=(const list& x); + constexpr list& operator=(list&& x) + noexcept(allocator_traits::is_always_equal::value); + constexpr list& operator=(initializer_list); + template + constexpr void assign(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const T& t); + constexpr void assign(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // \ref{list.capacity}, capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr void resize(size_type sz); + constexpr void resize(size_type sz, const T& c); + + // element access + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; + + // \ref{list.modifiers}, modifiers + template constexpr reference emplace_front(Args&&... args); + template constexpr reference emplace_back(Args&&... args); + constexpr void push_front(const T& x); + constexpr void push_front(T&& x); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void prepend_range(R&& rg); + constexpr void pop_front(); + constexpr void push_back(const T& x); + constexpr void push_back(T&& x); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); + constexpr void pop_back(); + + template constexpr iterator emplace(const_iterator position, Args&&... args); + constexpr iterator insert(const_iterator position, const T& x); + constexpr iterator insert(const_iterator position, T&& x); + constexpr iterator insert(const_iterator position, size_type n, const T& x); + template + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); + constexpr iterator insert(const_iterator position, initializer_list il); + + constexpr iterator erase(const_iterator position); + constexpr iterator erase(const_iterator position, const_iterator last); + constexpr void swap(list&) noexcept(allocator_traits::is_always_equal::value); + constexpr void clear() noexcept; + + // \ref{list.ops}, list operations + constexpr void splice(const_iterator position, list& x); + constexpr void splice(const_iterator position, list&& x); + constexpr void splice(const_iterator position, list& x, const_iterator i); + constexpr void splice(const_iterator position, list&& x, const_iterator i); + constexpr void splice(const_iterator position, list& x, + const_iterator first, const_iterator last); + constexpr void splice(const_iterator position, list&& x, + const_iterator first, const_iterator last); + + constexpr size_type remove(const T& value); + template constexpr size_type remove_if(Predicate pred); + + constexpr size_type unique(); + template + constexpr size_type unique(BinaryPredicate binary_pred); + + constexpr void merge(list& x); + constexpr void merge(list&& x); + template constexpr void merge(list& x, Compare comp); + template constexpr void merge(list&& x, Compare comp); + + constexpr void sort(); + template constexpr void sort(Compare comp); + + constexpr void reverse() noexcept; + }; + + template>> + list(InputIterator, InputIterator, Allocator = Allocator()) + -> list<@\placeholder{iter-value-type}@, Allocator>; + + template>> + list(from_range_t, R&&, Allocator = Allocator()) + -> list, Allocator>; +} +\end{codeblock} + +\pnum +An incomplete type \tcode{T} may be used when instantiating \tcode{list} +if the allocator meets the +allocator completeness requirements\iref{allocator.requirements.completeness}. +\tcode{T} shall be complete before any member of the resulting specialization +of \tcode{list} is referenced. + +\rSec3[list.cons]{Constructors, copy, and assignment} + +\indexlibraryctor{list}% +\begin{itemdecl} +constexpr explicit list(const Allocator&); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{list}, using the specified allocator. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{list}% +\begin{itemdecl} +constexpr explicit list(size_type n, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{list}. + +\pnum +\effects +Constructs a \tcode{list} with +\tcode{n} default-inserted elements using the specified allocator. + +\pnum +\complexity +Linear in +\tcode{n}. +\end{itemdescr} + +\indexlibraryctor{list}% +\begin{itemdecl} +constexpr list(size_type n, const T& value, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{list}. + +\pnum +\effects +Constructs a +\tcode{list} +with +\tcode{n} +copies of +\tcode{value}, +using the specified allocator. + +\pnum +\complexity +Linear in +\tcode{n}. +\end{itemdescr} + +\indexlibraryctor{list}% +\begin{itemdecl} +template + constexpr list(InputIterator first, InputIterator last, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a +\tcode{list} +equal to the range +\range{first}{last}. + +\pnum +\complexity +Linear in +\tcode{distance(first, last)}. +\end{itemdescr} + +\indexlibraryctor{list}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr list(from_range_t, R&& rg, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \tcode{list} object with the elements of the range \tcode{rg}. + +\pnum +\complexity +Linear in \tcode{ranges::distance(rg)}. +\end{itemdescr} + +\rSec3[list.capacity]{Capacity} + +\indexlibrarymember{resize}{list}% +\begin{itemdecl} +constexpr void resize(size_type sz); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{list}. + +\pnum +\effects +If \tcode{size() < sz}, +appends \tcode{sz - size()} default-inserted elements to the +sequence. +If \tcode{sz <= size()}, equivalent to: + +\begin{codeblock} +list::iterator it = begin(); +advance(it, sz); +erase(it, end()); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{resize}{list}% +\begin{itemdecl} +constexpr void resize(size_type sz, const T& c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{list}. + +\pnum +\effects +As if by: +\begin{codeblock} +if (sz > size()) + insert(end(), sz-size(), c); +else if (sz < size()) { + iterator i = begin(); + advance(i, sz); + erase(i, end()); +} +else + ; // do nothing +\end{codeblock} +\end{itemdescr} + +\rSec3[list.modifiers]{Modifiers} + +\indexlibrarymember{insert}{list}% +\begin{itemdecl} +constexpr iterator insert(const_iterator position, const T& x); +constexpr iterator insert(const_iterator position, T&& x); +constexpr iterator insert(const_iterator position, size_type n, const T& x); +template + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); +template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); +constexpr iterator insert(const_iterator position, initializer_list); + +template constexpr reference emplace_front(Args&&... args); +template constexpr reference emplace_back(Args&&... args); +template constexpr iterator emplace(const_iterator position, Args&&... args); +constexpr void push_front(const T& x); +constexpr void push_front(T&& x); +template<@\exposconcept{container-compatible-range}@ R> + constexpr void prepend_range(R&& rg); +constexpr void push_back(const T& x); +constexpr void push_back(T&& x); +template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\complexity +Insertion of a single element into a list takes constant time and +exactly one call to a constructor of +\tcode{T}. Insertion of multiple elements into a list is linear in the +number of elements inserted, and the number of calls to the copy +constructor or move constructor of \tcode{T} is exactly equal +to the number of elements inserted. + +\pnum +\remarks +Does not affect the validity of iterators and references. +If an exception is thrown, there are no effects. +\end{itemdescr} + +\indexlibrarymember{erase}{list}% +\begin{itemdecl} +constexpr iterator erase(const_iterator position); +constexpr iterator erase(const_iterator first, const_iterator last); +constexpr void pop_front(); +constexpr void pop_back(); +constexpr void clear() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Invalidates only the iterators and references to the erased elements. + +\pnum +\throws +Nothing. + +\pnum +\complexity +Erasing a single element is a constant time operation with a single call to the destructor of +\tcode{T}. +Erasing a range in a list is linear time in the +size of the range and the number of calls to the destructor of type +\tcode{T} +is exactly equal to the size of the range. +\end{itemdescr} + +\rSec3[list.ops]{Operations} + +\pnum +Since lists allow fast insertion and erasing from the middle of a list, certain +operations are provided specifically for them. +\begin{footnote} +As specified +in~\ref{allocator.requirements}, the requirements in this Clause apply only to +lists whose allocators compare equal. +\end{footnote} +In this subclause, +arguments for a template parameter +named \tcode{Predicate} or \tcode{BinaryPredicate} +shall meet the corresponding requirements in \ref{algorithms.requirements}. +The semantics of \tcode{i + n} and \tcode{i - n}, +where \tcode{i} is an iterator into the list and \tcode{n} is an integer, +are the same as those of \tcode{next(i, n)} and \tcode{prev(i, n)}, +respectively. +For \tcode{merge} and \tcode{sort}, +the definitions and requirements in \ref{alg.sorting} apply. + +\pnum +\tcode{list} provides three splice operations that destructively move elements from one list to +another. The behavior of splice operations is undefined if \tcode{get_allocator() != +x.get_allocator()}. + +\indexlibrarymember{splice}{list}% +\begin{itemdecl} +constexpr void splice(const_iterator position, list& x); +constexpr void splice(const_iterator position, list&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{addressof(x) != this} is \tcode{true}. + +\pnum +\effects +Inserts the contents of +\tcode{x} +before +\tcode{position} +and +\tcode{x} +becomes empty. +Pointers and references to the moved elements of +\tcode{x} +now refer to those same elements but as members of +\tcode{*this}. +Iterators referring to the moved elements will continue to refer to their +elements, but they now behave as iterators into +\tcode{*this}, +not into +\tcode{x}. + +\pnum +\throws +Nothing. + +\pnum +\complexity +Constant time. +\end{itemdescr} + +\indexlibrarymember{splice}{list}% +\begin{itemdecl} +constexpr void splice(const_iterator position, list& x, const_iterator i); +constexpr void splice(const_iterator position, list&& x, const_iterator i); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{i} is a valid dereferenceable iterator of \tcode{x}. + +\pnum +\effects +Inserts an element pointed to by +\tcode{i} +from list +\tcode{x} +before \tcode{position} and removes the element from +\tcode{x}. +The result is unchanged if +\tcode{position == i} +or +\tcode{position == ++i}. +Pointers and references to +\tcode{*i} +continue to refer to this same element but as a member of +\tcode{*this}. +Iterators +to +\tcode{*i} +(including +\tcode{i} +itself) continue to refer to the same element, but now behave as iterators into +\tcode{*this}, +not into +\tcode{x}. + +\pnum +\throws +Nothing. + +\pnum +\complexity +Constant time. +\end{itemdescr} + +\indexlibrarymember{splice}{list}% +\begin{itemdecl} +constexpr void splice(const_iterator position, list& x, + const_iterator first, const_iterator last); +constexpr void splice(const_iterator position, list&& x, + const_iterator first, const_iterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{first}{last} is a valid range in \tcode{x}. +\tcode{position} is not an iterator in the range \range{first}{last}. + +\pnum +\effects +Inserts elements in the range +\range{first}{last} +before +\tcode{position} +and removes the elements from +\tcode{x}. +Pointers and references to the moved elements of +\tcode{x} +now refer to those same elements but as members of +\tcode{*this}. +Iterators referring to the moved elements will continue to refer to their +elements, but they now behave as iterators into +\tcode{*this}, +not into +\tcode{x}. + +\pnum +\throws +Nothing. + +\pnum +\complexity +Constant time if +\tcode{addressof(x) == this}; +otherwise, linear time. +\end{itemdescr} + +\indexlibrarymember{remove}{list}% +\begin{itemdecl} +constexpr size_type remove(const T& value); +template constexpr size_type remove_if(Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Erases all the elements in the list referred to by a list iterator \tcode{i} for which the +following conditions hold: \tcode{*i == value}, \tcode{pred(*i) != false}. +Invalidates only the iterators and references to the erased elements. + +\pnum +\returns +The number of elements erased. + +\pnum +\throws +Nothing unless an exception is thrown by +\tcode{*i == value} +or +\tcode{pred(*i) != false}. + +\pnum +\complexity +Exactly +\tcode{size()} +applications of the corresponding predicate. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} + +\indexlibrarymember{unique}{list}% +\begin{itemdecl} +constexpr size_type unique(); +template constexpr size_type unique(BinaryPredicate binary_pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{binary_pred} be \tcode{equal_to<>\{\}} for the first overload. + +\pnum +\expects +\tcode{binary_pred} is an equivalence relation. + +\pnum +\effects +Erases all but the first element from every +consecutive group of equivalent elements. +That is, for a nonempty list, erases all elements referred to +by the iterator \tcode{i} in the range \range{begin() + 1}{end()} +for which \tcode{binary_pred(*i, *(i - 1))} is \tcode{true}. +Invalidates only the iterators and references to the erased elements. + +\pnum +\returns +The number of elements erased. + +\pnum +\throws +Nothing unless an exception is thrown by the predicate. + +\pnum +\complexity +If \tcode{empty()} is \tcode{false}, +exactly \tcode{size() - 1} applications of the corresponding predicate, +otherwise no applications of the predicate. +\end{itemdescr} + +\indexlibrarymember{merge}{list}% +\begin{itemdecl} +constexpr void merge(list& x); +constexpr void merge(list&& x); +template constexpr void merge(list& x, Compare comp); +template constexpr void merge(list&& x, Compare comp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{comp} be \tcode{less<>{}} for the first two overloads. + +\pnum +\expects +\tcode{*this} and \tcode{x} are both sorted +with respect to the comparator \tcode{comp}, and +\tcode{get_allocator() == x.get_allocator()} is \tcode{true}. + +\pnum +\effects +If \tcode{addressof(x) == this}, there are no effects. +Otherwise, merges +the two sorted ranges \range{begin()}{end()} and \range{x.begin()}{x.end()}. +The result is a range +that is sorted with respect to the comparator \tcode{comp}. +Pointers and references to the moved elements of \tcode{x} now refer to those same elements +but as members of \tcode{*this}. Iterators referring to the moved elements will continue to +refer to their elements, but they now behave as iterators into \tcode{*this}, not into +\tcode{x}. + +\pnum +\complexity +At most \tcode{size() + x.size() - 1} comparisons +if \tcode{addressof(x) != this}; +otherwise, no comparisons are performed. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +If \tcode{addressof(x) != this}, \tcode{x} is empty after the merge. +No elements are copied by this operation. +If an exception is thrown other than by a comparison, there are no effects. +\end{itemdescr} + +\indexlibrarymember{reverse}{list}% +\begin{itemdecl} +constexpr void reverse() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Reverses the order of the elements in the list. +Does not affect the validity of iterators and references. + +\pnum +\complexity +Linear time. +\end{itemdescr} + +\indexlibrarymember{sort}{list}% +\begin{itemdecl} +void sort(); +template void sort(Compare comp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Sorts the list according to the \tcode{operator<} or a \tcode{Compare} function object. +If an exception is thrown, +the order of the elements in \tcode{*this} is unspecified. +Does not affect the validity of iterators and references. + +\pnum +\complexity +Approximately +$N \log N$ +comparisons, where $N$ is \tcode{size()}. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +\end{itemdescr} + +\rSec3[list.erasure]{Erasure} + +\indexlibrarymember{erase}{list}% +\begin{itemdecl} +template + typename list::size_type + constexpr erase(list& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return erase_if(c, [&](const auto& elem) -> bool { return elem == value; }); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{erase_if}{list}% +\begin{itemdecl} +template + typename list::size_type + constexpr erase_if(list& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return c.remove_if(pred);} +\end{itemdescr} + +\rSec2[vector.syn]{Header \tcode{} synopsis} + +\indexheader{vector}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{vector}, class template \tcode{vector} + template> class vector; + + template + constexpr bool operator==(const vector& x, const vector& y); + template + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const vector& x, const vector& y); + + template + constexpr void swap(vector& x, vector& y) + noexcept(noexcept(x.swap(y))); + + // \ref{vector.erasure}, erasure + template + constexpr typename vector::size_type + erase(vector& c, const U& value); + template + constexpr typename vector::size_type + erase_if(vector& c, Predicate pred); + + namespace pmr { + template + using vector = std::vector>; + } + + // \ref{vector.bool}, specialization of \tcode{vector} for \tcode{bool} + // \ref{vector.bool.pspc}, partial class template specialization \tcode{vector} + template + class vector; + + template + constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; // \expos + + // hash support + template struct hash; + template struct hash>; + + // \ref{vector.bool.fmt}, formatter specialization for \tcode{vector} + template requires @\exposid{is-vector-bool-reference}@ + struct formatter; +} +\end{codeblock} + +\rSec2[vector]{Class template \tcode{vector}} + +\rSec3[vector.overview]{Overview} + +\pnum +\indexlibraryglobal{vector}% +A +\tcode{vector} +is a sequence container that supports +(amortized) constant time insert and erase operations at the end; +insert and erase in the middle take linear time. +Storage management is handled automatically, though hints can be given +to improve efficiency. + +\pnum +A \tcode{vector} meets all of the requirements +of a container\iref{container.reqmts}, +of a reversible container\iref{container.rev.reqmts}, +of an allocator-aware container\iref{container.alloc.reqmts}, +of a sequence container, including most of the optional sequence container +requirements\iref{sequence.reqmts}, +and, for an element type other than \tcode{bool}, +of a contiguous container\iref{container.reqmts}. +The exceptions are the +\tcode{push_front}, \tcode{prepend_range}, \tcode{pop_front}, and \tcode{emplace_front} member functions, which are not +provided. Descriptions are provided here only for operations on \tcode{vector} +that are not described in one of these tables or for operations where there is +additional semantic information. + +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + +\begin{codeblock} +namespace std { + template> + class vector { + public: + // types + using value_type = T; + using allocator_type = Allocator; + using pointer = 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} + using difference_type = @\impdefx{type of \tcode{vector::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{vector::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{vector::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // \ref{vector.cons}, construct/copy/destroy + constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { } + constexpr explicit vector(const Allocator&) noexcept; + constexpr explicit vector(size_type n, const Allocator& = Allocator()); + constexpr vector(size_type n, const T& value, const Allocator& = Allocator()); + template + constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr vector(const vector& x); + constexpr vector(vector&&) noexcept; + constexpr vector(const vector&, const type_identity_t&); + constexpr vector(vector&&, const type_identity_t&); + constexpr vector(initializer_list, const Allocator& = Allocator()); + constexpr ~vector(); + constexpr vector& operator=(const vector& x); + constexpr vector& operator=(vector&& x) + noexcept(allocator_traits::propagate_on_container_move_assignment::value || + allocator_traits::is_always_equal::value); + constexpr vector& operator=(initializer_list); + template + constexpr void assign(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const T& u); + constexpr void assign(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // \ref{vector.capacity}, capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr size_type capacity() const noexcept; + constexpr void resize(size_type sz); + constexpr void resize(size_type sz, const T& c); + constexpr void reserve(size_type n); + constexpr void shrink_to_fit(); + + // element access + constexpr reference operator[](size_type n); + constexpr const_reference operator[](size_type n) const; + constexpr reference at(size_type n); + constexpr const_reference at(size_type n) const; + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; + + // \ref{vector.data}, data access + constexpr T* data() noexcept; + constexpr const T* data() const noexcept; + + // \ref{vector.modifiers}, modifiers + template constexpr reference emplace_back(Args&&... args); + constexpr void push_back(const T& x); + constexpr void push_back(T&& x); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); + constexpr void pop_back(); + + template constexpr iterator emplace(const_iterator position, Args&&... args); + constexpr iterator insert(const_iterator position, const T& x); + constexpr iterator insert(const_iterator position, T&& x); + constexpr iterator insert(const_iterator position, size_type n, const T& x); + template + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); + constexpr iterator insert(const_iterator position, initializer_list il); + constexpr iterator erase(const_iterator position); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(vector&) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); + constexpr void clear() noexcept; + }; + + template>> + vector(InputIterator, InputIterator, Allocator = Allocator()) + -> vector<@\placeholder{iter-value-type}@, Allocator>; + + template>> + vector(from_range_t, R&&, Allocator = Allocator()) + -> vector, Allocator>; +} +\end{codeblock}% +\indexlibrarymember{vector}{operator==}% +\indexlibrarymember{vector}{operator<} + +\pnum +An incomplete type \tcode{T} may be used when instantiating \tcode{vector} +if the allocator meets the +allocator completeness requirements\iref{allocator.requirements.completeness}. +\tcode{T} shall be complete before any member of the resulting specialization +of \tcode{vector} is referenced. + +\rSec3[vector.cons]{Constructors} + +\indexlibraryctor{vector} +\begin{itemdecl} +constexpr explicit vector(const Allocator&) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{vector}, using the +specified allocator. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{vector} +\begin{itemdecl} +constexpr explicit vector(size_type n, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{vector}. + +\pnum +\effects +Constructs a \tcode{vector} with \tcode{n} +default-inserted elements using the specified allocator. + +\pnum +\complexity +Linear in \tcode{n}. +\end{itemdescr} + +\indexlibraryctor{vector} +\begin{itemdecl} +constexpr vector(size_type n, const T& value, + const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is +\oldconcept{CopyInsertable} into \tcode{vector}. + +\pnum +\effects +Constructs a \tcode{vector} with \tcode{n} +copies of \tcode{value}, using the specified allocator. + +\pnum +\complexity +Linear in \tcode{n}. +\end{itemdescr} + +\indexlibraryctor{vector} +\begin{itemdecl} +template + constexpr vector(InputIterator first, InputIterator last, + const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \tcode{vector} equal to the +range \range{first}{last}, using the specified allocator. + +\pnum +\complexity +Makes only $N$ +calls to the copy constructor of +\tcode{T} +(where $N$ +is the distance between +\tcode{first} +and +\tcode{last}) +and no reallocations if +\tcode{InputIterator} meets the \oldconcept{ForwardIterator} requirements. +It makes order +$N$ +calls to the copy constructor of +\tcode{T} +and order +$\log N$ +reallocations if they are just input iterators. +\end{itemdescr} + +\indexlibraryctor{vector}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs a \tcode{vector} object with the elements of the range \tcode{rg}, +using the specified allocator. + +\pnum +\complexity +Initializes exactly $N$ elements +from the results of dereferencing successive iterators of \tcode{rg}, +where $N$ is \tcode{ranges::distance(rg)}. + +\pnum +Performs no reallocations if: +\begin{itemize} +\item +\tcode{R} models \tcode{ranges::\libconcept{approximately_sized_range}}, and +\tcode{ranges::distance(rg) <= ranges::re\-serve_hint(rg)} is \tcode{true}, or +\item +\tcode{R} models \tcode{ranges::\libconcept{forward_range}} and +\tcode{R} does not model \tcode{ranges::\libconcept{approximately_sized_range}}. +\end{itemize} +Otherwise, performs order $\log N$ reallocations and +order $N$ calls to the copy or move constructor of \tcode{T}. +\end{itemdescr} + +\rSec3[vector.capacity]{Capacity} + +\indexlibrarymember{capacity}{vector}% +\begin{itemdecl} +constexpr size_type capacity() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The total number of elements that the vector can hold +without requiring reallocation. + +\pnum +\complexity +Constant time. +\end{itemdescr} + +\indexlibrarymember{reserve}{vector}% +\begin{itemdecl} +constexpr void reserve(size_type n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{vector}. + +\pnum +\effects +A directive that informs a +\tcode{vector} +of a planned change in size, so that it can manage the storage allocation accordingly. +After +\tcode{reserve()}, +\tcode{capacity()} +is greater or equal to the argument of +\tcode{reserve} +if reallocation happens; and equal to the previous value of +\tcode{capacity()} +otherwise. +Reallocation happens at this point if and only if the current capacity is less than the +argument of +\tcode{reserve()}. If an exception is thrown +other than by the move constructor of a non-\oldconcept{CopyInsertable} type, +there are no effects. + +\pnum +\throws +\tcode{length_error} if \tcode{n > +max_size()}. +\begin{footnote} +\tcode{reserve()} uses \tcode{Allocator::allocate()} which +can throw an appropriate exception. +\end{footnote} + +\pnum +\complexity +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} +If no reallocation happens, they remain valid. +\end{note} +No reallocation shall take place during insertions that happen +after a call to \tcode{reserve()} +until an insertion would make the size of the vector +greater than the value of \tcode{capacity()}. +\end{itemdescr} + +\indexlibrarymember{shrink_to_fit}{vector}% +\begin{itemdecl} +constexpr void shrink_to_fit(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{MoveInsertable} into \tcode{vector}. + +\pnum +\effects +\tcode{shrink_to_fit} is a non-binding request to reduce +\tcode{capacity()} to \tcode{size()}. +\begin{note} +The request is non-binding to allow latitude for +implementation-specific optimizations. +\end{note} +It does not increase \tcode{capacity()}, but may reduce \tcode{capacity()} +by causing reallocation. +If an exception is thrown other than by the move constructor +of a non-\oldconcept{CopyInsertable} \tcode{T}, there are no effects. + +\pnum +\complexity +If reallocation happens, +linear in the size of the sequence. + +\pnum +\remarks +Reallocation invalidates all the references, pointers, and iterators +referring to the elements in the sequence as well as the past-the-end iterator. +\begin{note} +If no reallocation happens, they remain valid. +\end{note} +\end{itemdescr} + +\indexlibrarymember{swap}{vector}% +\begin{itemdecl} +constexpr void swap(vector& x) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Exchanges the contents and +\tcode{capacity()} +of +\tcode{*this} +with that of \tcode{x}. + +\pnum +\complexity +Constant time. +\end{itemdescr} + +\indexlibrarymember{resize}{vector}% +\begin{itemdecl} +constexpr void resize(size_type sz); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is +\oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{vector}. + +\pnum +\effects +If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements +from the sequence. Otherwise, +appends \tcode{sz - size()} default-inserted elements to the sequence. + +\pnum +\remarks +If an exception is thrown other than by the move constructor of a non-\oldconcept{CopyInsertable} +\tcode{T}, there are no effects. +\end{itemdescr} + +\indexlibrarymember{resize}{vector}% +\begin{itemdecl} +constexpr void resize(size_type sz, const T& c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is +\oldconcept{CopyInsertable} into \tcode{vector}. + +\pnum +\effects +If \tcode{sz < size()}, erases the last \tcode{size() - sz} elements +from the sequence. Otherwise, +appends \tcode{sz - size()} copies of \tcode{c} to the sequence. + +\pnum +\remarks +If an exception is thrown, there are no effects. +\end{itemdescr} + +\rSec3[vector.data]{Data} + +\indexlibrarymember{data}{vector}% +\begin{itemdecl} +constexpr T* data() noexcept; +constexpr const T* data() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A pointer such that \range{data()}{data() + size()} is a valid range. For a +non-empty vector, \tcode{data() == addressof(front())} is \keyword{true}. + +\pnum +\complexity +Constant time. +\end{itemdescr} + +\rSec3[vector.modifiers]{Modifiers} + +\indexlibrarymember{insert}{vector}% +\begin{itemdecl} +constexpr iterator insert(const_iterator position, const T& x); +constexpr iterator insert(const_iterator position, T&& x); +constexpr iterator insert(const_iterator position, size_type n, const T& x); +template + constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); +template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); +constexpr iterator insert(const_iterator position, initializer_list); + +template constexpr reference emplace_back(Args&&... args); +template constexpr iterator emplace(const_iterator position, Args&&... args); +constexpr void push_back(const T& x); +constexpr void push_back(T&& x); +template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\complexity +If reallocation happens, +linear in the number of elements of the resulting vector; +otherwise, +linear in the number of elements inserted plus the distance +to the end of the vector. + +\pnum +\remarks +Causes reallocation if the new size is greater than the old capacity. +Reallocation invalidates all the references, pointers, and iterators +referring to the elements in the sequence, as well as the past-the-end iterator. +If no reallocation happens, then +references, pointers, and iterators +before the insertion point remain valid +but those at or after the insertion point, +including the past-the-end iterator, +are invalidated. +If an exception is thrown other than by +the copy constructor, move constructor, +assignment operator, or move assignment operator of +\tcode{T} or by any \tcode{InputIterator} operation, +there are no effects. +If an exception is thrown while inserting a single element at the end and +\tcode{T} is \oldconcept{CopyInsertable} or \tcode{is_nothrow_move_constructible_v} +is \tcode{true}, there are no effects. +Otherwise, if an exception is thrown by the move constructor of a non-\oldconcept{CopyInsertable} +\tcode{T}, the effects are unspecified. + +\pnum +For the declarations taking a range \tcode{R}, +performs at most one reallocation if: +\begin{itemize} +\item +\tcode{R} models \tcode{ranges::\libconcept{approximately_sized_range}} and +\tcode{ranges::distance(rg) <= ranges::re\-serve_hint(rg)} is \tcode{true}, or +\item +\tcode{R} models \tcode{ranges::\libconcept{forward_range}} and +\tcode{R} does not model \tcode{ranges::\libconcept{approximately_sized_range}}. +\end{itemize} +For the declarations taking a pair of \tcode{InputIterator}, +performs at most one reallocation if +\tcode{InputItera\-tor} meets the \oldconcept{ForwardIterator} requirements. +\end{itemdescr} + +\indexlibrarymember{erase}{vector}% +\begin{itemdecl} +constexpr iterator erase(const_iterator position); +constexpr iterator erase(const_iterator first, const_iterator last); +constexpr void pop_back(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Invalidates iterators and references at or after the point of the erase. + +\pnum +\throws +Nothing unless an exception is thrown by the +assignment operator or move assignment operator of +\tcode{T}. + +\pnum +\complexity +The destructor of \tcode{T} is called the number of times equal to the +number of the elements erased, but the assignment operator +of \tcode{T} is called the number of times equal to the number of +elements in the vector after the erased elements. +\end{itemdescr} + +\rSec3[vector.erasure]{Erasure} + +\indexlibrarymember{erase}{vector}% +\begin{itemdecl} +template + constexpr typename vector::size_type + erase(vector& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto it = remove(c.begin(), c.end(), value); +auto r = distance(it, c.end()); +c.erase(it, c.end()); +return r; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{erase_if}{vector}% +\begin{itemdecl} +template + constexpr typename vector::size_type + erase_if(vector& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto it = remove_if(c.begin(), c.end(), pred); +auto r = distance(it, c.end()); +c.erase(it, c.end()); +return r; +\end{codeblock} +\end{itemdescr} + +\rSec2[vector.bool]{Specialization of \tcode{vector} for \tcode{bool}} + +\rSec3[vector.bool.pspc]{Partial class template specialization \tcode{vector}} + +\pnum +\indexlibraryglobal{vector}% +To optimize space allocation, a partial specialization of \tcode{vector} for +\tcode{bool} elements is provided: +\begin{codeblock} +namespace std { + template + class vector { + public: + // types + using value_type = bool; + using allocator_type = Allocator; + using pointer = @\impdefx{type of \tcode{vector::pointer}}@; + using const_pointer = @\impdefx{type of \tcode{vector::const_pointer}}@; + using const_reference = bool; + using size_type = @\impdefx{type of \tcode{vector::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{vector::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{vector::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{vector::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // bit reference + class @\libmember{reference}{vector}@ { + public: + constexpr reference(const reference& x) noexcept; + constexpr ~reference(); + 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 + constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { } + constexpr explicit vector(const Allocator&) noexcept; + constexpr explicit vector(size_type n, const Allocator& = Allocator()); + constexpr vector(size_type n, const bool& value, const Allocator& = Allocator()); + template + constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr vector(const vector& x); + constexpr vector(vector&& x) noexcept; + constexpr vector(const vector&, const type_identity_t&); + constexpr vector(vector&&, const type_identity_t&); + constexpr vector(initializer_list, const Allocator& = Allocator()); + constexpr ~vector(); + constexpr vector& operator=(const vector& x); + constexpr vector& operator=(vector&& x) + noexcept(allocator_traits::propagate_on_container_move_assignment::value || + allocator_traits::is_always_equal::value); + constexpr vector& operator=(initializer_list); + template + constexpr void assign(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const bool& t); + constexpr void assign(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr size_type capacity() const noexcept; + constexpr void resize(size_type sz, bool c = false); + constexpr void reserve(size_type n); + constexpr void shrink_to_fit(); + + // element access + constexpr reference operator[](size_type n); + constexpr const_reference operator[](size_type n) const; + constexpr reference at(size_type n); + constexpr const_reference at(size_type n) const; + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; + + // modifiers + template constexpr reference emplace_back(Args&&... args); + constexpr void push_back(const bool& x); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); + constexpr void pop_back(); + template constexpr iterator emplace(const_iterator position, Args&&... args); + constexpr iterator insert(const_iterator position, const bool& x); + constexpr iterator insert(const_iterator position, size_type n, const bool& x); + template + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); + constexpr iterator insert(const_iterator position, initializer_list il); + + constexpr iterator erase(const_iterator position); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(vector&) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); + constexpr void flip() noexcept; // flips all bits + constexpr void clear() noexcept; + }; +} +\end{codeblock}% + +\pnum +Unless described below, all operations have the same requirements and +semantics as the \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 +\returns +\tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator bool}{vector::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{flip}{vector::reference}% +\begin{itemdecl} +constexpr void reference::flip() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{*this = !*this}. +\end{itemdescr} + +\indexlibrarymember{swap}{vector::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} + +\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}{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} +template struct hash>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The specialization is enabled\iref{unord.hash}. +\end{itemdescr} + +\indexlibrary{is-vector-bool-reference@\exposid{is-vector-bool-reference}}% +\begin{itemdecl} +template + constexpr bool @\exposid{is-vector-bool-reference}@ = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The expression +\tcode{\exposid{is-vector-bool-reference}} is \tcode{true} +if \tcode{T} denotes the type \tcode{vector::\linebreak{}reference} +for some type \tcode{Alloc} and +\tcode{vector} is not a program-defined specialization. +\end{itemdescr} + +\rSec3[vector.bool.fmt]{Formatter specialization for \tcode{vector}} + +\indexlibraryglobal{formatter}% +\begin{codeblock} +namespace std { + template + requires @\exposid{is-vector-bool-reference}@ + struct formatter { + private: + formatter @\exposid{underlying_}@; // \expos + + public: + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + constexpr typename FormatContext::iterator + format(const T& ref, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\indexlibrarymember{parse}{formatter}% +\begin{itemdecl} +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} +\end{itemdescr} + +\indexlibrarymember{format}{formatter}% +\begin{itemdecl} +template + constexpr typename FormatContext::iterator + format(const T& ref, FormatContext& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Equivalent to: \tcode{return \exposid{underlying_}.format(ref, ctx);} +\end{itemdescr} + +\rSec2[inplace.vector.syn]{Header \tcode{} synopsis} + +\indexheader{inplace_vector}% +\begin{codeblock} +// mostly freestanding +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{inplace.vector}, class template \tcode{inplace_vector} + template class inplace_vector; // partially freestanding + + // \ref{inplace.vector.erasure}, erasure + template + constexpr typename inplace_vector::size_type + erase(inplace_vector& c, const U& value); + template + constexpr typename inplace_vector::size_type + erase_if(inplace_vector& c, Predicate pred); +} +\end{codeblock} + +\rSec2[inplace.vector]{Class template \tcode{inplace_vector}} + +\rSec3[inplace.vector.overview]{Overview} + +\pnum +\indexlibraryglobal{inplace_vector}% +An \tcode{inplace_vector} is a contiguous container. +Its capacity is fixed and +its elements are stored within the \tcode{inplace_vector} object itself. + +\pnum +An \tcode{inplace_vector} meets all of the requirements +of a container\iref{container.reqmts}, +of a reversible container\iref{container.rev.reqmts}, +of a contiguous container, and +of a sequence container, +including most of the optional sequence container requirements\iref{sequence.reqmts}. +The exceptions are the +\tcode{push_front}, +\tcode{prepend_range}, +\tcode{pop_front}, and +\tcode{emplace_front} +member functions, which are not provided. +Descriptions are provided here only +for operations on \tcode{inplace_vector} that +are not described in one of these tables or +for operations where there is additional semantic information. + +\pnum +For any \tcode{N}, +\tcode{inplace_vector::iterator} and +\tcode{inplace_vector::const_iterator} +meet the constexpr iterator requirements. + +\pnum +Any member function of \tcode{inplace_vector} that +would cause the size to exceed \tcode{N} +throws an exception of type \tcode{bad_alloc}. + +\pnum +Let \tcode{IV} denote a specialization of \tcode{inplace_vector}. +If \tcode{N} is zero, then +\tcode{IV} is trivially copyable and empty, and +\tcode{std::is_trivially_default_constructible_v} is \tcode{true}. +Otherwise: +\begin{itemize} +\item +If \tcode{is_trivially_copy_constructible_v} is \tcode{true}, then +\tcode{IV} has a trivial copy constructor. +\item +If \tcode{is_trivially_move_constructible_v} is \tcode{true}, then +\tcode{IV} has a trivial move constructor. +\item +If \tcode{is_trivially_destructible_v} is \tcode{true}, then: + \begin{itemize} + \item + \tcode{IV} has a trivial destructor. + \item + If +\begin{codeblock} + is_trivially_copy_constructible_v && is_trivially_copy_assignable_v +\end{codeblock} + is \tcode{true}, then + \tcode{IV} has a trivial copy assignment operator. + \item + If +\begin{codeblock} + is_trivially_move_constructible_v && is_trivially_move_assignable_v +\end{codeblock} + is \tcode{true}, then + \tcode{IV} has a trivial move assignment operator. + \end{itemize} +\end{itemize} + +\begin{codeblock} +namespace std { + template + class inplace_vector { + public: + // types: + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator = @\impdefx{type of \tcode{inplace_vector::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{inplace_vector::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // \ref{inplace.vector.cons}, construct/copy/destroy + constexpr inplace_vector() noexcept; + constexpr explicit inplace_vector(size_type n); // freestanding-deleted + constexpr inplace_vector(size_type n, const T& value); // freestanding-deleted + template + constexpr inplace_vector(InputIterator first, InputIterator last); // freestanding-deleted + template<@\exposconcept{container-compatible-range}@ R> + constexpr inplace_vector(from_range_t, R&& rg); // freestanding-deleted + constexpr inplace_vector(const inplace_vector&); + constexpr inplace_vector(inplace_vector&&) + noexcept(N == 0 || is_nothrow_move_constructible_v); + constexpr inplace_vector(initializer_list il); // freestanding-deleted + constexpr ~inplace_vector(); + constexpr inplace_vector& operator=(const inplace_vector& other); + constexpr inplace_vector& operator=(inplace_vector&& other) + noexcept(N == 0 || (is_nothrow_move_assignable_v && + is_nothrow_move_constructible_v)); + constexpr inplace_vector& operator=(initializer_list); // freestanding-deleted + template + constexpr void assign(InputIterator first, InputIterator last); // freestanding-deleted + template<@\exposconcept{container-compatible-range}@ R> + constexpr void assign_range(R&& rg); // freestanding-deleted + constexpr void assign(size_type n, const T& u); // freestanding-deleted + constexpr void assign(initializer_list il); // freestanding-deleted + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // \ref{inplace.vector.capacity}, capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + static constexpr size_type max_size() noexcept; + static constexpr size_type capacity() noexcept; + constexpr void resize(size_type sz); // freestanding-deleted + constexpr void resize(size_type sz, const T& c); // freestanding-deleted + static constexpr void reserve(size_type n); // freestanding-deleted + static constexpr void shrink_to_fit() noexcept; + + // element access + constexpr reference operator[](size_type n); + constexpr const_reference operator[](size_type n) const; + constexpr reference at(size_type n); // freestanding-deleted + constexpr const_reference at(size_type n) const; // freestanding-deleted + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; + + // \ref{inplace.vector.data}, data access + constexpr T* data() noexcept; + constexpr const T* data() const noexcept; + + // \ref{inplace.vector.modifiers}, modifiers + template + constexpr reference emplace_back(Args&&... args); // freestanding-deleted + constexpr reference push_back(const T& x); // freestanding-deleted + constexpr reference push_back(T&& x); // freestanding-deleted + template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); // freestanding-deleted + constexpr void pop_back(); + + template + 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); + constexpr reference unchecked_push_back(const T& x); + constexpr reference unchecked_push_back(T&& x); + + template + constexpr iterator emplace(const_iterator position, Args&&... args); // freestanding-deleted + constexpr iterator insert(const_iterator position, const T& x); // freestanding-deleted + constexpr iterator insert(const_iterator position, T&& x); // freestanding-deleted + constexpr iterator insert(const_iterator position, size_type n, // freestanding-deleted + const T& x); + template + constexpr iterator insert(const_iterator position, // freestanding-deleted + InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); // freestanding-deleted + constexpr iterator insert(const_iterator position, // freestanding-deleted + initializer_list il); + constexpr iterator erase(const_iterator position); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(inplace_vector& x) + noexcept(N == 0 || (is_nothrow_swappable_v && + is_nothrow_move_constructible_v)); + constexpr void clear() noexcept; + + friend constexpr bool operator==(const inplace_vector& x, + const 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} + +\indexlibraryctor{inplace_vector} +\begin{itemdecl} +constexpr explicit inplace_vector(size_type n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{inplace_vector}. + +\pnum +\effects +Constructs an \tcode{inplace_vector} with \tcode{n} default-inserted elements. + +\pnum +\complexity +Linear in \tcode{n}. +\end{itemdescr} + +\indexlibraryctor{inplace_vector} +\begin{itemdecl} +constexpr inplace_vector(size_type n, const T& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{inplace_vector}. + +\pnum +\effects +Constructs an \tcode{inplace_vector} with \tcode{n} copies of \tcode{value}. + +\pnum +\complexity +Linear in \tcode{n}. +\end{itemdescr} + +\indexlibraryctor{inplace_vector} +\begin{itemdecl} +template + constexpr inplace_vector(InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an \tcode{inplace_vector} equal to the range \range{first}{last}. + +\pnum +\complexity +Linear in \tcode{distance(first, last)}. +\end{itemdescr} + +\indexlibraryctor{inplace_vector} +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr inplace_vector(from_range_t, R&& rg); +\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 +the elements of the range \tcode{rg}. + +\pnum +\complexity +Linear in \tcode{ranges::distance(rg)}. +\end{itemdescr} + +\rSec3[inplace.vector.capacity]{Capacity} + +\indexlibrarymember{capacity}{inplace_vector}% +\indexlibrarymember{max_size}{inplace_vector}% +\begin{itemdecl} +static constexpr size_type capacity() noexcept; +static constexpr size_type max_size() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{N}. +\end{itemdescr} + +\indexlibrarymember{resize}{inplace_vector}% +\begin{itemdecl} +constexpr void resize(size_type sz); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{DefaultInsertable} into \tcode{inplace_vector}. + +\pnum +\effects +%FIXME: Should "is \tcode{true}" be appended here? +If \tcode{sz < size()}, +erases the last \tcode{size() - sz} elements from the sequence. +Otherwise, +appends \tcode{sz - size()} default-inserted elements to the sequence. + +\pnum +\remarks +If an exception is thrown, there are no effects on \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{resize}{inplace_vector}% +\begin{itemdecl} +constexpr void resize(size_type sz, const T& c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{T} is \oldconcept{CopyInsertable} into \tcode{inplace_vector}. + +\pnum +\effects +%FIXME: Should "is \tcode{true}" be appended here? +If \tcode{sz < size()}, +erases the last \tcode{size() - sz} elements from the sequence. +Otherwise, +appends \tcode{sz - size()} copies of \tcode{c} to the sequence. + +\pnum +\remarks +If an exception is thrown, there are no effects 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}% +\begin{itemdecl} +constexpr T* data() noexcept; +constexpr const T* data() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A pointer such that \range{data()}{data() + size()} is a valid range. +For a non-empty \tcode{inplace_vector}, +\tcode{data() == addressof(front())} is \tcode{true}. + +\pnum +\complexity +Constant time. +\end{itemdescr} + +\rSec3[inplace.vector.modifiers]{Modifiers} + +\indexlibrarymember{insert}{inplace_vector}% +\indexlibrarymember{insert_range}{inplace_vector}% +\indexlibrarymember{emplace}{inplace_vector}% +\indexlibrarymember{append_range}{inplace_vector}% +\begin{itemdecl} +constexpr iterator insert(const_iterator position, const T& x); +constexpr iterator insert(const_iterator position, T&& x); +constexpr iterator insert(const_iterator position, size_type n, const T& x); +template + constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); +template<@\exposconcept{container-compatible-range}@ R> + constexpr iterator insert_range(const_iterator position, R&& rg); +constexpr iterator insert(const_iterator position, initializer_list il); + +template + constexpr iterator emplace(const_iterator position, Args&&... args); +template<@\exposconcept{container-compatible-range}@ R> + constexpr void append_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $n$ be the value of \tcode{size()} before this call for +the \tcode{append_range} overload, and +\tcode{distance(begin, position)} otherwise. + +\pnum +\complexity +Linear in the number of elements inserted plus +the distance to the end of the vector. + +\pnum +\remarks +If an exception is thrown other than by the +copy constructor, +move constructor, +assignment operator, or +move assignment operator +of \tcode{T} or by +any \tcode{InputIterator} operation, +there are no effects. +Otherwise, +if an exception is thrown, then +$\tcode{size()} \ge n$ and +elements in the range \tcode{begin() + \range{0}{$n$}} are not modified. +\end{itemdescr} + +\indexlibrarymember{push_back}{inplace_vector}% +\indexlibrarymember{emplace_back}{inplace_vector}% +\begin{itemdecl} +constexpr reference push_back(const T& x); +constexpr reference push_back(T&& x); +template + constexpr reference emplace_back(Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{back()}. + +\pnum +\throws +\tcode{bad_alloc} or +any exception thrown by the initialization of the inserted element. + +\pnum +\complexity +Constant. + +\pnum +\remarks +If an exception is thrown, there are no effects on \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{try_emplace_back}{inplace_vector}% +\indexlibrarymember{try_push_back}{inplace_vector}% +\begin{itemdecl} +template + 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} +\pnum +Let \tcode{vals} denote a pack: +\begin{itemize} +\item \tcode{std::forward(args)...} for the first overload, +\item \tcode{x} for the second overload, +\item \tcode{std::move(x)} for the third overload. +\end{itemize} + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} +into \tcode{inplace_vector} from \tcode{vals...}. + +\pnum +\effects +If \tcode{size() < capacity()} is \tcode{true}, +appends an object of type \tcode{T} +direct-non-list-initialized with \tcode{vals...}. +Otherwise, there are no effects. + +\pnum +\returns +\keyword{nullopt} if \tcode{size() == capacity()} is \tcode{true}, +otherwise \tcode{optional(in_place, back())}. + +\pnum +\throws +Nothing unless an exception is thrown by the initialization of the inserted element. + +\pnum +\complexity +Constant. + +\pnum +\remarks +If an exception is thrown, there are no effects on \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{unchecked_emplace_back}{inplace_vector}% +\begin{itemdecl} +template + constexpr reference unchecked_emplace_back(Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{size() < capacity()} is \tcode{true}. + +\pnum +\effects +Equivalent to: +\tcode{return *try_emplace_back(std::forward(args)...);} +\end{itemdescr} + +\indexlibrarymember{unchecked_push_back}{inplace_vector}% +\begin{itemdecl} +constexpr reference unchecked_push_back(const T& x); +constexpr reference unchecked_push_back(T&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{size() < capacity()} is \tcode{true}. + +\pnum +\effects +Equivalent to: +\tcode{return *try_push_back(std::forward(x));} +\end{itemdescr} + +\indexlibrarymember{erase}{inplace_vector}% +\indexlibrarymember{pop_back}{inplace_vector}% +\begin{itemdecl} +constexpr iterator erase(const_iterator position); +constexpr iterator erase(const_iterator first, const_iterator last); +constexpr void pop_back(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Invalidates iterators and references at or after the point of the erase. + +\pnum +\throws +Nothing unless an exception is thrown by +the assignment operator or move assignment operator of \tcode{T}. + +\pnum +\complexity +The destructor of \tcode{T} is called the number of times +equal to the number of the elements erased, but +the assignment operator of \tcode{T} is called the number of times +equal to the number of elements 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}% +\begin{itemdecl} +template + constexpr size_t erase(inplace_vector& c, const U& value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto it = remove(c.begin(), c.end(), value); +auto r = distance(it, c.end()); +c.erase(it, c.end()); +return r; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{erase_if}{inplace_vector}% +\begin{itemdecl} +template + constexpr size_t erase_if(inplace_vector& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto it = remove_if(c.begin(), c.end(), pred); +auto r = distance(it, c.end()); +c.erase(it, c.end()); +return r; +\end{codeblock} +\end{itemdescr} + +\rSec1[associative]{Associative containers} + +\rSec2[associative.general]{General} + +\pnum +The header \libheaderrefx{map}{associative.map.syn} defines the class templates +\tcode{map} and \tcode{multimap}; +the header \libheaderrefx{set}{associative.set.syn} defines the class templates +\tcode{set} and \tcode{multiset}. + +\pnum +The following exposition-only alias templates may appear in deduction guides for associative containers: +\begin{codeblock} +template + using @\placeholder{iter-value-type}@ = iterator_traits::value_type; // \expos +template + using @\placeholder{iter-key-type}@ = remove_cvref_t< + tuple_element_t<0, @\exposid{iter-value-type}@>>; // \expos +template + 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< + const @\exposid{iter-key-type}@, + @\exposid{iter-mapped-type}@>; // \expos +template + using @\exposid{range-key-type}@ = + remove_cvref_t>>; // \expos +template + using @\exposid{range-mapped-type}@ = + remove_cvref_t>>; // \expos +template + using @\exposid{range-to-alloc-type}@ = + pair, + @\exposid{range-mapped-type}@>; // \expos +\end{codeblock} + +\rSec2[associative.map.syn]{Header \tcode{} synopsis} + +\indexheader{map}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{map}, class template \tcode{map} + template, + class Allocator = allocator>> + class map; + + template + constexpr bool operator==(const map& x, + const map& y); + template + constexpr @\exposid{synth-three-way-result}@> + operator<=>(const map& x, + const map& y); + + template + constexpr void swap(map& x, + map& y) + noexcept(noexcept(x.swap(y))); + + // \ref{map.erasure}, erasure for \tcode{map} + template + constexpr typename map::size_type + erase_if(map& c, Predicate pred); + + // \ref{multimap}, class template \tcode{multimap} + template, + class Allocator = allocator>> + class multimap; + + template + constexpr bool operator==(const multimap& x, + const multimap& y); + template + constexpr @\exposid{synth-three-way-result}@> + operator<=>(const multimap& x, + const multimap& y); + + template + constexpr void swap(multimap& x, + multimap& y) + noexcept(noexcept(x.swap(y))); + + // \ref{multimap.erasure}, erasure for \tcode{multimap} + template + constexpr typename multimap::size_type + erase_if(multimap& c, Predicate pred); + + namespace pmr { + template> + using map = std::map>>; + + template> + using multimap = std::multimap>>; + } +} +\end{codeblock} + +\rSec2[map]{Class template \tcode{map}} + +\rSec3[map.overview]{Overview} + +\indexlibraryglobal{map}% +\pnum +A \tcode{map} is an associative container that +supports unique keys (i.e., contains at most one of each key value) and +provides for fast retrieval of values of another type \tcode{T} based +on the keys. The \tcode{map} class supports bidirectional iterators. + +\pnum +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 associative container\iref{associative.reqmts}. +A +\tcode{map} +also provides most operations described in~\ref{associative.reqmts} +for unique keys. +This means that a +\tcode{map} +supports the +\tcode{a_uniq} +operations in~\ref{associative.reqmts} +but not the +\tcode{a_eq} +operations. +For a +\tcode{map} +the +\tcode{key_type} +is +\tcode{Key} +and the +\tcode{value_type} +is +\tcode{pair}. +Descriptions are provided here only for operations on +\tcode{map} +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} +namespace std { + template, + class Allocator = allocator>> + class map { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = pair; + using key_compare = Compare; + 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 = @\impdefx{type of \tcode{map::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{map::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{map::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{map::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using node_type = @\unspec@; + using insert_return_type = @\placeholdernc{insert-return-type}@; + + class value_compare { + protected: + Compare comp; + constexpr value_compare(Compare c) : comp(c) {} + + public: + constexpr bool operator()(const value_type& x, const value_type& y) const { + return comp(x.first, y.first); + } + }; + + // \ref{map.cons}, construct/copy/destroy + constexpr map() : map(Compare()) { } + constexpr explicit map(const Compare& comp, const Allocator& = Allocator()); + template + constexpr map(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + 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 + constexpr map(InputIterator first, InputIterator last, const Allocator& a) + : map(first, last, Compare(), a) { } + template<@\exposconcept{container-compatible-range}@ R> + constexpr map(from_range_t, R&& rg, const Allocator& a) + : map(from_range, std::forward(rg), Compare(), a) { } + constexpr map(initializer_list il, const Allocator& a) + : map(il, Compare(), a) { } + 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); + constexpr map& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // \ref{map.access}, element access + constexpr mapped_type& operator[](const key_type& x); + constexpr mapped_type& operator[](key_type&& x); + template constexpr mapped_type& operator[](K&& x); + constexpr mapped_type& at(const key_type& x); + constexpr const mapped_type& at(const key_type& x) const; + template constexpr mapped_type& at(const K& x); + template constexpr const mapped_type& at(const K& x) const; + + // \ref{map.modifiers}, modifiers + template 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 + constexpr iterator insert(const_iterator position, P&&); + template + constexpr void insert(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + 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 insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); + + template + constexpr pair try_emplace(const key_type& k, Args&&... args); + template + constexpr pair try_emplace(key_type&& k, Args&&... args); + template + constexpr pair try_emplace(K&& k, Args&&... args); + template + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + template + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + template + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + template + constexpr pair insert_or_assign(const key_type& k, M&& obj); + template + constexpr pair insert_or_assign(key_type&& k, M&& obj); + template + constexpr pair insert_or_assign(K&& k, M&& obj); + template + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + template + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + template + 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); + constexpr void clear() noexcept; + + template + constexpr void merge(map& source); + template + constexpr void merge(map&& source); + template + constexpr void merge(multimap& source); + template + constexpr void merge(multimap&& source); + + // observers + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; + + // map operations + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; + + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; + + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; + + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; + + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; + + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; + template + constexpr pair equal_range(const K& x); + template + constexpr pair equal_range(const K& x) const; + }; + + template>, + class Allocator = allocator<@\placeholder{iter-to-alloc-type}@>> + map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator()) + -> map<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, Compare, Allocator>; + + 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>; + + template, + class Allocator = allocator>> + map(initializer_list>, Compare = Compare(), Allocator = Allocator()) + -> map; + + template + map(InputIterator, InputIterator, Allocator) + -> map<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, + less<@\placeholder{iter-key-type}@>, Allocator>; + + template + map(from_range_t, R&&, Allocator) + -> map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, less<@\exposid{range-key-type}@>, Allocator>; + + template + map(initializer_list>, Allocator) -> map, Allocator>; +} +\end{codeblock} + + +\rSec3[map.cons]{Constructors, copy, and assignment}% +\indexlibrarymember{map}{operator==}% +\indexlibrarymember{map}{operator<} + +\indexlibraryctor{map}% +\begin{itemdecl} +constexpr explicit map(const Compare& comp, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty +\tcode{map} +using the specified comparison object and allocator. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{map}% +\begin{itemdecl} +template + constexpr map(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty +\tcode{map} +using the specified comparison object and allocator, +and inserts elements from the range +\range{first}{last}. + +\pnum +\complexity +Linear in $N$ if the range +\range{first}{last} +is already sorted with respect to \tcode{comp} +and otherwise $N \log N$, where $N$ +is \tcode{last - first}. +\end{itemdescr} + +\indexlibraryctor{map}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{map} +using the specified comparison object and allocator, +and inserts elements from the range \tcode{rg}. + +\pnum +\complexity +Linear in $N$ if \tcode{rg} is already sorted with respect to \tcode{comp} and +otherwise $N \log N$, where $N$ is \tcode{ranges::distance(rg)}. +\end{itemdescr} + +\rSec3[map.access]{Element access} + +\indexlibrary{\idxcode{operator[]}!\idxcode{map}}% +\begin{itemdecl} +constexpr mapped_type& operator[](const key_type& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return try_emplace(x).first->second;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator[]}!\idxcode{map}}% +\begin{itemdecl} +constexpr mapped_type& operator[](key_type&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return try_emplace(std::move(x)).first->second;} +\end{itemdescr} + +\indexlibrary{\idxcode{operator[]}!\idxcode{map}}% +\begin{itemdecl} +template constexpr mapped_type& operator[](K&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. + +\pnum +\effects +Equivalent to: \tcode{return try_emplace(std::forward(x)).first->second;} +\end{itemdescr} + +\indexlibrarymember{at}{map}% +\begin{itemdecl} +constexpr mapped_type& at(const key_type& x); +constexpr const mapped_type& at(const key_type& x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A reference to the \tcode{mapped_type} corresponding to \tcode{x} in \tcode{*this}. + +\pnum +\throws +An exception object of type \tcode{out_of_range} if +no such element is present. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexlibrarymember{at}{map}% +\begin{itemdecl} +template constexpr mapped_type& at(const K& x); +template constexpr const mapped_type& at(const K& x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +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 +A reference to \tcode{find(x)->second}. + +\pnum +\throws +An exception object of type \tcode{out_of_range} if +\tcode{find(x) == end()} is \tcode{true}. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\rSec3[map.modifiers]{Modifiers} + +\indexlibrarymember{insert}{map}% +\begin{itemdecl} +template + constexpr pair insert(P&& x); +template + constexpr iterator insert(const_iterator position, P&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +The first form is equivalent to +\tcode{return emplace(std::forward

(x))}. The second form is +equivalent to \tcode{return emplace_hint(position, std::forward

(x))}. +\end{itemdescr} + +\indexlibrarymember{try_emplace}{map}% +\begin{itemdecl} +template + constexpr pair try_emplace(const key_type& k, Args&&... args); +template + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} +from \tcode{piecewise_construct}, \tcode{for\-ward_as_tuple(k)}, +\tcode{forward_as_tuple(std::forward(args)...)}. + +\pnum +\effects +If the map already contains an element +whose key is equivalent to \tcode{k}, +there is no effect. +Otherwise inserts an object of type \tcode{value_type} +constructed with \tcode{piecewise_construct}, \tcode{forward_as_tuple(k)}, +\tcode{forward_as_tuple(std::forward(args)...)}. + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, +respectively. +\end{itemdescr} + +\indexlibrarymember{try_emplace}{map}% +\begin{itemdecl} +template + constexpr pair try_emplace(key_type&& k, Args&&... args); +template + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} +from \tcode{piecewise_construct}, \tcode{for\-ward_as_tuple(std::move(k))}, +\tcode{forward_as_tuple(std::forward(args)...)}. + +\pnum +\effects +If the map already contains an element +whose key is equivalent to \tcode{k}, +there is no effect. +Otherwise inserts an object of type \tcode{value_type} +constructed with \tcode{piecewise_construct}, \tcode{forward_as_tuple(std::move(k))}, +\tcode{forward_as_tuple(std::forward(args)...)}. + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, +respectively. +\end{itemdescr} + +\indexlibrarymember{try_emplace}{map}% +\begin{itemdecl} +template + constexpr pair try_emplace(K&& k, Args&&... args); +template + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. +For the first overload, +\tcode{is_convertible_v} and +\tcode{is_convertible_v} +are both \tcode{false}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} from +\tcode{piecewise_construct, forward_as_tuple(std::forward(k)), +forward_as_tuple(std::forward(args)...)}. + +\pnum +\effects +If the map already contains an element whose key is equivalent to \tcode{k}, +there is no effect. +Otherwise, let \tcode{r} be \tcode{equal_range(k)}. +Constructs an object \tcode{u} of type \tcode{value_type} with +\tcode{piecewise_construct, forward_as_tuple(std::forward(k)), +forward_as_tuple(std::forward(args)...)}.\linebreak +If \tcode{equal_range(u.first) == r} is \tcode{false}, +the behavior is undefined. +Inserts \tcode{u} into \tcode{*this}. + +\pnum +\returns +For the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, respectively. +\end{itemdescr} + +\indexlibrarymember{insert_or_assign}{map}% +\begin{itemdecl} +template + constexpr pair insert_or_assign(const key_type& k, M&& obj); +template + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_assignable_v} is \tcode{true}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} +from \tcode{k}, \tcode{std::forward(obj)}. + +\pnum +\effects +If the map already contains an element \tcode{e} +whose key is equivalent to \tcode{k}, +assigns \tcode{std::for\-ward(obj)} to \tcode{e.second}. +Otherwise inserts an object of type \tcode{value_type} +constructed with \tcode{k}, \tcode{std::forward(obj)}. + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, +respectively. +\end{itemdescr} + +\indexlibrarymember{insert_or_assign}{map}% +\begin{itemdecl} +template + constexpr pair insert_or_assign(key_type&& k, M&& obj); +template + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_assignable_v} is \tcode{true}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} +from \tcode{std::move(k)}, \tcode{std::for\-ward(obj)}. + +\pnum +\effects +If the map already contains an element \tcode{e} +whose key is equivalent to \tcode{k}, +assigns \tcode{std::for\-ward(obj)} to \tcode{e.second}. +Otherwise inserts an object of type \tcode{value_type} +constructed with \tcode{std::\brk{}move(k)}, \tcode{std::forward(obj)}. + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, +respectively. +\end{itemdescr} + +\indexlibrarymember{insert_or_assign}{map}% +\begin{itemdecl} +template + constexpr pair insert_or_assign(K&& k, M&& obj); +template + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. + +\pnum +\mandates +\tcode{is_assignable_v} is \tcode{true}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{map} from +\tcode{std::forward(k), std::\newline forward(obj)}. + +\pnum +\effects +If the map already contains an element \tcode{e} +whose key is equivalent to \tcode{k}, +assigns \tcode{std::forward\newline (obj)} to \tcode{e.second}. +Otherwise, let \tcode{r} be \tcode{equal_range(k)}. +Constructs an object \tcode{u} of type \tcode{value_type} +with \tcode{std::forward(k), std::forward(obj)}. +If \tcode{equal_range(u.first) == r} is \tcode{false}, +the behavior is undefined. +Inserts \tcode{u} into \tcode{*this}. + +\pnum +\returns +For the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, respectively. +\end{itemdescr} + +\rSec3[map.erasure]{Erasure} + +\indexlibrarymember{erase_if}{map}% +\begin{itemdecl} +template + typename map::size_type + constexpr erase_if(map& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); +\end{codeblock} +\end{itemdescr} + +\rSec2[multimap]{Class template \tcode{multimap}} + +\rSec3[multimap.overview]{Overview} + +\pnum +\indexlibraryglobal{multimap}% +A +\tcode{multimap} +is an associative container that supports equivalent keys (i.e., possibly containing multiple copies of +the same key value) and provides for fast retrieval of values of another type +\tcode{T} +based on the keys. +The +\tcode{multimap} +class +supports bidirectional iterators. + +\pnum +A \tcode{multimap} meets all of the requirements +of a container\iref{container.reqmts}, +of a reversible container\iref{container.rev.reqmts}, +of an allocator-aware container\iref{container.alloc.reqmts}, and +of an associative container\iref{associative.reqmts}. +A +\tcode{multimap} +also provides most operations described in~\ref{associative.reqmts} +for equal keys. +This means that a +\tcode{multimap} +supports the +\tcode{a_eq} +operations in~\ref{associative.reqmts} +but not the +\tcode{a_uniq} +operations. +For a +\tcode{multimap} +the +\tcode{key_type} +is +\tcode{Key} +and the +\tcode{value_type} +is +\tcode{pair}. +Descriptions are provided here only for operations on +\tcode{multimap} +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} +namespace std { + template, + class Allocator = allocator>> + class multimap { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = pair; + using key_compare = Compare; + 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 = @\impdefx{type of \tcode{multimap::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{multimap::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{multimap::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{multimap::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using node_type = @\unspec@; + + class value_compare { + protected: + Compare comp; + constexpr value_compare(Compare c) : comp(c) { } + + public: + constexpr bool operator()(const value_type& x, const value_type& y) const { + return comp(x.first, y.first); + } + }; + + // \ref{multimap.cons}, construct/copy/destroy + constexpr multimap() : multimap(Compare()) { } + constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator()); + template + constexpr multimap(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + 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 + constexpr multimap(InputIterator first, InputIterator last, const Allocator& a) + : multimap(first, last, Compare(), a) { } + template<@\exposconcept{container-compatible-range}@ R> + constexpr multimap(from_range_t, R&& rg, const Allocator& a) + : multimap(from_range, std::forward(rg), Compare(), a) { } + constexpr multimap(initializer_list il, const Allocator& a) + : multimap(il, Compare(), a) { } + 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); + constexpr multimap& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // \ref{multimap.modifiers}, modifiers + 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 + constexpr void insert(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + 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 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& 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); + constexpr void clear() noexcept; + + template + constexpr void merge(multimap& source); + template + constexpr void merge(multimap&& source); + template + constexpr void merge(map& source); + template + constexpr void merge(map&& source); + + // observers + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; + + // map operations + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; + + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; + + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; + + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; + + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; + + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; + template + constexpr pair equal_range(const K& x); + template + constexpr pair equal_range(const K& x) const; + }; + + template>, + class Allocator = allocator<@\placeholder{iter-to-alloc-type}@>> + multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator()) + -> multimap<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, + Compare, Allocator>; + + template>, + class Allocator = allocator<@\exposid{range-to-alloc-type}@>> + multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) + -> multimap<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Compare, Allocator>; + + template, + class Allocator = allocator>> + multimap(initializer_list>, Compare = Compare(), Allocator = Allocator()) + -> multimap; + + template + multimap(InputIterator, InputIterator, Allocator) + -> multimap<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, + less<@\placeholder{iter-key-type}@>, Allocator>; + + template + multimap(from_range_t, R&&, Allocator) + -> multimap<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, less<@\exposid{range-key-type}@>, Allocator>; + + template + multimap(initializer_list>, Allocator) + -> multimap, Allocator>; +} +\end{codeblock}% +\indexlibrarymember{multimap}{operator==}% +\indexlibrarymember{multimap}{operator<} + +\rSec3[multimap.cons]{Constructors} + +\indexlibraryctor{multimap}% +\begin{itemdecl} +constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty +\tcode{multimap} +using the specified comparison object and allocator. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{multimap}% +\begin{itemdecl} +template + constexpr multimap(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty +\tcode{multimap} +using the specified comparison object and allocator, +and inserts elements from the range +\range{first}{last}. + +\pnum +\complexity +Linear in $N$ if the range +\range{first}{last} +is already sorted with respect to \tcode{comp} +and otherwise $N \log N$, +where $N$ is +\tcode{last - first}. +\end{itemdescr} + +\indexlibraryctor{multimap}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr multimap(from_range_t, R&& rg, + const Compare& comp = Compare(), const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{multimap} +using the specified comparison object and allocator, and +inserts elements from the range \tcode{rg}. + +\pnum +\complexity +Linear in $N$ if \tcode{rg} is already sorted with respect to \tcode{comp} and +otherwise $N \log N$, where $N$ is \tcode{ranges::distance(rg)}. +\end{itemdescr} + +\rSec3[multimap.modifiers]{Modifiers} + +\indexlibrarymember{insert}{multimap}% +\begin{itemdecl} +template constexpr iterator insert(P&& x); +template constexpr iterator insert(const_iterator position, P&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +The first form is equivalent to +\tcode{return emplace(std::forward

(x))}. The second form is +equivalent to \tcode{return emplace_hint(position, std::forward

(x))}. +\end{itemdescr} + +\rSec3[multimap.erasure]{Erasure} + +\indexlibrarymember{erase_if}{multimap}% +\begin{itemdecl} +template + typename multimap::size_type + constexpr erase_if(multimap& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); +\end{codeblock} +\end{itemdescr} + +\rSec2[associative.set.syn]{Header \tcode{} synopsis}% + +\indexheader{set}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{set}, class template \tcode{set} + template, class Allocator = allocator> + class set; + + template + constexpr bool operator==(const set& x, + const set& y); + template + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const set& x, + const set& y); + + template + constexpr void swap(set& x, + set& y) + noexcept(noexcept(x.swap(y))); + + // \ref{set.erasure}, erasure for \tcode{set} + template + constexpr typename set::size_type + erase_if(set& c, Predicate pred); + + // \ref{multiset}, class template \tcode{multiset} + template, class Allocator = allocator> + class multiset; + + template + constexpr bool operator==(const multiset& x, + const multiset& y); + template + constexpr @\exposid{synth-three-way-result}@ + operator<=>(const multiset& x, + const multiset& y); + + template + constexpr void swap(multiset& x, + multiset& y) + noexcept(noexcept(x.swap(y))); + + // \ref{multiset.erasure}, erasure for \tcode{multiset} + template + constexpr typename multiset::size_type + erase_if(multiset& c, Predicate pred); + + namespace pmr { + template> + using set = std::set>; + + template> + using multiset = std::multiset>; + } +} +\end{codeblock} + +\rSec2[set]{Class template \tcode{set}} + +\rSec3[set.overview]{Overview} + +\pnum +\indexlibraryglobal{set}% +A +\tcode{set} +is an associative container that supports unique keys (i.e., contains at most one of each key value) and +provides for fast retrieval of the keys themselves. +The +\tcode{set} class +supports bidirectional iterators. + +\pnum +A \tcode{set} meets all of the requirements +of a container\iref{container.reqmts}, +of a reversible container\iref{container.rev.reqmts}, +of an allocator-aware container\iref{container.alloc.reqmts}, and +of an associative container\iref{associative.reqmts}. +A +\tcode{set} +also provides most operations described in~\ref{associative.reqmts} +for unique keys. +This means that a +\tcode{set} +supports the +\tcode{a_uniq} +operations in~\ref{associative.reqmts} +but not the +\tcode{a_eq} +operations. +For a +\tcode{set} +both the +\tcode{key_type} +and +\tcode{value_type} +are +\tcode{Key}. +Descriptions are provided here only for operations on +\tcode{set} +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, + class Allocator = allocator> + class set { + public: + // types + using key_type = Key; + using key_compare = Compare; + using value_type = Key; + using value_compare = Compare; + 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 = @\impdefx{type of \tcode{set::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{set::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{set::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{set::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using node_type = @\unspec@; + using insert_return_type = @\placeholdernc{insert-return-type}@; + + // \ref{set.cons}, construct/copy/destroy + constexpr set() : set(Compare()) { } + constexpr explicit set(const Compare& comp, const Allocator& = Allocator()); + template + constexpr set(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + 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 + constexpr set(InputIterator first, InputIterator last, const Allocator& a) + : set(first, last, Compare(), a) { } + template<@\exposconcept{container-compatible-range}@ R> + constexpr set(from_range_t, R&& rg, const Allocator& a) + : set(from_range, std::forward(rg), Compare(), a) { } + constexpr set(initializer_list il, const Allocator& a) + : set(il, Compare(), a) { } + 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); + constexpr set& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // \ref{set.modifiers}, modifiers + 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 + constexpr void insert(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + 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 insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); + + 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); + constexpr void swap(set&) + noexcept(allocator_traits::is_always_equal::value && + is_nothrow_swappable_v); + constexpr void clear() noexcept; + + template + constexpr void merge(set& source); + template + constexpr void merge(set&& source); + template + constexpr void merge(multiset& source); + template + constexpr void merge(multiset&& source); + + // observers + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; + + // set operations + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; + + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; + + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; + + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; + + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; + + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; + template + constexpr pair equal_range(const K& x); + template + constexpr pair equal_range(const K& x) const; + }; + + template>, + class Allocator = allocator<@\placeholder{iter-value-type}@>> + set(InputIterator, InputIterator, + Compare = Compare(), Allocator = Allocator()) + -> set<@\placeholder{iter-value-type}@, Compare, Allocator>; + + template>, + class Allocator = allocator>> + set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) + -> set, Compare, Allocator>; + + template, class Allocator = allocator> + set(initializer_list, Compare = Compare(), Allocator = Allocator()) + -> set; + + template + set(InputIterator, InputIterator, Allocator) + -> set<@\placeholder{iter-value-type}@, + less<@\placeholder{iter-value-type}@>, Allocator>; + + template + set(from_range_t, R&&, Allocator) + -> set, less>, Allocator>; + + template + set(initializer_list, Allocator) -> set, Allocator>; +} +\end{codeblock}% +\indexlibrarymember{set}{operator==}% +\indexlibrarymember{set}{operator<} + +\rSec3[set.cons]{Constructors, copy, and assignment} + +\indexlibraryctor{set}% +\begin{itemdecl} +constexpr explicit set(const Compare& comp, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{set} using the specified comparison object and allocator. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{set}% +\begin{itemdecl} +template + constexpr set(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty +\tcode{set} +using the specified comparison object and allocator, +and inserts elements from the range +\range{first}{last}. + +\pnum +\complexity +Linear in $N$ if the range +\range{first}{last} +is already sorted with respect to \tcode{comp} +and otherwise $N \log N$, +where $N$ is +\tcode{last - first}. +\end{itemdescr} + +\indexlibraryctor{set}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr set(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{set} using the specified comparison object and allocator, +and inserts elements from the range \tcode{rg}. + +\pnum +\complexity +Linear in $N$ if \tcode{rg} is already sorted with respect to \tcode{comp} and +otherwise $N \log N$, where $N$ is \tcode{ranges::distance(rg)}. +\end{itemdescr} + +\rSec3[set.erasure]{Erasure} + +\indexlibrarymember{erase_if}{set}% +\begin{itemdecl} +template + constexpr typename set::size_type + erase_if(set& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); +\end{codeblock} +\end{itemdescr} + +\rSec3[set.modifiers]{Modifiers} + +\indexlibrarymember{insert}{set}% +\begin{itemdecl} +template constexpr pair insert(K&& x); +template constexpr iterator insert(const_iterator hint, K&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. +For the second overload, +\tcode{is_convertible_v} and +\tcode{is_convertible_v} are both \tcode{false}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{set} from +\tcode{std::forward(x)}. + +\pnum +\effects +If the set already contains an element that is equivalent to \tcode{x}, +there is no effect. +Otherwise, let \tcode{r} be \tcode{equal_range(x)}. +Constructs an object \tcode{u} of type \tcode{value_type} +with \tcode{std::forward(x)}. +If \tcode{equal_range(u) == r} is \tcode{false}, the behavior is undefined. +Inserts \tcode{u} into \tcode{*this}. + +\pnum +\returns +For the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the set element that is equivalent to \tcode{x}. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\rSec2[multiset]{Class template \tcode{multiset}} + +\rSec3[multiset.overview]{Overview} + +\pnum +\indexlibraryglobal{multiset}% +A +\tcode{multiset} +is an associative container that supports equivalent keys (i.e., possibly contains multiple copies of +the same key value) and provides for fast retrieval of the keys themselves. +The +\tcode{multiset} class +supports bidirectional iterators. + +\pnum +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}, and +of an associative container\iref{associative.reqmts}. +\tcode{multiset} +also provides most operations described in~\ref{associative.reqmts} +for duplicate keys. +This means that a +\tcode{multiset} +supports the +\tcode{a_eq} +operations in~\ref{associative.reqmts} +but not the +\tcode{a_uniq} +operations. +For a +\tcode{multiset} +both the +\tcode{key_type} +and +\tcode{value_type} +are +\tcode{Key}. +Descriptions are provided here only for operations on +\tcode{multiset} +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, + class Allocator = allocator> + class multiset { + public: + // types + using key_type = Key; + using key_compare = Compare; + using value_type = Key; + using value_compare = Compare; + 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 = @\impdefx{type of \tcode{multiset::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{multiset::difference_type}}@; // see \ref{container.requirements} + using iterator = @\impdefx{type of \tcode{multiset::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{multiset::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using node_type = @\unspec@; + + // \ref{multiset.cons}, construct/copy/destroy + constexpr multiset() : multiset(Compare()) { } + constexpr explicit multiset(const Compare& comp, const Allocator& = Allocator()); + template + constexpr multiset(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); + template<@\exposconcept{container-compatible-range}@ R> + 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 + constexpr multiset(InputIterator first, InputIterator last, const Allocator& a) + : multiset(first, last, Compare(), a) { } + template<@\exposconcept{container-compatible-range}@ R> + constexpr multiset(from_range_t, R&& rg, const Allocator& a) + : multiset(from_range, std::forward(rg), Compare(), a) { } + constexpr multiset(initializer_list il, const Allocator& a) + : multiset(il, Compare(), a) { } + 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); + constexpr multiset& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // modifiers + 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 + constexpr void insert(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + 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) + 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); + constexpr void swap(multiset&) + noexcept(allocator_traits::is_always_equal::value && + is_nothrow_swappable_v); + constexpr void clear() noexcept; + + template + constexpr void merge(multiset& source); + template + constexpr void merge(multiset&& source); + template + constexpr void merge(set& source); + template + constexpr void merge(set&& source); + + // observers + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; + + // set operations + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; + + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; + + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; + + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; + + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; + + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; + template + constexpr pair equal_range(const K& x); + template + constexpr pair equal_range(const K& x) const; + }; + + template>, + class Allocator = allocator<@\placeholder{iter-value-type}@>> + multiset(InputIterator, InputIterator, + Compare = Compare(), Allocator = Allocator()) + -> multiset<@\placeholder{iter-value-type}@, Compare, Allocator>; + + template>, + class Allocator = allocator>> + multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) + -> multiset, Compare, Allocator>; + + template, class Allocator = allocator> + multiset(initializer_list, Compare = Compare(), Allocator = Allocator()) + -> multiset; + + template + multiset(InputIterator, InputIterator, Allocator) + -> multiset<@\placeholder{iter-value-type}@, + less<@\placeholder{iter-value-type}@>, Allocator>; + + template + multiset(from_range_t, R&&, Allocator) + -> multiset, less>, Allocator>; + + template + multiset(initializer_list, Allocator) -> multiset, Allocator>; +} +\end{codeblock}% +\indexlibrarymember{multiset}{operator==}% +\indexlibrarymember{multiset}{operator<} + +\rSec3[multiset.cons]{Constructors} + +\indexlibraryctor{multiset}% +\begin{itemdecl} +constexpr explicit multiset(const Compare& comp, const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{multiset} using the specified comparison object and allocator. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{multiset}% +\begin{itemdecl} +template + constexpr multiset(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty +\tcode{multiset} +using the specified comparison object and allocator, +and inserts elements from the range +\range{first}{last}. + +\pnum +\complexity +Linear in $N$ +if the range +\range{first}{last} +is already sorted with respect to \tcode{comp} and otherwise $N \log N$, +where $N$ is +\tcode{last - first}. +\end{itemdescr} + +\indexlibraryctor{multiset}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr multiset(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{multiset} +using the specified comparison object and allocator, and +inserts elements from the range \tcode{rg}. + +\pnum +\complexity +Linear in $N$ if \tcode{rg} is already sorted with respect to \tcode{comp} and +otherwise $N \log N$, where $N$ is \tcode{ranges::distance(rg)}. +\end{itemdescr} + +\rSec3[multiset.erasure]{Erasure} + +\indexlibrarymember{erase_if}{multiset}% +\begin{itemdecl} +template + constexpr typename multiset::size_type + erase_if(multiset& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); +\end{codeblock} +\end{itemdescr} + +\rSec1[unord]{Unordered associative containers} + +\rSec2[unord.general]{General} + +\pnum +The header \libheaderrefx{unordered_map}{unord.map.syn} defines the class +templates \tcode{unordered_map} and \tcode{unordered_multimap}; +the header \libheaderrefx{unordered_set}{unord.set.syn} defines the class +templates \tcode{unordered_set} and \tcode{unordered_multiset}. + +\pnum +The exposition-only alias templates +\exposid{iter-value-type}, \exposid{iter-key-type}, +\exposid{iter-mapped-type}, \exposid{iter-to\--alloc-type}, +\exposid{range-key-type}, \exposid{range-mapped-type}, +and \exposid{range-to-alloc-type} +defined in \ref{associative.general} may appear in deduction guides for unordered containers. + +\rSec2[unord.map.syn]{Header \tcode{} synopsis} + +\indexheader{unordered_map}% +\indexlibraryglobal{unordered_map}% +\indexlibraryglobal{unordered_multimap}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{unord.map}, class template \tcode{unordered_map} + template, + class Pred = equal_to, + class Alloc = allocator>> + class unordered_map; + + // \ref{unord.multimap}, class template \tcode{unordered_multimap} + template, + class Pred = equal_to, + class Alloc = allocator>> + class unordered_multimap; + + template + constexpr bool operator==(const unordered_map& a, + const unordered_map& b); + + template + constexpr bool operator==(const unordered_multimap& a, + const unordered_multimap& b); + + template + constexpr void swap(unordered_map& x, + unordered_map& y) + noexcept(noexcept(x.swap(y))); + + template + constexpr void swap(unordered_multimap& x, + unordered_multimap& y) + noexcept(noexcept(x.swap(y))); + + // \ref{unord.map.erasure}, erasure for \tcode{unordered_map} + template + constexpr typename unordered_map::size_type + erase_if(unordered_map& c, Predicate pred); + + // \ref{unord.multimap.erasure}, erasure for \tcode{unordered_multimap} + template + constexpr typename unordered_multimap::size_type + erase_if(unordered_multimap& c, Predicate pred); + + namespace pmr { + template, + class Pred = equal_to> + using unordered_map = + std::unordered_map>>; + template, + class Pred = equal_to> + using unordered_multimap = + std::unordered_multimap>>; + + } +} +\end{codeblock} + +\rSec2[unord.map]{Class template \tcode{unordered_map}}% +\indexlibraryglobal{unordered_map} + +\rSec3[unord.map.overview]{Overview} + +\pnum +\indextext{\idxcode{unordered_map}!unique keys}% +\indextext{unordered associative containers!unique keys}% +An \tcode{unordered_map} is an unordered associative container that +supports unique keys (an \tcode{unordered_map} contains at most one of each +key value) and that associates values of another type +\tcode{mapped_type} with the keys. +The \tcode{unordered_map} class +supports forward iterators. + +\pnum +An \tcode{unordered_map} meets all of the requirements +of a container\iref{container.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_map} supports the \tcode{a_uniq} operations in that table, +not the \tcode{a_eq} operations. +For an \tcode{unordered_map} the \tcode{key_type} is \tcode{Key}, +the \tcode{mapped_type} is \tcode{T}, +and the \tcode{value_type} is \tcode{pair}. + +\pnum +Subclause~\ref{unord.map} only describes operations on \tcode{unordered_map} 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_map}% +\begin{codeblock} +namespace std { + template, + class Pred = equal_to, + class Allocator = allocator>> + class unordered_map { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = pair; + using hasher = Hash; + using key_equal = Pred; + 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 = @\impdefx{type of \tcode{unordered_map::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{unordered_map::difference_type}}@; // see \ref{container.requirements} + + using iterator = @\impdefx{type of \tcode{unordered_map::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{unordered_map::const_iterator}}@; // see \ref{container.requirements} + using local_iterator = @\impdefx{type of \tcode{unordered_map::local_iterator}}@; // see \ref{container.requirements} + using const_local_iterator = @\impdefx{type of \tcode{unordered_map::const_local_iterator}}@; // see \ref{container.requirements} + using node_type = @\unspec@; + using insert_return_type = @\placeholdernc{insert-return-type}@; + + // \ref{unord.map.cnstr}, construct/copy/destroy + 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 + 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> + 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) { } + constexpr unordered_map(size_type n, const hasher& hf, const allocator_type& a) + : unordered_map(n, hf, key_equal(), a) { } + template + constexpr unordered_map(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) + : unordered_map(f, l, n, hasher(), key_equal(), a) { } + template + 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> + 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> + 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) { } + constexpr unordered_map(initializer_list il, size_type n, + const allocator_type& a) + : unordered_map(il, n, hasher(), key_equal(), 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) { } + 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); + constexpr unordered_map& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // \ref{unord.map.modifiers}, modifiers + 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> + 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 insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); + + template + constexpr pair try_emplace(const key_type& k, Args&&... args); + template + constexpr pair try_emplace(key_type&& k, Args&&... args); + template + constexpr pair try_emplace(K&& k, Args&&... args); + template + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + template + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + template + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + template + constexpr pair insert_or_assign(const key_type& k, M&& obj); + template + constexpr pair insert_or_assign(key_type&& k, M&& obj); + template + constexpr pair insert_or_assign(K&& k, M&& obj); + template + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + template + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + template + 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); + constexpr void clear() noexcept; + + template + constexpr void merge(unordered_map& source); + template + constexpr void merge(unordered_map&& source); + template + constexpr void merge(unordered_multimap& source); + template + constexpr void merge(unordered_multimap&& source); + + // observers + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; + + // map operations + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; + template + constexpr iterator find(const K& k); + template + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; + template + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; + template + 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 + constexpr pair equal_range(const K& k); + template + constexpr pair equal_range(const K& k) const; + + // \ref{unord.map.elem}, element access + constexpr mapped_type& operator[](const key_type& k); + constexpr mapped_type& operator[](key_type&& k); + template constexpr mapped_type& operator[](K&& k); + constexpr mapped_type& at(const key_type& k); + constexpr const mapped_type& at(const key_type& k) const; + template constexpr mapped_type& at(const K& k); + template constexpr const mapped_type& at(const K& k) const; + + // bucket interface + 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 + 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-key-type}@>, + class Allocator = allocator<@\placeholder{iter-to-alloc-type}@>> + unordered_map(InputIterator, InputIterator, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_map<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, Hash, Pred, + Allocator>; + + template>, + class Pred = equal_to<@\exposid{range-key-type}@>, + class Allocator = allocator<@\exposid{range-to-alloc-type}@>> + unordered_map(from_range_t, R&&, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Hash, Pred, Allocator>; + + template, + class Pred = equal_to, class Allocator = allocator>> + unordered_map(initializer_list>, + typename @\seebelow@::size_type = @\seebelow@, Hash = Hash(), + Pred = Pred(), Allocator = Allocator()) + -> unordered_map; + + template + unordered_map(InputIterator, InputIterator, typename @\seebelow@::size_type, Allocator) + -> unordered_map<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, + hash<@\placeholder{iter-key-type}@>, + equal_to<@\placeholder{iter-key-type}@>, Allocator>; + + template + unordered_map(InputIterator, InputIterator, Allocator) + -> unordered_map<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, + hash<@\placeholder{iter-key-type}@>, + equal_to<@\placeholder{iter-key-type}@>, Allocator>; + + template + unordered_map(InputIterator, InputIterator, typename @\seebelow@::size_type, Hash, Allocator) + -> unordered_map<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, Hash, + equal_to<@\placeholder{iter-key-type}@>, Allocator>; + + template + unordered_map(from_range_t, R&&, typename @\seebelow@::size_type, Allocator) + -> unordered_map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, hash<@\exposid{range-key-type}@>, + equal_to<@\exposid{range-key-type}@>, Allocator>; + + template + unordered_map(from_range_t, R&&, Allocator) + -> unordered_map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, hash<@\exposid{range-key-type}@>, + equal_to<@\exposid{range-key-type}@>, Allocator>; + + template + unordered_map(from_range_t, R&&, typename @\seebelow@::size_type, Hash, Allocator) + -> unordered_map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Hash, + equal_to<@\exposid{range-key-type}@>, Allocator>; + + template + unordered_map(initializer_list>, typename @\seebelow@::size_type, + Allocator) + -> unordered_map, equal_to, Allocator>; + + template + unordered_map(initializer_list>, Allocator) + -> unordered_map, equal_to, Allocator>; + + template + unordered_map(initializer_list>, typename @\seebelow@::size_type, Hash, + Allocator) + -> unordered_map, Allocator>; +} +\end{codeblock} + +\pnum +A \tcode{size_type} parameter type in an \tcode{unordered_map} deduction guide +refers to the \tcode{size_type} member type of the type deduced by the deduction guide. + +\rSec3[unord.map.cnstr]{Constructors} + +\indexlibraryctor{unordered_map}% +\begin{itemdecl} +constexpr unordered_map() : unordered_map(size_type(@\seebelow@)) { } +constexpr explicit unordered_map(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{unordered_map} using the +specified hash function, key equality predicate, and allocator, and +using at least \tcode{n} buckets. For the default constructor, +the number of buckets is \impldef{default number of buckets in +\tcode{unordered_map}}. +\tcode{max_load_factor()} returns \tcode{1.0}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{unordered_map}% +\begin{itemdecl} +template + 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> + 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} +\pnum +\effects +Constructs an empty \tcode{unordered_map} using the +specified hash function, key equality predicate, and allocator, and +using at least \tcode{n} buckets. If \tcode{n} is not +provided, the number of buckets is \impldef{default number of buckets in +\tcode{unordered_map}}. Then +inserts elements from the range \range{f}{l}, \tcode{rg}, or \tcode{il}, +respectively. +\tcode{max_load_factor()} returns \tcode{1.0}. + +\pnum +\complexity +Average case linear, worst case quadratic. +\end{itemdescr} + +\rSec3[unord.map.elem]{Element access} + +\indexlibrarymember{unordered_map}{operator[]}% +\indextext{\idxcode{unordered_map}!element access}% +\begin{itemdecl} +constexpr mapped_type& operator[](const key_type& k); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return try_emplace(k).first->second;} +\end{itemdescr} + +\indexlibrarymember{unordered_map}{operator[]}% +\indextext{\idxcode{unordered_map}!element access}% +\begin{itemdecl} +constexpr mapped_type& operator[](key_type&& k); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return try_emplace(std::move(k)).first->second;} +\end{itemdescr} + +\indexlibrarymember{unordered_map}{operator[]}% +\indextext{\idxcode{unordered_map}!element access}% +\begin{itemdecl} +template constexpr mapped_type& operator[](K&& k); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id}s \tcode{Hash::is_transparent} and +\tcode{Pred::is_transparent} are valid and denote types. + +\pnum +\effects +Equivalent to: \tcode{return try_emplace(std::forward(k)).first->second;} +\end{itemdescr} + +\indexlibrarymember{unordered_map}{at}% +\indextext{\idxcode{unordered_map}!element access}% +\begin{itemdecl} +constexpr mapped_type& at(const key_type& k); +constexpr const mapped_type& at(const key_type& k) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A reference to \tcode{x.second}, where \tcode{x} is the (unique) element whose key is equivalent to \tcode{k}. + +\pnum +\throws +An exception object of type \tcode{out_of_range} if no such element is present. +\end{itemdescr} + +\indexlibrarymember{unordered_map}{at}% +\indextext{\idxcode{unordered_map}!element access}% +\begin{itemdecl} +template constexpr mapped_type& at(const K& k); +template constexpr const mapped_type& at(const K& k) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id}s \tcode{Hash::is_transparent} and +\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 +A reference to \tcode{find(k)->second}. + +\pnum +\throws +An exception object of type \tcode{out_of_range} +if \tcode{find(k) == end()} is \tcode{true}. +\end{itemdescr} + +\rSec3[unord.map.modifiers]{Modifiers} + +\indexlibrarymember{unordered_map}{insert}% +\begin{itemdecl} +template + constexpr pair insert(P&& obj); +\end{itemdecl} + +\begin{itemdescr} + +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +Equivalent to: \tcode{return emplace(std::forward

(obj));} +\end{itemdescr} + +\indexlibrarymember{unordered_map}{insert}% +\begin{itemdecl} +template + constexpr iterator insert(const_iterator hint, P&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +Equivalent to: +\tcode{return emplace_hint(hint, std::forward

(obj));} +\end{itemdescr} + +\indexlibrarymember{try_emplace}{unordered_map}% +\begin{itemdecl} +template + constexpr pair try_emplace(const key_type& k, Args&&... args); +template + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{unordered_map} +from \tcode{piecewise_con\-struct}, \tcode{forward_as_tuple(k)}, +\tcode{forward_as_tuple(std::forward(args)...)}. + +\pnum +\effects +If the map already contains an element +whose key is equivalent to \tcode{k}, +there is no effect. +Otherwise inserts an object of type \tcode{value_type} +constructed with \tcode{piecewise_construct}, \tcode{forward_as_tuple(k)}, +\tcode{forward_as_tuple(std::forward(args)...)}. + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, +respectively. +\end{itemdescr} + +\indexlibrarymember{try_emplace}{unordered_map}% +\begin{itemdecl} +template + constexpr pair try_emplace(key_type&& k, Args&&... args); +template + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{unordered_map} +from \tcode{piecewise_con\-struct}, \tcode{forward_as_tuple(std::move(k))}, +\tcode{forward_as_tuple(std::forward(args)...)}. + +\pnum +\effects +If the map already contains an element +whose key is equivalent to \tcode{k}, +there is no effect. +Otherwise inserts an object of type \tcode{value_type} +constructed with \tcode{piecewise_construct}, \tcode{forward_as_tuple(std::move(k))}, +\tcode{forward_as_tuple(std::forward(args)...)}. + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, +respectively. +\end{itemdescr} + +\indexlibrarymember{try_emplace}{unordered_map}% +\begin{itemdecl} +template + constexpr pair try_emplace(K&& k, Args&&... args); +template + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id}s \tcode{Hash::is_transparent} and +\tcode{Pred::is_transparent} are valid and denote types. +For the first overload, +\tcode{is_convertible_v} and +\tcode{is_convertible_v} are both \tcode{false}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} +into \tcode{unordered_map} from +\tcode{piecewise_construct, forward_as_tuple(std::forward(k)), +forward_as_tuple(std::forward\newline (args)...)}. + +\pnum +\effects +If the map already contains an element whose key is equivalent to \tcode{k}, +there is no effect. +Otherwise, let \tcode{h} be \tcode{hash_function()(k)}. +Constructs an object \tcode{u} of type \tcode{value_type} +with \tcode{piecewise_construct, forward_as_tuple(std::forward(k)), +forward_as_tuple(std::forward(args)...)}.\newline +If \tcode{hash_function()(u.first) != h || contains(u.first)} is \tcode{true}, +the behavior is undefined. +Inserts \tcode{u} into \tcode{*this}. + +\pnum +\returns +For the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, respectively. +\end{itemdescr} + +\indexlibrarymember{insert_or_assign}{unordered_map}% +\begin{itemdecl} +template + constexpr pair insert_or_assign(const key_type& k, M&& obj); +template + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_assignable_v} is \tcode{true}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{unordered_map} +from \tcode{k}, \tcode{std::for\-ward(obj)}. + +\pnum +\effects +If the map already contains an element \tcode{e} +whose key is equivalent to \tcode{k}, +assigns \tcode{std::for\-ward(obj)} to \tcode{e.second}. +Otherwise inserts an object of type \tcode{value_type} +constructed with \tcode{k}, \tcode{std::forward(obj)}. + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, +respectively. +\end{itemdescr} + +\indexlibrarymember{insert_or_assign}{unordered_map}% +\begin{itemdecl} +template + constexpr pair insert_or_assign(key_type&& k, M&& obj); +template + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{is_assignable_v} is \tcode{true}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{Emplace\-Constructible} into \tcode{unordered_map} +from \tcode{std::move(k)}, \tcode{std::\brk{}forward(obj)}. + +\pnum +\effects +If the map already contains an element \tcode{e} +whose key is equivalent to \tcode{k}, +assigns \tcode{std::for\-ward(obj)} to \tcode{e.second}. +Otherwise inserts an object of type \tcode{value_type} +constructed with \tcode{std::\brk{}move(k)}, \tcode{std::forward(obj)}. + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, +respectively. +\end{itemdescr} + +\indexlibrarymember{insert_or_assign}{unordered_map}% +\begin{itemdecl} +template + constexpr pair insert_or_assign(K&& k, M&& obj); +template + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id}s \tcode{Hash::is_transparent} and +\tcode{Pred::is_transparent} are valid and denote types. + +\pnum +\mandates +\tcode{is_assignable_v} is \tcode{true}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} +into \tcode{unordered_map} +from \tcode{std::forward\newline (k), std::forward(obj)}. + +\pnum +\effects +If the map already contains an element \tcode{e} +whose key is equivalent to \tcode{k}, +assigns \tcode{std::forward\newline (obj)} to \tcode{e.second}. +Otherwise, let \tcode{h} be \tcode{hash_function()(k)}. +Constructs an object \tcode{u} of type \tcode{value_type} +with \tcode{std::forward(k), std::forward(obj)}. +If \tcode{hash_function()(u.first) != h || contains(u.first)} is \tcode{true}, +the behavior is undefined. +Inserts \tcode{u} into \tcode{*this}. + +\pnum +\returns +For the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, respectively. +\end{itemdescr} + +\rSec3[unord.map.erasure]{Erasure} + +\indexlibrarymember{erase_if}{unordered_map}% +\begin{itemdecl} +template + constexpr typename unordered_map::size_type + erase_if(unordered_map& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); +\end{codeblock} +\end{itemdescr} + +\rSec2[unord.multimap]{Class template \tcode{unordered_multimap}}% +\indexlibraryglobal{unordered_multimap} + +\rSec3[unord.multimap.overview]{Overview} + +\pnum +\indextext{\idxcode{unordered_multimap}!equivalent keys}% +\indextext{unordered associative containers!equivalent keys}% +An \tcode{unordered_multimap} is an unordered associative container +that supports equivalent keys (an instance of \tcode{unordered_multimap} may contain +multiple copies of each key value) and that associates values of +another type \tcode{mapped_type} with the keys. +The \tcode{unordered_multimap} class +supports forward iterators. + +\pnum +An \tcode{unordered_multimap} meets all of the requirements +of a container\iref{container.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 equivalent keys; that is, an \tcode{unordered_multimap} +supports the \tcode{a_eq} operations in that table, not the \tcode{a_uniq} operations. +For an \tcode{unordered_multimap} the \tcode{key_type} is \tcode{Key}, +the \tcode{mapped_type} is \tcode{T}, +and the \tcode{value_type} is \tcode{pair}. + +\pnum +Subclause~\ref{unord.multimap} only describes operations on \tcode{unordered_multimap} +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 { + template, + class Pred = equal_to, + class Allocator = allocator>> + class unordered_multimap { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = pair; + using hasher = Hash; + using key_equal = Pred; + 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 = @\impdefx{type of \tcode{unordered_multimap::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{unordered_multimap::difference_type}}@; // see \ref{container.requirements} + + using iterator = @\impdefx{type of \tcode{unordered_multimap::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{unordered_multimap::const_iterator}}@; // see \ref{container.requirements} + using local_iterator = @\impdefx{type of \tcode{unordered_multimap::local_iterator}}@; // see \ref{container.requirements} + using const_local_iterator = @\impdefx{type of \tcode{unordered_multimap::const_local_it\-erator}}@; // see \ref{container.requirements} + using node_type = @\unspec@; + + // \ref{unord.multimap.cnstr}, construct/copy/destroy + 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 + 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> + 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) { } + constexpr unordered_multimap(size_type n, const hasher& hf, const allocator_type& a) + : unordered_multimap(n, hf, key_equal(), a) { } + template + constexpr unordered_multimap(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) + : unordered_multimap(f, l, n, hasher(), key_equal(), a) { } + template + 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> + 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) { } + constexpr unordered_multimap(initializer_list il, size_type n, const hasher& hf, + const allocator_type& a) + : unordered_multimap(il, n, hf, key_equal(), a) { } + 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); + constexpr unordered_multimap& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // \ref{unord.multimap.modifiers}, modifiers + 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> + 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); + constexpr void clear() noexcept; + + template + constexpr void merge(unordered_multimap& source); + template + constexpr void merge(unordered_multimap&& source); + template + constexpr void merge(unordered_map& source); + template + constexpr void merge(unordered_map&& source); + + // observers + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; + + // map operations + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; + template + constexpr iterator find(const K& k); + template + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; + template + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; + template + 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 + constexpr pair equal_range(const K& k); + template + constexpr pair equal_range(const K& k) const; + + // bucket interface + 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 + 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-key-type}@>, + class Allocator = allocator<@\placeholder{iter-to-alloc-type}@>> + unordered_multimap(InputIterator, InputIterator, + typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multimap<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, + Hash, Pred, Allocator>; + + template>, + class Pred = equal_to<@\exposid{range-key-type}@>, + class Allocator = allocator<@\exposid{range-to-alloc-type}@>> + unordered_multimap(from_range_t, R&&, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multimap<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Hash, Pred, Allocator>; + + template, + class Pred = equal_to, class Allocator = allocator>> + unordered_multimap(initializer_list>, + typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multimap; + + template + unordered_multimap(InputIterator, InputIterator, typename @\seebelow@::size_type, Allocator) + -> unordered_multimap<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, + hash<@\placeholder{iter-key-type}@>, + equal_to<@\placeholder{iter-key-type}@>, Allocator>; + + template + unordered_multimap(InputIterator, InputIterator, Allocator) + -> unordered_multimap<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, + hash<@\placeholder{iter-key-type}@>, + equal_to<@\placeholder{iter-key-type}@>, Allocator>; + + template + unordered_multimap(InputIterator, InputIterator, typename @\seebelow@::size_type, Hash, + Allocator) + -> unordered_multimap<@\placeholder{iter-key-type}@, @\placeholder{iter-mapped-type}@, Hash, + equal_to<@\placeholder{iter-key-type}@>, Allocator>; + + template + unordered_multimap(from_range_t, R&&, typename @\seebelow@::size_type, Allocator) + -> unordered_multimap<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, hash<@\exposid{range-key-type}@>, + equal_to<@\exposid{range-key-type}@>, Allocator>; + + template + unordered_multimap(from_range_t, R&&, Allocator) + -> unordered_multimap<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, hash<@\exposid{range-key-type}@>, + equal_to<@\exposid{range-key-type}@>, Allocator>; + + template + unordered_multimap(from_range_t, R&&, typename @\seebelow@::size_type, Hash, Allocator) + -> unordered_multimap<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Hash, + equal_to<@\exposid{range-key-type}@>, Allocator>; + + template + unordered_multimap(initializer_list>, typename @\seebelow@::size_type, + Allocator) + -> unordered_multimap, equal_to, Allocator>; + + template + unordered_multimap(initializer_list>, Allocator) + -> unordered_multimap, equal_to, Allocator>; + + template + unordered_multimap(initializer_list>, typename @\seebelow@::size_type, + Hash, Allocator) + -> unordered_multimap, Allocator>; +} +\end{codeblock} + +\pnum +A \tcode{size_type} parameter type in an \tcode{unordered_multimap} deduction guide +refers to the \tcode{size_type} member type of the type deduced by the deduction guide. + +\rSec3[unord.multimap.cnstr]{Constructors} + +\indexlibraryctor{unordered_multimap}% +\begin{itemdecl} +constexpr unordered_multimap() : unordered_multimap(size_type(@\seebelow@)) { } +constexpr explicit unordered_multimap(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an empty \tcode{unordered_multimap} using the +specified hash function, key equality predicate, and allocator, and +using at least \tcode{n} buckets. For the default constructor, +the number of buckets is \impldef{default number of buckets in +\tcode{unordered_multimap}}. +\tcode{max_load_factor()} returns \tcode{1.0}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{unordered_multimap}% +\begin{itemdecl} +template + 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> + 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} +\pnum +\effects +Constructs an empty \tcode{unordered_multimap} using the +specified hash function, key equality predicate, and allocator, and +using at least \tcode{n} buckets. If \tcode{n} is not +provided, the number of buckets is \impldef{default number of buckets in +\tcode{unordered_multimap}}. Then +inserts elements from the range \range{f}{l}, \tcode{rg}, or \tcode{il}, +respectively. +\tcode{max_load_factor()} returns \tcode{1.0}. + +\pnum +\complexity +Average case linear, worst case quadratic. +\end{itemdescr} + +\rSec3[unord.multimap.modifiers]{Modifiers} + +\indexlibrarymember{unordered_multimap}{insert}% +\begin{itemdecl} +template + constexpr iterator insert(P&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +Equivalent to: \tcode{return emplace(std::forward

(obj));} +\end{itemdescr} + +\indexlibrarymember{unordered_multimap}{insert}% +\begin{itemdecl} +template + constexpr iterator insert(const_iterator hint, P&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +Equivalent to: +\tcode{return emplace_hint(hint, std::forward

(obj));} +\end{itemdescr} + +\rSec3[unord.multimap.erasure]{Erasure} + +\indexlibrarymember{erase_if}{unordered_multimap}% +\begin{itemdecl} +template + constexpr typename unordered_multimap::size_type + erase_if(unordered_multimap& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); +\end{codeblock} +\end{itemdescr} + +\rSec2[unord.set.syn]{Header \tcode{} synopsis} + +\indexheader{unordered_set}% +\indexlibraryglobal{unordered_set}% +\indexlibraryglobal{unordered_multiset}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{unord.set}, class template \tcode{unordered_set} + template, + class Pred = equal_to, + class Alloc = allocator> + class unordered_set; + + // \ref{unord.multiset}, class template \tcode{unordered_multiset} + template, + class Pred = equal_to, + class Alloc = allocator> + class unordered_multiset; + + template + constexpr bool operator==(const unordered_set& a, + const unordered_set& b); + + template + constexpr bool operator==(const unordered_multiset& a, + const unordered_multiset& b); + + template + constexpr void swap(unordered_set& x, + unordered_set& y) + noexcept(noexcept(x.swap(y))); + + template + constexpr void swap(unordered_multiset& x, + unordered_multiset& y) + noexcept(noexcept(x.swap(y))); + + // \ref{unord.set.erasure}, erasure for \tcode{unordered_set} + template + constexpr typename unordered_set::size_type + erase_if(unordered_set& c, Predicate pred); + + // \ref{unord.multiset.erasure}, erasure for \tcode{unordered_multiset} + template + constexpr typename unordered_multiset::size_type + erase_if(unordered_multiset& c, Predicate pred); + + namespace pmr { + template, + class Pred = equal_to> + using unordered_set = std::unordered_set>; + + template, + class Pred = equal_to> + using unordered_multiset = std::unordered_multiset>; + } +} +\end{codeblock} + +\rSec2[unord.set]{Class template \tcode{unordered_set}}% +\indexlibraryglobal{unordered_set} + +\rSec3[unord.set.overview]{Overview} + +\pnum +\indextext{\idxcode{unordered_set}!unique keys}% +\indextext{unordered associative containers!unique keys}% +An \tcode{unordered_set} is an unordered associative container that +supports unique keys (an \tcode{unordered_set} contains at most one of each +key value) and in which the elements' keys are the elements +themselves. +The \tcode{unordered_set} class +supports forward iterators. + +\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}, 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, +not the \tcode{a_eq} operations. +For an \tcode{unordered_set} the \tcode{key_type} +and the \tcode{value_type} are both \tcode{Key}. +The \tcode{iterator} and \tcode{const_iterator} types are both constant iterator types. +It is unspecified whether they are the same type. + +\pnum +Subclause~\ref{unord.set} only describes operations on \tcode{unordered_set} 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_set}% +\begin{codeblock} +namespace std { + template, + class Pred = equal_to, + class Allocator = allocator> + class unordered_set { + public: + // types + using key_type = Key; + using value_type = Key; + using hasher = Hash; + using key_equal = Pred; + 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 = @\impdefx{type of \tcode{unordered_set::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{unordered_set::difference_type}}@; // see \ref{container.requirements} + + using iterator = @\impdefx{type of \tcode{unordered_set::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{unordered_set::const_iterator}}@; // see \ref{container.requirements} + using local_iterator = @\impdefx{type of \tcode{unordered_set::local_iterator}}@; // see \ref{container.requirements} + using const_local_iterator = @\impdefx{type of \tcode{unordered_set::const_local_iterator}}@; // see \ref{container.requirements} + using node_type = @\unspec@; + using insert_return_type = @\placeholdernc{insert-return-type}@; + + // \ref{unord.set.cnstr}, construct/copy/destroy + 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 + 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> + 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) { } + constexpr unordered_set(size_type n, const hasher& hf, const allocator_type& a) + : unordered_set(n, hf, key_equal(), a) { } + template + constexpr unordered_set(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) + : unordered_set(f, l, n, hasher(), key_equal(), a) { } + template + 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> + 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> + 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) { } + constexpr unordered_set(initializer_list il, size_type n, const hasher& hf, + const allocator_type& a) + : unordered_set(il, n, hf, key_equal(), a) { } + 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); + constexpr unordered_set& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // \ref{unord.set.modifiers}, modifiers + 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> + 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 insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); + + constexpr iterator erase(iterator position) + requires (!@\libconcept{same_as}@); + 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); + constexpr void clear() noexcept; + + template + constexpr void merge(unordered_set& source); + template + constexpr void merge(unordered_set&& source); + template + constexpr void merge(unordered_multiset& source); + template + constexpr void merge(unordered_multiset&& source); + + // observers + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; + + // set operations + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; + template + constexpr iterator find(const K& k); + template + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; + template + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; + template + 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 + constexpr pair equal_range(const K& k); + template + constexpr pair equal_range(const K& k) const; + + // bucket interface + 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 + 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_set(InputIterator, InputIterator, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_set<@\placeholder{iter-value-type}@, + Hash, Pred, Allocator>; + + template>, + class Pred = equal_to>, + class Allocator = allocator>> + unordered_set(from_range_t, R&&, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_set, Hash, Pred, Allocator>; + + template, + class Pred = equal_to, class Allocator = allocator> + unordered_set(initializer_list, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_set; + + template + unordered_set(InputIterator, InputIterator, typename @\seebelow@::size_type, Allocator) + -> unordered_set<@\placeholder{iter-value-type}@, + hash<@\placeholder{iter-value-type}@>, + equal_to<@\placeholder{iter-value-type}@>, + Allocator>; + + template + unordered_set(InputIterator, InputIterator, typename @\seebelow@::size_type, + Hash, Allocator) + -> unordered_set<@\placeholder{iter-value-type}@, Hash, + equal_to<@\placeholder{iter-value-type}@>, + Allocator>; + + template + unordered_set(from_range_t, R&&, typename @\seebelow@::size_type, Allocator) + -> unordered_set, hash>, + equal_to>, Allocator>; + + template + unordered_set(from_range_t, R&&, Allocator) + -> unordered_set, hash>, + equal_to>, Allocator>; + + template + unordered_set(from_range_t, R&&, typename @\seebelow@::size_type, Hash, Allocator) + -> unordered_set, Hash, + equal_to>, Allocator>; + + template + unordered_set(initializer_list, typename @\seebelow@::size_type, Allocator) + -> unordered_set, equal_to, Allocator>; + + template + unordered_set(initializer_list, typename @\seebelow@::size_type, Hash, Allocator) + -> unordered_set, Allocator>; +} +\end{codeblock} + +\pnum +A \tcode{size_type} parameter type in an \tcode{unordered_set} deduction guide +refers to the \tcode{size_type} member type of +the type deduced by the deduction guide. + +\rSec3[unord.set.cnstr]{Constructors} + +\indexlibraryctor{unordered_set}% +\begin{itemdecl} +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} +\pnum +\effects +Constructs an empty \tcode{unordered_set} using the +specified hash function, key equality predicate, and allocator, and +using at least \tcode{n} buckets. For the default constructor, +the number of buckets is \impldef{default number of buckets in +\tcode{unordered_set}}. +\tcode{max_load_factor()} returns \tcode{1.0}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{unordered_set}% +\begin{itemdecl} +template + 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> + 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} +\pnum +\effects +Constructs an empty \tcode{unordered_set} using the +specified hash function, key equality predicate, and allocator, and +using at least \tcode{n} buckets. If \tcode{n} is not +provided, the number of buckets is \impldef{default number of buckets in +\tcode{unordered_set}}. Then +inserts elements from the range \range{f}{l}, \tcode{rg}, or \tcode{il}, +respectively. +\tcode{max_load_factor()} returns \tcode{1.0}. + +\pnum +\complexity +Average case linear, worst case quadratic. +\end{itemdescr} + +\rSec3[unord.set.erasure]{Erasure} + +\indexlibrarymember{erase_if}{unordered_set}% +\begin{itemdecl} +template + constexpr typename unordered_set::size_type + erase_if(unordered_set& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); +\end{codeblock} +\end{itemdescr} + +\rSec3[unord.set.modifiers]{Modifiers} + +\indexlibrarymember{insert}{unordered_set}% +\begin{itemdecl} +template constexpr pair insert(K&& obj); +template constexpr iterator insert(const_iterator hint, K&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id}s \tcode{Hash::is_transparent} and +\tcode{Pred::is_transparent} are valid and denote types. +For the second overload, +\tcode{is_convertible_v} and +\tcode{is_convertible_v} are both \tcode{false}. + +\pnum +\expects +\tcode{value_type} is \oldconcept{EmplaceConstructible} +into \tcode{unordered_set} from \tcode{std::forward\newline (obj)}. + +\pnum +\effects +If the set already contains an element that is equivalent to \tcode{obj}, +there is no effect. +Otherwise, let \tcode{h} be \tcode{hash_function()(obj)}. +Constructs an object \tcode{u} of type \tcode{value_type} +with \tcode{std::forward(obj)}. +If \tcode{hash_function()(u) != h || contains(u)} is \tcode{true}, +the behavior is undefined. +Inserts \tcode{u} into \tcode{*this}. + +\pnum +\returns +For the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the set element +that is equivalent to \tcode{obj}. + +\pnum +\complexity +Average case constant, worst case linear. +\end{itemdescr} + +\rSec2[unord.multiset]{Class template \tcode{unordered_multiset}}% +\indexlibraryglobal{unordered_multiset} + +\rSec3[unord.multiset.overview]{Overview} + +\pnum +\indextext{\idxcode{unordered_multiset}!equivalent keys}% +\indextext{unordered associative containers!equivalent keys}% +An \tcode{unordered_multiset} is an unordered associative container +that supports equivalent keys (an instance of \tcode{unordered_multiset} may contain +multiple copies of the same key value) and in which each element's key +is the element itself. +The \tcode{unordered_multiset} class +supports forward iterators. + +\pnum +An \tcode{unordered_multiset} meets all of the requirements +of a container\iref{container.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 equivalent keys; that is, an \tcode{unordered_multiset} +supports the \tcode{a_eq} operations in that table, not the \tcode{a_uniq} operations. +For an \tcode{unordered_multiset} the \tcode{key_type} and the \tcode{value_type} are +both \tcode{Key}. The \tcode{iterator} and \tcode{const_iterator} types are both +constant iterator types. It is unspecified whether they are the same type. + +\pnum +Subclause~\ref{unord.multiset} only describes operations on \tcode{unordered_multiset} 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_multiset}% +\begin{codeblock} +namespace std { + template, + class Pred = equal_to, + class Allocator = allocator> + class unordered_multiset { + public: + // types + using key_type = Key; + using value_type = Key; + using hasher = Hash; + using key_equal = Pred; + 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 = @\impdefx{type of \tcode{unordered_multiset::size_type}}@; // see \ref{container.requirements} + using difference_type = @\impdefx{type of \tcode{unordered_multiset::difference_type}}@; // see \ref{container.requirements} + + using iterator = @\impdefx{type of \tcode{unordered_multiset::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{unordered_multiset::const_iterator}}@; // see \ref{container.requirements} + using local_iterator = @\impdefx{type of \tcode{unordered_multiset::local_iterator}}@; // see \ref{container.requirements} + using const_local_iterator = @\impdefx{type of \tcode{unordered_multiset::const_local_it\-erator}}@; // see \ref{container.requirements} + using node_type = @\unspec@; + + // \ref{unord.multiset.cnstr}, construct/copy/destroy + 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 + 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> + 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) { } + constexpr unordered_multiset(size_type n, const hasher& hf, const allocator_type& a) + : unordered_multiset(n, hf, key_equal(), a) { } + template + constexpr unordered_multiset(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) + : unordered_multiset(f, l, n, hasher(), key_equal(), a) { } + template + 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> + 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> + 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) { } + constexpr unordered_multiset(initializer_list il, size_type n, + const allocator_type& a) + : unordered_multiset(il, n, hasher(), key_equal(), 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) { } + 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); + constexpr unordered_multiset& operator=(initializer_list); + constexpr allocator_type get_allocator() const noexcept; + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // modifiers + 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> + 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) + requires (!@\libconcept{same_as}@); + 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); + constexpr void clear() noexcept; + + template + constexpr void merge(unordered_multiset& source); + template + constexpr void merge(unordered_multiset&& source); + template + constexpr void merge(unordered_set& source); + template + constexpr void merge(unordered_set&& source); + + // observers + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; + + // set operations + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; + template + constexpr iterator find(const K& k); + template + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; + template + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; + template + 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 + constexpr pair equal_range(const K& k); + template + constexpr pair equal_range(const K& k) const; + + // bucket interface + 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 + 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, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multiset<@\placeholder{iter-value-type}@, + Hash, Pred, Allocator>; + + template>, + class Pred = equal_to>, + class Allocator = allocator>> + unordered_multiset(from_range_t, R&&, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multiset, Hash, Pred, Allocator>; + + template, + class Pred = equal_to, class Allocator = allocator> + unordered_multiset(initializer_list, typename @\seebelow@::size_type = @\seebelow@, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multiset; + + template + unordered_multiset(InputIterator, InputIterator, typename @\seebelow@::size_type, Allocator) + -> unordered_multiset<@\placeholder{iter-value-type}@, + hash<@\placeholder{iter-value-type}@>, + equal_to<@\placeholder{iter-value-type}@>, + Allocator>; + + template + unordered_multiset(InputIterator, InputIterator, typename @\seebelow@::size_type, + Hash, Allocator) + -> unordered_multiset<@\placeholder{iter-value-type}@, Hash, + equal_to<@\placeholder{iter-value-type}@>, + Allocator>; + + template + unordered_multiset(from_range_t, R&&, typename @\seebelow@::size_type, Allocator) + -> unordered_multiset, hash>, + equal_to>, Allocator>; + + template + unordered_multiset(from_range_t, R&&, Allocator) + -> unordered_multiset, hash>, + equal_to>, Allocator>; + + template + unordered_multiset(from_range_t, R&&, typename @\seebelow@::size_type, Hash, Allocator) + -> unordered_multiset, Hash, equal_to>, + Allocator>; + + template + unordered_multiset(initializer_list, typename @\seebelow@::size_type, Allocator) + -> unordered_multiset, equal_to, Allocator>; + + template + unordered_multiset(initializer_list, typename @\seebelow@::size_type, Hash, Allocator) + -> unordered_multiset, Allocator>; +} +\end{codeblock} + +\pnum +A \tcode{size_type} parameter type in an \tcode{unordered_multiset} deduction guide +refers to the \tcode{size_type} member type of +the type deduced by the deduction guide. + +\rSec3[unord.multiset.cnstr]{Constructors} + +\indexlibraryctor{unordered_multiset}% +\begin{itemdecl} +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} +\pnum +\effects +Constructs an empty \tcode{unordered_multiset} using the +specified hash function, key equality predicate, and allocator, and +using at least \tcode{n} buckets. For the default constructor, +the number of buckets is \impldef{default number of buckets in +\tcode{unordered_multiset}}. +\tcode{max_load_factor()} returns \tcode{1.0}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\indexlibraryctor{unordered_multiset}% +\begin{itemdecl} +template + 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> + 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} +\pnum +\effects +Constructs an empty \tcode{unordered_multiset} using the +specified hash function, key equality predicate, and allocator, and +using at least \tcode{n} buckets. If \tcode{n} is not +provided, the number of buckets is \impldef{default number of buckets in +\tcode{unordered_multiset}}. Then +inserts elements from the range \range{f}{l}, \tcode{rg}, or \tcode{il}, +respectively. +\tcode{max_load_factor()} returns \tcode{1.0}. + +\pnum +\complexity +Average case linear, worst case quadratic. +\end{itemdescr} + +\rSec3[unord.multiset.erasure]{Erasure} + +\indexlibrarymember{erase_if}{unordered_multiset}% +\begin{itemdecl} +template + constexpr typename unordered_multiset::size_type + erase_if(unordered_multiset& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); +\end{codeblock} +\end{itemdescr} + +\rSec1[container.adaptors]{Container adaptors} + +\rSec2[container.adaptors.general]{General} + +\pnum +The headers +\libheaderref{queue}, +\libheaderref{stack}, +\libheaderrefx{flat_map}{flat.map.syn}, +and \libheaderrefx{flat_set}{flat.set.syn} +define the container adaptors +\tcode{queue} and \tcode{priority_queue}, +\tcode{stack}, +\tcode{flat_map} and \tcode{flat_multimap}, +and \tcode{flat_set} and \tcode{flat_multiset}, +respectively. + +\pnum +Each container adaptor takes +one or more template parameters +named \tcode{Container}, \tcode{KeyContainer}, or \tcode{MappedContainer} +that denote the types of containers that the container adaptor adapts. +Each container adaptor has at least one constructor +that takes a reference argument to one or more such template parameters. +For each constructor reference argument to a container \tcode{C}, +the constructor copies the container into the container adaptor. +If \tcode{C} takes an allocator, then a compatible allocator may be passed in +to the adaptor's constructor. Otherwise, normal copy or move construction is used for the container +argument. +For the container adaptors +that take a single container template parameter \tcode{Container}, +the first template parameter \tcode{T} of the container adaptor +shall denote the same type as \tcode{Container::value_type}. + +\pnum +For container adaptors, no \tcode{swap} function throws an exception unless that +exception is thrown by the swap of the adaptor's +\tcode{Container}, +\tcode{KeyContainer}, +\tcode{MappedContainer}, or +\tcode{Compare} object (if any). + +\pnum +A constructor template of a container adaptor +shall not participate in overload resolution +if it has an \tcode{InputIterator} template parameter and +a type that does not qualify as an input iterator is deduced for that parameter. + +\pnum +For container adaptors that have them, +the \tcode{insert}, \tcode{emplace}, and \tcode{erase} members +affect the validity of iterators, references, and pointers +to the adaptor's container(s) in the same way that +the containers' respective +\tcode{insert}, \tcode{emplace}, and \tcode{erase} members do. +\begin{example} +A call to \tcode{flat_map::insert} +can invalidate all iterators to the \tcode{flat_map}. +\end{example} + +\pnum +A deduction guide for a container adaptor shall not participate in overload resolution if any of the following are true: +\begin{itemize} +\item It has an \tcode{InputIterator} template parameter and a type that does not qualify as an input iterator is deduced for that parameter. +\item It has a \tcode{Compare} template parameter and a type that qualifies as an allocator is deduced for that parameter. +\item It has a \tcode{Container}, \tcode{KeyContainer}, or \tcode{MappedContainer} template parameter and a type that qualifies as an allocator is deduced for that parameter. +\item It has no \tcode{Container}, \tcode{KeyContainer}, or \tcode{MappedContainer} template parameter, and it has an \tcode{Allocator} template parameter, and a type that does not qualify as an allocator is deduced for that parameter. +\item It has both \tcode{Container} and \tcode{Allocator} template parameters, and \tcode{uses_allocator_v} is \tcode{false}. +\item It has both \tcode{KeyContainer} and \tcode{Allocator} template parameters, and +\tcode{uses_allocator_v} is \tcode{false}. +\item It has both \tcode{KeyContainer} and \tcode{Compare} template parameters, and +\begin{codeblock} +is_invocable_v +\end{codeblock} +is not a valid expression or is \tcode{false}. +\item It has both \tcode{MappedContainer} and \tcode{Allocator} template parameters, and +\tcode{uses_allocator_v} is \tcode{false}. +\end{itemize} + +\pnum +The exposition-only alias template \exposid{iter-value-type} +defined in \ref{sequences.general} and +the exposition-only alias templates \exposid{iter-key-type}, \exposid{iter-mapped-type}, +\exposid{range-key-type}, and \exposid{range-mapped-type} +defined in \ref{associative.general} +may appear in deduction guides for container adaptors. + +\pnum +The following exposition-only alias template +may appear in deduction guides for container adaptors: +\begin{codeblock} +template + using @\exposid{alloc-rebind}@ = allocator_traits::template rebind_alloc; // \expos +\end{codeblock} + +\rSec2[queue.syn]{Header \tcode{} synopsis} + +\indexheader{queue} +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{queue}, class template \tcode{queue} + template> class queue; + + template + constexpr bool operator==(const queue& x, const queue& y); + template + constexpr bool operator!=(const queue& x, const queue& y); + template + constexpr bool operator< (const queue& x, const queue& y); + template + constexpr bool operator> (const queue& x, const queue& y); + template + constexpr bool operator<=(const queue& x, const queue& y); + template + constexpr bool operator>=(const queue& x, const queue& y); + template + constexpr compare_three_way_result_t + operator<=>(const queue& x, const queue& y); + + template + constexpr void swap(queue& x, queue& y) + noexcept(noexcept(x.swap(y))); + template + struct uses_allocator, Alloc>; + + // \ref{container.adaptors.format}, formatter specialization for \tcode{queue} + template Container> + struct formatter, charT>; + + template + constexpr bool enable_nonlocking_formatter_optimization> = false; + + // \ref{priority.queue}, class template \tcode{priority_queue} + template, + class Compare = less> + class priority_queue; + + template + 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} + +\rSec2[queue]{Class template \tcode{queue}} + +\rSec3[queue.defn]{Definition} + +\pnum +\indexlibraryglobal{queue}% +Any sequence container supporting operations +\tcode{front()}, +\tcode{back()}, +\tcode{push_back()} +and +\tcode{pop_front()} +can be used to instantiate +\tcode{queue}. +In particular, +\tcode{list}\iref{list} +and +\tcode{deque}\iref{deque} +can be used. + +\begin{codeblock} +namespace std { + template> + class queue { + public: + 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: + 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 + constexpr queue(InputIterator first, InputIterator last, const Alloc&); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + 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 + constexpr decltype(auto) emplace(Args&&... args) + { return c.emplace_back(std::forward(args)...); } + constexpr void pop() { c.pop_front(); } + constexpr void swap(queue& q) noexcept(is_nothrow_swappable_v) + { using std::swap; swap(c, q.c); } + }; + + template + queue(Container) -> queue; + + template + queue(InputIterator, InputIterator) -> queue<@\exposid{iter-value-type}@>; + + template + queue(from_range_t, R&&) -> queue>; + + template + queue(Container, Allocator) -> queue; + + template + queue(InputIterator, InputIterator, Allocator) + -> queue<@\exposid{iter-value-type}@, deque<@\exposid{iter-value-type}@, + Allocator>>; + + template + queue(from_range_t, R&&, Allocator) + -> queue, deque, Allocator>>; + + template + struct uses_allocator, Alloc> + : uses_allocator::type { }; +} +\end{codeblock} + +\rSec3[queue.cons]{Constructors} + +\indexlibraryctor{queue}% +\begin{itemdecl} +constexpr explicit queue(const Container& cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{cont}. +\end{itemdescr} + +\indexlibraryctor{queue}% +\begin{itemdecl} +constexpr explicit queue(Container&& cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{std::move(cont)}. +\end{itemdescr} + +\indexlibraryctor{queue}% +\begin{itemdecl} +template + constexpr queue(InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with +\tcode{first} as the first argument and \tcode{last} as the second argument. +\end{itemdescr} + +\indexlibraryctor{queue}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr queue(from_range_t, R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{ranges::to(std::forward(rg))}. +\end{itemdescr} + +\rSec3[queue.cons.alloc]{Constructors with allocators} + +\pnum +If \tcode{uses_allocator_v} is \tcode{false} +the constructors in this subclause shall not participate in overload resolution. + +\indexlibraryctor{queue}% +\begin{itemdecl} +template constexpr explicit queue(const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{a}. +\end{itemdescr} + +\indexlibraryctor{queue}% +\begin{itemdecl} +template constexpr queue(const container_type& cont, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{cont} as the first argument and \tcode{a} +as the second argument. +\end{itemdescr} + +\indexlibraryctor{queue}% +\begin{itemdecl} +template constexpr queue(container_type&& cont, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{std::move(cont)} as the first argument and \tcode{a} +as the second argument. +\end{itemdescr} + +\indexlibraryctor{queue}% +\begin{itemdecl} +template constexpr queue(const queue& q, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{q.c} as the first argument and \tcode{a} as the +second argument. +\end{itemdescr} + +\indexlibraryctor{queue}% +\begin{itemdecl} +template constexpr queue(queue&& q, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{std::move(q.c)} as the first argument and \tcode{a} +as the second argument. +\end{itemdescr} + +\indexlibraryctor{queue}% +\begin{itemdecl} +template + constexpr queue(InputIterator first, InputIterator last, const Alloc& alloc); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with +\tcode{first} as the first argument, +\tcode{last} as the second argument, and +\tcode{alloc} as the third argument. +\end{itemdescr} + +\indexlibraryctor{queue}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr queue(from_range_t, R&& rg, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with +\tcode{ranges::to(std::forward(rg), a)}. +\end{itemdescr} + +\rSec3[queue.mod]{Modifiers} + +\indexlibrarymember{push_range}{queue}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr void push_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{c.append_range(std::forward(rg))} +if that is a valid expression, +otherwise \tcode{ranges::copy(rg, back_inserter(c))}. +\end{itemdescr} + +\rSec3[queue.ops]{Operators} + +\indexlibrarymember{operator==}{queue}% +\begin{itemdecl} +template + constexpr bool operator==(const queue& x, const queue& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c == y.c}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator"!=}!\idxcode{queue}}% +\begin{itemdecl} +template + constexpr bool operator!=(const queue& x, const queue& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c != y.c}. +\end{itemdescr} + +\indexlibrarymember{operator<}{queue}% +\begin{itemdecl} +template + constexpr bool operator< (const queue& x, const queue& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c < y.c}. +\end{itemdescr} + +\indexlibrarymember{operator>}{queue}% +\begin{itemdecl} +template + constexpr bool operator> (const queue& x, const queue& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c > y.c}. +\end{itemdescr} + +\indexlibrarymember{operator<=}{queue}% +\begin{itemdecl} +template + constexpr bool operator<=(const queue& x, const queue& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c <= y.c}. +\end{itemdescr} + +\indexlibrarymember{operator>=}{queue}% +\begin{itemdecl} +template + constexpr bool operator>=(const queue& x, const queue& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c >= y.c}. +\end{itemdescr} + +\indexlibrarymember{operator<=>}{queue}% +\begin{itemdecl} +template + constexpr compare_three_way_result_t + operator<=>(const queue& x, const queue& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c <=> y.c}. +\end{itemdescr} + +\rSec3[queue.special]{Specialized algorithms} + +\indexlibrarymember{swap}{queue}% +\begin{itemdecl} +template + constexpr void swap(queue& x, queue& y) + noexcept(noexcept(x.swap(y))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_swappable_v} is \tcode{true}. + +\pnum +\effects +As if by \tcode{x.swap(y)}. +\end{itemdescr} + +\rSec2[priority.queue]{Class template \tcode{priority_queue}} + +\rSec3[priqueue.overview]{Overview} + +\pnum +\indexlibraryglobal{priority_queue}% +Any sequence container with random access iterator and supporting operations +\tcode{front()}, +\tcode{push_back()} +and +\tcode{pop_back()} +can be used to instantiate +\tcode{priority_queue}. +In particular, +\tcode{vector}\iref{vector} +and +\tcode{deque}\iref{deque} +can be used. +Instantiating +\tcode{priority_queue} +also involves supplying a function or function object for making +priority comparisons; the library assumes that the function or function +object defines a strict weak ordering\iref{alg.sorting}. + +\begin{codeblock} +namespace std { + template, + class Compare = less> + class priority_queue { + public: + 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; + + protected: + Container c; + Compare comp; + + public: + 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 + constexpr priority_queue(InputIterator first, InputIterator last, + const Compare& x = Compare()); + template + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + const Container&); + template + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + Container&&); + template<@\exposconcept{container-compatible-range}@ R> + 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 + constexpr priority_queue(InputIterator, InputIterator, const Alloc&); + template + constexpr priority_queue(InputIterator, InputIterator, const Compare&, const Alloc&); + template + constexpr priority_queue(InputIterator, InputIterator, const Compare&, const Container&, + const Alloc&); + template + constexpr priority_queue(InputIterator, InputIterator, const Compare&, Container&&, + const Alloc&); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr priority_queue(from_range_t, R&& rg, const Alloc&); + + 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> + 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); } + }; + + template + priority_queue(Compare, Container) + -> priority_queue; + + template>, + class Container = vector<@\exposid{iter-value-type}@>> + priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container()) + -> priority_queue<@\exposid{iter-value-type}@, Container, Compare>; + + template>> + priority_queue(from_range_t, R&&, Compare = Compare()) + -> priority_queue, vector>, Compare>; + + template + priority_queue(Compare, Container, Allocator) + -> priority_queue; + + template + priority_queue(InputIterator, InputIterator, Allocator) + -> priority_queue<@\exposid{iter-value-type}@, + vector<@\exposid{iter-value-type}@, Allocator>, + less<@\exposid{iter-value-type}@>>; + + template + priority_queue(InputIterator, InputIterator, Compare, Allocator) + -> priority_queue<@\exposid{iter-value-type}@, + vector<@\exposid{iter-value-type}@, Allocator>, Compare>; + + template + priority_queue(InputIterator, InputIterator, Compare, Container, Allocator) + -> priority_queue; + + template + priority_queue(from_range_t, R&&, Compare, Allocator) + -> priority_queue, vector, Allocator>, + Compare>; + + template + priority_queue(from_range_t, R&&, Allocator) + -> priority_queue, vector, Allocator>>; + + // no equality is provided + + template + struct uses_allocator, Alloc> + : uses_allocator::type { }; +} +\end{codeblock} + +\rSec3[priqueue.cons]{Constructors} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +constexpr priority_queue(const Compare& x, const Container& y); +constexpr priority_queue(const Compare& x, Container&& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{x} defines a strict weak ordering\iref{alg.sorting}. + +\pnum +\effects +Initializes +\tcode{comp} with +\tcode{x} and +\tcode{c} with +\tcode{y} (copy constructing or move constructing as appropriate); +calls +\tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{x} defines a strict weak ordering\iref{alg.sorting}. + +\pnum +\effects +Initializes \tcode{c} with +\tcode{first} as the first argument and +\tcode{last} as the second argument, and +initializes \tcode{comp} with \tcode{x}; +then calls \tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + const Container& y); +template + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + Container&& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{x} defines a strict weak ordering\iref{alg.sorting}. + +\pnum +\effects +Initializes +\tcode{comp} with +\tcode{x} and +\tcode{c} with +\tcode{y} (copy constructing or move constructing as appropriate); +calls +\tcode{c.insert(c.end(), first, last)}; +and finally calls +\tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{x} defines a strict weak ordering\iref{alg.sorting}. + +\pnum +\effects +Initializes \tcode{comp} with \tcode{x} and +\tcode{c} with \tcode{ranges::to(std::forward(rg))} and +finally calls \tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\rSec3[priqueue.cons.alloc]{Constructors with allocators} + +\pnum +If \tcode{uses_allocator_v} is \tcode{false} +the constructors in this subclause shall not participate in overload resolution. + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template constexpr explicit priority_queue(const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{a} and value-initializes \tcode{comp}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template constexpr priority_queue(const Compare& compare, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{a} and initializes \tcode{comp} with \tcode{compare}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template + constexpr priority_queue(const Compare& compare, const Container& cont, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{cont} as the first argument and \tcode{a} as the second +argument, and initializes \tcode{comp} with \tcode{compare}; +calls \tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template + constexpr priority_queue(const Compare& compare, Container&& cont, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{std::move(cont)} as the first argument and \tcode{a} +as the second argument, and initializes \tcode{comp} with \tcode{compare}; +calls \tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template constexpr priority_queue(const priority_queue& q, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{q.c} as the first argument and \tcode{a} as +the second argument, and initializes \tcode{comp} with \tcode{q.comp}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template constexpr priority_queue(priority_queue&& q, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{std::move(q.c)} as the first argument and \tcode{a} +as the second argument, and initializes \tcode{comp} with \tcode{std::move(q.comp)}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template + constexpr priority_queue(InputIterator first, InputIterator last, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with +\tcode{first} as the first argument, +\tcode{last} as the second argument, and +\tcode{a} as the third argument, and +value-initializes \tcode{comp}; +calls \tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template + constexpr priority_queue(InputIterator first, InputIterator last, + const Compare& compare, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with +\tcode{first} as the first argument, +\tcode{last} as the second argument, and +\tcode{a} as the third argument, and +initializes \tcode{comp} with \tcode{compare}; +calls \tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& compare, + const Container& cont, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with +\tcode{cont} as the first argument and \tcode{a} as the second argument, and +initializes \tcode{comp} with \tcode{compare}; +calls \tcode{c.insert(c.end(), first, last)}; and +finally calls \tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& compare, + Container&& cont, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with +\tcode{std::move(cont)} as the first argument and +\tcode{a} as the second argument, and +initializes \tcode{comp} with \tcode{compare}; +calls \tcode{c.insert(c.end(), first, last)}; and +finally calls \tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr priority_queue(from_range_t, R&& rg, const Compare& compare, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{comp} with \tcode{compare} and +\tcode{c} with \tcode{ranges::to(std::forward(rg), a)}; +calls \tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\indexlibraryctor{priority_queue}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr priority_queue(from_range_t, R&& rg, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes +\tcode{c} with \tcode{ranges::to(std::forward(rg), a)} +and value-initializes \tcode{comp}; +calls \tcode{make_heap(c.begin(), c.end(), comp)}. +\end{itemdescr} + +\rSec3[priqueue.members]{Members} + +\indexlibrarymember{push}{priority_queue}% +\begin{itemdecl} +constexpr void push(const value_type& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: +\begin{codeblock} +c.push_back(x); +push_heap(c.begin(), c.end(), comp); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{push}{priority_queue}% +\begin{itemdecl} +constexpr void push(value_type&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: +\begin{codeblock} +c.push_back(std::move(x)); +push_heap(c.begin(), c.end(), comp); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{push_range}{priority_queue}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr void push_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Inserts all elements of \tcode{rg} in \tcode{c} via +\tcode{c.append_range(std::forward(rg))} if that is a valid expression, or +\tcode{ranges::copy(rg, back_inserter(c))} otherwise. +Then restores the heap property as if by +\tcode{make_heap(c.begin(), c.end(), comp)}. + +\pnum +\ensures +\tcode{is_heap(c.begin(), c.end(), comp)} is \tcode{true}. +\end{itemdescr} + +\indexlibrarymember{emplace}{priority_queue}% +\begin{itemdecl} +template constexpr void emplace(Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: +\begin{codeblock} +c.emplace_back(std::forward(args)...); +push_heap(c.begin(), c.end(), comp); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{pop}{priority_queue}% +\begin{itemdecl} +constexpr void pop(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +As if by: +\begin{codeblock} +pop_heap(c.begin(), c.end(), comp); +c.pop_back(); +\end{codeblock} +\end{itemdescr} + +\rSec3[priqueue.special]{Specialized algorithms} + +\indexlibrarymember{swap}{priority_queue}% +\begin{itemdecl} +template + constexpr void swap(priority_queue& x, + priority_queue& y) noexcept(noexcept(x.swap(y))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_swappable_v} is \tcode{true} and +\tcode{is_swappable_v} is \tcode{true}. + +\pnum +\effects +As if by \tcode{x.swap(y)}. +\end{itemdescr} + +\rSec2[stack.syn]{Header \tcode{} synopsis} + +\indexheader{stack}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{stack}, class template \tcode{stack} + template> class stack; + + template + constexpr bool operator==(const stack& x, const stack& y); + template + constexpr bool operator!=(const stack& x, const stack& y); + template + constexpr bool operator< (const stack& x, const stack& y); + template + constexpr bool operator> (const stack& x, const stack& y); + template + constexpr bool operator<=(const stack& x, const stack& y); + template + constexpr bool operator>=(const stack& x, const stack& y); + template + constexpr compare_three_way_result_t + operator<=>(const stack& x, const stack& y); + + template + constexpr void swap(stack& x, stack& y) + noexcept(noexcept(x.swap(y))); + template + struct uses_allocator, Alloc>; + + // \ref{container.adaptors.format}, formatter specialization for \tcode{stack} + template Container> + struct formatter, charT>; + + template + constexpr bool enable_nonlocking_formatter_optimization> = false; +} +\end{codeblock} + +\rSec2[stack]{Class template \tcode{stack}} + +\rSec3[stack.general]{General} + +\pnum +\indexlibraryglobal{stack}% +Any sequence container supporting operations +\tcode{back()}, +\tcode{push_back()} +and +\tcode{pop_back()} +can be used to instantiate +\tcode{stack}. +In particular, +\tcode{vector}\iref{vector}, +\tcode{list}\iref{list} +and +\tcode{deque}\iref{deque} +can be used. + +\rSec3[stack.defn]{Definition} + +\begin{codeblock} +namespace std { + template> + class stack { + public: + 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: + 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 + constexpr stack(InputIterator first, InputIterator last, const Alloc&); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + 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> + constexpr void push_range(R&& rg); + template + constexpr decltype(auto) emplace(Args&&... args) + { return c.emplace_back(std::forward(args)...); } + constexpr void pop() { c.pop_back(); } + constexpr void swap(stack& s) noexcept(is_nothrow_swappable_v) + { using std::swap; swap(c, s.c); } + }; + + template + stack(Container) -> stack; + + template + stack(InputIterator, InputIterator) -> stack<@\exposid{iter-value-type}@>; + + template + stack(from_range_t, R&&) -> stack>; + + template + stack(Container, Allocator) -> stack; + + template + stack(InputIterator, InputIterator, Allocator) + -> stack<@\exposid{iter-value-type}@, deque<@\exposid{iter-value-type}@, + Allocator>>; + + template + stack(from_range_t, R&&, Allocator) + -> stack, deque, Allocator>>; + + template + struct uses_allocator, Alloc> + : uses_allocator::type { }; +} +\end{codeblock} + +\rSec3[stack.cons]{Constructors} + +\indexlibraryctor{stack}% +\begin{itemdecl} +constexpr explicit stack(const Container& cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{cont}. +\end{itemdescr} + +\indexlibraryctor{stack}% +\begin{itemdecl} +constexpr explicit stack(Container&& cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{std::move(cont)}. +\end{itemdescr} + +\indexlibraryctor{stack}% +\begin{itemdecl} +template + constexpr stack(InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with +\tcode{first} as the first argument and \tcode{last} as the second argument. +\end{itemdescr} + +\indexlibraryctor{stack}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr stack(from_range_t, R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{ranges::to(std::forward(rg))}. +\end{itemdescr} + +\rSec3[stack.cons.alloc]{Constructors with allocators} + +\pnum +If \tcode{uses_allocator_v} is \tcode{false} +the constructors in this subclause shall not participate in overload resolution. + +\indexlibraryctor{stack}% +\begin{itemdecl} +template constexpr explicit stack(const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{a}. +\end{itemdescr} + +\indexlibraryctor{stack}% +\begin{itemdecl} +template constexpr stack(const container_type& cont, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{cont} as the first argument and \tcode{a} as the +second argument. +\end{itemdescr} + +\indexlibraryctor{stack}% +\begin{itemdecl} +template constexpr stack(container_type&& cont, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{std::move(cont)} as the first argument and \tcode{a} +as the second argument. +\end{itemdescr} + +\indexlibraryctor{stack}% +\begin{itemdecl} +template constexpr stack(const stack& s, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{s.c} as the first argument and \tcode{a} +as the second argument. +\end{itemdescr} + +\indexlibraryctor{stack}% +\begin{itemdecl} +template constexpr stack(stack&& s, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with \tcode{std::move(s.c)} as the first argument and \tcode{a} +as the second argument. +\end{itemdescr} + +\indexlibraryctor{stack}% +\begin{itemdecl} +template + constexpr stack(InputIterator first, InputIterator last, const Alloc& alloc); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes \tcode{c} with +\tcode{first} as the first argument, +\tcode{last} as the second argument, and +\tcode{alloc} as the third argument. +\end{itemdescr} + +\indexlibraryctor{stack}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr stack(from_range_t, R&& rg, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes +\tcode{c} with \tcode{ranges::to(std::forward(rg), a)}. +\end{itemdescr} + +\rSec3[stack.mod]{Modifiers} + +\indexlibrarymember{push_range}{stack}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr void push_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{c.append_range(std::forward(rg))} +if that is a valid expression, +otherwise \tcode{ranges::copy(rg, back_inserter(c))}. +\end{itemdescr} + +\rSec3[stack.ops]{Operators} + +\indexlibrarymember{operator==}{stack}% +\begin{itemdecl} +template + constexpr bool operator==(const stack& x, const stack& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c == y.c}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator"!=}!\idxcode{stack}}% +\begin{itemdecl} +template + constexpr bool operator!=(const stack& x, const stack& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c != y.c}. +\end{itemdescr} + +\indexlibrarymember{operator<}{stack}% +\begin{itemdecl} +template + constexpr bool operator< (const stack& x, const stack& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c < y.c}. +\end{itemdescr} + +\indexlibrarymember{operator>}{stack}% +\begin{itemdecl} +template + constexpr bool operator> (const stack& x, const stack& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c > y.c}. +\end{itemdescr} + +\indexlibrarymember{operator<=}{stack}% +\begin{itemdecl} +template + constexpr bool operator<=(const stack& x, const stack& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c <= y.c}. +\end{itemdescr} + +\indexlibrarymember{operator>=}{stack}% +\begin{itemdecl} +template + constexpr bool operator>=(const stack& x, const stack& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c >= y.c}. +\end{itemdescr} + +\indexlibrarymember{operator<=>}{stack}% +\begin{itemdecl} +template + constexpr compare_three_way_result_t + operator<=>(const stack& x, const stack& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.c <=> y.c}. +\end{itemdescr} + +\rSec3[stack.special]{Specialized algorithms} + +\indexlibrarymember{swap}{stack}% +\begin{itemdecl} +template + constexpr void swap(stack& x, stack& y) + noexcept(noexcept(x.swap(y))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_swappable_v} is \tcode{true}. + +\pnum +\effects +As if by \tcode{x.swap(y)}. +\end{itemdescr} + +\rSec2[flat.map.syn]{Header \tcode{} synopsis} + +\indexheader{flat_map}% +\begin{codeblock} +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{flat.map}, class template \tcode{flat_map} + template, + class KeyContainer = vector, class MappedContainer = vector> + class flat_map; + + struct sorted_unique_t { explicit sorted_unique_t() = default; }; + inline constexpr sorted_unique_t sorted_unique{}; + + template + struct uses_allocator, + Allocator>; + + // \ref{flat.map.erasure}, erasure for \tcode{flat_map} + template + constexpr typename flat_map::size_type + erase_if(flat_map& c, Predicate pred); + + // \ref{flat.multimap}, class template \tcode{flat_multimap} + template, + class KeyContainer = vector, class MappedContainer = vector> + class flat_multimap; + + struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; + inline constexpr sorted_equivalent_t sorted_equivalent{}; + + template + struct uses_allocator, + Allocator>; + + // \ref{flat.multimap.erasure}, erasure for \tcode{flat_multimap} + template + constexpr typename flat_multimap::size_type + erase_if(flat_multimap& c, Predicate pred); +} +\end{codeblock} + +\rSec2[flat.map]{Class template \tcode{flat_map}} + +\rSec3[flat.map.overview]{Overview} + +\pnum +\indexlibraryglobal{flat_map}% +A \tcode{flat_map} is a container adaptor +that provides an associative container interface +that supports unique keys +(i.e., contains at most one of each key value) and +provides for fast retrieval of values of another type \tcode{T} +based on the keys. +\tcode{flat_map} supports iterators +that meet the \oldconcept{InputIterator} requirements and +model the +\libconcept{random_access_iterator} concept\iref{iterator.concept.random.access}. + +\pnum +A \tcode{flat_map} meets all of the requirements +of a container\iref{container.reqmts} and +of a reversible container\iref{container.rev.reqmts}, +plus the optional container requirements\iref{container.opt.reqmts}. +\tcode{flat_map} meets the requirements of +an associative container\iref{associative.reqmts}, +except that: +\begin{itemize} +\item +it does not meet the requirements related to node handles\iref{container.node}, +\item +it does not meet the requirements related to iterator invalidation, and +\item +the time complexity of the operations that insert or erase a single +element from the map is linear, including the ones that take an insertion +position iterator. +\end{itemize} +\begin{note} +A \tcode{flat_map} does not meet the additional requirements of +an allocator-aware container\iref{container.alloc.reqmts}. +\end{note} + +\pnum +A \tcode{flat_map} also provides most operations +described in \ref{associative.reqmts} for unique keys. +This means that a \tcode{flat_map} supports +the \tcode{a_uniq} operations in \ref{associative.reqmts} +but not the \tcode{a_eq} operations. +For a \tcode{flat_map} +the \tcode{key_type} is \tcode{Key} and +the \tcode{value_type} is \tcode{pair}. + +\pnum +Descriptions are provided here only for operations on \tcode{flat_map} that +are not described in one of those sets of requirements or for operations where +there is additional semantic information. + +\pnum +A \tcode{flat_map} maintains the following invariants: +\begin{itemize} +\item +it contains the same number of keys and values; +\item +the keys are sorted with respect to the comparison object; and +\item +the value at offset \tcode{off} within the value container is +the value associated with the key at offset \tcode{off} +within the key container. +\end{itemize} + +\pnum +If any member function in \ref{flat.map.defn} exits via an exception +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} + +\pnum +Any type \tcode{C} +that meets the sequence container requirements\iref{sequence.reqmts} +can be used to instantiate \tcode{flat_map}, +as long as +\tcode{C::iterator} meets the \oldconcept{RandomAccessIterator} requirements and +invocations of +member functions \tcode{C::size} and \tcode{C::max_size} do not exit via an exception. +In particular, \tcode{vector}\iref{vector} and \tcode{deque}\iref{deque} +can be used. +\begin{note} +\tcode{vector} is not a sequence container. +\end{note} + +\pnum +The program is ill-formed if +\tcode{Key} is not the same type as \tcode{KeyContainer::value_type} or +\tcode{T} is not the same type as \tcode{MappedContainer::value_type}. + +\pnum +The effect of calling a constructor +that takes +both \tcode{key_container_type} and \tcode{mapped_container_type} arguments with +containers of different sizes is undefined. + +\pnum +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} +namespace std { + template, + class KeyContainer = vector, class MappedContainer = vector> + class flat_map { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = pair; + using key_compare = Compare; + using reference = pair; + using const_reference = pair; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator = @\impdefx{type of \tcode{flat_map::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{flat_map::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using key_container_type = KeyContainer; + using mapped_container_type = MappedContainer; + + class value_compare { + private: + key_compare @\exposid{comp}@; // \expos + constexpr value_compare(key_compare c) : @\exposid{comp}@(c) { } // \expos + + public: + constexpr bool operator()(const_reference x, const_reference y) const { + return @\exposid{comp}@(x.first, y.first); + } + }; + + struct containers { + key_container_type keys; + mapped_container_type values; + }; + + // \ref{flat.map.cons}, constructors + constexpr flat_map() : flat_map(key_compare()) { } + + 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) { } + + constexpr flat_map(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); + + constexpr flat_map(sorted_unique_t, key_container_type key_cont, + mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); + + template + constexpr flat_map(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } + + template + 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> + constexpr flat_map(from_range_t, R&& rg) + : flat_map(from_range, std::forward(rg), key_compare()) { } + template<@\exposconcept{container-compatible-range}@ R> + constexpr flat_map(from_range_t, R&& rg, const key_compare& comp) + : flat_map(comp) { insert_range(std::forward(rg)); } + + constexpr flat_map(initializer_list il, const key_compare& comp = key_compare()) + : flat_map(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 + constexpr explicit flat_map(const Alloc& a); + template + constexpr flat_map(const key_compare& comp, const Alloc& a); + template + constexpr flat_map(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const Alloc& a); + template + constexpr flat_map(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); + template + constexpr flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); + template + constexpr flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const key_compare& comp, + const Alloc& a); + template + constexpr flat_map(const flat_map&, const Alloc& a); + template + constexpr flat_map(flat_map&&, const Alloc& a); + template + constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a); + template + constexpr flat_map(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const Alloc& a); + template + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_map(from_range_t, R&& rg, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + template + constexpr flat_map(initializer_list il, const Alloc& a); + template + constexpr flat_map(initializer_list il, const key_compare& comp, + const Alloc& a); + template + constexpr flat_map(sorted_unique_t, initializer_list il, const Alloc& a); + template + constexpr flat_map(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); + + constexpr flat_map& operator=(initializer_list); + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // \ref{flat.map.capacity}, capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // \ref{flat.map.access}, element access + constexpr mapped_type& operator[](const key_type& x); + constexpr mapped_type& operator[](key_type&& x); + template constexpr mapped_type& operator[](K&& x); + constexpr mapped_type& at(const key_type& x); + constexpr const mapped_type& at(const key_type& x) const; + template constexpr mapped_type& at(const K& x); + template constexpr const mapped_type& at(const K& x) const; + + // \ref{flat.map.modifiers}, modifiers + template constexpr pair emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + + constexpr pair insert(const value_type& x) + { return emplace(x); } + constexpr pair insert(value_type&& x) + { return emplace(std::move(x)); } + constexpr iterator insert(const_iterator position, const value_type& x) + { return emplace_hint(position, x); } + constexpr iterator insert(const_iterator position, value_type&& x) + { return emplace_hint(position, std::move(x)); } + + template constexpr pair insert(P&& x); + template + constexpr iterator insert(const_iterator position, P&&); + template + constexpr void insert(InputIterator first, InputIterator last); + template + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(R&& rg); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(sorted_unique_t, R&& rg); + + constexpr void insert(initializer_list il) + { insert(il.begin(), il.end()); } + constexpr void insert(sorted_unique_t, initializer_list il) + { insert(sorted_unique, il.begin(), il.end()); } + + constexpr containers extract() &&; + constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); + + template + constexpr pair try_emplace(const key_type& k, Args&&... args); + template + constexpr pair try_emplace(key_type&& k, Args&&... args); + template + constexpr pair try_emplace(K&& k, Args&&... args); + template + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + template + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + template + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + template + constexpr pair insert_or_assign(const key_type& k, M&& obj); + template + constexpr pair insert_or_assign(key_type&& k, M&& obj); + template + constexpr pair insert_or_assign(K&& k, M&& obj); + template + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + template + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + template + 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(flat_map& y) noexcept(@\seebelow@); + constexpr void clear() noexcept; + + // observers + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; + + constexpr const key_container_type& keys() const noexcept { return @\exposid{c}@.keys; } + constexpr const mapped_container_type& values() const noexcept { return @\exposid{c}@.values; } + + // map operations + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; + + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; + + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; + + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; + + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; + + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; + template constexpr pair equal_range(const K& x); + template + constexpr pair equal_range(const K& x) const; + + friend constexpr bool operator==(const flat_map& x, const flat_map& y); + + friend constexpr @\exposid{synth-three-way-result}@ + operator<=>(const flat_map& x, const flat_map& y); + + friend constexpr void swap(flat_map& x, flat_map& y) noexcept(noexcept(x.swap(y))) + { x.swap(y); } + + private: + containers @\exposid{c}@; // \expos + key_compare @\exposid{compare}@; // \expos + + struct @\exposid{key-equiv}@ { // \expos + constexpr @\exposid{key-equiv}@(key_compare c) : comp(c) { } + constexpr bool operator()(const_reference x, const_reference y) const { + return !comp(x.first, y.first) && !comp(y.first, x.first); + } + key_compare comp; + }; + }; + + template> + flat_map(KeyContainer, MappedContainer, Compare = Compare()) + -> flat_map; + + template + flat_map(KeyContainer, MappedContainer, Allocator) + -> flat_map, KeyContainer, MappedContainer>; + template + flat_map(KeyContainer, MappedContainer, Compare, Allocator) + -> flat_map; + + template> + flat_map(sorted_unique_t, KeyContainer, MappedContainer, Compare = Compare()) + -> flat_map; + + template + flat_map(sorted_unique_t, KeyContainer, MappedContainer, Allocator) + -> flat_map, KeyContainer, MappedContainer>; + template + flat_map(sorted_unique_t, KeyContainer, MappedContainer, Compare, Allocator) + -> flat_map; + + template>> + flat_map(InputIterator, InputIterator, Compare = Compare()) + -> flat_map<@\exposid{iter-key-type}@, @\exposid{iter-mapped-type}@, Compare>; + + template>> + flat_map(sorted_unique_t, InputIterator, InputIterator, Compare = Compare()) + -> flat_map<@\exposid{iter-key-type}@, @\exposid{iter-mapped-type}@, Compare>; + + template>, + class Allocator = allocator> + flat_map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) + -> flat_map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Compare, + vector<@\exposid{range-key-type}@, @\exposid{alloc-rebind}@>>, + vector<@\exposid{range-mapped-type}@, @\exposid{alloc-rebind}@>>>; + + template + flat_map(from_range_t, R&&, Allocator) + -> flat_map<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, less<@\exposid{range-key-type}@>, + vector<@\exposid{range-key-type}@, @\exposid{alloc-rebind}@>>, + vector<@\exposid{range-mapped-type}@, @\exposid{alloc-rebind}@>>>; + + template> + flat_map(initializer_list>, Compare = Compare()) + -> flat_map; + + template> + flat_map(sorted_unique_t, initializer_list>, Compare = Compare()) + -> flat_map; + + template + struct uses_allocator, Allocator> + : bool_constant && + uses_allocator_v> { }; +} +\end{codeblock} + +\pnum +The member type \tcode{containers} has the data members and special members +specified above. +It has no base classes or members other than those specified. + +\rSec3[flat.map.cons]{Constructors} + +\indexlibraryctor{flat_map}% +\begin{itemdecl} +constexpr flat_map(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes +\tcode{\exposid{c}.keys} with \tcode{std::move(key_cont)}, +\tcode{\exposid{c}.values} with \tcode{std::move(mapped_cont)}, and +\exposid{compare} with \tcode{comp}; +sorts the range \range{begin()}{end()} with respect to \tcode{value_comp()}; and +finally erases the duplicate elements as if by: +\begin{codeblock} +auto zv = views::zip(@\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} + +\pnum +\complexity +Linear in $N$ if the container arguments are already sorted +with respect to \tcode{value_comp()} and otherwise $N \log N$, +where $N$ is the value of \tcode{key_cont.size()} before this call. +\end{itemdescr} + +\indexlibraryctor{flat_map}% +\begin{itemdecl} +constexpr flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes +\tcode{\exposid{c}.keys} with \tcode{std::move(key_cont)}, +\tcode{\exposid{c}.values} with \tcode{std::move(mapped_cont)}, and +\exposid{compare} with \tcode{comp}. + +\pnum +\complexity +Constant. +\end{itemdescr} + +\rSec3[flat.map.cons.alloc]{Constructors with allocators} + +\pnum +The constructors in this subclause shall not participate in overload resolution +unless \tcode{uses_allocator_v} is \tcode{true} +and \tcode{uses_allocator_v} is \tcode{true}. + +\indexlibraryctor{flat_map}% +\begin{itemdecl} +template + constexpr flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const Alloc& a); +template + constexpr flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{flat_map(key_cont, mapped_cont)} and +\tcode{flat_map(key_cont, mapped_cont, comp)}, respectively, +except that \tcode{\exposid{c}.keys} and \tcode{\exposid{c}.values} are constructed with +uses-allocator construction\iref{allocator.uses.construction}. + +\pnum +\complexity +Same as \tcode{flat_map(key_cont, mapped_cont)} and +\tcode{flat_map(key_cont, mapped_cont, comp)}, respectively. +\end{itemdescr} + +\indexlibraryctor{flat_map}% +\begin{itemdecl} +template + constexpr flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); +template + constexpr flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const key_compare& comp, + const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +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}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\indexlibraryctor{flat_map}% +\begin{itemdecl} +template + constexpr explicit flat_map(const Alloc& a); +template + constexpr flat_map(const key_compare& comp, const Alloc& a); +template + constexpr flat_map(const flat_map&, const Alloc& a); +template + constexpr flat_map(flat_map&&, const Alloc& a); +template + constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_map(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); +template + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_map(from_range_t, R&& rg, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); +template + constexpr flat_map(initializer_list il, const Alloc& a); +template + constexpr flat_map(initializer_list il, const key_compare& comp, const Alloc& a); +template + constexpr flat_map(sorted_unique_t, initializer_list il, const Alloc& a); +template + constexpr flat_map(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to the corresponding non-allocator constructors +except that \tcode{\exposid{c}.keys} and \tcode{\exposid{c}.values} are constructed +with uses-allocator construction\iref{allocator.uses.construction}. +\end{itemdescr} + +\rSec3[flat.map.capacity]{Capacity} + +\indexlibrarymember{size}{flat_map}% +\begin{itemdecl} +constexpr size_type size() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{c}.keys.size()}. +\end{itemdescr} + +\indexlibrarymember{max_size}{flat_map}% +\begin{itemdecl} +constexpr size_type max_size() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{min(\exposid{c}.keys.max_size(), \exposid{c}.values.max_size())}. +\end{itemdescr} + +\rSec3[flat.map.access]{Access} + +\indexlibrarymember{operator[]}{flat_map}% +\begin{itemdecl} +constexpr mapped_type& operator[](const key_type& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return try_emplace(x).first->second;} +\end{itemdescr} + +\indexlibrarymember{operator[]}{flat_map}% +\begin{itemdecl} +constexpr mapped_type& operator[](key_type&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return try_emplace(std::move(x)).first->second;} +\end{itemdescr} + +\indexlibrarymember{operator[]}{flat_map}% +\begin{itemdecl} +template constexpr mapped_type& operator[](K&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} is valid and +denotes a type. + +\pnum +\effects +Equivalent to: \tcode{return try_emplace(std::forward(x)).first->second;} +\end{itemdescr} + +\indexlibrarymember{at}{flat_map}% +\begin{itemdecl} +constexpr mapped_type& at(const key_type& x); +constexpr const mapped_type& at(const key_type& x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A reference to the \tcode{mapped_type} corresponding +to \tcode{x} in \tcode{*this}. + +\pnum +\throws +An exception object of type \tcode{out_of_range} if +no such element is present. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\indexlibrarymember{at}{flat_map}% +\begin{itemdecl} +template constexpr mapped_type& at(const K& x); +template constexpr const mapped_type& at(const K& x) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +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 +A reference to the \tcode{mapped_type} corresponding to +\tcode{x} in \tcode{*this}. + +\pnum +\throws +An exception object of type \tcode{out_of_range} +if no such element is present. + +\pnum +\complexity +Logarithmic. +\end{itemdescr} + +\rSec3[flat.map.modifiers]{Modifiers} + +\indexlibrarymember{emplace}{flat_map}% +\begin{itemdecl} +template constexpr pair emplace(Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v, Args...>} is \tcode{true}. + +\pnum +\effects +Initializes an object \tcode{t} of type \tcode{pair} +with \tcode{std::forward(\linebreak args)...}; +if the map already contains an element +whose key is equivalent to \tcode{t.first}, +\tcode{*this} is unchanged. +Otherwise, equivalent to: +\begin{codeblock} +auto key_it = ranges::upper_bound(@\exposid{c}@.keys, t.first, @\exposid{compare}@); +auto value_it = @\exposid{c}@.values.begin() + distance(@\exposid{c}@.keys.begin(), key_it); +@\exposid{c}@.keys.insert(key_it, std::move(t.first)); +@\exposid{c}@.values.insert(value_it, std::move(t.second)); +\end{codeblock} + +\pnum +\returns +The \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place, and +the iterator component of the pair points to +the element with key equivalent to \tcode{t.first}. +\end{itemdescr} + +\indexlibrarymember{insert}{flat_map}% +\begin{itemdecl} +template constexpr pair insert(P&& x); +template constexpr iterator insert(const_iterator position, P&& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v, P>} is \tcode{true}. + +\pnum +\effects +The first form is equivalent to \tcode{return emplace(std::forward

(x));}. +The second form is equivalent to +\tcode{return emplace_hint(position, std::forward

(x));}. +\end{itemdescr} + +\indexlibrarymember{insert}{flat_map}% +\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} +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, sorts the range of newly inserted elements +with respect to \tcode{value_comp()}; +merges the resulting sorted range 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} + +\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_map}% +\begin{itemdecl} +template + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{insert(first, last)}. + +\pnum +\complexity +Linear in $N$, where $N$ is \tcode{size()} after the operation. +\end{itemdescr} + +\indexlibrarymember{insert_range}{flat_map}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(R&& rg); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Adds elements to \exposid{c} as if by: +\begin{codeblock} +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()}; +merges the resulting sorted range 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} + +\pnum +\complexity +$N$ + $M \log M$, +where $N$ is \tcode{size()} before the operation and +$M$ is \tcode{ranges::distance(rg)}. + +\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> + 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 + constexpr pair try_emplace(const key_type& k, Args&&... args); +template + constexpr pair try_emplace(key_type&& k, Args&&... args); +template + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); +template + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +If the map already contains an element whose key is equivalent to \tcode{k}, +\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 value_it = @\exposid{c}@.values.begin() + distance(@\exposid{c}@.keys.begin(), key_it); +@\exposid{c}@.keys.insert(key_it, std::forward(k)); +@\exposid{c}@.values.emplace(value_it, std::forward(args)...); +\end{codeblock} + +\pnum +\returns +In the first two overloads, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} for the first two overloads, and +the same as \tcode{emplace_hint} for the last two overloads. +\end{itemdescr} + +\indexlibrarymember{try_emplace}{flat_map}% +\begin{itemdecl} +template + constexpr pair try_emplace(K&& k, Args&&... args); +template + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. +\item +\tcode{is_constructible_v} is \tcode{true}. +\item +\tcode{is_constructible_v} is \tcode{true}. +\item +For the first overload, +\tcode{is_convertible_v} and +\tcode{is_convertible_v} are both \tcode{false}. +\end{itemize} + +\pnum +\expects +The conversion from \tcode{k} into \tcode{key_type} constructs +an object \tcode{u}, +for which \tcode{find(k) == find(u)} is \tcode{true}. + +\pnum +\effects +If the map already contains an element whose key is equivalent to \tcode{k}, +\tcode{*this} and \tcode{args...} are unchanged. +Otherwise equivalent to: +\begin{codeblock} +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)...); +\end{codeblock} + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, respectively. +\end{itemdescr} + +\indexlibrarymember{insert_or_assign}{flat_map}% +\begin{itemdecl} +template + constexpr pair insert_or_assign(const key_type& k, M&& obj); +template + constexpr pair insert_or_assign(key_type&& k, M&& obj); +template + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); +template + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_assignable_v} is \tcode{true} and +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects +If the map already contains an element \tcode{e} +whose key is equivalent to \tcode{k}, +assigns \tcode{std::forward<\linebreak M>(obj)} to \tcode{e.second}. +Otherwise, equivalent to +\begin{codeblock} +try_emplace(std::forward(k), std::forward(obj)) +\end{codeblock} +for the first two overloads or +\begin{codeblock} +try_emplace(hint, std::forward(k), std::forward(obj)) +\end{codeblock} +for the last two overloads. + +\pnum +\returns +In the first two overloads, the \tcode{bool} component of the returned pair +is \tcode{true} if and only if the insertion took place. The returned +iterator points to the map element whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} for the first two overloads and +the same as \tcode{emplace_hint} for the last two overloads. +\end{itemdescr} + +\indexlibrarymember{insert_or_assign}{flat_map}% +\begin{itemdecl} +template + constexpr pair insert_or_assign(K&& k, M&& obj); +template + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. +\item +\tcode{is_constructible_v} is \tcode{true}. +\item +\tcode{is_assignable_v} is \tcode{true}. +\item +\tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +The conversion from \tcode{k} into \tcode{key_type} constructs +an object \tcode{u}, for which \tcode{find(k) == find(u)} is \tcode{true}. + +\pnum +\effects +If the map already contains an element \tcode{e} +whose key is equivalent to \tcode{k}, +assigns \tcode{std::forward<\linebreak M>(obj)} to \tcode{e.second}. +Otherwise, equivalent to +\begin{codeblock} +try_emplace(std::forward(k), std::forward(obj)) +\end{codeblock} +for the first overload or +\begin{codeblock} +try_emplace(hint, std::forward(k), std::forward(obj)) +\end{codeblock} +for the second overload. + +\pnum +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the map element +whose key is equivalent to \tcode{k}. + +\pnum +\complexity +The same as \tcode{emplace} and \tcode{emplace_hint}, respectively. +\end{itemdescr} + +\indexlibrarymember{swap}{flat_map}% +\begin{itemdecl} +constexpr void swap(flat_map& y) + noexcept(is_nothrow_swappable_v && + is_nothrow_swappable_v && + is_nothrow_swappable_v); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +ranges::swap(@\exposid{compare}@, y.@\exposid{compare}@); +ranges::swap(@\exposid{c}@.keys, y.@\exposid{c}@.keys); +ranges::swap(@\exposid{c}@.values, y.@\exposid{c}@.values); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{extract}{flat_map}% +\begin{itemdecl} +constexpr containers extract() &&; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{*this} is emptied, even if the function exits via an exception. + +\pnum +\returns +\tcode{std::move(\exposid{c})}. +\end{itemdescr} + +\indexlibrarymember{replace}{flat_map}% +\begin{itemdecl} +constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{key_cont.size() == mapped_cont.size()} is \tcode{true}, +the elements of \tcode{key_cont} are sorted with respect to \exposid{compare}, and +\tcode{key_cont} contains no equal elements. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +@\exposid{c}@.keys = std::move(key_cont); +@\exposid{c}@.values = std::move(mapped_cont); +\end{codeblock} +\end{itemdescr} + +\rSec3[flat.map.erasure]{Erasure} + +\indexlibrarymember{erase_if}{flat_map}% +\begin{itemdecl} +template + constexpr typename flat_map::size_type + erase_if(flat_map& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{Key} and \tcode{T} meet the \oldconcept{MoveAssignable} requirements. + +\pnum +\effects +Let $E$ be \tcode{bool(pred(pair(e)))}. +Erases all elements \tcode{e} in \tcode{c} for which $E$ holds. + +\pnum +\returns +The number of elements erased. + +\pnum +\complexity +Exactly \tcode{c.size()} applications of the predicate. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +If an invocation of \tcode{erase_if} exits via an exception, +\tcode{c} is in a valid but unspecified state\iref{defns.valid}. +\begin{note} +\tcode{c} still meets its invariants, +but can be empty. +\end{note} +\end{itemdescr} + +\rSec2[flat.multimap]{Class template \tcode{flat_multimap}} + +\rSec3[flat.multimap.overview]{Overview} + +\pnum +\indexlibraryglobal{flat_multimap}% +A \tcode{flat_multimap} is a container adaptor +that provides an associative container interface +that supports equivalent keys +(i.e., possibly containing multiple copies of the same key value) and +provides for fast retrieval of values of another type \tcode{T} +based on the keys. +\tcode{flat_multimap} supports iterators that meet +the \oldconcept{InputIterator} requirements and +model the +\libconcept{random_access_iterator} concept\iref{iterator.concept.random.access}. + +\pnum +A \tcode{flat_multimap} meets all of the requirements +for a container\iref{container.reqmts} and +for a reversible container\iref{container.rev.reqmts}, +plus the optional container requirements\iref{container.opt.reqmts}. +\tcode{flat_multimap} meets the requirements of +an associative container\iref{associative.reqmts}, except that: +\begin{itemize} +\item +it does not meet the requirements related to node handles\iref{container.node}, +\item +it does not meet the requirements related to iterator invalidation, and +\item +the time complexity of the operations +that insert or erase a single element from the map is linear, +including the ones that take an insertion position iterator. +\end{itemize} +\begin{note} +A \tcode{flat_multimap} does not meet the additional requirements of an +allocator-aware container\iref{container.alloc.reqmts}. +\end{note} + +\pnum +A \tcode{flat_multimap} also provides most operations described +in \ref{associative.reqmts} for equal keys. +This means that a \tcode{flat_multimap} supports +the \tcode{a_eq} operations in \ref{associative.reqmts} +but not the \tcode{a_uniq} operations. +For a \tcode{flat_multimap} +the \tcode{key_type} is \tcode{Key} and +the \tcode{value_type} is \tcode{pair}. + +\pnum +Except as otherwise noted, +operations on \tcode{flat_multimap} are equivalent to those of \tcode{flat_map}, +except that \tcode{flat_multimap} operations +do not remove or replace elements with equal keys. +\begin{example} +\tcode{flat_multimap} constructors and emplace do not erase +non-unique elements after sorting them. +\end{example} + +\pnum +A \tcode{flat_multimap} maintains the following invariants: +\begin{itemize} +\item +it contains the same number of keys and values; +\item +the keys are sorted with respect to the comparison object; and +\item +the value at offset \tcode{off} within the value container is the value +associated with the key at offset \tcode{off} within the key container. +\end{itemize} + +\pnum +If any member function in \ref{flat.multimap.defn} exits via an exception, +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} + +\pnum +Any type \tcode{C} +that meets the sequence container requirements\iref{sequence.reqmts} +can be used to instantiate \tcode{flat_multimap}, +as long as +\tcode{C::iterator} meets the \oldconcept{RandomAccessIterator} requirements and +invocations of +member functions \tcode{C::size} and \tcode{C::max_size} do not exit via an exception. +In particular, +\tcode{vector}\iref{vector} and \tcode{deque}\iref{deque} can be used. +\begin{note} +\tcode{vector} is not a sequence container. +\end{note} + +\pnum +The program is ill-formed if +\tcode{Key} is not the same type as \tcode{KeyContainer::value_type} or +\tcode{T} is not the same type as \tcode{MappedContainer::value_type}. \pnum -Each associative container is parameterized on -\tcode{Key} -and an ordering relation -\tcode{Compare} -that induces a strict weak ordering~(\ref{alg.sorting}) on -elements of -\tcode{Key}. -In addition, -\tcode{map} -and -\tcode{multimap} -associate an arbitrary \term{mapped type} -\tcode{T} -with the -\tcode{Key}. -The object of type -\tcode{Compare} -is called the -\term{comparison object} -of a container. +The effect of calling a constructor +that takes both \tcode{key_container_type} and +\tcode{mapped_container_type} arguments +with containers of different sizes is undefined. \pnum -The phrase ``equivalence of keys'' means the equivalence relation imposed by the -comparison and -\textit{not} -the -\tcode{operator==} -on keys. -That is, two keys -\tcode{k1} -and -\tcode{k2} -are considered to be equivalent if for the -comparison object -\tcode{comp}, -\tcode{comp(k1, k2) == false \&\& comp(k2, k1) == false}. -For any two keys -\tcode{k1} -and -\tcode{k2} -in the same container, calling -\tcode{comp(k1, k2)} -shall always return the same value. +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 -An associative container supports \term{unique keys} if it may contain at -most one element for each key. Otherwise, it supports \term{equivalent keys}. -The \tcode{set} and \tcode{map} classes support unique keys; the \tcode{multiset} -and \tcode{multimap} classes support equivalent keys. -For \tcode{multiset} and \tcode{multimap}, -\tcode{insert}, \tcode{emplace}, and \tcode{erase} preserve the relative ordering -of equivalent elements. +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + +\rSec3[flat.multimap.defn]{Definition} + +\begin{codeblock} +namespace std { + template, + class KeyContainer = vector, class MappedContainer = vector> + class flat_multimap { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = pair; + using key_compare = Compare; + using reference = pair; + using const_reference = pair; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator = @\impdefx{type of \tcode{flat_multimap::iterator}}@; // see \ref{container.requirements} + using const_iterator = @\impdefx{type of \tcode{flat_multimap::const_iterator}}@; // see \ref{container.requirements} + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using key_container_type = KeyContainer; + using mapped_container_type = MappedContainer; + + class value_compare { + private: + key_compare @\exposid{comp}@; // \expos + constexpr value_compare(key_compare c) : @\exposid{comp}@(c) { } // \expos + + public: + constexpr bool operator()(const_reference x, const_reference y) const { + return @\exposid{comp}@(x.first, y.first); + } + }; + + struct containers { + key_container_type keys; + mapped_container_type values; + }; + + // \ref{flat.multimap.cons}, constructors + 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&&); + + constexpr explicit flat_multimap(const key_compare& comp) + : @\exposid{c}@(), @\exposid{compare}@(comp) { } + + constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); + + constexpr flat_multimap(sorted_equivalent_t, + key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); + + template + constexpr flat_multimap(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(), @\exposid{compare}@(comp) + { insert(first, last); } + + template + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(sorted_equivalent, first, last); } + + template<@\exposconcept{container-compatible-range}@ R> + constexpr flat_multimap(from_range_t, R&& rg) + : flat_multimap(from_range, std::forward(rg), key_compare()) { } + template<@\exposconcept{container-compatible-range}@ R> + constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp) + : flat_multimap(comp) { insert_range(std::forward(rg)); } + + constexpr flat_multimap(initializer_list il, + const key_compare& comp = key_compare()) + : flat_multimap(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 + constexpr explicit flat_multimap(const Alloc& a); + template + constexpr flat_multimap(const key_compare& comp, const Alloc& a); + template + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); + template + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); + template + constexpr flat_multimap(const flat_multimap&, const Alloc& a); + template + constexpr flat_multimap(flat_multimap&&, const Alloc& a); + template + constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); + template + constexpr flat_multimap(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + template + constexpr flat_multimap(initializer_list il, const Alloc& a); + template + constexpr flat_multimap(initializer_list il, const key_compare& comp, + const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, + const Alloc& a); + template + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); + + flat_multimap& operator=(initializer_list); + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // modifiers + template constexpr iterator emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + + constexpr iterator insert(const value_type& x) + { return emplace(x); } + constexpr iterator insert(value_type&& x) + { return emplace(std::move(x)); } + constexpr iterator insert(const_iterator position, const value_type& x) + { return emplace_hint(position, x); } + constexpr iterator insert(const_iterator position, value_type&& x) + { return emplace_hint(position, std::move(x)); } + + template constexpr iterator insert(P&& x); + template + constexpr iterator insert(const_iterator position, P&&); + template + constexpr void insert(InputIterator first, InputIterator last); + template + constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(R&& rg); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(sorted_equivalent_t, R&& rg); + + constexpr void insert(initializer_list il) + { insert(il.begin(), il.end()); } + constexpr void insert(sorted_equivalent_t, initializer_list il) + { insert(sorted_equivalent, il.begin(), il.end()); } + + constexpr containers extract() &&; + constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); + + 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(flat_multimap&) + noexcept(is_nothrow_swappable_v && + is_nothrow_swappable_v && + is_nothrow_swappable_v); + constexpr void clear() noexcept; + + // observers + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; + + constexpr const key_container_type& keys() const noexcept { return @\exposid{c}@.keys; } + constexpr const mapped_container_type& values() const noexcept { return @\exposid{c}@.values; } + + // map operations + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; + + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; + + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; + + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; + + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; + + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; + template + constexpr pair equal_range(const K& x); + template + constexpr pair equal_range(const K& x) const; + + friend constexpr bool operator==(const flat_multimap& x, const flat_multimap& y); + + friend constexpr @\exposid{synth-three-way-result}@ + operator<=>(const flat_multimap& x, const flat_multimap& y); + + friend constexpr void swap(flat_multimap& x, flat_multimap& y) + noexcept(noexcept(x.swap(y))) + { x.swap(y); } + + private: + containers @\exposid{c}@; // \expos + key_compare @\exposid{compare}@; // \expos + }; + + template> + flat_multimap(KeyContainer, MappedContainer, Compare = Compare()) + -> flat_multimap; + + template + flat_multimap(KeyContainer, MappedContainer, Allocator) + -> flat_multimap, KeyContainer, MappedContainer>; + template + flat_multimap(KeyContainer, MappedContainer, Compare, Allocator) + -> flat_multimap; + + template> + flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare = Compare()) + -> flat_multimap; + + template + flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Allocator) + -> flat_multimap, KeyContainer, MappedContainer>; + template + flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare, Allocator) + -> flat_multimap; + + template>> + flat_multimap(InputIterator, InputIterator, Compare = Compare()) + -> flat_multimap<@\exposid{iter-key-type}@, @\exposid{iter-mapped-type}@, Compare>; + + template>> + flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare()) + -> flat_multimap<@\exposid{iter-key-type}@, @\exposid{iter-mapped-type}@, Compare>; + + template>, + class Allocator = allocator> + flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) + -> flat_multimap<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, Compare, + vector<@\exposid{range-key-type}@, + @\exposid{alloc-rebind}@>>, + vector<@\exposid{range-mapped-type}@, + @\exposid{alloc-rebind}@>>>; + + template + flat_multimap(from_range_t, R&&, Allocator) + -> flat_multimap<@\exposid{range-key-type}@, @\exposid{range-mapped-type}@, less<@\exposid{range-key-type}@>, + vector<@\exposid{range-key-type}@, + @\exposid{alloc-rebind}@>>, + vector<@\exposid{range-mapped-type}@, + @\exposid{alloc-rebind}@>>>; + + template> + flat_multimap(initializer_list>, Compare = Compare()) + -> flat_multimap; + + template> + flat_multimap(sorted_equivalent_t, initializer_list>, Compare = Compare()) + -> flat_multimap; + + template + struct uses_allocator, + Allocator> + : bool_constant && + uses_allocator_v> { }; +} +\end{codeblock} \pnum -For \tcode{set} and \tcode{multiset} the value type is the same as the key type. -For \tcode{map} and \tcode{multimap} it is equal to \tcode{pair}. +The member type \tcode{containers} has the data members and special members +specified above. It has no base classes or members other than those +specified. + +\rSec3[flat.multimap.cons]{Constructors} + +\indexlibraryctor{flat_multimap}% +\begin{itemdecl} +constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); +\end{itemdecl} +\begin{itemdescr} \pnum -\tcode{iterator} -of an associative container is of the bidirectional iterator category. -For associative containers where the value type is the same as the key type, both -\tcode{iterator} -and -\tcode{const_iterator} -are constant iterators. It is unspecified whether or not -\tcode{iterator} -and -\tcode{const_iterator} -are the same type. -\enternote \tcode{iterator} and \tcode{const_iterator} have identical semantics in this case, and \tcode{iterator} is convertible to \tcode{const_iterator}. Users can avoid violating the One Definition Rule by always using \tcode{const_iterator} in their function parameter lists. \exitnote +\effects +Initializes +\tcode{\exposid{c}.keys} with \tcode{std::move(key_cont)}, +\tcode{\exposid{c}.values} with \tcode{std::move(mapped_cont)}, and +\exposid{compare} with \tcode{comp}; +sorts the range \range{begin()}{end()} with respect to \tcode{value_comp()}. \pnum -The associative containers meet all the requirements of Allocator-aware -containers~(\ref{container.requirements.general}), except that for -\tcode{map} and \tcode{multimap}, the requirements placed on \tcode{value_type} -in Table~\ref{tab:containers.container.requirements} apply instead to \tcode{key_type} -and \tcode{mapped_type}. \enternote For example, in some cases \tcode{key_type} and \tcode{mapped_type} -are required to be \tcode{CopyAssignable} even though the associated -\tcode{value_type}, \tcode{pair}, is not -\tcode{CopyAssignable}. \exitnote +\complexity +Linear in $N$ if the container arguments are already sorted +with respect to \tcode{value_comp()} and otherwise $N \log N$, +where $N$ is the value of \tcode{key_cont.size()} before this call. +\end{itemdescr} + +\indexlibraryctor{flat_multimap}% +\begin{itemdecl} +constexpr flat_multimap(sorted_equivalent_t, key_container_type key_cont, + mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); +\end{itemdecl} +\begin{itemdescr} \pnum -In Table~\ref{tab:containers.associative.requirements}, -\tcode{X} denotes an associative container class, -\tcode{a} denotes a value of \tcode{X}, -\tcode{a_uniq} denotes a value of \tcode{X} -when \tcode{X} supports unique keys, -\tcode{a_eq} denotes a value of \tcode{X} -when \tcode{X} supports multiple keys, -\tcode{a_tran} denotes a value of \tcode{X} when the \grammarterm{qualified-id} -\tcode{X::key_compare::is_transparent} is valid -and denotes a type~(\ref{temp.deduct}), -\tcode{i} and \tcode{j} -satisfy input iterator requirements and refer to elements -implicitly convertible to -\tcode{value_type}, \range{i}{j} -denotes a valid range, -\tcode{p} denotes a valid const iterator to \tcode{a}, -\tcode{q} denotes a valid dereferenceable const iterator to \tcode{a}, -\tcode{[q1, q2)} denotes a valid range of const iterators in \tcode{a}, -\tcode{il} designates an object of type \tcode{initializer_list}, -\tcode{t} denotes a value of \tcode{X::value_type}, -\tcode{k} denotes a value of \tcode{X::key_type} -and \tcode{c} denotes a value of type \tcode{X::key_compare}; -\tcode{kl} is a value such that \tcode{a} is partitioned~(\ref{alg.sorting}) -with respect to \tcode{c(r, kl)}, with \tcode{r} the key value of \tcode{e} -and \tcode{e} in \tcode{a}; -\tcode{ku} is a value such that \tcode{a} is partitioned with respect to -\tcode{!c(ku, r)}; -\tcode{ke} is a value such that \tcode{a} is partitioned with respect to -\tcode{c(r, ke)} and \tcode{!c(ke, r)}, with \tcode{c(r, ke)} implying -\tcode{!c(ke, r)}. -\tcode{A} denotes the storage allocator used by \tcode{X}, if any, or \tcode{std::allocator} otherwise, and \tcode{m} denotes an allocator of a type convertible to \tcode{A}. - -\begin{libreqtab4b} -{Associative container requirements (in addition to container)} -{tab:containers.associative.requirements} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Assertion/note} & \rhdr{Complexity} \\ - & & \chdr{pre-/post-condition} & \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \chdr{Assertion/note} & \rhdr{Complexity} \\ - & & \chdr{pre-/post-condition} & \\ \capsep -\endhead - -\tcode{X::key_type} & - \tcode{Key} & - & - compile time \\ \rowsep - -\tcode{mapped_type} (\tcode{map} and \tcode{multimap} only) & - \tcode{T} & - & - compile time \\ \rowsep - -\tcode{X::value_type} (\tcode{set} and \tcode{multiset} only) & - \tcode{Key} & - \requires\ \tcode{value_type} is \tcode{Erasable} from \tcode{X} & - compile time \\ \rowsep - -\tcode{X::value_type} (\tcode{map} and \tcode{multimap} only) & - \tcode{pair} & - \requires\ \tcode{value_type} is \tcode{Erasable} from \tcode{X} & - compile time \\ \rowsep - -\tcode{X::key_compare} & - \tcode{Compare} & - defaults to \tcode{less} & - compile time \\ \rowsep - -\tcode{X::value_compare} & - a binary predicate type & - is the same as \tcode{key_compare} for \tcode{set} and - \tcode{multiset}; is an ordering relation on pairs induced by the - first component (i.e., \tcode{Key}) for \tcode{map} and \tcode{multimap}. & - compile time \\ \rowsep - -\tcode{X(c)}\br -\tcode{X a(c);} & - & - \requires\ \tcode{key_compare} is \tcode{CopyConstructible}.\br - \effects\ Constructs an empty container. - Uses a copy of \tcode{c} as a comparison object. & - constant \\ \rowsep - -\tcode{X()}\br\tcode{X a;} & - & - \requires\ \tcode{key_compare} is \tcode{DefaultConstructible}.\br - \effects\ Constructs an empty container. - Uses \tcode{Compare()} as a comparison object & - constant \\ \rowsep - -\tcode{X(i,j,c)}\br -\tcode{X~a(i,j,c);} & - & - \requires\ \tcode{key_compare} is \tcode{CopyConstructible}. - \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br - \effects\ Constructs an empty container and inserts elements from the - range \tcode{[i, j)} into it; uses \tcode{c} as a comparison object. & - $N \log N$ in general ($N$ has the value \tcode{distance(i, j)}); - linear if \tcode{[i, j)} is sorted with \tcode{value_comp()} \\ \rowsep - -\tcode{X(i,j)} \tcode{X~a(i,j);} & - & - \requires\ \tcode{key_compare} is \tcode{DefaultConstructible}. - \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br - \effects\ Same as above, but uses \tcode{Compare()} as a comparison object & - same as above \\ \rowsep - -\tcode{X(il);} & - & - Same as \tcode{X(il.begin(), il.end())}. & - Same as \tcode{X(il.begin(), il.end())}. \\ \rowsep - -\tcode{X(il,c);} & - & - Same as \tcode{X(il.begin(), il.end(), c)}. & - Same as \tcode{X(il.begin(), il.end(), c)}. \\ \rowsep - -\tcode{a = il} & - \tcode{X\&} & - \requires\ \tcode{value_type} is - \tcode{CopyInsertable} into \tcode{X} - and \tcode{CopyAssignable}.\br - \effects Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. All - existing elements of \tcode{a} are either assigned to or destroyed. & - $N log N$ in general (where $N$ has the value \tcode{il.size() + a.size()}); - linear if \range{il.begin()}{il.end()} is sorted with \tcode{value_comp()}. - \\ \rowsep - -\tcode{a.key_comp()} & - \tcode{X::key_compare} & - returns the comparison object out of which \tcode{a} was constructed. & - constant \\ \rowsep - -\tcode{a.value_comp()} & - \tcode{X::value_compare} & - returns an object of \tcode{value_compare} constructed out of the comparison object & - constant \\ \rowsep - -\tcode{a_uniq.} \tcode{emplace(args)} & - \tcode{pair} & - \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br - \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with - \tcode{std::forward(args)...} if and only if there is no - element in the container with key equivalent to the key of \tcode{t}. - The \tcode{bool} component of the returned - pair is true if and only if the insertion takes place, and the iterator - component of the pair points to the element with key equivalent to the - key of \tcode{t}. & - logarithmic \\ \rowsep - -\tcode{a_eq.} \tcode{emplace(args)} & - \tcode{iterator} & - \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br - \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with - \tcode{std::forward(args)...} and returns the iterator pointing - to the newly inserted element. - If a range containing elements equivalent to \tcode{t} exists in \tcode{a_eq}, - \tcode{t} is inserted at the end of that range. & - logarithmic \\ \rowsep - -\tcode{a.emplace_hint(p, args)} & - \tcode{iterator} & - equivalent to \tcode{a.emplace(} \tcode{std::forward(args)...)}. - Return value is an iterator pointing to the element with the key equivalent - to the newly inserted element. - The element is inserted as close as possible to the position just prior - to \tcode{p}. & - logarithmic in general, but amortized constant if the element - is inserted right before \tcode{p} \\ \rowsep - -\tcode{a_uniq.} \tcode{insert(t)} & - \tcode{pair} & - \requires\ If \tcode{t} is a non-const rvalue expression, \tcode{value_type} shall be - \tcode{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be - \tcode{CopyInsertable} into \tcode{X}.\br - \effects\ Inserts \tcode{t} if and only if there is no element in the container - with key equivalent to the key of \tcode{t}. The \tcode{bool} component of - the returned pair is true if and only if the insertion - takes place, and the \tcode{iterator} - component of the pair points to the element with key - equivalent to the key of \tcode{t}. & - logarithmic \\ \rowsep - -\tcode{a_eq.insert(t)} & - \tcode{iterator} & - \requires\ If \tcode{t} is a non-const rvalue expression, \tcode{value_type} shall be - \tcode{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be - \tcode{CopyInsertable} into \tcode{X}.\br - \effects\ Inserts \tcode{t} and returns the iterator pointing - to the newly inserted element. - If a range containing elements equivalent to - \tcode{t} exists in \tcode{a_eq}, \tcode{t} - is inserted at the end of that range. & - logarithmic \\ \rowsep - -\tcode{a.insert(}\br - \tcode{p, t)} & - \tcode{iterator} & - \requires\ If \tcode{t} is a non-const rvalue expression, \tcode{value_type} shall be - \tcode{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be - \tcode{CopyInsertable} into \tcode{X}.\br - \effects\ Inserts \tcode{t} if and only if there is no element with key - equivalent to the key of \tcode{t} in containers with unique keys; - always inserts \tcode{t} in containers with equivalent keys. Always - returns the iterator pointing to the element with key equivalent to - the key of \tcode{t}. \tcode{t} is inserted as close as possible to the position - just prior to \tcode{p}.& - logarithmic in general, but amortized constant if \tcode{t} - is inserted right before \tcode{p}. \\ \rowsep - -\tcode{a.insert(}\br - \tcode{i, j)} & - \tcode{void} & - \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br - pre: \tcode{i}, \tcode{j} are not iterators into \tcode{a}. - inserts each element from the range \range{i}{j} if and only if there - is no element with key equivalent to the key of that element in containers - with unique keys; always inserts that element in containers with equivalent keys. & - $N\log (\mathrm{a.size}() + N)$ ($N$ has the value \tcode{distance(i, j)} \\ \rowsep - -\tcode{a.insert(il)} & - \tcode{void} & - Equivalent to \tcode{a.insert(il.begin(), il.end())}. & - \\ \rowsep - -\tcode{a.erase(k)} & - \tcode{size_type} & - erases all elements in the container with key equivalent to - \tcode{k}. returns the number of erased elements. & - $\log (\mathrm{a.size}()) + \mathrm{a.count}(k)$ \\ \rowsep - -\tcode{a.erase(q)} & - \tcode{iterator} & - erases the element pointed to by \tcode{q}. Returns an iterator pointing to - the element immediately following \tcode{q} prior to the element being erased. - If no such element exists, returns \tcode{a.end()}. & - amortized constant \\ \rowsep - -\tcode{a.erase(}\br - \tcode{q1, q2)} & - \tcode{iterator} & - erases all the elements in the range \range{q1}{q2}. Returns an iterator pointing to - the element pointed to by q2 prior to any elements being erased. If no such element - exists, \tcode{a.end()} is returned. & - $\log (\mathrm{a.size}()) + N$ where $N$ has the value \tcode{distance(q1, q2)}. \\ \rowsep - -\tcode{a.clear()} & - \tcode{void} & - \tcode{a.erase(a.begin(),a.end())}\br - post: \tcode{a.empty()} returns \tcode{true} & - linear in \tcode{a.size()}. \\ \rowsep - -\tcode{a.find(k)} & - \tcode{iterator}; \tcode{const_iterator} for constant \tcode{a}. & - returns an iterator pointing to an element with the key equivalent - to \tcode{k}, or \tcode{a.end()} if such an element is not found & - logarithmic \\ \rowsep - -\tcode{a_tran.}\br - \tcode{find(ke)} & - \tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. & - returns an iterator pointing to an element with key \tcode{r} such that - \tcode{!c(r, ke) \&\& !c(ke, r)}, or \tcode{a_tran.end()} if such an element - is not found & - logarithmic \\ \rowsep - -\tcode{a.count(k)} & - \tcode{size_type} & - returns the number of elements with key equivalent to \tcode{k} & - $\log (\mathrm{a.size}()) + \mathrm{a.count}(k)$ \\ \rowsep - -\tcode{a_tran.}\br - \tcode{count(ke)} & - \tcode{size_type} & - returns the number of elements with key \tcode{r} such that - \tcode{!c(r, ke) \&\& !c(ke, r)} & - $\log (\mathrm{a\_tran.size}()) + \mathrm{a\_tran.count}(\mathrm{ke})$ \\ \rowsep - -\tcode{a.lower_bound(k)} & - \tcode{iterator}; \tcode{const_iterator} for constant \tcode{a}. & - returns an iterator pointing to the first element with - key not less than \tcode{k}, - or \tcode{a.end()} if such an element is not found. & - logarithmic \\ \rowsep - -\tcode{a_tran.}\br - \tcode{lower_bound(kl)} & - \tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. & - returns an iterator pointing to the first element with - key \tcode{r} such that \tcode{!c(r, kl)}, - or \tcode{a_tran.end()} if such an element is not found. & - logarithmic \\ \rowsep - -\tcode{a.upper_bound(k)} & - \tcode{iterator}; \tcode{const_iterator} for constant \tcode{a}. & - returns an iterator pointing to the first element with - key greater than \tcode{k}, - or \tcode{a.end()} if such an element is not found. & - logarithmic \\ \rowsep - -\tcode{a_tran.}\br - \tcode{upper_bound(ku)} & - \tcode{iterator}; \tcode{const_iterator} for constant \tcode{a_tran}. & - returns an iterator pointing to the first element with - key \tcode{r} such that \tcode{c(ku, r)}, - or \tcode{a_tran.end()} if such an element is not found. & - logarithmic \\ \rowsep - -\tcode{a.equal_range(k)} & - \tcode{pair}; - \tcode{pair} for constant \tcode{a}. & - equivalent to \tcode{make_pair(a.lower_bound(k), a.upper_bound(k))}. & - logarithmic \\ \rowsep - -\tcode{a_tran.}\br - \tcode{equal_range(ke)} & - \tcode{pair}; - \tcode{pair} for constant \tcode{a_tran}. & - equivalent to \tcode{make_pair(}\br - \tcode{a_tran.lower_bound(ke), a_tran.upper_bound(ke))}. & - logarithmic \\ -\end{libreqtab4b} - -\pnum -The \tcode{insert} and \tcode{emplace} members shall not affect the validity of -iterators and references to the container, -and the \tcode{erase} members shall invalidate only iterators and -references to the erased elements. +\effects +Initializes +\tcode{\exposid{c}.keys} with \tcode{std::move(key_cont)}, +\tcode{\exposid{c}.values} with \tcode{std::move(mapped_cont)}, and +\exposid{compare} with \tcode{comp}. \pnum -The fundamental property of iterators of associative containers is that they iterate through the containers -in the non-descending order of keys where non-descending is defined by the comparison that was used to -construct them. -For any two dereferenceable iterators -\tcode{i} -and -\tcode{j} -such that distance from -\tcode{i} -to -\tcode{j} -is positive, +\complexity +Constant. +\end{itemdescr} + +\rSec3[flat.multimap.cons.alloc]{Constructors with allocators} + +\pnum +The constructors in this subclause shall not participate in overload resolution +unless \tcode{uses_allocator_v} is \tcode{true} +and \tcode{uses_allocator_v} is \tcode{true}. + +\indexlibraryctor{flat_multimap}% +\begin{itemdecl} +template + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); +template + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{flat_multimap(key_cont, mapped_cont)} and +\tcode{flat_multimap(key_cont, \linebreak{}mapped_cont, comp)}, respectively, +except that \tcode{\exposid{c}.keys} and \tcode{\exposid{c}.values} are constructed +with uses-allocator construction\iref{allocator.uses.construction}. + +\pnum +\complexity +Same as \tcode{flat_multimap(key_cont, mapped_cont)} and +\tcode{flat_multimap(key_cont, \linebreak{}mapped_cont, comp)}, respectively. +\end{itemdescr} + +\indexlibraryctor{flat_multimap}% +\begin{itemdecl} +template + constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); +template + constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const key_compare& comp, + const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{flat_multimap(sorted_equivalent, key_cont, mapped_cont)} and +\tcode{flat_multimap(sorted_equivalent, key_cont, mapped_cont, comp)}, respectively, +except that \tcode{\exposid{c}.keys} and \tcode{\exposid{c}.val\-ues} are constructed +with uses-allocator construction\iref{allocator.uses.construction}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\indexlibraryctor{flat_multimap}% +\begin{itemdecl} +template + constexpr explicit flat_multimap(const Alloc& a); +template + constexpr flat_multimap(const key_compare& comp, const Alloc& a); +template + constexpr flat_multimap(const flat_multimap&, const Alloc& a); +template + constexpr flat_multimap(flat_multimap&&, const Alloc& a); +template + constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); +template + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); +template + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); +template + constexpr flat_multimap(initializer_list il, const Alloc& a); +template + constexpr flat_multimap(initializer_list il, const key_compare& comp, + const Alloc& a); +template + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, const Alloc& a); +template + constexpr flat_multimap(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to the corresponding non-allocator constructors +except that \tcode{\exposid{c}.keys} and \tcode{\exposid{c}.values} are constructed +with uses-allocator construction\iref{allocator.uses.construction}. +\end{itemdescr} + +\rSec3[flat.multimap.erasure]{Erasure} + +\indexlibrarymember{erase_if}{flat_multimap}% +\begin{itemdecl} +template + constexpr typename flat_multimap::size_type + erase_if(flat_multimap& c, Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{Key} and \tcode{T} meet the \oldconcept{MoveAssignable} requirements. + +\pnum +\effects +Let $E$ be \tcode{bool(pred(pair(e)))}. +Erases all elements \tcode{e} in \tcode{c} for which $E$ holds. + +\pnum +\returns +The number of elements erased. + +\pnum +\complexity +Exactly \tcode{c.size()} applications of the predicate. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +If an invocation of \tcode{erase_if} exits via an exception, +\tcode{c} is in a valid but unspecified state\iref{defns.valid}. +\begin{note} +\tcode{c} still meets its invariants, +but can be empty. +\end{note} +\end{itemdescr} + +\rSec2[flat.set.syn]{Header \tcode{} synopsis}% +\indexheader{flat_set}% \begin{codeblock} -value_comp(*j, *i) == false +#include // see \ref{compare.syn} +#include // see \ref{initializer.list.syn} + +namespace std { + // \ref{flat.set}, class template \tcode{flat_set} + template, class KeyContainer = vector> + class flat_set; + + struct sorted_unique_t { explicit sorted_unique_t() = default; }; + inline constexpr sorted_unique_t sorted_unique{}; + + template + struct uses_allocator, Allocator>; + + // \ref{flat.set.erasure}, erasure for \tcode{flat_set} + template + constexpr typename flat_set::size_type + erase_if(flat_set& c, Predicate pred); + + // \ref{flat.multiset}, class template \tcode{flat_multiset} + template, class KeyContainer = vector> + class flat_multiset; + + struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; + inline constexpr sorted_equivalent_t sorted_equivalent{}; + + template + struct uses_allocator, Allocator>; + + // \ref{flat.multiset.erasure}, erasure for \tcode{flat_multiset} + template + constexpr typename flat_multiset::size_type + erase_if(flat_multiset& c, Predicate pred); +} \end{codeblock} +\rSec2[flat.set]{Class template \tcode{flat_set}} + +\rSec3[flat.set.overview]{Overview} + +\pnum +\indexlibraryglobal{flat_set}% +A \tcode{flat_set} is a container adaptor +that provides an associative container interface +that supports unique keys +(i.e., contains at most one of each key value) and +provides for fast retrieval of the keys themselves. +\tcode{flat_set} supports iterators that model +the \libconcept{random_access_iterator} concept\iref{iterator.concept.random.access}. + +\pnum +A \tcode{flat_set} meets all of the requirements +for a container\iref{container.reqmts} and +for a reversible container\iref{container.rev.reqmts}, +plus the optional container requirements\iref{container.opt.reqmts}. +\tcode{flat_set} meets the requirements of +an associative container\iref{associative.reqmts}, except that: +\begin{itemize} +\item +it does not meet the requirements +related to node handles\iref{container.node.overview}, +\item +it does not meet the requirements related to iterator invalidation, and +\item +the time complexity of the operations +that insert or erase a single element from the set +is linear, +including the ones that take an insertion position iterator. +\end{itemize} +\begin{note} +A \tcode{flat_set} does not meet +the additional requirements of an allocator-aware container, +as described in \ref{container.alloc.reqmts}. +\end{note} + +\pnum +A \tcode{flat_set} also provides most operations +described in \ref{associative.reqmts} for unique keys. +This means that a \tcode{flat_set} supports +the \tcode{a_uniq} operations in \ref{associative.reqmts} +but not the \tcode{a_eq} operations. +For a \tcode{flat_set}, +both the \tcode{key_type} and \tcode{value_type} are \tcode{Key}. + +\pnum +Descriptions are provided here only for operations on \tcode{flat_set} +that are not described in one of those sets of requirements or +for operations where there is additional semantic information. + +\pnum +A \tcode{flat_set} maintains the invariant that the keys are sorted with +respect to the comparison object. + +\pnum +If any member function in \ref{flat.set.defn} exits via an exception, +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} + +\pnum +Any sequence container\iref{sequence.reqmts} +supporting \oldconcept{RandomAccessIterator} +can be used to instantiate \tcode{flat_set}. +In particular, \tcode{vector}\iref{vector} and \tcode{deque}\iref{deque} +can be used. +\begin{note} +\tcode{vector} is not a sequence container. +\end{note} + +\pnum +The program is ill-formed if \tcode{Key} is not the same type +as \tcode{KeyContainer::value_type}. + \pnum -For associative containers with unique keys the stronger condition holds, +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} -value_comp(*i, *j) != false. +namespace std { + template, class KeyContainer = vector> + 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 = 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 + constexpr flat_set() : flat_set(key_compare()) { } + + 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) { } + + constexpr explicit flat_set(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 + constexpr flat_set(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(), @\exposid{compare}@(comp) + { insert(first, last); } + + template + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(first, last), @\exposid{compare}@(comp) { } + + template<@\exposconcept{container-compatible-range}@ R> + constexpr flat_set(from_range_t, R&& rg) + : flat_set(from_range, std::forward(rg), key_compare()) { } + template<@\exposconcept{container-compatible-range}@ R> + constexpr flat_set(from_range_t, R&& rg, const key_compare& comp) + : flat_set(comp) + { insert_range(std::forward(rg)); } + + constexpr flat_set(initializer_list il, const key_compare& comp = key_compare()) + : flat_set(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 + constexpr explicit flat_set(const Alloc& a); + template + constexpr flat_set(const key_compare& comp, const Alloc& a); + template + constexpr flat_set(const container_type& cont, const Alloc& a); + template + constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); + template + constexpr flat_set(sorted_unique_t, const container_type& cont, const Alloc& a); + template + constexpr flat_set(sorted_unique_t, const container_type& cont, + const key_compare& comp, const Alloc& a); + template + constexpr flat_set(const flat_set&, const Alloc& a); + template + constexpr flat_set(flat_set&&, const Alloc& a); + template + constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a); + template + constexpr flat_set(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const Alloc& a); + template + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_set(from_range_t, R&& rg, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + template + constexpr flat_set(initializer_list il, const Alloc& a); + template + constexpr flat_set(initializer_list il, const key_compare& comp, + const Alloc& a); + template + constexpr flat_set(sorted_unique_t, initializer_list il, const Alloc& a); + template + constexpr flat_set(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); + + constexpr flat_set& operator=(initializer_list); + + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + + // \ref{flat.set.modifiers}, modifiers + template constexpr pair emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + + constexpr pair insert(const value_type& x) + { return emplace(x); } + constexpr pair insert(value_type&& x) + { return emplace(std::move(x)); } + template constexpr pair insert(K&& x); + constexpr iterator insert(const_iterator position, const value_type& x) + { return emplace_hint(position, x); } + constexpr iterator insert(const_iterator position, value_type&& x) + { return emplace_hint(position, std::move(x)); } + template constexpr iterator insert(const_iterator hint, K&& x); + + template + constexpr void insert(InputIterator first, InputIterator last); + template + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(R&& rg); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(sorted_unique_t, R&& rg); + + constexpr void insert(initializer_list il) + { insert(il.begin(), il.end()); } + constexpr void insert(sorted_unique_t, initializer_list il) + { insert(sorted_unique, il.begin(), il.end()); } + + constexpr container_type extract() &&; + constexpr void replace(container_type&&); + + 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); + + constexpr void swap(flat_set& y) noexcept(@\seebelow@); + constexpr void clear() noexcept; + + // observers + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; + + // set operations + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; + + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; + + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; + + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; + + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; + + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; + template + constexpr pair equal_range(const K& x); + template + constexpr pair equal_range(const K& x) const; + + friend constexpr bool operator==(const flat_set& x, const flat_set& y); + + friend constexpr @\exposid{synth-three-way-result}@ + operator<=>(const flat_set& x, const flat_set& 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 + key_compare @\exposidnc{compare}@; // \expos + }; + + template> + flat_set(KeyContainer, Compare = Compare()) + -> flat_set; + template + flat_set(KeyContainer, Allocator) + -> flat_set, KeyContainer>; + template + flat_set(KeyContainer, Compare, Allocator) + -> flat_set; + + template> + flat_set(sorted_unique_t, KeyContainer, Compare = Compare()) + -> flat_set; + template + flat_set(sorted_unique_t, KeyContainer, Allocator) + -> flat_set, KeyContainer>; + template + flat_set(sorted_unique_t, KeyContainer, Compare, Allocator) + -> flat_set; + + template>> + flat_set(InputIterator, InputIterator, Compare = Compare()) + -> flat_set<@\placeholder{iter-value-type}@, Compare>; + + template>> + flat_set(sorted_unique_t, InputIterator, InputIterator, Compare = Compare()) + -> flat_set<@\placeholder{iter-value-type}@, Compare>; + + template>, + class Allocator = allocator>> + flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) + -> flat_set, Compare, + vector, + @\exposid{alloc-rebind}@>>>; + + template + flat_set(from_range_t, R&&, Allocator) + -> flat_set, less>, + vector, + @\exposid{alloc-rebind}@>>>; + + template> + flat_set(initializer_list, Compare = Compare()) + -> flat_set; + + template> + flat_set(sorted_unique_t, initializer_list, Compare = Compare()) + -> flat_set; + + template + struct uses_allocator, Allocator> + : bool_constant> { }; +} \end{codeblock} +\rSec3[flat.set.cons]{Constructors} + +\indexlibraryctor{flat_set}% +\begin{itemdecl} +constexpr explicit flat_set(container_type cont, const key_compare& comp = key_compare()); +\end{itemdecl} + +\begin{itemdescr} \pnum -When an associative container is constructed by passing a comparison object the -container shall not store a pointer or reference to the passed object, -even if that object is passed by reference. -When an associative container is copied, either through a copy constructor -or an assignment operator, -the target container shall then use the comparison object from the container -being copied, -as if that comparison object had been passed to the target container in -its constructor. +\effects +Initializes \exposid{c} with \tcode{std::move(cont)} and +\exposid{compare} with \tcode{comp}, +sorts the range \range{begin()}{end()} with respect to \exposid{compare}, and +finally erases all but the first element +from each group of consecutive equivalent elements. \pnum -The member function templates \tcode{find}, \tcode{count}, \tcode{lower_bound}, -\tcode{upper_bound}, and \tcode{equal_range} shall not participate in overload -resolution unless the \grammarterm{qualified-id} \tcode{Compare::is_transparent} is valid -and denotes a type~(\ref{temp.deduct}). +\complexity +Linear in $N$ if \tcode{cont} is already sorted with respect to \exposid{compare} and +otherwise $N \log N$, where $N$ is the value of \tcode{cont.size()} before this call. +\end{itemdescr} -\indextext{associative containers!exception safety}% -\indextext{associative containers!requirements}% -\rSec3[associative.reqmts.except]{Exception safety guarantees} +\rSec3[flat.set.cons.alloc]{Constructors with allocators} \pnum -For associative containers, no \tcode{clear()} function throws an exception. -\tcode{erase(k)} does not throw an exception unless that exception is thrown -by the container's \tcode{Compare} object (if any). +The constructors in this subclause shall not participate in overload resolution +unless \tcode{uses_allocator_v} is \tcode{true}. + +\indexlibraryctor{flat_set}% +\begin{itemdecl} +template + constexpr flat_set(const container_type& cont, const Alloc& a); +template + constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); +\end{itemdecl} +\begin{itemdescr} \pnum -For associative containers, if an exception is thrown by any operation from -within an \tcode{insert} or \tcode{emplace} function inserting a single element, the -insertion has no effect. +\effects +Equivalent to +\tcode{flat_set(cont)} and \tcode{flat_set(cont, comp)}, respectively, +except that \exposid{c} is constructed with +uses-allocator construction\iref{allocator.uses.construction}. \pnum -For associative containers, no \tcode{swap} function throws an exception unless -that exception is thrown by the -swap of the container's \tcode{Compare} object (if any). +\complexity +Same as \tcode{flat_set(cont)} and \tcode{flat_set(cont, comp)}, respectively. +\end{itemdescr} -\indextext{unordered associative containers|(} -\indextext{associative containers!unordered|see{unordered associative containers}} -\indextext{hash tables|see{unordered associative containers}} -\rSec2[unord.req]{Unordered associative containers} +\indexlibraryctor{flat_set}% +\begin{itemdecl} +template + constexpr flat_set(sorted_unique_t, const container_type& cont, const Alloc& a); +template + constexpr flat_set(sorted_unique_t, const container_type& cont, + const key_compare& comp, const Alloc& a); +\end{itemdecl} +\begin{itemdescr} \pnum -\indextext{unordered associative containers!complexity}% -Unordered associative containers provide an ability for fast retrieval -of data based on keys. The worst-case complexity for most operations -is linear, but the average case is much faster. The library provides -four unordered associative containers: \tcode{unordered_set}, -\tcode{unordered_map}, \tcode{unordered_multiset}, and -\tcode{unordered_multimap}. +\effects +Equivalent to +\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}. \pnum -\indextext{unordered associative containers!lack of comparison operators}% -\indextext{unordered associative containers!requirements}% -\indextext{requirements!container!not required for unordered associated containers}% -Unordered associative containers conform to the requirements for -Containers~(\ref{container.requirements}), except that -the expressions -\tcode{a == b} and \tcode{a != b} have different semantics than for the other -container types. +\complexity +Linear. +\end{itemdescr} -\pnum -Each unordered associative container is parameterized by \tcode{Key}, -by a function object type \tcode{Hash} that meets the \tcode{Hash} -requirements~(\ref{hash.requirements}) and acts as a hash function for -argument values of type \tcode{Key}, and by a binary predicate \tcode{Pred} -that induces an equivalence relation on values of type \tcode{Key}. -Additionally, \tcode{unordered_map} and \tcode{unordered_multimap} associate -an arbitrary \textit{mapped type} \tcode{T} with the \tcode{Key}. +\indexlibraryctor{flat_set}% +\begin{itemdecl} +template + constexpr explicit flat_set(const Alloc& a); +template + constexpr flat_set(const key_compare& comp, const Alloc& a); +template + constexpr flat_set(const flat_set&, const Alloc& a); +template + constexpr flat_set(flat_set&&, const Alloc& a); +template + constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_set(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); +template + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_set(from_range_t, R&& rg, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); +template + constexpr flat_set(initializer_list il, const Alloc& a); +template + constexpr flat_set(initializer_list il, const key_compare& comp, const Alloc& a); +template + constexpr flat_set(sorted_unique_t, initializer_list il, const Alloc& a); +template + constexpr flat_set(sorted_unique_t, initializer_list il, + const key_compare& comp, const Alloc& a); +\end{itemdecl} +\begin{itemdescr} \pnum -\indextext{unordered associative containers!hash function}% -\indextext{hash function}% -The container's object of type \tcode{Hash} --- denoted by -\tcode{hash} --- is called the \term{hash function} of the -container. The container's object of type \tcode{Pred} --- -denoted by \tcode{pred} --- is called the -\term{key equality predicate} of the container. +\effects +Equivalent to the corresponding non-allocator constructors +except that \exposid{c} is constructed with +uses-allocator construction\iref{allocator.uses.construction}. +\end{itemdescr} -\pnum -\indextext{unordered associative containers!equality function}% -Two values \tcode{k1} and \tcode{k2} of type \tcode{Key} are -considered equivalent if the container's -key equality predicate returns -\tcode{true} when passed those values. If \tcode{k1} and -\tcode{k2} are equivalent, the container's hash function shall -return the same value for both. -\enternote Thus, when an unordered associative container is instantiated with -a non-default \tcode{Pred} parameter it usually needs a non-default \tcode{Hash} -parameter as well. \exitnote -For any two keys \tcode{k1} and \tcode{k2} in the same container, -calling \tcode{pred(k1, k2)} shall always return the same value. -For any key \tcode{k} in a container, calling \tcode{hash(k)} -shall always return the same value. +\rSec3[flat.set.modifiers]{Modifiers} -\pnum -\indextext{unordered associative containers!unique keys}% -\indextext{unordered associative containers!equivalent keys}% -An unordered associative container supports \textit{unique keys} if it -may contain at most one element for each key. Otherwise, it supports -\textit{equivalent keys}. \tcode{unordered_set} and \tcode{unordered_map} -support unique keys. \tcode{unordered_multiset} and \tcode{unordered_multimap} -support equivalent keys. In containers that support equivalent keys, -elements with equivalent keys are adjacent to each other -in the iteration order of the container. Thus, although the absolute order -of elements in an unordered container is not specified, its elements are -grouped into \defn{equivalent-key group}{s} such that all elements of each -group have equivalent keys. Mutating operations on unordered containers shall -preserve the relative order of elements within each equivalent-key group -unless otherwise specified. +\indexlibrarymember{insert}{flat_set}% +\begin{itemdecl} +template constexpr pair insert(K&& x); +template constexpr iterator insert(const_iterator hint, K&& x); +\end{itemdecl} +\begin{itemdescr} \pnum -For \tcode{unordered_set} and \tcode{unordered_multiset} the value type is -the same as the key type. For \tcode{unordered_map} and -\tcode{unordered_multimap} it is \tcode{std::pair}. +\constraints +The \grammarterm{qualified-id} \tcode{Compare::is_transparent} +is valid and denotes a type. +\tcode{is_constructi\-ble_v} is \tcode{true}. \pnum -For unordered containers where the value type is the same as the key -type, both \tcode{iterator} and \tcode{const_iterator} are constant -iterators. It is unspecified whether or not \tcode{iterator} and -\tcode{const_iterator} are the same type. -\enternote \tcode{iterator} and \tcode{const_iterator} have identical -semantics in this case, and \tcode{iterator} is convertible to -\tcode{const_iterator}. Users can avoid violating the One Definition Rule -by always using \tcode{const_iterator} in their function parameter lists. -\exitnote +\expects +The conversion from \tcode{x} into \tcode{value_type} constructs +an object \tcode{u}, for which \tcode{find(x) == find(u)} is \tcode{true}. \pnum -\indextext{buckets}% -\indextext{hash code}% -The elements of an unordered associative container are organized into -\textit{buckets}. Keys with the same hash code appear in the same -bucket. The number of buckets is automatically increased as elements -are added to an unordered associative container, so that the average -number of elements per bucket is kept below a bound. Rehashing -invalidates iterators, changes ordering between elements, and changes -which buckets elements appear in, but does not invalidate pointers or -references to elements. For \tcode{unordered_multiset} and -\tcode{unordered_multimap}, rehashing preserves the relative ordering of -equivalent elements. +\effects +If the set already contains an element equivalent to \tcode{x}, +\tcode{*this} and \tcode{x} are unchanged. +Otherwise, +inserts a new element as if by \tcode{emplace(std::forward(x))}. \pnum -The unordered associative containers meet all the requirements of Allocator-aware -containers~(\ref{container.requirements.general}), except that for -\tcode{unordered_map} and \tcode{unordered_multimap}, the requirements placed on \tcode{value_type} -in Table~\ref{tab:containers.container.requirements} apply instead to \tcode{key_type} -and \tcode{mapped_type}. \enternote For example, \tcode{key_type} and \tcode{mapped_type} -are sometimes required to be \tcode{CopyAssignable} even though the associated -\tcode{value_type}, \tcode{pair}, is not -\tcode{CopyAssignable}. \exitnote +\returns +In the first overload, +the \tcode{bool} component of the returned pair is \tcode{true} +if and only if the insertion took place. +The returned iterator points to the element +whose key is equivalent to \tcode{x}. +\end{itemdescr} -\pnum -\indextext{unordered associative containers}% -\indextext{unordered associative containers!requirements}% -\indextext{requirements!unordered associative container}% -\indextext{unordered associative containers!unique keys}% -\indextext{unordered associative containers!equivalent keys}% -\indextext{requirements!container}% -In table~\ref{tab:HashRequirements}: -\tcode{X} is an unordered associative container class, \tcode{a} is an -object of type \tcode{X}, \tcode{b} is a possibly const object of -type \tcode{X}, \tcode{a_uniq} is an object of type \tcode{X} -when \tcode{X} supports unique keys, \tcode{a_eq} is an object of -type \tcode{X} when \tcode{X} supports equivalent keys, \tcode{i} -and \tcode{j} are input iterators that refer -to \tcode{value_type}, \tcode{[i, j)} is a valid range, -\tcode{p} and \tcode{q2} are valid const iterators to \tcode{a}, -\tcode{q} and \tcode{q1} are valid dereferenceable const iterators to \tcode{a}, -\tcode{[q1, q2)} is a valid range in \tcode{a}, -\tcode{il} designates an object of type \tcode{initializer_list}, -\tcode{t} is a value of -type \tcode{X::value_type}, \tcode{k} is a value of -type \tcode{key_type}, \tcode{hf} is a possibly const value of -type \tcode{hasher}, \tcode{eq} is a possibly const value of -type \tcode{key_equal}, \tcode{n} is a value of -type \tcode{size_type}, and \tcode{z} is a value of -type \tcode{float}. - -\begin{libreqtab4d} - {Unordered associative container requirements (in addition to container)} - {tab:HashRequirements} -\\ \topline -\lhdr{Expression} & \chdr{Return type} -& \chdr{Assertion/note pre-/post-condition} -& \rhdr{Complexity} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \chdr{Assertion/note pre-/post-condition} & \rhdr{Complexity} \\ \capsep -\endhead -%% -\tcode{X::key_type} & -\indextext{unordered associative containers!\idxcode{key_type}}% -\indextext{\idxcode{key_type}!unordered associative containers}% - \tcode{Key} & - & - compile time \\ \rowsep - -\tcode{X::mapped_type} (\tcode{unordered_map} and \tcode{unordered_multimap} only) & - \tcode{T} & - & - compile time \\ \rowsep - -\tcode{X::value_type} (\tcode{unordered_set} and \tcode{unordered_multiset} only) & - \tcode{Key} & - \requires\ \tcode{value_type} is \tcode{Erasable} from \tcode{X} & - compile time \\ \rowsep - -\tcode{X::value_type} (\tcode{unordered_map} and \tcode{unordered_multimap} only) & - \tcode{pair} & - \requires\ \tcode{value_type} is \tcode{Erasable} from \tcode{X} & - compile time \\ \rowsep - -\tcode{X::hasher} -& \tcode{Hash} -& \tcode{Hash} shall be a unary function object type such that the expression - \tcode{hf(k)} has type \tcode{std::size_t}.% - \indextext{unordered associative containers!\idxcode{hasher}}% - \indextext{\idxcode{hasher}!unordered associative containers}% -& compile time -\\ \rowsep -% -\tcode{X::key_equal} -& \tcode{Pred} -& \tcode{Pred} shall be a binary predicate that takes two arguments - of type \tcode{Key}. \tcode{Pred} is an equivalence relation.% - \indextext{unordered associative containers!\idxcode{key_equal}}% - \indextext{\idxcode{key_equal}!unordered associative containers}% -& compile time -\\ \rowsep -% -\tcode{X::local_iterator} -& An iterator type whose category, value type, - difference type, and pointer and reference types are the same as - \tcode{X::iterator}'s. \indextext{\idxcode{local_iterator}} -& A \tcode{local_iterator} object may be used to iterate through a - single bucket, but may not be used to iterate across - buckets.% - \indextext{unordered associative containers!\idxcode{local_iterator}}% - \indextext{\idxcode{local_iterator}!unordered associative containers}% -& compile time -\\ \rowsep -% -\tcode{X::const_local_iterator} -& An iterator type whose category, value type, - difference type, and pointer and reference types are the same as - \tcode{X::const_iterator}'s. \indextext{\idxcode{const_local_iterator}} -& A \tcode{const_local_iterator} object may be used to iterate through a - single bucket, but may not be used to iterate across - buckets.% - \indextext{unordered associative containers!\idxcode{const_local_iterator}}% - \indextext{\idxcode{const_local_iterator}!unordered associative containers}% -& compile time -\\ \rowsep -% -\tcode{X(n, hf, eq)}\br \tcode{X a(n, hf, eq)} -& X -& \requires\ \tcode{hasher} and \tcode{key_equal} are \tcode{CopyConstructible}.\br - \effects\ Constructs an empty container with at least \tcode{n} buckets, -using \tcode{hf} as the hash function and \tcode{eq} as the key -equality predicate. -& \bigoh{n} -\\ \rowsep -% -\tcode{X(n, hf)}\br \tcode{X a(n, hf)} -& X -& \requires\ \tcode{hasher} is \tcode{CopyConstructible} and \tcode{key_equal} - is \tcode{DefaultConstructible}.\br - \effects\ Constructs an empty container with at least \tcode{n} buckets, -using \tcode{hf} as the hash function and \tcode{key_equal()} as the key -equality predicate. -& \bigoh{n} -\\ \rowsep -% -\tcode{X(n)}\br \tcode{X a(n)} -& X -& \requires\ \tcode{hasher} and \tcode{key_equal} are \tcode{DefaultConstructible}.\br - \effects\ Constructs an empty container with at least \tcode{n} buckets, -using \tcode{hasher()} as the hash function and \tcode{key_equal()} -as the key equality predicate. -& \bigoh{n} -\\ \rowsep -% -\tcode{X()}\br \tcode{X a} -& X -& \requires\ \tcode{hasher} and \tcode{key_equal} are \tcode{DefaultConstructible}.\br - \effects\ Constructs an empty container with an unspecified number of - buckets, using \tcode{hasher()} as the hash function and - \tcode{key_equal()} as the key equality predicate. -& constant -\\ \rowsep -% -\tcode{X(i, j, n, hf, eq)}\br \tcode{X a(i, j, n, hf, eq)} -& X -& \requires\ \tcode{hasher} and \tcode{key_equal} are \tcode{CopyConstructible}. - \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br - \effects\ Constructs an empty container with at least \tcode{n} buckets, -using \tcode{hf} as the hash function and \tcode{eq} as the key -equality predicate, and inserts elements from \tcode{[i, j)} into it. -& Average case \bigoh{N} ($N$ is \tcode{distance(i, j)}), worst case -\bigoh{N^2} -\\ \rowsep -% -\tcode{X(i, j, n, hf)}\br \tcode{X a(i, j, n, hf)} -& X -& \requires\ \tcode{hasher} is \tcode{CopyConstructible} and \tcode{key_equal} - is \tcode{DefaultConstructible}. - \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br - \effects\ Constructs an empty container with at least \tcode{n} buckets, -using \tcode{hf} as the hash function and \tcode{key_equal()} as the key -equality predicate, and inserts elements from \tcode{[i, j)} into it. -& Average case \bigoh{N} ($N$ is \tcode{distance(i, j)}), worst case -\bigoh{N^2} -\\ \rowsep -% -\tcode{X(i, j, n)}\br \tcode{X a(i, j, n)} -& X -& \requires\ \tcode{hasher} and \tcode{key_equal} are \tcode{DefaultConstructible}. - \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br - \effects\ Constructs an empty container with at least \tcode{n} buckets, -using \tcode{hasher()} as the hash function and \tcode{key_equal()} -as the key equality predicate, and inserts elements from \tcode{[i, j)} -into it. -& Average case \bigoh{N} ($N$ is \tcode{distance(i, j)}), worst case -\bigoh{N^2} -\\ \rowsep -% -\tcode{X(i, j)}\br \tcode{X a(i, j)} -& X -& \requires\ \tcode{hasher} and \tcode{key_equal} are \tcode{DefaultConstructible}. - \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br - \effects\ Constructs an empty container with an unspecified number of -buckets, using \tcode{hasher()} as the hash function and -\tcode{key_equal()} as the key equality predicate, and inserts elements -from \tcode{[i, j)} into it. -& Average case \bigoh{N} ($N$ is \tcode{distance(i, j)}), worst case -\bigoh{N^2} -\\ \rowsep -% -\tcode{X(il)} -& \tcode{X} -& Same as \tcode{X(il.begin(), il.end())}. -& Same as \tcode{X(il.begin(),} \tcode{il.end())}. -\\ \rowsep -% -\tcode{X(il, n)} -& \tcode{X} -& Same as \tcode{X(il.begin(), il.end(), n)}. -& Same as \tcode{X(il.begin(),} \tcode{il.end(), n)}. -\\ \rowsep -% -\tcode{X(il, n, hf)} -& \tcode{X} -& Same as \tcode{X(il.begin(), il.end(), n, hf)}. -& Same as \tcode{X(il.begin(),} \tcode{il.end(), n, hf)}. -\\ \rowsep -% -\tcode{X(il, n, hf, eq)} -& \tcode{X} -& Same as \tcode{X(il.begin(), il.end(), n, hf, eq)}. -& Same as \tcode{X(il.begin(),} \tcode{il.end(), n, hf, eq)}. -\\ \rowsep -% -\tcode{X(b)}\br \tcode{X a(b)} -& \tcode{X} -& Copy constructor. In addition to the requirements - of Table~\ref{tab:containers.container.requirements}, copies the - hash function, predicate, and maximum load factor. -& Average case linear in \tcode{b.size()}, worst case quadratic. -\\ \rowsep -% -\tcode{a = b} -& \tcode{X\&} -& Copy assignment operator. In addition to the - requirements of Table~\ref{tab:containers.container.requirements}, copies - the hash function, predicate, and maximum load factor. -& Average case linear in \tcode{b.size()}, worst case quadratic. -\\ \rowsep -% -\tcode{a = il} -& \tcode{X\&} -& \requires\ \tcode{value_type} is -\tcode{CopyInsertable} into \tcode{X} -and \tcode{CopyAssignable}.\br - \effects\ Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. All - existing elements of \tcode{a} are either assigned to or destroyed. -& Same as \tcode{a = X(il).} -\\ \rowsep -% -\tcode{b.hash_function()} -& \tcode{hasher} -& Returns \tcode{b}'s hash function.% - \indextext{unordered associative containers!\idxcode{hash_function}}% - \indextext{\idxcode{hash_function}!unordered associative containers}% -& constant -\\ \rowsep -% -\tcode{b.key_eq()} -& \tcode{key_equal} -& Returns \tcode{b}'s key equality predicate.% - \indextext{unordered associative containers!\idxcode{key_eq}}% - \indextext{\idxcode{key_eq}!unordered associative containers}% -& constant -\\ \rowsep -% - -\tcode{a_uniq.} \tcode{emplace(args)} & - \tcode{pair} & - \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br - \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with - \tcode{std::forward(args)...} if and only if there is no - element in the container with key equivalent to the key of \tcode{t}. - The \tcode{bool} component of the returned - pair is true if and only if the insertion takes place, and the iterator - component of the pair points to the element with key equivalent to the - key of \tcode{t}. & - Average case \bigoh{1}, worst case \bigoh{\tcode{a_uniq.}\br\tcode{size()}}. -\\ \rowsep - -\tcode{a_eq.}\tcode{emplace(args)} & - \tcode{iterator} & - \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br - \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with - \tcode{std::forward(args)...} and returns the iterator pointing - to the newly inserted element. & - Average case \bigoh{1}, worst case \bigoh{\tcode{a_eq.}\br\tcode{size()}}. -\\ \rowsep - -\tcode{a.emplace_hint(p, args)} & - \tcode{iterator} & - \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br - \effects\ Equivalent to \tcode{a.emplace(} \tcode{std::forward(args)...)}. - Return value is an iterator pointing to the element with the key equivalent - to the newly inserted element. The \tcode{const_iterator} \tcode{p} - is a hint pointing to where the search should start. Implementations are - permitted to ignore the hint. & - Average case \bigoh{1}, worst case \bigoh{\tcode{a.} \tcode{size()}}. -\\ \rowsep - -\tcode{a_uniq.insert(t)} -& \tcode{pair} -& \requires\ If \tcode{t} is a non-const rvalue expression, \tcode{value_type} shall be - \tcode{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be - \tcode{CopyInsertable} into \tcode{X}.\br - \effects\ Inserts \tcode{t} if and only if there is no element in the container - with key equivalent to the key of \tcode{t}. The \tcode{bool} - component of the returned pair indicates whether the insertion - takes place, and the \tcode{iterator} component points to the element - with key equivalent to the key of \tcode{t}.% - \indextext{unordered associative containers!\idxcode{insert}}% - \indextext{\idxcode{insert}!unordered associative containers}% -& Average case \bigoh{1}, worst case \bigoh{\tcode{a_uniq.}\br\tcode{size()}}. -\\ \rowsep -% -\tcode{a_eq.insert(t)} -& \tcode{iterator} -& \requires\ If \tcode{t} is a non-const rvalue expression, \tcode{value_type} shall be - \tcode{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be - \tcode{CopyInsertable} into \tcode{X}.\br - \effects\ Inserts \tcode{t}, and returns an iterator pointing to the newly - inserted element. - \indextext{unordered associative containers!\idxcode{insert}}% - \indextext{\idxcode{insert}!unordered associative containers}% -& Average case \bigoh{1}, worst case \bigoh{\tcode{a_eq.}\br\tcode{size()}}. -\\ \rowsep -% -\tcode{a.insert(q, t)} -& \tcode{iterator} -& \requires\ If \tcode{t} is a non-const rvalue expression, \tcode{value_type} shall be - \tcode{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be - \tcode{CopyInsertable} into \tcode{X}.\br - \effects\ Equivalent to a.insert(t). Return value is an iterator pointing -to the element with the key equivalent to that of \tcode{t}. The -iterator \tcode{q} is a hint pointing to where the search should -start. Implementations are permitted to ignore the hint.% - \indextext{unordered associative containers!\idxcode{insert}}% - \indextext{\idxcode{insert}!unordered associative containers}% -& Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. -\\ \rowsep -% -\tcode{a.insert(i, j)} -& \tcode{void} -& \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br - Pre: \tcode{i} and \tcode{j} are not iterators in \tcode{a}. - Equivalent to \tcode{a.insert(t)} for each element in \tcode{[i,j)}.% - \indextext{unordered associative containers!\idxcode{insert}}% - \indextext{\idxcode{insert}!unordered associative containers}% -& Average case \bigoh{N}, where $N$ is \tcode{distance(i, j)}. Worst - case \bigoh{N * \tcode{(a.size())}\br\tcode{+ N}}. -\\ \rowsep -% -\tcode{a.insert(il)} -& \tcode{void} -& Same as \tcode{a.insert(il.begin(), il.end())}. -& Same as \tcode{a.insert(} \tcode{il.begin(),} \tcode{il.end())}. -\\ \rowsep -% -\tcode{a.erase(k)} -& \tcode{size_type} -& Erases all elements with key equivalent to \tcode{k}. Returns -the number of elements erased. -& Average case \bigoh{\tcode{a.count(k)}}. Worst case - \bigoh{\tcode{a.size()}}. -\\ \rowsep -% -\tcode{a.erase(q)} -& \tcode{iterator} -& Erases the element pointed to by \tcode{q}. Return value is the - iterator immediately following \tcode{q} prior to the erasure. - \indextext{unordered associative containers!\idxcode{erase}}% - \indextext{\idxcode{erase}!unordered associative containers}% -& Average case \bigoh{1}, worst case \bigoh{\tcode{a.size()}}. -\\ \rowsep -% -\tcode{a.erase(q1, q2)} -& \tcode{iterator} -& Erases all elements in the range \tcode{[q1, q2)}. Return value is - the iterator immediately following the erased elements prior to the - erasure.% - \indextext{unordered associative containers!\idxcode{erase}}% - \indextext{\idxcode{erase}!unordered associative containers}% -& Average case linear in \tcode{distance(q1, q2)}, - worst case \bigoh{\tcode{a.size()}}. -\\ \rowsep -% -\tcode{a.clear()} -& \tcode{void} -& Erases all elements in the container. - Post: \tcode{a.empty()} returns \tcode{true}% - \indextext{unordered associative containers!\idxcode{clear}}% - \indextext{\idxcode{clear}!unordered associative containers}% -& Linear. -\\ \rowsep -% -\tcode{b.find(k)} -& \tcode{iterator}; \br \tcode{const_iterator} for const \tcode{b}. -& Returns an iterator pointing to an element with key equivalent to - \tcode{k}, or \tcode{b.end()} if no such element exists.% - \indextext{unordered associative containers!\idxcode{find}}% - \indextext{\idxcode{find}!unordered associative containers}% -& Average case \bigoh{1}, worst case \bigoh{\tcode{b.size()}}. -\\ \rowsep -% -\tcode{b.count(k)} -& \tcode{size_type} -& Returns the number of elements with key equivalent to \tcode{k}.% - \indextext{unordered associative containers!\idxcode{count}}% - \indextext{\idxcode{count}!unordered associative containers}% -& Average case \bigoh{\tcode{b.count(k)}}, worst case \bigoh{\tcode{b.size()}}. -\\ \rowsep -% -\tcode{b.equal_range(k)} -& \tcode{pair}; \br - \tcode{pair} for const \tcode{b}. -& Returns a range containing all elements with keys equivalent to - \tcode{k}. Returns \tcode{make_pair(b.end(), b.end())} if - no such elements exist.% - \indextext{unordered associative containers!\idxcode{equal_range}}% - \indextext{\idxcode{equal_range}!unordered associative containers}% -& Average case \bigoh{\tcode{b.count(k)}}. Worst case - \bigoh{\tcode{b.size()}}. -\\ \rowsep -% -\tcode{b.bucket_count()} -& \tcode{size_type} -& Returns the number of buckets that \tcode{b} contains.% - \indextext{unordered associative containers!\idxcode{bucket_count}}% - \indextext{\idxcode{bucket_count}!unordered associative containers}% -& Constant -\\ \rowsep -% -\tcode{b.max_bucket_count()} -& \tcode{size_type} -& Returns an upper bound on the number of buckets that \tcode{b} might - ever contain.% - \indextext{unordered associative containers!\idxcode{max_bucket_count}}% - \indextext{\idxcode{max_bucket_count}!unordered associative containers}% -& Constant -\\ \rowsep -% -\tcode{b.bucket(k)} -& \tcode{size_type} -& - Pre: \tcode{b.bucket_count() > 0}.\br - Returns the index of the bucket in which elements with keys equivalent - to \tcode{k} would be found, if any such element existed. - Post: the return value shall be in the range \tcode{[0, b.bucket_count())}.% - \indextext{unordered associative containers!\idxcode{bucket}}% - \indextext{\idxcode{bucket}!unordered associative containers}% -& Constant -\\ \rowsep -% -\tcode{b.bucket_size(n)} -& \tcode{size_type} -& Pre: \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. - Returns the number of elements in the $\texttt{n}^{\textrm{ th}}$ bucket.% - \indextext{unordered associative containers!\idxcode{bucket_size}}% - \indextext{\idxcode{bucket_size}!unordered associative containers}% -& \bigoh{\tcode{b.bucket_}\-\tcode{size(n)}} -\\ \rowsep -% -\tcode{b.begin(n)} -& \tcode{local_iterator}; \br - \tcode{const_local_iterator} for const \tcode{b}. -& Pre: \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. - \tcode{b.begin(n)} returns an iterator referring to the - first element in the bucket. If the bucket is empty, then - \tcode{b.begin(n) == b.end(n)}.% - \indextext{unordered associative containers!\idxcode{begin}}% - \indextext{\idxcode{begin}!unordered associative containers}% -& Constant -\\ \rowsep -% -\tcode{b.end(n)} -& \tcode{local_iterator}; \br - \tcode{const_local_iterator} for const \tcode{b}. -& Pre: \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. - \tcode{b.end(n)} returns an iterator which is the past-the-end - value for the bucket.% - \indextext{unordered associative containers!\idxcode{end}}% - \indextext{\idxcode{end}!unordered associative containers}% -& Constant -\\ \rowsep -% -\tcode{b.cbegin(n)} -& \tcode{const_local_iterator} -& Pre: \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. - Note: \tcode{[b.cbegin(n), b.cend(n))} is a valid range containing - all of the elements in the $\texttt{n}^{\textrm{ th}}$ bucket.% - \indextext{unordered associative containers!\idxcode{cbegin}}% - \indextext{\idxcode{cbegin}!unordered associative containers}% -& Constant -\\ \rowsep -% -\tcode{b.cend(n)} -& \tcode{const_local_iterator} -& Pre: \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}.% - \indextext{unordered associative containers!\idxcode{cend}}% - \indextext{\idxcode{cend}!unordered associative containers}% -& Constant -\\ \rowsep -% -\tcode{b.load_factor()} -& \tcode{float} -& Returns the average number of elements per bucket.% - \indextext{unordered associative containers!\idxcode{load_factor}}% - \indextext{\idxcode{load_factor}!unordered associative containers}% -& Constant -\\ \rowsep -% -\tcode{b.max_load_factor()} -& \tcode{float} -& Returns a positive number that the container attempts to keep the load factor - less than or equal to. The container automatically increases the - number of buckets as necessary to keep the load factor below this - number.% - \indextext{unordered associative containers!\idxcode{max_load_factor}}% - \indextext{\idxcode{max_load_factor}!unordered associative containers}% -& Constant -\\ \rowsep -% -\tcode{a.max_load_factor(z)} -& \tcode{void} -& Pre: \tcode{z} shall be positive. - May change the container's maximum load factor, using \tcode{z} as a hint.% -& Constant -\\ \rowsep -% -\tcode{a.rehash(n)} -& \tcode{void} -& Post: \tcode{a.bucket_count() > a.size() / a.max_load_factor()} and - \tcode{a.bucket_count() >= n}.% - \indextext{unordered associative containers!\idxcode{rehash}}% - \indextext{\idxcode{rehash}!unordered associative containers}% -& Average case linear in \tcode{a.size()}, worst case quadratic. -\\ \rowsep - -\tcode{a.reserve(n)} & - \tcode{void} & - Same as \tcode{a.rehash(ceil(n /} \tcode{a.max_load_factor()))}. & - Average case linear in \tcode{a.size()}, worst case quadratic. \\ - -\end{libreqtab4d} -\pnum -Two unordered containers \tcode{a} and \tcode{b} compare equal if -\tcode{a.size() == b.size()} and, for every equivalent-key group -\range{Ea1}{Ea2} obtained from \tcode{a.equal_range(Ea1)}, there exists an -equivalent-key group \range{Eb1}{Eb2} obtained from \tcode{b.equal_range(Ea1)}, -such that -\tcode{is_permutation(Ea1, Ea2, Eb1, Eb2)} returns \tcode{true}. For -\tcode{unordered_set} and \tcode{unordered_map}, the complexity of -\tcode{operator==} (i.e., the number of calls to the \tcode{==} operator -of the \tcode{value_type}, to the predicate returned by \tcode{key_equal()}, -and to the hasher returned by \tcode{hash_function()}) is proportional to -$N$ in the average case and to $N^2$ in the worst case, where $N$ is -a.size(). For \tcode{unordered_multiset} and \tcode{unordered_multimap}, -the complexity of \tcode{operator==} is proportional to $\sum E_i^2$ -in the average case and to $N^2$ in the worst case, where $N$ is \tcode{a.size()}, -and $E_i$ is the size of the $i^{th}$ equivalent-key group in \tcode{a}. -However, if the respective elements of each corresponding pair of -equivalent-key groups $Ea_i$ and $Eb_i$ are arranged in the same order -(as is commonly the case, e.g., if \tcode{a} and \tcode{b} are unmodified copies -of the same container), then the average-case complexity for -\tcode{unordered_multiset} and \tcode{unordered_multimap} becomes -proportional to $N$ (but worst-case complexity remains \bigoh{N^2}, e.g., for -a pathologically bad hash function). The behavior of a program that uses -\tcode{operator==} or \tcode{operator!=} on unordered containers is undefined -unless the \tcode{Hash} and \tcode{Pred} function objects respectively have -the same behavior for both containers and the equality comparison operator -for \tcode{Key} is a refinement\footnote{Equality comparison is a refinement -of partitioning if no two objects that -compare equal fall into different partitions.} -of the partition into equivalent-key groups produced by \tcode{Pred}. +\indexlibrarymember{insert}{flat_set}% +\begin{itemdecl} +template + constexpr void insert(InputIterator first, InputIterator last); +\end{itemdecl} +\begin{itemdescr} \pnum -\indextext{unordered associative containers!iterators}% -The iterator types \tcode{iterator} and \tcode{const_iterator} of -an unordered associative container are of at least the forward iterator -category. For unordered associative containers where the key type and -value type are the same, both \tcode{iterator} and -\tcode{const_iterator} are const iterators. +\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}; +merges the resulting sorted range and +the sorted range of pre-existing elements into a single sorted range; and +finally erases all but the first element +from each group of consecutive equivalent elements. \pnum -\indextext{unordered associative containers!iterator invalidation}% -The \tcode{insert} and \tcode{emplace} members shall not affect the validity of references to -container elements, but may invalidate all iterators to the -container. The \tcode{erase} members shall invalidate only iterators and -references to the erased elements, and preserve the relative order of the -elements that are not erased. +\complexity +$N$ + $M \log M$, where $N$ is \tcode{size()} before the operation and +$M$ is \tcode{distance(first, last)}. \pnum -\indextext{unordered associative containers!iterator invalidation}% -\indextext{unordered associative containers!requirements}% -The \tcode{insert} 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 -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. +\remarks +Since this operation performs an in-place merge, it may allocate memory. +\end{itemdescr} -\rSec3[unord.req.except]{Exception safety guarantees} +\indexlibrarymember{insert}{flat_set}% +\begin{itemdecl} +template + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); +\end{itemdecl} +\begin{itemdescr} \pnum -\indextext{unordered associative containers!exception safety}% -\indextext{unordered associative containers!requirements}% -For unordered associative containers, no \tcode{clear()} function -throws an exception. \tcode{erase(k)} does not throw an -exception unless that exception is thrown by the container's \tcode{Hash} or -\tcode{Pred} object (if any). +\effects +Equivalent to \tcode{insert(first, last)}. \pnum -For unordered associative containers, if an exception is thrown by any -operation other than the container's hash function from within an -\tcode{insert} or \tcode{emplace} function inserting a single element, -the insertion has no effect. +\complexity +Linear. +\end{itemdescr} + +\indexlibrarymember{insert_range}{flat_set}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(R&& rg); +\end{itemdecl} +\begin{itemdescr} \pnum -For unordered associative containers, no \tcode{swap} function throws -an exception unless that exception is thrown by the swap of the container's -Hash or Pred object (if any). +\effects +Adds elements to \exposid{c} as if by: +\begin{codeblock} +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}; +merges the resulting sorted range and +the sorted range of pre-existing elements into a single sorted range; and +finally erases all but the first element +from each group of consecutive equivalent elements. \pnum -\indextext{unordered associative containers!exception safety}% -\indextext{unordered associative containers!requirements}% -For unordered associative containers, if an exception is thrown -from within a \tcode{rehash()} function other than by the container's hash -function or comparison function, the \tcode{rehash()} function has no effect. +\complexity +$N$ + $M \log M$, where $N$ is \tcode{size()} before the operation and $M$ +is \tcode{ranges::distance(rg)}. -\rSec1[sequences]{Sequence containers} +\pnum +\remarks +Since this operation performs an in-place merge, it may allocate memory. +\end{itemdescr} -\rSec2[sequences.general]{In general} +\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 -The headers \tcode{}, \tcode{}, \tcode{}, -\tcode{}, and \tcode{} define template classes that meet the -requirements for sequence containers. +\effects +Equivalent to \tcode{insert_range(rg)}. \pnum -The headers \tcode{} and \tcode{} define container -adaptors~(\ref{container.adaptors}) that also meet the requirements for -sequence containers. +\complexity +Linear in $N$, where $N$ is \tcode{size()} after the operation. +\end{itemdescr} -\synopsis{Header \tcode{} synopsis}% -\indexlibrary{\idxhdr{array}}% -\begin{codeblock} -#include +\indexlibrarymember{swap}{flat_set}% +\begin{itemdecl} +constexpr void swap(flat_set& y) + noexcept(is_nothrow_swappable_v && + is_nothrow_swappable_v); +\end{itemdecl} -namespace std { - template struct array; - template - bool operator==(const array& x, const array& y); - template - bool operator!=(const array& x, const array& y); - template - bool operator<(const array& x, const array& y); - template - bool operator>(const array& x, const array& y); - template - bool operator<=(const array& x, const array& y); - template - bool operator>=(const array& x, const array& y); - template - void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); - - template class tuple_size; - template class tuple_element; - template - struct tuple_size >; - template - struct tuple_element >; - template - constexpr T& get(array&) noexcept; - template - constexpr T&& get(array&&) noexcept; - template - constexpr const T& get(const array&) noexcept; -} +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +ranges::swap(@\exposid{compare}@, y.@\exposid{compare}@); +ranges::swap(@\exposid{c}@, y.@\exposid{c}@); \end{codeblock} +\end{itemdescr} -\synopsis{Header \tcode{} synopsis}% -\indexlibrary{\idxhdr{deque}} - -\begin{codeblock} -#include +\indexlibrarymember{extract}{flat_set}% +\begin{itemdecl} +constexpr container_type extract() &&; +\end{itemdecl} -namespace std { - template > class deque; - template - bool operator==(const deque& x, const deque& y); - template - bool operator<(const deque& x, const deque& y); - template - bool operator!=(const deque& x, const deque& y); - template - bool operator>(const deque& x, const deque& y); - template - bool operator>=(const deque& x, const deque& y); - template - bool operator<=(const deque& x, const deque& y); - template - void swap(deque& x, deque& y) - noexcept(noexcept(x.swap(y))); -} -\end{codeblock} +\begin{itemdescr} +\pnum +\ensures +\tcode{*this} is emptied, even if the function exits via an exception. -\synopsis{Header \tcode{} synopsis}% -\indexlibrary{\idxhdr{forward_list}} +\pnum +\returns +\tcode{std::move(\exposid{c})}. +\end{itemdescr} -\begin{codeblock} -#include +\indexlibrarymember{replace}{flat_set}% +\begin{itemdecl} +constexpr void replace(container_type&& cont); +\end{itemdecl} -namespace std { - template > class forward_list; - template - bool operator==(const forward_list& x, const forward_list& y); - template - bool operator< (const forward_list& x, const forward_list& y); - template - bool operator!=(const forward_list& x, const forward_list& y); - template - bool operator> (const forward_list& x, const forward_list& y); - template - bool operator>=(const forward_list& x, const forward_list& y); - template - bool operator<=(const forward_list& x, const forward_list& y); - template - void swap(forward_list& x, forward_list& y) - noexcept(noexcept(x.swap(y))); -} -\end{codeblock} +\begin{itemdescr} +\pnum +\expects +The elements of \tcode{cont} are sorted with respect to \exposid{compare}, and +\tcode{cont} contains no equal elements. -\synopsis{Header \tcode{} synopsis}% -\indexlibrary{\idxhdr{list}} +\pnum +\effects +Equivalent to: \tcode{\exposid{c} = std::move(cont);} +\end{itemdescr} -\begin{codeblock} -#include +\rSec3[flat.set.erasure]{Erasure} -namespace std { - template > class list; - template - bool operator==(const list& x, const list& y); - template - bool operator< (const list& x, const list& y); - template - bool operator!=(const list& x, const list& y); - template - bool operator> (const list& x, const list& y); - template - bool operator>=(const list& x, const list& y); - template - bool operator<=(const list& x, const list& y); - template - void swap(list& x, list& y) - noexcept(noexcept(x.swap(y))); -} -\end{codeblock} +\indexlibrarymember{erase_if}{flat_set}% +\begin{itemdecl} +template + constexpr typename flat_set::size_type + erase_if(flat_set& c, Predicate pred); +\end{itemdecl} -\synopsis{Header \tcode{} synopsis}% -\indexlibrary{\idxhdr{vector}} +\begin{itemdescr} +\pnum +\expects +\tcode{Key} meets the \oldconcept{MoveAssignable} requirements. -\begin{codeblock} -#include +\pnum +\effects +Let $E$ be \tcode{bool(pred(as_const(e)))}. +Erases all elements \tcode{e} in \tcode{c} for which $E$ holds. -namespace std { - template > class vector; - template - bool operator==(const vector& x,const vector& y); - template - bool operator< (const vector& x,const vector& y); - template - bool operator!=(const vector& x,const vector& y); - template - bool operator> (const vector& x,const vector& y); - template - bool operator>=(const vector& x,const vector& y); - template - bool operator<=(const vector& x,const vector& y); - template - void swap(vector& x, vector& y) - noexcept(noexcept(x.swap(y))); +\pnum +\returns +The number of elements erased. - template class vector; +\pnum +\complexity +Exactly \tcode{c.size()} applications of the predicate. - // hash support - template struct hash; - template struct hash >; -} -\end{codeblock} +\pnum +\remarks +Stable\iref{algorithm.stable}. +If an invocation of \tcode{erase_if} exits via an exception, +\tcode{c} is in a valid but unspecified state\iref{defns.valid}. +\begin{note} +\tcode{c} still meets its invariants, but can be empty. +\end{note} +\end{itemdescr} -\rSec2[array]{Class template \tcode{array}} -\indexlibrary{\idxcode{array}}% +\rSec2[flat.multiset]{Class template \tcode{flat_multiset}} -\rSec3[array.overview]{Class template \tcode{array} overview} +\rSec3[flat.multiset.overview]{Overview} \pnum -\indextext{\idxcode{array}!contiguous storage}% -The header \tcode{} defines a class template for storing fixed-size -sequences of objects. -An \tcode{array} is a contiguous container~(\ref{container.requirements.general}). -An instance of \tcode{array} stores \tcode{N} elements of type \tcode{T}, -so that \tcode{size() == N} is an invariant. +\indexlibraryglobal{flat_multiset}% +A \tcode{flat_multiset} is a container adaptor +that provides an associative container interface +that supports equivalent keys +(i.e., possibly containing multiple copies of the same key value) and +provides for fast retrieval of the keys themselves. +\tcode{flat_multiset} supports iterators that model the +\libconcept{random_access_iterator} concept\iref{iterator.concept.random.access}. \pnum -\indextext{\idxcode{array}!initialization}% -\indextext{\idxcode{array}!as aggregate}% -An \tcode{array} is an aggregate~(\ref{dcl.init.aggr}) that can be -initialized with the syntax -\begin{codeblock} -array a = { @\textit{initializer-list}@ }; -\end{codeblock} +A \tcode{flat_multiset} meets all of the requirements +for a container\iref{container.reqmts} and +for a reversible container\iref{container.rev.reqmts}, +plus the optional container requirements\iref{container.opt.reqmts}. +\tcode{flat_multiset} meets the requirements of +an associative container\iref{associative.reqmts}, except that: +\begin{itemize} +\item +it does not meet the requirements +related to node handles\iref{container.node.overview}, +\item +it does not meet the requirements related to iterator invalidation, and +\item +the time complexity of the operations +that insert or erase a single element from the +set is linear, +including the ones that take an insertion position iterator. +\end{itemize} +\begin{note} +A \tcode{flat_multiset} does not meet +the additional requirements of an allocator-aware container, +as described in \ref{container.alloc.reqmts}. +\end{note} -where \textit{initializer-list} is a comma-separated list of up -to \tcode{N} elements whose types are convertible to \tcode{T}. +\pnum +A \tcode{flat_multiset} also provides most operations +described in \ref{associative.reqmts} for equal keys. +This means that a \tcode{flat_multiset} supports +the \tcode{a_eq} operations in \ref{associative.reqmts} +but not the \tcode{a_uniq} operations. +For a \tcode{flat_multiset}, +both the \tcode{key_type} and \tcode{value_type} are \tcode{Key}. \pnum -\indextext{requirements!container}% -An \tcode{array} satisfies all of the requirements of a container and -of a reversible container~(\ref{container.requirements}), except that a default -constructed \tcode{array} object is not empty and that \tcode{swap} does not have constant -complexity. An \tcode{array} satisfies some of the requirements of a sequence -container~(\ref{sequence.reqmts}). -Descriptions are provided here -only for operations on \tcode{array} that are not described in -one of these tables and +Descriptions are provided here only for operations on \tcode{flat_multiset} +that are not described in one of the general sections or for operations where there is additional semantic information. -\indexlibrary{\idxcode{array}}% -\indexlibrary{\idxcode{array}!\idxcode{begin}}% -\indexlibrary{\idxcode{begin}!\idxcode{array}}% -\indexlibrary{\idxcode{array}!\idxcode{end}}% -\indexlibrary{\idxcode{end}!\idxcode{array}}% -\indexlibrary{\idxcode{array}!\idxcode{size}}% -\indexlibrary{\idxcode{size}!\idxcode{array}}% -\indexlibrary{\idxcode{array}!\idxcode{max_size}}% -\indexlibrary{\idxcode{max_size}!\idxcode{array}}% -\begin{codeblock} -namespace std { - template - struct array { - // types: - typedef T& reference; - typedef const T& const_reference; - typedef @\impdefx{type of \tcode{array::iterator}}@ iterator; - typedef @\impdefx{type of \tcode{array::const_iterator}}@ const_iterator; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T value_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - T elems[N]; // \expos +\pnum +A \tcode{flat_multiset} maintains the invariant +that the keys are sorted with respect to the comparison object. - // no explicit construct/copy/destroy for aggregate type +\pnum +If any member function in \ref{flat.multiset.defn} exits via an exception, +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} - void fill(const T& u); - void swap(array&) noexcept(noexcept(swap(declval(), declval()))); +\pnum +Any sequence container\iref{sequence.reqmts} +supporting \oldconcept{RandomAccessIterator} +can be used to instantiate \tcode{flat_multiset}. +In particular, +\tcode{vector}\iref{vector} and \tcode{deque}\iref{deque} can be used. +\begin{note} +\tcode{vector} is not a sequence container. +\end{note} - // iterators: - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; +\pnum +The program is ill-formed if \tcode{Key} is not the same type +as \tcode{KeyContainer::value_type}. - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; +\pnum +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. - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; +\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} +namespace std { + template, class KeyContainer = vector> + 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 = 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 + constexpr flat_multiset() : flat_multiset(key_compare()) { } + + 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) { } + + constexpr explicit flat_multiset(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 + constexpr flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(), @\exposid{compare}@(comp) + { insert(first, last); } + + template + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) + : @\exposid{c}@(first, last), @\exposid{compare}@(comp) { } + + template<@\exposconcept{container-compatible-range}@ R> + constexpr flat_multiset(from_range_t, R&& rg) + : flat_multiset(from_range, std::forward(rg), key_compare()) { } + template<@\exposconcept{container-compatible-range}@ R> + constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp) + : flat_multiset(comp) + { insert_range(std::forward(rg)); } + + constexpr flat_multiset(initializer_list il, + const key_compare& comp = key_compare()) + : flat_multiset(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 + constexpr explicit flat_multiset(const Alloc& a); + template + constexpr flat_multiset(const key_compare& comp, const Alloc& a); + template + constexpr flat_multiset(const container_type& cont, const Alloc& a); + template + constexpr flat_multiset(const container_type& cont, const key_compare& comp, + const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, + const key_compare& comp, const Alloc& a); + template + constexpr flat_multiset(const flat_multiset&, const Alloc& a); + template + constexpr flat_multiset(flat_multiset&&, const Alloc& a); + template + constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a); + template + constexpr flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a); + template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + template + constexpr flat_multiset(initializer_list il, const Alloc& a); + template + constexpr flat_multiset(initializer_list il, const key_compare& comp, + const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, + const Alloc& a); + template + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); + + constexpr flat_multiset& operator=(initializer_list); - // capacity: + // iterators + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + + constexpr reverse_iterator rbegin() noexcept; + constexpr const_reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() noexcept; + constexpr const_reverse_iterator rend() const noexcept; + + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept; + constexpr const_reverse_iterator crend() const noexcept; + + // capacity + constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; - constexpr bool empty() const noexcept; - // element access: - reference operator[](size_type n); - constexpr const_reference operator[](size_type n) const; - reference at(size_type n); - constexpr const_reference at(size_type n) const; - reference front(); - constexpr const_reference front() const; - reference back(); - constexpr const_reference back() const; + // \ref{flat.multiset.modifiers}, modifiers + template constexpr iterator emplace(Args&&... args); + template + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + + constexpr iterator insert(const value_type& x) + { return emplace(x); } + constexpr iterator insert(value_type&& x) + { return emplace(std::move(x)); } + constexpr iterator insert(const_iterator position, const value_type& x) + { return emplace_hint(position, x); } + constexpr iterator insert(const_iterator position, value_type&& x) + { return emplace_hint(position, std::move(x)); } + + template + constexpr void insert(InputIterator first, InputIterator last); + template + constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(R&& rg); + template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(sorted_equivalent_t, R&& rg); + + constexpr void insert(initializer_list il) + { insert(il.begin(), il.end()); } + constexpr void insert(sorted_equivalent_t, initializer_list il) + { insert(sorted_equivalent, il.begin(), il.end()); } + + constexpr container_type extract() &&; + constexpr void replace(container_type&&); + + 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); + + constexpr void swap(flat_multiset& y) noexcept(@\seebelow@); + constexpr void clear() noexcept; - T * data() noexcept; - const T * data() const noexcept; + // observers + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; + + // set operations + constexpr iterator find(const key_type& x); + constexpr const_iterator find(const key_type& x) const; + template constexpr iterator find(const K& x); + template constexpr const_iterator find(const K& x) const; + + constexpr size_type count(const key_type& x) const; + template constexpr size_type count(const K& x) const; + + constexpr bool contains(const key_type& x) const; + template constexpr bool contains(const K& x) const; + + constexpr iterator lower_bound(const key_type& x); + constexpr const_iterator lower_bound(const key_type& x) const; + template constexpr iterator lower_bound(const K& x); + template constexpr const_iterator lower_bound(const K& x) const; + + constexpr iterator upper_bound(const key_type& x); + constexpr const_iterator upper_bound(const key_type& x) const; + template constexpr iterator upper_bound(const K& x); + template constexpr const_iterator upper_bound(const K& x) const; + + constexpr pair equal_range(const key_type& x); + constexpr pair equal_range(const key_type& x) const; + template + constexpr pair equal_range(const K& x); + template + constexpr pair equal_range(const K& x) const; + + friend constexpr bool operator==(const flat_multiset& x, const flat_multiset& y); + + friend constexpr @\exposid{synth-three-way-result}@ + operator<=>(const flat_multiset& x, const flat_multiset& y); + + friend constexpr void swap(flat_multiset& x, flat_multiset& y) + noexcept(noexcept(x.swap(y))) + { x.swap(y); } + + private: + container_type @\exposidnc{c}@; // \expos + key_compare @\exposidnc{compare}@; // \expos }; + + template> + flat_multiset(KeyContainer, Compare = Compare()) + -> flat_multiset; + template + flat_multiset(KeyContainer, Allocator) + -> flat_multiset, KeyContainer>; + template + flat_multiset(KeyContainer, Compare, Allocator) + -> flat_multiset; + + template> + flat_multiset(sorted_equivalent_t, KeyContainer, Compare = Compare()) + -> flat_multiset; + template + flat_multiset(sorted_equivalent_t, KeyContainer, Allocator) + -> flat_multiset, KeyContainer>; + template + flat_multiset(sorted_equivalent_t, KeyContainer, Compare, Allocator) + -> flat_multiset; + + template>> + flat_multiset(InputIterator, InputIterator, Compare = Compare()) + -> flat_multiset<@\placeholder{iter-value-type}@, Compare>; + + template>> + flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare()) + -> flat_multiset<@\placeholder{iter-value-type}@, Compare>; + + template>, + class Allocator = allocator>> + flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) + -> flat_multiset, Compare, + vector, + @\exposid{alloc-rebind}@>>>; + + template + flat_multiset(from_range_t, R&&, Allocator) + -> flat_multiset, less>, + vector, + @\exposid{alloc-rebind}@>>>; + + template> + flat_multiset(initializer_list, Compare = Compare()) + -> flat_multiset; + + template> + flat_multiset(sorted_equivalent_t, initializer_list, Compare = Compare()) + -> flat_multiset; + + template + struct uses_allocator, Allocator> + : bool_constant> { }; } \end{codeblock} -\pnum -\enternote The member variable \tcode{elems} is shown for exposition only, -to emphasize that \tcode{array} is a class aggregate. The name \tcode{elems} -is not part of \tcode{array}'s interface. \exitnote +\rSec3[flat.multiset.cons]{Constructors} -\rSec3[array.cons]{\tcode{array} constructors, copy, and assignment} +\indexlibraryctor{flat_multiset}% +\begin{itemdecl} +constexpr explicit flat_multiset(container_type cont, const key_compare& comp = key_compare()); +\end{itemdecl} +\begin{itemdescr} \pnum -\indextext{\idxcode{array}!initialization}% -\indextext{requirements!container}% -The conditions for an aggregate~(\ref{dcl.init.aggr}) shall be -met. Class \tcode{array} relies on the implicitly-declared special -member functions~(\ref{class.ctor}, \ref{class.dtor}, and \ref{class.copy}) to -conform to the container requirements table in~\ref{container.requirements}. -In addition to the requirements specified in the container requirements table, -the implicit move constructor and move assignment operator for \tcode{array} -require that \tcode{T} be \tcode{MoveConstructible} or \tcode{MoveAssignable}, -respectively. +\effects +Initializes \exposid{c} with \tcode{std::move(cont)} and +\exposid{compare} with \tcode{comp}, and +sorts the range \range{begin()}{end()} with respect to \exposid{compare}. -\rSec3[array.special]{\tcode{array} specialized algorithms} +\pnum +\complexity +Linear in $N$ if \tcode{cont} is already sorted with respect to \exposid{compare} and +otherwise $N \log N$, where $N$ is the value of \tcode{cont.size()} before this call. +\end{itemdescr} + +\rSec3[flat.multiset.cons.alloc]{Constructors with allocators} -\indexlibrary{\idxcode{array}!\idxcode{swap}}% -\indexlibrary{\idxcode{swap}!\idxcode{array}}% +\pnum +The constructors in this subclause shall not participate in overload resolution +unless \tcode{uses_allocator_v} is \tcode{true}. + +\indexlibraryctor{flat_multiset}% \begin{itemdecl} -template void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); +template + constexpr flat_multiset(const container_type& cont, const Alloc& a); +template + constexpr flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum\effects -\begin{codeblock} -x.swap(y); -\end{codeblock} +\pnum +\effects +Equivalent to \tcode{flat_multiset(cont)} and +\tcode{flat_multiset(cont, comp)}, respectively, +except that \exposid{c} is constructed with +uses-allocator construction\iref{allocator.uses.construction}. \pnum -\complexity Linear in \tcode{N}. +\complexity +Same as \tcode{flat_multiset(cont)} and +\tcode{flat_multiset(cont, comp)}, respectively. \end{itemdescr} -\rSec3[array.size]{\tcode{array::size}} - -\indexlibrary{\idxcode{array}!\idxcode{size}}% -\indexlibrary{\idxcode{size}!\idxcode{array}}% +\indexlibraryctor{flat_multiset}% \begin{itemdecl} -template constexpr size_type array::size() const noexcept; +template + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a); +template + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum\returns \tcode{N} +\pnum +\effects +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}. + +\pnum +\complexity +Linear. \end{itemdescr} -\rSec3[array.data]{\tcode{array::data}} -\indexlibrary{\idxcode{array}!\idxcode{data}}% -\indexlibrary{\idxcode{data}!\idxcode{array}}% +\indexlibraryctor{flat_multiset}% \begin{itemdecl} -T* data() noexcept; -const T* data() const noexcept; +template + constexpr explicit flat_multiset(const Alloc& a); +template + constexpr flat_multiset(const key_compare& comp, const Alloc& a); +template + constexpr flat_multiset(const flat_multiset&, const Alloc& a); +template + constexpr flat_multiset(flat_multiset&&, const Alloc& a); +template + constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a); +template + constexpr flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); +template + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); +template + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a); +template<@\exposconcept{container-compatible-range}@ R, class Alloc> + constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); +template + constexpr flat_multiset(initializer_list il, const Alloc& a); +template + constexpr flat_multiset(initializer_list il, const key_compare& comp, + const Alloc& a); +template + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, const Alloc& a); +template + constexpr flat_multiset(sorted_equivalent_t, initializer_list il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} -\pnum \returns \tcode{elems}. +\pnum +\effects +Equivalent to the corresponding non-allocator constructors +except that \exposid{c} is constructed with +uses-allocator construction\iref{allocator.uses.construction}. \end{itemdescr} -\rSec3[array.fill]{\tcode{array::fill}} +\rSec3[flat.multiset.modifiers]{Modifiers} -\indexlibrary{\idxcode{array}!\idxcode{fill}}% -\indexlibrary{\idxcode{fill}!\idxcode{array}}% +\indexlibrarymember{emplace}{flat_multiset}% \begin{itemdecl} -void fill(const T& u); +template constexpr iterator emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum -\effects \tcode{fill_n(begin(), N, u)} -\end{itemdescr} +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\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} -\rSec3[array.swap]{\tcode{array::swap}} +\pnum +\returns +An iterator that points to the inserted element. +\end{itemdescr} -\indexlibrary{\idxcode{array}!\idxcode{swap}}% -\indexlibrary{\idxcode{swap}!\idxcode{array}}% +\indexlibrarymember{insert}{flat_multiset}% \begin{itemdecl} -void swap(array& y) noexcept(noexcept(swap(declval(), declval()))); +template + constexpr void insert(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum -\effects \tcode{swap_ranges(begin(), end(), y.begin())} +\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 -\throws Nothing unless one of the element-wise swap calls throws an exception. +\effects +Equivalent to \tcode{insert(first, last)}. \pnum -\realnote Unlike the \tcode{swap} function for other containers, \tcode{array::swap} -takes linear time, may exit via an exception, and does not cause iterators to -become associated with the other container. +\complexity +Linear in $N$, where $N$ is \tcode{size()} after the operation. \end{itemdescr} -\rSec3[array.zero]{Zero sized arrays} +\indexlibrarymember{insert_range}{flat_multiset}% +\begin{itemdecl} +template<@\exposconcept{container-compatible-range}@ R> + constexpr void insert_range(R&& rg); +\end{itemdecl} -\indextext{\idxcode{array}!zero sized}% -\pnum\tcode{array} shall provide support for the special case \tcode{N == 0}. +\begin{itemdescr} +\pnum +\effects +Adds elements to \exposid{c} as if by: +\begin{codeblock} +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 +the sorted range of pre-existing elements into a single sorted range. -\pnum In the case that \tcode{N == 0}, \tcode{begin() == end() ==} unique value. -The return value of \tcode{data()} is unspecified. +\pnum +\complexity +$N$ + $M \log M$, where $N$ is \tcode{size()} before the operation and $M$ +is \tcode{ranges::distance(rg)}. \pnum -The effect of calling \tcode{front()} or \tcode{back()} for a zero-sized array is -undefined. +\remarks +Since this operation performs an in-place merge, +it may allocate memory. +\end{itemdescr} + +\indexlibrarymember{insert_range}{flat_multiset}% +\begin{itemdecl} +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_range(rg)}. \pnum -Member function \tcode{swap()} shall have a \grammarterm{noexcept-specification} -which is equivalent to \tcode{noexcept(true)}. +\complexity +Linear in $N$, where $N$ is \tcode{size()} after the operation. +\end{itemdescr} -\rSec3[array.tuple]{Tuple interface to class template \tcode{array}} -\indexlibrary{\idxcode{array}}% -\indexlibrary{\idxcode{tuple}}% -\indextext{\idxcode{array}!tuple interface to}% -\indexlibrary{\idxcode{tuple_size}}% +\indexlibrarymember{swap}{flat_multiset}% \begin{itemdecl} -template -struct tuple_size> - : integral_constant { }; +constexpr void swap(flat_multiset& y) + noexcept(is_nothrow_swappable_v && + is_nothrow_swappable_v); \end{itemdecl} -\indexlibrary{\idxcode{tuple_element}}% +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +ranges::swap(@\exposid{compare}@, y.@\exposid{compare}@); +ranges::swap(@\exposid{c}@, y.@\exposid{c}@); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{extract}{flat_multiset}% \begin{itemdecl} -tuple_element >::type +constexpr container_type extract() &&; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{I < N}. The program is ill-formed if \tcode{I} is out of bounds. +\ensures +\tcode{*this} is emptied, even if the function exits via an exception. \pnum -\cvalue The type T. +\returns +\tcode{std::move(\exposid{c})}. \end{itemdescr} -\indexlibrary{\idxcode{array}!\idxcode{get}}% -\indexlibrary{\idxcode{get}!\idxcode{array}}% +\indexlibrarymember{replace}{flat_multiset}% \begin{itemdecl} -template -constexpr T& get(array& a) noexcept; +constexpr void replace(container_type&& cont); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{I < N}. The program is ill-formed if \tcode{I} is out of bounds. +\expects +The elements of \tcode{cont} are sorted with respect to \exposid{compare}. \pnum -\returns A reference to the \tcode{I}th element of \tcode{a}, -where indexing is zero-based. +\effects +Equivalent to: \tcode{\exposid{c} = std::move(cont);} \end{itemdescr} -\indexlibrary{\idxcode{array}!\idxcode{get}}% -\indexlibrary{\idxcode{get}!\idxcode{array}}% +\rSec3[flat.multiset.erasure]{Erasure} + +\indexlibrarymember{erase_if}{flat_multiset}% \begin{itemdecl} -template -constexpr T&& get(array&& a) noexcept; +template + constexpr typename flat_multiset::size_type + erase_if(flat_multiset& c, Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum -\effects Equivalent to \tcode{return std::move(get(a));} +\expects +\tcode{Key} meets the \oldconcept{MoveAssignable} requirements. + +\pnum +\effects +Let $E$ be \tcode{bool(pred(as_const(e)))}. +Erases all elements \tcode{e} in \tcode{c} for which $E$ holds. + +\pnum +\returns +The number of elements erased. + +\pnum +\complexity +Exactly \tcode{c.size()} applications of the predicate. + +\pnum +\remarks +Stable\iref{algorithm.stable}. +If an invocation of \tcode{erase_if} exits via an exception, +\tcode{c} is in a valid but unspecified state\iref{defns.valid}. +\begin{note} +\tcode{c} still meets its invariants, but can be empty. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{array}!\idxcode{get}}% -\indexlibrary{\idxcode{get}!\idxcode{array}}% +\rSec2[container.adaptors.format]{Container adaptors formatting} + +\pnum +For each of +\tcode{queue}, +\tcode{priority_queue}, and +\tcode{stack}, +the library provides the following constexpr-enabled formatter specialization +where \tcode{\placeholder{adaptor-type}} is the name of the template: + +\indexlibraryglobal{formatter}% +\begin{codeblock} +namespace std { + template Container, class... U> + struct formatter<@\placeholder{adaptor-type}@, charT> { + private: + using @\exposid{maybe-const-container}@ = // \expos + @\exposid{fmt-maybe-const}@; + using @\exposid{maybe-const-adaptor}@ = // \expos + @\exposid{maybe-const}@, // see \ref{ranges.syn} + @\placeholder{adaptor-type}@>; + formatter, charT> @\exposid{underlying_}@; // \expos + + public: + template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); + + template + constexpr typename FormatContext::iterator + format(@\exposid{maybe-const-adaptor}@& r, FormatContext& ctx) const; + }; +} +\end{codeblock} + +\indexlibrarymember{parse}{formatter}% \begin{itemdecl} -template -constexpr const T& get(const array& a) noexcept; +template + constexpr typename ParseContext::iterator + parse(ParseContext& ctx); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{I < N}. The program is ill-formed if \tcode{I} is out of bounds. +\effects +Equivalent to: \tcode{return \exposid{underlying_}.parse(ctx);} +\end{itemdescr} + +\indexlibrarymember{format}{formatter}% +\begin{itemdecl} +template + constexpr typename FormatContext::iterator + format(@\exposid{maybe-const-adaptor}@& r, FormatContext& ctx) const; +\end{itemdecl} +\begin{itemdescr} \pnum -\returns A const reference to the \tcode{I}th element of \tcode{a}, -where indexing is zero-based. +\effects +Equivalent to: \tcode{return \exposid{underlying_}.format(r.c, ctx);} \end{itemdescr} -\rSec2[deque]{Class template \tcode{deque}} +\rSec1[views]{Views} -\rSec3[deque.overview]{Class template \tcode{deque} overview} +\rSec2[views.general]{General} \pnum -A -\indexlibrary{\idxcode{deque}}% -\tcode{deque} -is a sequence container that, like a -\tcode{vector}~(\ref{vector}), supports random access iterators. -In addition, it supports constant time insert and erase operations at the beginning or the end; -insert and erase in the middle take linear time. -That is, a deque is especially optimized for pushing and popping elements at the beginning and end. -As with vectors, storage management is handled automatically. +The header \libheaderref{span} defines the view \tcode{span}. +The header \libheaderref{mdspan} defines the class template \tcode{mdspan} and +other facilities for interacting with these multidimensional views. \pnum -A -\tcode{deque} -satisfies all of the requirements of a container, of a reversible container -(given in tables in~\ref{container.requirements}), of a sequence container, -including the optional sequence container requirements~(\ref{sequence.reqmts}), and of an allocator-aware container (Table~\ref{tab:containers.allocatoraware}). -Descriptions are provided here only for operations on -\tcode{deque} -that are not described in one of these tables -or for operations where there is additional semantic information. +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} +// mostly freestanding namespace std { - template > - class deque { - public: - // types: - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ iterator; // See \ref{container.requirements} - typedef @\impdef@ const_iterator; // See \ref{container.requirements} - typedef @\impdef@ size_type; // See \ref{container.requirements} - typedef @\impdef@ difference_type;// See \ref{container.requirements} - typedef T value_type; - typedef Allocator allocator_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_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()); - template - deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); - deque(const deque& x); - deque(deque&&); - deque(const deque&, const Allocator&); - deque(deque&&, const Allocator&); - deque(initializer_list, const Allocator& = Allocator()); - - ~deque(); - deque& operator=(const deque& x); - deque& operator=(deque&& x) - noexcept(allocator_traits::is_always_equal::value); - deque& operator=(initializer_list); - template - void assign(InputIterator first, InputIterator last); - void assign(size_type n, const T& t); - void assign(initializer_list); - allocator_type get_allocator() const noexcept; + // constants + inline constexpr size_t @\libglobal{dynamic_extent}@ = numeric_limits::max(); + + template + concept @\defexposconcept{integral-constant-like}@ = // \expos + is_integral_v> && + !is_same_v> && + @\exposconcept{constexpr-wrapper-like}@; + + template + constexpr size_t @\defexposconcept{maybe-static-ext}@ = dynamic_extent; // \expos + template<@\exposconcept{integral-constant-like}@ T> + constexpr size_t @\exposconcept{maybe-static-ext}@ = {T::value}; + + // \ref{views.span}, class template \tcode{span} + template + class span; // partially freestanding + + template + constexpr bool ranges::@\libspec{enable_view}{span}@> = true; + template + constexpr bool ranges::@\libspec{enable_borrowed_range}{span}@> = true; + + // \ref{span.objectrep}, views of object representation + template + span + as_bytes(span s) noexcept; + + template + span + as_writable_bytes(span s) noexcept; +} +\end{codeblock} - // 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; +\rSec3[views.span]{Class template \tcode{span}} - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; +\rSec4[span.overview]{Overview} - // \ref{deque.capacity}, capacity: - 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(); - bool empty() const noexcept; - - // 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; - - // \ref{deque.modifiers}, modifiers: - template void emplace_front(Args&&... args); - template void emplace_back(Args&&... args); - template iterator emplace(const_iterator position, Args&&... args); - - void push_front(const T& x); - void push_front(T&& x); - void push_back(const T& x); - void push_back(T&& x); - - iterator insert(const_iterator position, const T& x); - iterator insert(const_iterator position, T&& x); - iterator insert(const_iterator position, size_type n, const T& x); - template - iterator insert (const_iterator position, InputIterator first, InputIterator last); - iterator insert(const_iterator position, initializer_list); - - void pop_front(); - void pop_back(); +\pnum +\indexlibraryglobal{span}% +A \tcode{span} is a view over a contiguous sequence of objects, +the storage of which is owned by some other object. - iterator erase(const_iterator position); - iterator erase(const_iterator first, const_iterator last); - void swap(deque&) - noexcept(allocator_traits::is_always_equal::value); - void clear() noexcept; +\pnum +All member functions of \tcode{span} have constant time complexity. + +\indexlibraryglobal{span}% +\begin{codeblock} +namespace std { + template + class span { + public: + // constants and types + using element_type = ElementType; + using value_type = remove_cv_t; + using size_type = size_t; + using difference_type = ptrdiff_t; + using pointer = element_type*; + using const_pointer = const element_type*; + using reference = element_type&; + using const_reference = const element_type&; + using iterator = @\impdefx{type of \tcode{span::iterator}}@; // see \ref{span.iterators} + using const_iterator = std::const_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::const_iterator; + static constexpr size_type extent = Extent; + + // \ref{span.cons}, constructors, copy, and assignment + constexpr span() noexcept; + template + constexpr explicit(extent != dynamic_extent) span(It first, size_type count); + template + constexpr explicit(extent != dynamic_extent) span(It first, End last); + template + constexpr span(type_identity_t (&arr)[N]) noexcept; + template + constexpr span(array& arr) noexcept; + template + constexpr span(const array& arr) noexcept; + template + constexpr explicit(extent != dynamic_extent) span(R&& r); + constexpr span(const span& other) noexcept = default; + template + constexpr explicit(@\seebelow@) span(const span& s) noexcept; + + constexpr span& operator=(const span& other) noexcept = default; + + // \ref{span.sub}, subviews + template + constexpr span first() const; + template + constexpr span last() const; + template + constexpr span subspan() const; + + constexpr span first(size_type count) const; + constexpr span last(size_type count) const; + constexpr span subspan( + size_type offset, size_type count = dynamic_extent) const; + + // \ref{span.obs}, observers + constexpr size_type size() const noexcept; + constexpr size_type size_bytes() const noexcept; + constexpr bool empty() const noexcept; + + // \ref{span.elem}, element access + constexpr reference operator[](size_type idx) const; + constexpr reference at(size_type idx) const; // freestanding-deleted + constexpr reference front() const; + constexpr reference back() const; + constexpr pointer data() const noexcept; + + // \ref{span.iterators}, iterator support + constexpr iterator begin() const noexcept; + constexpr iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept { return begin(); } + constexpr const_iterator cend() const noexcept { return end(); } + constexpr reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() const noexcept; + constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); } + constexpr const_reverse_iterator crend() const noexcept { return rend(); } + + private: + pointer @\exposid{data_}@; // \expos + size_type @\exposid{size_}@; // \expos }; - template - bool operator==(const deque& x, const deque& y); - template - bool operator< (const deque& x, const deque& y); - template - bool operator!=(const deque& x, const deque& y); - template - bool operator> (const deque& x, const deque& y); - template - bool operator>=(const deque& x, const deque& y); - template - bool operator<=(const deque& x, const deque& y); - - // specialized algorithms: - template - void swap(deque& x, deque& y) - noexcept(noexcept(x.swap(y))); + template + span(It, EndOrSize) -> span>, + @\exposconcept{maybe-static-ext}@>; + template + span(T (&)[N]) -> span; + template + span(array&) -> span; + template + span(const array&) -> span; + template + span(R&&) -> span>>; } \end{codeblock} -\rSec3[deque.cons]{\tcode{deque} constructors, copy, and assignment} +\pnum +\tcode{span} is +a trivially copyable type\iref{term.trivially.copyable.type}. + +\pnum +\tcode{ElementType} is required to be +a complete object type that is not an abstract class type. + +\pnum +For a \tcode{span} \tcode{s}, +any operation that invalidates a pointer in +the range \range{s.data()}{s.data() + s.size()} +invalidates pointers, iterators, and references to elements of \tcode{s}. + +\rSec4[span.cons]{Constructors, copy, and assignment} -\indexlibrary{\idxcode{deque}!\idxcode{deque}}% -\indexlibrary{\idxcode{deque}!\idxcode{deque}}% +\indexlibraryctor{span}% \begin{itemdecl} -explicit deque(const Allocator&); +constexpr span() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an empty -\tcode{deque}, -using the specified allocator. +\constraints +\tcode{Extent == dynamic_extent || Extent == 0} is \tcode{true}. \pnum -\complexity -Constant. +\ensures +%FIXME: Should "is \tcode{true}" be appended here? +\tcode{size() == 0 \&\& data() == nullptr}. \end{itemdescr} -\indexlibrary{\idxcode{deque}!\idxcode{deque}}% -\indexlibrary{\idxcode{deque}!\idxcode{deque}}% +\indexlibraryctor{span}% \begin{itemdecl} -explicit deque(size_type n, const Allocator& = Allocator()); +template + constexpr explicit(extent != dynamic_extent) span(It first, size_type count); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{deque} with -\tcode{n} default-inserted elements using the specified allocator. +\constraints +Let \tcode{U} be \tcode{remove_reference_t>}. +\begin{itemize} +\item \tcode{It} satisfies \libconcept{contiguous_iterator}. +\item +\tcode{is_convertible_v} is \tcode{true}. +\begin{note} +The intent is to allow only qualification conversions +of the iterator reference type to \tcode{element_type}. +\end{note} +\end{itemize} + +\pnum +\expects +\begin{itemize} +\item \range{first}{first + count} is a valid range. +\item \tcode{It} models \libconcept{contiguous_iterator}. +\end{itemize} + +\pnum +\hardexpects +If \tcode{extent} is not equal to \tcode{dynamic_extent}, +then \tcode{count == extent} is \tcode{true}. \pnum -\requires \tcode{T} shall be \tcode{DefaultInsertable} into \tcode{*this}. +\effects +Initializes \exposid{data_} with \tcode{to_address(first)} and +\exposid{size_} with \tcode{count}. \pnum -\complexity Linear in \tcode{n}. +\throws +Nothing. \end{itemdescr} -\indexlibrary{\idxcode{deque}!\idxcode{deque}}% -\indexlibrary{\idxcode{deque}!\idxcode{deque}}% +\indexlibraryctor{span}% \begin{itemdecl} -deque(size_type n, const T& value, - const Allocator& = Allocator()); +template + constexpr explicit(extent != dynamic_extent) span(It first, End last); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs a -\tcode{deque} -with \tcode{n} copies of \tcode{value}, -using the specified allocator. +\constraints +Let \tcode{U} be \tcode{remove_reference_t>}. +\begin{itemize} +\item +\tcode{is_convertible_v} is \tcode{true}. +\begin{note} +The intent is to allow only qualification conversions +of the iterator reference type to \tcode{element_type}. +\end{note} +\item \tcode{It} satisfies \libconcept{contiguous_iterator}. +\item \tcode{End} satisfies \tcode{\libconcept{sized_sentinel_for}}. +\item \tcode{is_convertible_v} is \tcode{false}. +\end{itemize} \pnum -\requires \tcode{T} shall be \tcode{CopyInsertable} into \tcode{*this}. +\expects +\begin{itemize} +\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 -\complexity -Linear in \tcode{n}. +\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 +\exposid{size_} with \tcode{last - first}. + +\pnum +\throws +When and what \tcode{last - first} throws. \end{itemdescr} -\indexlibrary{\idxcode{deque}!\idxcode{deque}}% -\indexlibrary{\idxcode{deque}!\idxcode{deque}}% +\indexlibraryctor{span}% \begin{itemdecl} -template - deque(InputIterator first, InputIterator last, - const Allocator& = Allocator()); +template constexpr span(type_identity_t (&arr)[N]) noexcept; +template constexpr span(array& arr) noexcept; +template constexpr span(const array& arr) noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +Let \tcode{U} be \tcode{remove_pointer_t}. +\begin{itemize} +\item \tcode{extent == dynamic_extent || N == extent} is \tcode{true}, and +\item \tcode{is_convertible_v} is \tcode{true}. +\begin{note} +The intent is to allow only qualification conversions +of the array element type to \tcode{element_type}. +\end{note} +\end{itemize} + \pnum \effects -Constructs a -\tcode{deque} -equal to the range -\range{first}{last}, -using the specified allocator. +Constructs a \tcode{span} that is a view over the supplied array. +\begin{note} +\tcode{type_identity_t} affects class template argument deduction. +\end{note} \pnum -\complexity Linear in \tcode{distance(first, last)}. +\ensures +\tcode{size() == N \&\& data() == std::data(arr)} is \tcode{true}. \end{itemdescr} -\rSec3[deque.capacity]{\tcode{deque} capacity} - -\indexlibrary{\idxcode{resize}!\tcode{deque}}% +\indexlibraryctor{span}% \begin{itemdecl} -void resize(size_type sz); +template constexpr explicit(extent != dynamic_extent) span(R&& r); \end{itemdecl} \begin{itemdescr} \pnum -\effects If \tcode{sz <= size()}, equivalent to calling -\tcode{pop_back()} \tcode{size() - sz} times. -If \tcode{size() < sz}, -appends \tcode{sz - size()} default-inserted elements to the -sequence. +\constraints +Let \tcode{U} be \tcode{remove_reference_t>}. +\begin{itemize} +\item \tcode{R} satisfies \tcode{ranges::\libconcept{contiguous_range}} and + \tcode{ranges::\libconcept{sized_range}}. +\item Either \tcode{R} satisfies \tcode{ranges::\libconcept{borrowed_range}} or +\tcode{is_const_v} is \tcode{true}. +\item \tcode{remove_cvref_t} is not a specialization of \tcode{span}. +\item \tcode{remove_cvref_t} is not a specialization of \tcode{array}. +\item \tcode{is_array_v>} is \tcode{false}. +\item +\tcode{is_convertible_v} is \tcode{true}. +\begin{note} +The intent is to allow only qualification conversions +of the range reference type to \tcode{element_type}. +\end{note} +\end{itemize} + +\pnum +\expects +\begin{itemize} +\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 +\exposid{size_} with \tcode{ranges::size(r)}. \pnum -\requires \tcode{T} shall be \tcode{MoveInsertable} and \tcode{DefaultInsertable} into \tcode{*this}. +\throws +What and when \tcode{ranges::data(r)} and \tcode{ranges::size(r)} throw. \end{itemdescr} -\indexlibrary{\idxcode{resize}!\tcode{deque}}% +\indexlibraryctor{span}% \begin{itemdecl} -void resize(size_type sz, const T& c); +constexpr span(const span& other) noexcept = default; \end{itemdecl} \begin{itemdescr} \pnum -\effects If \tcode{sz <= size()}, equivalent to calling -\tcode{pop_back()} \tcode{size() - sz} times. If \tcode{size() < sz}, -appends \tcode{sz - size()} copies of \tcode{c} to the sequence. +\ensures +\tcode{other.size() == size() \&\& other.data() == data()}. +\end{itemdescr} + +\indexlibraryctor{span}% +\begin{itemdecl} +template + constexpr explicit(@\seebelow@) span(const span& s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item \tcode{extent == dynamic_extent} \tcode{||} \tcode{OtherExtent == dynamic_extent} \tcode{||} \tcode{extent == OtherExtent} is \tcode{true}, and +\item \tcode{is_convertible_v} is \tcode{true}. +\begin{note} +The intent is to allow only qualification conversions +of the \tcode{OtherElementType} to \tcode{element_type}. +\end{note} +\end{itemize} + +\pnum +\hardexpects +If \tcode{extent} is not equal to \tcode{dynamic_extent}, +then \tcode{s.size() == extent} is \tcode{true}. + +\pnum +\effects +Constructs a \tcode{span} that is a view over the range +\range{s.data()}{s.data() + s.size()}. \pnum -\requires \tcode{T} shall be -\tcode{CopyInsertable} into \tcode{*this}. +\ensures +\tcode{size() == s.size() \&\& data() == s.data()}. + +\pnum +\remarks +The expression inside \keyword{explicit} is equivalent to: +\begin{codeblock} +extent != dynamic_extent && OtherExtent == dynamic_extent +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{shrink_to_fit}!\idxcode{deque}}% -\indexlibrary{\idxcode{deque}!\idxcode{shrink_to_fit}}% +\indexlibrarymember{operator=}{span}% \begin{itemdecl} -void shrink_to_fit(); +constexpr span& operator=(const span& other) noexcept = default; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{T} shall be \tcode{MoveInsertable} into \tcode{*this}. +\ensures +\tcode{size() == other.size() \&\& data() == other.data()}. +\end{itemdescr} + +\rSec4[span.deduct]{Deduction guides} +\indexlibrary{\idxcode{span}!deduction guide}% +\begin{itemdecl} +template + span(It, EndOrSize) -> span>, + @\exposconcept{maybe-static-ext}@>; +\end{itemdecl} + +\begin{itemdescr} \pnum -\complexity Linear in the size of the sequence. +\constraints +\tcode{It} satisfies \libconcept{contiguous_iterator}. +\end{itemdescr} + +\indexlibrary{\idxcode{span}!deduction guide}% +\begin{itemdecl} +template + span(R&&) -> span>>; +\end{itemdecl} +\begin{itemdescr} \pnum -\remarks \tcode{shrink_to_fit} is a non-binding request to reduce memory use -but does not change the size of the sequence. \enternote The request is non-binding to allow latitude for implementation-specific optimizations. \exitnote +\constraints +\tcode{R} satisfies \tcode{ranges::\libconcept{contiguous_range}}. \end{itemdescr} -\rSec3[deque.modifiers]{\tcode{deque} modifiers} +\rSec4[span.sub]{Subviews} -\indexlibrary{\idxcode{insert}!\tcode{deque}}% -\indexlibrary{insert@\tcode{push_front}!\tcode{deque}}% -\indexlibrary{insert@\tcode{push_back}!\tcode{deque}}% -\indexlibrary{insert@\tcode{emplace}!\tcode{deque}}% +\indexlibrarymember{span}{first}% \begin{itemdecl} -iterator insert(const_iterator position, const T& x); -iterator insert(const_iterator position, T&& x); -iterator insert(const_iterator position, size_type n, const T& x); -template - iterator insert(const_iterator position, - InputIterator first, InputIterator last); -iterator insert(const_iterator position, initializer_list); - -template void emplace_front(Args&&... args); -template void emplace_back(Args&&... args); -template iterator emplace(const_iterator position, Args&&... args); -void push_front(const T& x); -void push_front(T&& x); -void push_back(const T& x); -void push_back(T&& x); +template constexpr span first() const; \end{itemdecl} \begin{itemdescr} \pnum -\effects -An insertion in the middle of the deque invalidates all the iterators and -references to elements of the deque. -An insertion at either end of the -deque invalidates all the iterators to the deque, but has no effect on -the validity of references to elements of the deque. +\mandates +\tcode{Count <= Extent} is \tcode{true}. \pnum -\notes -If an exception is thrown other than by the -copy constructor, move constructor, -assignment operator, or move assignment operator of -\tcode{T} -there are no effects. -If an exception is thrown while inserting a single element at either end, -there are no effects. -Otherwise, if an exception is thrown by the move constructor of a -non-\tcode{CopyInsertable} -\tcode{T}, the effects are unspecified. +\hardexpects +\tcode{Count <= size()} is \tcode{true}. \pnum -\complexity -The complexity is linear in the number of elements inserted plus the lesser -of the distances to the beginning and end of the deque. -Inserting a single element either at the beginning or end of a deque always takes constant time -and causes a single call to a constructor of -\tcode{T}. +\effects +Equivalent to: \tcode{return R(data(), Count);} +where \tcode{R} is the return type. \end{itemdescr} -\indexlibrary{\idxcode{erase}!\tcode{deque}}% +\indexlibrarymember{span}{last}% \begin{itemdecl} -iterator erase(const_iterator position); -iterator erase(const_iterator first, const_iterator last); +template constexpr span last() const; \end{itemdecl} \begin{itemdescr} \pnum -\effects -An erase operation that erases the last element of a deque invalidates only the past-the-end iterator -and all iterators and references to the erased elements. An erase operation that erases the first -element of a deque but not the last element invalidates only the erased elements. An erase operation -that erases neither the first element nor the last element of a deque invalidates the past-the-end -iterator and all iterators and references to all the elements of the deque. +\mandates +\tcode{Count <= Extent} is \tcode{true}. \pnum -\complexity -The number of calls to the destructor is the same as the -number of elements erased, but the number of calls to the assignment operator is -no more than the lesser of the number of elements before the erased elements and the number of elements after the erased elements. +\hardexpects +\tcode{Count <= size()} is \tcode{true}. \pnum -\throws -Nothing unless an exception is thrown by the copy constructor, move constructor, -assignment operator, or move assignment operator of -\tcode{T}. +\effects +Equivalent to: \tcode{return R(data() + (size() - Count), Count);} +where \tcode{R} is the return type. \end{itemdescr} -\rSec3[deque.special]{\tcode{deque} specialized algorithms} - -\indexlibrary{\idxcode{swap}!\idxcode{deque}}% -\indexlibrary{\idxcode{deque}!\idxcode{swap}}% +\indexlibrarymember{span}{subspan}% \begin{itemdecl} -template - void swap(deque& x, deque& y) - noexcept(noexcept(x.swap(y))); +template + constexpr span subspan() const; \end{itemdecl} \begin{itemdescr} \pnum -\effects +\mandates \begin{codeblock} -x.swap(y); +Offset <= Extent && (Count == dynamic_extent || Count <= Extent - Offset) \end{codeblock} -\end{itemdescr} - -\rSec2[forwardlist]{Class template \tcode{forward_list}} - -\rSec3[forwardlist.overview]{Class template \tcode{forward_list} overview} +is \tcode{true}. \pnum -A \tcode{forward_list} is a container that supports forward iterators and allows -constant time insert and erase operations anywhere within the sequence, with storage -management handled automatically. Fast random access to list elements is not supported. -\enternote It is intended that \tcode{forward_list} have zero space or time overhead -relative to a hand-written C-style singly linked list. Features that would conflict with -that goal have been omitted.\exitnote +\hardexpects +\begin{codeblock} +Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset) +\end{codeblock} +is \tcode{true}. \pnum -A \tcode{forward_list} satisfies all of the requirements of a container -(Table~\ref{tab:containers.container.requirements}), except that the \tcode{size()} -member function is not provided and \tcode{operator==} has linear complexity. -A \tcode{forward_list} also satisfies all of the requirements for an allocator-aware -container (Table~\ref{tab:containers.allocatoraware}). In addition, a \tcode{forward_list} -provides the \tcode{assign} member functions -(Table~\ref{tab:containers.sequence.requirements}) and several of the optional -container requirements (Table~\ref{tab:containers.sequence.optional}). -Descriptions are provided here only for operations on -\tcode{forward_list} that are not described in that table or for operations where there -is additional semantic information. +\effects +Equivalent to: +\begin{codeblock} +return span( + data() + Offset, Count != dynamic_extent ? Count : size() - Offset); +\end{codeblock} \pnum -\enternote Modifying any list requires access to the element preceding the first element -of interest, but in a \tcode{forward_list} there is no constant-time way to access a -preceding element. For this reason, ranges that are modified, such as those supplied to -\tcode{erase} and \tcode{splice}, must be open at the beginning. \exitnote - +\remarks +The second template argument of the returned \tcode{span} type is: \begin{codeblock} -namespace std { - template > - class forward_list { - public: - // types: - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ iterator; // See \ref{container.requirements} - typedef @\impdef@ const_iterator; // See \ref{container.requirements} - typedef @\impdef@ size_type; // See \ref{container.requirements} - typedef @\impdef@ difference_type;// See \ref{container.requirements} - typedef T value_type; - typedef Allocator allocator_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - - // \ref{forwardlist.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()); - template - forward_list(InputIterator first, InputIterator last, - const Allocator& = Allocator()); - forward_list(const forward_list& x); - forward_list(forward_list&& x); - forward_list(const forward_list& x, const Allocator&); - forward_list(forward_list&& x, const Allocator&); - forward_list(initializer_list, const Allocator& = Allocator()); - ~forward_list(); - forward_list& operator=(const forward_list& x); - forward_list& operator=(forward_list&& x) - noexcept(allocator_traits::is_always_equal::value); - forward_list& operator=(initializer_list); - template - void assign(InputIterator first, InputIterator last); - void assign(size_type n, const T& t); - void assign(initializer_list); - allocator_type get_allocator() const noexcept; - - // \ref{forwardlist.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; - - const_iterator cbegin() const noexcept; - const_iterator cbefore_begin() const noexcept; - const_iterator cend() const noexcept; - - // capacity: - bool empty() const noexcept; - size_type max_size() const noexcept; - - // \ref{forwardlist.access}, element access: - reference front(); - const_reference front() const; - - // \ref{forwardlist.modifiers}, modifiers: - template void emplace_front(Args&&... args); - void push_front(const T& x); - void push_front(T&& x); - 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); - - 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); +Count != dynamic_extent ? Count + : (Extent != dynamic_extent ? Extent - Offset + : dynamic_extent) +\end{codeblock} +\end{itemdescr} - iterator erase_after(const_iterator position); - iterator erase_after(const_iterator position, const_iterator last); - void swap(forward_list&) - noexcept(allocator_traits::is_always_equal::value); +\indexlibrarymember{span}{first}% +\begin{itemdecl} +constexpr span first(size_type count) const; +\end{itemdecl} - void resize(size_type sz); - void resize(size_type sz, const value_type& c); - void clear() noexcept; +\begin{itemdescr} +\pnum +\hardexpects +\tcode{count <= size()} is \tcode{true}. - // \ref{forwardlist.ops}, 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); +\pnum +\effects +Equivalent to: \tcode{return R(data(), count);} +where \tcode{R} is the return type. +\end{itemdescr} - void remove(const T& value); - template void remove_if(Predicate pred); +\indexlibrarymember{span}{last}% +\begin{itemdecl} +constexpr span last(size_type count) const; +\end{itemdecl} - void unique(); - template void unique(BinaryPredicate binary_pred); +\begin{itemdescr} +\pnum +\hardexpects +\tcode{count <= size()} is \tcode{true}. - 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); +\pnum +\effects +Equivalent to: \tcode{return R(data() + (size() - count), count);} +where \tcode{R} is the return type. +\end{itemdescr} - void sort(); - template void sort(Compare comp); +\indexlibrarymember{span}{subspan}% +\begin{itemdecl} +constexpr span subspan( + size_type offset, size_type count = dynamic_extent) const; +\end{itemdecl} - void reverse() noexcept; - }; +\begin{itemdescr} +\pnum +\hardexpects +\begin{codeblock} +offset <= size() && (count == dynamic_extent || count <= size() - offset) +\end{codeblock} +is \tcode{true}. - // Comparison operators - template - bool operator==(const forward_list& x, const forward_list& y); - template - bool operator< (const forward_list& x, const forward_list& y); - template - bool operator!=(const forward_list& x, const forward_list& y); - template - bool operator> (const forward_list& x, const forward_list& y); - template - bool operator>=(const forward_list& x, const forward_list& y); - template - bool operator<=(const forward_list& x, const forward_list& y); - - // \ref{forwardlist.spec}, specialized algorithms: - template - void swap(forward_list& x, forward_list& y) - noexcept(noexcept(x.swap(y))); -} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return R(data() + offset, count == dynamic_extent ? size() - offset : count); \end{codeblock} +where \tcode{R} is the return type. +\end{itemdescr} -\rSec3[forwardlist.cons]{\tcode{forward_list} constructors, copy, assignment} +\rSec4[span.obs]{Observers} -\indexlibrary{\idxcode{forward_list}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{forward_list}}% +\indexlibrarymember{span}{size}% \begin{itemdecl} -explicit forward_list(const Allocator&); +constexpr size_type size() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an empty \tcode{forward_list} object using the specified allocator. - -\pnum -\complexity Constant. +\effects +Equivalent to: \tcode{return \exposid{size_};} \end{itemdescr} -\indexlibrary{\idxcode{forward_list}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{forward_list}}% +\indexlibrarymember{span}{size_bytes}% \begin{itemdecl} -explicit forward_list(size_type n, const Allocator& = Allocator()); +constexpr size_type size_bytes() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{forward_list} object with \tcode{n} -default-inserted elements using the specified allocator. +\effects +Equivalent to: \tcode{return size() * sizeof(element_type);} +\end{itemdescr} -\pnum -\requires \tcode{T} shall be \tcode{DefaultInsertable} into \tcode{*this}. +\indexlibrarymember{span}{empty}% +\begin{itemdecl} +constexpr bool empty() const noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity Linear in \tcode{n}. +\effects +Equivalent to: \tcode{return size() == 0;} \end{itemdescr} -\indexlibrary{\idxcode{forward_list}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{forward_list}}% +\rSec4[span.elem]{Element access} + +\indexlibrary{\idxcode{operator[]}!\idxcode{span}}% \begin{itemdecl} -forward_list(size_type n, const T& value, const Allocator& = Allocator()); +constexpr reference operator[](size_type idx) const; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{forward_list} object with \tcode{n} copies of \tcode{value} using the specified allocator. +\hardexpects +\tcode{idx < size()} is \tcode{true}. \pnum -\requires \tcode{T} shall be \tcode{CopyInsertable} into \tcode{*this}. +\returns +\tcode{*(data() + idx)}. \pnum -\complexity Linear in \tcode{n}. +\throws +Nothing. \end{itemdescr} -\indexlibrary{\idxcode{forward_list}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{forward_list}}% +\indexlibrarymember{span}{at}% \begin{itemdecl} -template - forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator()); +constexpr reference at(size_type idx) const; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{forward_list} object equal to the range \range{first}{last}. +\returns +\tcode{*(data() + idx)}. \pnum -\complexity Linear in \tcode{distance(first, last)}. +\throws +\tcode{out_of_range} if \tcode{idx >= size()} is \tcode{true}. \end{itemdescr} -\rSec3[forwardlist.iter]{\tcode{forward_list} iterators} - -\indexlibrary{\idxcode{before_begin}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{before_begin}}% -\indexlibrary{\idxcode{cbefore_begin}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{cbefore_begin}}% +\indexlibrarymember{span}{front}% \begin{itemdecl} -iterator before_begin() noexcept; -const_iterator before_begin() const noexcept; -const_iterator cbefore_begin() const noexcept; +constexpr reference front() const; \end{itemdecl} \begin{itemdescr} \pnum -\returns A non-dereferenceable iterator that, when incremented, is equal to the iterator -returned by \tcode{begin()}. +\hardexpects +\tcode{empty()} is \tcode{false}. \pnum -\effects \tcode{cbefore_begin()} is equivalent to -\tcode{const_cast(*this).before_begin()}. +\returns +\tcode{*data()}. \pnum -\remarks \tcode{before_begin() == end()} shall equal \tcode{false}. +\throws +Nothing. \end{itemdescr} -\rSec3[forwardlist.access]{\tcode{forward_list} element access} - -\indexlibrary{\idxcode{front}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{front}}% +\indexlibrarymember{span}{back}% \begin{itemdecl} -reference front(); -const_reference front() const; +constexpr reference back() const; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{*begin()} -\end{itemdescr} +\hardexpects +\tcode{empty()} is \tcode{false}. -\rSec3[forwardlist.modifiers]{\tcode{forward_list} modifiers} +\pnum +\returns +\tcode{*(data() + (size() - 1))}. \pnum -None of the overloads of \tcode{insert_after} shall affect the validity of iterators and -references, and \tcode{erase_after} shall invalidate only iterators and references to -the erased elements. If an exception is thrown during \tcode{insert_after} there shall -be no effect. Inserting \tcode{n} elements into a \tcode{forward_list} is linear in -\tcode{n}, and the number of calls to the copy or move constructor of \tcode{T} is -exactly equal to \tcode{n}. Erasing \tcode{n} elements from a \tcode{forward_list} is -linear in \tcode{n} and the number of calls to the destructor of type \tcode{T} is -exactly equal to \tcode{n}. +\throws +Nothing. +\end{itemdescr} -\indexlibrary{\idxcode{emplace_front}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{emplace_front}}% +\indexlibrarymember{span}{data}% \begin{itemdecl} -template void emplace_front(Args&&... args); +constexpr pointer data() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Inserts an object of type \tcode{value_type} constructed with -\tcode{value_type(std::forward(\brk{}args)...)} at the beginning of the list. +\returns +\exposid{data_}. \end{itemdescr} -\indexlibrary{\idxcode{push_front}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{push_front}}% +\rSec4[span.iterators]{Iterator support} + +\indexlibrarymember{iterator}{span}% \begin{itemdecl} -void push_front(const T& x); -void push_front(T&& x); +using iterator = @\impdefx{type of \tcode{span::iterator}}@; \end{itemdecl} \begin{itemdescr} \pnum -\effects Inserts a copy of \tcode{x} at the beginning of the list. -\end{itemdescr} +The 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}, +whose value type is \tcode{value_type} and +whose reference type is \tcode{reference}. +\pnum +All requirements on container iterators\iref{container.reqmts} apply to +\tcode{span::iterator} as well. +\end{itemdescr} -\indexlibrary{\idxcode{pop}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{pop}}% +\indexlibrarymember{span}{begin}% \begin{itemdecl} -void pop_front(); +constexpr iterator begin() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects \tcode{erase_after(before_begin())} +\returns +An iterator referring to the first element in the span. +If \tcode{empty()} is \tcode{true}, then it returns the +same value as \tcode{end()}. \end{itemdescr} -\indexlibrary{\idxcode{insert_after}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{insert_after}}% +\indexlibrarymember{span}{end}% \begin{itemdecl} -iterator insert_after(const_iterator position, const T& x); -iterator insert_after(const_iterator position, T&& x); +constexpr iterator end() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable -iterator in the range \range{begin()}{end()}. +\returns +An iterator which is the past-the-end value. +\end{itemdescr} -\pnum -\effects Inserts a copy of \tcode{x} after \tcode{position}. +\indexlibrarymember{span}{rbegin}% +\begin{itemdecl} +constexpr reverse_iterator rbegin() const noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\returns An iterator pointing to the copy of \tcode{x}. +\effects +Equivalent to: \tcode{return reverse_iterator(end());} \end{itemdescr} -\indexlibrary{\idxcode{insert_after}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{insert_after}}% +\indexlibrarymember{span}{rend}% \begin{itemdecl} -iterator insert_after(const_iterator position, size_type n, const T& x); +constexpr reverse_iterator rend() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable -iterator in the range \range{begin()}{end()}. - -\pnum -\effects Inserts \tcode{n} copies of \tcode{x} after \tcode{position}. - -\pnum -\returns -An iterator pointing to the last inserted copy of \tcode{x} or \tcode{position} if \tcode{n == 0}. +\effects +Equivalent to: \tcode{return reverse_iterator(begin());} \end{itemdescr} -\indexlibrary{\idxcode{insert_after}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{insert_after}}% +\rSec3[span.objectrep]{Views of object representation} + +\indexlibraryglobal{as_bytes}% \begin{itemdecl} -template - iterator insert_after(const_iterator position, InputIterator first, InputIterator last); +template + span + as_bytes(span s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable -iterator in the range \range{begin()}{end()}. -\tcode{first} and \tcode{last} are not iterators in \tcode{*this}. - -\pnum -\effects Inserts copies of elements in \range{first}{last} after \tcode{position}. +\constraints +\tcode{is_volatile_v} is \tcode{false}. \pnum -\returns -An iterator pointing to the last inserted element or \tcode{position} if \tcode{first == last}. +\effects +Equivalent to: \tcode{return R\{reinterpret_cast(s.data()), s.size_bytes()\};} +where \tcode{R} is the return type. \end{itemdescr} -\indexlibrary{\idxcode{insert_after}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{insert_after}}% +\indexlibraryglobal{as_writable_bytes}% \begin{itemdecl} -iterator insert_after(const_iterator position, initializer_list il); +template + span + as_writable_bytes(span s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects \tcode{insert_after(p, il.begin(), il.end())}. +\constraints +\tcode{is_const_v} is \tcode{false} and +\tcode{is_volatile_v} is \tcode{false}. \pnum -\returns -An iterator pointing to the last inserted element or \tcode{position} if \tcode{il} is empty. +\effects +Equivalent to: \tcode{return R\{reinterpret_cast(s.data()), s.size_bytes()\};} +where \tcode{R} is the return type. \end{itemdescr} +\rSec2[views.multidim]{Multidimensional access} -\indexlibrary{\idxcode{emplace_after}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{emplace_after}}% -\begin{itemdecl} -template - iterator emplace_after(const_iterator position, Args&&... args); -\end{itemdecl} +\rSec3[mdspan.overview]{Overview} -\begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable -iterator in the range \range{begin()}{end()}. +A \defnadj{multidimensional}{index space} is +a Cartesian product of integer intervals. +Each interval can be represented by a half-open range $[L_i, U_i)$, +where $L_i$ and $U_i$ are the lower and upper bounds of +the $i^\text{th}$ dimension. +The \defn{rank} of a multidimensional index space is +the number of intervals it represents. +The \defn{size of a multidimensional index space} is +the product of $U_i - L_i$ for each dimension $i$ +if its rank is greater than 0, and 1 otherwise. \pnum -\effects Inserts an object of type \tcode{value_type} constructed with -\tcode{value_type(std::forward(\brk{}args)...)} after \tcode{position}. +An integer $r$ is a \defn{rank index} of an index space $S$ +if $r$ is in the range $[0, \text{rank of $S$})$. \pnum -\returns An iterator pointing to the new object. -\end{itemdescr} +A pack of integers \tcode{idx} is +a \defnadj{multidimensional}{index} in a multidimensional index space $S$ +(or representation thereof) if both of the following are true: +\begin{itemize} +\item +\tcode{sizeof...(idx)} is equal to the rank of $S$, and +\item +for every rank index $i$ of $S$, +the $i^\text{th}$ value of \tcode{idx} is an integer +in the interval $[L_i, U_i)$ of $S$. +\end{itemize} -\indexlibrary{\idxcode{erase_after}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{erase_after}}% -\begin{itemdecl} -iterator erase_after(const_iterator position); -\end{itemdecl} +\rSec3[mdspan.syn]{Header \tcode{} synopsis} + +\indexheader{mdspan}% +\begin{codeblock} +// mostly freestanding +namespace std { + // \ref{mdspan.extents}, class template \tcode{extents} + template + class extents; + + // \ref{mdspan.extents.dextents}, alias template \tcode{dextents} + template + using dextents = @\seebelow@; + + // \ref{mdspan.extents.dims}, alias template \tcode{dims} + template + using dims = @\seebelow@; + + // \ref{mdspan.layout}, layout mapping + struct layout_left; + struct layout_right; + struct layout_stride; + template + struct layout_left_padded; + template + struct layout_right_padded; + + // \ref{mdspan.accessor.default}, class template \tcode{default_accessor} + template + class default_accessor; + + // \ref{mdspan.accessor.aligned}, class template \tcode{aligned_accessor} + template + class aligned_accessor; + + // \ref{mdspan.mdspan}, class template \tcode{mdspan} + template> + class mdspan; // partially freestanding + + // \ref{mdspan.sub}, \tcode{submdspan} creation + template + struct extent_slice; + template> + struct range_slice; + + template + struct submdspan_mapping_result; + + 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...); + + // \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... raw_slices) -> @\seebelow@; + + template + concept @\defexposconcept{index-pair-like}@ = // \expos + @\exposconcept{pair-like}@ && + @\libconcept{convertible_to}@, IndexType> && + @\libconcept{convertible_to}@, IndexType>; +} +\end{codeblock} + +\rSec3[mdspan.extents]{Class template \tcode{extents}} + +\rSec4[mdspan.extents.overview]{Overview} + +The class template \tcode{extents} represents +a multidimensional index space of rank equal to \tcode{sizeof...(Extents)}. +In~\ref{views}, +\tcode{extents} is used synonymously with multidimensional index space. + +\begin{codeblock} +namespace std { + template + class @\libglobal{extents}@ { + public: + 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 @\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; + + // \ref{mdspan.extents.cons}, constructors + constexpr extents() noexcept = default; + + template + constexpr explicit(@\seebelow@) + extents(const extents&) noexcept; + template + constexpr explicit extents(OtherIndexTypes...) noexcept; + template + constexpr explicit(N != rank_dynamic()) + extents(span) noexcept; + template + constexpr explicit(N != rank_dynamic()) + extents(const array&) noexcept; + + // \ref{mdspan.extents.cmp}, comparison operators + template + friend constexpr bool operator==(const extents&, + const extents&) noexcept; + + // \ref{mdspan.extents.expo}, exposition-only helpers + constexpr size_t @\exposid{fwd-prod-of-extents}@(rank_type) const noexcept; // \expos + constexpr size_t @\exposid{rev-prod-of-extents}@(rank_type) const noexcept; // \expos + template + static constexpr auto @\exposid{index-cast}@(OtherIndexType&&) noexcept; // \expos + + private: + static constexpr rank_type @\exposid{dynamic-index}@(rank_type) noexcept; // \expos + static constexpr rank_type @\exposid{dynamic-index-inv}@(rank_type) noexcept; // \expos + array @\exposid{dynamic-extents}@{}; // \expos + }; + + template + explicit extents(Integrals...) + -> @\seebelow@; +} +\end{codeblock} -\begin{itemdescr} \pnum -\requires The iterator following \tcode{position} is dereferenceable. +\mandates +\begin{itemize} +\item +\tcode{IndexType} is a signed or unsigned integer type, and +\item +each element of \tcode{Extents} is either equal to \tcode{dynamic_extent}, or +is representable as a value of type \tcode{IndexType}. +\end{itemize} \pnum -\effects Erases the element pointed to by the iterator following \tcode{position}. +Each specialization of \tcode{extents} models \libconcept{regular} and +is trivially copyable. \pnum -\returns An iterator pointing to the element following the one that was -erased, or \tcode{end()} if no such element exists. +Let $E_r$ be the $r^\text{th}$ element of \tcode{Extents}. +$E_r$ is a \defnadj{dynamic}{extent} if it is equal to \tcode{dynamic_extent}, +otherwise $E_r$ is a \defnadj{static}{extent}. +Let $D_r$ be the value of \tcode{\exposid{dynamic-extents}[\exposid{dynamic-index}($r$)]} +if $E_r$ is a dynamic extent, +otherwise $E_r$. \pnum -\throws Nothing. -\end{itemdescr} +The $r^\text{th}$ interval of the multidimensional index space +represented by an \tcode{extents} object is $[0, D_r)$. + +\rSec4[mdspan.extents.expo]{Exposition-only helpers} -\indexlibrary{\idxcode{erased}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{erased}}% \begin{itemdecl} -iterator erase_after(const_iterator position, const_iterator last); +static constexpr rank_type @\exposid{dynamic-index}@(rank_type i) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires All iterators in the range \orange{position}{last} are dereferenceable. +\expects +\tcode{i <= rank()} is \tcode{true}. \pnum -\effects Erases the elements in the range \orange{position}{last}. +\returns +The number of $E_r$ with $r < \tcode{i}$ for which $E_r$ is a dynamic extent. +\end{itemdescr} + +\begin{itemdecl} +static constexpr rank_type @\exposid{dynamic-index-inv}@(rank_type i) noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\returns \tcode{last}. +\expects +\tcode{i < rank_dynamic()} is \tcode{true}. \pnum -\throws Nothing. +\returns +The minimum value of $r$ +such that \tcode{\exposid{dynamic-index}($r$ + 1) == i + 1} is \tcode{true}. \end{itemdescr} -\indexlibrary{\idxcode{resize}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{resize}}% \begin{itemdecl} -void resize(size_type sz); +constexpr size_t @\exposid{fwd-prod-of-extents}@(rank_type i) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects If \tcode{sz < distance(begin(), end())}, erases the last \tcode{distance(begin(), -end()) - sz} elements from the list. Otherwise, inserts \tcode{sz - distance(begin(), end())} default-inserted -elements at the end of the list. +\expects +\tcode{i <= rank()} is \tcode{true}. \pnum -\requires \tcode{T} shall be \tcode{DefaultInsertable} into \tcode{*this}. +\returns +If \tcode{i > 0} is \tcode{true}, +the product of \tcode{extent($k$)} for all $k$ in the range $[0, \tcode{i})$, +otherwise \tcode{1}. \end{itemdescr} \begin{itemdecl} -void resize(size_type sz, const value_type& c); +constexpr size_t @\exposid{rev-prod-of-extents}@(rank_type i) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects If \tcode{sz < distance(begin(), end())}, erases the last \tcode{distance(begin(), -end()) - sz} elements from the list. Otherwise, inserts \tcode{sz - distance(begin(), end())} -elements at the end of the list such that each new element, \tcode{e}, is initialized -by a method equivalent to calling -\tcode{allocator_traits::construct(get_allocator(), std::addressof(e), c)}. +\expects +\tcode{i < rank()} is \tcode{true}. \pnum -\requires \tcode{T} shall be \tcode{CopyInsertable} into \tcode{*this}. +\returns +If \tcode{i + 1 < rank()} is \tcode{true}, +the product of \tcode{extent($k$)} +for all $k$ in the range $[\tcode{i + 1}, \tcode{rank()})$, +otherwise \tcode{1}. \end{itemdescr} - -\indexlibrary{\idxcode{clear}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{clear}}% \begin{itemdecl} -void clear() noexcept; +template + static constexpr auto @\exposid{index-cast}@(OtherIndexType&& i) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Erases all elements in the range \range{begin()}{end()}. - -\pnum -\remarks Does not invalidate past-the-end iterators. +\effects +\begin{itemize} +\item +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(std::forward(\brk{}i));}. +\end{itemize} +\begin{note} +This function will always return an integral type other than \tcode{bool}. +Since this function's call sites are constrained on +convertibility of \tcode{OtherIndexType} to \tcode{index_type}, +integer-class types can use the \tcode{static_cast} branch +without loss of precision. +\end{note} \end{itemdescr} -\rSec3[forwardlist.ops]{\tcode{forward_list} operations} +\rSec4[mdspan.extents.cons]{Constructors} -\indexlibrary{\idxcode{splice_after}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{splice_after}}% +\indexlibraryctor{extents}% \begin{itemdecl} -void splice_after(const_iterator position, forward_list& x); -void splice_after(const_iterator position, forward_list&& x); +template + constexpr explicit(@\seebelow@) + extents(const extents& other) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable -iterator in the range \range{begin()}{end()}. -\tcode{get_allocator() == x.get_allocator()}. -\tcode{\&x != this}. +\constraints +\begin{itemize} +\item +\tcode{sizeof...(OtherExtents) == rank()} is \tcode{true}. +\item +\tcode{((OtherExtents == dynamic_extent || Extents == dynamic_extent || OtherExtents ==\newline Extents) \&\& ...)} is \tcode{true}. +\end{itemize} \pnum -\effects Inserts the contents of \tcode{x} after -\tcode{position}, and \tcode{x} becomes empty. Pointers and references to the moved -elements of \tcode{x} now refer to those same elements but as members of \tcode{*this}. -Iterators referring to the moved elements will continue to refer to their elements, but -they now behave as iterators into \tcode{*this}, not into \tcode{x}. +\expects +\begin{itemize} +\item +\tcode{other.extent($r$)} equals $E_r$ +for each $r$ for which $E_r$ is a static extent, and +\item +either +\begin{itemize} +\item +\tcode{sizeof...(OtherExtents)} is zero, or +\item +\tcode{other.extent($r$)} is representable as +a value of type \tcode{index_type} for every rank index $r$ of \tcode{other}. +\end{itemize} +\end{itemize} \pnum -\throws Nothing. +\ensures +\tcode{*this == other} is \tcode{true}. \pnum -\complexity \bigoh{distance(x.begin(), x.end())} +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +(((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) || +(numeric_limits::max() < numeric_limits::max()) +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{splice_after}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{splice_after}}% +\indexlibraryctor{extents}% \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); +template + constexpr explicit extents(OtherIndexTypes... exts) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a dereferenceable -iterator in the range \range{begin()}{end()}. -The iterator following \tcode{i} is a dereferenceable iterator in \tcode{x}. -\tcode{get_allocator() == x.get_allocator()}. +Let \tcode{N} be \tcode{sizeof...(OtherIndexTypes)}, +and let \tcode{exts_arr} be +\tcode{array\{static_cast<\\index_type>(std::move(exts))...\}}. \pnum -\effects Inserts the element following \tcode{i} into \tcode{*this}, following -\tcode{position}, and removes it from \tcode{x}. -The result is unchanged if \tcode{position == i} or \tcode{position == ++i}. Pointers -and references to \tcode{*++i} continue to refer to the same element but as a member of -\tcode{*this}. Iterators to \tcode{*++i} continue to refer to -the same element, but now behave as iterators into \tcode{*this}, not into \tcode{x}. +\constraints +\begin{itemize} +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}, and +\item +\tcode{N == rank_dynamic() || N == rank()} is \tcode{true}. +\begin{note} +One can construct \tcode{extents} from just dynamic extents, +which are all the values getting stored, or +from all the extents with a precondition. +\end{note} +\end{itemize} \pnum -\throws Nothing. +\expects +\begin{itemize} +\item +If \tcode{N != rank_dynamic()} is \tcode{true}, +\tcode{exts_arr[$r$]} equals $E_r$ +for each $r$ for which $E_r$ is a static extent, and +\item +either +\begin{itemize} +\item +\tcode{sizeof...(exts) == 0} is \tcode{true}, or +\item +each element of \tcode{exts} is representable +as a nonnegative value of type \tcode{index_type}. +\end{itemize} +\end{itemize} \pnum -\complexity \bigoh{1} +\ensures +\tcode{*this == extents(exts_arr)} is \tcode{true}. \end{itemdescr} -\indexlibrary{\idxcode{splice_after}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{splice_after}}% +\indexlibraryctor{extents}% \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); +template + constexpr explicit(N != rank_dynamic()) + extents(span exts) noexcept; +template + constexpr explicit(N != rank_dynamic()) + extents(const array& exts) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{position} is \tcode{before_begin()} or is a -dereferenceable iterator in the range \range{begin()}{end()}. \orange{first}{last} is a -valid range in \tcode{x}, and all iterators in the range \orange{first}{last} are -dereferenceable. \tcode{position} is not an iterator in the range \orange{first}{last}. -\tcode{get_allocator() == x.get_allocator()}. +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} is \tcode{true}, +\item +\tcode{is_nothrow_constructible_v} is \tcode{true}, and +\item +\tcode{N == rank_dynamic() || N == rank()} is \tcode{true}. +\end{itemize} \pnum -\effects Inserts elements in the range \orange{first}{last} after \tcode{position} and -removes the elements from \tcode{x}. Pointers and references to the moved elements of -\tcode{x} now refer to those same elements but as members of \tcode{*this}. Iterators -referring to the moved elements will continue to refer to their elements, but they now -behave as iterators into \tcode{*this}, not into \tcode{x}. +\expects +\begin{itemize} +\item +If \tcode{N != rank_dynamic()} is \tcode{true}, +\tcode{exts[$r$]} equals $E_r$ for each $r$ for which $E_r$ is a static extent, and +\item +either +\begin{itemize} +\item +\tcode{N} is zero, or +\item +\tcode{exts[$r$]} is representable +as a nonnegative value of type \tcode{index_type} for every rank index $r$. +\end{itemize} +\end{itemize} \pnum -\complexity \bigoh{distance(first, last)} +\effects +\begin{itemize} +\item +If \tcode{N} equals \tcode{rank_dynamic()}, +for all $d$ in the range $[0, \tcode{rank_dynamic()})$, +direct-non-list-initializes \tcode{\exposidnc{dynamic-extents}[$d$]} +with \tcode{as_const(exts[$d$])}. +\item +Otherwise, for all $d$ in the range $[0, \tcode{rank_dynamic()})$, +direct-non-list-initializes \exposidnc{dynamic-ex\-tents}\tcode{[$d$]} +with \tcode{as_const(exts[\exposidnc{dynamic-index-inv}($d$)])}. +\end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{remove}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{remove}}% -\indexlibrary{\idxcode{remove_if}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{remove_if}}% +\indexlibraryctor{extents}% \begin{itemdecl} -void remove(const T& value); -template void remove_if(Predicate pred); +template + explicit extents(Integrals...) -> @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum -\effects Erases all the elements in the list referred by a list iterator \tcode{i} for -which the following conditions hold: \tcode{*i == value} (for \tcode{remove()}), -\tcode{pred(*i)} is true (for \tcode{remove_if()}). -Invalidates only the iterators and references to the erased elements. - -\pnum -\throws Nothing unless an exception is thrown by the equality comparison or the -predicate. - -\pnum -\remarks Stable~(\ref{algorithm.stable}). +\constraints +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}. \pnum -\complexity Exactly \tcode{distance(begin(), end())} applications of the corresponding -predicate. +\remarks +The deduced type is \tcode{extents...>}. \end{itemdescr} -\indexlibrary{\idxcode{unique}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{unique}}% +\rSec4[mdspan.extents.obs]{Observers of the multidimensional index space} + +\indexlibrarymember{static_extent}{extents}% \begin{itemdecl} -void unique(); -template void unique(BinaryPredicate pred); +static constexpr size_t static_extent(rank_type i) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Erases all but the first element from every consecutive -group of equal elements referred to by the iterator \tcode{i} in the range \range{first + -1}{last} for which \tcode{*i == *(i-1)} (for the version with no arguments) or \tcode{pred(*i, -*(i - 1))} (for the version with a predicate argument) holds. -Invalidates only the iterators and references to the erased elements. - -\pnum -\throws Nothing unless an exception is thrown by the equality comparison or the predicate. +\expects +\tcode{i < rank()} is \tcode{true}. \pnum -\complexity If the range \range{first}{last} is not empty, exactly \tcode{(last - first) - 1} applications of the corresponding predicate, otherwise no applications of the predicate. +\returns +$E_\tcode{i}$. \end{itemdescr} -\indexlibrary{\idxcode{merge}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{merge}}% +\indexlibrarymember{extent}{extents}% \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 index_type extent(rank_type i) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{comp} defines a strict weak ordering~(\ref{alg.sorting}), and \tcode{*this} -and \tcode{x} are both sorted according to this ordering. -\tcode{get_allocator() == x.get_allocator()}. - -\pnum -\effects Merges the two sorted ranges \tcode{[begin(), end())} and -\tcode{[x.begin(), x.end())}. \tcode{x} is empty after the merge. If an -exception is thrown other than by a comparison there are no effects. -Pointers and references to the moved elements of \tcode{x} now refer to those same elements -but as members of \tcode{*this}. Iterators referring to the moved elements will continue to -refer to their elements, but they now behave as iterators into \tcode{*this}, not into -\tcode{x}. - -\pnum -\remarks Stable~(\ref{algorithm.stable}). The behavior is undefined if -\tcode{this->get_allocator() != x.get_allocator()}. +\expects +\tcode{i < rank()} is \tcode{true}. \pnum -\complexity At most \tcode{distance(begin(), -end()) + distance(x.begin(), x.end()) - 1} comparisons. +\returns +$D_\tcode{i}$. \end{itemdescr} -\indexlibrary{\idxcode{sort}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{sort}}% +\rSec4[mdspan.extents.cmp]{Comparison operators} + +\indexlibrarymember{operator==}{extents}% \begin{itemdecl} -void sort(); -template void sort(Compare comp); +template + friend constexpr bool operator==(const extents& lhs, + const extents& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{operator<} (for the version with no arguments) or \tcode{comp} (for the -version with a comparison argument) defines a strict weak ordering~(\ref{alg.sorting}). - -\pnum -\effects Sorts the list according to the \tcode{operator<} or the \tcode{comp} function object. -If an exception is thrown the order of the elements in \tcode{*this} is unspecified. -Does not affect the validity of iterators and references. - -\pnum -\remarks Stable~(\ref{algorithm.stable}). - -\pnum -\complexity Approximately $N \log N$ comparisons, where $N$ is \tcode{distance(begin(), end())}. +\returns +\tcode{true} if \tcode{lhs.rank()} equals \tcode{rhs.rank()} and +if \tcode{lhs.extent(r)} equals \tcode{rhs.extent(r)} +for every rank index \tcode{r} of \tcode{rhs}, +otherwise \tcode{false}. \end{itemdescr} -\indexlibrary{\idxcode{reverse}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{reverse}}% +\rSec4[mdspan.extents.dextents]{Alias template \tcode{dextents}} + +\indexlibraryglobal{dextents}% \begin{itemdecl} -void reverse() noexcept; +template + using dextents = @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum -\effects Reverses the order of the elements in the list. -Does not affect the validity of iterators and references. - -\pnum -\complexity Linear time. +\result +A type \tcode{E} that is a specialization of \tcode{extents} +such that \tcode{E::rank() == Rank \&\& E::rank() == E::rank_dynamic()} is \tcode{true}, and +\tcode{E::index_type} denotes \tcode{IndexType}. \end{itemdescr} -\rSec3[forwardlist.spec]{\tcode{forward_list} specialized algorithms} +\rSec4[mdspan.extents.dims]{Alias template \tcode{dims}} -\indexlibrary{\idxcode{swap}!\idxcode{forward_list}}% -\indexlibrary{\idxcode{forward_list}!\idxcode{swap}}% +\indexlibraryglobal{dims}% \begin{itemdecl} -template - void swap(forward_list& x, forward_list& y) - noexcept(noexcept(x.swap(y))); +template + using dims = @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum -\effects \tcode{x.swap(y)} +\result +A type \tcode{E} that is a specialization of \tcode{extents} +such that \tcode{E::rank() == Rank \&\& E::rank() == E::rank_dynamic()} is \tcode{true}, and +\tcode{E::index_type} denotes \tcode{IndexType}. \end{itemdescr} -\rSec2[list]{Class template \tcode{list}} - -\rSec3[list.overview]{Class template \tcode{list} overview} +\rSec3[mdspan.layout]{Layout mapping} -\pnum -\indexlibrary{\idxcode{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~(\ref{vector}) and deques~(\ref{deque}), -fast random access to list elements is not supported, but many -algorithms only need sequential access anyway. +\rSec4[mdspan.layout.general]{General} \pnum -A \tcode{list} satisfies all of the requirements of a container, of -a reversible container (given in two tables in -\ref{container.requirements}), of a sequence container, -including most of the optional sequence container -requirements~(\ref{sequence.reqmts}), and of an allocator-aware container -(Table~\ref{tab:containers.allocatoraware}). -The exceptions are the -\tcode{operator[]} -and -\tcode{at} -member functions, which are not provided.\footnote{These member functions -are only provided by containers whose iterators -are random access iterators. -} -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. +In \ref{mdspan.layout.reqmts} and \ref{mdspan.layout.policy.reqmts}: -\begin{codeblock} -namespace std { - template > - class list { - public: - // types: - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ iterator; // see \ref{container.requirements} - typedef @\impdef@ const_iterator; // see \ref{container.requirements} - typedef @\impdef@ size_type; // see \ref{container.requirements} - typedef @\impdef@ difference_type;// see \ref{container.requirements} - typedef T value_type; - typedef Allocator allocator_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_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()); - template - list(InputIterator first, InputIterator last, const Allocator& = Allocator()); - list(const list& x); - list(list&& x); - list(const list&, const Allocator&); - list(list&&, const Allocator&); - list(initializer_list, const Allocator& = Allocator()); - ~list(); - list& operator=(const list& x); - list& operator=(list&& x) - noexcept(allocator_traits::is_always_equal::value); - list& operator=(initializer_list); - template - void assign(InputIterator first, InputIterator last); - void assign(size_type n, const T& t); - void assign(initializer_list); - allocator_type get_allocator() const noexcept; +\begin{itemize} +\item +\tcode{M} denotes a layout mapping class. - // 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; +\item +\tcode{m} denotes a (possibly const) value of type \tcode{M}. - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; +\item +\tcode{i} and \tcode{j} are packs of (possibly const) integers +that are multidimensional indices in \tcode{m.extents()}\iref{mdspan.overview}. +\begin{note} +The type of each element of the packs can be a different integer type. +\end{note} - // \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); - - // element access: - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - - // \ref{list.modifiers}, modifiers: - template void emplace_front(Args&&... args); - void pop_front(); - template void emplace_back(Args&&... args); - void push_front(const T& x); - void push_front(T&& x); - void push_back(const T& x); - void push_back(T&& x); - 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 - iterator insert(const_iterator position, InputIterator first, - InputIterator last); - iterator insert(const_iterator position, initializer_list il); +\item +\tcode{r} is a (possibly const) rank index of \tcode{typename M::extents_type}. - 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; - - // \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); - - void remove(const T& value); - template void remove_if(Predicate pred); - - void unique(); - template - void 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); - - void sort(); - template void sort(Compare comp); - - void reverse() noexcept; - }; +\item +$\tcode{d}_r$ is a pack of (possibly const) integers +for which \tcode{sizeof...($\tcode{d}_r$) == M::extents_type::rank()} is \tcode{true}, +the $r^\text{th}$ element is equal to 1, and +all other elements are equal to 0. +\end{itemize} - template - bool operator==(const list& x, const list& y); - template - bool operator< (const list& x, const list& y); - template - bool operator!=(const list& x, const list& y); - template - bool operator> (const list& x, const list& y); - template - bool operator>=(const list& x, const list& y); - template - bool operator<=(const list& x, const list& y); - - // specialized algorithms: - template - void swap(list& x, list& y) - noexcept(noexcept(x.swap(y))); -} +\pnum +In \ref{mdspan.layout.reqmts} through \ref{mdspan.layout.stride}: +\begin{itemize} +\item +Let \exposid{is-mapping-of} be the exposition-only variable template defined as follows: +\begin{codeblock} +template +constexpr bool @\exposid{is-mapping-of}@ = // \expos + is_same_v, Mapping>; +\end{codeblock} +\item +Let \exposid{is-layout-left-padded-mapping-of} be +the exposition-only variable template defined as follows: +\begin{codeblock} +template +constexpr bool @\exposid{is-layout-left-padded-mapping-of}@ = @\seebelow@; // \expos +\end{codeblock} +where \tcode{\exposid{is-layout-left-padded-mapping-of}} is \tcode{true} +if and only if \tcode{Mapping} denotes +a specialization of \tcode{layout_left_padded::mapping} +for some value \tcode{S} of type \tcode{size_t}. +\item +Let \exposid{is-layout-right-padded-mapping-of} be +the exposition-only variable template defined as follows: +\begin{codeblock} +template +constexpr bool @\exposid{is-layout-right-padded-mapping-of}@ = @\seebelow@; // \expos \end{codeblock} +where \tcode{\exposid{is-layout-right-padded-mapping-of}} is \tcode{true} +if and only if \tcode{Mapping} denotes +a specialization of \tcode{layout_right_padded::mapping} +for some value \tcode{S} of type \tcode{size_t}. +\item +For nonnegative integers $x$ and $y$, +let $\exposid{LEAST-MULTIPLE-AT-LEAST}(x, y)$ denote +\begin{itemize} +\item +$y$ if $x$ is zero, +\item +otherwise, the least multiple of $x$ that is greater than or equal to $y$. +\end{itemize} +\end{itemize} + +\rSec4[mdspan.layout.reqmts]{Requirements} -\rSec3[list.cons]{\tcode{list} constructors, copy, and assignment} +\pnum +A type \tcode{M} meets the \defn{layout mapping} requirements if + +\begin{itemize} +\item +\tcode{M} models \libconcept{copyable} and \libconcept{equality_comparable}, +\item +\tcode{is_nothrow_move_constructible_v} is \tcode{true}, +\item +\tcode{is_nothrow_move_assignable_v} is \tcode{true}, +\item +\tcode{is_nothrow_swappable_v} is \tcode{true}, and +\item +the following types and expressions are well-formed and +have the specified semantics. +\end{itemize} -\indexlibrary{\idxcode{list}!\idxcode{list}}% -\indexlibrary{\idxcode{list}!\idxcode{list}}% \begin{itemdecl} -explicit list(const Allocator&); +typename M::extents_type \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an empty list, using the specified allocator. - -\pnum -\complexity -Constant. +\result +A type that is a specialization of \tcode{extents}. \end{itemdescr} -\indexlibrary{\idxcode{list}!\idxcode{list}}% -\indexlibrary{\idxcode{list}!\idxcode{list}}% \begin{itemdecl} -explicit list(size_type n, const Allocator& = Allocator()); +typename M::index_type \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{list} with -\tcode{n} default-inserted elements using the specified allocator. +\result +\tcode{typename M::extents_type::index_type}. +\end{itemdescr} -\pnum -\requires \tcode{T} shall be \tcode{DefaultInsertable} into \tcode{*this}. +\begin{itemdecl} +typename M::rank_type +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -Linear in -\tcode{n}. +\result +\tcode{typename M::extents_type::rank_type}. \end{itemdescr} -\indexlibrary{\idxcode{list}!\idxcode{list}}% -\indexlibrary{\idxcode{list}!\idxcode{list}}% \begin{itemdecl} -list(size_type n, const T& value, - const Allocator& = Allocator()); +typename M::layout_type \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs a -\tcode{list} -with -\tcode{n} -copies of -\tcode{value}, -using the specified allocator. +\result +A type \tcode{MP} that meets +the layout mapping policy requirements\iref{mdspan.layout.policy.reqmts} and +for which \tcode{\exposid{is-mapping-of}} is \tcode{true}. +\end{itemdescr} -\pnum -\requires \tcode{T} shall be \tcode{CopyInsertable} into \tcode{*this}. +\begin{itemdecl} +m.extents() +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -Linear in -\tcode{n}. +\result +\tcode{const typename M::extents_type\&} \end{itemdescr} -\indexlibrary{\idxcode{list}!\idxcode{list}}% -\indexlibrary{\idxcode{list}!\idxcode{list}}% \begin{itemdecl} -template -list(InputIterator first, InputIterator last, - const Allocator& = Allocator()); +m(i...) \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs a -\tcode{list} -equal to the range -\range{first}{last}. +\result +\tcode{typename M::index_type} \pnum -\complexity -Linear in -\tcode{distance(first, last)}. +\returns +A nonnegative integer +less than \tcode{numeric_limits::max()} and +less than or equal to \tcode{numeric_limits::max()}. \end{itemdescr} -\rSec3[list.capacity]{\tcode{list} capacity} - -\indexlibrary{\idxcode{resize}!\tcode{list}}% \begin{itemdecl} -void resize(size_type sz); +m(i...) == m(static_cast(i)...) \end{itemdecl} \begin{itemdescr} \pnum -\effects -If \tcode{size() < sz}, -appends \tcode{sz - size()} default-inserted elements to the -sequence. -If \tcode{sz <= size()}, equivalent to - -\begin{codeblock} -list::iterator it = begin(); -advance(it, sz); -erase(it, end()); -\end{codeblock} - +\result +\tcode{bool} \pnum -\requires \tcode{T} shall be -\tcode{DefaultInsertable} into \tcode{*this}. +\returns +\tcode{true} \end{itemdescr} -\indexlibrary{\idxcode{resize}!\tcode{list}}% \begin{itemdecl} -void resize(size_type sz, const T& c); +m.required_span_size() \end{itemdecl} \begin{itemdescr} \pnum -\effects -\begin{codeblock} -if (sz > size()) - insert(end(), sz-size(), c); -else if (sz < size()) { - iterator i = begin(); - advance(i, sz); - erase(i, end()); -} -else - ; // do nothing -\end{codeblock} +\result +\tcode{typename M::index_type} \pnum -\requires \tcode{T} shall be \tcode{CopyInsertable} into \tcode{*this}. +\returns +If the size of the multidimensional index space \tcode{m.extents()} is 0, +then \tcode{0}, +else \tcode{1} plus the maximum value of \tcode{m(i...)} for all \tcode{i}. \end{itemdescr} -\rSec3[list.modifiers]{\tcode{list} modifiers} - -\indexlibrary{\idxcode{insert}!\tcode{list}}% \begin{itemdecl} -iterator insert(const_iterator position, const T& x); -iterator insert(const_iterator position, T&& x); -iterator insert(const_iterator position, size_type n, const T& x); -template - iterator insert(const_iterator position, InputIterator first, - InputIterator last); -iterator insert(const_iterator position, initializer_list); - -template void emplace_front(Args&&... args); -template void emplace_back(Args&&... args); -template iterator emplace(const_iterator position, Args&&... args); -void push_front(const T& x); -void push_front(T&& x); -void push_back(const T& x); -void push_back(T&& x); +m.is_unique() \end{itemdecl} \begin{itemdescr} \pnum -\notes -Does not affect the validity of iterators and references. -If an exception is thrown there are no effects. +\result +\tcode{bool} \pnum -\complexity -Insertion of a single element into a list takes constant time and -exactly one call to a constructor of -\tcode{T}. Insertion of multiple elements into a list is linear in the -number of elements inserted, and the number of calls to the copy -constructor or move constructor of \tcode{T} is exactly equal -to the number of elements inserted. +\returns +\tcode{true} only if +for every \tcode{i} and \tcode{j} where \tcode{(i != j || ...)} is \tcode{true}, +\tcode{m(i...) != m(j...)} is \tcode{true}. +\begin{note} +A mapping can return \tcode{false} even if the condition is met. +For certain layouts, it is possibly not feasible to determine efficiently +whether the layout is unique. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{erase}!\tcode{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; +m.is_exhaustive() \end{itemdecl} \begin{itemdescr} \pnum -\effects -Invalidates only the iterators and references to the erased elements. - -\pnum -\throws Nothing. +\result +\tcode{bool} \pnum -\complexity -Erasing a single element is a constant time operation with a single call to the destructor of -\tcode{T}. -Erasing a range in a list is linear time in the -size of the range and the number of calls to the destructor of type -\tcode{T} -is exactly equal to the size of the range. +\returns +\tcode{true} only if +for all $k$ in the range $[0, \tcode{m.required_span_size()})$ +there exists an \tcode{i} such that \tcode{m(i...)} equals $k$. +\begin{note} +A mapping can return \tcode{false} even if the condition is met. +For certain layouts, it is possibly not feasible to determine efficiently +whether the layout is exhaustive. +\end{note} \end{itemdescr} -\rSec3[list.ops]{\tcode{list} operations} +\begin{itemdecl} +m.is_strided() +\end{itemdecl} +\begin{itemdescr} \pnum -Since lists allow fast insertion and erasing from the middle of a list, certain -operations are provided specifically for them.\footnote{As specified -in~\ref{allocator.requirements}, the requirements in this Clause apply only to -lists whose allocators compare equal.} +\result +\tcode{bool} \pnum -\tcode{list} provides three splice operations that destructively move elements from one list to -another. The behavior of splice operations is undefined if \tcode{get_allocator() != -x.get_allocator()}. +\returns +\tcode{true} only if +for every rank index $r$ of \tcode{m.extents()} there exists an integer $s_r$ +such that, +for all \tcode{i} where $(\tcode{i}+d_r)$ is +a multidimensional index in \tcode{m.extents()}\iref{mdspan.overview}, +\tcode{m((i + $d_r$)...) - m(i...)} equals $s_r$. +\begin{note} +This implies that for a strided layout +$m(i_0, \dotsc, i_k) = m(0, \dotsc, 0) + i_0 \times s_0 + \dotsb + i_k \times s_k$. +\end{note} +\begin{note} +A mapping can return \tcode{false} even if the condition is met. +For certain layouts, it is possibly not feasible to determine efficiently +whether the layout is strided. +\end{note} +\end{itemdescr} -\indexlibrary{\idxcode{splice}!\tcode{list}}% \begin{itemdecl} -void splice(const_iterator position, list& x); -void splice(const_iterator position, list&& x); +m.stride(r) \end{itemdecl} \begin{itemdescr} \pnum -\requires -\tcode{\&x != this}. +\expects +\tcode{m.is_strided()} is \tcode{true}. \pnum -\effects -Inserts the contents of -\tcode{x} -before -\tcode{position} -and -\tcode{x} -becomes empty. -Pointers and references to the moved elements of -\tcode{x} -now refer to those same elements but as members of -\tcode{*this}. -Iterators referring to the moved elements will continue to refer to their -elements, but they now behave as iterators into -\tcode{*this}, -not into -\tcode{x}. +\result +\tcode{typename M::index_type} \pnum -\throws Nothing. +\returns +$s_r$ as defined in \tcode{m.is_strided()} above. \pnum -\complexity -Constant time. +\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} -\indexlibrary{\idxcode{splice}!\idxcode{list}}% -\indexlibrary{\idxcode{list}!\idxcode{splice}}% \begin{itemdecl} -void splice(const_iterator position, list& x, const_iterator i); -void splice(const_iterator position, list&& x, const_iterator i); +M::is_always_unique() \end{itemdecl} \begin{itemdescr} \pnum -\effects -Inserts an element pointed to by -\tcode{i} -from list -\tcode{x} -before \tcode{position} and removes the element from -\tcode{x}. -The result is unchanged if -\tcode{position == i} -or -\tcode{position == ++i}. -Pointers and references to -\tcode{*i} -continue to refer to this same element but as a member of -\tcode{*this}. -Iterators -to -\tcode{*i} -(including -\tcode{i} -itself) continue to refer to the same element, but now behave as iterators into -\tcode{*this}, -not into -\tcode{x}. +\result +A constant expression\iref{expr.const.const} of type \tcode{bool}. \pnum -\requires -\tcode{i} -is a valid dereferenceable iterator of -\tcode{x}. +\returns +\tcode{true} only if \tcode{m.is_unique()} is \tcode{true} +for all possible objects \tcode{m} of type \tcode{M}. +\begin{note} +A mapping can return \tcode{false} even if the above condition is met. +For certain layout mappings, it is possibly not feasible to determine +whether every instance is unique. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +M::is_always_exhaustive() +\end{itemdecl} +\begin{itemdescr} \pnum -\throws Nothing. +\result +A constant expression\iref{expr.const.const} of type \tcode{bool}. \pnum -\complexity -Constant time. +\returns +\tcode{true} only if \tcode{m.is_exhaustive()} is \tcode{true} +for all possible objects \tcode{m} of type \tcode{M}. +\begin{note} +A mapping can return \tcode{false} even if the above condition is met. +For certain layout mappings, it is possibly not feasible to determine +whether every instance is exhaustive. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{splice}!\idxcode{list}}% -\indexlibrary{\idxcode{list}!\idxcode{splice}}% \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); +M::is_always_strided() \end{itemdecl} \begin{itemdescr} \pnum -\effects -Inserts elements in the range -\range{first}{last} -before -\tcode{position} -and removes the elements from -\tcode{x}. +\result +A constant expression\iref{expr.const.const} of type \tcode{bool}. \pnum -\requires -\tcode{[first, last)} -is a valid range in -\tcode{x}. -The result is undefined if -\tcode{position} -is an iterator in the range -\range{first}{last}. -Pointers and references to the moved elements of -\tcode{x} -now refer to those same elements but as members of -\tcode{*this}. -Iterators referring to the moved elements will continue to refer to their -elements, but they now behave as iterators into -\tcode{*this}, -not into -\tcode{x}. +\returns +\tcode{true} only if \tcode{m.is_strided()} is \tcode{true} +for all possible objects \tcode{m} of type \tcode{M}. +\begin{note} +A mapping can return \tcode{false} even if the above condition is met. +For certain layout mappings, it is possibly not feasible to determine +whether every instance is strided. +\end{note} +\end{itemdescr} + +\rSec4[mdspan.layout.policy.reqmts]{Layout mapping policy requirements} \pnum -\throws Nothing. +A type \tcode{MP} meets the \defn{layout mapping policy} requirements +if for a type \tcode{E} that is a specialization of \tcode{extents}, +\tcode{MP::mapping} is valid and denotes a type \tcode{X} +that meets the layout mapping requirements\iref{mdspan.layout.reqmts}, and +for which the \grammarterm{qualified-id} \tcode{X::layout_type} is valid and +denotes the type \tcode{MP} and +the \grammarterm{qualified-id} \tcode{X::extents_type} denotes \tcode{E}. + +\rSec4[mdspan.layout.policy.overview]{Layout mapping policies} + +\begin{codeblock} +namespace std { + struct @\libglobal{layout_left}@ { + template + class mapping; + }; + struct @\libglobal{layout_right}@ { + template + class mapping; + }; + struct @\libglobal{layout_stride}@ { + template + class mapping; + }; + + template + struct @\libglobal{layout_left_padded}@ { + template class mapping; + }; + template + struct @\libglobal{layout_right_padded}@ { + template class mapping; + }; +} +\end{codeblock} \pnum -\complexity -Constant time if -\tcode{\&x == this}; -otherwise, linear time. -\end{itemdescr} +Each of \tcode{layout_left}, \tcode{layout_right}, and \tcode{layout_stride}, +as well as each specialization of +\tcode{layout_left_padded} and \tcode{layout_right_padded}, +meets the layout mapping policy requirements and is a trivially copyable type. +Furthermore, +\tcode{is_trivially_default_constructible_v} is \tcode{true} +for any such type \tcode{T}. -\indexlibrary{\idxcode{remove}!\tcode{list}}% -\begin{itemdecl} - void remove(const T& value); -template void remove_if(Predicate pred); -\end{itemdecl} +\rSec4[mdspan.layout.left]{Class template \tcode{layout_left::mapping}} + +\rSec5[mdspan.layout.left.overview]{Overview} -\begin{itemdescr} \pnum -\effects -Erases all the elements in the list referred by a list iterator \tcode{i} for which the -following conditions hold: \tcode{*i == value, pred(*i) != false}. -Invalidates only the iterators and references to the erased elements. +\tcode{layout_left} provides a layout mapping +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 @\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; + constexpr mapping(const mapping&) noexcept = default; + constexpr mapping(const extents_type&) noexcept; + template + constexpr explicit(!is_convertible_v) + mapping(const mapping&) noexcept; + template + constexpr explicit(!is_convertible_v) + mapping(const layout_right::mapping&) noexcept; + template + constexpr explicit(!is_convertible_v) + mapping(const LayoutLeftPaddedMapping&) noexcept; + template + 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& @\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 @\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 @\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; + + template + friend constexpr bool operator==(const mapping&, const mapping&) noexcept; + + private: + extents_type @\exposid{extents_}@{}; // \expos + + // \ref{mdspan.sub.map}, \tcode{submdspan} mapping specialization + template + constexpr auto @\exposid{submdspan-mapping-impl}@(SliceSpecifiers...) const // \expos + -> @\seebelow@; + + template + friend constexpr auto @\libmember{submdspan_mapping}{layout_left::mapping}@( + const mapping& src, SliceSpecifiers... slices) { + return src.@\exposid{submdspan-mapping-impl}@(slices...); + } + }; +} +\end{codeblock} \pnum -\throws -Nothing unless an exception is thrown by -\tcode{*i == value} -or -\tcode{pred(*i) != false}. +If \tcode{Extents} is not a specialization of \tcode{extents}, +then the program is ill-formed. \pnum -\remarks Stable~(\ref{algorithm.stable}). +\tcode{layout_left::mapping} is a trivially copyable type +that models \libconcept{regular} for each \tcode{E}. \pnum -\complexity -Exactly -\tcode{size()} -applications of the corresponding predicate. -\end{itemdescr} +\mandates +If \tcode{Extents::rank_dynamic() == 0} is \tcode{true}, +then the size of the multidimensional index space \tcode{Extents()} +is representable as a value of type \tcode{typename Extents::index_type}. + +\rSec5[mdspan.layout.left.cons]{Constructors} -\indexlibrary{\idxcode{unique}!\tcode{list}}% +\indexlibraryctor{layout_left::mapping}% \begin{itemdecl} - void unique(); -template void unique(BinaryPredicate binary_pred); +constexpr mapping(const extents_type& e) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Erases all but the first element from every -consecutive group of equal elements referred to by the iterator \tcode{i} in the range -\range{first + 1}{last} for which \tcode{*i == *(i-1)} (for the version of -\tcode{unique} with no arguments) or \tcode{pred(*i, *(i - 1))} (for the version of -\tcode{unique} with a predicate argument) holds. -Invalidates only the iterators and references to the erased elements. - -\pnum -\throws -Nothing unless an exception is thrown by -\tcode{*i == *(i-1)} -or -\tcode{pred(*i, *(i - 1))} +\expects +The size of the multidimensional index space \tcode{e} +is representable as a value of type \tcode{index_type}\iref{basic.fundamental}. \pnum -\complexity -If the range -\tcode{[first, last)} -is not empty, exactly -\tcode{(last - first) - 1} -applications of the corresponding predicate, -otherwise no applications of the predicate. +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{e}. \end{itemdescr} -\indexlibrary{\idxcode{merge}!\tcode{list}}% +\indexlibraryctor{layout_left::mapping}% \begin{itemdecl} -void merge(list& x); -void merge(list&& x); -template void merge(list& x, Compare comp); -template void merge(list&& x, Compare comp); +template + constexpr explicit(!is_convertible_v) + mapping(const mapping& other) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires -\tcode{comp} shall define a strict weak ordering~(\ref{alg.sorting}), and both the list and the argument list shall be -sorted according to this ordering. - -\pnum -\effects -If \tcode{(\&x == this)} does nothing; otherwise, merges the two sorted ranges \tcode{[begin(), -end())} and \tcode{[x.\brk{}begin(), x.end())}. The result is a range in which the elements -will be sorted in non-decreasing order according to the ordering defined by \tcode{comp}; that -is, for every iterator \tcode{i}, in the range other than the first, the condition -\tcode{comp(*i, *(i - 1))} will be false. -Pointers and references to the moved elements of \tcode{x} now refer to those same elements -but as members of \tcode{*this}. Iterators referring to the moved elements will continue to -refer to their elements, but they now behave as iterators into \tcode{*this}, not into -\tcode{x}. +\constraints +\tcode{is_constructible_v} is \tcode{true}. \pnum -\remarks Stable~(\ref{algorithm.stable}). If \tcode{(\&x != this)} the range \tcode{[x.begin(), x.end())} -is empty after the merge. -No elements are copied by this operation. The behavior is undefined if -\tcode{this->get_allocator() != x.get_allocator()}. +\expects +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}\iref{basic.fundamental}. \pnum -\complexity -At most -\tcode{size() + x.size() - 1} -applications of \tcode{comp} if -\tcode{(\&x != this)}; -otherwise, no applications of \tcode{comp} are performed. -If an exception is thrown other than by a comparison there are no effects. +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. \end{itemdescr} -\indexlibrary{\idxcode{reverse}!\tcode{list}}% +\indexlibraryctor{layout_left::mapping}% \begin{itemdecl} -void reverse() noexcept; +template + constexpr explicit(!is_convertible_v) + mapping(const layout_right::mapping& other) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Reverses the order of the elements in the list. -Does not affect the validity of iterators and references. +\constraints +\begin{itemize} +\item +\tcode{extents_type::rank() <= 1} is \tcode{true}, and +\item +\tcode{is_constructible_v} is \tcode{true}. +\end{itemize} \pnum -\complexity -Linear time. +\expects +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}\iref{basic.fundamental}. + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. \end{itemdescr} -\indexlibrary{\idxcode{sort}!\tcode{list}}% +\indexlibraryctor{layout_left::mapping}% \begin{itemdecl} - void sort(); -template void sort(Compare comp); +template + constexpr explicit(!is_convertible_v) + mapping(const LayoutLeftPaddedMapping&) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires -\tcode{operator<} -(for the first -version) -or -\tcode{comp} -(for the second version) -shall define a strict weak ordering~(\ref{alg.sorting}). +\constraints +\begin{itemize} +\item +\tcode{\exposid{is-layout-left-padded-mapping-of}} is \tcode{true}. +\item +\tcode{is_constructible_v}\newline is \tcode{true}. +\end{itemize} \pnum -\effects -Sorts the list according to the \tcode{operator<} or a \tcode{Compare} function object. -Does not affect the validity of iterators and references. +\mandates +If +\begin{itemize} +\item +\tcode{Extents::rank()} is greater than one, +\item +\tcode{Extents::static_extent(0)} does not equal \tcode{dynamic_extent}, and +\item +\tcode{LayoutLeftPaddedMapping::\exposid{static-padding-stride}} +does not equal \tcode{dynamic_extent}, +\end{itemize} +then \tcode{Extents::static_extent(0)} equals +\tcode{LayoutLeftPaddedMapping::\exposid{static-padding-stride}}. \pnum -\remarks Stable~(\ref{algorithm.stable}). +\expects +\begin{itemize} +\item +If \tcode{extents_type::rank() > 1} is \tcode{true}, +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}. +\end{itemize} \pnum -\complexity -Approximately -$N \log(N)$ -comparisons, where -\tcode{N == size()}. +\effects +Direct-non-list-initializes \tcode{extents_} with \tcode{other.extents()}. \end{itemdescr} -\rSec3[list.special]{\tcode{list} specialized algorithms} - -\indexlibrary{\idxcode{swap}!\idxcode{list}}% -\indexlibrary{\idxcode{list}!\idxcode{swap}}% +\indexlibraryctor{layout_left::mapping}% \begin{itemdecl} -template - void swap(list& x, list& y) - noexcept(noexcept(x.swap(y))); +template + constexpr explicit(@\seebelow@) + mapping(const layout_stride::mapping& other); \end{itemdecl} \begin{itemdescr} \pnum -\effects -\begin{codeblock} -x.swap(y); -\end{codeblock} -\end{itemdescr} - -\rSec2[vector]{Class template \tcode{vector}} - -\rSec3[vector.overview]{Class template \tcode{vector} overview} +\constraints +\tcode{is_constructible_v} is \tcode{true}. \pnum -\indexlibrary{\idxcode{vector}}% -A -\tcode{vector} -is a sequence container that supports -(amortized) constant time insert and erase operations at the end; -insert and erase in the middle take linear time. -Storage management is handled automatically, though hints can be given -to improve efficiency. +\expects +\begin{itemize} +\item +If \tcode{extents_type::rank() > 0} is \tcode{true}, +then for all $r$ in the range $[0, \tcode{extents_type::rank()})$, +\tcode{other.stride($r$)} equals +\tcode{other.extents().\exposid{fwd-prod-of-extents}($r$)}, and +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}\iref{basic.fundamental}. +\end{itemize} \pnum -A \tcode{vector} satisfies all of the requirements of a container and of a -reversible container (given in two tables in~\ref{container.requirements}), of a -sequence container, including most of the optional sequence container -requirements~(\ref{sequence.reqmts}), of an allocator-aware container -(Table~\ref{tab:containers.allocatoraware}), -and, for an element type other than \tcode{bool}, -of a contiguous container~(\ref{container.requirements.general}). -The exceptions are the -\tcode{push_front}, \tcode{pop_front}, and \tcode{emplace_front} member functions, which are not -provided. Descriptions are provided here only for operations on \tcode{vector} -that are not described in one of these tables or for operations where there is -additional semantic information. +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: \begin{codeblock} -namespace std { - template > - class vector { - public: - // types: - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ iterator; // see \ref{container.requirements} - typedef @\impdef@ const_iterator; // see \ref{container.requirements} - typedef @\impdef@ size_type; // see \ref{container.requirements} - typedef @\impdef@ difference_type;// see \ref{container.requirements} - typedef T value_type; - typedef Allocator allocator_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - // \ref{vector.cons}, construct/copy/destroy: - vector() noexcept : vector(Allocator()) { } - explicit vector(const Allocator&) noexcept; - explicit vector(size_type n, const Allocator& = Allocator()); - vector(size_type n, const T& value, const Allocator& = Allocator()); - template - vector(InputIterator first, InputIterator last, - const Allocator& = Allocator()); - vector(const vector& x); - vector(vector&&) noexcept; - vector(const vector&, const Allocator&); - vector(vector&&, const Allocator&); - vector(initializer_list, const Allocator& = Allocator()); - ~vector(); - vector& operator=(const vector& x); - vector& operator=(vector&& x) - noexcept(allocator_traits::propagate_on_container_move_assignment::value || - allocator_traits::is_always_equal::value); - vector& operator=(initializer_list); - template - void assign(InputIterator first, InputIterator last); - void assign(size_type n, const T& u); - 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{vector.capacity}, capacity: - size_type size() const noexcept; - size_type max_size() const noexcept; - void resize(size_type sz); - void resize(size_type sz, const T& c); - size_type capacity() const noexcept; - bool empty() const noexcept; - void reserve(size_type n); - void shrink_to_fit(); - - // element access: - reference operator[](size_type n); - const_reference operator[](size_type n) const; - const_reference at(size_type n) const; - reference at(size_type n); - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - - // \ref{vector.data}, data access - T* data() noexcept; - const T* data() const noexcept; - - // \ref{vector.modifiers}, modifiers: - template void emplace_back(Args&&... args); - void push_back(const T& x); - void push_back(T&& x); - 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 - iterator insert(const_iterator position, - InputIterator first, InputIterator last); - iterator insert(const_iterator position, initializer_list il); - iterator erase(const_iterator position); - iterator erase(const_iterator first, const_iterator last); - void swap(vector&) - noexcept(allocator_traits::propagate_on_container_swap::value || - allocator_traits::is_always_equal::value); - void clear() noexcept; - }; - - template - bool operator==(const vector& x, const vector& y); - template - bool operator< (const vector& x, const vector& y); - template - bool operator!=(const vector& x, const vector& y); - template - bool operator> (const vector& x, const vector& y); - template - bool operator>=(const vector& x, const vector& y); - template - bool operator<=(const vector& x, const vector& y); - - // \ref{vector.special}, specialized algorithms: - template - void swap(vector& x, vector& y) - noexcept(noexcept(x.swap(y))); -} -\end{codeblock}% -\indexlibrary{\idxcode{vector}!\tcode{operator==}}% -\indexlibrary{\idxcode{vector}!\tcode{operator<}} +!(extents_type::rank() == 0 && is_convertible_v) +\end{codeblock} +\end{itemdescr} -\rSec3[vector.cons]{\tcode{vector} constructors, copy, and assignment} +\rSec5[mdspan.layout.left.obs]{Observers} -\indexlibrary{\idxcode{vector}!\tcode{vector}} +\indexlibrarymember{required_span_size}{layout_left::mapping}% \begin{itemdecl} -explicit vector(const Allocator&); +constexpr index_type required_span_size() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an empty \tcode{vector}, using the -specified allocator. - -\pnum -\complexity Constant. +\returns +\tcode{extents().\exposid{fwd-prod-of-extents}(extents_type::rank())}. \end{itemdescr} -\indexlibrary{\idxcode{vector}!\tcode{vector}} +\indexlibrarymember{operator()}{layout_left::mapping}% \begin{itemdecl} -explicit vector(size_type n, const Allocator& = Allocator()); +template + constexpr index_type operator()(Indices... i) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{vector} with \tcode{n} -default-inserted elements using the specified allocator. +\constraints +\begin{itemize} +\item +\tcode{sizeof...(Indices) == extents_type::rank()} is \tcode{true}, +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}. +\end{itemize} \pnum -\requires \tcode{T} shall be \tcode{DefaultInsertable} into \tcode{*this}. +\expects +\tcode{extents_type::\exposid{index-cast}(i)} is +a multidimensional index in \exposid{extents_}\iref{mdspan.overview}. \pnum -\complexity Linear in \tcode{n}. +\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 ((static_cast(std::move(i)) * stride(P)) + ... + 0); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{vector}!\tcode{vector}} +\indexlibrarymember{stride}{layout_left::mapping}% \begin{itemdecl} -vector(size_type n, const T& value, - const Allocator& = Allocator()); +constexpr index_type stride(rank_type i) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs a \tcode{vector} with \tcode{n} -copies of \tcode{value}, using the specified allocator. +\constraints +\tcode{extents_type::rank() > 0} is \tcode{true}. \pnum -\requires \tcode{T} shall be -\tcode{CopyInsertable} into \tcode{*this}. +\expects +\tcode{i < extents_type::rank()} is \tcode{true}. \pnum -\complexity Linear in \tcode{n}. +\returns +\tcode{extents().\exposid{fwd-prod-of-extents}(i)}. \end{itemdescr} -\indexlibrary{\idxcode{vector}!\tcode{vector}} +\indexlibrarymember{operator==}{layout_left::mapping}% \begin{itemdecl} -template - vector(InputIterator first, InputIterator last, - const Allocator& = Allocator()); +template + friend constexpr bool operator==(const mapping& x, const mapping& y) noexcept; \end{itemdecl} \begin{itemdescr} - \pnum -\effects Constructs a \tcode{vector} equal to the -range \range{first}{last}, using the specified allocator. +\constraints +\tcode{extents_type::rank() == OtherExtents::rank()} is \tcode{true}. \pnum -\complexity -Makes only $N$ -calls to the copy constructor of -\tcode{T} -(where $N$ -is the distance between -\tcode{first} -and -\tcode{last}) -and no reallocations if iterators first and last are of forward, bidirectional, or random access categories. -It makes order -\tcode{N} -calls to the copy constructor of -\tcode{T} -and order -$\log(N)$ -reallocations if they are just input iterators. +\effects +Equivalent to: \tcode{return x.extents() == y.extents();} \end{itemdescr} -\rSec3[vector.capacity]{\tcode{vector} capacity} +\rSec4[mdspan.layout.right]{Class template \tcode{layout_right::mapping}} -\indexlibrary{\idxcode{capacity}!\idxcode{vector}}% -\begin{itemdecl} -size_type capacity() const noexcept; -\end{itemdecl} +\rSec5[mdspan.layout.right.overview]{Overview} -\begin{itemdescr} \pnum -\returns -The total number of elements that the vector can hold -without requiring reallocation. -\end{itemdescr} +\tcode{layout_right} provides a layout mapping +where the rightmost extent is stride 1, and +strides increase right-to-left as the product of extents. -\indexlibrary{\idxcode{reserve}!\idxcode{vector}}% -\begin{itemdecl} -void reserve(size_type n); -\end{itemdecl} +\indexlibrarymember{mapping}{layout_right}% +\begin{codeblock} +namespace std { + template + class layout_right::mapping { + public: + 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; + constexpr mapping(const mapping&) noexcept = default; + constexpr mapping(const extents_type&) noexcept; + template + constexpr explicit(!is_convertible_v) + mapping(const mapping&) noexcept; + template + constexpr explicit(!is_convertible_v) + mapping(const layout_left::mapping&) noexcept; + template + constexpr explicit(!is_convertible_v) + mapping(const LayoutRightPaddedMapping&) noexcept; + template + 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& @\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 @\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 @\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; + + template + friend constexpr bool operator==(const mapping&, const mapping&) noexcept; + + private: + extents_type @\exposid{extents_}@{}; // \expos + + // \ref{mdspan.sub.map}, \tcode{submdspan} mapping specialization + template + constexpr auto @\exposid{submdspan-mapping-impl}@(SliceSpecifiers...) const // \expos + -> @\seebelow@; + + template + friend constexpr auto @\libmember{submdspan_mapping}{layout_right::mapping}@( + const mapping& src, SliceSpecifiers... slices) { + return src.@\exposid{submdspan-mapping-impl}@(slices...); + } + }; +} +\end{codeblock} -\begin{itemdescr} \pnum -\requires \tcode{T} shall be \tcode{MoveInsertable} into \tcode{*this}. +If \tcode{Extents} is not a specialization of \tcode{extents}, +then the program is ill-formed. \pnum -\effects -A directive that informs a -\tcode{vector} -of a planned change in size, so that it can manage the storage allocation accordingly. -After -\tcode{reserve()}, -\tcode{capacity()} -is greater or equal to the argument of -\tcode{reserve} -if reallocation happens; and equal to the previous value of -\tcode{capacity()} -otherwise. -Reallocation happens at this point if and only if the current capacity is less than the -argument of -\tcode{reserve()}. If an exception is thrown -other than by the move constructor of a non-\tcode{CopyInsertable} type, -there are no effects. +\tcode{layout_right::mapping} is a trivially copyable type +that models \libconcept{regular} for each \tcode{E}. \pnum -\complexity -It does not change the size of the sequence and takes at most linear -time in the size of the sequence. +\mandates +If \tcode{Extents::rank_dynamic() == 0} is \tcode{true}, +then the size of the multidimensional index space \tcode{Extents()} +is representable as a value of type \tcode{typename Extents::index_type}. + +\rSec5[mdspan.layout.right.cons]{Constructors} +\indexlibraryctor{layout_right::mapping}% +\begin{itemdecl} +constexpr mapping(const extents_type& e) noexcept; +\end{itemdecl} + +\begin{itemdescr} \pnum -\throws -\tcode{length_error} if \tcode{n > -max_size()}.\footnote{\tcode{reserve()} uses \tcode{Allocator::allocate()} which -may throw an appropriate exception.} +\expects +The size of the multidimensional index space \tcode{e} is representable as +a value of type \tcode{index_type}\iref{basic.fundamental}. \pnum -\notes -Reallocation invalidates all the references, pointers, and iterators -referring to the elements in the sequence. -No reallocation shall take place during insertions that happen -after a call to -\tcode{reserve()} -until the time when an insertion would make the size of the vector -greater than the value of -\tcode{capacity()}. +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{e}. \end{itemdescr} -\indexlibrary{\idxcode{shrink_to_fit}!\idxcode{vector}}% +\indexlibraryctor{layout_right::mapping}% \begin{itemdecl} -void shrink_to_fit(); +template + constexpr explicit(!is_convertible_v) + mapping(const mapping& other) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{T} shall be \tcode{MoveInsertable} into \tcode{*this}. +\constraints +\tcode{is_constructible_v} is \tcode{true}. \pnum -\complexity Linear in the size of the sequence. +\expects +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}\iref{basic.fundamental}. \pnum -\notes \tcode{shrink_to_fit} is a non-binding request to reduce \tcode{capacity()} to \tcode{size()}. \enternote The request is non-binding to allow latitude for implementation-specific optimizations. \exitnote -If an exception is thrown other than by the move constructor of a non-\tcode{CopyInsertable} \tcode{T} there are no effects. +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. \end{itemdescr} -\indexlibrary{\idxcode{swap}!\idxcode{vector}}% +\indexlibraryctor{layout_right::mapping}% \begin{itemdecl} -void swap(vector& x) - noexcept(allocator_traits::propagate_on_container_swap::value || - allocator_traits::is_always_equal::value); +template + constexpr explicit(!is_convertible_v) + mapping(const layout_left::mapping& other) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Exchanges the contents and -\tcode{capacity()} -of -\tcode{*this} -with that of \tcode{x}. +\constraints +\begin{itemize} +\item +\tcode{extents_type::rank() <= 1} is \tcode{true}, and +\item +\tcode{is_constructible_v} is \tcode{true}. +\end{itemize} \pnum -\complexity -Constant time. +\expects +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}\iref{basic.fundamental}. + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. \end{itemdescr} -\indexlibrary{\idxcode{resize}!\idxcode{vector}}% +\indexlibraryctor{layout_right::mapping}% \begin{itemdecl} -void resize(size_type sz); +template + constexpr explicit(!is_convertible_v) + mapping(const LayoutRightPaddedMapping&) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects If \tcode{sz <= size()}, equivalent to -calling \tcode{pop_back()} \tcode{size() - sz} times. If \tcode{size() < sz}, -appends \tcode{sz - size()} default-inserted elements to the -sequence. +\constraints +\begin{itemize} +\item +\tcode{\exposid{is-layout-right-padded-mapping-of}} +is \tcode{true}. +\item +\tcode{is_constructible_v} +is \tcode{true}. +\end{itemize} + +\pnum +\mandates +If +\begin{itemize} +\item +\tcode{Extents::rank()} is greater than one, +\item +\tcode{Extents::static_extent(Extents::rank() - 1)} +does not equal \tcode{dynamic_extent}, and +\item +\tcode{LayoutRightPaddedMapping::\exposid{static-padding-stride}} +does not equal \tcode{dynamic_extent}, +\end{itemize} +then \tcode{Extents::static_extent(Extents::rank() - 1)} equals +\tcode{LayoutRightPaddedMapping::\exposid{sta\-tic-padding-stride}}. \pnum -\requires \tcode{T} shall be -\tcode{MoveInsertable} and \tcode{DefaultInsertable} into \tcode{*this}. +\expects +\begin{itemize} +\item +If \tcode{extents_type::rank() > 1} is \tcode{true}, +then \tcode{other.stride(extents_type::rank() - 2)}\newline equals +\tcode{other.extents().extent(extents_type::rank() - 1)}. +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}. +\end{itemize} \pnum -\notes If an exception is thrown other than by the move constructor of a non-\tcode{CopyInsertable} -\tcode{T} there are no effects. +\effects +Direct-non-list-initializes \tcode{extents_} with \tcode{other.extents()}. \end{itemdescr} -\indexlibrary{\idxcode{resize}!\idxcode{vector}}% +\indexlibraryctor{layout_right::mapping}% \begin{itemdecl} -void resize(size_type sz, const T& c); +template + constexpr explicit(@\seebelow@) + mapping(const layout_stride::mapping& other) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects If \tcode{sz <= size()}, equivalent to -calling \tcode{pop_back()} \tcode{size() - sz} times. If \tcode{size() < sz}, -appends \tcode{sz - size()} copies of \tcode{c} to the sequence. +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\expects +\begin{itemize} +\item +If \tcode{extents_type::rank() > 0} is \tcode{true}, +then for all $r$ in the range $[0, \tcode{extents_type::rank()})$, +\tcode{other.stride($r$)} equals +\tcode{other.extents().\exposid{rev-prod-of-extents}($r$)}. +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}\iref{basic.fundamental}. +\end{itemize} \pnum -\requires \tcode{T} shall be -\tcode{CopyInsertable} into \tcode{*this}. +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. \pnum -\notes If an exception is thrown there are no effects. +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(extents_type::rank() == 0 && is_convertible_v) +\end{codeblock} \end{itemdescr} -\rSec3[vector.data]{\tcode{vector} data} +\rSec5[mdspan.layout.right.obs]{Observers} -\indexlibrary{\idxcode{data}!\idxcode{vector}}% +\indexlibrarymember{required_span_size}{layout_right::mapping}% \begin{itemdecl} -T* data() noexcept; -const T* data() const noexcept; +constexpr index_type required_span_size() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -A pointer such that \range{data()}{data() + size()} is a valid range. For a -non-empty vector, \tcode{data()} \tcode{==} \tcode{\&front()}. - -\pnum -\complexity -Constant time. +\tcode{extents().\exposid{fwd-prod-of-extents}(extents_type::rank())}. \end{itemdescr} -\rSec3[vector.modifiers]{\tcode{vector} modifiers} - -\indexlibrary{\idxcode{insert}!\idxcode{vector}}% +\indexlibrarymember{operator()}{layout_right::mapping}% \begin{itemdecl} -iterator insert(const_iterator position, const T& x); -iterator insert(const_iterator position, T&& x); -iterator insert(const_iterator position, size_type n, const T& x); -template - iterator insert(const_iterator position, InputIterator first, InputIterator last); -iterator insert(const_iterator position, initializer_list); - -template void emplace_back(Args&&... args); -template iterator emplace(const_iterator position, Args&&... args); -void push_back(const T& x); -void push_back(T&& x); +template + constexpr index_type operator()(Indices... i) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\notes -Causes reallocation if the new size is greater than the old capacity. -If no reallocation happens, all the iterators and references before the insertion point remain valid. -If an exception is thrown other than by -the copy constructor, move constructor, -assignment operator, or move assignment operator of -\tcode{T} or by any \tcode{InputIterator} operation -there are no effects. -If an exception is thrown while inserting a single element at the end and -\tcode{T} is \tcode{CopyInsertable} or \tcode{is_nothrow_move_constructible::value} -is \tcode{true}, there are no effects. -Otherwise, if an exception is thrown by the move constructor of a non-\tcode{CopyInsertable} -\tcode{T}, the effects are unspecified. +\constraints +\begin{itemize} +\item +\tcode{sizeof...(Indices) == extents_type::rank()} is \tcode{true}, +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is +\tcode{true}. +\end{itemize} \pnum -\complexity -The complexity is linear in the number of elements inserted plus the distance -to the end of the vector. +\expects +\tcode{extents_type::\exposid{index-cast}(i)} is +a multidimensional index in \exposid{extents_}\iref{mdspan.overview}. + +\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 ((static_cast(std::move(i)) * stride(P)) + ... + 0); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{erase}!\idxcode{vector}}% +\indexlibrarymember{stride}{layout_right::mapping}% \begin{itemdecl} -iterator erase(const_iterator position); -iterator erase(const_iterator first, const_iterator last); +constexpr index_type stride(rank_type i) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Invalidates iterators and references at or after the point of the erase. +\constraints +\tcode{extents_type::rank() > 0} is \tcode{true}. -\pnum -\complexity -The destructor of \tcode{T} is called the number of times equal to the -number of the elements erased, but the move assignment operator -of \tcode{T} is called the number of times equal to the number of -elements in the vector after the erased elements. +\pnum +\expects +\tcode{i < extents_type::rank()} is \tcode{true}. \pnum -\throws -Nothing unless an exception is thrown by the -copy constructor, move constructor, -assignment operator, or move assignment operator of -\tcode{T}. +\returns +\tcode{extents().\exposid{rev-prod-of-extents}(i)}. \end{itemdescr} -\rSec3[vector.special]{\tcode{vector} specialized algorithms} - -\indexlibrary{\idxcode{swap}!\idxcode{vector}}% -\indexlibrary{\idxcode{vector}!\idxcode{swap}}% +\indexlibrarymember{operator==}{layout_right::mapping}% \begin{itemdecl} -template - void swap(vector& x, vector& y) - noexcept(noexcept(x.swap(y))); +template + friend constexpr bool operator==(const mapping& x, const mapping& y) noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{extents_type::rank() == OtherExtents::rank()} is \tcode{true}. + \pnum \effects -\begin{codeblock} -x.swap(y); -\end{codeblock} +Equivalent to: \tcode{return x.extents() == y.extents();} \end{itemdescr} -\rSec2[vector.bool]{Class \tcode{vector}} +\rSec4[mdspan.layout.stride]{Class template \tcode{layout_stride::mapping}} + +\rSec5[mdspan.layout.stride.overview]{Overview} \pnum -\indexlibrary{\idxcode{vector}}% -To optimize space allocation, a specialization of vector for -\tcode{bool} -elements is provided: +\tcode{layout_stride} provides a layout mapping +where the strides are user-defined. +\indexlibrarymember{mapping}{layout_stride}% \begin{codeblock} namespace std { - template class vector { + template + class layout_stride::mapping { public: - // types: - typedef bool const_reference; - typedef @\impdef@ iterator; // see \ref{container.requirements} - typedef @\impdef@ const_iterator; // see \ref{container.requirements} - typedef @\impdef@ size_type; // see \ref{container.requirements} - typedef @\impdef@ difference_type;// see \ref{container.requirements} - typedef bool value_type; - typedef Allocator allocator_type; - typedef @\impdef@ pointer; - typedef @\impdef@ const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - // bit reference: - class reference { - friend class vector; - reference() noexcept; - public: - ~reference(); - operator bool() const noexcept; - reference& operator=(const bool x) noexcept; - reference& operator=(const reference& x) noexcept; - void flip() noexcept; // flips the bit - }; + 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; - // construct/copy/destroy: - vector() : vector(Allocator()) { } - explicit vector(const Allocator&); - explicit vector(size_type n, const Allocator& = Allocator()); - vector(size_type n, const bool& value, - const Allocator& = Allocator()); - template - vector(InputIterator first, InputIterator last, - const Allocator& = Allocator()); - vector(const vector& x); - vector(vector&& x); - vector(const vector&, const Allocator&); - vector(vector&&, const Allocator&); - vector(initializer_list, const Allocator& = Allocator())); - ~vector(); - vector& operator=(const vector& x); - vector& operator=(vector&& x); - vector& operator=(initializer_list); - template - void assign(InputIterator first, InputIterator last); - void assign(size_type n, const bool& t); - void assign(initializer_list); - allocator_type get_allocator() const noexcept; + private: + static constexpr rank_type @\exposid{rank_}@ = extents_type::rank(); // \expos - // 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; + public: + // \ref{mdspan.layout.stride.cons}, constructors + constexpr mapping() noexcept; + constexpr mapping(const mapping&) noexcept = default; + template + constexpr mapping(const extents_type&, span) noexcept; + template + constexpr mapping(const extents_type&, const array&) noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + template + constexpr explicit(@\seebelow@) mapping(const StridedLayoutMapping&) noexcept; - // capacity: - size_type size() const noexcept; - size_type max_size() const noexcept; - void resize(size_type sz, bool c = false); - size_type capacity() const noexcept; - bool empty() const noexcept; - void reserve(size_type n); - void shrink_to_fit(); - - // element access: - reference operator[](size_type n); - const_reference operator[](size_type n) const; - const_reference at(size_type n) const; - reference at(size_type n); - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - - // modifiers: - template void emplace_back(Args&&... args); - void push_back(const bool& x); - void pop_back(); - template iterator emplace(const_iterator position, Args&&... args); - iterator insert(const_iterator position, const bool& x); - iterator insert (const_iterator position, size_type n, const bool& x); - template - iterator insert(const_iterator position, - InputIterator first, InputIterator last); - iterator insert(const_iterator position, initializer_list il); + constexpr mapping& operator=(const mapping&) noexcept = default; - iterator erase(const_iterator position); - iterator erase(const_iterator first, const_iterator last); - void swap(vector&); - static void swap(reference x, reference y) noexcept; - void flip() noexcept; // flips all bits - void clear() noexcept; + // \ref{mdspan.layout.stride.obs}, observers + 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 @\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 @\libmember{is_unique}{layout_stride::mapping}@() noexcept { return true; } + constexpr bool is_exhaustive() const noexcept; + static constexpr bool @\libmember{is_strided}{layout_stride::mapping}@() noexcept { return true; } + + 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; + + private: + extents_type @\exposid{extents_}@{}; // \expos + array @\exposid{strides_}@{}; // \expos + + // \ref{mdspan.sub.map}, \tcode{submdspan} mapping specialization + template + constexpr auto @\exposid{submdspan-mapping-impl}@(SliceSpecifiers...) const // \expos + -> @\seebelow@; + + template + friend constexpr auto @\libmember{submdspan_mapping}{layout_stride::mapping}@( + const mapping& src, SliceSpecifiers... slices) { + return src.@\exposid{submdspan-mapping-impl}@(slices...); + } }; } -\end{codeblock}% +\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}~(\ref{allocator.traits.members}) -is not used to construct these values. +If \tcode{Extents} is not a specialization of \tcode{extents}, +then the program is ill-formed. \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. +\tcode{layout_stride::mapping} is a trivially copyable type +that models \libconcept{regular} for each \tcode{E}. \pnum -\tcode{reference} -is a class that simulates the behavior of references of a single bit in -\tcode{vector}. The conversion operator returns \tcode{true} -when the bit is set, and \tcode{false} otherwise. The assignment operator -sets the bit when the argument is (convertible to) \tcode{true} and -clears it otherwise. \tcode{flip} reverses the state of the bit. +\mandates +If \tcode{Extents::rank_dynamic() == 0} is \tcode{true}, +then the size of the multidimensional index space \tcode{Extents()} +is representable as a value of type \tcode{typename Extents::index_type}. + +\rSec5[mdspan.layout.stride.expo]{Exposition-only helpers} + +\pnum +Let \tcode{\exposid{REQUIRED-SPAN-SIZE}(e, strides)} be: +\begin{itemize} +\item +\tcode{1}, if \tcode{e.rank() == 0} is \tcode{true}, +\item +otherwise \tcode{0}, if the size of the multidimensional index space \tcode{e} is 0, +\item +otherwise \tcode{1} plus the sum of products of +\tcode{(e.extent($r$) - 1)} and +\begin{codeblock} +extents_type::@\exposid{index-cast}@(strides[@$r$@]) +\end{codeblock} + for all $r$ in the range $[0, \tcode{e.rank()})$. +\end{itemize} + +\pnum +Let \tcode{\exposid{OFFSET}(m)} be: +\begin{itemize} +\item +\tcode{m()}, if \tcode{e.rank() == 0} is \tcode{true}, +\item +otherwise \tcode{0}, if the size of the multidimensional index space \tcode{e} is 0, +\item +otherwise \tcode{m(z...)} for a pack of integers \tcode{z} +that is a multidimensional index in \tcode{m.extents()} and +each element of \tcode{z} equals 0. +\end{itemize} + +\pnum +Let \exposid{is-extents} be the exposition-only variable template +defined as follows: +\begin{codeblock} +template + constexpr bool @\exposid{is-extents}@ = false; // \expos +template + constexpr bool @\exposid{is-extents}@> = true; // \expos +\end{codeblock} -\indexlibrary{\idxcode{flip}!\idxcode{vector}}% -\indexlibrary{\idxcode{vector}!\idxcode{flip}}% +\pnum +Let \exposconcept{layout-mapping-alike} be the exposition-only concept +defined as follows: +\begin{codeblock} +template +concept @\defexposconcept{layout-mapping-alike}@ = requires { // \expos + requires @\exposid{is-extents}@; + { M::is_always_strided() } -> @\libconcept{same_as}@; + { M::is_always_exhaustive() } -> @\libconcept{same_as}@; + { M::is_always_unique() } -> @\libconcept{same_as}@; + bool_constant::value; + bool_constant::value; + bool_constant::value; +}; +\end{codeblock} +\begin{note} +This concept checks that the functions +\tcode{M::is_always_strided()}, +\tcode{M::is_always_exhaustive()}, and +\tcode{M::is_always_unique()} exist, +are constant expressions, and +have a return type of \tcode{bool}. +\end{note} + +\rSec5[mdspan.layout.stride.cons]{Constructors} + +\indexlibraryctor{layout_stride::mapping}% \begin{itemdecl} -void flip() noexcept; +constexpr mapping() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Replaces each element in the container with its complement. +\expects +\tcode{layout_right::mapping().required_span_size()} +is representable as a value of type \tcode{index_type}\iref{basic.fundamental}. + +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{extents_type()}, and +for all $d$ in the range \range{0}{\exposid{rank_}}, +direct-non-list-initializes \tcode{\exposid{strides_}[$d$]} with +\tcode{layout_right::mapping().stride($d$)}. \end{itemdescr} -\indexlibrary{\idxcode{swap}!\idxcode{vector}}% -\indexlibrary{\idxcode{vector}!\idxcode{swap}}% +\indexlibraryctor{layout_stride::mapping}% \begin{itemdecl} -static void swap(reference x, reference y) noexcept; +template + constexpr mapping(const extents_type& e, span s) noexcept; +template + constexpr mapping(const extents_type& e, const array& s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects exchanges the contents of \tcode{x} and \tcode{y} as if by +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} is \tcode{true}, and +\item +\tcode{is_nothrow_constructible_v} is \tcode{true}. +\end{itemize} -\begin{codeblock} -bool b = x; -x = y; -y = b; -\end{codeblock} +\pnum +\expects +\begin{itemize} +\item +The result of converting \tcode{s[$i$]} to \tcode{index_type} +is greater than \tcode{0} +for all $i$ in the range $[0, \exposid{rank_})$. +\item +\tcode{\exposid{REQUIRED-SPAN-SIZE}(e, s)} is representable +as a value of type \tcode{index_type}\iref{basic.fundamental}. +\item +If \exposid{rank_} is greater than 0, +then there exists a permutation $P$ of the integers +in the range $[0, \exposid{rank_})$, +such that \tcode{s[$p_i$] >= s[$p_{i-1}$] * e.extent(p$_{i-1}$)} is \tcode{true} +for all $i$ in the range $[1, \exposid{rank_})$, +where $p_i$ is the $i^\text{th}$ element of $P$. +\begin{note} +For \tcode{layout_stride}, +this condition is necessary and sufficient +for \tcode{is_unique()} to be \tcode{true}. +\end{note} +\end{itemize} +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{e}, and +for all $d$ in the range $[0, \exposid{rank_})$, +direct-non-list-initializes \tcode{strides_[$d$]} with \tcode{as_const(s[$d$])}. \end{itemdescr} +\indexlibraryctor{layout_stride::mapping}% \begin{itemdecl} -template struct hash >; +template + constexpr explicit(@\seebelow@) + mapping(const StridedLayoutMapping& other) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -The template specialization shall meet the requirements of class template -\tcode{hash}~(\ref{unord.hash}). -\end{itemdescr} - -\rSec1[associative]{Associative containers} - -\rSec2[associative.general]{In general} +\constraints +\begin{itemize} +\item +\tcode{\exposconcept{layout-mapping-alike}} is satisfied. +\item +\tcode{is_constructible_v} is\\\tcode{true}. +\item +\tcode{StridedLayoutMapping::is_always_unique()} is \tcode{true}. +\item +\tcode{StridedLayoutMapping::is_always_strided()} is \tcode{true}. +\end{itemize} \pnum -The header \tcode{} defines the class templates \tcode{map} and -\tcode{multimap}; the header \tcode{} defines the class templates -\tcode{set} and \tcode{multiset}. +\expects +\begin{itemize} +\item +\tcode{StridedLayoutMapping} meets the layout mapping requirements\iref{mdspan.layout.reqmts}, +\item +\tcode{other.stride($r$) > 0} is \tcode{true} +for every rank index $r$ of \tcode{extents()}, +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}\iref{basic.fundamental}, and +\item +\tcode{\exposid{OFFSET}(other) == 0} is \tcode{true}. +\end{itemize} -\rSec2[associative.map.syn]{Header \tcode{} synopsis} +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}, and +for all $d$ in the range $[0, \exposid{rank_})$, +direct-non-list-initializes \tcode{\exposid{strides_}[$d$]} +with \tcode{other.stride($d$)}. -\indexlibrary{\idxhdr{map}}% +\pnum +Remarks: The expression inside \tcode{explicit} is equivalent to: \begin{codeblock} -#include - -namespace std { - - template , - class Allocator = allocator > > - class map; - template - bool operator==(const map& x, - const map& y); - template - bool operator< (const map& x, - const map& y); - template - bool operator!=(const map& x, - const map& y); - template - bool operator> (const map& x, - const map& y); - template - bool operator>=(const map& x, - const map& y); - template - bool operator<=(const map& x, - const map& y); - template - void swap(map& x, - map& y) - noexcept(noexcept(x.swap(y))); - - template , - class Allocator = allocator > > - class multimap; - template - bool operator==(const multimap& x, - const multimap& y); - template - bool operator< (const multimap& x, - const multimap& y); - template - bool operator!=(const multimap& x, - const multimap& y); - template - bool operator> (const multimap& x, - const multimap& y); - template - bool operator>=(const multimap& x, - const multimap& y); - template - bool operator<=(const multimap& x, - const multimap& y); - template - void swap(multimap& x, - multimap& y) - noexcept(noexcept(x.swap(y))); -} +!(is_convertible_v && + (@\exposid{is-mapping-of}@ || + @\exposid{is-mapping-of}@ || + @\exposid{is-layout-left-padded-mapping-of}@ || + @\exposid{is-layout-right-padded-mapping-of}@ || + @\exposid{is-mapping-of}@)) \end{codeblock} +\end{itemdescr} -\rSec2[associative.set.syn]{Header \tcode{} synopsis}% -\indexlibrary{\idxhdr{set}} - -\begin{codeblock} -#include - -namespace std { - - template , - class Allocator = allocator > - class set; - template - bool operator==(const set& x, - const set& y); - template - bool operator< (const set& x, - const set& y); - template - bool operator!=(const set& x, - const set& y); - template - bool operator> (const set& x, - const set& y); - template - bool operator>=(const set& x, - const set& y); - template - bool operator<=(const set& x, - const set& y); - template - void swap(set& x, - set& y) - noexcept(noexcept(x.swap(y))); +\rSec5[mdspan.layout.stride.obs]{Observers} - template , - class Allocator = allocator > - class multiset; - template - bool operator==(const multiset& x, - const multiset& y); - template - bool operator< (const multiset& x, - const multiset& y); - template - bool operator!=(const multiset& x, - const multiset& y); - template - bool operator> (const multiset& x, - const multiset& y); - template - bool operator>=(const multiset& x, - const multiset& y); - template - bool operator<=(const multiset& x, - const multiset& y); - template - void swap(multiset& x, - multiset& y) - noexcept(noexcept(x.swap(y))); -} -\end{codeblock} +\indexlibrarymember{required_span_size}{layout_stride::mapping}% +\begin{itemdecl} +constexpr index_type required_span_size() const noexcept; +\end{itemdecl} -\rSec2[map]{Class template \tcode{map}} +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{REQUIRED-SPAN-SIZE}(extents(), \exposid{strides_})}. +\end{itemdescr} -\rSec3[map.overview]{Class template \tcode{map} overview} +\indexlibrarymember{operator()}{layout_stride::mapping}% +\begin{itemdecl} +template + constexpr index_type operator()(Indices... i) const noexcept; +\end{itemdecl} -\indexlibrary{\idxcode{map}}% +\begin{itemdescr} \pnum -A \tcode{map} is an associative container that -supports unique keys (contains at most one of each key value) and -provides for fast retrieval of values of another type \tcode{T} based -on the keys. The \tcode{map} class supports bidirectional iterators. +\constraints +\begin{itemize} +\item +\tcode{sizeof...(Indices) == \exposid{rank_}} is \tcode{true}, +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, and +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}. +\end{itemize} \pnum -A -\tcode{map} -satisfies all of the requirements of a container, of a reversible container~(\ref{container.requirements}), of -an associative container~(\ref{associative.reqmts}), and of an allocator-aware container (Table~\ref{tab:containers.allocatoraware}). -A -\tcode{map} -also provides most operations described in~(\ref{associative.reqmts}) -for unique keys. -This means that a -\tcode{map} -supports the -\tcode{a_uniq} -operations in~(\ref{associative.reqmts}) -but not the -\tcode{a_eq} -operations. -For a -\tcode{map} -the -\tcode{key_type} -is -\tcode{Key} -and the -\tcode{value_type} -is -\tcode{pair}. -Descriptions are provided here only for operations on -\tcode{map} -that are not described in one of those tables -or for operations where there is additional semantic information. +\expects +\tcode{extents_type::\exposid{index-cast}(i)} is +a multidimensional index in \exposid{extents_}\iref{mdspan.overview}. +\pnum +\effects +Let \tcode{P} be a parameter pack such that \begin{codeblock} -namespace std { - template , - class Allocator = allocator > > - class map { - public: - // types: - typedef Key key_type; - typedef T mapped_type; - typedef pair value_type; - typedef Compare key_compare; - typedef Allocator allocator_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ iterator; // see \ref{container.requirements} - typedef @\impdef@ const_iterator; // see \ref{container.requirements} - typedef @\impdef@ size_type; // see \ref{container.requirements} - typedef @\impdef@ difference_type;// see \ref{container.requirements} - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - class value_compare { - friend class map; - protected: - Compare comp; - value_compare(Compare c) : comp(c) {} - public: - typedef bool result_type; - typedef value_type first_argument_type; - typedef value_type second_argument_type; - 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()); - template - map(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); - map(const map& x); - map(map&& x); - explicit map(const Allocator&); - map(const map&, const Allocator&); - map(map&&, const Allocator&); - map(initializer_list, - const Compare& = Compare(), - const Allocator& = Allocator()); - template - map(InputIterator first, InputIterator last, const Allocator& a) - : map(first, last, Compare(), a) { } - map(initializer_list il, const Allocator& a) - : map(il, Compare(), a) { } - ~map(); - map& operator=(const map& x); - map& operator=(map&& x) - noexcept(allocator_traits::is_always_equal::value && - is_nothrow_move_assignable::value); - map& operator=(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; - - // capacity: - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - - // \ref{map.access}, element access: - T& operator[](const key_type& x); - T& operator[](key_type&& x); - T& at(const key_type& x); - const T& at(const key_type& 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 - iterator insert(const_iterator position, P&&); - template - void insert(InputIterator first, InputIterator last); - void insert(initializer_list); - - template - pair try_emplace(const key_type& k, Args&&... args); - template - pair try_emplace(key_type&& k, Args&&... args); - template - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); - template - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); - template - pair insert_or_assign(const key_type& k, M&& obj); - template - pair insert_or_assign(key_type&& k, M&& obj); - template - 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); - - iterator erase(const_iterator position); - size_type erase(const key_type& x); - iterator erase(const_iterator first, const_iterator last); - void swap(map&) - noexcept(allocator_traits::is_always_equal::value && - noexcept(swap(declval(),declval()))); - void clear() noexcept; - - // observers: - key_compare key_comp() const; - 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; - - size_type count(const key_type& x) const; - template size_type count(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; - }; - - template - bool operator==(const map& x, - const map& y); - template - bool operator< (const map& x, - const map& y); - template - bool operator!=(const map& x, - const map& y); - template - bool operator> (const map& x, - const map& y); - template - bool operator>=(const map& x, - const map& y); - template - bool operator<=(const map& x, - const map& y); - - // specialized algorithms: - template - void swap(map& x, - map& y) - noexcept(noexcept(x.swap(y))); -} +is_same_v, index_sequence> \end{codeblock} +is \tcode{true}. +Equivalent to: +\begin{codeblock} +return ((static_cast(std::move(i)) * stride(P)) + ... + 0); +\end{codeblock} +\end{itemdescr} - -\rSec3[map.cons]{\tcode{map} constructors, copy, and assignment}% -\indexlibrary{\idxcode{map}!\idxcode{operator==}}% -\indexlibrary{\idxcode{map}!\idxcode{operator<}} - -\indexlibrary{\idxcode{map}!\idxcode{map}}% -\indexlibrary{\idxcode{map}!\idxcode{map}}% +\indexlibrarymember{is_always_exhaustive}{layout_stride::mapping}% \begin{itemdecl} -explicit map(const Compare& comp, - const Allocator& = Allocator()); +static constexpr bool is_always_exhaustive() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an empty -\tcode{map} -using the specified comparison object and allocator. +\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; +\end{itemdecl} + +\begin{itemdescr} \pnum -\complexity -Constant. +\returns +\begin{itemize} +\item +\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_})$ +such that \tcode{stride($p_0$)} equals 1, and +\tcode{stride($p_i$)} equals \tcode{stride($ p_{i-1}$) * extents().extent($p_{i-1}$)} +for $i$ in the range $[1, \exposid{rank_})$, +where $p_i$ is the $i^\text{th}$ element of $P$. +\item +Otherwise, \tcode{false}. +\end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{map}!constructor}% +\indexlibrarymember{operator==}{layout_stride::mapping}% \begin{itemdecl} -template - map(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); +template + friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires If the iterator's indirection operator returns an lvalue or a -const rvalue \tcode{pair}, then both -\tcode{key_type} and \tcode{mapped_type} shall be -\tcode{CopyInsertable} into \tcode{*this}. +\constraints +\begin{itemize} +\item +\tcode{\exposconcept{layout-mapping-alike}} is satisfied. +\item +\tcode{\exposid{rank_} == OtherMapping::extents_type::rank()} is \tcode{true}. +\item +\tcode{OtherMapping::is_always_strided()} is \tcode{true}. +\end{itemize} \pnum -\effects -Constructs an empty -\tcode{map} -using the specified comparison object and allocator, -and inserts elements from the range -\range{first}{last}. +\expects +\tcode{OtherMapping} meets the layout mapping requirements\iref{mdspan.layout.policy.reqmts}. \pnum -\complexity -Linear in $N$ if the range -\range{first}{last} -is already sorted using \tcode{comp} -and otherwise $N \log{N}$, where $N$ -is \tcode{last} - \tcode{first}. +\returns +\tcode{true} if \tcode{x.extents() == y.extents()} is \tcode{true}, +\tcode{\exposid{OFFSET}(y) == 0} is \tcode{true}, and +each of \tcode{x.stride($r$) == y.stride($r$)} is \tcode{true} +for $r$ in the range $[0, \tcode{x.extents().rank()})$. +Otherwise, \tcode{false}. \end{itemdescr} -\rSec3[map.access]{\tcode{map} element access} +\rSec4[mdspan.layout.leftpad]{Class template \tcode{layout_left_padded::mapping}} -\indexlibrary{\idxcode{operator[]}!\idxcode{map}}% -\begin{itemdecl} -T& operator[](const key_type& x); -\end{itemdecl} +\rSec5[mdspan.layout.leftpad.overview]{Overview} -\begin{itemdescr} \pnum -\effects -If there is no key equivalent to \tcode{x} in the map, inserts -\tcode{value_type(x, T())} -into the map. +\tcode{layout_left_padded} provides a layout mapping +that behaves like \tcode{layout_left::mapping}, +except that the padding stride \tcode{stride(1)} +can be greater than or equal to \tcode{extent(0)}. -\pnum -\requires \tcode{key_type} shall be -\tcode{CopyInsertable} and \tcode{mapped_type} shall be -\tcode{DefaultInsertable} into \tcode{*this}. +\indexlibrarymember{mapping}{layout_left_padded}% +\begin{codeblock} +namespace std { + template + template + class layout_left_padded::mapping { + public: + static constexpr size_t @\libmember{padding_value}{layout_left_padded::mapping}@ = PaddingValue; -\pnum -\returns -A reference to the -\tcode{mapped_type} -corresponding to \tcode{x} in -\tcode{*this}. + 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; -\pnum -\complexity Logarithmic. -\end{itemdescr} + private: + static constexpr size_t @\exposid{rank_}@ = extents_type::rank(); // \expos + static constexpr size_t @\exposid{first-static-extent}@ = // \expos + extents_type::static_extent(0); -\indexlibrary{\idxcode{operator[]}!\idxcode{map}}% -\begin{itemdecl} -T& operator[](key_type&& x); -\end{itemdecl} + // \ref{mdspan.layout.leftpad.expo}, exposition-only members + static constexpr size_t @\exposid{static-padding-stride}@ = @\seebelow@; // \expos + + public: + // \ref{mdspan.layout.leftpad.cons}, constructors + constexpr mapping() noexcept : mapping(extents_type{}) {} + constexpr mapping(const mapping&) noexcept = default; + constexpr mapping(const extents_type&); + template + constexpr mapping(const extents_type&, OtherIndexType); + template + constexpr explicit(!is_convertible_v) + mapping(const layout_left::mapping&); + template + constexpr explicit(@\seebelow@) + mapping(const layout_stride::mapping&); + template + constexpr explicit(@\seebelow@) + mapping(const LayoutLeftPaddedMapping&); + template + constexpr explicit(@\seebelow@) + mapping(const LayoutRightPaddedMapping&) noexcept; + + constexpr mapping& operator=(const mapping&) noexcept = default; + + // \ref{mdspan.layout.leftpad.obs}, observers + 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 @\libmember{is_always_unique}{layout_left_padded::mapping}@() noexcept { return true; } + static constexpr bool is_always_exhaustive() noexcept; + static constexpr bool @\libmember{is_always_strided}{layout_left_padded::mapping}@() 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 @\libmember{is_strided}{layout_left_padded::mapping}@() noexcept { return true; } + + constexpr index_type stride(rank_type) const noexcept; + + template + friend constexpr bool operator==(const mapping&, const LayoutLeftPaddedMapping&) noexcept; + + private: + // \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}, \tcode{submdspan} mapping specialization + template + constexpr auto @\exposid{submdspan-mapping-impl}@(SliceSpecifiers...) const // \expos + -> @\seebelow@; + + template + friend constexpr auto @\libmember{submdspan_mapping}{layout_left_padded::mapping}@(const mapping& src, SliceSpecifiers... slices) { + return src.@\exposid{submdspan-mapping-impl}@(slices...); + } + }; +} +\end{codeblock} -\begin{itemdescr} \pnum -\effects -If there is no key equivalent to \tcode{x} in the map, inserts -\tcode{value_type(std::move(x), T())} -into the map. +If \tcode{Extents} is not a specialization of \tcode{extents}, +then the program is ill-formed. \pnum -\requires \tcode{mapped_type} shall be -\tcode{DefaultInsertable} into \tcode{*this}. +\tcode{layout_left_padded::mapping} is a trivially copyable type +that models \libconcept{regular} for each \tcode{E}. \pnum -\returns -A reference to the -\tcode{mapped_type} -corresponding to \tcode{x} in -\tcode{*this}. +Throughout \ref{mdspan.layout.leftpad}, +let \tcode{P_rank} be the following +size \exposid{rank_} parameter pack of \tcode{size_}t values: +\begin{itemize} +\item +the empty parameter pack, if \exposid{rank_} equals zero; +\item +\tcode otherwise, \tcode{0zu}, if \exposid{rank_} equals one; +\item +otherwise, the parameter pack \tcode{0zu}, \tcode{1zu}, \ldots, \tcode{\exposid{rank_}- 1}. +\end{itemize} \pnum -\complexity Logarithmic. -\end{itemdescr} +\mandates +\begin{itemize} +\item +If \tcode{rank_dynamic() == 0} is \tcode{true}, +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 +\begin{itemize} +\item +\exposid{rank_} is greater than one, +\item +\tcode{padding_value} does not equal \tcode{dynamic_extent}, and +\item +\exposid{first-static-extent} does not equal \tcode{dynamic_extent}, +\end{itemize} +then \tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(padding_value, \exposid{first-static-extent})} +is representable as a val\-ue of type \tcode{size_t}, and +is representable as a value of type \tcode{index_type}. +\item +If +\begin{itemize} +\item +\exposid{rank_} is greater than one, +\item +\tcode{padding_value} does not equal \tcode{dynamic_extent}, and +\item +\tcode{extents_type::static_extent($k$)} does not equal \tcode{dynamic_extent} +for all $k$ in the range \range{0}{extents_type::rank()}, +\end{itemize} +then the product of +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(padding_value, ext.static_extent(0))} and +all values \tcode{ext.static_extent($k$)} +with $k$ in the range of \range{1}{\exposid{rank_}} +is representable as a value of type \tcode{size_t}, and +is representable as a value of type \tcode{index_type}. +\end{itemize} + +\rSec5[mdspan.layout.leftpad.expo]{Exposition-only members} -\indexlibrary{\idxcode{at}!\idxcode{map}}% \begin{itemdecl} -T& at(const key_type& x); -const T& at(const key_type& x) const; +static constexpr size_t @\exposid{static-padding-stride}@ = @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum -\returns -A reference to the \tcode{mapped_type} corresponding to \tcode{x} in \tcode{*this}. +The value is +\begin{itemize} +\item +\tcode{0}, if \exposid{rank_} equals zero or one; +\item +otherwise, \tcode{dynamic_extent}, +if \tcode{padding_value} or \exposid{first-static-extent} equals +\tcode{dynamic_extent}; +\item +otherwise, the \tcode{size_t} value which is +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(padding_value, \exposid{first-sta\-tic-extent})}. +\end{itemize} +\end{itemdescr} -\pnum -\throws -An exception object of type \tcode{out_of_range} if -no such element is present. +\begin{itemdecl} +index_type @\exposid{stride-1}@ = @\exposid{static-padding-stride}@; +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity Logarithmic. +\recommended +Implementations should not store this value +if \exposid{static-padding-stride} is not \tcode{dynamic_extent}. +\begin{note} +Using \tcode{extents} instead of +\tcode{index_type} as the type of \exposid{stride-1} would achieve this. +\end{note} \end{itemdescr} -\rSec3[map.modifiers]{\tcode{map} modifiers} +\rSec5[mdspan.layout.leftpad.cons]{Constructors} -\indexlibrary{\idxcode{insert}!\idxcode{map}}% -\indexlibrary{\idxcode{map}!\idxcode{insert}}% +\indexlibraryctor{layout_left_padded::mapping}% \begin{itemdecl} -template pair insert(P&& x); -template iterator insert(const_iterator position, P&& x); -template - void insert(InputIterator first, InputIterator last); +constexpr mapping(const extents_type& ext); \end{itemdecl} \begin{itemdescr} \pnum -\effects -The first form is equivalent to -\tcode{return emplace(std::forward

(x))}. The second form is -equivalent to \tcode{return emplace_hint(position, std::forward

(x))}. +\expects +\begin{itemize} +\item +The size of the multidimensional index space \tcode{ext} is representable as +a value of type \tcode{index_type}. +\item +If \exposid{rank_} is greater than one and +\tcode{padding_value} does not equal \tcode{dynamic_extent}, +then \tcode{\exposid{LEAST-MUL\-TIPLE-AT-LEAST}(padding_value, ext.extent(0))} +is representable as a value of type \exposid{index_type}. +\item +If \exposid{rank_} is greater than one and +\tcode{padding_value} does not equal \tcode{dynamic_extent}, +then the product of +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(padding_value, ext.extent(0))} and +all values \tcode{ext.extent($k$)} +with $k$ in the range of \range{1}{\exposid{rank_}} +is representable as a value of type \tcode{index_type}. +\end{itemize} \pnum -\remarks -These signatures shall not participate in overload resolution -unless \tcode{std::is_constructible::value} is -\tcode{true}. +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{extents_} with \tcode{ext}; and +\item +if \exposid{rank_} is greater than one, +direct-non-list-initializes \exposid{stride-1} +\begin{itemize} +\item +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))}. +\end{itemize} +\end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{try_emplace}!\idxcode{map}}% -\indexlibrary{\idxcode{map}!\idxcode{try_emplace}}% +\indexlibraryctor{layout_left_padded::mapping}% \begin{itemdecl} -template pair try_emplace(const key_type& k, Args&&... args); -template pair try_emplace(key_type&& k, Args&&... args); -template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); -template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); +template +constexpr mapping(const extents_type& ext, OtherIndexType padding); \end{itemdecl} \begin{itemdescr} \pnum -\effects -If the key \tcode{k} already exists in the map, there is no effect. -Otherwise, inserts an element into the map. -In the first and third forms, -the element is constructed from the arguments as -\tcode{value_type(k, std::forward(args)...)}. -In the second and fourth forms, -the element is constructed from the arguments as -\tcode{value_type(std::move(k), std::forward(args)...)}. -In the first two overloads, -the \tcode{bool} component of the returned pair is \tcode{true} -if and only if the insertion took place. -The returned \tcode{iterator} points to the element of the map whose key -is equivalent to \tcode{k}. +Let \tcode{pad} be +\tcode{extents_type::\exposid{index-cast}(std::move(padding))}. \pnum -\complexity -The same as \tcode{emplace} and \tcode{emplace_hint}, -respectively. -\end{itemdescr} - -\indexlibrary{\idxcode{insert_or_assign}!\idxcode{map}}% -\indexlibrary{\idxcode{map}!\idxcode{insert_or_assign}}% -\begin{itemdecl} -template pair insert_or_assign(const key_type& k, M&& obj); -template pair insert_or_assign(key_type&& k, M&& obj); -template 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); -\end{itemdecl} +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} is \tcode{true}. +\item +\tcode{is_nothrow_constructible_v} is \tcode{true}. +\end{itemize} -\begin{itemdescr} \pnum -\effects -If the key \tcode{k} does not exist in the map, -inserts an element into the map. -In the first and third forms, -the element is constructed from the arguments as -\tcode{value_type(k, std::forward(args)...)}. -In the second and fourth forms, -the element is constructed from the arguments as -\tcode{value_type(std::move(k), std::forward(args)...)}. -If the key already exists, -\tcode{std::forward(obj)} is assigned to the -\tcode{mapped_type} corresponding to the key. -In the first two overloads, -the \tcode{bool} component of the returned value is \tcode{true} -if and only if the insertion took place. -The returned \tcode{iterator} points to the element -that was inserted or updated. +\expects +\begin{itemize} +\item +\tcode{pad} is representable as a value of type \tcode{index_type}. +\item +\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))} +is representable as a value of type \tcode{index_type.} +\item +If \exposid{rank_} is greater than one, +then the product of +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(pad, ext.extent(\linebreak 0))} and +all values \tcode{ext.extent($k$)} +with $k$ in the range of \range{1}{\exposid{rank_}} +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{pad}. +\end{itemize} \pnum -\complexity -The same as \tcode{emplace} and \tcode{emplace_hint}, -respectively. +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{ext}, and +if \exposid{rank_} is greater than one, +direct-non-list-initializes \exposid{stride-1} with +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(pad, ext.extent(0))}. \end{itemdescr} -\rSec3[map.special]{\tcode{map} specialized algorithms} - -\indexlibrary{\idxcode{swap}!\idxcode{map}}% -\indexlibrary{\idxcode{map}!\idxcode{swap}}% +\indexlibraryctor{layout_left_padded::mapping}% \begin{itemdecl} -template - void swap(map& x, - map& y) - noexcept(noexcept(x.swap(y))); +template + constexpr explicit(!is_convertible_v) + mapping(const layout_left::mapping& other); \end{itemdecl} \begin{itemdescr} \pnum -\effects -\begin{codeblock} -x.swap(y); -\end{codeblock} -\end{itemdescr} - -\rSec2[multimap]{Class template \tcode{multimap}} - -\rSec3[multimap.overview]{Class template \tcode{multimap} overview} +\constraints +\tcode{is_constructible_v} is \tcode{true}. \pnum -\indexlibrary{\idxcode{multimap}}% -A -\tcode{multimap} -is an associative container that supports equivalent keys (possibly containing multiple copies of -the same key value) and provides for fast retrieval of values of another type -\tcode{T} -based on the keys. -The -\tcode{multimap} -class -supports bidirectional iterators. +\mandates +If \tcode{OtherExtents::rank()} is greater than \tcode{1}, then +\begin{codeblock} +(@\exposid{static-padding-stride}@ == dynamic_extent) || +(OtherExtents::static_extent(0) == dynamic_extent) || +(@\exposid{static-padding-stride}@ == OtherExtents::static_extent(0)) +\end{codeblock} +is \tcode{true}. \pnum -A -\tcode{multimap} satisfies all of the requirements of a container and of a -reversible container~(\ref{container.requirements}), of an associative -container~(\ref{associative.reqmts}), and of an allocator-aware container -(Table~\ref{tab:containers.allocatoraware}). -A -\tcode{multimap} -also provides most operations described in~(\ref{associative.reqmts}) -for equal keys. -This means that a -\tcode{multimap} -supports the -\tcode{a_eq} -operations in~(\ref{associative.reqmts}) -but not the -\tcode{a_uniq} -operations. -For a -\tcode{multimap} -the -\tcode{key_type} -is -\tcode{Key} -and the -\tcode{value_type} -is -\tcode{pair}. -Descriptions are provided here only for operations on -\tcode{multimap} -that are not described in one of those tables -or for operations where there is additional semantic information. - +\expects +\begin{itemize} +\item +If \tcode{extents_type::rank() > 1} is \tcode{true} and +\tcode{padding_value} == \tcode{dynamic_extent} is \tcode{false}, +then \tcode{other.stride(1)} equals \begin{codeblock} -namespace std { - template , - class Allocator = allocator > > - class multimap { - public: - // types: - typedef Key key_type; - typedef T mapped_type; - typedef pair value_type; - typedef Compare key_compare; - typedef Allocator allocator_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ iterator; // see \ref{container.requirements} - typedef @\impdef@ const_iterator; // see \ref{container.requirements} - typedef @\impdef@ size_type; // see \ref{container.requirements} - typedef @\impdef@ difference_type;// see \ref{container.requirements} - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - class value_compare { - friend class multimap; - protected: - Compare comp; - value_compare(Compare c) : comp(c) { } - public: - typedef bool result_type; - typedef value_type first_argument_type; - typedef value_type second_argument_type; - bool operator()(const value_type& x, const value_type& y) const { - return comp(x.first, y.first); - } - }; - - // construct/copy/destroy: - multimap() : multimap(Compare()) { } - explicit multimap(const Compare& comp, - const Allocator& = Allocator()); - template - multimap(InputIterator first, InputIterator last, - const Compare& comp = Compare(), - const Allocator& = Allocator()); - multimap(const multimap& x); - multimap(multimap&& x); - explicit multimap(const Allocator&); - multimap(const multimap&, const Allocator&); - multimap(multimap&&, const Allocator&); - multimap(initializer_list, - const Compare& = Compare(), - const Allocator& = Allocator()); - template - multimap(InputIterator first, InputIterator last, const Allocator& a) - : multimap(first, last, Compare(), a) { } - multimap(initializer_list il, const Allocator& a) - : multimap(il, Compare(), a) { } - ~multimap(); - multimap& operator=(const multimap& x); - multimap& operator=(multimap&& x) - noexcept(allocator_traits::is_always_equal::value && - is_nothrow_move_assignable::value); - multimap& operator=(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; - - // capacity: - bool empty() const noexcept; - size_type size() const noexcept; - 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); - 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 - void insert(InputIterator first, InputIterator last); - void insert(initializer_list); - - iterator erase(const_iterator position); - size_type erase(const key_type& x); - iterator erase(const_iterator first, const_iterator last); - void swap(multimap&) - noexcept(allocator_traits::is_always_equal::value && - noexcept(swap(declval(),declval()))); - void clear() noexcept; - - // observers: - key_compare key_comp() const; - 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; - - size_type count(const key_type& x) const; - template size_type count(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; - }; - - template - bool operator==(const multimap& x, - const multimap& y); - template - bool operator< (const multimap& x, - const multimap& y); - template - bool operator!=(const multimap& x, - const multimap& y); - template - bool operator> (const multimap& x, - const multimap& y); - template - bool operator>=(const multimap& x, - const multimap& y); - template - bool operator<=(const multimap& x, - const multimap& y); - - // specialized algorithms: - template - void swap(multimap& x, - multimap& y) - noexcept(noexcept(x.swap(y))); -} -\end{codeblock}% -\indexlibrary{\idxcode{multimap}!\idxcode{operator==}}% -\indexlibrary{\idxcode{multimap}!\idxcode{operator<}} +@\exposid{LEAST-MULTIPLE-AT-LEAST}@(padding_value, + extents_type::@\exposid{index-cast}@(other.extents().extent(0))) +\end{codeblock} +and +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}. +\end{itemize} -\rSec3[multimap.cons]{\tcode{multimap} constructors} +\pnum +\effects +Equivalent to \tcode{mapping(other.extents())}. +\end{itemdescr} -\indexlibrary{\idxcode{multimap}!\idxcode{multimap}}% -\indexlibrary{\idxcode{multimap}!\idxcode{multimap}}% +\indexlibraryctor{layout_left_padded::mapping}% \begin{itemdecl} -explicit multimap(const Compare& comp, - const Allocator& = Allocator()); +template + constexpr explicit(@\seebelow@) + mapping(const layout_stride::mapping& other); \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\expects +\begin{itemize} +\item +If \exposid{rank_} is greater than \tcode{1} and +\tcode{padding_value} does not equal \tcode{dynamic_extent}, +then \tcode{other.\linebreak stride(1)} equals +\begin{codeblock} +@\exposid{LEAST-MULTIPLE-AT-LEAST}@(padding_value, + extents_type::@\exposid{index-cast}@(other.extents().extent(0))) +\end{codeblock} +\item +If \exposid{rank_} is greater than 0, +then \tcode{other.stride(0)} equals 1. +\item +If \exposid{rank_} is greater than 2, +then for all $r$ in the range \range{2}{\exposid{rank_}}, +\tcode{other.stride(r)} equals +\begin{codeblock} +(other.extents().@\exposid{fwd-prod-of-extents}@(r) / other.extents().extent(0)) * other.stride(1) +\end{codeblock} +\item +\tcode{other.required_span_size()} is representable as +a value of type \exposid{index_type}. +\end{itemize} + \pnum \effects -Constructs an empty -\tcode{multimap} -using the specified comparison object and allocator. +\begin{itemize} +\item +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()} and +\item +if \exposid{rank_} is greater than one, +direct-non-list-initializes \exposid{stride-1} with +\tcode{other.stride(1)}. +\end{itemize} \pnum -\complexity -Constant. +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(rank_ == 0 && is_convertible_v) +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{multimap}!\idxcode{multimap}}% -\indexlibrary{\idxcode{multimap}!\idxcode{multimap}}% +\indexlibraryctor{layout_left_padded::mapping}% \begin{itemdecl} -template - multimap(InputIterator first, InputIterator last, - const Compare& comp = Compare(), - const Allocator& = Allocator()); +template + constexpr explicit(@\seebelow@) + mapping(const LayoutLeftPaddedMapping& other); \end{itemdecl} \begin{itemdescr} \pnum -\requires If the iterator's indirection operator returns an lvalue or a -const rvalue \tcode{pair}, then both -\tcode{key_type} and \tcode{mapped_type} shall be -\tcode{CopyInsertable} into \tcode{*this}. +\constraints +\begin{itemize} +\item +\tcode{\exposid{is-layout-left-padded-mapping-of}} +is \tcode{true}. +\item +\tcode{is_constructible_v} +\newline is \tcode{true}. +\end{itemize} \pnum -\effects -Constructs an empty -\tcode{multimap} -using the specified comparison object and allocator, -and inserts elements from the range -\range{first}{last}. +\mandates +If \exposid{rank_} is greater than 1, +then +\begin{codeblock} +padding_value == dynamic_extent || +LayoutLeftPaddedMapping::padding_value == dynamic_extent || +padding_value == LayoutLeftPaddedMapping::padding_value +\end{codeblock} +is \tcode{true}. \pnum -\complexity -Linear in $N$ if the range -\range{first}{last} -is already sorted using \tcode{comp} -and otherwise $N \log{N}$, -where $N$ is -\tcode{last - first}. -\end{itemdescr} - -\rSec3[multimap.modifiers]{\tcode{multimap} modifiers} - -\indexlibrary{\idxcode{insert}!\idxcode{multimap}}% -\indexlibrary{\idxcode{multimap}!\idxcode{insert}}% -\begin{itemdecl} -template iterator insert(P&& x); -template iterator insert(const_iterator position, P&& x); -\end{itemdecl} +\expects +\begin{itemize} +\item +If \exposid{rank_} is greater than 1 and +\tcode{padding_value} does not equal \tcode{dynamic_extent}, +then \tcode{other.\linebreak stride(1)} equals +\begin{codeblock} +@\exposid{LEAST-MULTIPLE-AT-LEAST}@(padding_value, + extents_type::@\exposid{index-cast}@(other.extent(0))) +\end{codeblock} +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}. +\end{itemize} -\begin{itemdescr} \pnum \effects -The first form is equivalent to -\tcode{return emplace(std::forward

(x))}. The second form is -equivalent to \tcode{return emplace_hint(position, std::forward

(x))}. +\begin{itemize} +\item +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()} and +\item +if \exposid{rank_} is greater than one, +direct-non-list-initializes \exposid{stride-1} with \tcode{other.stride(1)}. +\end{itemize} \pnum \remarks -These signatures shall not participate in overload resolution -unless \tcode{std::is_constructible::value} is -\tcode{true}. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!is_convertible_v || +rank_> 1 && +(padding_value != dynamic_extent || + LayoutLeftPaddedMapping::padding_value == dynamic_extent) +\end{codeblock} \end{itemdescr} -\rSec3[multimap.special]{\tcode{multimap} specialized algorithms} - -\indexlibrary{\idxcode{swap}!\idxcode{multimap}}% -\indexlibrary{\idxcode{multimap}!\idxcode{swap}}% +\indexlibraryctor{layout_left_padded::mapping}% \begin{itemdecl} -template - void swap(multimap& x, - multimap& y) - noexcept(noexcept(x.swap(y))); +template + constexpr explicit(@\seebelow@) + mapping(const LayoutRightPaddedMapping& other) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -\begin{codeblock} -x.swap(y); -\end{codeblock} -\end{itemdescr} - -\rSec2[set]{Class template \tcode{set}} - -\rSec3[set.overview]{Class template \tcode{set} overview} +\constraints +\begin{itemize} +\item +\tcode{\exposid{is-layout-right-padded-mapping-of}} +is \tcode{true} or\newline +\tcode{\exposid{is-mapping-of}} +is \tcode{true}. +\item +\exposid{rank_} equals zero or one. +\item +\tcode{is_constructible_v} +is \tcode{true}. +\end{itemize} \pnum -\indexlibrary{\idxcode{set}}% -A -\tcode{set} -is an associative container that supports unique keys (contains at most one of each key value) and -provides for fast retrieval of the keys themselves. -The -\tcode{set} class -supports bidirectional iterators. +\expects +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}. \pnum -A \tcode{set} satisfies all of the requirements of a container, of a reversible -container~(\ref{container.requirements}), of an associative -container~(\ref{associative.reqmts}), and of an allocator-aware container -(Table~\ref{tab:containers.allocatoraware}). -A -\tcode{set} -also provides most operations described in~(\ref{associative.reqmts}) -for unique keys. -This means that a -\tcode{set} -supports the -\tcode{a_uniq} -operations in~(\ref{associative.reqmts}) -but not the -\tcode{a_eq} -operations. -For a -\tcode{set} -both the -\tcode{key_type} -and -\tcode{value_type} -are -\tcode{Key}. -Descriptions are provided here only for operations on -\tcode{set} -that are not described in one of these tables -and for operations where there is additional semantic information. +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: \begin{codeblock} -namespace std { - template , - class Allocator = allocator > - class set { - public: - // types: - typedef Key key_type; - typedef Key value_type; - typedef Compare key_compare; - typedef Compare value_compare; - typedef Allocator allocator_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ iterator; // See \ref{container.requirements} - typedef @\impdef@ const_iterator; // See \ref{container.requirements} - typedef @\impdef@ size_type; // See \ref{container.requirements} - typedef @\impdef@ difference_type;// See \ref{container.requirements} - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - // \ref{set.cons}, construct/copy/destroy: - set() : set(Compare()) { } - explicit set(const Compare& comp, - const Allocator& = Allocator()); - template - set(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); - set(const set& x); - set(set&& x); - explicit set(const Allocator&); - set(const set&, const Allocator&); - set(set&&, const Allocator&); - set(initializer_list, - const Compare& = Compare(), - const Allocator& = Allocator()); - template - set(InputIterator first, InputIterator last, const Allocator& a) - : set(first, last, Compare(), a) { } - set(initializer_list il, const Allocator& a) - : set(il, Compare(), a) { } - ~set(); - set& operator=(const set& x); - set& operator=(set&& x) - noexcept(allocator_traits::is_always_equal::value && - is_nothrow_move_assignable::value); - set& operator=(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; - - // capacity: - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - - // 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); - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, value_type&& x); - template - void insert(InputIterator first, InputIterator last); - void insert(initializer_list); - - iterator erase(const_iterator position); - size_type erase(const key_type& x); - iterator erase(const_iterator first, const_iterator last); - void swap(set&) - noexcept(allocator_traits::is_always_equal::value && - noexcept(swap(declval(),declval()))); - void clear() noexcept; - - // observers: - key_compare key_comp() const; - 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; - - size_type count(const key_type& x) const; - template size_type count(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; - }; +!is_convertible_v +\end{codeblock} - template - bool operator==(const set& x, - const set& y); - template - bool operator< (const set& x, - const set& y); - template - bool operator!=(const set& x, - const set& y); - template - bool operator> (const set& x, - const set& y); - template - bool operator>=(const set& x, - const set& y); - template - bool operator<=(const set& x, - const set& y); - - // specialized algorithms: - template - void swap(set& x, - set& y) - noexcept(noexcept(x.swap(y))); -} -\end{codeblock}% -\indexlibrary{\idxcode{set}!\idxcode{operator==}}% -\indexlibrary{\idxcode{set}!\idxcode{operator<}} +\begin{note} +Neither the input mapping nor the mapping to be constructed +uses the padding stride in the rank-0 or rank-1 case, +so the padding stride does not affect +either the constraints or the preconditions. +\end{note} +\end{itemdescr} -\rSec3[set.cons]{\tcode{set} constructors, copy, and assignment} +\rSec5[mdspan.layout.leftpad.obs]{Observers} -\indexlibrary{\idxcode{set}!\idxcode{set}}% -\indexlibrary{\idxcode{set}!\idxcode{set}}% +\indexlibrarymember{strides}{layout_left_padded::mapping}% \begin{itemdecl} -explicit set(const Compare& comp, - const Allocator& = Allocator()); +constexpr array strides() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an empty set using the specified comparison objects and allocator. - -\pnum -\complexity -Constant. +\returns +\tcode{array(\{stride(P_rank)...\})}. \end{itemdescr} -\indexlibrary{\idxcode{set}!\idxcode{set}}% -\indexlibrary{\idxcode{set}!\idxcode{set}}% +\indexlibrarymember{required_span_size}{layout_left_padded::mapping}% \begin{itemdecl} -template - set(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); +constexpr index_type required_span_size() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an empty -\tcode{set} -using the specified comparison object and allocator, -and inserts elements from the range -\range{first}{last}. - -\pnum -\requires If the iterator's indirection operator returns an lvalue or a -non-const rvalue, then \tcode{Key} shall be -\tcode{CopyInsertable} into \tcode{*this}. - -\pnum -\complexity -Linear in $N$ if the range -\range{first}{last} -is already sorted using \tcode{comp} -and otherwise $N \log{N}$, -where $N$ is -\tcode{last - first}. +\returns +\begin{itemize} +\item +\tcode{0} if the multidimensional index space \exposid{extents_} is empty, +\item +otherwise, \tcode{(*this)(\exposid{extents_}.extent(P_rank) - index_type(1)...) + 1}. +\end{itemize} \end{itemdescr} -\rSec3[set.special]{\tcode{set} specialized algorithms} - -\indexlibrary{\idxcode{swap}!\idxcode{set}}% -\indexlibrary{\idxcode{set}!\idxcode{swap}}% +\indexlibrarymember{operator()}{layout_left_padded::mapping}% \begin{itemdecl} -template - void swap(set& x, - set& y) - noexcept(noexcept(x.swap(y))); +template +constexpr index_type operator()(Indices... idxs) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -\begin{codeblock} -x.swap(y); -\end{codeblock} -\end{itemdescr} - -\rSec2[multiset]{Class template \tcode{multiset}} - -\rSec3[multiset.overview]{Class template \tcode{multiset} overview} +\constraints +\begin{itemize} +\item +\tcode{sizeof...(Indices) == \exposid{rank_}} is \tcode{true}. +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}. +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}. +\end{itemize} \pnum -\indexlibrary{\idxcode{multiset}}% -A -\tcode{multiset} -is an associative container that supports equivalent keys (possibly contains multiple copies of -the same key value) and provides for fast retrieval of the keys themselves. -The -\tcode{multiset} class -supports bidirectional iterators. +\expects +\tcode{extents_type::\exposid{index-cast}(idxs)} is +a multidimensional index in \tcode{extents()}\iref{mdspan.overview}. \pnum -A \tcode{multiset} satisfies all of the requirements of a container, of a -reversible container~(\ref{container.requirements}), of an associative -container~(\ref{associative.reqmts}), and of an allocator-aware container -(Table~\ref{tab:containers.allocatoraware}). -\tcode{multiset} -also provides most operations described in~(\ref{associative.reqmts}) -for duplicate keys. -This means that a -\tcode{multiset} -supports the -\tcode{a_eq} -operations in~(\ref{associative.reqmts}) -but not the -\tcode{a_uniq} -operations. -For a -\tcode{multiset} -both the -\tcode{key_type} -and -\tcode{value_type} -are -\tcode{Key}. -Descriptions are provided here only for operations on -\tcode{multiset} -that are not described in one of these tables -and for operations where there is additional semantic information. - -\begin{codeblock} -namespace std { - template , - class Allocator = allocator > - class multiset { - public: - // types: - typedef Key key_type; - typedef Key value_type; - typedef Compare key_compare; - typedef Compare value_compare; - typedef Allocator allocator_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ iterator; // see \ref{container.requirements} - typedef @\impdef@ const_iterator; // see \ref{container.requirements} - typedef @\impdef@ size_type; // see \ref{container.requirements} - typedef @\impdef@ difference_type;// see \ref{container.requirements} - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - // construct/copy/destroy: - multiset() : multiset(Compare()) { } - explicit multiset(const Compare& comp, - const Allocator& = Allocator()); - template - multiset(InputIterator first, InputIterator last, - const Compare& comp = Compare(), - const Allocator& = Allocator()); - multiset(const multiset& x); - multiset(multiset&& x); - explicit multiset(const Allocator&); - multiset(const multiset&, const Allocator&); - multiset(multiset&&, const Allocator&); - multiset(initializer_list, - const Compare& = Compare(), - const Allocator& = Allocator()); - template - multiset(InputIterator first, InputIterator last, const Allocator& a) - : multiset(first, last, Compare(), a) { } - multiset(initializer_list il, const Allocator& a) - : multiset(il, Compare(), a) { } - ~multiset(); - multiset& operator=(const multiset& x); - multiset& operator=(multiset&& x) - noexcept(allocator_traits::is_always_equal::value && - is_nothrow_move_assignable::value); - multiset& operator=(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; - - // capacity: - bool empty() const noexcept; - size_type size() const noexcept; - 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 - void insert(InputIterator first, InputIterator last); - void insert(initializer_list); - - iterator erase(const_iterator position); - size_type erase(const key_type& x); - iterator erase(const_iterator first, const_iterator last); - void swap(multiset&) - noexcept(allocator_traits::is_always_equal::value && - noexcept(swap(declval(),declval()))); - void clear() noexcept; - - // observers: - key_compare key_comp() const; - 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; - - size_type count(const key_type& x) const; - template size_type count(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; - }; - - template - bool operator==(const multiset& x, - const multiset& y); - template - bool operator< (const multiset& x, - const multiset& y); - template - bool operator!=(const multiset& x, - const multiset& y); - template - bool operator> (const multiset& x, - const multiset& y); - template - bool operator>=(const multiset& x, - const multiset& y); - template - bool operator<=(const multiset& x, - const multiset& y); - - // specialized algorithms: - template - void swap(multiset& x, - multiset& y) - noexcept(noexcept(x.swap(y))); -} -\end{codeblock}% -\indexlibrary{\idxcode{multiset}!\idxcode{operator==}}% -\indexlibrary{\idxcode{multiset}!\idxcode{operator<}} - -\rSec3[multiset.cons]{\tcode{multiset} constructors} +\returns +\tcode{((static_cast(std::move(idxs)) * stride(P_rank)) + ... + 0)}. +\end{itemdescr} -\indexlibrary{\idxcode{multiset}!\idxcode{multiset}}% -\indexlibrary{\idxcode{multiset}!\idxcode{multiset}}% +\indexlibrarymember{is_always_exhaustive}{layout_left_padded::mapping}% \begin{itemdecl} -explicit multiset(const Compare& comp, - const Allocator& = Allocator()); +static constexpr bool is_always_exhaustive() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an empty set using the specified comparison object and allocator. - -\pnum -\complexity -Constant. +\returns +\begin{itemize} +\item +If \exposid{rank_} equals zero or one, then \tcode{true}; +\item +otherwise, if +neither \exposid{static-padding-stride} nor \exposid{first-static-extent} +equal \tcode{dynamic_extent}, +then \tcode{\exposid{static-padding-stride} == \exposid{first-static-extent}}; +\item +otherwise, \tcode{false}. +\end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{multiset}!\idxcode{multiset}}% -\indexlibrary{\idxcode{multiset}!\idxcode{multiset}}% +\indexlibrarymember{is_exhaustive}{layout_left_padded::mapping}% \begin{itemdecl} -template - multiset(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); +constexpr bool is_exhaustive() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires If the iterator's indirection operator returns an lvalue or a -const rvalue, then \tcode{Key} shall be -\tcode{CopyInsertable} into \tcode{*this}. +\returns +\tcode{true} if \exposid{rank_} equals zero or one; +otherwise, \tcode{extents_.extent(0) == stride(1)}. +\end{itemdescr} -\pnum -\effects -Constructs an empty -\tcode{multiset} -using the specified comparison object and allocator, -and inserts elements from the range -\range{first}{last}. +\indexlibrarymember{stride}{layout_left_padded::mapping}% +\begin{itemdecl} +constexpr index_type stride(rank_type r) const noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -Linear in $N$ -if the range -\range{first}{last} -is already sorted using \tcode{comp} and otherwise $N \log{N}$, -where $N$ is -\tcode{last - first}. -\end{itemdescr} +\expects +\tcode{r} is smaller than \exposid{rank_}. -\rSec3[multiset.special]{\tcode{multiset} specialized algorithms} +\pnum +\returns +\begin{itemize} +\item +If \tcode{r} equals zero: 1; +\item +otherwise, if \tcode{r} equals one: \exposid{stride-1}; +\item +otherwise, the product of \exposid{stride-1} and +all values \tcode{extents_.extent($k$)} with $k$ in the range \range{1}{r}. +\end{itemize} +\end{itemdescr} -\indexlibrary{\idxcode{swap}!\idxcode{multiset}}% -\indexlibrary{\idxcode{multiset}!\idxcode{swap}}% +\indexlibrarymember{operator==}{layout_left_padded::mapping}% \begin{itemdecl} -template - void swap(multiset& x, - multiset& y) - noexcept(noexcept(x.swap(y))); +template + friend constexpr bool operator==(const mapping& x, const LayoutLeftPaddedMapping& y) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -\begin{codeblock} -x.swap(y); -\end{codeblock} +\constraints +\begin{itemize} +\item +\tcode{\exposid{is-layout-left-padded-mapping-of}} +is \tcode{true}. +\item +\tcode{LayoutLeftPaddedMapping::extents_type::rank() == rank_} is \tcode{true}. +\end{itemize} + +\pnum +\returns +\tcode{true} if \tcode{x.extents() == y.extents()} is \tcode{true} and +\tcode{\exposid{rank_} < 2 || x.stride(1) == y.\newline stride(1)} is \tcode{true}. +Otherwise, \tcode{false}. \end{itemdescr} -\rSec1[unord]{Unordered associative containers} +\rSec4[mdspan.layout.rightpad]{Class template \tcode{layout_right_padded::mapping}} -\rSec2[unord.general]{In general} +\rSec5[mdspan.layout.rightpad.overview]{Overview} \pnum -The header \tcode{} defines the class templates -\tcode{unordered_map} and -\tcode{unordered_multimap}; the header \tcode{} defines the class templates -\tcode{unordered_set} and \tcode{unordered_multiset}. +\tcode{layout_right_padded} provides a layout mapping +that behaves like \tcode{layout_right::mapping}, +except that the padding stride \tcode{stride(extents_type::rank() - 2)} +can be greater than or equal to +\tcode{extents_type::ex\-tent(extents_type::rank() - 1)}. -\rSec2[unord.map.syn]{Header \tcode{} synopsis}% -\indexlibrary{\idxhdr{unordered_map}}% -\indexlibrary{\idxcode{unordered_map}}% -\indexlibrary{\idxcode{unordered_multimap}}% +\indexlibrarymember{mapping}{layout_right_padded}% \begin{codeblock} -#include - namespace std { + template + template + class layout_right_padded::mapping { + public: + static constexpr size_t @\libmember{padding_value}{layout_right_padded::mapping}@ = PaddingValue; - // \ref{unord.map}, class template unordered_map: - template , - class Pred = std::equal_to, - class Alloc = std::allocator > > - class unordered_map; - - // \ref{unord.multimap}, class template unordered_multimap: - template , - class Pred = std::equal_to, - class Alloc = std::allocator > > - class unordered_multimap; + 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; - template - void swap(unordered_map& x, - unordered_map& y) - noexcept(noexcept(x.swap(y))); + private: + static constexpr size_t @\exposid{rank_}@ = extents_type::rank(); // \expos + static constexpr size_t @\exposid{last-static-extent}@ = // \expos + extents_type::static_extent(@\exposid{rank_}@ - 1); - template - void swap(unordered_multimap& x, - unordered_multimap& y) - noexcept(noexcept(x.swap(y))); + // \ref{mdspan.layout.rightpad.expo}, exposition-only members + static constexpr size_t @\exposid{static-padding-stride}@ = @\seebelow@; // \expos - template - bool operator==(const unordered_map& a, - const unordered_map& b); - template - bool operator!=(const unordered_map& a, - const unordered_map& b); - template - bool operator==(const unordered_multimap& a, - const unordered_multimap& b); - template - bool operator!=(const unordered_multimap& a, - const unordered_multimap& b); -} // namespace std + public: + // \ref{mdspan.layout.rightpad.cons}, constructors + constexpr mapping() noexcept : mapping(extents_type{}) {} + constexpr mapping(const mapping&) noexcept = default; + constexpr mapping(const extents_type&); + template + constexpr mapping(const extents_type&, OtherIndexType); + + template + constexpr explicit(!is_convertible_v) + mapping(const layout_right::mapping&); + template + constexpr explicit(@\seebelow@) + mapping(const layout_stride::mapping&); + template + constexpr explicit(@\seebelow@) + mapping(const LayoutRightPaddedMapping&); + template + constexpr explicit(@\seebelow@) + mapping(const LayoutLeftPaddedMapping&) noexcept; + + constexpr mapping& operator=(const mapping&) noexcept = default; + + // \ref{mdspan.layout.rightpad.obs}, observers + 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 @\libmember{is_always_unique}{layout_right_padded::mapping}@() noexcept { return true; } + static constexpr bool is_always_exhaustive() noexcept; + static constexpr bool @\libmember{is_always_strided}{layout_right_padded::mapping}@() 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 @\libmember{is_strided}{layout_right_padded::mapping}@() noexcept { return true; } + + constexpr index_type stride(rank_type) const noexcept; + + template + friend constexpr bool operator==(const mapping&, const LayoutRightPaddedMapping&) noexcept; + + private: + // \ref{mdspan.layout.rightpad.expo}, exposition-only members + index_type @\exposid{stride-rm2}@ = @\exposid{static-padding-stride}@; // \expos + extents_type @\exposid{extents_}@{}; // \expos + + // \ref{mdspan.sub.map}, \tcode{submdspan} mapping specialization + template + constexpr auto @\exposid{submdspan-mapping-impl}@(SliceSpecifiers...) const // \expos + -> @\seebelow@; + + template + friend constexpr auto @\libmember{submdspan_mapping}{layout_right_padded::mapping}@(const mapping& src, SliceSpecifiers... slices) { + return src.@\exposid{submdspan-mapping-impl}@(slices...); + } + }; +} \end{codeblock} -\rSec2[unord.set.syn]{Header \tcode{} synopsis}% -\indexlibrary{\idxhdr{unordered_set}}% -\indexlibrary{\idxcode{unordered_set}}% -\indexlibrary{\idxcode{unordered_multiset}}% -\begin{codeblock} -#include - -namespace std { - - // \ref{unord.set}, class template unordered_set: - template , - class Pred = std::equal_to, - class Alloc = std::allocator > - class unordered_set; - - // \ref{unord.multiset}, class template unordered_multiset: - template , - class Pred = std::equal_to, - class Alloc = std::allocator > - class unordered_multiset; +\pnum +If \tcode{Extents} is not a specialization of \tcode{extents}, +then the program is ill-formed. - template - void swap(unordered_set& x, - unordered_set& y) - noexcept(noexcept(x.swap(y))); +\pnum +\tcode{layout_right_padded::mapping} is a trivially copyable type +that models \libconcept{regular} for each \tcode{E}. - template - void swap(unordered_multiset& x, - unordered_multiset& y) - noexcept(noexcept(x.swap(y))); +\pnum +Throughout \ref{mdspan.layout.rightpad}, +let \tcode{P_rank} be the following +size \exposid{rank_} parameter pack of \tcode{size_}t values: +\begin{itemize} +\item +the empty parameter pack, if \exposid{rank_} equals zero; +\item +\tcode otherwise, \tcode{0zu}, if \exposid{rank_} equals one; +\item +otherwise, the parameter pack \tcode{0zu}, \tcode{1zu}, \ldots, \tcode{\exposid{rank_}- 1}. +\end{itemize} - template - bool operator==(const unordered_set& a, - const unordered_set& b); - template - bool operator!=(const unordered_set& a, - const unordered_set& b); - template - bool operator==(const unordered_multiset& a, - const unordered_multiset& b); - template - bool operator!=(const unordered_multiset& a, - const unordered_multiset& b); -} // namespace std -\end{codeblock} +\pnum +\mandates +\begin{itemize} +\item +If \tcode{rank_dynamic() == 0} is \tcode{true}, +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 +\begin{itemize} +\item +\exposid{rank_} is greater than one, +\item +\tcode{padding_value} does not equal \tcode{dynamic_extent}, and +\item +\exposid{last-static-extent} does not equal \tcode{dynamic_extent}, +\end{itemize} +then \tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(padding_value, \exposid{last-static-extent})} +is representable as a value of type \tcode{size_t}, and +is representable as a value of type \tcode{index_type}. +\item +If +\begin{itemize} +\item +\exposid{rank_} is greater than one, +\item +\tcode{padding_value} does not equal \tcode{dynamic_extent}, and +\item +\tcode{extents_type::static_extent($k$)} does not equal \tcode{dynamic_extent} +for all $k$ in the range \range{0}{\exposid{rank_}}, +\end{itemize} +then the product of +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(padding_value, ext.static_extent(\exposid{rank_} - 1))} and +all values \tcode{ext.static_extent($k$)} +with $k$ in the range of \range{0}{\exposid{rank_} - 1} +is representable as a value of type \tcode{size_t}, and +is representable as a value of type \tcode{index_type}. +\end{itemize} -\rSec2[unord.map]{Class template \tcode{unordered_map}}% -\indexlibrary{\idxcode{unordered_map}} +\rSec5[mdspan.layout.rightpad.expo]{Exposition-only members} -\rSec3[unord.map.overview]{Class template \tcode{unordered_map} overview} +\begin{itemdecl} +static constexpr size_t @\exposid{static-padding-stride}@ = @\seebelow@; +\end{itemdecl} +\begin{itemdescr} \pnum -\indextext{\idxcode{unordered_map}!unique keys}% -\indextext{unordered associative containers!unique keys}% -An \tcode{unordered_map} is an unordered associative container that -supports unique keys (an \tcode{unordered_map} contains at most one of each -key value) and that associates values of another type -\tcode{mapped_type} with the keys. -The \tcode{unordered_map} class -supports forward iterators. +The value is +\begin{itemize} +\item +\tcode{0}, if \exposid{rank_} equals zero or one; +\item +otherwise, \tcode{dynamic_extent}, +if \tcode{padding_value} or \exposid{last-static-extent} equals +\tcode{dynamic_extent}; +\item +otherwise, the \tcode{size_t} value which is +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(padding_value, \exposid{last-sta\-tic-extent})}. +\end{itemize} +\end{itemdescr} -\pnum -An \tcode{unordered_map} satisfies all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table~\ref{tab:containers.allocatoraware}). It provides the operations described in the preceding requirements table for unique keys; that is, an \tcode{unordered_map} supports the \tcode{a_uniq} operations in that table, not the \tcode{a_eq} operations. For an \tcode{unordered_map} the \tcode{key type} is \tcode{Key}, the mapped type is \tcode{T}, and the value type is \tcode{std::pair}. +\begin{itemdecl} +index_type @\exposid{stride-rm2}@ = @\exposid{static-padding-stride}@; +\end{itemdecl} +\begin{itemdescr} \pnum -This section only describes operations on \tcode{unordered_map} that -are not described in one of the requirement tables, or for which there -is additional semantic information. +\recommended +Implementations should not store this value +if \exposid{static-padding-stride} is not \tcode{dynamic_extent}. +\begin{note} +Using \tcode{extents} +instead of \tcode{index_type} as the type of \exposid{stride-\linebreak rm2} +would achieve this. +\end{note} +\end{itemdescr} -\indexlibrary{\idxcode{unordered_map}}% -\begin{codeblock} -namespace std { - template , - class Pred = std::equal_to, - class Allocator = std::allocator > > - class unordered_map - { - public: - // types - typedef Key key_type; - typedef std::pair value_type; - typedef T mapped_type; - typedef Hash hasher; - typedef Pred key_equal; - typedef Allocator allocator_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ size_type; - typedef @\impdef@ difference_type; - - typedef @\impdef@ iterator; - typedef @\impdef@ const_iterator; - typedef @\impdef@ local_iterator; - typedef @\impdef@ const_local_iterator; - - // construct/destroy/copy - unordered_map(); - 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()); - unordered_map(const unordered_map&); - unordered_map(unordered_map&&); - explicit unordered_map(const Allocator&); - unordered_map(const unordered_map&, const Allocator&); - unordered_map(unordered_map&&, const Allocator&); - 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) - : unordered_map(n, hasher(), key_equal(), a) { } - 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) - : 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) - : unordered_map(f, l, n, hf, key_equal(), a) { } - 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) - : unordered_map(il, n, hf, key_equal(), a) { } - ~unordered_map(); - unordered_map& operator=(const unordered_map&); - unordered_map& operator=(unordered_map&&) - noexcept(allocator_traits::is_always_equal::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value); - unordered_map& operator=(initializer_list); - allocator_type get_allocator() const noexcept; +\rSec5[mdspan.layout.rightpad.cons]{Constructors} - // size and capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; +\indexlibraryctor{layout_right_padded::mapping}% +\begin{itemdecl} +constexpr mapping(const extents_type& ext); +\end{itemdecl} - // 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; +\begin{itemdescr} +\pnum +\expects +\begin{itemize} +\item +The size of the multidimensional index space \tcode{ext} +is representable as a value of type \tcode{index_type}. +\item +If \exposid{rank_} is greater than one and +\tcode{padding_value} does not equal \tcode{dynamic_extent}, +then \tcode{\exposid{LEAST-MUL\-TIPLE-AT-LEAST}(padding_value, ext.extent(\exposid{rank_} - 1))} +is representable as a value of type \exposid{index_type}. +\item +If \exposid{rank_} is greater than one and +\tcode{padding_value} does not equal \tcode{dynamic_extent}, +then the product of +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(padding_value, ext.extent(\exposid{rank_} - 1))} and +all values \tcode{ext.extent($k$)} +with $k$ in the range of \range{0}{\exposid{rank_} - 1} +is representable as a value of type \tcode{index_type}. +\end{itemize} - // 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); - void insert(initializer_list); - - template - pair try_emplace(const key_type& k, Args&&... args); - template - pair try_emplace(key_type&& k, Args&&... args); - template - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); - template - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); - template - pair insert_or_assign(const key_type& k, M&& obj); - template - pair insert_or_assign(key_type&& k, M&& obj); - template - 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); +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{extents_} with \tcode{ext}; and +\item +if \exposid{rank_} is greater than one, +direct-non-list-initializes \exposid{stride-rm2} +\begin{itemize} +\item +with \tcode{ext.extent(\exposid{rank_} - 1)} +if \tcode{padding_value} is \tcode{dynamic_extent}, +\item +otherwise with +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(padding_value, ext.extent(\exposid{rank_} - 1))}. +\end{itemize} +\end{itemize} +\end{itemdescr} - iterator erase(const_iterator position); - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; +\indexlibraryctor{layout_right_padded::mapping}% +\begin{itemdecl} +template +constexpr mapping(const extents_type& ext, OtherIndexType padding); +\end{itemdecl} - void swap(unordered_map&) - noexcept(allocator_traits::is_always_equal::value && - noexcept(swap(declval(),declval())) && - noexcept(swap(declval(),declval()))); +\begin{itemdescr} +\pnum +Let \tcode{pad} be +\tcode{extents_type::\exposid{index-cast}(std::move(padding))}. - // observers - hasher hash_function() const; - key_equal key_eq() const; +\pnum +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} is \tcode{true}. +\item +\tcode{is_nothrow_constructible_v} is \tcode{true}. +\end{itemize} - // lookup - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - size_type count(const key_type& k) const; - std::pair equal_range(const key_type& k); - std::pair equal_range(const key_type& k) const; +\pnum +\expects +\begin{itemize} +\item +\tcode{pad} is representable as a value of type \tcode{index_type}. +\item +\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))} +is representable as a value of type \tcode{index_type}. +\item +If \exposid{rank_} is greater than one, +then the product of +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(pad, ext.extent(\exposid{\linebreak rank_} - 1))} and +all values \tcode{ext.extent($k$)} +with $k$ in the range of \range{0}{\exposid{rank_} - 1} +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{pad}. +\end{itemize} - mapped_type& operator[](const key_type& k); - mapped_type& operator[](key_type&& k); - mapped_type& at(const key_type& k); - const mapped_type& at(const key_type& k) const; +\pnum +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{ext}, and +if \exposid{rank_} is greater than one, +direct-non-list-initializes \exposid{stride-rm2} with +\tcode{\exposid{LEAST-MULTIPLE-AT-LEAST}(pad, ext.extent(\exposid{rank_} - 1))}. +\end{itemdescr} - // 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; - 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; +\indexlibraryctor{layout_right_padded::mapping}% +\begin{itemdecl} +template + constexpr explicit(!is_convertible_v) + mapping(const layout_right::mapping& other); +\end{itemdecl} - // 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); - }; +\begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. - template - void swap(unordered_map& x, - unordered_map& y) - noexcept(noexcept(x.swap(y))); +\pnum +\mandates +If \tcode{OtherExtents::rank()} is greater than 1, then +\begin{codeblock} +(@\exposid{static-padding-stride}@ == dynamic_extent) || +(OtherExtents::static_extent(@\exposid{rank_}@ - 1) == dynamic_extent) || +(@\exposid{static-padding-stride}@ == OtherExtents::static_extent(@\exposid{rank_}@ - 1)) +\end{codeblock} +is \tcode{true}. - template - bool operator==(const unordered_map& a, - const unordered_map& b); - template - bool operator!=(const unordered_map& a, - const unordered_map& b); -} +\pnum +\expects +\begin{itemize} +\item +If \tcode{\exposid{rank_} > 1} is \tcode{true} and +\tcode{padding_value == dynamic_extent} is \tcode{false}, then +\tcode{other.stride(\newline \exposid{rank_} - 2)} equals +\begin{codeblock} +@\exposid{LEAST-MULTIPLE-AT-LEAST}@(padding_value, + extents_type::@\exposid{index-cast}@(other.extents().extent(rank_ - 1))) \end{codeblock} +and +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}. +\end{itemize} -\rSec3[unord.map.cnstr]{\tcode{unordered_map} constructors} +\pnum +\effects +Equivalent to \tcode{mapping(other.extents())}. +\end{itemdescr} -\indexlibrary{\idxcode{unordered_map}!\idxcode{unordered_map}}% +\indexlibraryctor{layout_right_padded::mapping}% \begin{itemdecl} -unordered_map() : unordered_map(size_type(@\seebelow@)) { } -explicit unordered_map(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); +template + constexpr explicit(@\seebelow@) + mapping(const layout_stride::mapping& other); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an empty \tcode{unordered_map} using the -specified hash function, key equality function, and allocator, and -using at least \tcode{n} buckets. For the default constructor, -the number of buckets is \impldef{default number of buckets in -\tcode{unordered_map}}. -\tcode{max_load_factor()} returns 1.0. +\constraints +\tcode{is_constructible_v} is \tcode{true}. + +\pnum +\expects +\begin{itemize} +\item +If \exposid{rank_} is greater than 1 and +\tcode{padding_value} does not equal \tcode{dynamic_extent}, +then \tcode{other.\linebreak stride(\exposid{rank_} - 2)} equals +\begin{codeblock} +@\exposid{LEAST-MULTIPLE-AT-LEAST}@(padding_value, + extents_type::@\exposid{index-cast}@(other.extents().extent(@\exposid{rank_}@ - 1))) +\end{codeblock} +\item +If \exposid{rank_} is greater than 0, +then other.stride(\exposid{rank_} - 1) equals 1. +\item +If \exposid{rank_} is greater than 2, +then for all $r$ in the range \range{0}{\exposid{rank_} - 2}, +\tcode{other.stride($r$)} equals +\begin{codeblock} +(other.extents().@\exposid{rev-prod-of-extents}@(r) / other.extents().extent(@\exposid{rank_}@ - 1)) * + other.stride(@\exposid{rank_}@ - 2) +\end{codeblock} +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}. +\end{itemize} + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}; and +\item +if \exposid{rank_} is greater than one, +direct-non-list-initializes \exposid{stride-rm2} +with \tcode{other.stride(\exposid{rank_} - 2)}. +\end{itemize} \pnum -\complexity Constant. +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(rank_ == 0 && is_convertible_v) +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{unordered_map}!\idxcode{unordered_map}}% +\indexlibraryctor{layout_right_padded::mapping}% \begin{itemdecl} -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()); -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()); +template + constexpr explicit(@\seebelow@) + mapping(const LayoutRightPaddedMapping& other); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an empty \tcode{unordered_map} using the -specified hash function, key equality function, and allocator, and -using at least \tcode{n} buckets. If \tcode{n} is not -provided, the number of buckets is \impldef{default number of buckets in -\tcode{unordered_map}}. Then -inserts elements from the range \range{f}{l} -for the first form, or from the range -\range{il.begin()}{il.end()} for the second form. -\tcode{max_load_factor()} returns 1.0. +\constraints +\begin{itemize} +\item +\tcode{\exposid{is-layout-right-padded-mapping-of}} +is \tcode{true}. +\item +\tcode{is_constructible_v} +is \tcode{true}. +\end{itemize} \pnum -\complexity Average case linear, worst case quadratic. -\end{itemdescr} +\mandates +If \exposid{rank_} is greater than 1, then +\begin{codeblock} +padding_value == dynamic_extent || +LayoutRightPaddedMapping::padding_value == dynamic_extent || +padding_value == LayoutRightPaddedMapping::padding_value +\end{codeblock} +is \tcode{true}. -\rSec3[unord.map.elem]{\tcode{unordered_map} element access} +\pnum +\expects +\begin{itemize} +\item +If \exposid{rank_} is greater than 1 and +\tcode{padding_value} does not equal \tcode{dynamic_extent}, +then \tcode{other.\linebreak stride(\exposid{rank_} - 2)} equals +\begin{codeblock} +@\exposid{LEAST-MULTIPLE-AT-LEAST}@(padding_value, + extents_type::@\exposid{index-cast}@(other.extent(@\exposid{rank_}@ - 1))) +\end{codeblock} +\item +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}. +\end{itemize} -\indexlibrary{\idxcode{unordered_map}!\idxcode{operator[]}}% -\indexlibrary{\idxcode{operator[]}!\idxcode{unordered_map}}% -\indextext{\idxcode{unordered_map}!element access}% +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}; and +\item +if \exposid{rank_} is greater than one, +direct-non-list-initializes \exposid{stride-rm2} +with \tcode{other.stride(rank_ - 2)}. +\end{itemize} + +\pnum +\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) +\end{codeblock} +\end{itemdescr} + +\indexlibraryctor{layout_right_padded::mapping}% \begin{itemdecl} -mapped_type& operator[](const key_type& k); -mapped_type& operator[](key_type&& k); +template + constexpr explicit(@\seebelow@) + mapping(const LayoutLeftPaddedMapping& other) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{mapped_type} shall be \tcode{DefaultInsertable} into \tcode{*this}. -For the first operator, \tcode{key_type} shall be \tcode{CopyInsertable} into \tcode{*this}. -For the second operator, \tcode{key_type} shall be \tcode{MoveConstructible}. +\constraints +\begin{itemize} +\item +\tcode{\exposid{is-layout-left-padded-mapping-of}} +is \tcode{true} or\newline +\tcode{\exposid{is-mapping-of}} +is \tcode{true}. +\item +\exposid{rank_} equals zero or one. +\item +\tcode{is_constructible_v}\newline +is \tcode{true}. +\end{itemize} \pnum -\effects If the \tcode{unordered_map} does not already contain -an element whose key is equivalent to \tcode{\textit{k}}, the first operator inserts -the value -\tcode{value_type(k, mapped_type())} -and the second operator inserts the value -\tcode{value_type(std::move(k), mapped_type())}. - +\expects +\tcode{other.required_span_size()} is representable as +a value of type \tcode{index_type}. \pnum -\returns A reference to \tcode{x.second}, where \tcode{x} -is the (unique) element whose key is equivalent to \tcode{\textit{k}}. +\effects +Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. \pnum -\complexity Average case \bigoh{1}, worst case \bigoh{\tcode{size()}}. +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!is_convertible_v +\end{codeblock} +\begin{note} +Neither the input mapping nor the mapping to be constructed +uses the padding stride in the rank-0 or rank-1 case, +so the padding stride affects neither the constraints nor the preconditions. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{unordered_map}!\idxcode{at}}% -\indexlibrary{\idxcode{at}!\idxcode{unordered_map}}% -\indextext{\idxcode{unordered_map}!element access}% +\rSec5[mdspan.layout.rightpad.obs]{Observers} + +\indexlibrarymember{strides}{layout_right_padded::mapping}% \begin{itemdecl} -mapped_type& at(const key_type& k); -const mapped_type& at(const key_type& k) const; +constexpr array strides() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns A reference to \tcode{x.second}, where \tcode{x} is the (unique) element whose key is equivalent to \tcode{k}. +\returns +\tcode{array({stride(P_rank)...})}. +\end{itemdescr} + +\indexlibrarymember{required_span_size}{layout_right_padded::mapping}% +\begin{itemdecl} +constexpr index_type required_span_size() const noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\throws An exception object of type \tcode{out_of_range} if no such element is present. +\returns +\tcode{0} if the multidimensional index space \exposid{extents_} is empty, +otherwise \tcode{(*this)(\exposid{extents_}.extent(P_rank) - index_type(1)...) + 1}. \end{itemdescr} -\rSec3[unord.map.modifiers]{\tcode{unordered_map} modifiers} - -\indexlibrary{\idxcode{unordered_map}!\idxcode{insert}}% -\indexlibrary{\idxcode{insert}!\idxcode{unordered_map}}% +\indexlibrarymember{operator()}{layout_right_padded::mapping}% \begin{itemdecl} -template - pair insert(P&& obj); +template +constexpr index_type operator()(Indices... idxs) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Equivalent to \tcode{return emplace(std::forward

(obj))}. +\constraints +\begin{itemize} +\item +\tcode{sizeof...(Indices) == \exposid{rank_}} is \tcode{true}. +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}. +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}. +\end{itemize} + +\pnum +\expects +\tcode{extents_type::\exposid{index-cast}(idxs)} is +a multidimensional index in \tcode{extents()}\iref{mdspan.overview}. \pnum -\remarks This signature shall not participate in overload resolution -unless \tcode{std::is_constructible::value} is \tcode{true}. +\returns +\tcode{((static_cast(std::move(idxs)) * stride(P_rank)) + ... + 0)}. \end{itemdescr} -\indexlibrary{\idxcode{unordered_map}!\idxcode{insert}}% -\indexlibrary{\idxcode{insert}!\idxcode{unordered_map}}% +\indexlibrarymember{is_always_exhaustive}{layout_right_padded::mapping}% \begin{itemdecl} -template - iterator insert(const_iterator hint, P&& obj); +static constexpr bool is_always_exhaustive() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Equivalent to -\tcode{return emplace_hint(hint, std::forward

(obj))}. - -\pnum -\remarks This signature shall not participate in overload resolution -unless \tcode{std::is_constructible::value} is \tcode{true}. +\returns +\begin{itemize} +\item +If \exposid{rank_} equals zero or one, then \tcode{true}; +\item +otherwise, +if neither \exposid{static-padding-stride} nor \exposid{last-static-extent} +equal \tcode{dynamic_extent}, +then \tcode{\exposid{static-padding-stride} == \exposid{last-static-extent}}; +\item +otherwise, \tcode{false}. +\end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{try_emplace}!\idxcode{unordered_map}}% -\indexlibrary{\idxcode{unordered_map}!\idxcode{try_emplace}}% +\indexlibrarymember{is_exhaustive}{layout_right_padded::mapping}% \begin{itemdecl} -template pair try_emplace(const key_type& k, Args&&... args); -template pair try_emplace(key_type&& k, Args&&... args); -template 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 bool is_exhaustive() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -If the key \tcode{k} already exists in the map, there is no effect. -Otherwise, inserts an element into the map. -In the first and third forms, -the element is constructed from the arguments as -\tcode{value_type(k, std::forward(args)...)}. -In the second and fourth forms, -the element is constructed from the arguments as -\tcode{value_type(std::move(k), std::forward(args)...)}. -In the first two overloads, -the \tcode{bool} component of the returned pair is \tcode{true} -if and only if the insertion took place. -The returned \tcode{iterator} points to the element of the map whose key -is equivalent to \tcode{k}. - -\pnum -\complexity -The same as \tcode{emplace} and \tcode{emplace_hint}, -respectively. +\returns +\tcode{true} if \exposid{rank_} equals zero or one; +otherwise, +\begin{codeblock} +@\exposid{extents_}@.extent(@\exposid{rank_}@ - 1) == stride(@\exposid{rank_}@ - 2) +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{insert_or_assign}!\idxcode{unordered_map}}% -\indexlibrary{\idxcode{unordered_map}!\idxcode{insert_or_assign}}% +\indexlibrarymember{stride}{layout_right_padded::mapping}% \begin{itemdecl} -template pair insert_or_assign(const key_type& k, M&& obj); -template pair insert_or_assign(key_type&& k, M&& obj); -template 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 index_type stride(rank_type r) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects -If the key \tcode{k} does not exist in the map, -inserts an element into the map. -In the first and third forms, -the element is constructed from the arguments as -\tcode{value_type(k, std::forward(args)...)}. -In the second and fourth forms, -the element is constructed from the arguments as -\tcode{value_type(std::move(k), std::forward(args)...)}. -If the key already exists, -\tcode{std::forward(obj)} is assigned to the -\tcode{mapped_type} corresponding to the key. -In the first two overloads, -the \tcode{bool} component of the returned value is \tcode{true} -if and only if the insertion took place. -The returned \tcode{iterator} points to the element -that was inserted or updated. +\expects +\tcode{r} is smaller than \exposid{rank_}. \pnum -\complexity -The same as \tcode{emplace} and \tcode{emplace_hint}, -respectively. +\returns +\begin{itemize} +\item +If \tcode{r} equals \tcode{\exposid{rank_} - 1}: \tcode{1}; +\item +otherwise, if \tcode{r} equals \tcode{\exposid{rank_} - 2}: \exposid{stride-rm2}; +\item +otherwise, +the product of \exposid{stride-rm2} and +all values \tcode{extents_.extent($k$)} +with $k$ in the range of \range{r + 1}{\exposid{rank_} - 1}. +\end{itemize} \end{itemdescr} -\rSec3[unord.map.swap]{\tcode{unordered_map} swap} - -\indexlibrary{\idxcode{unordered_map}!\idxcode{swap}}% -\indexlibrary{\idxcode{swap}!\idxcode{unordered_map}}% +\indexlibrarymember{operator==}{layout_right_padded::mapping}% \begin{itemdecl} -template - void swap(unordered_map& x, - unordered_map& y) - noexcept(noexcept(x.swap(y))); +template + friend constexpr bool operator==(const mapping& x, const LayoutRightPaddedMapping& y) noexcept; \end{itemdecl} \begin{itemdescr} -\pnum\effects \tcode{x.swap(y)}. +\pnum +\constraints +\begin{itemize} +\item +\tcode{\exposid{is-layout-right-padded-mapping-of}} +is \tcode{true}. +\item +\tcode{LayoutRightPaddedMapping::extents_type::rank() == \exposid{rank_}} +is \tcode{true}. +\end{itemize} + +\pnum +\returns +\tcode{true} if \tcode{x.extents() == y.extents()} is \tcode{true} and +\tcode{\exposid{rank_} < 2 || x.stride(\exposid{rank_} - 2) == y.stride(\exposid{rank_} - 2)} is \tcode{true}. +Otherwise, \tcode{false}. \end{itemdescr} -\rSec2[unord.multimap]{Class template \tcode{unordered_multimap}}% -\indexlibrary{\idxcode{unordered_multimap}} +\rSec3[mdspan.accessor]{Accessor policy} -\rSec3[unord.multimap.overview]{Class template \tcode{unordered_multimap} overview} +\rSec4[mdspan.accessor.general]{General} \pnum -\indextext{\idxcode{unordered_multimap}!equivalent keys}% -\indextext{unordered associative containers!equivalent keys}% -An \tcode{unordered_multimap} is an unordered associative container -that supports equivalent keys (an instance of \tcode{unordered_multimap} may contain -multiple copies of each key value) and that associates values of -another type \tcode{mapped_type} with the keys. -The \tcode{unordered_multimap} class -supports forward iterators. +An \defn{accessor policy} defines types and operations by which +a reference to a single object is created +from an abstract data handle to a number of such objects and an index. \pnum -An \tcode{unordered_multimap} satisfies all of the requirements of a container, of an -unordered associative container, and of an allocator-aware container -(Table~\ref{tab:containers.allocatoraware}). It provides the operations described in the -preceding requirements table for equivalent keys; that is, an \tcode{unordered_multimap} -supports the \tcode{a_eq} operations in that table, not the \tcode{a_uniq} operations. -For an \tcode{unordered_multimap} the \tcode{key type} is \tcode{Key}, the -mapped type is \tcode{T}, and the value type is \tcode{std::pair}. +A range of indices $[0, N)$ is an \defnadj{accessible}{range} of +a given data handle and an accessor +if, for each $i$ in the range, +the accessor policy's \tcode{access} function produces a valid reference to an object. \pnum -This section only describes operations on \tcode{unordered_multimap} -that are not described in one of the requirement tables, or for which -there is additional semantic information. - -\indexlibrary{\idxcode{unordered_multimap}}% -\begin{codeblock} -namespace std { - template , - class Pred = std::equal_to, - class Allocator = std::allocator > > - class unordered_multimap - { - public: - // types - typedef Key key_type; - typedef std::pair value_type; - typedef T mapped_type; - typedef Hash hasher; - typedef Pred key_equal; - typedef Allocator allocator_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ size_type; - typedef @\impdef@ difference_type; - - typedef @\impdef@ iterator; - typedef @\impdef@ const_iterator; - typedef @\impdef@ local_iterator; - typedef @\impdef@ const_local_iterator; - - // construct/destroy/copy - unordered_multimap(); - 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()); - unordered_multimap(const unordered_multimap&); - unordered_multimap(unordered_multimap&&); - explicit unordered_multimap(const Allocator&); - unordered_multimap(const unordered_multimap&, const Allocator&); - unordered_multimap(unordered_multimap&&, const Allocator&); - 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) - : unordered_multimap(n, hasher(), key_equal(), a) { } - 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) - : 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) - : unordered_multimap(f, l, n, hf, key_equal(), a) { } - 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) - : unordered_multimap(il, n, hf, key_equal(), a) { } - ~unordered_multimap(); - unordered_multimap& operator=(const unordered_multimap&); - unordered_multimap& operator=(unordered_multimap&&) - noexcept(allocator_traits::is_always_equal::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value); - unordered_multimap& operator=(initializer_list); - allocator_type get_allocator() const noexcept; - - // size and capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() 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; - - // 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); - void insert(initializer_list); - - iterator erase(const_iterator position); - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; - - void swap(unordered_multimap&) - noexcept(allocator_traits::is_always_equal::value && - noexcept(swap(declval(),declval())) && - noexcept(swap(declval(),declval()))); - - // observers - hasher hash_function() const; - key_equal key_eq() const; - - // lookup - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - size_type count(const key_type& k) const; - std::pair equal_range(const key_type& k); - std::pair equal_range(const key_type& 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; - 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; - - // 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); - }; +In \ref{mdspan.accessor.reqmts}, - template - void swap(unordered_multimap& x, - unordered_multimap& y) - noexcept(noexcept(x.swap(y))); +\begin{itemize} +\item +\tcode{A} denotes an accessor policy. +\item +\tcode{a} denotes a value of type \tcode{A} or \tcode{const A}. +\item +\tcode{p} denotes a value of type \tcode{A::data_handle_type} or \tcode{const A::data_handle_type}. +\begin{note} +The type \tcode{A::data_handle_type} need not be dereferenceable. +\end{note} +\item +\tcode{n}, \tcode{i}, and \tcode{j} each denote values of type \tcode{size_t}. +\end{itemize} - template - bool operator==(const unordered_multimap& a, - const unordered_multimap& b); - template - bool operator!=(const unordered_multimap& a, - const unordered_multimap& b); -} -\end{codeblock} +\rSec4[mdspan.accessor.reqmts]{Requirements} -\rSec3[unord.multimap.cnstr]{\tcode{unordered_multimap} constructors} +\pnum +A type \tcode{A} meets the accessor policy requirements if +\begin{itemize} +\item +\tcode{A} models \libconcept{copyable}, +\item +\tcode{is_nothrow_move_constructible_v} is \tcode{true}, +\item +\tcode{is_nothrow_move_assignable_v} is \tcode{true}, +\item +\tcode{is_nothrow_swappable_v} is \tcode{true}, and +\item +the following types and expressions +are well-formed and have the specified semantics. +\end{itemize} -\indexlibrary{\idxcode{unordered_multimap}!\idxcode{unordered_multimap}}% \begin{itemdecl} -unordered_multimap() : unordered_multimap(size_type(@\seebelow@)) { } -explicit unordered_multimap(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); +typename A::element_type \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an empty \tcode{unordered_multimap} using the -specified hash function, key equality function, and allocator, and -using at least \tcode{n} buckets. For the default constructor, -the number of buckets is \impldef{default number of buckets in -\tcode{unordered_multimap}}. -\tcode{max_load_factor()} returns 1.0. - -\pnum -\complexity Constant. +\result +A complete object type that is not an abstract class type. \end{itemdescr} -\indexlibrary{\idxcode{unordered_multimap}!\idxcode{unordered_multimap}}% \begin{itemdecl} -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()); -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()); +typename A::data_handle_type \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an empty \tcode{unordered_multimap} using the -specified hash function, key equality function, and allocator, and -using at least \tcode{n} buckets. If \tcode{n} is not -provided, the number of buckets is \impldef{default number of buckets in -\tcode{unordered_multimap}}. Then -inserts elements from the range \range{f}{l} -for the first form, or from the range -\range{il.begin()}{il.end()} for the second form. -\tcode{max_load_factor()} returns 1.0. - -\pnum -\complexity Average case linear, worst case quadratic. +\result +A type that models \libconcept{copyable}, and +for which \tcode{is_nothrow_move_constructible_v} is \tcode{true}, +\tcode{is_nothrow_move_assignable_v} is \tcode{true}, and +\tcode{is_nothrow_swappable_v} is \tcode{true}. +\begin{note} +The type of \tcode{data_handle_type} need not be \tcode{element_type*}. +\end{note} \end{itemdescr} -\rSec3[unord.multimap.modifiers]{\tcode{unordered_multimap} modifiers} - -\indexlibrary{\idxcode{unordered_multimap}!\idxcode{insert}}% -\indexlibrary{\idxcode{insert}!\idxcode{unordered_multimap}}% \begin{itemdecl} -template - iterator insert(P&& obj); +typename A::reference \end{itemdecl} \begin{itemdescr} \pnum -\effects Equivalent to \tcode{return emplace(std::forward

(obj))}. - -\pnum -\remarks This signature shall not participate in overload resolution -unless \tcode{std::is_constructible::value} is \tcode{true}. +\result +A type that models +\tcode{\libconcept{common_reference_with}}. +\begin{note} +The type of \tcode{reference} need not be \tcode{element_type\&}. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{unordered_multimap}!\idxcode{insert}}% -\indexlibrary{\idxcode{insert}!\idxcode{unordered_multimap}}% \begin{itemdecl} -template - iterator insert(const_iterator hint, P&& obj); +typename A::offset_policy \end{itemdecl} \begin{itemdescr} \pnum -\effects Equivalent to -\tcode{return emplace_hint(hint, std::forward

(obj))}. +\result +A type \tcode{OP} such that: -\pnum -\remarks This signature shall not participate in overload resolution -unless \tcode{std::is_constructible::value} is \tcode{true}. +\begin{itemize} +\item +\tcode{OP} meets the accessor policy requirements, +\item +\tcode{\libconcept{constructible_from}} is modeled, and +\item +\tcode{is_same_v} is \tcode{true}. +\end{itemize} \end{itemdescr} -\rSec3[unord.multimap.swap]{\tcode{unordered_multimap} swap} - -\indexlibrary{\idxcode{unordered_multimap}!\idxcode{swap}}% -\indexlibrary{\idxcode{swap}!\idxcode{unordered_multimap}}% \begin{itemdecl} -template - void swap(unordered_multimap& x, - unordered_multimap& y) - noexcept(noexcept(x.swap(y))); +a.access(p, i) \end{itemdecl} - \begin{itemdescr} -\pnum\effects \tcode{x.swap(y)}. -\end{itemdescr} - -\rSec2[unord.set]{Class template \tcode{unordered_set}}% -\indexlibrary{\idxcode{unordered_set}} - -\rSec3[unord.set.overview]{Class template \tcode{unordered_set} overview} - \pnum -\indextext{\idxcode{unordered_set}!unique keys}% -\indextext{unordered associative containers!unique keys}% -An \tcode{unordered_set} is an unordered associative container that -supports unique keys (an \tcode{unordered_set} contains at most one of each -key value) and in which the elements' keys are the elements -themselves. -The \tcode{unordered_set} class -supports forward iterators. +\result +\tcode{A::reference} \pnum -An \tcode{unordered_set} satisfies all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table~\ref{tab:containers.allocatoraware}). 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, not the \tcode{a_eq} operations. For an \tcode{unordered_set} the \tcode{key type} and the value type are both \tcode{Key}. The \tcode{iterator} and \tcode{const_iterator} types are both const iterator types. It is unspecified whether they are the same type. +\remarks +The expression is equality preserving. \pnum -This section only describes operations on \tcode{unordered_set} that -are not described in one of the requirement tables, or for which there -is additional semantic information. - -\indexlibrary{\idxcode{unordered_set}}% -\begin{codeblock} -namespace std { - template , - class Pred = std::equal_to, - class Allocator = std::allocator > - class unordered_set - { - public: - // types - typedef Key key_type; - typedef Key value_type; - typedef Hash hasher; - typedef Pred key_equal; - typedef Allocator allocator_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ size_type; - typedef @\impdef@ difference_type; - - typedef @\impdef@ iterator; - typedef @\impdef@ const_iterator; - typedef @\impdef@ local_iterator; - typedef @\impdef@ const_local_iterator; - - // construct/destroy/copy - unordered_set(); - 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()); - unordered_set(const unordered_set&); - unordered_set(unordered_set&&); - explicit unordered_set(const Allocator&); - unordered_set(const unordered_set&, const Allocator&); - unordered_set(unordered_set&&, const Allocator&); - 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) - : unordered_set(n, hasher(), key_equal(), a) { } - 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) - : 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) - : unordered_set(il, n, hasher(), key_equal(), a) { } - 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&&) - noexcept(allocator_traits::is_always_equal::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value); - unordered_set& operator=(initializer_list); - allocator_type get_allocator() const noexcept; - - // size and capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() 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; +\begin{note} +Concrete accessor policies can impose preconditions for their \tcode{access} function. +However, they might not. +For example, an accessor where +\tcode{p} is \tcode{span} and +\tcode{access(p, i)} returns \tcode{p[i \% p.size()]} +does not need to impose a precondition on \tcode{i}. +\end{note} +\end{itemdescr} - // 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); - iterator insert(const_iterator hint, const value_type& obj); - iterator insert(const_iterator hint, value_type&& obj); - template void insert(InputIterator first, InputIterator last); - void insert(initializer_list); +\begin{itemdecl} +a.offset(p, i) +\end{itemdecl} - iterator erase(const_iterator position); - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; +\begin{itemdescr} +\pnum +\result +\tcode{A::offset_policy::data_handle_type} - void swap(unordered_set&) - noexcept(allocator_traits::is_always_equal::value && - noexcept(swap(declval(),declval())) && - noexcept(swap(declval(),declval()))); +\pnum +\returns +\tcode{q} such that for \tcode{b} being \tcode{A::offset_policy(a)}, and +any integer \tcode{n} for which $[0, \tcode{n})$ is +an accessible range of \tcode{p} and \tcode{a}: +\begin{itemize} +\item +$[0, \tcode{n} - \tcode{i})$ is an accessible range of \tcode{q} and \tcode{b}; and +\item +\tcode{b.access(q, j)} provides access to +the same element as \tcode{a.access(p, i + j)}, +for every \tcode{j} in the range $[0, \tcode{n} - \tcode{i})$. +\end{itemize} - // observers - hasher hash_function() const; - key_equal key_eq() const; +\pnum +\remarks +The expression is equality-preserving. +\end{itemdescr} - // lookup - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - size_type count(const key_type& k) const; - std::pair equal_range(const key_type& k); - std::pair equal_range(const key_type& k) const; +\rSec4[mdspan.accessor.default]{Class template \tcode{default_accessor}} - // 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; - 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; +\rSec5[mdspan.accessor.default.overview]{Overview} - // 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); +\begin{codeblock} +namespace std { + template + 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 + constexpr default_accessor(default_accessor) noexcept; + constexpr reference access(data_handle_type p, size_t i) const noexcept; + constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept; }; - - template - void swap(unordered_set& x, - unordered_set& y) - noexcept(noexcept(x.swap(y))); - - template - bool operator==(const unordered_set& a, - const unordered_set& b); - template - bool operator!=(const unordered_set& a, - const unordered_set& b); } \end{codeblock} -\rSec3[unord.set.cnstr]{\tcode{unordered_set} constructors} +\pnum +\tcode{default_accessor} meets the accessor policy requirements. -\indexlibrary{\idxcode{unordered_set}!\idxcode{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()); -\end{itemdecl} +\pnum +\tcode{ElementType} is required to be a complete object type +that is neither an abstract class type nor an array type. -\begin{itemdescr} \pnum -\effects Constructs an empty \tcode{unordered_set} using the -specified hash function, key equality function, and allocator, and -using at least \tcode{n} buckets. For the default constructor, -the number of buckets is \impldef{default number of buckets in -\tcode{unordered_set}}. \tcode{max_load_factor()} returns 1.0. +Each specialization of \tcode{default_accessor} is +a trivially copyable type that models \libconcept{semiregular}. \pnum -\complexity Constant. -\end{itemdescr} +$[0, n)$ is an accessible range for +an object \tcode{p} of type \tcode{data_handle_type} and +an object of type \tcode{default_accessor} +if and only if \range{p}{p + $n$} is a valid range. -\indexlibrary{\idxcode{unordered_set}!\idxcode{unordered_set}}% +\rSec5[mdspan.accessor.default.members]{Members} + +\indexlibraryctor{default_accessor}% \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()); -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()); +template + constexpr default_accessor(default_accessor) noexcept {} \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an empty \tcode{unordered_set} using the -specified hash function, key equality function, and allocator, and -using at least \tcode{n} buckets. If \tcode{n} is not -provided, the number of buckets is \impldef{default number of buckets in -\tcode{unordered_set}}. Then -inserts elements from the range \range{f}{l} -for the first form, or from the range -\range{il.begin()}{il.end()} for the second form. -\tcode{max_load_factor()} returns 1.0. - -\pnum -\complexity Average case linear, worst case quadratic. +\constraints +\tcode{is_convertible_v} +is \tcode{true}. \end{itemdescr} -\rSec3[unord.set.swap]{\tcode{unordered_set} swap} - -\indexlibrary{\idxcode{unordered_set}!\idxcode{swap}}% -\indexlibrary{\idxcode{swap}!\idxcode{unordered_set}}% +\indexlibrarymember{access}{default_accessor}% \begin{itemdecl} -template - void swap(unordered_set& x, - unordered_set& y) - noexcept(noexcept(x.swap(y))); +constexpr reference access(data_handle_type p, size_t i) const noexcept; \end{itemdecl} \begin{itemdescr} -\pnum\effects \tcode{x.swap(y)}. +\pnum +\effects +Equivalent to: \tcode{return p[i];} \end{itemdescr} -\rSec2[unord.multiset]{Class template \tcode{unordered_multiset}}% -\indexlibrary{\idxcode{unordered_multiset}} - -\rSec3[unord.multiset.overview]{Class template \tcode{unordered_multiset} overview} +\indexlibrarymember{offset}{default_accessor}% +\begin{itemdecl} +constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -\indextext{\idxcode{unordered_multiset}!equivalent keys}% -\indextext{unordered associative containers!equivalent keys}% -An \tcode{unordered_multiset} is an unordered associative container -that supports equivalent keys (an instance of \tcode{unordered_multiset} may contain -multiple copies of the same key value) and in which each element's key -is the element itself. -The \tcode{unordered_multiset} class -supports forward iterators. +\effects +Equivalent to: \tcode{return p + i;} +\end{itemdescr} -\pnum -An \tcode{unordered_multiset} satisfies all of the requirements of a container, of an -unordered associative container, and of an allocator-aware container -(Table~\ref{tab:containers.allocatoraware}). It provides the operations described in the -preceding requirements table for equivalent keys; that is, an \tcode{unordered_multiset} -supports the \tcode{a_eq} operations in that table, not the \tcode{a_uniq} operations. -For an \tcode{unordered_multiset} the \tcode{key type} and the value type are -both \tcode{Key}. The \tcode{iterator} and \tcode{const_iterator} types are both const -iterator types. It is unspecified whether they are the same type. +\rSec4[mdspan.accessor.aligned]{Class template \tcode{aligned_accessor}} -\pnum -This section only describes operations on \tcode{unordered_multiset} that -are not described in one of the requirement tables, or for which there -is additional semantic information. +\rSec5[mdspan.accessor.aligned.overview]{Overview} -\indexlibrary{\idxcode{unordered_multiset}}% \begin{codeblock} namespace std { - template , - class Pred = std::equal_to, - class Allocator = std::allocator > - class unordered_multiset - { - public: - // types - typedef Key key_type; - typedef Key value_type; - typedef Hash hasher; - typedef Pred key_equal; - typedef Allocator allocator_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef @\impdef@ size_type; - typedef @\impdef@ difference_type; - - typedef @\impdef@ iterator; - typedef @\impdef@ const_iterator; - typedef @\impdef@ local_iterator; - typedef @\impdef@ const_local_iterator; - - // construct/destroy/copy - unordered_multiset(); - 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()); - unordered_multiset(const unordered_multiset&); - unordered_multiset(unordered_multiset&&); - explicit unordered_multiset(const Allocator&); - unordered_multiset(const unordered_multiset&, const Allocator&); - unordered_multiset(unordered_multiset&&, const Allocator&); - 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) - : unordered_multiset(n, hasher(), key_equal(), a) { } - 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) - : 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) { } - 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) - : unordered_multiset(il, n, hf, key_equal(), a) { } - ~unordered_multiset(); - unordered_multiset& operator=(const unordered_multiset&); - unordered_multiset& operator=(unordered_multiset&&) - noexcept(allocator_traits::is_always_equal::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value); - unordered_multiset& operator=(initializer_list); - allocator_type get_allocator() const noexcept; + template + struct @\libglobal{aligned_accessor}@ { + 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*; - // size and capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + static constexpr size_t @\libmember{byte_alignment}{aligned_accessor}@ = ByteAlignment; - // 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 aligned_accessor() noexcept = default; + template + constexpr aligned_accessor( + aligned_accessor) noexcept; + template + constexpr explicit aligned_accessor(default_accessor) 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); - void insert(initializer_list); + template + constexpr operator default_accessor() const noexcept; - iterator erase(const_iterator position); - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; + constexpr reference access(data_handle_type p, size_t i) const noexcept; - void swap(unordered_multiset&) - noexcept(allocator_traits::is_always_equal::value && - noexcept(swap(declval(),declval())) && - noexcept(swap(declval(),declval()))); + constexpr typename offset_policy::data_handle_type offset( + data_handle_type p, size_t i) const noexcept; + }; +} +\end{codeblock} - // observers - hasher hash_function() const; - key_equal key_eq() const; +\pnum +\mandates +\begin{itemize} +\item \tcode{byte_alignment} is a power of two, and +\item \tcode{byte_alignment >= alignof(ElementType)} is \tcode{true}. +\end{itemize} - // lookup - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - size_type count(const key_type& k) const; - std::pair equal_range(const key_type& k); - std::pair equal_range(const key_type& k) const; +\pnum +\tcode{aligned_accessor} meets the accessor policy requirements. - // 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; - 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; +\pnum +\tcode{ElementType} is required to be a complete object type +that is neither an abstract class type nor an array type. - // 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); - }; +\pnum +Each specialization of \tcode{aligned_accessor} is +a trivially copyable type that models \libconcept{semiregular}. - template - void swap(unordered_multiset& x, - unordered_multiset& y) - noexcept(noexcept(x.swap(y))); +\pnum +\range{0}{$n$} is an accessible range +for an object \tcode{p} of type \tcode{data_handle_type} and +an object of type \tcode{aligned_accessor} if and only if +\begin{itemize} +\item +\range{p}{p + $n$} is a valid range, and, +\item +if $n$ is greater than zero, +then \tcode{is_sufficiently_aligned(p)} is \tcode{true}. +\end{itemize} - template - bool operator==(const unordered_multiset& a, - const unordered_multiset& b); - template - bool operator!=(const unordered_multiset& a, - const unordered_multiset& b); +\pnum +\begin{example} +The following function \tcode{compute} +uses \tcode{is_sufficiently_aligned} to check +whether a given \tcode{mdspan} with \tcode{default_accessor} has +a data handle with sufficient alignment +to be used with \tcode{aligned_accessor}. +If so, the function dispatches to +a function \tcode{compute_using_fourfold_overalignment} +that requires fourfold over-alignment of arrays, +but can therefore use hardware-specific instructions, +such as four-wide SIMD (Single Instruction Multiple Data) instructions. +Otherwise, \tcode{compute} dispatches to a +possibly less optimized function \tcode{compute_without_requiring_overalignment} +that has no over-alignment requirement. +\begin{codeblock} +void compute_using_fourfold_overalignment( + mdspan, layout_right, aligned_accessor> x); + +void compute_without_requiring_overalignment( + mdspan, layout_right> x); + +void compute(mdspan> x) { + constexpr auto byte_alignment = 4 * sizeof(float); + auto accessor = aligned_accessor{}; + auto x_handle = x.data_handle(); + + if (is_sufficiently_aligned(x_handle)) { + compute_using_fourfold_overalignment(mdspan{x_handle, x.mapping(), accessor}); + } else { + compute_without_requiring_overalignment(x); + } } \end{codeblock} +\end{example} -\rSec3[unord.multiset.cnstr]{\tcode{unordered_multiset} constructors} +\rSec5[mdspan.accessor.aligned.members]{Members} -\indexlibrary{\idxcode{unordered_multiset}!\idxcode{unordered_multiset}}% +\indexlibraryctor{aligned_accessor}% \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()); +template + constexpr aligned_accessor(aligned_accessor) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an empty \tcode{unordered_multiset} using the -specified hash function, key equality function, and allocator, and -using at least \tcode{n} buckets. For the default constructor, -the number of buckets is \impldef{default number of buckets in -\tcode{unordered_multiset}}. -\tcode{max_load_factor()} returns 1.0. +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} +is \tcode{true}. +\item +\tcode{OtherByteAlignment >= byte_alignment} is \tcode{true}. +\end{itemize} \pnum -\complexity Constant. +\effects +None. \end{itemdescr} -\indexlibrary{\idxcode{unordered_multiset}!\idxcode{unordered_multiset}}% +\indexlibraryctor{aligned_accessor}% \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()); -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()); +template + constexpr explicit aligned_accessor(default_accessor) noexcept; \end{itemdecl} \begin{itemdescr} -\pnum\effects -Constructs an empty \tcode{unordered_multiset} using the -specified hash function, key equality function, and allocator, and -using at least \tcode{n} buckets. If \tcode{n} is not -provided, the number of buckets is \impldef{default number of buckets in -\tcode{unordered_multiset}}. Then -inserts elements from the range \range{f}{l} -for the first form, or from the range -\range{il.begin()}{il.end()} for the second form. -\tcode{max_load_factor()} returns 1.0. +\pnum +\constraints +\tcode{is_convertible_v} +is \tcode{true}. -\pnum\complexity Average case linear, worst case quadratic. +\pnum +\effects +None. \end{itemdescr} -\rSec3[unord.multiset.swap]{\tcode{unordered_multiset} swap} - -\indexlibrary{\idxcode{unordered_multiset}!\idxcode{swap}}% -\indexlibrary{\idxcode{swap}!\idxcode{unordered_multiset}}% +\indexlibrarymember{access}{aligned_accessor}% \begin{itemdecl} -template - void swap(unordered_multiset& x, - unordered_multiset& y) - noexcept(noexcept(x.swap(y))); +constexpr reference access(data_handle_type p, size_t i) const noexcept; \end{itemdecl} \begin{itemdescr} -\pnum\effects \tcode{x.swap(y);} -\end{itemdescr} +\pnum +\expects +\range{0}{i + 1} is an accessible range for \tcode{p} and \tcode{*this}. -\indextext{unordered associative containers|)} +\pnum +\effects +Equivalent to: \tcode{return assume_aligned(p)[i];} +\end{itemdescr} -\rSec1[container.adaptors]{Container adaptors} +\indexlibrarymember{operator default_accessor}{aligned_accessor}% +\begin{itemdecl} +template + constexpr operator default_accessor() const noexcept; +\end{itemdecl} -\rSec2[container.adaptors.general]{In general} +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} +is \tcode{true}. \pnum -The headers \tcode{} and \tcode{} define the container adaptors -\tcode{queue}, \tcode{priority_queue}, and \tcode{stack}. +\effects +Equivalent to: \tcode{return \{\};} +\end{itemdescr} + +\indexlibrarymember{offset}{aligned_accessor}% +\begin{itemdecl} +constexpr typename offset_policy::data_handle_type + offset(data_handle_type p, size_t i) const noexcept; +\end{itemdecl} +\begin{itemdescr} \pnum -The container adaptors each take a \tcode{Container} template parameter, and each constructor takes -a \tcode{Container} reference argument. This container is copied into the \tcode{Container} member -of each adaptor. If the container takes an allocator, then a compatible allocator may be passed in -to the adaptor's constructor. Otherwise, normal copy or move construction is used for the container -argument. +\expects +\range{0}{i + 1} is an accessible range for \tcode{p} and \tcode{*this}. \pnum -For container adaptors, no \tcode{swap} function throws an exception unless that -exception is thrown by the swap of the adaptor's \tcode{Container} or -\tcode{Compare} object (if any). +\effects +Equivalent to: \tcode{return assume_aligned(p) + i;} +\end{itemdescr} -\rSec2[queue.syn]{Header \tcode{} synopsis}% -\indexlibrary{\idxhdr{queue}} +\rSec3[mdspan.mdspan]{Class template \tcode{mdspan}} -\begin{codeblock} -#include +\rSec4[mdspan.mdspan.overview]{Overview} +\pnum +\tcode{mdspan} is a view of a multidimensional array of elements. + +\begin{codeblock} namespace std { + template> + class @\libglobal{mdspan}@ { + public: + 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 @\libmember{extent}{mdspan}@(rank_type r) const noexcept { return extents().extent(r); } + + // \ref{mdspan.mdspan.cons}, constructors + constexpr mdspan(); + constexpr mdspan(const mdspan& rhs) = default; + constexpr mdspan(mdspan&& rhs) = default; + + template + constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts); + template + constexpr explicit(N != rank_dynamic()) + mdspan(data_handle_type p, span exts); + template + constexpr explicit(N != rank_dynamic()) + mdspan(data_handle_type p, const array& exts); + constexpr mdspan(data_handle_type p, const extents_type& ext); + constexpr mdspan(data_handle_type p, const mapping_type& m); + constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a); + + template + constexpr explicit(@\seebelow@) + mdspan(const mdspan& other); + + constexpr mdspan& operator=(const mdspan& rhs) = default; + constexpr mdspan& operator=(mdspan&& rhs) = default; + + // \ref{mdspan.mdspan.members}, members + template + constexpr reference operator[](OtherIndexTypes... indices) const; + template + constexpr reference operator[](span indices) const; + 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 - template > class queue; - template , - class Compare = less > - class priority_queue; - - template - bool operator==(const queue& x,const queue& y); - template - bool operator< (const queue& x,const queue& y); - template - bool operator!=(const queue& x,const queue& y); - template - bool operator> (const queue& x,const queue& y); - template - bool operator>=(const queue& x,const queue& y); - template - bool operator<=(const queue& x,const queue& y); - - template - void swap(queue& x, queue& y) noexcept(noexcept(x.swap(y))); - template - void swap(priority_queue& x, - priority_queue& y) noexcept(noexcept(x.swap(y))); + constexpr size_type size() const noexcept; + constexpr bool empty() const noexcept; + + friend constexpr void swap(mdspan& x, mdspan& y) noexcept; + + 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 @\libmember{is_always_unique}{mdspan}@() + { return mapping_type::is_always_unique(); } + static constexpr bool @\libmember{is_always_exhaustive}{mdspan}@() + { return mapping_type::is_always_exhaustive(); } + static constexpr bool @\libmember{is_always_strided}{mdspan}@() + { return mapping_type::is_always_strided(); } + + constexpr bool @\libmember{is_unique}{mdspan}@() const + { return @\exposid{map_}@.is_unique(); } + constexpr bool @\libmember{is_exhaustive}{mdspan}@() const + { return @\exposid{map_}@.is_exhaustive(); } + constexpr bool @\libmember{is_strided}{mdspan}@() const + { return @\exposid{map_}@.is_strided(); } + constexpr index_type @\libmember{stride}{mdspan}@(rank_type r) const + { return @\exposid{map_}@.stride(r); } + + private: + accessor_type @\exposid{acc_}@; // \expos + mapping_type @\exposid{map_}@; // \expos + data_handle_type @\exposid{ptr_}@; // \expos + }; + + template + requires (is_array_v && rank_v == 1) + mdspan(CArray&) + -> mdspan, extents>>; + + template + requires (is_pointer_v>) + mdspan(Pointer&&) + -> mdspan>, extents>; + + template + requires ((is_convertible_v && ...) && sizeof...(Integrals) > 0) + explicit mdspan(ElementType*, Integrals...) + -> mdspan...>>; + + template + mdspan(ElementType*, span) + -> mdspan>; + + template + mdspan(ElementType*, const array&) + -> mdspan>; + + template + mdspan(ElementType*, const extents&) + -> mdspan>; + + template + mdspan(ElementType*, const MappingType&) + -> mdspan; + + template + mdspan(typename AccessorType::data_handle_type, const MappingType&, + const AccessorType&) + -> mdspan; } \end{codeblock} -\rSec2[queue]{Class template \tcode{queue}} +\pnum +\mandates +\begin{itemize} +\item +\tcode{ElementType} is a complete object type +that is neither an abstract class type nor an array type, +\item +\tcode{Extents} is a specialization of \tcode{extents}, and +\item +\tcode{is_same_v} +is \tcode{true}. +\end{itemize} -\rSec3[queue.defn]{\tcode{queue} definition} +\pnum +\tcode{LayoutPolicy} shall meet +the layout mapping policy requirements\iref{mdspan.layout.policy.reqmts}, and +\tcode{AccessorPolicy} shall meet +the accessor policy requirements\iref{mdspan.accessor.reqmts}. \pnum -\indexlibrary{\idxcode{queue}}% -Any sequence container supporting operations -\tcode{front()}, -\tcode{back()}, -\tcode{push_back()} -and -\tcode{pop_front()} -can be used to instantiate -\tcode{queue}. -In particular, -\tcode{list}~(\ref{list}) -and -\tcode{deque}~(\ref{deque}) -can be used. +Each specialization \tcode{MDS} of \tcode{mdspan} models \libconcept{copyable} and +\begin{itemize} +\item +\tcode{is_nothrow_move_constructible_v} is \tcode{true}, +\item +\tcode{is_nothrow_move_assignable_v} is \tcode{true}, and +\item +\tcode{is_nothrow_swappable_v} is \tcode{true}. +\end{itemize} -\begin{codeblock} -namespace std { - template > - class queue { - public: - typedef typename Container::value_type value_type; - typedef typename Container::reference reference; - typedef typename Container::const_reference const_reference; - typedef typename Container::size_type size_type; - typedef Container container_type; - protected: - Container c; +\pnum +A specialization of \tcode{mdspan} is a trivially copyable type if +its \tcode{accessor_type}, \tcode{mapping_type}, and \tcode{data_handle_type} +are trivially copyable types. - public: - explicit queue(const Container&); - explicit queue(Container&& = Container()); - 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&); - - 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 void emplace(Args&&... args) - { c.emplace_back(std::forward(args)...); } - void pop() { c.pop_front(); } - void swap(queue& q) noexcept(noexcept(swap(c, q.c))) - { using std::swap; swap(c, q.c); } - }; +\rSec4[mdspan.mdspan.cons]{Constructors} - template - bool operator==(const queue& x, const queue& y); - template - bool operator< (const queue& x, const queue& y); - template - bool operator!=(const queue& x, const queue& y); - template - bool operator> (const queue& x, const queue& y); - template - bool operator>=(const queue& x, const queue& y); - template - bool operator<=(const queue& x, const queue& y); - - template - void swap(queue& x, queue& y) noexcept(noexcept(x.swap(y))); - - template - struct uses_allocator, Alloc> - : uses_allocator::type { }; -} -\end{codeblock} +\indexlibraryctor{mdspan}% +\begin{itemdecl} +constexpr mdspan(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +\tcode{rank_dynamic() > 0} is \tcode{true}. +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +$[0, \tcode{\exposid{map_}.required_span_size()})$ is +an accessible range of \exposid{ptr_} and \exposid{acc_} +for the values of \exposid{map_} and \exposid{acc_} +after the invocation of this constructor. + +\pnum +\effects +Value-initializes \exposid{ptr_}, \exposid{map_}, and \exposid{acc_}. +\end{itemdescr} + +\indexlibraryctor{mdspan}% +\begin{itemdecl} +template + constexpr explicit mdspan(data_handle_type p, OtherIndexTypes... exts); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{N} be \tcode{sizeof...(OtherIndexTypes)}. -\rSec3[queue.cons]{\tcode{queue} constructors} +\pnum +\constraints +\begin{itemize} +\item +\tcode{(is_convertible_v \&\& ...)} is \tcode{true}, +\item +\tcode{(is_nothrow_constructible_v \&\& ...)} is \tcode{true}, +\item +\tcode{N == rank() || N == rank_dynamic()} is \tcode{true}, +\item +\tcode{is_constructible_v} is \tcode{true}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +$[0, \tcode{\exposid{map_}.required_span_size()})$ is +an accessible range of \tcode{p} and \exposid{acc_} +for the values of \exposid{map_} and \exposid{acc_} +after the invocation of this constructor. + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{std::move(p)}, +\item +direct-non-list-initializes \exposid{map_} with +\tcode{extents_type(static_cast(std::move(exts\brk{}))...)}, and +\item +value-initializes \exposid{acc_}. +\end{itemize} +\end{itemdescr} +\indexlibraryctor{mdspan}% \begin{itemdecl} -explicit queue(const Container& cont); +template + constexpr explicit(N != rank_dynamic()) + mdspan(data_handle_type p, span exts); +template + constexpr explicit(N != rank_dynamic()) + mdspan(data_handle_type p, const array& exts); \end{itemdecl} \begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{cont}. +\constraints +\begin{itemize} +\item +\tcode{is_convertible_v} is \tcode{true}, +\item +\tcode{is_nothrow_constructible_v} is \tcode{true}, +\item +\tcode{N == rank() || N == rank_dynamic()} is \tcode{true}, +\item +\tcode{is_constructible_v} is \tcode{true}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +$[0, \tcode{\exposid{map_}.required_span_size()})$ is +an accessible range of \tcode{p} and \exposid{acc_} +for the values of \exposid{map_} and \exposid{acc_} +after the invocation of this constructor. + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{std::move(p)}, +\item +direct-non-list-initializes \exposid{map_} with \tcode{extents_type(exts)}, and +\item +value-initializes \exposid{acc_}. +\end{itemize} \end{itemdescr} +\indexlibraryctor{mdspan}% \begin{itemdecl} -explicit queue(Container&& cont = Container()); +constexpr mdspan(data_handle_type p, const extents_type& ext); \end{itemdecl} \begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{std::move(cont)}. +\constraints +\begin{itemize} +\item +\tcode{is_constructible_v} is \tcode{true}, and +\item +\tcode{is_default_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +$[0, \tcode{\exposid{map_}.required_span_size()})$ is +an accessible range of \tcode{p} and \exposid{acc_} +for the values of \exposid{map_} and \exposid{acc_} +after the invocation of this constructor. + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{std::move(p)}, +\item +direct-non-list-initializes \exposid{map_} with \tcode{ext}, and +\item +value-initializes \exposid{acc_}. +\end{itemize} \end{itemdescr} -\rSec3[queue.cons.alloc]{\tcode{queue} constructors with allocators} +\indexlibraryctor{mdspan}% +\begin{itemdecl} +constexpr mdspan(data_handle_type p, const mapping_type& m); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_default_constructible_v} is \tcode{true}. \pnum -If \tcode{uses_allocator::value} is \tcode{false} -the constructors in this subclause shall not participate in overload resolution. +\expects +$[0, \tcode{m.required_span_size()})$ is +an accessible range of \tcode{p} and \exposid{acc_} +for the value of \exposid{acc_} after the invocation of this constructor. + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{std::move(p)}, +\item +direct-non-list-initializes \exposid{map_} with \tcode{m}, and +\item +value-initializes \exposid{acc_}. +\end{itemize} +\end{itemdescr} +\indexlibraryctor{mdspan}% \begin{itemdecl} -template - explicit queue(const Alloc& a); +constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a); \end{itemdecl} \begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{a}. +\expects +$[0, \tcode{m.required_span_size()})$ is +an accessible range of \tcode{p} and \tcode{a}. + +\pnum +\effects +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{std::move(p)}, +\item +direct-non-list-initializes \exposid{map_} with \tcode{m}, and +\item +direct-non-list-initializes \exposid{acc_} with \tcode{a}. +\end{itemize} \end{itemdescr} +\indexlibraryctor{mdspan}% \begin{itemdecl} -template - queue(const container_type& cont, const Alloc& a); +template + constexpr explicit(@\seebelow@) + mdspan(const mdspan& other); \end{itemdecl} \begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{cont} as the first argument and \tcode{a} -as the second argument. +\constraints +\begin{itemize} +\item +\tcode{is_constructible_v\&>} +is \tcode{true}, and +\item +\tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\mandates +\begin{itemize} +\item +\tcode{is_constructible_v} is\newline \tcode{true}, and +\item +\tcode{is_constructible_v} is \tcode{true}. +\end{itemize} + +\pnum +\expects +$[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. + +\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 +\begin{itemize} +\item +Direct-non-list-initializes \exposid{ptr_} with \tcode{other.\exposid{ptr_}}, +\item +direct-non-list-initializes \exposid{map_} with \tcode{other.\exposid{map_}}, and +\item +direct-non-list-initializes \exposid{acc_} with \tcode{other.\exposid{acc_}}. +\end{itemize} + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!is_convertible_v&, mapping_type> +|| !is_convertible_v +\end{codeblock} \end{itemdescr} +\rSec4[mdspan.mdspan.members]{Members} + +\indexlibrarymember{operator[]}{mdspan}% \begin{itemdecl} -template - queue(container_type&& cont, const Alloc& a); +template + constexpr reference operator[](OtherIndexTypes... indices) const; \end{itemdecl} \begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{std::move(cont)} as the first argument and \tcode{a} -as the second argument. +\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 +\hardexpects +\tcode{I} is a multidimensional index in \tcode{extents()}. +\begin{note} +This implies that +\tcode{\exposid{map_}(I) < \exposid{map_}.required_span_size()} +is \tcode{true}. +\end{note} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +return @\exposid{acc_}@.access(@\exposid{ptr_}@, @\exposid{map_}@(static_cast(std::move(indices))...)); +\end{codeblock} \end{itemdescr} +\indexlibrarymember{operator[]}{mdspan}% \begin{itemdecl} -template - queue(const queue& q, const Alloc& a); +template + constexpr reference operator[](span indices) const; +template + constexpr reference operator[](const array& indices) const; \end{itemdecl} \begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{q.c} as the first argument and \tcode{a} as the -second argument. +\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 operator[](extents_type::@\exposid{index-cast}@(as_const(indices[P]))...); +\end{codeblock} \end{itemdescr} +\indexlibrarymember{at}{mdspan}% \begin{itemdecl} -template - queue(queue&& q, const Alloc& a); +template + constexpr reference at(OtherIndexTypes... indices) const; \end{itemdecl} \begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{std::move(q.c)} as the first argument and \tcode{a} -as the second argument. -\end{itemdescr} - -\rSec3[queue.ops]{\tcode{queue} operators} +\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} -\indexlibrary{\idxcode{operator==}!\idxcode{queue}}% -\begin{itemdecl} -template - bool operator==(const queue& x, - const queue& y); -\end{itemdecl} +\pnum +Let \tcode{I} be \tcode{extents_type::\exposid{index-cast}(std::move(indices))}. -\begin{itemdescr} \pnum \returns -\tcode{x.c == y.c}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator"!=}!\idxcode{queue}}% -\begin{itemdecl} -template - bool operator!=(const queue& x, - const queue& y); -\end{itemdecl} +\tcode{(*this)[I...]}. -\begin{itemdescr} \pnum -\returns -\tcode{x.c != y.c}. +\throws +\tcode{out_of_range} if \tcode{I} is not a multidimensional index in \tcode{extents()}. \end{itemdescr} -\indexlibrary{\idxcode{operator<}!\idxcode{queue}}% +\indexlibrarymember{at}{mdspan}% \begin{itemdecl} -template - bool operator< (const queue& x, - const queue& y); +template + constexpr reference at(span indices) const; +template + constexpr reference at(const array& indices) const; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{x.c < y.c}. +\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} -\indexlibrary{\idxcode{operator<=}!\idxcode{queue}}% +\indexlibrarymember{size}{mdspan}% \begin{itemdecl} -template - bool operator<=(const queue& x, - const queue& y); +constexpr size_type size() const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\expects +The size of the multidimensional index space \tcode{extents()} +is representable as a value of type \tcode{size_type}\iref{basic.fundamental}. + \pnum \returns -\tcode{x.c <= y.c}. +\tcode{extents().\exposid{fwd-prod-of-extents}(rank())}. \end{itemdescr} -\indexlibrary{\idxcode{operator>}!\idxcode{queue}}% +\indexlibrarymember{empty}{mdspan}% \begin{itemdecl} -template - bool operator> (const queue& x, - const queue& y); +constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{x.c > y.c}. +\tcode{true} +if the size of the multidimensional index space \tcode{extents()} is 0, +otherwise \tcode{false}. \end{itemdescr} -\indexlibrary{\idxcode{operator>=}!\idxcode{queue}}% +\indexlibrarymember{swap}{mdspan}% \begin{itemdecl} -template - bool operator>=(const queue& x, - const queue& y); +friend constexpr void swap(mdspan& x, mdspan& y) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{x.c >= y.c}. +\effects +Equivalent to: +\begin{codeblock} +swap(x.@\exposid{ptr_}@, y.@\exposid{ptr_}@); +swap(x.@\exposid{map_}@, y.@\exposid{map_}@); +swap(x.@\exposid{acc_}@, y.@\exposid{acc_}@); +\end{codeblock} \end{itemdescr} -\rSec3[queue.special]{\tcode{queue} specialized algorithms} +\rSec3[mdspan.sub]{\tcode{submdspan}} -\indexlibrary{\idxcode{swap}!\idxcode{queue}}% -\indexlibrary{\idxcode{queue}!\idxcode{swap}}% -\begin{itemdecl} -template - void swap(queue& x, queue& y) noexcept(noexcept(x.swap(y))); -\end{itemdecl} +\rSec4[mdspan.sub.overview]{Overview} -\begin{itemdescr} \pnum -\effects \tcode{x.swap(y)}. -\end{itemdescr} - -\rSec2[priority.queue]{Class template \tcode{priority_queue}} +The \tcode{submdspan} facilities create a new \tcode{mdspan} +viewing a subset of elements of an existing input \tcode{mdspan}. +The subset viewed by the created \tcode{mdspan} is determined by +the \tcode{SliceSpecifier} arguments. \pnum -\indexlibrary{\idxcode{priority_queue}}% -Any sequence container with random access iterator and supporting operations -\tcode{front()}, -\tcode{push_back()} -and -\tcode{pop_back()} -can be used to instantiate -\tcode{priority_queue}. -In particular, -\tcode{vector}~(\ref{vector}) -and -\tcode{deque}~(\ref{deque}) -can be used. -Instantiating -\tcode{priority_queue} -also involves supplying a function or function object for making -priority comparisons; the library assumes that the function or function -object defines a strict weak ordering~(\ref{alg.sorting}). +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} -\begin{codeblock} -namespace std { - template , - class Compare = less > - class priority_queue { - public: - typedef typename Container::value_type value_type; - typedef typename Container::reference reference; - typedef typename Container::const_reference const_reference; - typedef typename Container::size_type size_type; - typedef Container container_type; - protected: - Container c; - Compare comp; +\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. - public: - priority_queue(const Compare& x, const Container&); - explicit priority_queue(const Compare& x = Compare(), Container&& = Container()); - template - priority_queue(InputIterator first, InputIterator last, - const Compare& x, const Container&); - template - priority_queue(InputIterator first, InputIterator last, - const Compare& x = Compare(), Container&& = Container()); - 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&); - - 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); - template void emplace(Args&&... args); - void pop(); - void swap(priority_queue& q) noexcept( - noexcept(swap(c, q.c)) && noexcept(swap(comp, q.comp))) - { using std::swap; swap(c, q.c); swap(comp, q.comp); } - }; - // no equality is provided - template - void swap(priority_queue& x, - priority_queue& y) noexcept(noexcept(x.swap(y))); +\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} - template - struct uses_allocator, Alloc> - : uses_allocator::type { }; -} -\end{codeblock} +\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} -\rSec3[priqueue.cons]{\tcode{priority_queue} constructors} +\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} -\indexlibrary{\idxcode{priority_queue}!\idxcode{priority_queue}}% -\begin{itemdecl} -priority_queue(const Compare& x, - const Container& y); -explicit priority_queue(const Compare& x = Compare(), - Container&& y = Container()); -\end{itemdecl} +\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} -\begin{itemdescr} \pnum -\requires -\tcode{x} shall define a strict weak ordering~(\ref{alg.sorting}). +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 + if \tcode{S} is a specialization of \tcode{extent_slice}, then + \begin{itemize} + \item + $o$ is less than or equal to $x$; + \item + $e$ is less than or equal to $x$; + \item + 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} + where + \begin{itemize} + \item + $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 + $e$ is the value of \tcode{S::extent_type::value} + if \tcode{S::extend_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 -\effects -Initializes -\tcode{comp} with -\tcode{x} and -\tcode{c} with -\tcode{y} (copy constructing or move constructing as appropriate); -calls -\tcode{make_heap(c.begin(), c.end(), comp)}. -\end{itemdescr} +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} -\indexlibrary{\idxcode{priority_queue}!\idxcode{priority_queue}}% -\begin{itemdecl} -template - priority_queue(InputIterator first, InputIterator last, - const Compare& x, - const Container& y); -template - priority_queue(InputIterator first, InputIterator last, - const Compare& x = Compare(), - Container&& y = Container()); -\end{itemdecl} +\rSec4[mdspan.sub.range.slices]{Range slices} -\begin{itemdescr} \pnum -\requires -\tcode{x} shall define a strict weak ordering~(\ref{alg.sorting}). +\tcode{extent_slice} and \tcode{range_slice} represent a set of +\tcode{extent} regularly spaced integer indices. +The indices start at \tcode{offset} and \tcode{first}, respectively, and +increase by increments of \tcode{stride}. -\pnum -\effects -Initializes -\tcode{comp} with -\tcode{x} and -\tcode{c} with -\tcode{y} (copy constructing or move constructing as appropriate); -calls -\tcode{c.insert(c.end(), first, last)}; -and finally calls -\tcode{make_heap(c.begin(), c.end(), comp)}. -\end{itemdescr} +\indexlibraryglobal{extent_slice}% +\indexlibraryglobal{range_slice}% +\begin{codeblock} +namespace std { + template + 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}@{}; + }; -\rSec3[priqueue.cons.alloc]{\tcode{priority_queue} constructors with allocators} + 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 -If \tcode{uses_allocator::value} is \tcode{false} -the constructors in this subclause shall not participate in overload resolution. - -\begin{itemdecl} -template - explicit priority_queue(const Alloc& a); -\end{itemdecl} +\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. -\begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{a} and value-initializes \tcode{comp}. -\end{itemdescr} +\mandates +\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} +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} -\begin{itemdecl} -template - priority_queue(const Compare& compare, const Alloc& a); -\end{itemdecl} +\rSec4[mdspan.sub.map.result]{\tcode{submdspan_mapping_result}} -\begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{a} and initializes \tcode{comp} with \tcode{compare}. -\end{itemdescr} +Specializations of \tcode{submdspan_mapping_result} +are returned by overloads of \tcode{submdspan_mapping}. -\begin{itemdecl} -template - priority_queue(const Compare& compare, const Container& cont, const Alloc& a); -\end{itemdecl} +\indexlibraryglobal{submdspan_mapping_result}% +\begin{codeblock} +namespace std { + template + struct submdspan_mapping_result { + [[no_unique_address]] LayoutMapping @\libmember{mapping}{submdspan_mapping_result}@ = LayoutMapping(); + size_t @\libmember{offset}{submdspan_mapping_result}@{}; + }; +} +\end{codeblock} -\begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{cont} as the first argument and \tcode{a} as the second -argument, and initializes \tcode{comp} with \tcode{compare}. -\end{itemdescr} +\tcode{submdspan_mapping_result} has +the data members and special members specified above. +It has no base classes or members other than those specified. -\begin{itemdecl} -template - priority_queue(const Compare& compare, Container&& cont, const Alloc& a); -\end{itemdecl} +\pnum +\tcode{LayoutMapping} shall meet +the layout mapping requirements\iref{mdspan.layout.policy.reqmts}. + +\rSec4[mdspan.sub.helpers]{Exposition-only helpers} -\begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{std::move(cont)} as the first argument and \tcode{a} -as the second argument, and initializes \tcode{comp} with \tcode{compare}. -\end{itemdescr} +\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 - priority_queue(const priority_queue& q, const Alloc& a); +template + concept @\defexposconcept{is-extent-slice}@ = @\seebelow;@ \end{itemdecl} \begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{q.c} as the first argument and \tcode{a} as -the second argument, and initializes \tcode{comp} with \tcode{q.comp}. +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} \begin{itemdecl} -template - priority_queue(priority_queue&& q, const Alloc& a); +template + concept @\defexposconcept{is-range-slice}@ = @\seebelow;@ \end{itemdecl} \begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{std::move(q.c)} as the first argument and \tcode{a} -as the second argument, and initializes \tcode{comp} with \tcode{std::move(q.comp)}. +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} -\rSec3[priqueue.members]{\tcode{priority_queue} members} - -\indexlibrary{\idxcode{push}!\tcode{priority_queue}}% +\indexlibraryglobal{\exposid{canonical-index}}% \begin{itemdecl} -void push(const value_type& x); +template + constexpr auto @\exposid{canonical-index}@(S s); \end{itemdecl} \begin{itemdescr} \pnum -\effects -\begin{codeblock} -c.push_back(x); -push_heap(c.begin(), c.end(), comp); -\end{codeblock} -\end{itemdescr} +\mandates +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}. -\indexlibrary{\idxcode{push}!\tcode{priority_queue}}% -\begin{itemdecl} -void push(value_type&& x); -\end{itemdecl} +\pnum +\expects +\tcode{extents::\exposid{index-cast}(std::move(s))} +is representable as a value of type \tcode{IndexType}. -\begin{itemdescr} \pnum \effects -\begin{codeblock} -c.push_back(std::move(x)); -push_heap(c.begin(), c.end(), comp); -\end{codeblock} +Equivalent to: +\begin{itemize} +\item +\tcode{return cw;} +if \tcode{S} models \exposconcept{integral-constant-like}; +\item +\tcode{return IndexType(std::move(s));} otherwise. +\end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{emplace}!\idxcode{priority_queue}}% -\indexlibrary{\idxcode{priority_queue}!\idxcode{emplace}}% \begin{itemdecl} -template void emplace(Args&&... args) +template + constexpr auto @\exposid{canonical-range-slice}@(OffsetType offset, SpanType span, StrideTypes... strides); \end{itemdecl} \begin{itemdescr} \pnum -\effects -\begin{codeblock} -c.emplace_back(std::forward(args)...); -push_heap(c.begin(), c.end(), comp); -\end{codeblock} -\end{itemdescr} +Let +\begin{itemize} +\item + \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}. -\indexlibrary{\idxcode{pop}!\tcode{priority_queue}}% -\begin{itemdecl} -void pop(); -\end{itemdecl} +\pnum +\expects +\tcode{stride > 0} is \tcode{true}. -\begin{itemdescr} \pnum -\effects -\begin{codeblock} -pop_heap(c.begin(), c.end(), comp); -c.pop_back(); -\end{codeblock} +\returns +\tcode{extent_slice\{.offset = offset, .extent = extent, .stride = stride\}}. \end{itemdescr} -\rSec3[priqueue.special]{\tcode{priority_queue} specialized algorithms} - -\indexlibrary{\idxcode{swap}!\idxcode{priority_queue}}% -\indexlibrary{\idxcode{priority_queue}!\idxcode{swap}}% +\indexlibraryglobal{\exposid{canonical-slice}} \begin{itemdecl} -template - void swap(priority_queue& x, - priority_queue& y) noexcept(noexcept(x.swap(y))); +template + constexpr auto @\exposid{canonical-slice}@(S s); \end{itemdecl} \begin{itemdescr} -\pnum -\effects \tcode{x.swap(y)}. -\end{itemdescr} - -\rSec2[stack]{Class template \tcode{stack}} - -\pnum -\indexlibrary{\idxcode{stack}}% -Any sequence container supporting operations -\tcode{back()}, -\tcode{push_back()} -and -\tcode{pop_back()} -can be used to instantiate -\tcode{stack}. -In particular, -\tcode{vector}~(\ref{vector}), -\tcode{list}~(\ref{list}) -and -\tcode{deque}~(\ref{deque}) -can be used. - -\rSec3[stack.syn]{Header \tcode{} synopsis}% -\indexlibrary{\idxhdr{stack}} - -\begin{codeblock} -#include - -namespace std { - - template > class stack; - template - bool operator==(const stack& x,const stack& y); - template - bool operator< (const stack& x,const stack& y); - template - bool operator!=(const stack& x,const stack& y); - template - bool operator> (const stack& x,const stack& y); - template - bool operator>=(const stack& x,const stack& y); - template - bool operator<=(const stack& x,const stack& y); - template - void swap(stack& x, stack& y) noexcept(noexcept(x.swap(y))); -} -\end{codeblock} - -\rSec3[stack.defn]{\tcode{stack} definition} - -\begin{codeblock} -namespace std { - template > - class stack { - public: - typedef typename Container::value_type value_type; - typedef typename Container::reference reference; - typedef typename Container::const_reference const_reference; - typedef typename Container::size_type size_type; - typedef Container container_type; - protected: - Container c; - - public: - explicit stack(const Container&); - explicit stack(Container&& = Container()); - 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&); - - 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)); } - template void emplace(Args&&... args) - { c.emplace_back(std::forward(args)...); } - void pop() { c.pop_back(); } - void swap(stack& s) noexcept(noexcept(swap(c, s.c))) - { using std::swap; swap(c, s.c); } - }; +\pnum +\mandates +\tcode{S} is a \tcode{submdspan} slice type for \tcode{IndexType}. - template - bool operator==(const stack& x, const stack& y); - template - bool operator< (const stack& x, const stack& y); - template - bool operator!=(const stack& x, const stack& y); - template - bool operator> (const stack& x, const stack& y); - template - bool operator>=(const stack& x, const stack& y); - template - bool operator<=(const stack& x, const stack& y); - template - void swap(stack& x, stack& y) noexcept(noexcept(x.swap(y))); - - template - struct uses_allocator, Alloc> - : uses_allocator::type { }; +\pnum +\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.extent)), + .extent = @\exposid{canonical-index}@(std::move(s.offset)), + .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} -\rSec3[stack.cons]{\tcode{stack} constructors} +\rSec4[mdspan.sub.canonical]{\tcode{submdspan} slice canonicalization} +\indexlibraryglobal{canonical_slices}% \begin{itemdecl} -explicit stack(const Container& cont); +template + constexpr auto canonical_slices(const extents& src, + SliceSpecifiers... slices); \end{itemdecl} \begin{itemdescr} \pnum -\effects Initializes \tcode{c} with \tcode{cont}. +\constraints +\tcode{sizeof...(SliceSpecifiers)} equals \tcode{sizeof...(Extents)}. + +\pnum +\mandates +For each rank index $k$ of \tcode{src}: +\begin{itemize} +\item + \tcode{SliceSpecifiers...[k]} + is a \tcode{submdspan} slice type for \tcode{IndexType}, and +\item + \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{subextents} function} + +\indexlibraryglobal{subextents}% \begin{itemdecl} -explicit stack(Container&& cont = Container()); +template + constexpr auto subextents(const extents& src, + SliceSpecifiers... raw_slices); \end{itemdecl} \begin{itemdescr} \pnum -\effects Initializes \tcode{c} with \tcode{std::move(cont)}. -\end{itemdescr} +Let \tcode{slices} be the pack introduced by the following declaration: +\begin{codeblock} +auto [...slices] = canonical_slices(src, raw_slices...); +\end{codeblock} -\rSec3[stack.cons.alloc]{\tcode{stack} constructors with allocators} +\pnum +\constraints +\tcode{sizeof...(SliceSpecifiers)} equals \tcode{sizeof...(Extents)}. \pnum -If \tcode{uses_allocator::value} is \tcode{false} -the constructors in this subclause shall not participate in overload resolution. +\mandates +For each rank index $k$ of \tcode{src}: +\begin{itemize} +\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} -\begin{itemdecl} -template - explicit stack(const Alloc& a); -\end{itemdecl} +\pnum +\expects +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}. -\begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{a}. -\end{itemdescr} +Let \tcode{SubExtents} be a specialization of \tcode{extents} such that: -\begin{itemdecl} -template - stack(const container_type& cont, const Alloc& a); -\end{itemdecl} +\begin{itemize} +\item +\tcode{SubExtents::rank()} equals +\tcode{\placeholder{MAP_RANK}(slices, Extents::rank())}; and + +\item +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 $\Sigma_k$ denotes \tcode{full_extent_t}; + otherwise + + \item + \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, + \tcode{dynamic_extent}. + \end{itemize} +\end{itemize} -\begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{cont} as the first argument and \tcode{a} as the -second argument. +\returns +A value \tcode{ext} of type \tcode{SubExtents} such that +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{$\sigma_k$.extent} + if the type of $\sigma_k$ is a specialization of \tcode{extent_slice}, +\item + 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} -\begin{itemdecl} -template - stack(container_type&& cont, const Alloc& a); -\end{itemdecl} +\rSec4[mdspan.sub.map]{Specializations of \tcode{submdspan_mapping}} + +\rSec5[mdspan.sub.map.sliceable]{Sliceable layout mapping requirements} -\begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{std::move(cont)} as the first argument and \tcode{a} -as the second argument. -\end{itemdescr} +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} -\begin{itemdecl} -template - stack(const stack& s, const Alloc& a); -\end{itemdecl} +\pnum +\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 +A type \tcode{M} meets the \defn{sliceable layout mapping requirements} if +\begin{itemize} +\item +\tcode{M} meets the layout mapping requirements\iref{mdspan.layout.policy.reqmts}, +\item +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 -\effects\ Initializes \tcode{c} with \tcode{s.c} as the first argument and \tcode{a} -as the second argument. +\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{smr.mapping.extents() == subextents(m.extents(), valid_slices...)} + is \tcode{true};\newline and +\item + 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 - stack(stack&& s, const Alloc& a); +template + concept @\defexposconcept{sliceable-mapping}@ = @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum -\effects\ Initializes \tcode{c} with \tcode{std::move(s.c)} as the first argument and \tcode{a} -as the second argument. +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 + the expression \tcode{submdspan_mapping(lm, fe...)} is well-formed + when treated as an unevaluated operand, and +\item + 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} -\rSec3[stack.ops]{\tcode{stack} operators} +\rSec5[mdspan.sub.map.common]{Common} -\indexlibrary{\idxcode{operator==}!\idxcode{stack}}% -\begin{itemdecl} -template - bool operator==(const stack& x, - const stack& y); -\end{itemdecl} +\pnum +The following elements apply to all functions in \ref{mdspan.sub.map}. -\begin{itemdescr} \pnum -\returns -\tcode{x.c == y.c}. -\end{itemdescr} +\constraints +\tcode{sizeof...(SliceSpecifiers)} equals \tcode{extents_type::rank()}. -\indexlibrary{\idxcode{operator"!=}!\idxcode{stack}}% +\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{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 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) * 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{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{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{required_span_size()}. +Otherwise, +let \tcode{offset} be a value of type \tcode{size_t} equal to +\tcode{operator()(ls...)}. + +\rSec5[mdspan.sub.map.left]{\tcode{layout_left} specialization of \tcode{submdspan_mapping}} + +\indexlibrarymemberexpos{layout_left::mapping}{submdspan-mapping-impl}% \begin{itemdecl} -template - bool operator!=(const stack& x, - const stack& y); +template +template +constexpr auto layout_left::mapping::@\exposid{submdspan-mapping-impl}@( + SliceSpecifiers... slices) const -> @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{x.c != y.c}. +\begin{itemize} +\item +\tcode{submdspan_mapping_result\{*this, 0\}}, +if \tcode{Extents::rank() == 0} is \tcode{true}; +\item +otherwise, +\tcode{submdspan_mapping_result\{layout_left::mapping(sub_ext), offset\}},\newline +if \tcode{SubEx\-tents::rank() == 0} is \tcode{true}; +\item +otherwise, +\tcode{submdspan_mapping_result\{layout_left::mapping(sub_ext), offset\}}, +if + \begin{itemize} + \item + 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}, + \tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; + \end{itemize} +\begin{note} +If the above conditions are true, +all \tcode{SliceSpecifiers...[$k$]} with $k$ larger than \tcode{SubExtents\brk{}::rank\brk{}() - 1} +are convertible to \tcode{index_type}. +\end{note} +\item +otherwise, +\begin{codeblock} +submdspan_mapping_result{layout_left_padded::mapping(sub_ext, stride(@$u$@ + 1)), + offset} +\end{codeblock} +if for a value $u$ for which $u+1$ is +the smallest value $p$ larger than zero +for which \tcode{SliceSpecifiers...\brk{}[\brk{}$p$]} is a unit-stride slice type, +the following conditions are met: +\begin{itemize} +\item +\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{SliceSpecifiers...[$k$]} denotes \tcode{full_extent_t}; and +\item +for $k$ equal to \tcode{$u$ + SubExtents::rank() - 1}, +\tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; +\end{itemize} +and where \tcode{S_static} is: +\begin{itemize} +\item +\tcode{dynamic_extent}, +if \tcode{static_extent($k$)} is \tcode{dynamic_extent} +for any $k$ in the range \range{0}{$u$ + 1}, +\item +otherwise, the product of all values +\tcode{static_extent($k$)} for $k$ in the range \range{0}{$u$ + 1}; +\end{itemize} +\item +otherwise, +\begin{codeblock} +submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset} +\end{codeblock} +\end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{operator<}!\idxcode{stack}}% +\rSec5[mdspan.sub.map.right]{\tcode{layout_right} specialization of \tcode{submdspan_mapping}} + +\indexlibrarymemberexpos{layout_right::mapping}{submdspan-mapping-impl}% \begin{itemdecl} -template - bool operator< (const stack& x, - const stack& y); +template +template +constexpr auto layout_right::mapping::@\exposid{submdspan-mapping-impl}@( + SliceSpecifiers... slices) const -> @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{x.c < y.c}. +\begin{itemize} +\item +\tcode{submdspan_mapping_result\{*this, 0\}}, +if \tcode{Extents::rank() == 0} is \tcode{true}; +\item +otherwise, +\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_right::mapping(sub_ext), offset\}}, +if + \begin{itemize} + \item + 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()}, + \tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; + \end{itemize} +\begin{note} +If the above conditions are true, +all \tcode{SliceSpecifiers...[$k$]} with\newline +$k < \tcode{\exposid{rank_} - SubExtents::rank()}$ +are convertible to \tcode{index_type}. +\end{note} +\item +otherwise, +\begin{codeblock} +submdspan_mapping_result{layout_right_padded::mapping(sub_ext, + stride(@\exposid{rank_}@ - @$u$@ - 2)), offset} +\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 \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}, +\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},\newline +\tcode{SliceSpecifiers...[$p$]} denotes \tcode{full_extent_t}; and +\item +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} +\item +\tcode{dynamic_extent}, +if \tcode{static_extent($k$)} is \tcode{dynamic_extent} +for any $k$ in the range \range{\exposid{rank_} - $u$ - 1}{\exposid{rank_}}, +\item +otherwise, the product of all values +\tcode{static_extent($k$)} +for $k$ in the range \range{\exposid{rank_} - $u$ - 1}{\exposid{rank_}}; +\end{itemize} +\item +otherwise, +\begin{codeblock} +submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset} +\end{codeblock} +\end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{operator<=}!\idxcode{stack}}% +\rSec5[mdspan.sub.map.stride]{\tcode{layout_stride} specialization of \tcode{submdspan_mapping}} + +\indexlibrarymemberexpos{layout_stride::mapping}{submdspan-mapping-impl}% \begin{itemdecl} -template - bool operator<=(const stack& x, - const stack& y); +template +template +constexpr auto layout_stride::mapping::@\exposid{submdspan-mapping-impl}@( + SliceSpecifiers... slices) const -> @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{x.c <= y.c}. +\begin{itemize} +\item +\tcode{submdspan_mapping_result\{*this, 0\}}, +if \tcode{Extents::rank() == 0} is \tcode{true}; +\item +otherwise, +\begin{codeblock} +submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset} +\end{codeblock} +\end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{operator>}!\idxcode{stack}}% +\rSec5[mdspan.sub.map.leftpad]{\tcode{layout_left_padded} specialization of \tcode{submdspan_mapping}} + +\indexlibrarymemberexpos{layout_left_padded::mapping}{submdspan-mapping-impl}% \begin{itemdecl} -template - bool operator> (const stack& x, - const stack& y); +template +template +constexpr auto layout_left_padded::mapping::@\exposid{submdspan-mapping-impl}@( + SliceSpecifiers... slices) const -> @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{x.c > y.c}. +\begin{itemize} +\item +\tcode{submdspan_mapping_result\{*this, 0\}}, +if \tcode{Extents::rank() == 0} is \tcode{true}; +\item +otherwise, +\tcode{submdspan_mapping_result\{layout_left::mapping(sub_ext), offset\}}, +if \tcode{\exposid{rank_} == 1} is \tcode{true} or +\tcode{SubExtents::rank() == 0} is \tcode{true}; +\item +otherwise, +\tcode{submdspan_mapping_result\{layout_left::mapping(sub_ext), offset\}}, +if +\begin{itemize} +\item +\tcode{SubExtents::rank() == 1} is \tcode{true} and +\item +\tcode{SliceSpecifiers...[0]} is a unit-stride slice type; +\end{itemize} +\item +otherwise, +\begin{codeblock} +submdspan_mapping_result{layout_left_padded::mapping(sub_ext, stride(@$u$@ + 1)), + offset} +\end{codeblock} +if for a value $u$ +for which \tcode{$u$ + 1} is the smallest value $p$ larger than zero +for which \tcode{Slice\-Speci\-fiers\brk{}...[\brk{}$p$]} is a unit-stride slice type, +the following conditions are met: +\begin{itemize} +\item +\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{SliceSpecifiers...[$k$]} denotes \tcode{full_extent_t}; and +\item +for $k$ equal to \tcode{$u$ + SubExtents::rank() - 1}, +\tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; +\end{itemize} +where \tcode{S_static} is: +\begin{itemize} +\item +\tcode{dynamic_extent}, +if \exposid{static-padding-stride} is \tcode{dynamic_extent} or +\tcode{static_extent($k$)} is \tcode{dynamic_extent} +for any $k$ in the range \range{1}{$u$ + 1}, +\item +otherwise, the product of \exposid{static-padding-stride} and +all values \tcode{static_extent($k$)} for $k$ in the range \range{1}{$u$ + 1}; +\end{itemize} +\item +otherwise, +\begin{codeblock} +submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset} +\end{codeblock} +\end{itemize} \end{itemdescr} -\indexlibrary{\idxcode{operator>=}!\idxcode{stack}}% +\rSec5[mdspan.sub.map.rightpad]{\tcode{layout_right_padded} specialization of \tcode{submdspan_mapping}} + +\indexlibrarymemberexpos{layout_right_padded::mapping}{submdspan-mapping-impl}% \begin{itemdecl} -template - bool operator>=(const stack& x, - const stack& y); +template +template +constexpr auto layout_right_padded::mapping::@\exposid{submdspan-mapping-impl}@( + SliceSpecifiers... slices) const -> @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{x.c >= y.c}. +\begin{itemize} +\item +\tcode{submdspan_mapping_result\{*this, 0\}}, +if \tcode{\exposid{rank_} == 0} is \tcode{true}; +\item +otherwise, +\tcode{submdspan_mapping_result\{layout_right::mapping(sub_ext), offset\}},\newline +if \tcode{\exposid{rank_} == 1} is \tcode{true} or +\tcode{SubExtents::rank() == 0} is \tcode{true}; +\item +otherwise, +\tcode{submdspan_mapping_result\{layout_right::mapping(sub_ext), offset\}}, +if +\begin{itemize} +\item +\tcode{SubExtents::rank() == 1} is \tcode{true} and +\item +for $k$ equal to \tcode{\exposid{rank_} - 1}, +\tcode{SliceSpecifiers...[$k$]} is a unit-stride slice type; +\end{itemize} +\item +otherwise, +\begin{codeblock} +submdspan_mapping_result{layout_right_padded::mapping(sub_ext, + stride(@\exposid{rank_}@ - @$u$@ - 2)), offset} +\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 \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}, +\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},\newline +\tcode{SliceSpecifiers...[$k$]} denotes \tcode{full_extent_t}; and +\item +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} +\item +\tcode{dynamic_extent} +if \exposid{static-padding-stride} is \tcode{dynamic_extent} or +for any $k$ in the range \range{\exposid{rank_} - $u$ - 1}{\exposid{rank_} - 1} +\tcode{static_extent($k$)} is \tcode{dynamic_extent}, +\item +otherwise, the product of \exposid{static-padding-stride} and +all values \tcode{static_extent($k$)} +with $k$ in the range \range{\exposid{rank_} - $u$ - 1}{\exposid{rank_} - 1}; +\end{itemize} +\item +otherwise, +\begin{codeblock} +submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset} +\end{codeblock} +\end{itemize} \end{itemdescr} -\rSec3[stack.special]{\tcode{stack} specialized algorithms} +\rSec4[mdspan.sub.sub]{\tcode{submdspan} function template} -\indexlibrary{\idxcode{swap}!\idxcode{stack}}% -\indexlibrary{\idxcode{stack}!\idxcode{swap}}% +\indexlibraryglobal{submdspan}% \begin{itemdecl} -template - void swap(stack& x, stack& y) noexcept(noexcept(x.swap(y))); +template + constexpr auto submdspan( + const mdspan& src, + SliceSpecifiers... raw_slices) -> @\seebelow@; \end{itemdecl} \begin{itemdescr} \pnum -\effects \tcode{x.swap(y)}. +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...)}. +\begin{note} +This invocation of \tcode{submdspan_mapping} +selects a function call via overload resolution +on a candidate set that includes the lookup set +found by argument-dependent lookup\iref{basic.lookup.argdep}. +\end{note} + +\pnum +\constraints +\begin{itemize} +\item +\tcode{sizeof...(slices)} equals \tcode{Extents::rank()}, and +\item +\tcode{LayoutPolicy::mapping} models \exposconcept{sliceable-mapping}. +\end{itemize} + +\pnum +\mandates +For each rank index $k$ of \tcode{src}: +\begin{itemize} +\item + \tcode{SliceSpecifiers...[$k$]} is a \tcode{submdspan} slice type + for \tcode{index_type}, and +\item + \tcode{decltype(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.extents()}, +\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_handle(), sub_map_result.offset), + sub_map_result.mapping, + typename AccessorPolicy::offset_policy(src.accessor())); +\end{codeblock} \end{itemdescr} + +\pnum +\begin{example} +Given a rank-3 \tcode{mdspan grid3d} representing a three-dimensional grid +of regularly spaced points in a rectangular prism, +the function \tcode{zero_surface} sets all elements on +the surface of the 3-dimensional shape to zero. +It does so by reusing a function \tcode{zero_2d} +that takes a rank-2 \tcode{mdspan}. + +\begin{codeblock} +// zero out all elements in an \tcode{mdspan} +template +void zero_2d(mdspan a) { + static_assert(a.rank() == 2); + for (int i = 0; i < a.extent(0); i++) + for (int j = 0; j < a.extent(1); j++) + a[i, j] = 0; +} + +// zero out just the surface +template +void zero_surface(mdspan grid3d) { + static_assert(grid3d.rank() == 3); + zero_2d(submdspan(grid3d, 0, full_extent, full_extent)); + zero_2d(submdspan(grid3d, full_extent, 0, full_extent)); + zero_2d(submdspan(grid3d, full_extent, full_extent, 0)); + zero_2d(submdspan(grid3d, grid3d.extent(0) - 1, full_extent, full_extent)); + zero_2d(submdspan(grid3d, full_extent, grid3d.extent(1) - 1, full_extent)); + zero_2d(submdspan(grid3d, full_extent, full_extent, grid3d.extent(2) - 1)); +} +\end{codeblock} +\end{example} diff --git a/source/conversions.tex b/source/conversions.tex deleted file mode 100644 index ed81a23eba..0000000000 --- a/source/conversions.tex +++ /dev/null @@ -1,609 +0,0 @@ -%!TEX root = std.tex -\rSec0[conv]{Standard conversions} - -\indextext{implicit~conversion|see{conversion, implicit}} -\indextext{contextually converted to bool|see{conversion, contextual}} -\indextext{rvalue!lvalue conversion to|see{conversion, lvalue to rvalue}}% - -\pnum -\indextext{conversion!standard|(}% -\indextext{conversion!implicit}% -Standard conversions are implicit conversions with built-in meaning. -Clause~\ref{conv} enumerates the full set of such conversions. A -\indextext{sequence!standard conversion}% -\term{standard conversion sequence} is a sequence of standard -conversions in the following order: - -\begin{itemize} -\item Zero or one conversion from the following set: lvalue-to-rvalue -conversion, array-to-pointer conversion, and function-to-pointer -conversion. - -\item Zero or one conversion from the following set: integral -promotions, floating point promotion, integral conversions, floating -point conversions, floating-integral conversions, pointer conversions, -pointer to member conversions, and boolean conversions. - -\item Zero or one qualification conversion. -\end{itemize} - -\enternote -A standard conversion sequence can be empty, i.e., it can consist of no -conversions. \exitnote A standard conversion sequence will be applied to -an expression if necessary to convert it to a required destination type. - -\pnum -\enternote -expressions with a given type will be implicitly converted to other -types in several contexts: - -\begin{itemize} -\item When used as operands of operators. The operator's requirements -for its operands dictate the destination type (Clause~\ref{expr}). - -\item When used in the condition of an \tcode{if} statement or iteration -statement~(\ref{stmt.select}, \ref{stmt.iter}). The destination type is -\tcode{bool}. - -\item When used in the expression of a \tcode{switch} statement. The -destination type is integral~(\ref{stmt.select}). - -\item When used as the source expression for an initialization (which -includes use as an argument in a function call and use as the expression -in a \tcode{return} statement). The type of the entity being initialized -is (generally) the destination type. -See~\ref{dcl.init},~\ref{dcl.init.ref}. -\end{itemize} -\exitnote - -\pnum -An expression \tcode{e} can be -\indextext{conversion!implicit}% -\term{implicitly converted} to a type \tcode{T} if and only if the -declaration \tcode{T t=e;} is well-formed, for some invented temporary -variable \tcode{t}~(\ref{dcl.init}). - -\pnum -Certain language constructs require that an expression be converted to a Boolean -value. An expression \tcode{e} appearing in such a context is said to be -\indextext{conversion!contextual to \tcode{bool}}% -\term{contextually converted to \tcode{bool}} and is well-formed if and only if -the declaration \tcode{bool t(e);} is well-formed, for some invented temporary -variable \tcode{t}~(\ref{dcl.init}). - -\pnum -Certain language constructs require conversion to a value having -one of a specified set of types appropriate to the construct. An -expression \tcode{e} of class type \tcode{E} appearing in such a -context is said to be -\indextext{conversion!contextual}% -\term{contextually implicitly converted to} a specified type \tcode{T} and is -well-formed if and only if \tcode{e} can be implicitly converted to a type \tcode{T} -that is determined as follows: \tcode{E} is searched for conversion functions -whose return type is \cvqual{cv} \tcode{T} or reference to \cvqual{cv} -\tcode{T} such that \tcode{T} is allowed by the context. -There shall be exactly one such \tcode{T}. - -\pnum -The effect of any implicit -conversion is the same as performing the corresponding declaration and initialization -and then using the temporary variable as the result of the conversion. -The result is an lvalue if \tcode{T} is an lvalue reference -type or an rvalue reference to function type~(\ref{dcl.ref}), -an xvalue if \tcode{T} is an rvalue reference to object type, -and a prvalue otherwise. The expression \tcode{e} -is used as a glvalue if and only if the initialization uses it as a glvalue. - -\pnum -\enternote -For class types, user-defined conversions are considered as well; -see~\ref{class.conv}. In general, an implicit conversion -sequence~(\ref{over.best.ics}) consists of a standard conversion -sequence followed by a user-defined conversion followed by another -standard conversion sequence. -\exitnote - -\pnum -\enternote -There are some contexts where certain conversions are suppressed. For -example, the lvalue-to-rvalue conversion is not done on the operand of -the unary \tcode{\&} operator. Specific exceptions are given in the -descriptions of those operators and contexts. -\exitnote - -\rSec1[conv.lval]{Lvalue-to-rvalue conversion} - -\pnum -\indextext{conversion!lvalue-to-rvalue}% -\indextext{type!incomplete}% -A glvalue~(\ref{basic.lval}) of a non-function, non-array type \tcode{T} -can be converted to -a prvalue.\footnote{For historical reasons, this conversion is called the ``lvalue-to-rvalue'' -conversion, even though that name does not accurately reflect the taxonomy -of expressions described in~\ref{basic.lval}.} -If \tcode{T} is an incomplete type, a -program that necessitates this conversion is ill-formed. If \tcode{T} -is a non-class type, the type of the prvalue is -the cv-unqualified version of \tcode{T}. Otherwise, the type of the -prvalue is \tcode{T}.\footnote{In \Cpp class prvalues can have cv-qualified types (because they are -objects). This differs from ISO C, in which non-lvalues never have -cv-qualified types.} - -\pnum -When an lvalue-to-rvalue conversion -is applied to an expression \tcode{e}, and either -\begin{itemize} -\item \tcode{e} is not potentially evaluated, or -\item the evaluation of \tcode{e} results in the evaluation of a member - \tcode{ex} of the set of potential results of \tcode{e}, and \tcode{ex} - names a variable \tcode{x} that is not odr-used by - \tcode{ex}~(\ref{basic.def.odr}), -\end{itemize} -the value contained in the referenced object is not accessed. -\enterexample -\begin{codeblock} -struct S { int n; }; -auto f() { - S x { 1 }; - constexpr S y { 2 }; - return [&](bool b) { return (b ? y : x).n; }; -} -auto g = f(); -int m = g(false); // undefined behavior due to access of \tcode{x.n} outside its lifetime -int n = g(true); // OK, does not access \tcode{y.n} -\end{codeblock} -\exitexample -In all other cases, the result of the conversion is determined according to the -following rules: - -\begin{itemize} - -\item If \tcode{T} is (possibly cv-qualified) \tcode{std::nullptr_t}, the result is a -null pointer constant~(\ref{conv.ptr}). - -\item Otherwise, if \tcode{T} has a class -type, the conversion copy-initializes a temporary of type \tcode{T} from -the glvalue and the result of the conversion is a prvalue for the -temporary. - -\item Otherwise, if the object to which the glvalue refers contains an invalid -pointer value~(\ref{basic.stc.dynamic.deallocation}, -\ref{basic.stc.dynamic.safety}), the behavior is implementation-defined. - -\item Otherwise, the value contained in the object indicated by the -glvalue is the prvalue result. - -\end{itemize} - -\pnum -\enternote -See also~\ref{basic.lval}.\exitnote - -\rSec1[conv.array]{Array-to-pointer conversion} - -\pnum -\indextext{conversion!array-to-pointer}% -\indextext{decay|see{conversion, array to pointer; conversion, function to pointer}}% -An lvalue or rvalue 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 result is a pointer to the first element -of the array. - -\rSec1[conv.func]{Function-to-pointer conversion} - -\pnum -\indextext{conversion!function-to-pointer}% -An lvalue of function type \tcode{T} can be converted to a prvalue of -type ``pointer to \tcode{T}.'' The result is a pointer to the -function.\footnote{This conversion never applies to non-static member functions because an -lvalue that refers to a non-static member function cannot be obtained.} - -\pnum -\enternote -See~\ref{over.over} for additional rules for the case where the function -is overloaded. -\exitnote - -\rSec1[conv.qual]{Qualification conversions} - -\indextext{conversion!qualification|(}% -\pnum -A \defn{cv-decomposition} of a type \tcode{T} -is a sequence of -$cv_i$ and $P_i$ -such that \tcode{T} is - -\begin{indented} -``$cv_0$ $P_0$ $cv_1$ $P_1$ $\cdots$ $cv_{n-1}$ $P_{n-1}$ $cv_n$ \tcode{U}'' for \placeholder{n} $> 0$, -\end{indented} - -where -each $cv_i$ is a set of cv-qualifiers~(\ref{basic.type.qualifier}), and -each $P_i$ is -``pointer to''~(\ref{dcl.ptr}), -``pointer to member of class $C_i$ of type''~(\ref{dcl.mptr}), -``array of $N_i$'', or -``array of unknown bound of''~(\ref{dcl.array}). -If $P_i$ designates an array, -the cv-qualifiers $cv_{i+1}$ on the element type are also taken as -the cv-qualifiers $cv_i$ of the array. -\enterexample -The type denoted by the \grammarterm{type-id} \tcode{const int **} -has two cv-decompositions, -taking \tcode{U} as ``\tcode{int}'' and as ``pointer to \tcode{const int}''. -\exitexample -The \placeholder{n}-tuple of cv-qualifiers after the first one -in the longest cv-decomposition of \tcode{T}, that is, -$cv_1$, $cv_2$, $\cdots$, $cv_n$, is called the -\defn{cv-qualification signature} of \tcode{T}. - -\pnum -\indextext{type!similar|see{similar types}}% -Two types \tcode{T1} and \tcode{T2} are \defnx{similar}{similar types} if -they have cv-decompositions with the same \placeholder{n} -such that corresponding $P_i$ components are the same -and the types denoted by \tcode{U} are the same. - -\pnum -A prvalue expression of type \tcode{T1} -can be converted to type \tcode{T2} -if the following conditions are satisfied, -% NB: forbid line break between 'where' and 'cv' -% to stop superscript j from running into -% desecender of p on the previous line. -where~$cv_i^j$ denotes the cv-qualifiers in the cv-qualification signature of $T_j$% -\footnote{These rules ensure that const-safety is preserved by the conversion.}: - -\begin{itemize} -\item \tcode{T1} and \tcode{T2} are similar. - -\item For every $i > 0$, if \tcode{const} is in $\mathit{cv}_i^1$ then \tcode{const} is in $\mathit{cv}_i^2$, and similarly for \tcode{volatile}. - -\item If the $\mathit{cv}_i^1$ and $\mathit{cv}_i^2$ are different, -then \tcode{const} is in every $\mathit{cv}_k^2$ for $0 < k < i$. -\end{itemize} - -\enternote -if a program could assign a pointer of type \tcode{T**} to a pointer of -type \tcode{const} \tcode{T**} (that is, if line \tcode{\#1} below were -allowed), a program could inadvertently modify a \tcode{const} object -(as it is done on line \tcode{\#2}). For example, - -\begin{codeblock} -int main() { - const char c = 'c'; - char* pc; - const char** pcc = &pc; // \#1: not allowed - *pcc = &c; - *pc = 'C'; // \#2: modifies a \tcode{const} object -} -\end{codeblock} -\exitnote - -\pnum -\enternote -A prvalue of type ``pointer to \cvqual{cv1} \tcode{T}'' can be -converted to a prvalue of type ``pointer to \cvqual{cv2} \tcode{T}'' if -``\cvqual{cv2} \tcode{T}'' is more cv-qualified than ``\cvqual{cv1} -\tcode{T}''. -A prvalue of type ``pointer to member of \tcode{X} of type \cvqual{cv1} -\tcode{T}'' can be converted to a prvalue of type ``pointer to member -of \tcode{X} of type \cvqual{cv2} \tcode{T}'' if ``\cvqual{cv2} -\tcode{T}'' is more cv-qualified than ``\cvqual{cv1} \tcode{T}''. -\exitnote - -\pnum -\enternote -Function types (including those used in pointer to member function -types) are never cv-qualified~(\ref{dcl.fct}). -\exitnote -\indextext{conversion!qualification|)} - -\rSec1[conv.prom]{Integral promotions} - -\pnum -\indextext{promotion!integral}% -A prvalue of an integer type other than \tcode{bool}, \tcode{char16_t}, -\tcode{char32_t}, or \tcode{wchar_t} whose integer conversion -rank~(\ref{conv.rank}) is less than the rank of \tcode{int} can be -converted to a prvalue of type \tcode{int} if \tcode{int} can represent -all the values of the source type; otherwise, the source prvalue can be -converted to a prvalue of type \tcode{unsigned int}. - -\pnum -A prvalue of type \tcode{char16_t}, \tcode{char32_t}, or -\tcode{wchar_t}~(\ref{basic.fundamental}) can be converted to a prvalue -of the first of the following types that can represent all the values of -its underlying type: \tcode{int}, \tcode{unsigned int}, \tcode{long} -\tcode{int}, \tcode{unsigned long} \tcode{int}, \tcode{long long int}, -or \tcode{unsigned long long int}. If none of the types in that list can -represent all the values of its underlying type, a prvalue of type -\tcode{char16_t}, \tcode{char32_t}, or \tcode{wchar_t} can be converted -to a prvalue of its underlying type. - -\pnum -A prvalue of an unscoped enumeration type whose underlying type is not -fixed~(\ref{dcl.enum}) can be converted to a prvalue of the first of the following -types that can represent all the values of the enumeration (i.e., the values in the -range $b_\mathit{min}$ to $b_\mathit{max}$ as described in~\ref{dcl.enum}): \tcode{int}, -\tcode{unsigned int}, \tcode{long} \tcode{int}, \tcode{unsigned long} \tcode{int}, -\tcode{long long int}, or \tcode{unsigned long long int}. If none of the types in that -list can represent all the values of the enumeration, a prvalue of an unscoped -enumeration type can be converted to a prvalue of the extended integer type with lowest -integer conversion rank~(\ref{conv.rank}) greater than the rank of \tcode{long} -\tcode{long} in which all the values of the enumeration can be represented. If there are -two such extended types, the signed one is chosen. - -\pnum -A prvalue of an unscoped enumeration type whose underlying type is -fixed~(\ref{dcl.enum}) can be converted to a prvalue of its underlying type. Moreover, -if integral promotion can be applied to its underlying type, a prvalue of an unscoped -enumeration type whose underlying type is fixed can also be converted to a prvalue of -the promoted underlying type. - -\pnum -A prvalue for an integral bit-field~(\ref{class.bit}) can be converted -to a prvalue of type \tcode{int} if \tcode{int} can represent all the -values of the bit-field; otherwise, it can be converted to -\tcode{unsigned int} if \tcode{unsigned int} can represent all the -values of the bit-field. If the bit-field is larger yet, no integral -promotion applies to it. If the bit-field has an enumerated type, it is -treated as any other value of that type for promotion purposes. - -\pnum -\indextext{promotion!bool to int}% -A prvalue of type \tcode{bool} can be converted to a prvalue of type -\tcode{int}, with \tcode{false} becoming zero and \tcode{true} becoming -one. - -\pnum -These conversions are called \term{integral promotions}. - -\rSec1[conv.fpprom]{Floating point promotion} - -\pnum -\indextext{promotion!floating~point}% -A prvalue of type \tcode{float} can be converted to a prvalue of type -\tcode{double}. The value is unchanged. - -\pnum -This conversion is called \term{floating point promotion}. - -\rSec1[conv.integral]{Integral conversions} - -\pnum -\indextext{conversion!integral}% -A prvalue of an integer type can be converted to a prvalue of another -integer type. A prvalue of an unscoped enumeration type can be converted to -a prvalue of an integer type. - -\pnum -\indextext{conversion!to unsigned}% -If the destination type is unsigned, the resulting value is the least -unsigned integer congruent to the source integer (modulo $2^n$ where $n$ -is the number of bits used to represent the unsigned type). -\enternote -In a two's complement representation, this conversion is conceptual and -there is no change in the bit pattern (if there is no truncation). -\exitnote - -\pnum -\indextext{conversion!to signed}% -If the destination type is signed, the value is unchanged if it can be -represented in the destination type; otherwise, -the value is \impldef{value of result of unsigned to signed conversion}. - -\pnum -\indextext{conversion!bool@\tcode{bool}}% -If the destination type is \tcode{bool}, see~\ref{conv.bool}. If the -source type is \tcode{bool}, the value \tcode{false} is converted to -zero and the value \tcode{true} is converted to one. - -\pnum -The conversions allowed as integral promotions are excluded from the set -of integral conversions. - -\rSec1[conv.double]{Floating point conversions} - -\pnum -\indextext{conversion!floating~point}% -A prvalue of floating point type can be converted to a prvalue of -another floating point type. If the source value can be exactly -represented in the destination type, the result of the conversion is -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. - -\pnum -The conversions allowed as floating point promotions are excluded from -the set of floating point conversions. - -\rSec1[conv.fpint]{Floating-integral conversions} - -\pnum -\indextext{conversion!floating~to~integral}% -A prvalue of a floating point type can be converted to a prvalue of an -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 -in the destination type. -\enternote -If the destination type is \tcode{bool}, see~\ref{conv.bool}. -\exitnote - -\pnum -\indextext{conversion!integral~to~floating}% -\indextext{truncation}% -\indextext{rounding}% -A prvalue of an integer type or of an unscoped enumeration type can be converted to -a prvalue of a floating point type. The result is exact if possible. If the value being -converted is in the range of values that can be represented but the value cannot be -represented exactly, it is an \impldef{value of result of inexact integer to -floating-point conversion} choice of either the next lower or higher representable -value. \enternote Loss of precision occurs if the integral value cannot be represented -exactly as a value of the floating type. \exitnote If the value being converted is -outside the range of values that can be represented, the behavior is undefined. If the -source type is \tcode{bool}, the value \tcode{false} is converted to zero and the value -\tcode{true} is converted to one. - -\rSec1[conv.ptr]{Pointer conversions} - -\pnum -\indextext{conversion!pointer}% -\indextext{pointer!zero}% -\indextext{constant!null pointer}% -\indextext{value!null pointer}% -A \term{null pointer constant} is an integer literal~(\ref{lex.icon}) with -value zero -or a prvalue of type \tcode{std::nullptr_t}. A null pointer constant can be -converted to a pointer type; the -result is the \term{null pointer value} of that type and is -distinguishable from every other value of -object pointer or function pointer -type. -Such a conversion is called a \term{null pointer conversion}. -Two null pointer values of the same type shall compare -equal. The conversion of a null pointer constant to a pointer to -cv-qualified type is a single conversion, and not the sequence of a -pointer conversion followed by a qualification -conversion~(\ref{conv.qual}). A null pointer constant of integral type -can be converted to a prvalue of type \tcode{std::nullptr_t}. -\enternote The resulting prvalue is not a null pointer value. \exitnote - -\pnum -A prvalue of type ``pointer to \cvqual{cv} \tcode{T},'' where \tcode{T} -is an object type, can be converted to a prvalue of type ``pointer to -\cvqual{cv} \tcode{void}''. The result of converting a -non-null pointer value of a pointer to object type to a ``pointer to -\cvqual{cv} \tcode{void}'' -represents the address of the same byte in memory as the original pointer -value. The null pointer value is converted to the null pointer -value of the destination type. - -\pnum -A prvalue of type ``pointer to \cvqual{cv} \tcode{D}'', where \tcode{D} -is a class type, can be converted to a prvalue of type ``pointer to -\cvqual{cv} \tcode{B}'', where \tcode{B} is a base class -(Clause~\ref{class.derived}) of \tcode{D}. If \tcode{B} is an -inaccessible (Clause~\ref{class.access}) or -ambiguous~(\ref{class.member.lookup}) base class of \tcode{D}, a program -that necessitates this conversion is ill-formed. The result of the -conversion is a pointer to the base class subobject of the derived class -object. The null pointer value is converted to the null pointer value of -the destination type. - -\rSec1[conv.mem]{Pointer to member conversions} - -\pnum -\indextext{conversion!pointer to member}% -\indextext{constant!null pointer}% -\indextext{value!null member pointer}% -A null pointer constant~(\ref{conv.ptr}) can be converted to a pointer -to member type; the result is the \term{null member pointer value} -of that type and is distinguishable from any pointer to member not -created from a null pointer constant. -Such a conversion is called a \term{null member pointer conversion}. -Two null member pointer values of -the same type shall compare equal. The conversion of a null pointer -constant to a pointer to member of cv-qualified type is a single -conversion, and not the sequence of a pointer to member conversion -followed by a qualification conversion~(\ref{conv.qual}). - -\pnum -A prvalue of type ``pointer to member of \tcode{B} of type \cvqual{cv} -\tcode{T}'', where \tcode{B} is a class type, can be converted to -a prvalue of type ``pointer to member of \tcode{D} of type \cvqual{cv} -\tcode{T}'', where \tcode{D} is a derived class -(Clause~\ref{class.derived}) of \tcode{B}. If \tcode{B} is an -inaccessible (Clause~\ref{class.access}), -ambiguous~(\ref{class.member.lookup}), or virtual~(\ref{class.mi}) base -class of \tcode{D}, or a base class of a virtual base class of -\tcode{D}, a program that necessitates this conversion is ill-formed. -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 -the member in \tcode{D}'s instance of \tcode{B}. Since the result has -type ``pointer to member of \tcode{D} of type \cvqual{cv} \tcode{T}'', -indirection through it with a \tcode{D} object is valid. The result is the same -as if indirecting through the pointer to member of \tcode{B} with the -\tcode{B} subobject of \tcode{D}. The null member pointer value is -converted to the null member pointer value of the destination -type.\footnote{The rule for conversion of pointers to members (from pointer to member -of base to pointer to member of derived) appears inverted compared to -the rule for pointers to objects (from pointer to derived to pointer to -base)~(\ref{conv.ptr}, Clause~\ref{class.derived}). This inversion is -necessary to ensure type safety. Note that a pointer to member is not -an object pointer or a function pointer -and the rules for conversions -of such pointers do not apply to pointers to members. -\indextext{conversion!pointer to member!\idxcode{void*}}% -In particular, a pointer to member cannot be converted to a -\tcode{void*}.} - -\rSec1[conv.bool]{Boolean conversions} - -\pnum -\indextext{conversion!boolean}% -A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member -type can be converted to a prvalue of type \tcode{bool}. A zero value, null -pointer value, or null member pointer value is converted to \tcode{false}; any -other value is converted to \tcode{true}. For -direct-initialization~(\ref{dcl.init}), a prvalue of type -\tcode{std::nullptr_t} can be converted to a prvalue of type -\tcode{bool}; the resulting value is \tcode{false}. - -\rSec1[conv.rank]{Integer conversion rank}% -\indextext{conversion!integer rank} - -\pnum -Every integer type has an \term{integer conversion rank} defined as follows: - -\begin{itemize} -\item No two signed integer types other than \tcode{char} and \tcode{signed -char} (if \tcode{char} is signed) shall have the same rank, even if they have -the same representation. - -\item The rank of a signed integer type shall be greater than the rank -of any signed integer type with a smaller size. - -\item The rank of \tcode{long} \tcode{long} \tcode{int} shall be greater -than the rank of \tcode{long} \tcode{int}, which shall be greater than -the rank of \tcode{int}, which shall be greater than the rank of -\tcode{short} \tcode{int}, which shall be greater than the rank of -\tcode{signed} \tcode{char}. - -\item The rank of any unsigned integer type shall equal the rank of the -corresponding signed integer type. - -\item The rank of any standard integer type shall be greater than the -rank of any extended integer type with the same size. - -\item The rank of \tcode{char} shall equal the rank of \tcode{signed} -\tcode{char} and \tcode{unsigned} \tcode{char}. - -\item The rank of \tcode{bool} shall be less than the rank of all other -standard integer types. - -\item The ranks of \tcode{char16_t}, \tcode{char32_t}, and -\tcode{wchar_t} shall equal the ranks of their underlying -types~(\ref{basic.fundamental}). - -\item The rank of any extended signed integer type relative to another -extended signed integer type with the same size is \impldef{rank of extended signed -integer type}, but still subject to the other rules for determining the integer -conversion rank. - -\item For all integer types \tcode{T1}, \tcode{T2}, and \tcode{T3}, if -\tcode{T1} has greater rank than \tcode{T2} and \tcode{T2} has greater -rank than \tcode{T3}, then \tcode{T1} shall have greater rank than -\tcode{T3}. -\end{itemize} - -\enternote -The integer conversion rank is used in the definition of the integral -promotions~(\ref{conv.prom}) and the usual arithmetic -conversions (Clause~\ref{expr}). -\exitnote% -\indextext{conversion!standard|)} diff --git a/source/cover-reg.tex b/source/cover-reg.tex index 0910f727fa..5923fce26d 100644 --- a/source/cover-reg.tex +++ b/source/cover-reg.tex @@ -2,9 +2,14 @@ %%-------------------------------------------------- %% Title page for the C++ Standard +\setlength{\fboxsep}{1em} +\newlength{\copyboxwidth} +\setlength{\copyboxwidth}{\textwidth} +\addtolength{\copyboxwidth}{-2\fboxsep} +\addtolength{\copyboxwidth}{-2\fboxrule} \thispagestyle{empty} -{\raisebox{.35ex}{\smaller\copyright}}\,ISO 2014 --- All rights reserved +{\raisebox{.35ex}{\smaller\copyright}}\,ISO 2017 --- All rights reserved \vspace{2ex} \begin{flushright} @@ -12,7 +17,7 @@ Date: \reldate -ISO/IEC FDIS 14882 +ISO/IEC DIS 14882 ISO/IEC JTC1 SC22 @@ -22,29 +27,28 @@ \vfill -\textbf{\LARGE Programming Languages --- \Cpp} +\textbf{\LARGE Programming Languages --- \Cpp{}} -Langages de programmation --- \Cpp +Langages de programmation --- \Cpp{} \vfill -\begin{tabular}{|p{\hsize}|} -\hline +\fbox{% +\begin{minipage}{\copyboxwidth} +\vspace{1ex} \begin{center} \textbf{Warning} \end{center} - \vspace{2ex} This document is not an ISO International Standard. It is distributed for review and comment. It is subject to change without notice and may -not be referred to as an International Standard.\\\\ +not be referred to as an International Standard.\\[1em] Recipients of this draft are invited to submit, with their comments, notification of any relevant patent rights of which they are aware -and to provide supporting documentation.\\\\ -\hline -\end{tabular} +and to provide supporting documentation.\\ +\end{minipage}} \vfill \noindent @@ -55,44 +59,35 @@ \thispagestyle{cpppage} -\begin{tabular}{|p{\hsize}|} -\hline -\begin{center} -\textbf{Copyright notice} -\end{center} +\vspace*{\fill} +\vspace{1ex} +\raisebox{-1ex}{\includegraphics{assets/iso-logo-caution.png}}\qquad{\Large{\textbf{COPYRIGHT PROTECTED DOCUMENT}}} \vspace{2ex} -This ISO document is a working draft or committee draft and is -copyright-protected by ISO. While the reproduction of working -drafts or committee drafts in any form for use by participants -in the ISO standards development process is permitted without -prior permission from ISO, neither this document nor any extract -from it may be reproduced, stored or transmitted in any form for -any other purpose without prior written permission from ISO.\\\\ +\isocopyright -Requests for permission to reproduce this document for the -purpose of selling it should be addressed as shown below or -to ISO's member body in the country of the requestor.\\\\ +All rights reserved. Unless otherwise specified, +or required in the context of its implementation, +no part of this publication may be reproduced or +utilized otherwise in any form or by any means, +electronic or mechanical, including photocopying, +or posting on the internet or an intranet, +without prior written permission. +Permission can be requested +from either ISO at the address below +or ISO's member body in the country of the requester. -\begin{minipage}{\hsize} \begin{indented} +\microtypesetup{activate=false}% ISO copyright office\\ -Case postale 56, CH-1211 Geneva 20\\ -Tel. + 41 22 749 01 11\\ -Fax + 41 22 749 09 47\\ -E-mail copyright@iso.org\\ -Web www.iso.org +CP 401 \textbullet{} Ch.\ de Blandonnet 8\\ +CH-1214 Vernier, Geneva\\ +Phone: +41 22 749 01 11\\ +Email: \texttt{copyright@iso.org}\\ +Website: \url{www.iso.org} \end{indented} -\end{minipage} - -\vspace{2ex} - -Reproduction for sales purposes may be subject to royalty payments -or a licensing agreement.\\\\ -Violators may be prosecuted.\\\\ -\hline -\end{tabular} +Published in Switzerland \newpage diff --git a/source/cover-wd.tex b/source/cover-wd.tex index d2fcdb118b..54d00f4b64 100644 --- a/source/cover-wd.tex +++ b/source/cover-wd.tex @@ -9,8 +9,8 @@ \textbf{Document Number:} & {\larger\docno} \\ \textbf{Date:} & \reldate \\ \textbf{Revises:} & \prevdocno \\ - \textbf{Reply to:} & Richard Smith \\ - & Google Inc \\ + \textbf{Reply to:} & Thomas K\"{o}ppe \\ + & Google DeepMind \\ & cxxeditor@gmail.com \end{tabular} } @@ -22,7 +22,7 @@ \vspace{2.5cm} \begin{center} \textbf{\Huge -Working Draft, Standard for Programming Language \Cpp} +Working Draft\\[2ex]Programming Languages --- \Cpp{}} \end{center} \vfill \textbf{Note: this is an early draft. It's known to be incomplet and diff --git a/source/declarations.tex b/source/declarations.tex index 0c283f3224..627360a226 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -1,62 +1,111 @@ %!TEX root = std.tex -\rSec0[dcl.dcl]{Declarations}% +\rSec0[dcl]{Declarations}% \indextext{declaration|(} -%gram: \rSec1[gram.dcl]{Declarations} -%gram: +\gramSec[gram.dcl]{Declarations} \indextext{linkage specification|see{specification, linkage}} +\rSec1[dcl.pre]{Preamble} + \pnum Declarations generally specify how names are to be interpreted. Declarations have the form - \begin{bnf} \nontermdef{declaration-seq}\br - declaration\br - declaration-seq declaration + declaration \opt{declaration-seq} \end{bnf} \begin{bnf} \nontermdef{declaration}\br + name-declaration\br + special-declaration +\end{bnf} + +\begin{bnf} +\nontermdef{name-declaration}\br block-declaration\br + nodeclspec-function-declaration\br function-definition\br + friend-type-declaration\br template-declaration\br - explicit-instantiation\br - explicit-specialization\br + deduction-guide\br linkage-specification\br namespace-definition\br empty-declaration\br - attribute-declaration + attribute-declaration\br + module-import-declaration +\end{bnf} + +\begin{bnf} +\nontermdef{special-declaration}\br + explicit-instantiation\br + explicit-specialization\br + export-declaration \end{bnf} \begin{bnf} \nontermdef{block-declaration}\br simple-declaration\br - asm-definition\br + asm-declaration\br namespace-alias-definition\br using-declaration\br + using-enum-declaration\br using-directive\br static_assert-declaration\br + consteval-block-declaration\br alias-declaration\br opaque-enum-declaration \end{bnf} +\begin{bnf} +\nontermdef{nodeclspec-function-declaration}\br + \opt{attribute-specifier-seq} declarator \terminal{;} +\end{bnf} + \begin{bnf} \nontermdef{alias-declaration}\br - \terminal{using} identifier attribute-specifier-seq\opt \terminal{=} type-id \terminal{;} + \keyword{using} identifier \opt{attribute-specifier-seq} \terminal{=} defining-type-id \terminal{;} +\end{bnf} + +\begin{bnf} +\nontermdef{sb-identifier}\br + \opt{\terminal{...}} identifier \opt{attribute-specifier-seq} +\end{bnf} + +\begin{bnf} +\nontermdef{sb-identifier-list}\br + sb-identifier\br + sb-identifier-list \terminal{,} sb-identifier +\end{bnf} + +\begin{bnf} +\nontermdef{structured-binding-declaration}\br + \opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{[} sb-identifier-list \terminal{]} \end{bnf} \begin{bnf} \nontermdef{simple-declaration}\br - decl-specifier-seq\opt init-declarator-list\opt \terminal{;}\br - attribute-specifier-seq decl-specifier-seq\opt init-declarator-list \terminal{;} + decl-specifier-seq \opt{init-declarator-list} \terminal{;}\br + attribute-specifier-seq decl-specifier-seq init-declarator-list \terminal{;}\br + structured-binding-declaration initializer \terminal{;} +\end{bnf} + +\begin{bnf} +\nontermdef{static_assert-message}\br + unevaluated-string\br + constant-expression \end{bnf} \begin{bnf} \nontermdef{static_assert-declaration}\br - \terminal{static_assert} \terminal{(} constant-expression \terminal{)} \terminal{;}\br - \terminal{static_assert} \terminal{(} constant-expression \terminal{,} string-literal \terminal{)} \terminal{;} + \keyword{static_assert} \terminal{(} constant-expression \terminal{)} \terminal{;}\br + \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} @@ -69,232 +118,398 @@ attribute-specifier-seq \terminal{;} \end{bnf} -\enternote -\grammarterm{asm-definition}{s} are described in~\ref{dcl.asm}, and -\grammarterm{linkage-specification}{s} are described in~\ref{dcl.link}. -\grammarterm{Function-definition}{s} are described in~\ref{dcl.fct.def} and -\grammarterm{template-declaration}{s} are described in Clause~\ref{temp}. -\grammarterm{Namespace-definition}{s} are described in~\ref{namespace.def}, +\begin{note} +\grammarterm{asm-declaration}{s} are described in~\ref{dcl.asm}, and +\grammarterm{linkage-specification}{s} are described in~\ref{dcl.link}; +\grammarterm{function-definition}{s} are described in~\ref{dcl.fct.def} and +\grammarterm{template-declaration}{s} and +\grammarterm{deduction-guide}{s} are described in \ref{temp.deduct.guide}; +\grammarterm{namespace-definition}{s} are described in~\ref{namespace.def}, \grammarterm{using-declaration}{s} are described in~\ref{namespace.udecl} and \grammarterm{using-directive}{s} are described in~\ref{namespace.udir}. -\exitnote +\end{note} \pnum -The -\grammarterm{simple-declaration} +\indextext{declaration}% +\indextext{scope}% +Certain declarations contain one or more scopes\iref{basic.scope.scope}. +Unless otherwise stated, utterances in +\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. +\pnum +If a \grammarterm{name-declaration} matches +the syntactic requirements of \grammarterm{friend-type-declaration}, +it is a \grammarterm{friend-type-declaration}. + +\pnum +A +\grammarterm{simple-declaration} or +\grammarterm{nodeclspec-function-declaration} of the form \begin{ncsimplebnf} -attribute-specifier-seq\opt decl-specifier-seq\opt init-declarator-list\opt \terminal{;} +\opt{attribute-specifier-seq} \opt{decl-specifier-seq} \opt{init-declarator-list} \terminal{;} \end{ncsimplebnf} - is divided into three parts. Attributes are described in~\ref{dcl.attr}. \grammarterm{decl-specifier}{s}, the principal components of a \grammarterm{decl-specifier-seq}, are described in~\ref{dcl.spec}. \grammarterm{declarator}{s}, the components of an -\grammarterm{init-declarator-list}, are described in Clause~\ref{dcl.decl}. -The \grammarterm{attribute-specifier-seq} in a -\grammarterm{simple-declaration} appertains to each of the entities declared by +\grammarterm{init-declarator-list}, are described in \ref{dcl.decl}. +The \grammarterm{attribute-specifier-seq} +appertains to each of the entities declared by the \grammarterm{declarator}{s} of the \grammarterm{init-declarator-list}. -\enternote In the declaration for an entity, attributes appertaining to that -entity may appear at the start of the declaration and after the +\begin{note} +In the declaration for an entity, attributes appertaining to that +entity can appear at the start of the declaration and after the \grammarterm{declarator-id} for that declaration. -\exitnote \enterexample +\end{note} +\begin{example} \begin{codeblock} -[[noreturn]] void f [[noreturn]] (); // OK +[[noreturn]] void f [[noreturn]] (); // OK \end{codeblock} -\exitexample - -\pnum -Except where otherwise specified, the meaning of an \grammarterm{attribute-declaration} -is \impldef{meaning of attribute declaration}. +\end{example} \pnum -\indextext{declaration}% -\indextext{scope}% -A declaration occurs in a scope~(\ref{basic.scope}); the scope rules are -summarized in~\ref{basic.lookup}. A declaration that declares a function -or defines a class, namespace, template, or function also has one or -more scopes nested within it. These nested scopes, in turn, can have -declarations nested within them. Unless otherwise stated, utterances in -Clause~\ref{dcl.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. +If a \grammarterm{declarator-id} is a name, the +\grammarterm{init-declarator} and (hence) the declaration introduce that name. +\begin{note} +Otherwise, the \grammarterm{declarator-id} is +a \grammarterm{qualified-id} or +names a destructor or +its \grammarterm{unqualified-id} is a \grammarterm{template-id} and +no name is introduced. +\end{note} +The \grammarterm{defining-type-specifier}{s}\iref{dcl.type} in +the \grammarterm{decl-specifier-seq} and +the recursive \grammarterm{declarator} structure +describe a type\iref{dcl.meaning}, +which is then associated with the \grammarterm{declarator-id}. \pnum \indextext{identifier}% \indextext{declarator}% In a \grammarterm{simple-declaration}, the optional \grammarterm{init-declarator-list} can be omitted only when declaring a -class (Clause~\ref{class}) or enumeration~(\ref{dcl.enum}), that is, +class\iref{class.pre} or enumeration\iref{dcl.enum}, that is, when the \grammarterm{decl-specifier-seq} contains either a \grammarterm{class-specifier}, an \grammarterm{elaborated-type-specifier} with -a \grammarterm{class-key}~(\ref{class.name}), or an +a \grammarterm{class-key}\iref{class.name}, or an \grammarterm{enum-specifier}. In these cases and whenever a \grammarterm{class-specifier} or \grammarterm{enum-specifier} is present in the \grammarterm{decl-specifier-seq}, the identifiers in these specifiers -are among the names being declared by the declaration (as +are also declared (as \grammarterm{class-name}{s}, \grammarterm{enum-name}{s}, or \grammarterm{enumerator}{s}, depending on the syntax). In such cases, -the \grammarterm{decl-specifier-seq} shall introduce one or more names into -the program, or shall redeclare a name introduced by a previous -declaration. -\enterexample +the \grammarterm{decl-specifier-seq} shall (re)introduce one or more names into +the program. +\begin{example} +\begin{codeblock} +enum { }; // error +typedef class { }; // error +\end{codeblock} +\end{example} +\pnum +A \grammarterm{simple-declaration} or a \grammarterm{condition} +with a \grammarterm{structured-binding-declaration} is called +a \defn{structured binding declaration}\iref{dcl.struct.bind}. +Each \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq} +shall be +\tcode{constexpr}, +\tcode{constinit}, +\tcode{static}, +\tcode{thread_local}, +\tcode{auto}\iref{dcl.spec.auto}, or +a \grammarterm{cv-qualifier}. +The declaration shall contain at most one \grammarterm{sb-identifier} +whose \grammarterm{identifier} is preceded by an ellipsis. +If the declaration contains any such \grammarterm{sb-identifier}, +it shall declare a templated entity\iref{temp.pre}. +\begin{example} +\begin{codeblock} +template concept C = true; +C auto [x, y] = std::pair{1, 2}; // error: constrained \grammarterm{placeholder-type-specifier} + // not permitted for structured bindings +\end{codeblock} +\end{example} +The \grammarterm{initializer} shall be +of the form ``\tcode{=} \grammarterm{assignment-expression}'', +of the form ``\tcode{\{} \grammarterm{assignment-expression} \tcode{\}}'', +or +of the form ``\tcode{(} \grammarterm{assignment-expression} \tcode{)}''. +If the \grammarterm{structured-binding-declaration} appears as +a \grammarterm{condition}, +the \grammarterm{assignment-expression} shall be of non-union class type. +Otherwise, +the \grammarterm{assignment-expression} shall be of +array or non-union class type. + +\pnum +If the \grammarterm{decl-specifier-seq} contains the \keyword{typedef} +specifier, the declaration is a \defnx{typedef declaration}{declaration!\idxcode{typedef}} +and each \grammarterm{declarator-id} +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}. +\end{note} +Otherwise, if the type associated with a \grammarterm{declarator-id} +is a function type\iref{dcl.fct}, +the declaration is a \defnx{function declaration}{declaration!function}. +Otherwise, if the type associated with a \grammarterm{declarator-id} +is an object or reference type, the declaration is +an \defnx{object declaration}{declaration!object}. +Otherwise, the program is ill-formed. +\begin{example} \begin{codeblock} -enum { }; // ill-formed -typedef class { }; // ill-formed +int f(), x; // OK, function declaration for \tcode{f} and object declaration for \tcode{x} +extern void g(), // OK, function declaration for \tcode{g} + y; // error: \tcode{void} is not an object type \end{codeblock} -\exitexample +\end{example} \pnum -\indextext{\idxgram{static_assert}}% -In a \grammarterm{static_assert-declaration} the -\grammarterm{constant-expression} shall be a constant -expression~(\ref{expr.const}) that can be contextually converted to \tcode{bool} -(Clause~\ref{conv}). If the value of the expression when -so converted is \tcode{true}, the declaration has no -effect. Otherwise, the program is ill-formed, and the resulting -diagnostic message~(\ref{intro.compliance}) shall include the text of -the \grammarterm{string-literal}, if one is supplied, -except that characters not in the basic -source character set~(\ref{lex.charset}) are not required to appear in -the diagnostic message. -\enterexample +\indextext{initialization!definition and}% +An object definition causes +storage of appropriate size and alignment to be reserved and +any appropriate initialization\iref{dcl.init} to be done. -\begin{codeblock} -static_assert(sizeof(long) >= 8, "64-bit code generation required for this library."); -\end{codeblock}\exitexample +\pnum +\indextext{definition!declaration as}% +Syntactic components beyond those found in the general form of +\grammarterm{simple-declaration} are added to a function declaration to make a +\grammarterm{function-definition}. +A token sequence starting with \tcode{\{} or \tcode{=} +is treated as a \grammarterm{function-body}\iref{dcl.fct.def.general} +if the type of the \grammarterm{declarator-id}\iref{dcl.meaning.general} +is a function type, and +is otherwise +treated as a \grammarterm{brace-or-equal-initializer}\iref{dcl.init.general}. +\begin{note} +If the declaration acquires a function type through template instantiation, +the program is ill-formed; see \ref{temp.spec.general}. +The function type of a function definition +cannot be specified with a \grammarterm{typedef-name}\iref{dcl.fct}. +\end{note} + +\pnum +A \grammarterm{nodeclspec-function-declaration} shall declare a +constructor, destructor, or conversion function. +\begin{note} +Because a member function cannot be subject to a non-defining declaration +outside of a class definition\iref{class.mfct}, a \grammarterm{nodeclspec-function-declaration} +can only be used in a \grammarterm{template-declaration}\iref{temp.pre}, +\grammarterm{explicit-instantiation}\iref{temp.explicit}, or +\grammarterm{explicit-specialization}\iref{temp.expl.spec}. +\end{note} + +\pnum +If a \grammarterm{static_assert-message} +matches the syntactic requirements of \grammarterm{unevaluated-string}, +it is an \grammarterm{unevaluated-string} and +the text of the \grammarterm{static_assert-message} is +the text of the \grammarterm{unevaluated-string}. +Otherwise, a \grammarterm{static_assert-message} shall be an expression $M$ +such that +\begin{itemize} +\item +the expression \tcode{$M$.size()} is +implicitly convertible to the type \tcode{std::size_t}, and +\item +the expression \tcode{$M$.data()} is +implicitly convertible to the type ``pointer to \tcode{\keyword{const} \keyword{char}}''. +\end{itemize} \pnum -An \grammarterm{empty-declaration} has no effect. +\indextext{\idxcode{static_assert}}% +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.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 +the \grammarterm{static_assert-message} is +an unevaluated operand\iref{term.unevaluated.operand}. +Otherwise, +the \grammarterm{static_assert-declaration} \defnx{fails}{\idxcode{static_assert}!failed} and +\begin{itemize} +\item +the program is ill-formed, and +\item +if the \grammarterm{static_assert-message} is +a \grammarterm{constant-expression} $M$, +\begin{itemize} +\item +\tcode{$M$.size()} shall be a converted constant expression of +type \tcode{std::size_t} and +let $N$ denote the value of that expression, +\item +\tcode{$M$.data()}, implicitly converted to +the type ``pointer to \tcode{\keyword{const} \keyword{char}}'', +shall be a core constant expression and let $D$ denote the converted expression, +\item +for each $i$ where $0 \le i < N$, +\tcode{$D$[$i$]} shall be an integral constant expression, and +\item +the text of the \grammarterm{static_assert-message} is formed by +the sequence of $N$ code units, starting at $D$, of +the ordinary literal encoding\iref{lex.charset}. +\end{itemize} +\end{itemize} \pnum -Each \grammarterm{init-declarator} in the \grammarterm{init-declarator-list} -contains exactly one \grammarterm{declarator-id}, which is the name -declared by that \grammarterm{init-declarator} and hence one of the names -declared by the declaration. The -\grammarterm{type-specifiers}~(\ref{dcl.type}) in the -\grammarterm{decl-specifier-seq} and the recursive \grammarterm{declarator} -structure of the \grammarterm{init-declarator} describe a -type~(\ref{dcl.meaning}), which is then associated with the name being -declared by the \grammarterm{init-declarator}. +\recommended +When a \grammarterm{static_assert-declaration} fails, +the resulting diagnostic message should include the text of +the \grammarterm{static_assert-message}, if one is supplied. +\begin{example} +\begin{codeblock} +static_assert(sizeof(int) == sizeof(void*), "wrong pointer size"); +static_assert(sizeof(int[2])); // OK, narrowing allowed + +template +void f(T t) { + if constexpr (sizeof(T) == sizeof(int)) { + use(t); + } else { + static_assert(false, "must be int-sized"); + } +} + +void g(char c) { + f(0); // OK + f(c); // error on implementations where \tcode{sizeof(int) > 1}: must be \tcode{int}-sized +} +\end{codeblock} +\end{example} \pnum -If the \grammarterm{decl-specifier-seq} contains the \tcode{typedef} -specifier, the declaration is called a \term{typedef declaration} and the name -of each \grammarterm{init-declarator} -is declared to be a \grammarterm{typedef-name}, synonymous with its -associated type~(\ref{dcl.typedef}). If the -\grammarterm{decl-specifier-seq} contains no \tcode{typedef} specifier, the -declaration is called a \term{function declaration} if -the type associated with the name is a function type~(\ref{dcl.fct}) and -an \term{object declaration} otherwise. +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 -\indextext{definition!declaration~as}% -Syntactic components beyond those found in the general form of -declaration are added to a function declaration to make a -\grammarterm{function-definition}. An object declaration, however, is also -a definition unless it contains the \tcode{extern} specifier and has no -initializer~(\ref{basic.def}). -\indextext{initialization!definition~and}% -A -definition causes the appropriate amount of storage to be reserved and -any appropriate initialization~(\ref{dcl.init}) to be done. +An \grammarterm{empty-declaration} has no effect. \pnum -Only in function declarations for constructors, destructors, and type -conversions can the \grammarterm{decl-specifier-seq} be omitted.\footnote{The -``implicit int'' rule of C is no longer supported.} +Except where otherwise specified, the meaning of an \grammarterm{attribute-declaration} +is \impldef{meaning of attribute declaration}. \rSec1[dcl.spec]{Specifiers}% + +\rSec2[dcl.spec.general]{General}% \indextext{specifier|(} \pnum \indextext{specifier!declaration}% The specifiers that can be used in a declaration are - \begin{bnf} \nontermdef{decl-specifier}\br storage-class-specifier\br - type-specifier\br + defining-type-specifier\br function-specifier\br - \terminal{friend}\br - \terminal{typedef}\br - \terminal{constexpr} + \keyword{friend}\br + \keyword{typedef}\br + \keyword{constexpr}\br + \keyword{consteval}\br + \keyword{constinit}\br + \keyword{inline} \end{bnf} \begin{bnf} \nontermdef{decl-specifier-seq}\br - decl-specifier attribute-specifier-seq\opt\br + decl-specifier \opt{attribute-specifier-seq}\br decl-specifier decl-specifier-seq \end{bnf} The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{decl-specifier-seq} appertains to the type determined by the preceding -\grammarterm{decl-specifier}{s}~(\ref{dcl.meaning}). The \grammarterm{attribute-specifier-seq} +\grammarterm{decl-specifier}{s}\iref{dcl.meaning}. The \grammarterm{attribute-specifier-seq} affects the type only for the declaration it appears in, not other declarations involving the same type. \pnum -Each \grammarterm{decl-specifier} shall appear at most once in the complete -\grammarterm{decl-specifier-seq} of a declaration, except that -\tcode{long} may appear twice. +At most one of each of the \grammarterm{decl-specifier}s +\keyword{friend}, \keyword{typedef}, or \keyword{inline} +shall appear in a \grammarterm{decl-specifier-seq}. +At most one of +the \keyword{constexpr}, \keyword{consteval}, and \keyword{constinit} keywords +shall appear in a \grammarterm{decl-specifier-seq}. \pnum \indextext{ambiguity!declaration type}% If a \grammarterm{type-name} is encountered while parsing a \grammarterm{decl-specifier-seq}, it is interpreted as part of the \grammarterm{decl-specifier-seq} if and only if there is no -previous \grammarterm{type-specifier} other than a \grammarterm{cv-qualifier} in the +previous \grammarterm{defining-type-specifier} other than a \grammarterm{cv-qualifier} in the \grammarterm{decl-specifier-seq}. The sequence shall be self-consistent as described below. -\enterexample - +\begin{example} \begin{codeblock} typedef char* Pc; static Pc; // error: name missing \end{codeblock} - -Here, the declaration \tcode{static} \tcode{Pc} is ill-formed because no +Here, the declaration \keyword{static} \tcode{Pc} is ill-formed because no name was specified for the static variable of type \tcode{Pc}. To get a variable called \tcode{Pc}, a \grammarterm{type-specifier} (other than -\tcode{const} or \tcode{volatile}) has to be present to indicate that +\keyword{const} or \tcode{volatile}) has to be present to indicate that the \grammarterm{typedef-name} \tcode{Pc} is the name being (re)declared, rather than being part of the \grammarterm{decl-specifier} sequence. For another example, - \begin{codeblock} void f(const Pc); // \tcode{void f(char* const)} (not \tcode{const char*}) void g(const int Pc); // \tcode{void g(const int)} \end{codeblock} -\exitexample +\end{example} \pnum -\indextext{\idxcode{signed}!typedef@\tcode{typedef}~and}% -\indextext{\idxcode{unsigned}!typedef@\tcode{typedef}~and}% -\indextext{\idxcode{long}!typedef@\tcode{typedef}~and}% -\indextext{\idxcode{short}!typedef@\tcode{typedef}~and}% -\enternote +\indextext{\idxcode{signed}!typedef@\tcode{typedef} and}% +\indextext{\idxcode{unsigned}!typedef@\tcode{typedef} and}% +\indextext{\idxcode{long}!typedef@\tcode{typedef} and}% +\indextext{\idxcode{short}!typedef@\tcode{typedef} and}% +\begin{note} Since \tcode{signed}, \tcode{unsigned}, \tcode{long}, and \tcode{short} by default imply \tcode{int}, a \grammarterm{type-name} appearing after one of those specifiers is treated as the name being (re)declared. -\enterexample - +\begin{example} \begin{codeblock} void h(unsigned Pc); // \tcode{void h(unsigned int)} void k(unsigned int Pc); // \tcode{void k(unsigned int)} \end{codeblock} -\exitexample -\exitnote +\end{example} +\end{note} \rSec2[dcl.stc]{Storage class specifiers}% -\indextext{specifier!storage~class}% -\indextext{declaration!storage~class}% -\indextext{\idxcode{register}}% +\indextext{specifier!storage class}% +\indextext{declaration!storage class}% \indextext{\idxcode{static}}% \indextext{\idxcode{thread_local}}% \indextext{\idxcode{extern}}% @@ -302,114 +517,101 @@ \pnum The storage class specifiers are - \begin{bnf} \nontermdef{storage-class-specifier}\br - \terminal{register}\br - \terminal{static}\br - \terminal{thread_local}\br - \terminal{extern}\br - \terminal{mutable} + \keyword{static}\br + \keyword{thread_local}\br + \keyword{extern}\br + \keyword{mutable} \end{bnf} At most one \grammarterm{storage-class-specifier} shall appear in a given -\grammarterm{decl-specifier-seq}, except that \tcode{thread_local} may appear with \tcode{static} or -\tcode{extern}. If \tcode{thread_local} appears in any declaration of -a variable it shall be present in all declarations of that entity. If a +\grammarterm{decl-specifier-seq}, except that \keyword{thread_local} may appear with \keyword{static} or +\keyword{extern}. If \keyword{thread_local} appears in any declaration of +a variable it shall be present in all declarations of that entity. If a \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} of the declaration shall not be -empty (except for an anonymous union declared in a named namespace or in the -global namespace, which shall be declared -\indextext{specifier!\idxcode{static}}% -\tcode{static}~(\ref{class.union})). 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. A \grammarterm{storage-class-specifier} -other than \tcode{thread_local} -shall not be -specified in an explicit specialization~(\ref{temp.expl.spec}) or an -explicit instantiation~(\ref{temp.explicit}) directive. +other specifiers. +\begin{note} +See \ref{temp.expl.spec} and \ref{temp.explicit} for restrictions +in explicit specializations and explicit instantiations, respectively. +\end{note} \pnum -\indextext{restriction!\idxcode{register}}% -The \tcode{register} specifier shall be applied only to names of variables -declared in a block~(\ref{stmt.block}) or to function -parameters~(\ref{dcl.fct.def}). It specifies that the named variable has -automatic storage duration~(\ref{basic.stc.auto}). A variable declared -without a \grammarterm{storage-class-specifier} at block scope or declared -as a function parameter has automatic storage duration by default. +\begin{note} +A variable declared without a \grammarterm{storage-class-specifier} +at block scope or declared as a function parameter +has automatic storage duration by default\iref{basic.stc.auto}. +\end{note} \pnum -\indextext{declaration!\idxcode{register}}% -A \tcode{register} specifier is a hint to the implementation that the -variable so declared will be heavily used. -\enternote -The hint can be ignored and in most implementations it will be ignored -if the address of the variable is taken. This use is deprecated (see~\ref{depr.register}). -\exitnote - -\pnum -The \tcode{thread_local} specifier -indicates that the named entity has thread storage duration~(\ref{basic.stc.thread}). It +The \keyword{thread_local} specifier +indicates that the named entity has thread storage duration\iref{basic.stc.thread}. It shall be applied only -to the names of variables of namespace -or block scope and to the names of static data members. -When \tcode{thread_local} is applied to a variable of block scope the -\grammarterm{storage-class-specifier} \tcode{static} is implied if no other +to the declaration of a variable of namespace or block scope, +to a structured binding declaration\iref{dcl.struct.bind}, or +to the declaration of a static data member. +When \keyword{thread_local} is applied to a variable of block scope the +\grammarterm{storage-class-specifier} \keyword{static} is implied if no other \grammarterm{storage-class-specifier} appears in the \grammarterm{decl-specifier-seq}. \pnum \indextext{restriction!\idxcode{static}}% -The \tcode{static} specifier can be applied only to names of variables and -functions and to anonymous unions~(\ref{class.union}). There can be no -\tcode{static} function declarations within a block, nor any -\tcode{static} function parameters. A \tcode{static} specifier used in +The \keyword{static} specifier shall be applied only +to the declaration of a variable or function, +to a structured binding declaration\iref{dcl.struct.bind}, or +to the declaration of an anonymous union\iref{class.union.anon}. +There can be no +\keyword{static} function declarations within a block, nor any +\keyword{static} function parameters. A \tcode{static} specifier used in the declaration of a variable declares the variable to have static storage -duration~(\ref{basic.stc.static}), unless accompanied by the -\tcode{thread_local} specifier, which declares the variable to have thread -storage duration~(\ref{basic.stc.thread}). A \tcode{static} specifier can be +duration\iref{basic.stc.static}, unless accompanied by the +\keyword{thread_local} specifier, which declares the variable to have thread +storage duration\iref{basic.stc.thread}. A \keyword{static} specifier can be used in declarations of class members;~\ref{class.static} describes its effect. -\indextext{\idxcode{static}!linkage~of}% -For the linkage of a name declared with a \tcode{static} specifier, +\indextext{\idxcode{static}!linkage of}% +For the linkage of a name declared with a \keyword{static} specifier, see~\ref{basic.link}. \pnum \indextext{restriction!\idxcode{extern}}% -The \tcode{extern} specifier can be applied only to the names of variables -and functions. The \tcode{extern} specifier cannot be used in the -declaration of class members or function parameters. -\indextext{\idxcode{extern}!linkage~of}% +The \keyword{extern} specifier shall be applied only to the declaration of a variable +or function. The \keyword{extern} specifier shall not be used in the +declaration of a class member or function parameter. +\indextext{\idxcode{extern}!linkage of}% \indextext{consistency!linkage}% -For the linkage of a name declared with an \tcode{extern} specifier, +For the linkage of a name declared with an \keyword{extern} specifier, see~\ref{basic.link}. -\enternote -The \tcode{extern} keyword can also be used in -\nonterminal{explicit-instantiation}s and -\nonterminal{linkage-specification}s, but it is not a -\nonterminal{storage-class-specifier} in such contexts. -\exitnote - -\pnum -The linkages implied by successive declarations for a given entity shall -agree. That is, within a given scope, each declaration declaring the -same variable name or the same overloading of a function name shall imply -the same linkage. Each function in a given set of overloaded functions -can have a different linkage, however. -\enterexample -\indextext{example!linkage consistency}% - +\begin{note} +The \keyword{extern} keyword can also be used in +\grammarterm{explicit-instantiation}{s} and +\grammarterm{linkage-specification}{s}, but it is not a +\grammarterm{storage-class-specifier} in such contexts. +\end{note} + +\pnum +All declarations for a given entity shall give its name the same linkage. +\begin{note} +The linkage given by some declarations is affected by previous declarations. +Overloads are distinct entities. +\end{note} +\begin{example} \begin{codeblock} static char* f(); // \tcode{f()} has internal linkage char* f() // \tcode{f()} still has internal linkage - { /* ... */ } + { @\commentellip@ } char* g(); // \tcode{g()} has external linkage static char* g() // error: inconsistent linkage - { /* ... */ } + { @\commentellip@ } void h(); inline void h(); // external linkage @@ -435,15 +637,14 @@ extern int d; // \tcode{d} has external linkage static int d; // error: inconsistent linkage \end{codeblock} -\exitexample +\end{example} \pnum \indextext{declaration!forward}% The name of a declared but undefined class can be used in an -\tcode{extern} declaration. Such a declaration can only be used in ways +\keyword{extern} declaration. Such a declaration can only be used in ways that do not require a complete class type. -\enterexample - +\begin{example} \begin{codeblock} struct S; extern S a; @@ -455,251 +656,171 @@ f(); // error: \tcode{S} is incomplete } \end{codeblock} -\exitexample +\end{example} \pnum -The \tcode{mutable} specifier shall appear only in the declaration of -a non-static data member~(\ref{class.mem}) +The \keyword{mutable} specifier shall appear only in the declaration of +a non-static data member\iref{class.mem} whose type is neither const-qualified nor a reference type. -\enterexample - +\begin{example} \begin{codeblock} class X { mutable const int* p; // OK - mutable int* const q; // ill-formed + mutable int* const q; // error }; \end{codeblock} -\exitexample +\end{example} \pnum -The \tcode{mutable} specifier on a class data member nullifies a -\tcode{const} specifier applied to the containing class object and +\begin{note} +The \keyword{mutable} specifier on a class data member nullifies a +\keyword{const} specifier applied to the containing class object and permits modification of the mutable class member even though the rest of -the object is \tcode{const}~(\ref{dcl.type.cv}). +the object is const\iref{basic.type.qualifier,dcl.type.cv}. +\end{note} \rSec2[dcl.fct.spec]{Function specifiers}% \indextext{specifier!function}% -\indextext{function|seealso{friend function; member~function; inline~function; virtual~function}} +\indextext{function|seealso{friend function}} +\indextext{function|seealso{member function}} +\indextext{function|seealso{inline function}} +\indextext{function|seealso{virtual function}} \pnum -\grammarterm{Function-specifiers} -can be used only in function declarations. +A +\grammarterm{function-specifier} +can be used only in a function declaration. +At most one \grammarterm{explicit-specifier} and +at most one \keyword{virtual} keyword shall appear in +a \grammarterm{decl-specifier-seq}. \begin{bnf} \nontermdef{function-specifier}\br - \terminal{inline}\br - \terminal{virtual}\br - \terminal{explicit} + \keyword{virtual}\br + explicit-specifier \end{bnf} -\pnum -\indextext{specifier!\idxcode{inline}}% -\indextext{inline~function}% -A function declaration~(\ref{dcl.fct},~\ref{class.mfct}, -\ref{class.friend}) with an \tcode{inline} specifier declares an -\term{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 defined by~\ref{dcl.fct.spec} shall -still be respected. - -\pnum -A function defined within a class definition is an inline function. The -\tcode{inline} specifier shall not appear on a block scope function -declaration.\footnote{The inline keyword has no effect on the linkage of a function.} -If the \tcode{inline} specifier is used in a friend declaration, that -declaration shall be a definition or the function shall have previously -been declared inline. - -\pnum -An inline function shall be defined in every translation unit in which -it is odr-used and shall have exactly the same definition in every -case~(\ref{basic.def.odr}). -\enternote -A call to the inline function may be encountered before its definition -appears in the translation unit. -\exitnote -If the definition of a function appears in a translation unit before its -first declaration as inline, the program is ill-formed. If a function -with external linkage is declared inline in one translation unit, it -shall be declared inline in all translation units in which it appears; -no diagnostic is required. An \tcode{inline} function with external -linkage shall have the same address in all translation units. A -\tcode{static} local variable in an \tcode{extern} \tcode{inline} -function always refers to the same object. -A type defined within the body of an \tcode{extern inline} function is the -same type in every translation unit. +\begin{bnf} +\nontermdef{explicit-specifier}\br + \keyword{explicit} \terminal{(} constant-expression \terminal{)}\br + \keyword{explicit} +\end{bnf} \pnum \indextext{specifier!\idxcode{virtual}}% -The \tcode{virtual} specifier shall be used only in the initial -declaration of a non-static class member function; -see~\ref{class.virtual}. +The \keyword{virtual} specifier shall be used only in the initial +declaration of a non-static member function; see~\ref{class.virtual}. \pnum \indextext{specifier!\idxcode{explicit}}% -The \tcode{explicit} specifier shall be used only in the declaration of +An \grammarterm{explicit-specifier} shall be used only in the declaration of a constructor or conversion function within its class definition; see~\ref{class.conv.ctor} and~\ref{class.conv.fct}. -\rSec2[dcl.typedef]{The \tcode{typedef} specifier}% +\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.const}. +The \grammarterm{explicit-specifier} \keyword{explicit} +without a \grammarterm{constant-expression} is equivalent to +the \grammarterm{explicit-specifier} \tcode{explicit(true)}. +If the constant expression evaluates to \tcode{true}, +the function is explicit. Otherwise, the function is not explicit. +A \tcode{(} token that follows \keyword{explicit} is parsed as +part of the \grammarterm{explicit-specifier}. +\begin{example} +\begin{codeblock} +struct S { + explicit(sizeof(char[2])) S(char); // error: narrowing conversion of value 2 to type \keyword{bool} + explicit(sizeof(char)) S(bool); // OK, conversion of value 1 to type \keyword{bool} is non-narrowing +}; +\end{codeblock} +\end{example} + +\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} \tcode{typedef} -declare identifiers that can be used later for naming -fundamental~(\ref{basic.fundamental}) or compound~(\ref{basic.compound}) -types. The \tcode{typedef} specifier shall not be +Declarations containing the \grammarterm{decl-specifier} \keyword{typedef} +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{type-specifier,} and it shall not be used in the +specifier except a \grammarterm{defining-type-specifier}, and it shall not be used in the \grammarterm{decl-specifier-seq} of a -\grammarterm{parameter-declaration}~(\ref{dcl.fct}) nor in the +\grammarterm{parameter-declaration}\iref{dcl.fct} nor in the \grammarterm{decl-specifier-seq} of a -\grammarterm{function-definition}~(\ref{dcl.fct.def}). +\grammarterm{function-definition}\iref{dcl.fct.def}. +If a \keyword{typedef} specifier appears in a declaration without a \grammarterm{declarator}, +the program is ill-formed. \begin{bnf} \nontermdef{typedef-name}\br - identifier + identifier\br + simple-template-id \end{bnf} -A name declared with the \tcode{typedef} specifier becomes a -\grammarterm{typedef-name}. Within the scope of its declaration, a -\grammarterm{typedef-name} is syntactically equivalent to a keyword and -names the type associated with the identifier in the way described in -Clause~\ref{dcl.decl}. -\indextext{declaration!typedef@\tcode{typedef}~as type}% +A name declared with the \keyword{typedef} specifier becomes a +\grammarterm{typedef-name}. +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{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 -declaration~(\ref{class.name}) or enum declaration does. -\enterexample -\indextext{example!\idxcode{typedef}}% -after - +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 \begin{codeblock} typedef int MILES, *KLICKSP; \end{codeblock} - the constructions - \begin{codeblock} MILES distance; extern KLICKSP metricp; \end{codeblock} - are all correct declarations; the type of \tcode{distance} is -\tcode{int} and that of \tcode{metricp} is ``pointer to \tcode{int}.'' -\exitexample +\tcode{int} and that of \tcode{metricp} is ``pointer to \tcode{int}''. +\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 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}. -It has the same -semantics as if it were introduced by the \tcode{typedef} specifier. In -particular, it does not define a new type and it shall not appear in the -\grammarterm{type-id}. -\enterexample - +\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); extern handler_t ignore; extern void (*ignore)(int); // redeclare \tcode{ignore} -using cell = pair; // ill-formed -\end{codeblock} - -\exitexample - -\pnum -\indextext{redefinition!\idxcode{typedef}}% -In a given non-class scope, a \tcode{typedef} specifier can be used to -redefine the name of any type declared in that scope to refer to the -type to which it already refers. -\enterexample - -\begin{codeblock} -typedef struct s { /* ... */ } s; -typedef int I; -typedef int I; -typedef I I; -\end{codeblock} -\exitexample - -\pnum -In a given class scope, a \tcode{typedef} specifier can be used to -redefine any \grammarterm{class-name} declared in that scope that is not -also a \grammarterm{typedef-name} to refer to the type to which it already -refers. -\enterexample - -\begin{codeblock} -struct S { - typedef struct A { } A; // OK - typedef struct B B; // OK - typedef A A; // error -}; -\end{codeblock} -\exitexample - -\pnum -If a \tcode{typedef} specifier is used to redefine in a given scope an -entity that can be referenced using an \grammarterm{elaborated-type-specifier}, -the entity can continue to be referenced by an -\grammarterm{elaborated-type-specifier} or as an enumeration or class name -in an enumeration or class definition respectively. \enterexample -\begin{codeblock} -struct S; -typedef struct S S; -int main() { - struct S* p; // OK -} -struct S { }; // OK -\end{codeblock} -\exitexample - -\pnum -In a given scope, a \tcode{typedef} specifier shall not be used to -redefine the name of any type declared in that scope to refer to a -different type. -\enterexample - -\begin{codeblock} -class complex { /* ... */ }; -typedef int complex; // error: redefinition -\end{codeblock} -\exitexample - -\pnum -Similarly, in a given scope, a class or enumeration shall not be -declared with the same name as a \grammarterm{typedef-name} that is -declared in that scope and refers to a type other than the class or -enumeration itself. -\enterexample - -\begin{codeblock} -typedef int complex; -class complex @\tcode{\{ /* ... */ \}}@; // error: redefinition +template struct P { }; +using cell = P; // error: \tcode{cell} not found\iref{basic.scope.pdecl} \end{codeblock} -\exitexample - -\pnum -\enternote -\indextext{class~name!\idxcode{typedef}}% -A \grammarterm{typedef-name} that names a class type, or a cv-qualified -version thereof, is also a \grammarterm{class-name}~(\ref{class.name}). If -a \grammarterm{typedef-name} is used to identify the subject of an -\grammarterm{elaborated-type-specifier}~(\ref{dcl.type.elab}), a class -definition (Clause~\ref{class}), a constructor -declaration~(\ref{class.ctor}), or a destructor -declaration~(\ref{class.dtor}), the program is ill-formed. -\exitnote -\enterexample - +\end{example} +The \grammarterm{defining-type-specifier-seq} +of the \grammarterm{defining-type-id} shall not define +a class or enumeration if the \grammarterm{alias-declaration} +is the \grammarterm{declaration} of a \grammarterm{template-declaration}. + +\pnum +\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 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}. +If a \grammarterm{typedef-name} is used to identify the subject of an +\grammarterm{elaborated-type-specifier}\iref{dcl.type.elab}, a class +definition\iref{class}, a constructor +declaration\iref{class.ctor}, or a destructor +declaration\iref{class.dtor}, the program is ill-formed. +\end{note} +\begin{example} \begin{codeblock} struct S { S(); @@ -711,134 +832,148 @@ S a = T(); // OK struct T * p; // error \end{codeblock} -\exitexample +\end{example} \pnum -\indextext{class~name!\idxcode{typedef}}% -\indextext{enum~name!\idxcode{typedef}}% +\indextext{class name!\idxcode{typedef}}% +\indextext{enum name!\idxcode{typedef}}% \indextext{class!unnamed}% -If the typedef declaration defines an unnamed class (or enum), the first -\grammarterm{typedef-name} declared by the declaration to be that class -type (or enum type) is used to denote the class type (or enum type) for -linkage purposes only~(\ref{basic.link}). -\enterexample +An unnamed class or enumeration $C$ defined in a typedef declaration has +the first \grammarterm{typedef-name} +declared by the declaration to be of type $C$ +as its \defn{typedef name for linkage purposes}\iref{basic.link}. +\begin{note} +A typedef declaration involving a \grammarterm{lambda-expression} +does not itself define the associated closure type, +and so the closure type is not given a typedef name for linkage purposes. +\end{note} +\begin{example} +\begin{codeblock} +typedef struct { } *ps, S; // \tcode{S} is the typedef name for linkage purposes +typedef decltype([]{}) C; // the closure type has no typedef name for linkage purposes +\end{codeblock} +\end{example} +\pnum +An unnamed class with a typedef name for linkage purposes shall not +\begin{itemize} +\item + declare any members + other than non-static data members, member enumerations, or member classes, +\item + have any base classes or default member initializers, or +\item + contain a \grammarterm{lambda-expression}, +\end{itemize} +and all member classes shall also satisfy these requirements (recursively). +\begin{example} \begin{codeblock} -typedef struct { } *ps, S; // \tcode{S} is the class name for linkage purposes +typedef struct { + int f() {} +} X; // error: struct with typedef name for linkage has member functions \end{codeblock} -\exitexample +\end{example} -\rSec2[dcl.friend]{The \tcode{friend} specifier}% +\rSec2[dcl.friend]{The \keyword{friend} specifier}% \indextext{specifier!\idxcode{friend}} \pnum -The \tcode{friend} specifier is used to specify access to class members; +The \keyword{friend} specifier is used to specify access to class members; see~\ref{class.friend}. -\rSec2[dcl.constexpr]{The \tcode{constexpr} specifier}% +\rSec2[dcl.constexpr]{The \keyword{constexpr} and \keyword{consteval} specifiers}% \indextext{specifier!\idxcode{constexpr}} - -\pnum -The \tcode{constexpr} specifier shall be applied only to the definition of -a variable or variable template, -the declaration of a -function or function template, or the declaration of a static -data member of a literal type~(\ref{basic.types}). +\indextext{specifier!\idxcode{consteval}} + +\pnum +The \keyword{constexpr} specifier shall be applied only to +the definition of a variable or variable template, +a structured binding declaration, or +the declaration of a function or function template. +The \keyword{consteval} specifier shall be applied only to +the declaration of a function or function template. +A function or static data member +declared with the \keyword{constexpr} or \keyword{consteval} specifier +on its first declaration +is implicitly an inline function or variable\iref{dcl.inline}. If any declaration of a function or function template has -a \tcode{constexpr} specifier, -then all its declarations shall contain the \tcode{constexpr} specifier. \enternote An -explicit specialization can differ from the template declaration with respect to the -\tcode{constexpr} specifier. \exitnote -\enternote -Function parameters cannot be declared \tcode{constexpr}.\exitnote -\enterexample -\begin{codeblock} -constexpr void square(int &x); // OK: declaration -constexpr int bufsz = 1024; // OK: definition +a \keyword{constexpr} or \keyword{consteval} specifier, +then all its declarations shall contain the same specifier. +\begin{note} +An explicit specialization can differ from the template declaration +with respect to the \keyword{constexpr} or \keyword{consteval} specifier. +\end{note} +\begin{note} +Function parameters cannot be declared \keyword{constexpr}. +\end{note} +\begin{example} +\begin{codeblock} +constexpr void square(int &x); // OK, declaration +constexpr int bufsz = 1024; // OK, definition constexpr struct pixel { // error: \tcode{pixel} is a type int x; int y; - constexpr pixel(int); // OK: declaration -}; + constexpr pixel(int); // OK, declaration +}; constexpr pixel::pixel(int a) - : x(a), y(x) // OK: definition + : x(a), y(x) // OK, definition { square(x); } constexpr pixel small(2); // error: \tcode{square} not defined, so \tcode{small(2)} - // not constant~(\ref{expr.const}) so \tcode{constexpr} not satisfied + // not constant\iref{expr.const.core} so \keyword{constexpr} not satisfied -constexpr void square(int &x) { // OK: definition +constexpr void square(int &x) { // OK, definition x *= x; } -constexpr pixel large(4); // OK: \tcode{square} defined +constexpr pixel large(4); // OK, \tcode{square} defined int next(constexpr int x) { // error: not for parameters return x + 1; -} -extern constexpr int memsz; // error: not a definition +} +extern constexpr int memsz; // error: not a definition \end{codeblock} -\exitexample +\end{example} \pnum -A \tcode{constexpr} specifier used in the declaration of a function that is not a -constructor declares that -function to be a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}. Similarly, a -\tcode{constexpr} specifier used in -a constructor declaration declares that constructor to be a -\defnx{constexpr constructor}{specifier!\idxcode{constexpr}!constructor}. -\tcode{constexpr} functions and \tcode{constexpr} constructors are -implicitly \tcode{inline}~(\ref{dcl.fct.spec}). +A \keyword{constexpr} or \keyword{consteval} specifier +used in the declaration of a function +declares that function to be +a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}. +\begin{note} +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. \pnum -\indextext{specifier!\idxcode{constexpr}!function} -\indextext{constexpr function} -The definition of a \tcode{constexpr} function shall satisfy the following -constraints: - -\begin{itemize} -\item -it shall not be virtual~(\ref{class.virtual}); - -\item -its return type shall be a literal type; - -\item -each of its parameter types shall be a literal type; - -\item -its \grammarterm{function-body} shall be -\tcode{= delete}, \tcode{= default}, or -a \grammarterm{compound-statement} -that does not contain - -\begin{itemize} -\item an \grammarterm{asm-definition}, -\item a \tcode{goto} statement, -\item a \grammarterm{try-block}, or -\item a definition of a variable -of non-literal type or -of static or thread storage duration or -for which no initialization is performed. -\end{itemize} +\indextext{specifier!\idxcode{constexpr}!function}% +\indextext{constexpr function}% +A function is \defn{constexpr-suitable} if +it is not a coroutine\iref{dcl.fct.def.coroutine}. -\end{itemize} +Except for instantiated constexpr functions, +non-templated constexpr functions shall be constexpr-suitable. -\enterexample +\begin{example} \begin{codeblock} -constexpr int square(int x) +constexpr int square(int x) { return x * x; } // OK -constexpr long long_max() +constexpr long long_max() { return 2147483647; } // OK constexpr int abs(int x) { if (x < 0) x = -x; return x; // OK } -constexpr int first(int n) { - static int value = n; // error: variable has static storage duration - return value; +constexpr int constant_non_42(int n) { // OK + if (n == 42) { + static int value = n; + return value; + } + return n; } constexpr int uninit() { - int a; // error: variable is uninitialized - return a; + struct { int a; } s; + return s.a; // error: uninitialized read of \tcode{s.a} } constexpr int prev(int x) { return --x; } // OK @@ -848,165 +983,191 @@ return r; } \end{codeblock} -\exitexample +\end{example} \pnum -\indextext{specifier!\idxcode{constexpr}!constructor}% -The definition of a \tcode{constexpr} constructor shall satisfy the -following constraints: - -\begin{itemize} -\item -the class shall not have any virtual base classes; - -\item -each of the parameter types shall be a literal type; - -\item -its \grammarterm{function-body} shall not be a \grammarterm{function-try-block}; -\end{itemize} - -In addition, either its \grammarterm{function-body} shall be -\tcode{= delete}, or it shall satisfy the following constraints: - +An invocation of a constexpr function in a given context +produces the same result as +an invocation of an equivalent non-constexpr function in the same context +in all respects except that \begin{itemize} \item -either its \grammarterm{function-body} shall be \tcode{= default}, or the \grammarterm{compound-statement} of its \grammarterm{function-body} -shall satisfy the constraints for a \grammarterm{function-body} of a -\tcode{constexpr} function; - -\item -every non-variant non-static data member and base class sub-object -shall be initialized~(\ref{class.base.init}); - -\item -if the class is a union having variant members~(\ref{class.union}), exactly one of them -shall be initialized; - -\item -if the class is a union-like class, but is not a union, for each of its anonymous union -members having variant members, exactly one of them shall be initialized; - -\item -for a non-delegating constructor, every constructor selected to initialize non-static -data members and base class sub-objects shall be a \tcode{constexpr} constructor; - +an invocation of a constexpr function +can appear in a constant expression\iref{expr.const.core} and \item -for a delegating constructor, the target constructor shall be a \tcode{constexpr} -constructor. +copy elision is not performed in a constant expression\iref{class.copy.elision}. \end{itemize} - -\enterexample +\begin{note} +Declaring a function constexpr can change whether an expression +is a constant expression. +This can indirectly cause calls to \tcode{std::is_constant_evaluated} +within an invocation of the function to produce a different value. +\end{note} +\begin{note} +It is possible to write a constexpr function for which +no invocation satisfies the requirements of a core constant expression. +\end{note} + +\pnum +The \keyword{constexpr} and \keyword{consteval} specifiers have no +effect on the type of a constexpr function. +\begin{example} \begin{codeblock} -struct Length { - constexpr explicit Length(int i = 0) : val(i) { } -private: - int val; -}; +constexpr int bar(int x, int y) // OK + { return x + y + x*y; } +// ... +int bar(int x, int y) // error: redefinition of \tcode{bar} + { return x * 2 + 3 * y; } \end{codeblock} -\exitexample +\end{example} \pnum -For a non-template, non-defaulted -\tcode{constexpr} function or a non-template, non-defaulted, non-inheriting -\tcode{constexpr} constructor, if no argument values exist such that -an invocation of the function or constructor could be an evaluated subexpression of a core -constant expression~(\ref{expr.const}), or, -for a constructor, a constant initializer for some object~(\ref{basic.start.init}), -the program is ill-formed; no diagnostic required. -\enterexample +A \keyword{constexpr} specifier used in an object declaration +declares the object as const. +Such an object +shall have literal type and +shall be initialized. +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. +\begin{example} \begin{codeblock} -constexpr int f(bool b) - { return b ? throw 0 : 0; } // OK -constexpr int f() { return f(true); } // ill-formed, no diagnostic required - -struct B { - constexpr B(int x) : i(0) { } // \tcode{x} is unused - int i; +struct pixel { + int x, y; }; +constexpr pixel ur = { 1294, 1024 }; // OK +constexpr pixel origin; // error: initializer missing -int global; - -struct D : B { - constexpr D() : B(global) { } // ill-formed, no diagnostic required - // lvalue-to-rvalue conversion on non-constant \tcode{global} -}; +namespace N { + void f() { + int x; + constexpr int& ar = x; // OK + static constexpr int& sr = x; // error: \tcode{x} is not constexpr-representable + // at the point indicated below + } + // immediate scope here is that of \tcode{N} +} \end{codeblock} +\end{example} -\exitexample +\rSec2[dcl.constinit]{The \keyword{constinit} specifier} +\indextext{specifier!\idxcode{constinit}} \pnum -If the instantiated template specialization of a \tcode{constexpr} function -template -or member function of a class template -would fail to satisfy the requirements for a \tcode{constexpr} -function or \tcode{constexpr} constructor, -that specialization is still a \tcode{constexpr} function or \tcode{constexpr} -constructor, even though a call to such a function cannot appear in a constant -expression. If no specialization of the template would satisfy the -requirements for a \tcode{constexpr} function or \tcode{constexpr} constructor -when considered as a non-template function or constructor, the template is -ill-formed; no diagnostic -required. +The \keyword{constinit} specifier shall be applied only +to a declaration of a variable with static or thread storage duration +or to a structured binding declaration\iref{dcl.struct.bind}. +\begin{note} +A structured binding declaration introduces a uniquely named variable, +to which the \tcode{constinit} specifier applies. +\end{note} +If the specifier is applied to any declaration of a variable, +it shall be applied to the initializing declaration. +No diagnostic is required if no \keyword{constinit} declaration +is reachable at the point of the initializing declaration. \pnum -A call to a \tcode{constexpr} function produces the same result as a call to an equivalent -non-\tcode{constexpr} function in all respects except that a call to a \tcode{constexpr} -function can appear in a constant expression. +If a variable declared with the \keyword{constinit} specifier has +dynamic initialization\iref{basic.start.dynamic}, the program is ill-formed, +even if the implementation would perform that initialization as +a static initialization\iref{basic.start.static}. +\begin{note} +The \keyword{constinit} specifier ensures that the variable +is initialized during static initialization. +\end{note} \pnum -The \tcode{constexpr} specifier has no -effect on the type of a \tcode{constexpr} function or a \tcode{constexpr} constructor. \enterexample +\begin{example} \begin{codeblock} -constexpr int bar(int x, int y) // OK - { return x + y + x*y; } -// ... -int bar(int x, int y) // error: redefinition of \tcode{bar} - { return x * 2 + 3 * y; } +const char * g() { return "dynamic initialization"; } +constexpr const char * f(bool p) { return p ? "constant initializer" : g(); } +constinit const char * c = f(true); // OK +constinit const char * d = f(false); // error \end{codeblock} -\exitexample +\end{example} + +\rSec2[dcl.inline]{The \keyword{inline} specifier}% +\indextext{specifier!\idxcode{inline}} \pnum -A \tcode{constexpr} specifier used in an object -declaration declares the object as \tcode{const}. -Such an object -shall have literal type and -shall be initialized. -If it is initialized by a constructor call, -that call shall be a constant expression~(\ref{expr.const}). -Otherwise, -or if a \tcode{constexpr} specifier is used in a reference declaration, -every full-expression that appears in its initializer shall be a constant expression. \enternote Each -implicit conversion used in converting the initializer expressions and each constructor call -used for the initialization is part of such a full-expression. \exitnote -\enterexample -\begin{codeblock} -struct pixel { - int x, y; -}; -constexpr pixel ur = { 1294, 1024 };// OK -constexpr pixel origin; // error: initializer missing -\end{codeblock} -\exitexample +\indextext{specifier!\idxcode{inline}}% +\indextext{inline function}% +\indextext{inline variable}% +The \keyword{inline} specifier shall be applied only to the declaration +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. -\rSec2[dcl.type]{Type specifiers}% -\indextext{specifier!type|see{type~specifier}} +\pnum +A function declaration\iref{dcl.fct,class.mfct,class.friend} +with an \keyword{inline} specifier declares an +\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; +see~\ref{basic.link}. +\end{note} \pnum -The type-specifiers are +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. -\indextext{type!\idxcode{const}}% +\pnum +If a definition of a function or variable is reachable +at the point of its +first declaration as inline, the program is ill-formed. If a function or variable +with external or module linkage +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. +\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 +If an inline function or variable that is attached to a named module +is declared in a definition domain, +it shall be defined in that domain. +\begin{note} +A constexpr function\iref{dcl.constexpr} is implicitly inline. +In the global module, a function defined within a class definition +is implicitly inline\iref{class.mfct,class.friend}. +\end{note} + +\rSec2[dcl.type]{Type specifiers}% + +\rSec3[dcl.type.general]{General}% +\indextext{specifier!type|see{type specifier}} + +\pnum +The type-specifiers are +\indextext{type!\idxcode{const}}% \indextext{type!\idxcode{volatile}}% % \begin{bnf} \nontermdef{type-specifier}\br - trailing-type-specifier\br - class-specifier\br - enum-specifier -\end{bnf} - -\begin{bnf} -\nontermdef{trailing-type-specifier}\br simple-type-specifier\br elaborated-type-specifier\br typename-specifier\br @@ -1015,31 +1176,44 @@ \begin{bnf} \nontermdef{type-specifier-seq}\br - type-specifier attribute-specifier-seq\opt\br + type-specifier \opt{attribute-specifier-seq}\br type-specifier type-specifier-seq \end{bnf} \begin{bnf} -\nontermdef{trailing-type-specifier-seq}\br - trailing-type-specifier attribute-specifier-seq\opt\br - trailing-type-specifier trailing-type-specifier-seq +\nontermdef{defining-type-specifier}\br + type-specifier\br + class-specifier\br + enum-specifier +\end{bnf} + +\begin{bnf} +\nontermdef{defining-type-specifier-seq}\br + defining-type-specifier \opt{attribute-specifier-seq}\br + defining-type-specifier defining-type-specifier-seq \end{bnf} The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{type-specifier-seq} -or a \grammarterm{trailing-type-specifier-seq} +or a \grammarterm{defining-type-specifier-seq} appertains -to the type denoted by the preceding \grammarterm{type-specifier}{s}~(\ref{dcl.meaning}). The +to the type denoted by the preceding \grammarterm{type-specifier}{s} +or \grammarterm{defining-type-specifier}{s}\iref{dcl.meaning}. The \grammarterm{attribute-specifier-seq} affects the type only for the declaration it appears in, not other declarations involving the same type. \pnum -As a general rule, at most one \grammarterm{type-specifier} is allowed in the complete +As a general rule, at most one +\grammarterm{defining-type-specifier} +is allowed in the complete \grammarterm{decl-specifier-seq} of a \grammarterm{declaration} or in a -\grammarterm{type-specifier-seq} or \grammarterm{trailing-type-specifier-seq}. +\grammarterm{defining-type-specifier-seq}, +and at most one +\grammarterm{type-specifier} +is allowed in a +\grammarterm{type-specifier-seq}. The only exceptions to this rule are the following: - \begin{itemize} -\item \tcode{const} can be combined with any type specifier except itself. +\item \keyword{const} can be combined with any type specifier except itself. \item \tcode{volatile} can be combined with any type specifier except itself. @@ -1055,21 +1229,13 @@ \pnum Except in a declaration of a constructor, destructor, or conversion -function, at least one \grammarterm{type-specifier} that is not a +function, at least one \grammarterm{defining-type-specifier} that is not a \grammarterm{cv-qualifier} shall appear in a complete \grammarterm{type-specifier-seq} or a complete -\grammarterm{decl-specifier-seq}.\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.} -A \grammarterm{type-specifier-seq} shall not define a class or enumeration unless -it appears in the \grammarterm{type-id} of an -\grammarterm{alias-declaration}~(\ref{dcl.typedef}) that is not the \grammarterm{declaration} -of a \grammarterm{template-declaration}. - -\pnum -\enternote +\grammarterm{decl-specifier-seq}. + +\pnum +\begin{note} \grammarterm{enum-specifier}{s}, \grammarterm{class-specifier}{s}, and @@ -1077,39 +1243,44 @@ are discussed in \ref{dcl.enum}, -Clause~\ref{class}, +\ref{class}, and \ref{temp.res}, respectively. The remaining -\grammarterm{type-specifier}{s} are discussed in the rest of this section. -\exitnote +\grammarterm{type-specifier}{s} are discussed in the rest of \ref{dcl.type}. +\end{note} -\rSec3[dcl.type.cv]{The \grammarterm{cv-qualifiers}}% +\rSec3[dcl.type.cv]{The \fakegrammarterm{cv-qualifier}{s}}% \indextext{specifier!cv-qualifier}% \indextext{initialization!\idxcode{const}}% \indextext{type specifier!\idxcode{const}}% \indextext{type specifier!\idxcode{volatile}} \pnum -There are two \grammarterm{cv-qualifiers}, \tcode{const} and +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} of -the declaration shall not be empty. -\enternote +\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. -\exitnote -Redundant cv-qualifications are ignored. \enternote For example, -these could be introduced by typedefs.\exitnote +\end{note} +Redundant cv-qualifications are ignored. +\begin{note} +For example, +these could be introduced by typedefs. +\end{note} \pnum -\enternote -Declaring a variable \tcode{const} can affect its linkage~(\ref{dcl.stc}) -and its usability in constant expressions~(\ref{expr.const}). As +\begin{note} +Declaring a variable \keyword{const} can affect its linkage\iref{dcl.stc} +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. -\exitnote +\end{note} \pnum A pointer or reference to a cv-qualified type need not actually point or @@ -1117,39 +1288,35 @@ const-qualified access path cannot be used to modify an object even if the object referenced is a non-const object and can be modified through some other access path. -\enternote +\begin{note} Cv-qualifiers are supported by the type system so that they cannot be -subverted without casting~(\ref{expr.const.cast}). -\exitnote +subverted without casting\iref{expr.const.cast}. +\end{note} \pnum -\indextext{const~object@\tcode{const}-object!undefined change~to}% -Except that any class member declared \tcode{mutable}~(\ref{dcl.stc}) -can be modified, any attempt to modify a \tcode{const} object during its -lifetime~(\ref{basic.life}) results in undefined behavior. -\enterexample - +\indextext{const object!undefined change to}% +Any attempt to modify\iref{expr.assign,expr.post.incr,expr.pre.incr} a +const object\iref{basic.type.qualifier} during its +lifetime\iref{basic.life} results in undefined behavior. +\begin{example} \begin{codeblock} -const int ci = 3; // cv-qualified (initialized as required) -ci = 4; // ill-formed: attempt to modify \tcode{const} +const int ci = 3; // cv-qualified (initialized as required) +ci = 4; // error: attempt to modify \keyword{const} -int i = 2; // not cv-qualified -const int* cip; // pointer to \tcode{const int} -cip = &i; // OK: cv-qualified access path to unqualified -*cip = 4; // ill-formed: attempt to modify through ptr to \tcode{const} +int i = 2; // not cv-qualified +const int* cip; // pointer to \tcode{const int} +cip = &i; // OK, cv-qualified access path to unqualified +*cip = 4; // error: attempt to modify through ptr to \keyword{const} int* ip; -ip = const_cast(cip); // cast needed to convert \tcode{const int*} to \tcode{int*} -*ip = 4; // defined: \tcode{*ip} points to \tcode{i}, a non-\tcode{const} object +ip = const_cast(cip); // cast needed to convert \tcode{const int*} to \tcode{int*} +*ip = 4; // defined: \tcode{*ip} points to \tcode{i}, a non-const object const int* ciq = new const int (3); // initialized as required int* iq = const_cast(ciq); // cast required -*iq = 4; // undefined: modifies a \tcode{const} object +*iq = 4; // undefined behavior: modifies a const object \end{codeblock} - -\pnum -For another example - +For another example, \begin{codeblock} struct X { mutable int i; @@ -1161,1783 +1328,7202 @@ }; const Y y; -y.x.i++; // well-formed: \tcode{mutable} member can be modified -y.x.j++; // ill-formed: \tcode{const}-qualified member modified -Y* p = const_cast(&y); // cast away const-ness of \tcode{y} -p->x.i = 99; // well-formed: \tcode{mutable} member can be modified -p->x.j = 99; // undefined: modifies a \tcode{const} member +y.x.i++; // well-formed: \keyword{mutable} member can be modified +y.x.j++; // error: const-qualified member modified +Y* p = const_cast(&y); // cast away const-ness of \tcode{y} +p->x.i = 99; // well-formed: \keyword{mutable} member can be modified +p->x.j = 99; // undefined behavior: modifies a const subobject \end{codeblock} -\exitexample +\end{example} \pnum -What constitutes an access to an object that has volatile-qualified type is -implementation-defined. -If an attempt is made to refer to an object defined with a -volatile-qualified type through the use of a glvalue with a -non-volatile-qualified type, the program behavior is undefined. +The semantics of an access through a volatile glvalue are +\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. \pnum -\indextext{type~specifier!\idxcode{volatile}}% +\indextext{type specifier!\idxcode{volatile}}% \indextext{\idxcode{volatile}!implementation-defined}% -\enternote +\begin{note} \tcode{volatile} is a hint to the implementation to avoid aggressive -optimization involving the object because the value of the object might -be changed by means undetectable by an implementation. -Furthermore, for some implementations, \tcode{volatile} might indicate that -special hardware instructions are required to access the object. +optimization involving the object because it is possible for the value of the object +to change by means undetectable by an implementation. +Furthermore, for some implementations, \tcode{volatile} can indicate that +special hardware instructions are needed to access the object. See~\ref{intro.execution} for detailed semantics. In general, the -semantics of \tcode{volatile} are intended to be the same in \Cpp as +semantics of \tcode{volatile} are intended to be the same in \Cpp{} as they are in C. -\exitnote +\end{note} \rSec3[dcl.type.simple]{Simple type specifiers}% \indextext{type specifier!simple} \pnum The simple type specifiers are - \begin{bnf} \nontermdef{simple-type-specifier}\br - nested-name-specifier\opt type-name\br - nested-name-specifier \terminal{template} simple-template-id\br - \terminal{char}\br - \terminal{char16_t}\br - \terminal{char32_t}\br - \terminal{wchar_t}\br - \terminal{bool}\br - \terminal{short}\br - \terminal{int}\br - \terminal{long}\br - \terminal{signed}\br - \terminal{unsigned}\br - \terminal{float}\br - \terminal{double}\br - \terminal{void}\br - \terminal{auto}\br - decltype-specifier + \opt{nested-name-specifier} type-name\br + nested-name-specifier \keyword{template} simple-template-id\br + computed-type-specifier\br + placeholder-type-specifier\br + \opt{nested-name-specifier} template-name\br + \keyword{char}\br + \keyword{char8_t}\br + \keyword{char16_t}\br + \keyword{char32_t}\br + \keyword{wchar_t}\br + \keyword{bool}\br + \keyword{short}\br + \keyword{int}\br + \keyword{long}\br + \keyword{signed}\br + \keyword{unsigned}\br + \keyword{float}\br + \keyword{double}\br + \keyword{void} \end{bnf} \begin{bnf} \nontermdef{type-name}\br class-name\br enum-name\br - typedef-name\br - simple-template-id + typedef-name \end{bnf} \begin{bnf} -\nontermdef{decltype-specifier}\br - \terminal{decltype} \terminal{(} expression \terminal{)}\br - \terminal{decltype} \terminal{(} \terminal{auto} \terminal{)} -\end{bnf} - -\pnum -\indextext{type~specifier!\idxcode{char}}% -\indextext{type~specifier!\idxcode{char16_t}}% -\indextext{type~specifier!\idxcode{char32_t}}% -\indextext{type-specifier!\idxcode{wchar_t}}% -\indextext{type-specifier!\idxcode{bool}}% -\indextext{type~specifier!\idxcode{short}}% -\indextext{type~specifier!\idxcode{int}}% -\indextext{type~specifier!\idxcode{long}}% -\indextext{type~specifier!\idxcode{signed}}% -\indextext{type~specifier!\idxcode{unsigned}}% -\indextext{type~specifier!\idxcode{float}}% -\indextext{type~specifier!\idxcode{double}}% -\indextext{type~specifier!\idxcode{void}}% -\indextext{type~specifier!\idxcode{auto}}% -\indextext{type~specifier!\idxcode{decltype}}% +\nontermdef{computed-type-specifier}\br + decltype-specifier\br + pack-index-specifier\br + splice-type-specifier +\end{bnf} + +\pnum +\indextext{component name} +The component names of a \grammarterm{simple-type-specifier} are those of its +\grammarterm{nested-name-specifier}, +\grammarterm{type-name}, +\grammarterm{simple-template-id}, +\grammarterm{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. + +\pnum +\indextext{type specifier!\idxcode{char}}% +\indextext{type specifier!\idxcode{char8_t}}% +\indextext{type specifier!\idxcode{char16_t}}% +\indextext{type specifier!\idxcode{char32_t}}% +\indextext{type specifier!\idxcode{wchar_t}}% +\indextext{type specifier!\idxcode{bool}}% +\indextext{type specifier!\idxcode{short}}% +\indextext{type specifier!\idxcode{int}}% +\indextext{type specifier!\idxcode{long}}% +\indextext{type specifier!\idxcode{signed}}% +\indextext{type specifier!\idxcode{unsigned}}% +\indextext{type specifier!\idxcode{float}}% +\indextext{type specifier!\idxcode{double}}% +\indextext{type specifier!\idxcode{void}}% \indextext{\idxgram{type-name}}% \indextext{\idxgram{lambda-introducer}}% -The \grammarterm{simple-type-specifier} \tcode{auto} is a placeholder for a type to be -deduced~(\ref{dcl.spec.auto}). +A \grammarterm{placeholder-type-specifier} +is a placeholder for +a type to be deduced\iref{dcl.spec.auto}. +\indextext{deduction!class template arguments}% +A \grammarterm{type-specifier} is a placeholder for +a deduced class type\iref{dcl.type.class.deduct} if either +\begin{itemize} +\item +it is of the form +\opt{\keyword{typename}} \opt{\grammarterm{nested-name-specifier}} \grammarterm{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{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 +\end{ncsimplebnf} + +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 +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}. +\end{note} The other \grammarterm{simple-type-specifier}{s} specify either a previously-declared type, a type determined from an expression, or one of the -fundamental types~(\ref{basic.fundamental}). -Table~\ref{tab:simple.type.specifiers} +fundamental types\iref{basic.fundamental}. +\tref{dcl.type.simple} summarizes the valid combinations of \grammarterm{simple-type-specifier}{s} and the types they specify. \begin{simpletypetable} {\grammarterm{simple-type-specifier}{s} and the types they specify} -{tab:simple.type.specifiers} +{dcl.type.simple} {ll} \topline -Specifier(s) & Type \\ \capsep -\grammarterm{type-name} & the type named \\ -\grammarterm{simple-template-id} & the type as defined in~\ref{temp.names} \\ -char & ``char'' \\ -unsigned char & ``unsigned char'' \\ -signed char & ``signed char'' \\ -char16_t & ``char16_t'' \\ -char32_t & ``char32_t'' \\ -bool & ``bool'' \\ -unsigned & ``unsigned int'' \\ -unsigned int & ``unsigned int'' \\ -signed & ``int'' \\ -signed int & ``int'' \\ -int & ``int'' \\ -unsigned short int & ``unsigned short int'' \\ -unsigned short & ``unsigned short int'' \\ -unsigned long int & ``unsigned long int'' \\ -unsigned long & ``unsigned long int'' \\ -unsigned long long int & ``unsigned long long int''\\ -unsigned long long & ``unsigned long long int''\\ -signed long int & ``long int'' \\ -signed long & ``long int'' \\ -signed long long int & ``long long int'' \\ -signed long long & ``long long int'' \\ -long long int & ``long long int'' \\ -long long & ``long long int'' \\ -long int & ``long int'' \\ -long & ``long int'' \\ -signed short int & ``short int'' \\ -signed short & ``short int'' \\ -short int & ``short int'' \\ -short & ``short int'' \\ -wchar_t & ``wchar_t'' \\ -float & ``float'' \\ -double & ``double'' \\ -long double & ``long double'' \\ -void & ``void'' \\ -auto & placeholder for a type to be deduced\\ -decltype(\grammarterm{expression}) & the type as defined below\\ +\hdstyle{Specifier(s)} & \hdstyle{Type} \\ \capsep +\grammarterm{type-name} & the type named \\ +\grammarterm{simple-template-id} & the type as defined in~\ref{temp.names}\\ +\grammarterm{decltype-specifier} & the type as defined in~\ref{dcl.type.decltype}\\ +\grammarterm{pack-index-specifier} & the type as defined in~\ref{dcl.type.pack.index}\\ +\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}'' \\ +\keyword{char8_t} & ``\tcode{char8_t}'' \\ +\keyword{char16_t} & ``\tcode{char16_t}'' \\ +\keyword{char32_t} & ``\tcode{char32_t}'' \\ +\tcode{bool} & ``\tcode{bool}'' \\ +\tcode{unsigned} & ``\tcode{unsigned int}'' \\ +\tcode{unsigned int} & ``\tcode{unsigned int}'' \\ +\tcode{signed} & ``\tcode{int}'' \\ +\tcode{signed int} & ``\tcode{int}'' \\ +\tcode{int} & ``\tcode{int}'' \\ +\tcode{unsigned short int} & ``\tcode{unsigned short int}'' \\ +\tcode{unsigned short} & ``\tcode{unsigned short int}'' \\ +\tcode{unsigned long int} & ``\tcode{unsigned long int}'' \\ +\tcode{unsigned long} & ``\tcode{unsigned long int}'' \\ +\tcode{unsigned long long int} & ``\tcode{unsigned long long int}''\\ +\tcode{unsigned long long} & ``\tcode{unsigned long long int}''\\ +\tcode{signed long int} & ``\tcode{long int}'' \\ +\tcode{signed long} & ``\tcode{long int}'' \\ +\tcode{signed long long int} & ``\tcode{long long int}'' \\ +\tcode{signed long long} & ``\tcode{long long int}'' \\ +\tcode{long long int} & ``\tcode{long long int}'' \\ +\tcode{long long} & ``\tcode{long long int}'' \\ +\tcode{long int} & ``\tcode{long int}'' \\ +\tcode{long} & ``\tcode{long int}'' \\ +\tcode{signed short int} & ``\tcode{short int}'' \\ +\tcode{signed short} & ``\tcode{short int}'' \\ +\tcode{short int} & ``\tcode{short int}'' \\ +\tcode{short} & ``\tcode{short int}'' \\ +\keyword{wchar_t} & ``\tcode{wchar_t}'' \\ +\tcode{float} & ``\tcode{float}'' \\ +\tcode{double} & ``\tcode{double}'' \\ +\tcode{long double} & ``\tcode{long double}'' \\ +\keyword{void} & ``\tcode{void}'' \\ \end{simpletypetable} \pnum -When multiple \grammarterm{simple-type-specifiers} are allowed, they can be -freely intermixed with other \grammarterm{decl-specifiers} in any order. -\enternote -It is implementation-defined whether objects of \tcode{char} type are +When multiple \grammarterm{simple-type-specifier}{s} are allowed, they can be +freely intermixed with other \grammarterm{decl-specifier}{s} in any order. +\begin{note} +It is \impldef{signedness of \tcode{char}} whether objects of \tcode{char} type are represented as signed or unsigned quantities. The \tcode{signed} specifier forces \tcode{char} objects to be signed; it is redundant in other contexts. -\exitnote -\clearpage - -\pnum -\indextext{type~specifier!\idxcode{decltype}}% -For an expression \tcode{e}, the type denoted by \tcode{decltype(e)} is defined as follows: -\begin{itemize} -\item if \tcode{e} is an unparenthesized \grammarterm{id-expression} or -an unparenthesized -class -member access~(\ref{expr.ref}), \tcode{decltype(e)} is the -type of the entity named by \tcode{e}. If there is no such entity, or -if \tcode{e} names a set of overloaded functions, the program is -ill-formed; +\end{note} -\item otherwise, if \tcode{e} is -an xvalue, \tcode{decltype(e)} is \tcode{T\&\&}, where \tcode{T} is the type -of \tcode{e}; +\rSec3[dcl.type.pack.index]{Pack indexing specifier} -\item otherwise, if \tcode{e} is an lvalue, \tcode{decltype(e)} -is \tcode{T\&}, where \tcode{T} is the type of \tcode{e}; +\begin{bnf} +\nontermdef{pack-index-specifier}\br + typedef-name \terminal{...} \terminal{[} constant-expression \terminal{]} +\end{bnf} -\item otherwise, \tcode{decltype(e)} is the type of \tcode{e}. -\end{itemize} +\pnum +The \grammarterm{typedef-name} $P$ in a \grammarterm{pack-index-specifier} +shall be an \grammarterm{identifier} that denotes a pack. -The operand of the \tcode{decltype} specifier is an unevaluated -operand (Clause~\ref{expr}). +\pnum +The \grammarterm{constant-expression} shall be +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$)}$. -\enterexample -\begin{codeblock} -const int&& foo(); -int i; -struct A { double x; }; -const A* a = new A(); -decltype(foo()) x1 = 17; // type is \tcode{const int\&\&} -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\&} -\end{codeblock} -\exitexample -\enternote -The rules for determining types involving \tcode{decltype(auto)} are specified -in~\ref{dcl.spec.auto}. -\exitnote +\pnum +A \grammarterm{pack-index-specifier} is a pack expansion\iref{temp.variadic}. \pnum -\enternote in the case where the operand of a \grammarterm{decltype-specifier} -is a function call and the return type of the function is a class type, a -special rule~(\ref{expr.call}) ensures that the return type is not required to -be complete (as it would be if the call appeared in a sub-expression or outside -of a \grammarterm{decltype-specifier}). In this context, the common purpose of -writing the expression is merely to refer to its type. In that sense, a -\grammarterm{decltype-specifier} is analogous to a use of a \grammarterm{typedef-name}, -so the usual reasons for requiring a complete type do not apply. In particular, -it is not necessary to allocate storage for a temporary object or to enforce the -semantic constraints associated with invoking the type's destructor. \enterexample -\begin{codeblock} -template struct A { ~A() = delete; }; -template auto h() - -> A; -template auto i(T) // identity - -> T; -template auto f(T) // \#1 - -> decltype(i(h())); // forces completion of \tcode{A} and implicitly uses - // \tcode{A::\~{}A()} for the temporary introduced by the - // use of \tcode{h()}. (A temporary is not introduced - // as a result of the use of \tcode{i()}.) -template auto f(T) // \#2 - -> void; -auto g() -> void { - f(42); // OK: calls \#2. (\#1 is not a viable candidate: type - // deduction fails~(\ref{temp.deduct}) because \tcode{A::\tilde{}A()} - // is implicitly used in its \grammarterm{decltype-specifier}) -} -template auto q(T) - -> decltype((h())); // does not force completion of \tcode{A}; \tcode{A::\~{}A()} is - // not implicitly used within the context of this \grammarterm{decltype-specifier} -void r() { - q(42); // Error: deduction against \tcode{q} succeeds, so overload resolution - // selects the specialization ``\tcode{q(T) -> decltype((h())) [with T=int]}''. - // The return type is \tcode{A}, so a temporary is introduced and its - // destructor is used, so the program is ill-formed. -} -\end{codeblock} -\exitexample\exitnote +\begin{note} +The \grammarterm{pack-index-specifier} denotes +the type of the $V^\text{th}$ element of the pack. +\end{note} \rSec3[dcl.type.elab]{Elaborated type specifiers}% \indextext{type specifier!elaborated}% \indextext{\idxcode{typename}}% -\indextext{type~specifier!\idxcode{enum}} +\indextext{type specifier!\idxcode{enum}} \begin{bnf} \nontermdef{elaborated-type-specifier}\br - class-key attribute-specifier-seq\opt nested-name-specifier\opt identifier\br + class-key \opt{attribute-specifier-seq} \opt{nested-name-specifier} identifier\br class-key simple-template-id\br - class-key nested-name-specifier \terminal{template}\opt simple-template-id\br - \terminal{enum} nested-name-specifier\opt identifier + class-key nested-name-specifier \opt{\keyword{template}} simple-template-id\br + \keyword{enum} \opt{nested-name-specifier} identifier \end{bnf} \pnum -\indextext{class~name!elaborated}% +\indextext{component name}% +The component names of an \grammarterm{elaborated-type-specifier} are +its \grammarterm{identifier} (if any) and +those of its \grammarterm{nested-name-specifier} and +\grammarterm{simple-template-id} (if any). + +\pnum +\indextext{class name!elaborated}% \indextext{name!elaborated!\idxcode{enum}}% -An \grammarterm{attribute-specifier-seq} shall not appear in an \grammarterm{elaborated-type-specifier} -unless the latter is the sole constituent of a declaration. If an \grammarterm{elaborated-type-specifier} is the sole constituent of a declaration, the declaration is ill-formed unless it is an explicit -specialization~(\ref{temp.expl.spec}), an explicit -instantiation~(\ref{temp.explicit}) or it has one of the following +specialization\iref{temp.expl.spec}, +a partial specialization\iref{temp.spec.partial}, +an explicit +instantiation\iref{temp.explicit}, or it has one of the following forms: \begin{ncsimplebnf} -class-key attribute-specifier-seq\opt identifier \terminal{;}\br -\terminal{friend} class-key \terminal{::\opt} identifier \terminal{;}\br -\terminal{friend} class-key \terminal{::\opt} simple-template-id \terminal{;}\br -\terminal{friend} class-key nested-name-specifier identifier \terminal{;}\br -\terminal{friend} class-key nested-name-specifier \terminal{template\opt} simple-template-id \terminal{;} +class-key \opt{attribute-specifier-seq} identifier \terminal{;}\br +class-key \opt{attribute-specifier-seq} simple-template-id \terminal{;} \end{ncsimplebnf} -In the first case, the \grammarterm{attribute-specifier-seq}, if any, appertains -to the class being declared; the attributes in the -\grammarterm{attribute-specifier-seq} are thereafter considered attributes of -the class whenever it is named. - -\pnum -\ref{basic.lookup.elab} describes how name lookup proceeds for the -\grammarterm{identifier} in an \grammarterm{elaborated-type-specifier}. If the -\grammarterm{identifier} resolves to a \grammarterm{class-name} or +In the first case, +the \grammarterm{elaborated-type-specifier} declares +the \grammarterm{identifier} as a \grammarterm{class-name}. +The second case shall appear only +in an \grammarterm{explicit-specialization}\iref{temp.expl.spec} or +in a \grammarterm{template-declaration} +(where it declares a partial specialization). +The \grammarterm{attribute-specifier-seq}, if any, appertains +to the class or template being declared. + +\pnum +Otherwise, an \grammarterm{elaborated-type-specifier} $E$ shall not have +an \grammarterm{attribute-specifier-seq}. +If $E$ contains an \grammarterm{identifier} +but no \grammarterm{nested-name-specifier} and +(unqualified) lookup for the \grammarterm{identifier} finds nothing, +$E$ shall not be introduced by the \keyword{enum} keyword and +declares the \grammarterm{identifier} as a \grammarterm{class-name}. +The target scope of $E$ is the nearest enclosing namespace or block scope. + +\pnum +A \grammarterm{friend-type-specifier} +that is an \grammarterm{elaborated-type-specifier} +shall have one of the following forms: +\begin{ncsimplebnf} +class-key \opt{nested-name-specifier} identifier\br +class-key simple-template-id\br +class-key nested-name-specifier \opt{\keyword{template}} simple-template-id +\end{ncsimplebnf} +Any unqualified lookup for the \grammarterm{identifier} (in the first case) +does not consider scopes that contain +the nearest enclosing namespace or block scope; no name is bound. +\begin{note} +A \grammarterm{using-directive} in the target scope is ignored +if it refers to a namespace not contained by that scope. +\end{note} + +\pnum +\begin{note} +\ref{basic.lookup.elab} describes how name lookup proceeds +in an \grammarterm{elaborated-type-specifier}. +An \grammarterm{elaborated-type-specifier} can be used to refer to +a previously declared \grammarterm{class-name} or \grammarterm{enum-name} +even if the name has been hidden by a non-type declaration. +\end{note} + +\pnum +If the \grammarterm{identifier} or \grammarterm{simple-template-id} +in an \grammarterm{elaborated-type-specifier} +resolves to a \grammarterm{class-name} or \grammarterm{enum-name}, the \grammarterm{elaborated-type-specifier} introduces it into the declaration the same way a -\grammarterm{simple-type-specifier} introduces its \grammarterm{type-name}. If -the \grammarterm{identifier} resolves to a -\grammarterm{typedef-name} or the \grammarterm{simple-template-id} resolves to -an alias template specialization, -the -\grammarterm{elaborated-type-specifier} is ill-formed. -\enternote +\grammarterm{simple-type-specifier} introduces +its \grammarterm{type-name}\iref{dcl.type.simple}. +If the \grammarterm{identifier} or \grammarterm{simple-template-id} resolves to a +\grammarterm{typedef-name}\iref{dcl.typedef,temp.names}, +the \grammarterm{elaborated-type-specifier} is ill-formed. +\begin{note} This implies that, within a class template with a template \grammarterm{type-parameter} \tcode{T}, the declaration - \begin{codeblock} friend class T; \end{codeblock} - -is ill-formed. However, the similar declaration \tcode{friend T;} is allowed~(\ref{class.friend}). -\exitnote +is ill-formed. However, the similar declaration \tcode{friend T;} is well-formed\iref{class.friend}. +\end{note} \pnum -The \grammarterm{class-key} or \tcode{enum} keyword -present in the +The \grammarterm{class-key} or \keyword{enum} keyword +present in an \grammarterm{elaborated-type-specifier} shall agree in kind with the declaration to which the name in the \grammarterm{elaborated-type-specifier} refers. This rule also applies to the form of \grammarterm{elaborated-type-specifier} that declares a -\grammarterm{class-name} or \tcode{friend} class since it can be construed +\grammarterm{class-name} or friend class since it can be construed as referring to the definition of the class. Thus, in any -\grammarterm{elaborated-type-specifier}, the \tcode{enum} keyword +\grammarterm{elaborated-type-specifier}, the \keyword{enum} keyword shall be -used to refer to an enumeration~(\ref{dcl.enum}), the \tcode{union} -\grammarterm{class-key} shall be used to refer to a union -(Clause~\ref{class}), and either the \tcode{class} or \tcode{struct} -\grammarterm{class-key} shall be used to refer to a class -(Clause~\ref{class}) declared using the \tcode{class} or \tcode{struct} -\grammarterm{class-key}. \enterexample - +used to refer to an enumeration\iref{dcl.enum}, the \keyword{union} +\grammarterm{class-key} shall be used to refer to a union\iref{class.union}, +and either the \keyword{class} or \keyword{struct} +\grammarterm{class-key} shall be used to refer to a non-union class\iref{class.pre}. +\begin{example} \begin{codeblock} enum class E { a, b }; enum E x = E::a; // OK +struct S { } s; +class S* p = &s; // OK \end{codeblock} -\exitexample +\end{example} -\rSec3[dcl.spec.auto]{\tcode{auto} specifier}% -\indextext{type specifier!\idxcode{auto}} +\rSec3[dcl.type.decltype]{Decltype specifiers}% +\indextext{type specifier!\idxcode{decltype}}% -\pnum -The \tcode{auto} and \tcode{decltype(auto)} \grammarterm{type-specifier}{s} -are used to -designate a placeholder type that will be replaced later by deduction -from an initializer. The \tcode{auto} -\grammarterm{type-specifier} is also used to -introduce a function type having a \grammarterm{trailing-return-type} or to -signify that a lambda is a generic lambda. +\begin{bnf} +\nontermdef{decltype-specifier}\br + \keyword{decltype} \terminal{(} expression \terminal{)} +\end{bnf} \pnum -The placeholder type can appear with a function declarator in the -\grammarterm{decl-specifier-seq}, \grammarterm{type-specifier-seq}, -\grammarterm{conversion-function-id}, or \grammarterm{trailing-return-type}, -in any context where such a declarator is valid. If the function declarator -includes a \grammarterm{trailing-return-type}~(\ref{dcl.fct}), that -\grammarterm{trailing-return-type} specifies -the declared return type of the function. Otherwise, the function declarator -shall declare a function. If the declared return type of the -function contains a placeholder type, the return type of the function is -deduced from \tcode{return} statements in the body of the function, if any. +\indextext{type specifier!\idxcode{decltype}}% +For an expression $E$, the type denoted by \tcode{decltype($E$)} is defined as follows: +\begin{itemize} +\item if $E$ is an unparenthesized \grammarterm{id-expression} +naming a structured binding\iref{dcl.struct.bind}, +\tcode{decltype($E$)} is the referenced type as given in +the specification of the structured binding declaration; + +\item otherwise, if $E$ is an unparenthesized \grammarterm{id-expression} +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}; + +\item otherwise, if $E$ is an unparenthesized \grammarterm{id-expression} or +an unparenthesized +class +member access\iref{expr.ref}, \tcode{decltype($E$)} is the +type of the entity named by $E$. +If there is no such entity, the program is ill-formed; -\pnum -If the \tcode{auto} \grammarterm{type-specifier} appears as one of the -\grammarterm{decl-specifier}{s} in the \grammarterm{decl-specifier-seq} of a -\grammarterm{parameter-declaration} of a \grammarterm{lambda-expression}, the -\indextext{generic lambda!definition of}% -lambda is a \term{generic lambda}~(\ref{expr.prim.lambda}). \enterexample -\begin{codeblock} -auto glambda = [](int i, auto a) { return i; }; // OK: a generic lambda -\end{codeblock} -\exitexample +\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$; -\pnum -The type of a variable declared using \tcode{auto} or \tcode{decltype(auto)} is -deduced from its initializer. This use is allowed when declaring variables in a -block~(\ref{stmt.block}), in -namespace scope~(\ref{basic.scope.namespace}), and in a -\nonterminal{for-init-statement}~(\ref{stmt.for}). -\tcode{auto} or \tcode{decltype(auto)} shall appear as one of the -\grammarterm{decl-specifier}{s} in the -\grammarterm{decl-specifier-seq} and the -\grammarterm{decl-specifier-seq} -shall be followed by one or more \grammarterm{init-declarator}{s}, each of which shall -have a non-empty \grammarterm{initializer}. In an -\grammarterm{initializer} of the form - -\begin{codeblock} -( @\grammarterm{expression-list}@ ) -\end{codeblock} - -the \grammarterm{expression-list} shall be a single -\grammarterm{assignment-expression}. - -\enterexample -\begin{codeblock} -auto x = 5; // OK: \tcode{x} has type \tcode{int} -const auto *v = &x, u = 6; // OK: \tcode{v} has type \tcode{const int*}, \tcode{u} has type \tcode{const int} -static auto y = 0.0; // OK: \tcode{y} has type \tcode{double} -auto int r; // error: auto is not a \grammarterm{storage-class-specifier} -auto f() -> int; // OK: \tcode{f} returns \tcode{int} -auto g() { return 0.0; } // OK: \tcode{g} returns \tcode{double} -auto h(); // OK: \tcode{h}'s return type will be deduced when it is defined -\end{codeblock} -\exitexample - -\pnum -A placeholder type can also be used in declaring a variable in -the \nonterminal{condition} of a selection statement~(\ref{stmt.select}) or an iteration -statement~(\ref{stmt.iter}), in the \nonterminal{type-specifier-seq} in -the \nonterminal{new-type-id} or \nonterminal{type-id} of a -\nonterminal{new-expression}~(\ref{expr.new}), in a -\grammarterm{for-range-declaration}, and in declaring a static data member with a -\grammarterm{brace-or-equal-initializer} that appears within the -\nonterminal{member-specification} of a class definition~(\ref{class.static.data}). - -\pnum -A program that uses \tcode{auto} or \tcode{decltype(auto)} in a context not -explicitly allowed in this section is ill-formed. - -\pnum -When a variable declared using a placeholder type is initialized, or a -\tcode{return} statement occurs in a function declared with a return type that -contains a placeholder type, the deduced return type or variable type is -determined from the type of its initializer. In the case of a \tcode{return} -with no operand or with an operand of type \tcode{void}, the declared return -type shall be \tcode{auto} and the deduced return type is \tcode{void}. -Otherwise, let \tcode{T} be the declared type of the variable or return type of -the function. -If the placeholder is the \tcode{auto} \grammarterm{type-specifier}, the -deduced type is determined using the rules for template argument deduction. -If the initialization is direct-list-initialization -then the \grammarterm{braced-init-list} shall contain -only a single \grammarterm{initializer-clause} \tcode{L}. -If the deduction is for a \tcode{return} statement and the initializer is a -\grammarterm{braced-init-list}~(\ref{dcl.init.list}), the program is -ill-formed. Otherwise, obtain \tcode{P} from -\tcode{T} by replacing the occurrences of \tcode{auto} with either 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 -of template argument deduction from a function call~(\ref{temp.deduct.call}), -where \tcode{P} is a -function template parameter type and -the corresponding argument is the initializer, -or \tcode{L} in the case of direct-list-initialization. -If the deduction fails, the declaration is ill-formed. -Otherwise, the type deduced for the variable or return type is obtained by -substituting the deduced \tcode{U} into \tcode{P}. -\enterexample +\item otherwise, if $E$ is +an xvalue, \tcode{decltype($E$)} is \tcode{T\&\&}, where \tcode{T} is the type +of $E$; + +\item otherwise, if $E$ is an lvalue, \tcode{decltype($E$)} +is \tcode{T\&}, where \tcode{T} is the type of $E$; + +\item otherwise, \tcode{decltype($E$)} is the type of $E$. +\end{itemize} + +The operand of the \keyword{decltype} specifier is an unevaluated +operand\iref{term.unevaluated.operand}. + +\begin{example} \begin{codeblock} -auto x1 = { 1, 2 }; // \tcode{decltype(x1)} is \tcode{std::initializer_list} -auto x2 = { 1, 2.0 }; // error: cannot deduce element type -auto x3{ 1, 2 }; // error: not a single element -auto x4 = { 3 }; // \tcode{decltype(x4)} is \tcode{std::initializer_list} -auto x5{ 3 }; // \tcode{decltype(x5)} is \tcode{int} -\end{codeblock} -\exitexample +const int&& foo(); +int i; +struct A { double x; }; +const A* a = new A(); +decltype(foo()) x1 = 17; // type is \tcode{const int\&\&} +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\&} -\enterexample +void f() { + [](auto ...pack) { + decltype(pack...[0]) x7; // type is \tcode{int} + decltype((pack...[0])) x8; // type is \tcode{int\&} + }(0); +} +\end{codeblock} +\end{example} +\begin{note} +The rules for determining types involving \tcode{decltype(auto)} are specified +in~\ref{dcl.spec.auto}. +\end{note} + +\pnum +If the operand of a \grammarterm{decltype-specifier} is a prvalue +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. +\begin{note} +As a result, storage is not allocated for the prvalue and it is not destroyed. +Thus, a class type is not instantiated +as a result of being the type of a function call in this context. +In this context, the common purpose of +writing the expression is merely to refer to its type. In that sense, a +\grammarterm{decltype-specifier} is analogous to a use of a \grammarterm{typedef-name}, +so the usual reasons for requiring a complete type do not apply. In particular, +it is not necessary to allocate storage for a temporary object or to enforce the +semantic constraints associated with invoking the type's destructor. +\end{note} +\begin{note} +Unlike the preceding rule, parentheses have no special meaning in this context. +\end{note} +\begin{example} \begin{codeblock} -const auto &i = expr; +template struct A { ~A() = delete; }; +template auto h() + -> A; +template auto i(T) // identity + -> T; +template auto f(T) // \#1 + -> decltype(i(h())); // forces completion of \tcode{A} and implicitly uses \tcode{A::\~{}A()} + // for the temporary introduced by the use of \tcode{h()}. + // (A temporary is not introduced as a result of the use of \tcode{i()}.) +template auto f(T) // \#2 + -> void; +auto g() -> void { + f(42); // OK, calls \#2. (\#1 is not a viable candidate: type deduction + // fails\iref{temp.deduct} because \tcode{A::\~{}A()} is implicitly used in its + // \grammarterm{decltype-specifier}) +} +template auto q(T) + -> decltype((h())); // does not force completion of \tcode{A}; \tcode{A::\~{}A()} is not implicitly + // used within the context of this \grammarterm{decltype-specifier} +void r() { + q(42); // error: deduction against \tcode{q} succeeds, so overload resolution selects + // the specialization ``\tcode{q(T) -> decltype((h()))}'' with \tcode{T}$=$\tcode{int}; + // the return type is \tcode{A}, so a temporary is introduced and its + // destructor is used, so the program is ill-formed +} \end{codeblock} +\end{example} -The type of \tcode{i} is the deduced type of the parameter \tcode{u} in -the call \tcode{f(expr)} of the following invented function template: +\rSec3[dcl.spec.auto]{Placeholder type specifiers}% -\begin{codeblock} -template void f(const U& u); -\end{codeblock} -\exitexample +\rSec4[dcl.spec.auto.general]{General}% +\indextext{type specifier!\idxcode{auto}} +\indextext{type specifier!\idxcode{decltype(auto)}}% -If the placeholder is the \tcode{decltype(auto)} \grammarterm{type-specifier}, -the declared type of the variable or return type of the function shall be the -placeholder alone. The type deduced for the variable or return type is -determined as described in~\ref{dcl.type.simple}, as though the initializer had -been the operand of the \tcode{decltype}. \enterexample +\begin{bnf} +\nontermdef{placeholder-type-specifier}\br + \opt{type-constraint} \keyword{auto}\br + \opt{type-constraint} \keyword{decltype} \terminal{(} \keyword{auto} \terminal{)} +\end{bnf} + +\pnum +A \grammarterm{placeholder-type-specifier} +designates a placeholder type that will be replaced later, +typically by deduction +from an initializer. + +\pnum +The type of a \grammarterm{parameter-declaration} of a +\begin{itemize} + \item function declaration\iref{dcl.fct}, + \item \grammarterm{lambda-expression}\iref{expr.prim.lambda}, or + \item \grammarterm{template-parameter}\iref{temp.param} +\end{itemize} +can be declared using +a \grammarterm{placeholder-type-specifier} of the form +\opt{\grammarterm{type-constraint}} \keyword{auto}. +The placeholder type shall appear +as one of the \grammarterm{decl-specifier}{s} in +the \grammarterm{decl-specifier-seq} or +as one of the \grammarterm{type-specifier}{s} in +a \grammarterm{trailing-return-type} +that specifies the type that replaces such +a \grammarterm{decl-specifier} (see below); +the placeholder type +is a \defn{generic parameter type placeholder} +of the +function declaration, +\grammarterm{lambda-expression}, or +\grammarterm{template-parameter}, respectively. +\begin{note} +Having a generic parameter type placeholder +signifies that the function is +an abbreviated function template\iref{dcl.fct} or +the lambda is a generic lambda\iref{expr.prim.lambda}. +\end{note} + +\pnum +A placeholder type can appear in +the \grammarterm{decl-specifier-seq} for a function declarator +that includes a \grammarterm{trailing-return-type}\iref{dcl.fct}. + +\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 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}. + +\pnum +The type of a variable declared using a placeholder type is +deduced from its initializer. +This use is allowed +in an initializing declaration\iref{dcl.init} of a variable. +The placeholder type shall appear as one of the +\grammarterm{decl-specifier}{s} in the \grammarterm{decl-specifier-seq} +or as one of the +\grammarterm{type-specifier}{s} in a \grammarterm{trailing-return-type} +that specifies the type that replaces such a \grammarterm{decl-specifier}; +the \grammarterm{decl-specifier-seq} +shall be followed by one or more +\grammarterm{declarator}{s}, +each of which shall +be followed by a non-empty +\grammarterm{initializer}. +\begin{example} \begin{codeblock} -int i; -int&& f(); -auto x3a = i; // \tcode{decltype(x3a)} is \tcode{int} -decltype(auto) x3d = i; // \tcode{decltype(x3d)} is \tcode{int} -auto x4a = (i); // \tcode{decltype(x4a)} is \tcode{int} -decltype(auto) x4d = (i); // \tcode{decltype(x4d)} is \tcode{int\&} -auto x5a = f(); // \tcode{decltype(x5a)} is \tcode{int} -decltype(auto) x5d = f(); // \tcode{decltype(x5d)} is \tcode{int\&\&} -auto x6a = { 1, 2 }; // \tcode{decltype(x6a)} is \tcode{std::initializer_list} -decltype(auto) x6d = { 1, 2 }; // error, \tcode{\{ 1, 2 \}} is not an expression -auto *x7a = &i; // \tcode{decltype(x7a)} is \tcode{int*} -decltype(auto)*x7d = &i; // error, declared type is not plain \tcode{decltype(auto)} +auto x = 5; // OK, \tcode{x} has type \tcode{int} +const auto *v = &x, u = 6; // OK, \tcode{v} has type \tcode{const int*}, \tcode{u} has type \tcode{const int} +static auto y = 0.0; // OK, \tcode{y} has type \tcode{double} +auto int r; // error: \keyword{auto} is not a \grammarterm{storage-class-specifier} +auto f() -> int; // OK, \tcode{f} returns \tcode{int} +auto g() { return 0.0; } // OK, \tcode{g} returns \tcode{double} +auto (*fp)() -> auto = f; // OK +auto h(); // OK, \tcode{h}'s return type will be deduced when it is defined \end{codeblock} -\exitexample +\end{example} +The \keyword{auto} \grammarterm{type-specifier} +can also be used to introduce +a structured binding declaration\iref{dcl.struct.bind}. + +\pnum +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 +\grammarterm{new-expression}\iref{expr.new}. +In such a \grammarterm{type-id}, +the placeholder type shall appear +as one of the \grammarterm{type-specifier}{s} in +the \grammarterm{type-specifier-seq} or +as one of the \grammarterm{type-specifier}{s} in +a \grammarterm{trailing-return-type} +that specifies the type that replaces such a \grammarterm{type-specifier}. + +\pnum +The \tcode{auto} \grammarterm{type-specifier} can also be used +as the \grammarterm{simple-type-specifier} +in an explicit type conversion (functional notation)\iref{expr.type.conv}. + +\pnum +A program that uses a placeholder type in a context not +explicitly allowed in \ref{dcl.spec.auto} is ill-formed. \pnum If the \grammarterm{init-declarator-list} contains more than one \grammarterm{init-declarator}, they shall all form declarations of -variables. The type of each declared variable is determined as -described above, and if the type that replaces the placeholder type is not the +variables. The type of each declared variable is determined +by placeholder type deduction\iref{dcl.type.auto.deduct}, +and if the type that replaces the placeholder type is not the same in each deduction, the program is ill-formed. -\enterexample +\begin{example} \begin{codeblock} -auto x = 5, *y = &x; // OK: \tcode{auto} is \tcode{int} -auto a = 5, b = { 1, 2 }; // error: different types for \tcode{auto} +auto x = 5, *y = &x; // OK, \keyword{auto} is \tcode{int} +auto a = 5, b = { 1, 2 }; // error: different types for \keyword{auto} \end{codeblock} -\exitexample% -\indextext{specifier|)} +\end{example} \pnum If a function with a declared return type that contains a placeholder type has -multiple \tcode{return} statements, the return type is deduced for each -\tcode{return} statement. If the type deduced is not the same in each +multiple non-discarded \tcode{return} statements, the return type is deduced for each +such \tcode{return} statement. If the type deduced is not the same in each deduction, the program is ill-formed. \pnum If a function with a declared return type that uses a placeholder type has no -\tcode{return} statements, the return type is deduced as though from a +non-discarded \tcode{return} statements, the return type is deduced as though from a \tcode{return} statement with no operand at the closing brace of the function body. -\enterexample +\begin{example} \begin{codeblock} -auto f() { } // OK, return type is \tcode{void} -auto* g() { } // error, cannot deduce \tcode{auto*} from \tcode{void()} +auto f() { } // OK, return type is \keyword{void} +auto* g() { } // error: cannot deduce \tcode{auto*} from \tcode{void()} \end{codeblock} -\exitexample +\end{example} \pnum -If the type of an entity with an undeduced placeholder type is needed to -determine the type of an expression, the program is ill-formed. Once a -\tcode{return} statement has been seen in a function, however, the return type deduced +An exported function +with a declared return type that uses a placeholder type +shall be defined in the translation unit +containing its exported declaration, +outside the \grammarterm{private-module-fragment} (if any). +\begin{note} +The deduced return type cannot have +a name with internal linkage\iref{basic.link}. +\end{note} + +\pnum +If a variable or function with an undeduced placeholder type is named by an +expression\iref{basic.def.odr}, the program is ill-formed. Once a +non-discarded \tcode{return} statement has been seen in a function, however, the return type deduced from that statement can be used in the rest of the function, including in other \tcode{return} statements. -\enterexample +\begin{example} \begin{codeblock} -auto n = n; // error, \tcode{n}'s type is unknown +auto n = n; // error: \tcode{n}'s initializer refers to \tcode{n} auto f(); -void g() { &f; } // error, \tcode{f}'s return type is unknown +void g() { &f; } // error: \tcode{f}'s return type is unknown auto sum(int i) { if (i == 1) - return i; // \tcode{sum}'s return type is \tcode{int} + return i; // \tcode{sum}'s return type is \tcode{int} else - return sum(i-1)+i; // OK, \tcode{sum}'s return type has been deduced + return sum(i-1)+i; // OK, \tcode{sum}'s return type has been deduced +} +\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} -\exitexample +\end{example} + \pnum -Return type deduction for a function template with a placeholder in its +Return type deduction for a templated +function with a placeholder in its declared type occurs when the definition is instantiated even if the function body contains a \tcode{return} statement with a non-type-dependent operand. -\enternote Therefore, any use of a specialization of the function template will +\begin{note} +Therefore, any use of a specialization of the function template will cause an implicit instantiation. Any errors that arise from this instantiation are not in the immediate context of the function type and can result in the -program being ill-formed. \exitnote -\enterexample +program being ill-formed\iref{temp.deduct}. +\end{note} +\begin{example} \begin{codeblock} -template auto f(T t) { return t; } // return type deduced at instantiation time -typedef decltype(f(1)) fint_t; // instantiates \tcode{f} to deduce return type +template auto f(T t) { return t; } // return type deduced at instantiation time +typedef decltype(f(1)) fint_t; // instantiates \tcode{f} to deduce return type template auto f(T* t) { return *t; } -void g() { int (*p)(int*) = &f; } // instantiates both \tcode{f}s to determine return types, - // chooses second +void g() { int (*p)(int*) = &f; } // instantiates both \tcode{f}s to determine return types, + // chooses second \end{codeblock} -\exitexample +\end{example} \pnum -Redeclarations or specializations of a function or function template with a -declared return type that uses a placeholder type shall also use that -placeholder, not a deduced type. -\enterexample +If a function or function template $F$ has +a declared return type that uses a placeholder type, +redeclarations or specializations of $F$ shall use that +placeholder type, not a deduced type; +otherwise, they shall not use a placeholder type. +\begin{example} \begin{codeblock} auto f(); -auto f() { return 42; } // return type is \tcode{int} -auto f(); // OK -int f(); // error, cannot be overloaded with \tcode{auto f()} -decltype(auto) f(); // error, \tcode{auto} and \tcode{decltype(auto)} don't match +auto f() { return 42; } // return type is \tcode{int} +auto f(); // OK +int f(); // error: \keyword{auto} and \tcode{int} don't match +decltype(auto) f(); // error: \keyword{auto} and \tcode{decltype(auto)} don't match template auto g(T t) { return t; } // \#1 template auto g(int); // OK, return type is \tcode{int} -template char g(char); // error, no matching template +template char g(char); // error: no matching template template<> auto g(double); // OK, forward declaration with unknown return type -template T g(T t) { return t; } // OK, not functionally equivalent to \#1 -template char g(char); // OK, now there is a matching template -template auto g(float); // still matches \#1 +template T g(T t) { return t; } // OK, not functionally equivalent to \#1 +template char g(char); // OK, now there is a matching template +template auto g(float); // still matches \#1 -void h() { return g(42); } // error, ambiguous +void h() { return g(42); } // error: ambiguous template struct A { friend T frf(T); }; -auto frf(int i) { return i; } // not a friend of \tcode{A} +auto frf(int i) { return i; } // not a friend of \tcode{A} +extern int v; +auto v = 17; // OK, redeclares \tcode{v} +struct S { + static int i; +}; +auto S::i = 23; // OK \end{codeblock} -\exitexample +\end{example} + +\pnum +A function declared with a return type that uses a placeholder type shall not +be \keyword{virtual}\iref{class.virtual}. \pnum A function declared with a return type that uses a placeholder type shall not -be \tcode{virtual}~(\ref{class.virtual}). +be a coroutine\iref{dcl.fct.def.coroutine}. \pnum -An explicit instantiation declaration~(\ref{temp.explicit}) does not cause the +An explicit instantiation declaration\iref{temp.explicit} does not cause the instantiation of an entity declared using a placeholder type, but it also does not prevent that entity from being instantiated as needed to determine its type. -\enterexample +\begin{example} \begin{codeblock} template auto f(T t) { return t; } -extern template auto f(int); // does not instantiate \tcode{f} -int (*p)(int) = f; // instantiates \tcode{f} to determine its return type, but an explicit - // instantiation definition is still required somewhere in the program +extern template auto f(int); // does not instantiate \tcode{f} +int (*p)(int) = f; // instantiates \tcode{f} to determine its return type, but an explicit + // instantiation definition is still required somewhere in the program \end{codeblock} -\exitexample +\end{example} -\rSec1[dcl.enum]{Enumeration declarations}% -\indextext{enumeration}% -\indextext{\idxcode{\{\}}!enum declaration@\tcode{enum} declaration}% -\indextext{\idxcode{enum}!type~of} +\rSec4[dcl.type.auto.deduct]{Placeholder type deduction} +\indextext{deduction!placeholder type}% \pnum -An enumeration is a distinct type~(\ref{basic.compound}) with named -constants. Its name becomes an \grammarterm{enum-name}, within its scope. +\defnx{Placeholder type deduction}{placeholder type deduction} +is the process by which +a type containing a placeholder type +is replaced by a deduced type. -\begin{bnf} -\nontermdef{enum-name}\br - identifier -\end{bnf} +\pnum +A type \tcode{T} containing a placeholder type, +and a corresponding \grammarterm{initializer-clause} $E$, +are determined as follows: +\begin{itemize} +\item +For a non-discarded \tcode{return} statement that occurs +in a function declared with a return type +that contains a placeholder type, +\tcode{T} is the declared return type. +\begin{itemize} +\item +If the \tcode{return} statement has no operand, +then $E$ is \tcode{void()}. +\item +If the operand is a \grammarterm{braced-init-list}\iref{dcl.init.list}, +the program is ill-formed. +\item +If the operand is an \grammarterm{expression} $X$ +that is not an \grammarterm{assignment-expression}, +$E$ is \tcode{($X$)}. +\begin{note} +A comma expression\iref{expr.comma} is not +an \grammarterm{assignment-expression}. +\end{note} +\item +Otherwise, $E$ is the operand of the \tcode{return} statement. +\end{itemize} +If $E$ has type \keyword{void}, +\tcode{T} shall be either +\opt{\grammarterm{type-constraint}} \tcode{decltype(auto)} or +\cv{}~\opt{\grammarterm{type-constraint}} \keyword{auto}. +\item +For a variable declared with a type +that contains a placeholder type, +\tcode{T} is the declared type of the variable. +\begin{itemize} +\item +If the initializer of the variable is a \grammarterm{brace-or-equal-initializer} +of the form \tcode{= \grammarterm{initializer-clause}}, +$E$ is the \grammarterm{initializer-clause}. +\item +If the initializer is a \grammarterm{braced-init-list}, +it shall consist of a single brace-enclosed \grammarterm{assignment-expression} +and $E$ is the \grammarterm{assignment-expression}. +\item +If the initializer is a parenthesized \grammarterm{expression-list}, +the \grammarterm{expression-list} shall be +a single \grammarterm{assignment-expression} +and $E$ is the \grammarterm{assignment-expression}. +\end{itemize} +\item +For an explicit type conversion\iref{expr.type.conv}, +\tcode{T} is the specified type, which shall be \keyword{auto}. +\begin{itemize} +\item +If the initializer is a \grammarterm{braced-init-list}, +it shall consist of a single brace-enclosed \grammarterm{assignment-expression} +and $E$ is the \grammarterm{assignment-expression}. +\item +If the initializer is a parenthesized \grammarterm{expression-list}, +the \grammarterm{expression-list} shall be +a single \grammarterm{assignment-expression} +and $E$ is the \grammarterm{assignment-expression}. +\end{itemize} +\item +For a constant template parameter declared with a type +that contains a placeholder type, +\tcode{T} is the declared type of the constant template parameter +and $E$ is the corresponding template argument. +\end{itemize} -\begin{bnf} -\nontermdef{enum-specifier}\br - enum-head \terminal{\{} enumerator-list\opt \terminal{\}}\br - enum-head \terminal{\{} enumerator-list \terminal{, \}} -\end{bnf} +\tcode{T} shall not be an array type. + +\pnum +If the \grammarterm{placeholder-type-specifier} is of the form +\opt{\grammarterm{type-constraint}} \keyword{auto}, +the deduced type +$\mathtt{T}'$ replacing \tcode{T} +is determined using the rules for template argument deduction. +If the initialization is copy-list-initialization, +a declaration of \tcode{std::initializer_list} +shall precede\iref{basic.lookup.general} +the \grammarterm{placeholder-type-specifier}. +Obtain \tcode{P} from +\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}. +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 +the corresponding argument is $E$. +If the deduction fails, the declaration is ill-formed. +Otherwise, $\mathtt{T}'$ is obtained by +substituting the deduced \tcode{U} into \tcode{P}. +\begin{example} +\begin{codeblock} +auto x1 = { 1, 2 }; // \tcode{decltype(x1)} is \tcode{std::initializer_list} +auto x2 = { 1, 2.0 }; // error: cannot deduce element type +auto x3{ 1, 2 }; // error: not a single element +auto x4 = { 3 }; // \tcode{decltype(x4)} is \tcode{std::initializer_list} +auto x5{ 3 }; // \tcode{decltype(x5)} is \tcode{int} +\end{codeblock} +\end{example} -\begin{bnf} -\nontermdef{enum-head}\br - enum-key attribute-specifier-seq\opt identifier\opt enum-base\opt\br - enum-key attribute-specifier-seq\opt nested-name-specifier identifier\br -\hspace*{\bnfindentinc}enum-base\opt -\end{bnf} +\begin{example} +\begin{codeblock} +const auto &i = expr; +\end{codeblock} +The type of \tcode{i} is the deduced type of the parameter \tcode{u} in +the call \tcode{f(expr)} of the following invented function template: +\begin{codeblock} +template void f(const U& u); +\end{codeblock} +\end{example} -\begin{bnf} -\nontermdef{opaque-enum-declaration}\br - enum-key attribute-specifier-seq\opt identifier enum-base\opt \terminal{;} -\end{bnf} +\pnum +If the \grammarterm{placeholder-type-specifier} is of the form +\opt{\grammarterm{type-constraint}} \tcode{decltype(auto)}, +\tcode{T} shall be the +placeholder alone. The type deduced for \tcode{T} is +determined as described in~\ref{dcl.type.decltype}, as though +$E$ had +been the operand of the \keyword{decltype}. +\begin{example} +\begin{codeblock} +int i; +int&& f(); +auto x2a(i); // \tcode{decltype(x2a)} is \tcode{int} +decltype(auto) x2d(i); // \tcode{decltype(x2d)} is \tcode{int} +auto x3a = i; // \tcode{decltype(x3a)} is \tcode{int} +decltype(auto) x3d = i; // \tcode{decltype(x3d)} is \tcode{int} +auto x4a = (i); // \tcode{decltype(x4a)} is \tcode{int} +decltype(auto) x4d = (i); // \tcode{decltype(x4d)} is \tcode{int\&} +auto x5a = f(); // \tcode{decltype(x5a)} is \tcode{int} +decltype(auto) x5d = f(); // \tcode{decltype(x5d)} is \tcode{int\&\&} +auto x6a = { 1, 2 }; // \tcode{decltype(x6a)} is \tcode{std::initializer_list} +decltype(auto) x6d = { 1, 2 }; // error: \tcode{\{ 1, 2 \}} is not an expression +auto *x7a = &i; // \tcode{decltype(x7a)} is \tcode{int*} +decltype(auto)*x7d = &i; // error: declared type is not plain \tcode{decltype(auto)} +auto f1(int x) -> decltype((x)) { return (x); } // return type is \tcode{int\&} +auto f2(int x) -> decltype(auto) { return (x); } // return type is \tcode{int\&\&} +\end{codeblock} +\end{example} -\begin{bnf} -\nontermdef{enum-key}\br - \terminal{enum}\br - \terminal{enum class}\br - \terminal{enum struct} -\end{bnf} +\pnum +For a \grammarterm{placeholder-type-specifier} +with a \grammarterm{type-constraint}, +the immediately-declared constraint\iref{temp.param} +of the \grammarterm{type-constraint} for the type deduced for the placeholder +shall be satisfied. -\begin{bnf} -\nontermdef{enum-base}\br - \terminal{:} type-specifier-seq -\end{bnf} +\rSec3[dcl.type.class.deduct]{Deduced class template specialization types} +\indextext{deduction!class template arguments}% -\begin{bnf} -\nontermdef{enumerator-list}\br - enumerator-definition\br - enumerator-list \terminal{,} enumerator-definition -\end{bnf} +\pnum +If a placeholder for a deduced class type +appears as a \grammarterm{decl-specifier} +in the \grammarterm{decl-specifier-seq} +of an initializing declaration\iref{dcl.init} of a variable, +the declared type of the variable shall be \cv{}~\tcode{T}, +where \tcode{T} is the placeholder. +\begin{example} +\begin{codeblock} +template struct A { + A(T...) {} +}; +A x[29]{}; // error: no declarator operators allowed +const A& y{}; // error: no declarator operators allowed +\end{codeblock} +\end{example} +The placeholder is replaced by the return type +of the function selected by overload resolution +for class template deduction\iref{over.match.class.deduct}. +If the \grammarterm{decl-specifier-seq} +is followed by an \grammarterm{init-declarator-list} +or \grammarterm{member-declarator-list} +containing more than one \grammarterm{declarator}, +the type that replaces the placeholder shall be the same in each deduction. + +\pnum +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} +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}, +or +as the \grammarterm{type-specifier} in the \grammarterm{parameter-declaration} +of a \grammarterm{template-parameter}\iref{temp.param}. +A placeholder for a deduced class type +shall not appear in any other context. + +\pnum +\begin{example} +\begin{codeblock} +template struct container { + container(T t) {} + template container(Iter beg, Iter end); +}; +template +container(Iter b, Iter e) -> container::value_type>; +std::vector v = { @\commentellip@ }; -\begin{bnf} -\nontermdef{enumerator-definition}\br - enumerator\br - enumerator \terminal{=} constant-expression -\end{bnf} +container c(7); // OK, deduces \tcode{int} for \tcode{T} +auto d = container(v.begin(), v.end()); // OK, deduces \tcode{double} for \tcode{T} +container e{5, 6}; // error: \tcode{int} is not an iterator +\end{codeblock} +\end{example} + +\rSec3[dcl.type.splice]{Type splicing} \begin{bnf} -\nontermdef{enumerator}\br - identifier attribute-specifier-seq\opt +\nontermdef{splice-type-specifier}\br + \opt{\keyword{typename}} splice-specifier\br + \opt{\keyword{typename}} splice-specialization-specifier \end{bnf} -The optional \grammarterm{attribute-specifier-seq} in the \grammarterm{enum-head} and -the \grammarterm{opaque-enum-declaration} appertains to the enumeration; the attributes -in that \grammarterm{attribute-specifier-seq} are thereafter considered attributes of the -enumeration whenever it is named. -A \tcode{:} following ``\tcode{enum} \grammarterm{identifier}'' is parsed as part of an -\grammarterm{enum-base}. -\enternote This resolves a potential ambiguity between the declaration of an enumeration -with an \grammarterm{enum-base} and the declaration of an unnamed bit-field of enumeration -type. \enterexample - -\begin{codeblock} - struct S { - enum E : int {}; - enum E : int {}; // error: redeclaration of enumeration - }; -\end{codeblock} - -\exitexample -\exitnote - \pnum -\indextext{constant!enumeration}% -\indextext{enumeration}% -\indextext{enumeration!unscoped}% -\indextext{enumeration!scoped}% -The enumeration type declared with an \grammarterm{enum-key} -of only \tcode{enum} is an \term{}{unscoped enumeration}, -and its \grammarterm{enumerator}{s} are \term{unscoped enumerators}. -The \grammarterm{enum-key}{s} \tcode{enum class} and -\tcode{enum struct} are semantically equivalent; an enumeration -type declared with one of these is a \term{scoped enumeration}, -and its \grammarterm{enumerator}{s} are \term{scoped enumerators}. -The optional \grammarterm{identifier} shall not be omitted in the declaration of a scoped enumeration. -The \grammarterm{type-specifier-seq} of an \grammarterm{enum-base} -shall name an integral type; any cv-qualification is ignored. -An \grammarterm{opaque-enum-declaration} declaring an unscoped enumeration shall -not omit the \grammarterm{enum-base}. -The identifiers in an \grammarterm{enumerator-list} are declared as -constants, and can appear wherever constants are required. -\indextext{enumerator!value~of}% -An \grammarterm{enumerator-definition} with \tcode{=} gives the associated -\grammarterm{enumerator} the value indicated by the -\grammarterm{constant-expression}. -If the first \grammarterm{enumerator} -has no \grammarterm{initializer}, the value of the corresponding constant -is zero. An \grammarterm{enumerator-definition} without an -\grammarterm{initializer} gives the \grammarterm{enumerator} the value -obtained by increasing the value of the previous \grammarterm{enumerator} -by one. -\enterexample - +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} -enum { a, b, c=0 }; -enum { d, e, f=e+2 }; -\end{codeblock} +template void tfn() { + typename [:R:]::type m; // OK, \keyword{typename} applies to the qualified name +} -defines \tcode{a}, \tcode{c}, and \tcode{d} to be zero, \tcode{b} and -\tcode{e} to be \tcode{1}, and \tcode{f} to be \tcode{3}. -\exitexample -The optional \grammarterm{attribute-specifier-seq} in an -\grammarterm{enumerator} appertains to that enumerator. +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*} +} -\pnum -An \grammarterm{opaque-enum-declaration} is either a redeclaration -of an enumeration in the current scope or a declaration of a new enumeration. -\enternote An enumeration declared by an -\grammarterm{opaque-enum-declaration} has fixed underlying type and is a -complete type. The list of enumerators can be provided in a later redeclaration -with an \grammarterm{enum-specifier}. \exitnote A scoped enumeration -shall not be later redeclared as unscoped or with a different underlying type. -An unscoped enumeration shall not be later redeclared as scoped and each -redeclaration shall include an \grammarterm{enum-base} specifying the same -underlying type as in the original declaration. +using alias = [:^^S::type:]; // OK, type-only context +\end{codeblock} +\end{example} \pnum -If the \grammarterm{enum-key} is followed by a -\grammarterm{nested-name-specifier}, the \grammarterm{enum-specifier} shall -refer to an enumeration that was previously declared directly in the class or -namespace to which the \grammarterm{nested-name-specifier} refers (i.e., neither -inherited nor introduced by a \grammarterm{using-declaration}), and the -\grammarterm{enum-specifier} shall appear in a namespace enclosing the previous -declaration. +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 -\indextext{\idxcode{enum}!type~of}% -\indextext{\idxcode{enum}!underlying~type}% -Each enumeration defines a type that is different from all other types. -Each enumeration also has an underlying type. -The underlying type can be explicitly specified using an \grammarterm{enum-base}. -For a scoped enumeration type, the underlying type is \tcode{int} if it is not -explicitly specified. In both of these cases, the underlying type is said to be -\term{fixed}. -Following the closing brace of an \grammarterm{enum-specifier}, each -enumerator has the type of its enumeration. -If the underlying type is fixed, the type of each enumerator -prior to the closing brace is the underlying -type -and the \grammarterm{constant-expression} in the \grammarterm{enumerator-definition} -shall be a converted constant expression of the underlying -type~(\ref{expr.const}). -If the underlying -type is not fixed, -the type of each enumerator prior to the closing brace is determined as -follows: - -\begin{itemize} -\item If an -initializer is specified for an enumerator, the -\grammarterm{constant-expression} shall be an integral constant -expression~(\ref{expr.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. +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|)}% -\item If no initializer is specified for the -first enumerator, its type is an unspecified signed integral type. +\rSec1[dcl.decl]{Declarators}% -\item Otherwise -the type of the enumerator is the same as that of the -preceding enumerator unless the incremented value is not representable -in that type, in which case the type is an unspecified integral type -sufficient to contain the incremented value. If no such type exists, the program -is ill-formed. -\end{itemize} +\rSec2[dcl.decl.general]{General}% +\indextext{declarator|(} -\pnum -An enumeration whose underlying type is fixed is an incomplete type from its -point of declaration~(\ref{basic.scope.pdecl}) to immediately after its -\grammarterm{enum-base} (if any), at which point it becomes a complete type. -An enumeration whose underlying type is not fixed is an incomplete type from -its point of declaration to immediately after the closing \tcode{\}} of its -\grammarterm{enum-specifier}, at which point it becomes a complete type. +\indextext{initialization!class object|seealso{constructor}}% +\indextext{\idxcode{*}|see{declarator, pointer}} +\indextext{\idxcode{\&}|see{declarator, reference}}% +\indextext{\idxcode{::*}|see{declarator, pointer-to-member}}% +\indextext{\idxcode{[]}|see{declarator, array}}% +\indextext{\idxcode{()}|see{declarator, function}}% \pnum -For an enumeration whose underlying type is not fixed, -the underlying type -is an -integral type that can represent all the enumerator values defined in -the enumeration. If no integral type can represent all the enumerator -values, the enumeration is ill-formed. It is \impldef{underlying type for enumeration} -which integral type is used as the underlying type -except that the underlying type shall not be larger than \tcode{int} -unless the value of an enumerator cannot fit in an \tcode{int} or -\tcode{unsigned int}. If the \grammarterm{enumerator-list} is empty, the -underlying type is as if the enumeration had a single enumerator with -value 0. +A declarator declares a single variable, function, or type, within a declaration. +The +\grammarterm{init-declarator-list} +appearing in a \grammarterm{simple-declaration} +is a comma-separated sequence of declarators, +each of which can have an initializer. -\pnum -For an enumeration whose underlying type is fixed, the values of -the enumeration are the values of the underlying type. Otherwise, -for an enumeration where $e_\mathit{min}$ is the smallest enumerator and -$e_\mathit{max}$ is the largest, the values of the enumeration are the -values in the range $b_{min}$ to $b_{max}$, defined as follows: Let $K$ -be 1 for a two's complement representation and 0 for a one's complement -or sign-magnitude representation. $b_{max}$ is the smallest value -greater than or equal to $max(|e_{min}| - K, |e_{max}|)$ and equal to -$2^M-1$, where $M$ is a non-negative integer. $b_{min}$ is zero if -$e_{min}$ is non-negative and $-(b_{max}+K)$ otherwise. The size of the -smallest bit-field large enough to hold all the values of the -enumeration type is $max(M,1)$ if $b_{min}$ is zero and $M+1$ otherwise. -It is possible to define an enumeration that has values not defined by -any of its enumerators. If the \grammarterm{enumerator-list} is empty, the -values of the enumeration are as if the enumeration had a single enumerator with -value 0.\footnote{This set of values is used to define promotion and -conversion semantics for the enumeration type. It does not preclude an -expression of enumeration type from having a value that falls outside -this range.} +\begin{bnf} +\nontermdef{init-declarator-list}\br + init-declarator\br + init-declarator-list \terminal{,} init-declarator +\end{bnf} -\pnum -Two enumeration types are \defn{layout-compatible} if they have the same -\term{underlying type}. +\begin{bnf} +\nontermdef{init-declarator}\br + declarator initializer\br + declarator \opt{requires-clause} \opt{function-contract-specifier-seq} +\end{bnf} \pnum -The value of an enumerator or an object of an unscoped enumeration type is -converted to an integer by integral promotion~(\ref{conv.prom}). -\enterexample - -\indextext{example!enumeration}% +In all contexts, a \grammarterm{declarator} is interpreted as given below. +Where an \grammarterm{abstract-declarator} can be used (or omitted) +in place of a \grammarterm{declarator}\iref{dcl.fct,except.pre}, +it is as if a unique identifier were included in +the appropriate place\iref{dcl.name}. +The preceding specifiers indicate +the type, storage duration, linkage, or other properties +of the entity or entities being declared. +Each declarator specifies one entity and +(optionally) names it and/or +modifies the type of the specifiers with operators such as +\tcode{*} (pointer to) and \tcode{()} (function returning). +\begin{note} +An \grammarterm{init-declarator} can also specify an initializer\iref{dcl.init}. +\end{note} + +\pnum +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, \begin{codeblock} - enum color { red, yellow, green=20, blue }; - color col = red; - color* cp = &col; - if (*cp == blue) // ... +T D1, D2, ... Dn; \end{codeblock} - -makes \tcode{color} a type describing various colors, and then declares -\tcode{col} as an object of that type, and \tcode{cp} as a pointer to an -object of that type. The possible values of an object of type -\tcode{color} are \tcode{red}, \tcode{yellow}, \tcode{green}, -\tcode{blue}; these values can be converted to the integral values -\tcode{0}, \tcode{1}, \tcode{20}, and \tcode{21}. Since enumerations are -distinct types, objects of type \tcode{color} can be assigned only -values of type \tcode{color}. - +is usually equivalent to \begin{codeblock} -color c = 1; // error: type mismatch, - // no conversion from \tcode{int} to \tcode{color} - -int i = yellow; // OK: \tcode{yellow} converted to integral value \tcode{1} - // integral promotion +T D1; T D2; ... T Dn; \end{codeblock} +where \tcode{T} is a \grammarterm{decl-specifier-seq} +and each \tcode{Di} is +an \grammarterm{init-declarator} or \grammarterm{member-declarator}. +One exception is when a name introduced by one of the +\grammarterm{declarator}{s} hides a type name used by the +\grammarterm{decl-specifier}{s}, so that when the same +\grammarterm{decl-specifier}{s} are used in a subsequent declaration, +they do not have the same meaning, as in +\begin{codeblock} +struct S { @\commentellip@ }; +S S, T; // declare two instances of \tcode{struct S} +\end{codeblock} +which is not equivalent to +\begin{codeblock} +struct S { @\commentellip@ }; +S S; +S T; // error +\end{codeblock} +Another exception is when \tcode{T} is \keyword{auto}\iref{dcl.spec.auto}, +for example: +\begin{codeblock} +auto i = 1, j = 2.0; // error: deduced types for \tcode{i} and \tcode{j} do not match +\end{codeblock} +as opposed to +\begin{codeblock} +auto i = 1; // OK, \tcode{i} deduced to have type \tcode{int} +auto j = 2.0; // OK, \tcode{j} deduced to have type \tcode{double} +\end{codeblock} +\end{note} -Note that this implicit \tcode{enum} to \tcode{int} -conversion is not provided for a scoped enumeration: - +\pnum +The optional \grammarterm{requires-clause} in an +\grammarterm{init-declarator} or \grammarterm{member-declarator} +shall be present only if the declarator declares a +templated function\iref{temp.pre}. +% +\indextext{trailing requires-clause@trailing \gterm{requires-clause}|see{\gterm{requires-clause}, trailing}}% +When present after a declarator, the \grammarterm{requires-clause} +is called the \defnx{trailing \grammarterm{requires-clause}}{% +\idxgram{requires-clause}!trailing}. +The trailing \grammarterm{requires-clause} introduces the +\grammarterm{constraint-expression} that results from interpreting +its \grammarterm{constraint-logical-or-expression} as a +\grammarterm{constraint-expression}. +% +\begin{example} \begin{codeblock} -enum class Col { red, yellow, green }; -int x = Col::red; // error: no \tcode{Col} to \tcode{int} conversion -Col y = Col::red; -if (y) { } // error: no \tcode{Col} to \tcode{bool} conversion +void f1(int a) requires true; // error: non-templated function +template + auto f2(T a) -> bool requires true; // OK +template + auto f3(T a) requires true -> bool; // error: \grammarterm{requires-clause} precedes \grammarterm{trailing-return-type} +void (*pf)() requires true; // error: constraint on a variable +void g(int (*)() requires true); // error: constraint on a \grammarterm{parameter-declaration} + +auto* p = new void(*)(char) requires true; // error: not a function declaration \end{codeblock} +\end{example} -\exitexample +\pnum +The optional \grammarterm{function-contract-specifier-seq}\iref{dcl.contract.func} +in an \grammarterm{init-declarator} +shall be present only if +the \grammarterm{declarator} declares a function. \pnum -\indextext{class!scope~of enumerator}% -Each \grammarterm{enum-name} and each unscoped \grammarterm{enumerator} is -declared in the scope that immediately contains the \grammarterm{enum-specifier}. -Each scoped \grammarterm{enumerator} is declared in the scope of the -enumeration. -These names obey the scope rules defined for all names -in~(\ref{basic.scope}) and~(\ref{basic.lookup}).\enterexample +Declarators have the syntax -\begin{codeblock} -enum direction { left='l', right='r' }; +\begin{bnf} +\nontermdef{declarator}\br + ptr-declarator\br + noptr-declarator parameters-and-qualifiers trailing-return-type +\end{bnf} -void g() { - direction d; // OK - d = left; // OK - d = direction::right; // OK -} +\begin{bnf} +\nontermdef{ptr-declarator}\br + noptr-declarator\br + ptr-operator ptr-declarator +\end{bnf} -enum class altitude { high='h', low='l' }; +\begin{bnf} +\nontermdef{noptr-declarator}\br + declarator-id \opt{attribute-specifier-seq}\br + noptr-declarator parameters-and-qualifiers\br + noptr-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br + \terminal{(} ptr-declarator \terminal{)} +\end{bnf} -void h() { - altitude a; // OK - a = high; // error: high not in scope - a = altitude::low; // OK -} -\end{codeblock} -\exitexample -\indextext{member!enumerator}% -An enumerator declared in class scope can be referred to using the class -member access operators (\tcode{::}, \tcode{.} (dot) and \tcode{->} -(arrow)), see~\ref{expr.ref}. -\enterexample +\begin{bnf} +\nontermdef{parameters-and-qualifiers}\br + \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br + \bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} +\end{bnf} -\begin{codeblock} -struct X { - enum direction { left='l', right='r' }; - int f(int i) { return i==left ? 0 : i==right ? 1 : 2; } -}; +\begin{bnf} +\nontermdef{trailing-return-type}\br + \terminal{->} type-id +\end{bnf} -void g(X* p) { - direction d; // error: \tcode{direction} not in scope - int i; - i = p->f(left); // error: \tcode{left} not in scope - i = p->f(X::right); // OK - i = p->f(p->left); // OK - // ... -} -\end{codeblock} -\exitexample +\begin{bnf} +\microtypesetup{protrusion=false} +\nontermdef{ptr-operator}\br + \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq}\br + \terminal{\&} \opt{attribute-specifier-seq}\br + \terminal{\&\&} \opt{attribute-specifier-seq}\br + nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} +\end{bnf} -\rSec1[basic.namespace]{Namespaces}% -\indextext{namespaces|(} +\begin{bnf} +\nontermdef{cv-qualifier-seq}\br + cv-qualifier \opt{cv-qualifier-seq} +\end{bnf} -\pnum -A namespace is an optionally-named declarative region. The name of a -namespace can be used to access entities declared in that namespace; -that is, the members of the namespace. Unlike other declarative regions, -the definition of a namespace can be split over several parts of one or -more translation units. +\begin{bnf} +\nontermdef{cv-qualifier}\br + \keyword{const}\br + \keyword{volatile} +\end{bnf} -\pnum -The outermost declarative region of a translation unit is a namespace; -see~\ref{basic.scope.namespace}. +\begin{bnf} +\nontermdef{ref-qualifier}\br + \terminal{\&}\br + \terminal{\&\&} +\end{bnf} -\rSec2[namespace.def]{Namespace definition}% -\indextext{definition!namespace}% -\indextext{namespace!definition} +\begin{bnf} +\nontermdef{declarator-id}\br + \opt{\terminal{...}} id-expression +\end{bnf} + +\rSec2[dcl.name]{Type names} \pnum -The grammar for a -\grammarterm{namespace-definition} -is +\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 +of that type that omits the name of the entity. \begin{bnf} -\nontermdef{namespace-name}\br - identifier\br - namespace-alias +\nontermdef{type-id}\br + type-specifier-seq \opt{abstract-declarator} \end{bnf} \begin{bnf} -\nontermdef{namespace-definition}\br - named-namespace-definition\br - unnamed-namespace-definition\br - nested-namespace-definition +\nontermdef{defining-type-id}\br + defining-type-specifier-seq \opt{abstract-declarator} \end{bnf} \begin{bnf} -\nontermdef{named-namespace-definition}\br - \terminal{inline\opt} \terminal{namespace} attribute-specifier-seq\opt identifier \terminal{\{} namespace-body \terminal{\}} +\nontermdef{abstract-declarator}\br + ptr-abstract-declarator\br + \opt{noptr-abstract-declarator} parameters-and-qualifiers trailing-return-type\br + abstract-pack-declarator \end{bnf} \begin{bnf} -\nontermdef{unnamed-namespace-definition}\br - \terminal{inline\opt} \terminal{namespace} attribute-specifier-seq\opt \terminal{\{} namespace-body \terminal{\}} +\nontermdef{ptr-abstract-declarator}\br + noptr-abstract-declarator\br + ptr-operator \opt{ptr-abstract-declarator} \end{bnf} \begin{bnf} -\nontermdef{nested-namespace-definition}\br - \terminal{namespace} enclosing-namespace-specifier \terminal{::} identifier \terminal{\{} namespace-body \terminal{\}} +\nontermdef{noptr-abstract-declarator}\br + \opt{noptr-abstract-declarator} parameters-and-qualifiers\br + \opt{noptr-abstract-declarator} \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br + \terminal{(} ptr-abstract-declarator \terminal{)} \end{bnf} \begin{bnf} -\nontermdef{enclosing-namespace-specifier}\br - identifier\br - enclosing-namespace-specifier \terminal{::} identifier +\nontermdef{abstract-pack-declarator}\br + noptr-abstract-pack-declarator\br + ptr-operator abstract-pack-declarator \end{bnf} \begin{bnf} -\nontermdef{namespace-body}\br - declaration-seq\opt +\nontermdef{noptr-abstract-pack-declarator}\br + noptr-abstract-pack-declarator parameters-and-qualifiers\br + \terminal{...} \end{bnf} -\pnum -Every \grammarterm{namespace-definition} shall appear in the global scope -or in a namespace scope~(\ref{basic.scope.namespace}). - -\pnum -In a \grammarterm{named-namespace-definition}, -the \grammarterm{identifier} is the name of the namespace. -If the \grammarterm{identifier}, when looked up~(\ref{basic.lookup.unqual}), -refers to a \grammarterm{namespace-name} (but not a \grammarterm{namespace-alias}) -introduced in the declarative region -in which the \grammarterm{named-namespace-definition} appears, -the \grammarterm{namespace-definition} -\indextext{extend|see{namespace, extend}} -\defnx{extends}{namespace!extend} the previously-declared namespace. -Otherwise, the \grammarterm{identifier} is introduced -as a \grammarterm{namespace-name} into the declarative region -in which the \grammarterm{named-namespace-definition} appears. +It is possible to identify uniquely the location in the +\grammarterm{abstract-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 +hypothetical identifier. +\begin{example} +\begin{codeblock} +int // \tcode{int i} +int * // \tcode{int *pi} +int *[3] // \tcode{int *p[3]} +int (*)[3] // \tcode{int (*p3i)[3]} +int *() // \tcode{int *f()} +int (*)(double) // \tcode{int (*pf)(double)} +\end{codeblock} +name respectively the types +``\tcode{int}'', +``pointer to +\tcode{int}'', +``array of 3 pointers to +\tcode{int}'', +``pointer to array of 3 +\tcode{int}'', +``function of (no parameters) returning pointer to +\tcode{int}'', +and ``pointer to a function of +(\tcode{double}) +returning +\tcode{int}''. +\end{example} + +\pnum +\begin{note} +A type can also be named by a \grammarterm{typedef-name}, +which is introduced by a typedef declaration +or \grammarterm{alias-declaration}\iref{dcl.typedef}. +\end{note} + +\rSec2[dcl.ambig.res]{Ambiguity resolution}% +\indextext{ambiguity!declaration versus cast}% +\indextext{declaration!parentheses in} + +\pnum +The ambiguity arising from the similarity between a function-style cast and +a declaration mentioned in~\ref{stmt.ambig} can also occur in the context of a declaration. +In that context, the choice is between +an object declaration +with a function-style cast as the initializer and +a declaration involving a function declarator +with a redundant set of parentheses around a parameter name. +Just as for the ambiguities mentioned in~\ref{stmt.ambig}, +the resolution is to consider any construct, +such as the potential parameter declaration, +that could possibly be a declaration +to be a declaration. +However, a construct that can syntactically be a \grammarterm{declaration} +whose outermost \grammarterm{declarator} +would match the grammar of a \grammarterm{declarator} +with a \grammarterm{trailing-return-type} +is a declaration only if it starts with \keyword{auto}. +\begin{note} +A declaration can be explicitly disambiguated by adding parentheses +around the argument. +The ambiguity can be avoided by use of copy-initialization or +list-initialization syntax, or by use of a non-function-style cast. +\end{note} +\begin{example} +\begin{codeblock} +struct S { + S(int); +}; +typedef struct BB { int C[2]; } *B, C; + +void foo(double a) { + S v(int(a)); // function declaration + S w(int()); // function declaration + S x((int(a))); // object declaration + S y((int)a); // object declaration + S z = int(a); // object declaration + S a(B()->C); // object declaration + S b(auto()->C); // function declaration +} +\end{codeblock} +\end{example} \pnum -Because a \grammarterm{namespace-definition} contains -\grammarterm{declaration}{s} in its \grammarterm{namespace-body} and a -\grammarterm{namespace-definition} is itself a \grammarterm{declaration}, it -follows that \grammarterm{namespace-definitions} can be nested. -\enterexample +An ambiguity can arise from the similarity between a function-style +cast and a +\grammarterm{type-id}. +The resolution is that any construct that could possibly be a +\grammarterm{type-id} +in its syntactic context shall be considered a +\grammarterm{type-id}. +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} +with a \grammarterm{trailing-return-type} +is considered a \grammarterm{type-id} only if it starts with \keyword{auto}. +\begin{example} +\begin{codeblock} +template struct X {}; +template struct Y {}; +X a; // \grammarterm{type-id} +X b; // expression (ill-formed) +Y c; // \grammarterm{type-id} (ill-formed) +Y d; // expression + +void foo(signed char a) { + sizeof(int()); // \grammarterm{type-id} (ill-formed) + sizeof(int(a)); // expression + sizeof(int(unsigned(a))); // \grammarterm{type-id} (ill-formed) + + (int())+1; // \grammarterm{type-id} (ill-formed) + (int(a))+1; // expression + (int(unsigned(a)))+1; // \grammarterm{type-id} (ill-formed) +} +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 +} +\end{codeblock} +\end{example} + +\pnum +Another ambiguity arises in a +\grammarterm{parameter-declaration-clause} when a +\grammarterm{type-name} +is nested in parentheses. +In this case, the choice is between the declaration of a parameter of type +pointer to function and the declaration of a parameter with redundant +parentheses around the +\grammarterm{declarator-id}. +The resolution is to consider the +\grammarterm{type-name} +as a +\grammarterm{simple-type-specifier} +rather than a +\grammarterm{declarator-id}. +\begin{example} \begin{codeblock} -namespace Outer { - int i; - namespace Inner { - void f() { i++; } // \tcode{Outer::i} - int i; - void g() { i++; } // \tcode{Inner::i} - } +class C { }; +void f(int(C)) { } // \tcode{void f(int(*fp)(C c)) \{ \}} + // not: \tcode{void f(int C) \{ \}} + +int g(C); + +void foo() { + f(1); // error: cannot convert \tcode{1} to function pointer + f(g); // OK } \end{codeblock} -\exitexample -\pnum -The \term{enclosing namespaces} of a declaration are those -namespaces in which the declaration lexically appears, except for a -redeclaration of a namespace member outside its original namespace -(e.g., a definition as specified in~\ref{namespace.memdef}). Such a -redeclaration has the same enclosing namespaces as the original -declaration. -\enterexample +For another example, \begin{codeblock} -namespace Q { - namespace V { - void f(); // enclosing namespaces are the global namespace, \tcode{Q}, and \tcode{Q::V} - class C { void m(); }; - } - void V::f() { // enclosing namespaces are the global namespace, \tcode{Q}, and \tcode{Q::V} - extern void h(); // ... so this declares \tcode{Q::V::h} - } - void V::C::m() { // enclosing namespaces are the global namespace, \tcode{Q}, and \tcode{Q::V} - } -} +class C { }; +void h(int *(C[10])); // \tcode{void h(int *(*_fp)(C _parm[10]));} + // not: \tcode{void h(int *C[10]);} \end{codeblock} -\exitexample +\end{example} -\pnum -If the optional initial \tcode{inline} keyword appears in a -\grammarterm{namespace-definition} for a particular namespace, that namespace is -declared to be an \term{inline namespace}. The \tcode{inline} keyword may be -used on a \grammarterm{namespace-definition} that extends a namespace -only if it was previously used on the \grammarterm{namespace-definition} -that initially declared the \grammarterm{namespace-name} for that namespace. +\rSec2[dcl.meaning]{Meaning of declarators}% + +\rSec3[dcl.meaning.general]{General}% +\indextext{declarator!meaning of|(} \pnum -The optional \grammarterm{attribute-specifier-seq} -in a \grammarterm{named-namespace-definition} -appertains to the namespace being defined or extended. +\indextext{declaration!type}% +A declarator contains exactly one \grammarterm{declarator-id}; +it names the entity that is declared. +If the \grammarterm{unqualified-id} occurring in a \grammarterm{declarator-id} +is a \grammarterm{template-id}, +the declarator shall appear in the \grammarterm{declaration} of a +\grammarterm{template-declaration}\iref{temp.decls}, +\grammarterm{explicit-specialization}\iref{temp.expl.spec}, or +\grammarterm{explicit-instantiation}\iref{temp.explicit}. +\begin{note} +An \grammarterm{unqualified-id} that is not an \grammarterm{identifier} +is used to declare +certain functions\iref{class.conv.fct,class.dtor,over.oper,over.literal}. +\end{note} +The optional \grammarterm{attribute-specifier-seq} following a \grammarterm{declarator-id} appertains to the entity that is declared. \pnum -Members of an inline namespace can be used in most respects as though they were members -of the enclosing namespace. Specifically, the inline namespace and its enclosing -namespace are both added to the set of associated namespaces used in -argument-dependent lookup~(\ref{basic.lookup.argdep}) whenever one of them is, -and a \grammarterm{using-directive}~(\ref{namespace.udir}) that names the inline -namespace is implicitly inserted into the enclosing namespace as for an unnamed -namespace~(\ref{namespace.unnamed}). Furthermore, each -member of the inline namespace can subsequently be partially -specialized~(\ref{temp.class.spec}), explicitly -instantiated~(\ref{temp.explicit}), or explicitly specialized~(\ref{temp.expl.spec}) as -though it were a member of the enclosing namespace. Finally, looking up a name in the -enclosing namespace via explicit qualification~(\ref{namespace.qual}) will include -members of the inline namespace brought in by the \grammarterm{using-directive} even if -there are declarations of that name in the enclosing namespace. - -\pnum -These properties are transitive: if a namespace \tcode{N} contains an inline namespace -\tcode{M}, which in turn contains an inline namespace \tcode{O}, then the members of -\tcode{O} can be used as though they were members of \tcode{M} or \tcode{N}. -The \term{inline namespace set} of \tcode{N} is the transitive closure of all -inline namespaces in \tcode{N}. -The \term{enclosing namespace set} of \tcode{O} is the set of namespaces -consisting of the innermost non-inline namespace enclosing -an inline namespace \tcode{O}, together with any intervening inline namespaces. - -\pnum -A \grammarterm{nested-namespace-definition} with an -\grammarterm{enclosing-namespace-specifier} \tcode{E}, -\grammarterm{identifier} \tcode{I} and -\grammarterm{namespace-body} \tcode{B} -is equivalent to -\begin{codeblock} -namespace E { namespace I { B } } -\end{codeblock} -\enterexample -\begin{codeblock} -namespace A::B::C { - int i; -} -\end{codeblock} -The above has the same effect as: -\begin{codeblock} -namespace A { - namespace B { - namespace C { - int i; - } - } -} -\end{codeblock} -\exitexample - -\rSec3[namespace.unnamed]{Unnamed namespaces}% -\indextext{namespace!unnamed} +If the declaration is a friend declaration: +\begin{itemize} +\item +The \grammarterm{declarator} does not bind a name. +\item +If the \grammarterm{id-expression} $E$ in +the \grammarterm{declarator-id} of the \grammarterm{declarator} is +a \grammarterm{qualified-id} or a \grammarterm{template-id}: +\begin{itemize} + \item +If the friend declaration is not a template declaration, +then in the lookup for the terminal name of $E$: +\begin{itemize} + \item +if the \grammarterm{unqualified-id} in $E$ is a \grammarterm{template-id}, +all function declarations are discarded; + \item +otherwise, +if the \grammarterm{declarator} corresponds\iref{basic.scope.scope} to +any declaration found of a non-template function, +all function template declarations are discarded; + \item +each remaining function template is replaced with the specialization chosen by +deduction from the friend declaration\iref{temp.deduct.decl} or +discarded if deduction fails. +\end{itemize} + \item +The \grammarterm{declarator} shall correspond to +one or more declarations found by the lookup; +they shall all have the same target scope, and +the target scope of the \grammarterm{declarator} is that scope. +\end{itemize} +\item +Otherwise, the terminal name of $E$ is not looked up. +The declaration's target scope is the innermost enclosing namespace scope; +if the declaration is contained by a block scope, +the declaration shall correspond to a reachable\iref{module.reach} declaration +that inhabits the innermost block scope. +\end{itemize} \pnum -An \grammarterm{unnamed-namespace-definition} behaves as if it were -replaced by - -\begin{ncsimplebnf} -\terminal{inline}\opt \terminal{namespace} \uniquens{} \terminal{\{ /* empty body */ \}}\br -\terminal{using namespace} \uniquens{} \terminal{;}\br -\terminal{namespace} \uniquens{} \terminal{\{} namespace-body \terminal{\}} -\end{ncsimplebnf} - -where -\tcode{inline} appears if and only if it appears in the -\grammarterm{unnamed-namespace-definition} -and all occurrences of \uniquens{} in a translation unit are replaced by -the same identifier, and this identifier differs from all other -identifiers in the translation unit. -The optional \grammarterm{attribute-specifier-seq} -in the \grammarterm{unnamed-namespace-definition} -appertains to \uniquens{}. -\enterexample - +Otherwise: +\begin{itemize} +\item +If the \grammarterm{id-expression} in +the \grammarterm{declarator-id} of the \grammarterm{declarator} is +a \grammarterm{qualified-id} $Q$, +let $S$ be its lookup context\iref{basic.lookup.qual}; +the declaration shall inhabit a namespace scope. +\item +Otherwise, let $S$ be the entity associated with the scope inhabited by +the \grammarterm{declarator}. +\item +If the \grammarterm{declarator} declares +an explicit instantiation or a partial or explicit specialization, +the \grammarterm{declarator} does not bind a name. +If it declares a class member, +the terminal name of the \grammarterm{declarator-id} is not looked up; +otherwise, only those lookup results that are nominable in $S$ +are considered when identifying +any function template specialization being declared\iref{temp.deduct.decl}. +\begin{example} \begin{codeblock} -namespace { int i; } // \uniquens\tcode{::i} -void f() { i++; } // \uniquens\tcode{::i++} - -namespace A { - namespace { - int i; // \tcode{A::}\uniquens\tcode{::i} - int j; // \tcode{A::}\uniquens\tcode{::j} +namespace N { + inline namespace O { + template void f(T); // \#1 + template void g(T) {} } - void g() { i++; } // \tcode{A::}\uniquens\tcode{::i++} -} - -using namespace A; -void h() { - i++; // error: \uniquens\tcode{::i} or \tcode{A::}\uniquens\tcode{::i} - A::i++; // \tcode{A::}\uniquens\tcode{::i} - j++; // \tcode{A::}\uniquens\tcode{::j} -} -\end{codeblock} -\exitexample - -\rSec3[namespace.memdef]{Namespace member definitions}% -\indextext{namespace!member definition} - -\pnum -A declaration in a namespace \tcode{N} (excluding declarations in nested scopes) -whose \grammarterm{declarator-id} is an \grammarterm{unqualified-id} -declares (or redeclares) a member of \tcode{N}, and may be a definition. -\enternote An explicit instantiation~(\ref{temp.explicit}) or -explicit specialization~(\ref{temp.expl.spec}) of a template -does not introduce a name and thus may be declared using an -\grammarterm{unqualified-id} in a member of the enclosing namespace set, -if the primary template is declared in an inline namespace. \exitnote -\enterexample - -\begin{codeblock} -namespace X { - void f() { /* ... */ } // OK: introduces \tcode{X::f()} - - namespace M { - void g(); // OK: introduces \tcode{X::M::g()} + namespace P { + template void f(T*); // \#2, more specialized than \#1 + template int g; } - using M::g; - void g(); // error: conflicts with \tcode{X::M::g()} + using P::f,P::g; } +template<> void N::f(int*) {} // OK, \#2 is not nominable +template void N::g(int); // error: lookup is ambiguous \end{codeblock} -\exitexample - -\pnum -Members of a named namespace can also be -defined outside that namespace by explicit -qualification~(\ref{namespace.qual}) of the name being defined, provided -that the entity being defined was already declared in the namespace and -the definition appears after the point of declaration in a namespace -that encloses the declaration's namespace. -\enterexample - +\end{example} +\item +Otherwise, +the terminal name of the \grammarterm{declarator-id} is not looked up. +If it is a qualified name, +the \grammarterm{declarator} shall correspond to +one or more declarations nominable in $S$; +all the declarations shall have the same target scope and +the target scope of the \grammarterm{declarator} is that scope. +\begin{example} \begin{codeblock} namespace Q { namespace V { void f(); } - void V::f() { /* ... */ } // OK - void V::g() { /* ... */ } // error: \tcode{g()} is not yet a member of \tcode{V} + void V::f() { @\commentellip@ } // OK + void V::g() { @\commentellip@ } // error: \tcode{g()} is not yet a member of \tcode{V} namespace V { void g(); } } namespace R { - void Q::V::g() { /* ... */ } // error: \tcode{R} doesn't enclose \tcode{Q} -} -\end{codeblock} -\exitexample - -\pnum -If a \tcode{friend} declaration in a non-local class first declares a -class, function, class template or function template\footnote{this implies that the name of the class or function is unqualified.} -the friend is a member of the innermost enclosing -namespace. The \tcode{friend} declaration does not by itself make the name -visible to unqualified lookup~(\ref{basic.lookup.unqual}) or qualified -lookup~(\ref{basic.lookup.qual}). \enternote The name of the friend will be -visible in its namespace if a matching declaration is provided at namespace -scope (either before or after the class definition granting friendship). -\exitnote If a friend -function or function template is called, its name may be found by the -name lookup that considers functions from namespaces and classes -associated with the types of the function -arguments~(\ref{basic.lookup.argdep}). If the -name in a \tcode{friend} declaration is neither qualified nor a -\grammarterm{template-id} and the declaration is a function or an -\grammarterm{elaborated-type-specifier}, the lookup to determine whether -the entity has been previously declared shall not consider any scopes -outside the innermost enclosing namespace. \enternote The other forms of -\tcode{friend} declarations cannot declare a new member of the innermost -enclosing namespace and thus follow the usual lookup rules. -\exitnote -\enterexample - -\begin{codeblock} -// Assume \tcode{f} and \tcode{g} have not yet been declared. -void h(int); -template void f2(T); -namespace A { - class X { - friend void f(X); // \tcode{A::f(X)} is a friend - class Y { - friend void g(); // \tcode{A::g} is a friend - friend void h(int); // \tcode{A::h} is a friend - // \tcode{::h} not considered - friend void f2<>(int); // \tcode{::f2<>(int)} is a friend - }; - }; - - // \tcode{A::f}, \tcode{A::g} and \tcode{A::h} are not visible here - X x; - void g() { f(x); } // definition of \tcode{A::g} - void f(X) @\tcode{\{ /* ... */\}}@ // definition of \tcode{A::f} - void h(int) @\tcode{\{ /* ... */ \}}@ // definition of \tcode{A::h} - // \tcode{A::f}, \tcode{A::g} and \tcode{A::h} are visible here and known to be friends + void Q::V::g() { @\commentellip@ } // error: \tcode{R} doesn't enclose \tcode{Q} } +\end{codeblock} +\end{example} +\item +If the declaration inhabits a block scope $S$ and +declares a function\iref{dcl.fct} or uses the \keyword{extern} specifier, +the declaration shall not be attached to a named module\iref{module.unit}; +its target scope is the innermost enclosing namespace scope, +but the name is bound in $S$. +\begin{example} +\begin{codeblock} +namespace X { + void p() { + q(); // error: \tcode{q} not yet declared + extern void q(); // \tcode{q} is a member of namespace \tcode{X} + extern void r(); // \tcode{r} is a member of namespace \tcode{X} + } -using A::x; + void middle() { + q(); // error: \tcode{q} not found + } -void h() { - A::f(x); - A::X::f(x); // error: \tcode{f} is not a member of \tcode{A::X} - A::X::Y::g(); // error: \tcode{g} is not a member of \tcode{A::X::Y} + void q() { @\commentellip@ } // definition of \tcode{X::q} } -\end{codeblock} -\exitexample -\rSec2[namespace.alias]{Namespace alias}% -\indextext{namespace!alias}% -\indextext{alias!namespace}% -\indextext{synonym} +void q() { @\commentellip@ } // some other, unrelated \tcode{q} +void X::r() { @\commentellip@ } // error: \tcode{r} cannot be declared by \grammarterm{qualified-id} +\end{codeblock} +\end{example} +\end{itemize} \pnum -A \grammarterm{namespace-alias-definition} declares an alternate name for a -namespace according to the following grammar: +A +\keyword{static}, +\keyword{thread_local}, +\keyword{extern}, +\keyword{mutable}, +\keyword{friend}, +\keyword{inline}, +\keyword{virtual}, +\keyword{constexpr}, +\keyword{consteval}, +\keyword{constinit}, +or +\tcode{typedef} +specifier +or an \grammarterm{explicit-specifier} +applies directly to each \grammarterm{declarator-id} +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}. + +\pnum +Thus, (for each \grammarterm{declarator}) a declaration has the form +\begin{codeblock} +T D +\end{codeblock} +where +\tcode{T} +is of the form \opt{\grammarterm{attribute-specifier-seq}} +\grammarterm{decl-specifier-seq} +and +\tcode{D} +is a declarator. +Following is a recursive procedure for determining +the type specified for the contained +\grammarterm{declarator-id} +by such a declaration. -\begin{bnf} -\nontermdef{namespace-alias}\br - identifier -\end{bnf} +\pnum +First, the +\grammarterm{decl-specifier-seq} +determines a type. +In a declaration +\begin{codeblock} +T D +\end{codeblock} +the +\grammarterm{decl-specifier-seq} +\tcode{T} +determines the type +\tcode{T}. +\begin{example} +In the declaration +\begin{codeblock} +int unsigned i; +\end{codeblock} +the type specifiers +\tcode{int} +\tcode{unsigned} +determine the type +``\tcode{unsigned int}''\iref{dcl.type.simple}. +\end{example} + +\pnum +In a declaration +\opt{\grammarterm{attribute-specifier-seq}} +\tcode{T} +\tcode{D} +where +\tcode{D} +is an unadorned \grammarterm{declarator-id}, +the type of the declared entity is +``\tcode{T}''. -\begin{bnf} -\nontermdef{namespace-alias-definition}\br - \terminal{namespace} identifier \terminal{=} qualified-namespace-specifier \terminal{;} -\end{bnf} +\pnum +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{D} +has the form +\begin{ncsimplebnf} +\terminal{(} \terminal{D1} \terminal{)} +\end{ncsimplebnf} +the type of the contained +\grammarterm{declarator-id} +is the same as that of the contained +\grammarterm{declarator-id} +in the declaration +\begin{codeblock} +T D1 +\end{codeblock} +\indextext{declaration!parentheses in}% +Parentheses do not alter the type of the embedded +\grammarterm{declarator-id}, +but they can alter the binding of complex declarators. -\begin{bnf} -\nontermdef{qualified-namespace-specifier}\br - nested-name-specifier\opt namespace-name -\end{bnf} +\rSec3[dcl.ptr]{Pointers}% +\indextext{declarator!pointer}% \pnum -The \grammarterm{identifier} in a \grammarterm{namespace-alias-definition} is -a synonym for the name of the namespace denoted by the -\grammarterm{qualified-namespace-specifier} and becomes a -\grammarterm{namespace-alias}. -\enternote -When looking up a \grammarterm{namespace-name} in a -\grammarterm{namespace-alias-definition}, only namespace names are -considered, see~\ref{basic.lookup.udir}. -\exitnote +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{D} +has the form +\begin{ncsimplebnf} +\terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1} +\end{ncsimplebnf} +and the type of the contained \grammarterm{declarator-id} in the declaration +\tcode{T} +\tcode{D1} +is ``\placeholder{derived-declarator-type-list} +\tcode{T}'', +the type of the \grammarterm{declarator-id} in +\tcode{D} +is ``\placeholder{derived-declarator-type-list} \grammarterm{cv-qualifier-seq} pointer to +\tcode{T}''. +\indextext{declaration!pointer}% +\indextext{declaration!constant pointer}% +The +\grammarterm{cv-qualifier}{s} +apply to the pointer and not to the object pointed to. +Similarly, the optional \grammarterm{attribute-specifier-seq}\iref{dcl.attr.grammar} appertains to the pointer and not to the object pointed to. \pnum -In a declarative region, a \grammarterm{namespace-alias-definition} can be -used to redefine a \grammarterm{namespace-alias} declared in that -declarative region to refer only to the namespace to which it already -refers. -\enterexample -the following declarations are well-formed: +\begin{example} +The declarations +\begin{codeblock} +const int ci = 10, *pc = &ci, *const cpc = pc, **ppc; +int i, *p, *const cp = &i; +\end{codeblock} +declare +\tcode{ci}, +a constant integer; +\tcode{pc}, +a pointer to a constant integer; +\tcode{cpc}, +a constant pointer to a constant integer; +\tcode{ppc}, +a pointer to a pointer to a constant integer; +\tcode{i}, +an integer; +\tcode{p}, +a pointer to integer; and +\tcode{cp}, +a constant pointer to integer. +The value of +\tcode{ci}, +\tcode{cpc}, +and +\tcode{cp} +cannot be changed after initialization. +The value of +\tcode{pc} +can be changed, and so can the object pointed to by +\tcode{cp}. +Examples of +some correct operations are +\begin{codeblock} +i = ci; +*cp = ci; +pc++; +pc = cpc; +pc = p; +ppc = &pc; +\end{codeblock} +Examples of ill-formed operations are \begin{codeblock} -namespace Company_with_very_long_name { /* ... */ } -namespace CWVLN = Company_with_very_long_name; -namespace CWVLN = Company_with_very_long_name; // OK: duplicate -namespace CWVLN = CWVLN; +ci = 1; // error +ci++; // error +*pc = 2; // error +cp = &ci; // error +cpc++; // error +p = pc; // error +ppc = &p; // error \end{codeblock} -\exitexample -\rSec2[namespace.udecl]{The \tcode{using} declaration}% -\indextext{using-declaration|(} +Each is unacceptable because it would either change the value of an object declared +\keyword{const} +or allow it to be changed through a cv-unqualified pointer later, for example: +\begin{codeblock} +*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 -A \grammarterm{using-declaration} introduces a name into the declarative -region in which the \grammarterm{using-declaration} appears. - -\begin{bnf} -\nontermdef{using-declaration}\br - \terminal{using typename\opt} nested-name-specifier unqualified-id \terminal{;}\br -\end{bnf} +\begin{note} +Forming a pointer to reference type is ill-formed; see~\ref{dcl.ref}. +Forming a function pointer type is ill-formed if the function type has +\grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier}; +see~\ref{dcl.fct}. +Since the address of a bit-field\iref{class.bit} cannot be taken, +a pointer can never point to a bit-field. +\end{note} -The member name specified in a \grammarterm{using-declaration} is declared -in the declarative region in which the \grammarterm{using-declaration} -appears. \enternote Only the specified name is so declared; specifying -an enumeration name in a \grammarterm{using-declaration} does not declare -its enumerators in the \grammarterm{using-declaration}'s declarative -region. -\exitnote -If a \grammarterm{using-declaration} names a constructor~(\ref{class.qual}), it -implicitly declares a set of constructors in the class in which the -\grammarterm{using-declaration} appears~(\ref{class.inhctor}); otherwise the -name specified in a \grammarterm{using-declaration} is a synonym for a set of -declarations in another namespace or class. +\rSec3[dcl.ref]{References}% +\indextext{declarator!reference} \pnum -Every \grammarterm{using-declaration} is a \grammarterm{declaration} and a -\grammarterm{member-declaration} and so can be used in a class definition. -\enterexample - +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{D} +has either of the forms +\begin{ncsimplebnf} +\terminal{\&} \opt{attribute-specifier-seq} \terminal{D1}\br +\terminal{\&\&} \opt{attribute-specifier-seq} \terminal{D1} +\end{ncsimplebnf} +and the type of the contained \grammarterm{declarator-id} in the declaration +\tcode{T} +\tcode{D1} +is ``\placeholder{derived-declarator-type-list} +\tcode{T}'', +the type of the \grammarterm{declarator-id} in +\tcode{D} +is ``\placeholder{derived-declarator-type-list} reference to +\tcode{T}''. +The optional \grammarterm{attribute-specifier-seq} appertains to the reference type. +Cv-qualified references are ill-formed except when the cv-qualifiers +are introduced through the use of a +\grammarterm{typedef-name}\iref{dcl.typedef,temp.param} or +\grammarterm{decltype-specifier}\iref{dcl.type.decltype}, +in which case the cv-qualifiers are ignored. +\begin{example} \begin{codeblock} -struct B { - void f(char); - void g(char); - enum E { e }; - union { int x; }; -}; - -struct D : B { - using B::f; - void f(int) { f('c'); } // calls \tcode{B::f(char)} - void g(int) { g('c'); } // recursively calls \tcode{D::g(int)} -}; +typedef int& A; +const A aref = 3; // error: lvalue reference to non-\keyword{const} initialized with rvalue \end{codeblock} -\exitexample + +The type of +\tcode{aref} +is ``lvalue reference to \tcode{int}'', +not ``lvalue reference to \tcode{const int}''. +\end{example} +\begin{note} +A reference can be thought of as a name of an object. +\end{note} +\indextext{\idxcode{void\&}}% +Forming the type +``reference to \cv{}~\keyword{void}'' +is ill-formed. + \pnum -In a \grammarterm{using-declaration} used as a -\grammarterm{member-declaration}, the \grammarterm{nested-name-specifier} -shall name a base class of the class being defined. If such a -\grammarterm{using-declaration} names a constructor, the -\grammarterm{nested-name-specifier} shall name a direct base class of the class -being defined; otherwise it introduces the set of declarations found by -member name lookup~(\ref{class.member.lookup},~\ref{class.qual}). -\enterexample +A reference type that is declared using \tcode{\&} is called an +\defn{lvalue reference}, and a reference type that +is declared using \tcode{\&\&} is called an +\defn{rvalue reference}. Lvalue references and +rvalue references are distinct types. Except where explicitly noted, they are +semantically equivalent and commonly referred to as references. +\pnum +\indextext{declaration!reference}% +\indextext{parameter!reference}% +\begin{example} \begin{codeblock} -class C { - int g(); -}; +void f(double& a) { a += 3.14; } +// ... +double d = 0; +f(d); +\end{codeblock} +declares +\tcode{a} +to be a reference parameter of +\tcode{f} +so the call +\tcode{f(d)} +will add +\tcode{3.14} +to +\tcode{d}. -class D2 : public B { - using B::f; // OK: \tcode{B} is a base of \tcode{D2} - using B::e; // OK: \tcode{e} is an enumerator of base \tcode{B} - using B::x; // OK: \tcode{x} is a union member of base \tcode{B} - using C::g; // error: \tcode{C} isn't a base of \tcode{D2} -}; +\begin{codeblock} +int v[20]; +// ... +int& g(int i) { return v[i]; } +// ... +g(3) = 7; \end{codeblock} -\exitexample +declares the function +\tcode{g()} +to return a reference to an integer so +\tcode{g(3)=7} +will assign +\tcode{7} +to the fourth element of the array +\tcode{v}. +For another example, +\begin{codeblock} +struct link { + link* next; +}; -\pnum -\enternote -Since destructors do not have names, a -\grammarterm{using-declaration} cannot refer to a -destructor for a base class. Since specializations of member templates -for conversion functions are not found by name lookup, they are not -considered when a \grammarterm{using-declaration} specifies a conversion -function~(\ref{temp.mem}). -\exitnote -If an assignment operator brought from a base class into a derived class -scope has the signature of a copy/move assignment -operator for the derived -class~(\ref{class.copy}), the \grammarterm{using-declaration} does not by -itself suppress the implicit declaration of the derived class -assignment operator; the copy/move assignment -operator from the base -class is hidden or overridden by the implicitly-declared -copy/move assignment -operator of the derived class, as described below. +link* first; -\pnum -A \grammarterm{using-declaration} shall not name a \grammarterm{template-id}. -\enterexample +void h(link*& p) { // \tcode{p} is a reference to pointer + p->next = first; + first = p; + p = 0; +} +void k() { + link* q = new link; + h(q); +} +\end{codeblock} +declares +\tcode{p} +to be a reference to a pointer to +\tcode{link} +so +\tcode{h(q)} +will leave +\tcode{q} +with the value zero. +See also~\ref{dcl.init.ref}. +\end{example} + +\pnum +It is unspecified whether or not +a reference requires storage\iref{basic.stc}. + +\pnum +\indextext{restriction!reference}% +There shall be no references to references, +no arrays of references, and no pointers to references. +\indextext{initialization!reference}% +The declaration of a reference shall contain an +\grammarterm{initializer}\iref{dcl.init.ref} +except when the declaration contains an explicit +\keyword{extern} +specifier\iref{dcl.stc}, +is a class member\iref{class.mem} declaration within a class definition, +or is the declaration of a parameter or a return type\iref{dcl.fct}; see~\ref{basic.def}. + +\pnum +Attempting to bind a reference to a function where +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. +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. +\begin{note} +\indextext{reference!null}% +The object designated by such a glvalue can be +outside its lifetime\iref{basic.life}. +Because a null pointer value or a pointer past the end of an object +does not point to an object, +a reference in a well-defined program cannot refer to such things; +see~\ref{expr.unary.op}. +As described in~\ref{class.bit}, a reference cannot be bound directly +to a bit-field. +\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. +\begin{example} \begin{codeblock} -struct A { - template void f(T); - template struct X { }; -}; -struct B : A { - using A::f; // ill-formed - using A::X; // ill-formed -}; +int &f(int&); +int &g(); +extern int &ir3; +int *ip = 0; +int &ir1 = *ip; // undefined behavior: null pointer +int &ir2 = f(ir3); // undefined behavior: \tcode{ir3} not yet initialized +int &ir3 = g(); +int &ir4 = f(ir4); // undefined behavior: \tcode{ir4} used in its own initializer + +char x alignas(int); +int &ir5 = *reinterpret_cast(&x); // undefined behavior: initializer refers to char object +\end{codeblock} +\end{example} + +\pnum +\indextext{reference collapsing}% +If a \grammarterm{typedef-name}\iref{dcl.typedef,temp.param} +or a \grammarterm{decltype-specifier}\iref{dcl.type.decltype} denotes a type \tcode{TR} that +is a reference to a type \tcode{T}, an attempt to create the type ``lvalue reference to \cv{}~\tcode{TR}'' +creates the type ``lvalue reference to \tcode{T}'', while an attempt to create +the type ``rvalue reference to \cv{}~\tcode{TR}'' creates the type \tcode{TR}. +\begin{note} +This rule is known as reference collapsing. +\end{note} +\begin{example} +\begin{codeblock} +int i; +typedef int& LRI; +typedef int&& RRI; + +LRI& r1 = i; // \tcode{r1} has the type \tcode{int\&} +const LRI& r2 = i; // \tcode{r2} has the type \tcode{int\&} +const LRI&& r3 = i; // \tcode{r3} has the type \tcode{int\&} + +RRI& r4 = i; // \tcode{r4} has the type \tcode{int\&} +RRI&& r5 = 5; // \tcode{r5} has the type \tcode{int\&\&} + +decltype(r2)& r6 = i; // \tcode{r6} has the type \tcode{int\&} +decltype(r2)&& r7 = i; // \tcode{r7} has the type \tcode{int\&} \end{codeblock} -\exitexample +\end{example} \pnum -A \grammarterm{using-declaration} shall not name a namespace. +\begin{note} +Forming a reference to function type is ill-formed if the function +type has \grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier}; +see~\ref{dcl.fct}. +\end{note} -\pnum -A \grammarterm{using-declaration} shall not name a scoped enumerator. +\rSec3[dcl.mptr]{Pointers to members}% +\indextext{declarator!pointer-to-member}% +\indextext{pointer to member}% \pnum -A \grammarterm{using-declaration} for a class member shall be a -\grammarterm{member-declaration}. -\enterexample +\indextext{component name}% +The component names of a \grammarterm{ptr-operator} are +those of its \grammarterm{nested-name-specifier}, if any. +\pnum +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{D} +has the form +\begin{ncsimplebnf} +nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1} +\end{ncsimplebnf} +and the +\grammarterm{nested-name-specifier} +designates a class, +and the type of the contained \grammarterm{declarator-id} in the declaration +\tcode{T} +\tcode{D1} +is ``\placeholder{derived-declarator-type-list} +\tcode{T}'', +the type of the \grammarterm{declarator-id} in +\tcode{D} +is ``\placeholder{derived-declarator-type-list} \grammarterm{cv-qualifier-seq} pointer to member of class +\grammarterm{nested-name-specifier} of type +\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} \begin{codeblock} struct X { - int i; - static int s; + void f(int); + int a; }; +struct Y; -void f() { - using X::i; // error: \tcode{X::i} is a class member - // and this is not a member declaration. - using X::s; // error: \tcode{X::s} is a class member - // and this is not a member declaration. -} +int X::* pmi = &X::a; +void (X::* pmf)(int) = &X::f; +double X::* pmd; +char Y::* pmc; +\end{codeblock} +declares +\tcode{pmi}, +\tcode{pmf}, +\tcode{pmd} +and +\tcode{pmc} +to be a pointer to a member of +\tcode{X} +of type +\tcode{int}, +a pointer to a member of +\tcode{X} +of type +\tcode{void(int)}, +a pointer to a member of +\tcode{X} +of type +\tcode{double} +and a pointer to a member of +\tcode{Y} +of type +\tcode{char} +respectively. +The declaration of +\tcode{pmd} +is well-formed even though +\tcode{X} +has no members of type +\tcode{double}. +Similarly, the declaration of +\tcode{pmc} +is well-formed even though +\tcode{Y} +is an incomplete type. +\tcode{pmi} +and +\tcode{pmf} +can be used like this: +\begin{codeblock} +X obj; +// ... +obj.*pmi = 7; // assign \tcode{7} to an integer member of \tcode{obj} +(obj.*pmf)(7); // call a function member of \tcode{obj} with the argument \tcode{7} \end{codeblock} -\exitexample +\end{example} \pnum -Members declared by a \grammarterm{using-declaration} can be referred to by -explicit qualification just like other member -names~(\ref{namespace.qual}). -\enterexample +A pointer to member shall not point to a static member +of a class\iref{class.static}, +a member with reference type, +or +``\cv{}~\keyword{void}''. -\begin{codeblock} -void f(); +\pnum +\begin{note} +See also~\ref{expr.unary} and~\ref{expr.mptr.oper}. +The type ``pointer to member'' is distinct from the type ``pointer'', +that is, a pointer to member is declared only by the pointer-to-member +declarator syntax, and never by the pointer declarator syntax. +There is no ``reference-to-member'' type in \Cpp{}. +\end{note} -namespace A { - void g(); -} +\rSec3[dcl.array]{Arrays}% +\indextext{declarator!array} -namespace X { - using ::f; // global \tcode{f} - using A::g; // \tcode{A}'s \tcode{g} -} +\pnum +In a declaration \tcode{T} \tcode{D} where \tcode{D} has the form +\begin{ncsimplebnf} +\terminal{D1} \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq} +\end{ncsimplebnf} +and the type of the contained \grammarterm{declarator-id} +in the declaration \tcode{T} \tcode{D1} +is ``\placeholder{derived-declarator-type-list} \tcode{T}'', +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.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; +\tcode{N} shall be greater than zero. + +\pnum +In a declaration \tcode{T} \tcode{D} where \tcode{D} has the form +\begin{ncsimplebnf} +\terminal{D1 [ ]} \opt{attribute-specifier-seq} +\end{ncsimplebnf} +and the type of the contained \grammarterm{declarator-id} +in the declaration \tcode{T} \tcode{D1} +is ``\placeholder{derived-declarator-type-list} \tcode{T}'', +the type of the \grammarterm{declarator-id} in \tcode{D} is +``\placeholder{derived-declarator-type-list} array of unknown bound of \tcode{T}'', except as specified below. -void h() -{ - X::f(); // calls \tcode{::f} - X::g(); // calls \tcode{A::g} -} +\pnum +\indextext{declaration!array}% +\label{term.array.type}% +A type of the form ``array of \tcode{N} \tcode{U}'' or +``array of unknown bound of \tcode{U}'' is an \defn{array type}. +The optional \grammarterm{attribute-specifier-seq} +appertains to the array type. + +\pnum +\tcode{U} is called the array \defn{element type}; +this type shall not be +a reference type, +a function type, +an array of unknown bound, or +\cv{}~\keyword{void}. +\begin{note} +An array can be constructed +from one of the fundamental types (except \keyword{void}), +from a pointer, +from a pointer to member, +from a class, +from an enumeration type, +or from an array of known bound. +\end{note} +\begin{example} +\begin{codeblock} +float fa[17], *afp[17]; \end{codeblock} -\exitexample +declares an array of \tcode{float} numbers and +an array of pointers to \tcode{float} numbers. +\end{example} \pnum -A \grammarterm{using-declaration} is a \grammarterm{declaration} and can -therefore be used repeatedly where (and only where) multiple -declarations are allowed. -\enterexample - +Any type of the form +``\grammarterm{cv-qualifier-seq} array of \tcode{N} \tcode{U}'' +is adjusted to +``array of \tcode{N} \grammarterm{cv-qualifier-seq} \tcode{U}'', +and similarly for ``array of unknown bound of \tcode{U}''. +\begin{example} \begin{codeblock} -namespace A { - int i; -} +typedef int A[5], AA[2][3]; +typedef const A CA; // type is ``array of 5 \tcode{const int}'' +typedef const AA CAA; // type is ``array of 2 array of 3 \tcode{const int}'' +\end{codeblock} +\end{example} +\begin{note} +An ``array of \tcode{N} \grammarterm{cv-qualifier-seq} \tcode{U}'' +has cv-qualified type; see~\ref{basic.type.qualifier}. +\end{note} + +\pnum +An object of type ``array of \tcode{N} \tcode{U}'' consists of +a contiguously allocated non-empty set +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, +an array bound may be omitted in some cases in the declaration of a function +parameter\iref{dcl.fct}. +An array bound may also be omitted +when an object (but not a non-static data member) of array type is initialized +and the declarator is followed by +an initializer\iref{dcl.init,class.mem,expr.type.conv,expr.new}. +\indextext{array size!default}% +In these cases, the array bound is calculated +from the number of initial elements (say, \tcode{N}) +supplied\iref{dcl.init.aggr}, +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 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} +\begin{codeblock} +extern int x[10]; +struct S { + static int y[10]; +}; -namespace A1 { - using A::i; - using A::i; // OK: double declaration -} +int x[]; // OK, bound is 10 +int S::y[]; // OK, bound is 10 void f() { - using A::i; - using A::i; // error: double declaration + extern int x[]; + int i = sizeof(x); // error: incomplete object type } -struct B { - int i; -}; - -struct X : B { - using B::i; - using B::i; // error: double member declaration -}; +namespace A { extern int z[3]; } +int A::z[] = {}; // OK, defines an array of 3 elements \end{codeblock} -\exitexample +\end{example} \pnum -Members added to the namespace after the \grammarterm{using-declaration} -are not considered when a use of the name is made. \enternote Thus, additional -overloads added after the \grammarterm{using-declaration} are ignored, but -default function arguments~(\ref{dcl.fct.default}), default template -arguments~(\ref{temp.param}), and template specializations~(\ref{temp.class.spec}, -\ref{temp.expl.spec}) are considered. \exitnote -\enterexample - +\indextext{declarator!multidimensional array}% +\begin{note} +When several ``array of'' specifications are adjacent, +a multidimensional array type is created; +only the first of the constant expressions +that specify the bounds of the arrays can be omitted. +\begin{example} \begin{codeblock} -namespace A { - void f(int); -} +int x3d[3][5][7]; +\end{codeblock} +declares an array of three elements, +each of which is an array of five elements, +each of which is an array of seven integers. +The overall array can be viewed as a +three-dimensional array of integers, +with rank $3 \times 5 \times 7$. +Any of the expressions +\tcode{x3d}, +\tcode{x3d[i]}, +\tcode{x3d[i][j]}, +\tcode{x3d[i][j][k]} +can reasonably appear in an expression. +The expression +\tcode{x3d[i]} +is equivalent to +\tcode{*(x3d + i)}; +in that expression, +\tcode{x3d} +is subject to the array-to-pointer conversion\iref{conv.array} +and is first converted to +a pointer to a 2-dimensional +array with rank +$5 \times 7$ +that points to the first element of \tcode{x3d}. +Then \tcode{i} is added, +which on typical implementations involves multiplying +\tcode{i} by the +length of the object to which the pointer points, +which is \tcode{sizeof(int)}$ \times 5 \times 7$. +The result of the addition and indirection is +an lvalue denoting +the $\tcode{i}^\text{th}$ array element of +\tcode{x3d} +(an array of five arrays of seven integers). +If there is another subscript, +the same argument applies again, so +\tcode{x3d[i][j]} is +an lvalue denoting +the $\tcode{j}^\text{th}$ array element of +the $\tcode{i}^\text{th}$ array element of +\tcode{x3d} +(an array of seven integers), and +\tcode{x3d[i][j][k]} is +an lvalue denoting +the $\tcode{k}^\text{th}$ array element of +the $\tcode{j}^\text{th}$ array element of +the $\tcode{i}^\text{th}$ array element of +\tcode{x3d} +(an integer). +\end{example} +The first subscript in the declaration helps determine +the amount of storage consumed by an array +but plays no other part in subscript calculations. +\end{note} + +\pnum +\begin{note} +Conversions affecting expressions of array type are described in~\ref{conv.array}. +\end{note} + +\pnum +\begin{note} +The subscript operator can be overloaded for a class\iref{over.sub}. +For the operator's built-in meaning, see \ref{expr.sub}. +\end{note} + +\rSec3[dcl.fct]{Functions}% +\indextext{declarator!function|(} + +\pnum +\indextext{type!function}% +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{T} may be empty and +\tcode{D} +has the form +\begin{ncsimplebnf} +\terminal{D1} \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br +\bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \opt{trailing-return-type} +\end{ncsimplebnf} +a \placeholder{derived-declarator-type-list} is determined as follows: +\begin{itemize} +\item +If the \grammarterm{unqualified-id} of the \grammarterm{declarator-id} +is a \grammarterm{conversion-function-id}, +the \placeholder{derived-declarator-type-list} is empty. -using A::f; // \tcode{f} is a synonym for \tcode{A::f}; - // that is, for \tcode{A::f(int)}. -namespace A { - void f(char); -} +\item +Otherwise, the \placeholder{derived-declarator-type-list} is as appears in +the type ``\placeholder{derived-declarator-type-list} \tcode{T}'' +of the contained +\grammarterm{declarator-id} +in the declaration +\tcode{T} +\tcode{D1}. +\end{itemize} +The declared return type \tcode{U} of the function type +is determined as follows: +\begin{itemize} +\item +If the \grammarterm{trailing-return-type} is present, +\tcode{T} shall be the single \grammarterm{type-specifier} \keyword{auto}, and +\tcode{U} is the type specified by the \grammarterm{trailing-return-type}. -void foo() { - f('a'); // calls \tcode{f(int)}, -} // even though \tcode{f(char)} exists. +\item +Otherwise, if the declaration declares a conversion function, +see~\ref{class.conv.fct}. -void bar() { - using A::f; // \tcode{f} is a synonym for \tcode{A::f}; - // that is, for \tcode{A::f(int)} and \tcode{A::f(char)}. - f('a'); // calls \tcode{f(char)} +\item +Otherwise, \tcode{U} is \tcode{T}. +\end{itemize} +The type of the +\grammarterm{declarator-id} +in +\tcode{D} +is +``\placeholder{derived-declarator-type-list} +\opt{\keyword{noexcept}} +function of parameter-type-list +\opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}} +returning \tcode{U}'', where +\begin{itemize} +\item +the parameter-type-list is derived from +the \grammarterm{parameter-declaration-clause} as described below and +\item +the optional \keyword{noexcept} is present if and only if +the exception specification\iref{except.spec} is non-throwing. +\end{itemize} +Such a type is a \defnadj{function}{type}. +\begin{footnote} +As indicated by syntax, cv-qualifiers are a significant component in function return types. +\end{footnote} +The optional \grammarterm{attribute-specifier-seq} +appertains to the function type. + +\pnum +\indextext{declaration!function}% +\begin{bnf} +\nontermdef{parameter-declaration-clause}\br + \terminal{...}\br + \opt{parameter-declaration-list}\br + parameter-declaration-list \terminal{,} \terminal{...}\br + parameter-declaration-list \terminal{...} +\end{bnf} + +\begin{bnf} +\nontermdef{parameter-declaration-list}\br + parameter-declaration\br + parameter-declaration-list \terminal{,} parameter-declaration +\end{bnf} + +\begin{bnf} +\nontermdef{parameter-declaration}\br + \opt{attribute-specifier-seq} \opt{\keyword{this}} decl-specifier-seq declarator\br + \opt{attribute-specifier-seq} decl-specifier-seq declarator \terminal{=} initializer-clause\br + \opt{attribute-specifier-seq} \opt{\keyword{this}} decl-specifier-seq \opt{abstract-declarator}\br + \opt{attribute-specifier-seq} decl-specifier-seq \opt{abstract-declarator} \terminal{=} initializer-clause +\end{bnf} + +The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{parameter-declaration} +appertains to the parameter. + +\pnum +\indextext{declaration!parameter}% +The +\grammarterm{parameter-declaration-clause} +determines the arguments that can be specified, and their processing, when the function is called. +\begin{note} +\indextext{conversion!argument}% +The +\grammarterm{parameter-declaration-clause} +is used to convert the arguments specified on the function call; +see~\ref{expr.call}. +\end{note} +\indextext{argument list!empty}% +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. +\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}. +If the +\grammarterm{parameter-declaration-clause} +\indextext{argument type!unknown}% +\indextext{\idxcode{...}|see{ellipsis}}% +\indextext{declaration!ellipsis in function}% +\indextext{argument list!variable}% +\indextext{parameter list!variable}% +terminates with an ellipsis or a function parameter +pack\iref{temp.variadic}, the number of arguments shall be equal +to or greater than the number of parameters that do not have a default +argument and are not function parameter packs. +Where syntactically correct and where ``\tcode{...}'' is not +part of an \grammarterm{abstract-declarator}, +``\tcode{...}'' +is synonymous with +``\tcode{, ...}''. +A \grammarterm{parameter-declaration-clause} +of the form +\grammarterm{parameter-declaration-list} \tcode{...} +is deprecated\iref{depr.ellipsis.comma}. +\begin{example} +The declaration +\begin{codeblock} +int printf(const char*, ...); +\end{codeblock} +declares a function that can be called with varying numbers and types of arguments. + +\begin{codeblock} +printf("hello world"); +printf("a=%d b=%d", a, b); +\end{codeblock} + +However, the first argument must be of a type +that can be converted to a +\keyword{const} +\tcode{char*}. +\end{example} +\begin{note} +The standard header \libheaderref{cstdarg} +contains a mechanism for accessing arguments passed using the ellipsis +(see~\ref{expr.call} and~\ref{support.runtime}). +\end{note} + +\pnum +\indextext{type!function}% +The type of a function is determined using the following rules. +The type of each parameter (including function parameter packs) is +determined from its own \grammarterm{parameter-declaration}\iref{dcl.decl}. +After determining the type of each parameter, any parameter +\indextext{array!parameter of type}% +of type ``array of \tcode{T}'' or +\indextext{function!parameter of type}% +of function type \tcode{T} +is adjusted to be ``pointer to \tcode{T}''. +After producing the list of parameter types, +any top-level +\grammarterm{cv-qualifier}{s} +modifying a parameter type are deleted +when forming the function type. +The resulting list of transformed parameter types +and the presence or absence of the ellipsis or a function parameter pack +is the function's +\defn{parameter-type-list}. +\begin{note} +This transformation does not affect the types of the parameters. +For example, \tcode{int(*)(const int p, decltype(p)*)} and +\tcode{int(*)(int, const int*)} are identical types. +\end{note} +\begin{example} +\begin{codeblock} +void f(char*); // \#1 +void f(char[]) {} // defines \#1 +void f(const char*) {} // OK, another overload +void f(char *const) {} // error: redefines \#1 + +void g(char(*)[2]); // \#2 +void g(char[3][2]) {} // defines \#2 +void g(char[3][3]) {} // OK, another overload + +void h(int x(const int)); // \#3 +void h(int (*)(int)) {} // defines \#3 +\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. +An explicit-object-parameter-declaration shall appear only as +the first \grammarterm{parameter-declaration} of +a \grammarterm{parameter-declaration-list} of one of: +\begin{itemize} +\item +a declaration of +a member function or member function template\iref{class.mem}, or +\item +an explicit instantiation\iref{temp.explicit} or +explicit specialization\iref{temp.expl.spec} of +a templated member function, or +\item +a \grammarterm{lambda-declarator}\iref{expr.prim.lambda}. +\end{itemize} +A \grammarterm{member-declarator} with an explicit-object-parameter-declaration +shall not include +a \grammarterm{ref-qualifier} or a \grammarterm{cv-qualifier-seq} and +shall not be declared \keyword{static} or \keyword{virtual}. +\begin{example} +\begin{codeblock} +struct C { + void f(this C& self); + template void g(this Self&& self, int); + + void h(this C) const; // error: \tcode{const} not allowed here +}; + +void test(C c) { + c.f(); // OK, calls \tcode{C::f} + c.g(42); // OK, calls \tcode{C::g} + std::move(c).g(42); // OK, calls \tcode{C::g} } \end{codeblock} -\exitexample +\end{example} + +\pnum +A function parameter declared with an explicit-object-parameter-declaration +is an \defnadj{explicit object}{parameter}. +An explicit object parameter shall not be +a function parameter pack\iref{temp.variadic}. +An \defnadj{explicit object}{member function} is a non-static member function +with an explicit object parameter. +An \defnadj{implicit object}{member function} is a non-static member function +without an explicit object parameter. + +\pnum +The \defnadj{object}{parameter} of a non-static member function is either +the explicit object parameter or +the implicit object parameter\iref{over.match.funcs}. + +\pnum +A \defnadj{non-object}{parameter} is a function parameter +that is not the explicit object parameter. +The \defn{non-object-parameter-type-list} of a member function is +the parameter-type-list of that function with the explicit object parameter, +if any, omitted. +\begin{note} +The non-object-parameter-type-list consists of +the adjusted types of all the non-object parameters. +\end{note} + +\pnum +A function type with a \grammarterm{cv-qualifier-seq} or a +\grammarterm{ref-qualifier} (including a type denoted by +\grammarterm{typedef-name}\iref{dcl.typedef,temp.param}) +shall appear only as: +\begin{itemize} +\item the function type for a non-static member function, + +\item the function type to which a pointer to member refers, + +\item the top-level function type of a function typedef declaration +or \grammarterm{alias-declaration}, + +\item the \grammarterm{type-id} in the default argument of a +\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}, 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 +struct S { + FIC f; // OK +}; +FIC S::*pm = &S::f; // OK +constexpr std::meta::info yeti = ^^void(int) const &; // OK +\end{codeblock} +\end{example} + +\pnum +The effect of a +\grammarterm{cv-qualifier-seq} +in a function declarator is not the same as +adding cv-qualification on top of the function type. +In the latter case, the cv-qualifiers are ignored. +\begin{note} +A function type that has a \grammarterm{cv-qualifier-seq} is not a +cv-qualified type; there are no cv-qualified function types. +\end{note} +\begin{example} +\begin{codeblock} +typedef void F(); +struct S { + const F f; // OK, equivalent to: \tcode{void f();} +}; +\end{codeblock} +\end{example} + +\pnum +The return type, the parameter-type-list, the \grammarterm{ref-qualifier}, +the \grammarterm{cv-qualifier-seq}, and +the exception specification, +but not the default arguments\iref{dcl.fct.default} +or the trailing \grammarterm{requires-clause}\iref{dcl.decl}, +are part of the function type. +\begin{note} +Function types are checked during the assignments and initializations of +pointers to functions, references to functions, and pointers to member functions. +\end{note} + +\pnum +\begin{example} +The declaration +\begin{codeblock} +int fseek(FILE*, long, int); +\end{codeblock} +declares a function taking three arguments of the specified types, +and returning +\tcode{int}\iref{dcl.type}. +\end{example} + +\pnum +\indextext{overloading}% +\begin{note} +A single name can be used for several different functions in a single scope; +this is function overloading\iref{over}. +\end{note} + +\pnum +\indextext{function return type|see{return type}}% +\indextext{return type}% +The return type shall be a non-array object type, a reference type, or \cv{}~\keyword{void}. +\begin{note} +An array of placeholder type is considered an array type. +\end{note} \pnum -\enternote -Partial specializations of class templates are found by looking up the -primary class template and then considering all partial specializations -of that template. If a \grammarterm{using-declaration} names a class -template, partial specializations introduced after the -\grammarterm{using-declaration} are effectively visible because the primary -template is visible~(\ref{temp.class.spec}). -\exitnote +A volatile-qualified return type is deprecated; +see~\ref{depr.volatile.type}. \pnum -Since a \grammarterm{using-declaration} is a declaration, the restrictions -on declarations of the same name in the same declarative -region~(\ref{basic.scope}) also apply to \grammarterm{using-declaration}{s}. -\enterexample +Types shall not be defined in return or parameter types. +\pnum +\indextext{typedef!function}% +A typedef of function type may be used to declare a function but shall not be +used to define a function\iref{dcl.fct.def}. +\begin{example} \begin{codeblock} -namespace A { - int x; -} +typedef void F(); +F fv; // OK, equivalent to \tcode{void fv();} +F fv { } // error +void fv() { } // OK, definition of \tcode{fv} +\end{codeblock} +\end{example} -namespace B { - int i; - struct g { }; - struct x { }; - void f(int); - void f(double); - void g(char); // OK: hides \tcode{struct g} -} +\pnum +An identifier can optionally be provided as a parameter name; +if present in a function definition\iref{dcl.fct.def}, it names a parameter. +\begin{note} +In particular, parameter names are also optional in function definitions +and names used for a parameter in different declarations and the definition +of a function need not be the same. +\end{note} -void func() { - int i; - using B::i; // error: \tcode{i} declared twice - void f(char); - using B::f; // OK: each \tcode{f} is a function - f(3.5); // calls \tcode{B::f(double)} - using B::g; - g('a'); // calls \tcode{B::g(char)} - struct g g1; // \tcode{g1} has class type \tcode{B::g} - using B::x; - using A::x; // OK: hides \tcode{struct B::x} - x = 99; // assigns to \tcode{A::x} - struct x x1; // \tcode{x1} has class type \tcode{B::x} -} -\end{codeblock} -\exitexample - -\pnum -If a function declaration in namespace scope or block scope has the same -name and the same parameter-type-list~(\ref{dcl.fct}) as -a function introduced by a \grammarterm{using-declaration}, and the -declarations do not declare the same function, the program is -ill-formed. If a function template declaration in namespace scope has -the same name, parameter-type-list, return type, and template -parameter list as a function template introduced by a -\grammarterm{using-declaration}, the program is ill-formed. -\enternote -Two \grammarterm{using-declaration}{s} may introduce functions with the same -name and the same parameter-type-list. If, for a call to an unqualified -function name, function overload resolution selects the functions -introduced by such \grammarterm{using-declaration}{s}, the function call is -ill-formed. -\enterexample +\pnum +\begin{example} +The declaration +\begin{codeblock} +int i, + *pi, + f(), + *fpi(int), + (*pif)(const char*, const char*), + (*fpif(int))(int); +\end{codeblock} +declares an integer +\tcode{i}, +a pointer +\tcode{pi} +to an integer, +a function +\tcode{f} +taking no arguments and returning an integer, +a function +\tcode{fpi} +taking an integer argument and returning a pointer to an integer, +a pointer +\tcode{pif} +to a function which +takes two pointers to constant characters and returns an integer, +a function +\tcode{fpif} +taking an integer argument and returning a pointer to a function that takes an integer argument and returns an integer. +It is especially useful to compare +\tcode{fpi} +and +\tcode{pif}. +The binding of +\tcode{*fpi(int)} +is +\tcode{*(fpi(int))}, +so the declaration suggests, +and the same construction in an expression +requires, the calling of a function +\tcode{fpi}, +and then using indirection through the (pointer) result +to yield an integer. +In the declarator +\tcode{(*pif)(const char*, const char*)}, +the extra parentheses are necessary to indicate that indirection through +a pointer to a function yields a function, which is then called. +\end{example} +\begin{note} +Typedefs and \grammarterm{trailing-return-type}{s} are sometimes convenient when the return type of a function is complex. +For example, +the function +\tcode{fpif} +above can be declared +\begin{codeblock} +typedef int IFUNC(int); +IFUNC* fpif(int); +\end{codeblock} +or +\begin{codeblock} +auto fpif(int)->int(*)(int); +\end{codeblock} +A \grammarterm{trailing-return-type} is most useful for a type that would be more complicated to specify before the \grammarterm{declarator-id}: \begin{codeblock} -namespace B { - void f(int); - void f(double); +template auto add(T t, U u) -> decltype(t + u); +\end{codeblock} +rather than +\begin{codeblock} +template decltype((*(T*)0) + (*(U*)0)) add(T t, U u); +\end{codeblock} +\end{note} + +\pnum +A \defnadj{non-template}{function} is a function that is not a function template +specialization. +\begin{note} +A function template is not a function. +\end{note} + +\pnum +\indextext{abbreviated!template function|see{template, function, abbreviated}}% +An \defnx{abbreviated function template}{template!function!abbreviated} +is a function declaration that has +one or more generic parameter type placeholders\iref{dcl.spec.auto}. +An abbreviated function template is equivalent to +a function template\iref{temp.fct} +whose \grammarterm{template-parameter-list} includes +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}, +the invented parameter is +an unconstrained \grammarterm{type-parameter}. +For a \grammarterm{placeholder-type-specifier} of the form +\grammarterm{type-constraint} \keyword{auto}, +the invented parameter is a \grammarterm{type-parameter} with +that \grammarterm{type-constraint}. +The invented \grammarterm{type-parameter} declares +a template parameter pack +if the corresponding \grammarterm{parameter-declaration} +declares a function parameter pack. +If the placeholder contains \tcode{decltype(auto)}, +the program is ill-formed. +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{type-parameter}. +\begin{example} +\begin{codeblock} +template concept C1 = /* ... */; +template concept C2 = /* ... */; +template concept C3 = /* ... */; + +void g1(const C1 auto*, C2 auto&); +void g2(C1 auto&...); +void g3(C3 auto...); +void g4(C3 auto); +\end{codeblock} +The declarations above are functionally equivalent (but not equivalent) to +their respective declarations below: +\begin{codeblock} +template void g1(const T*, U&); +template void g2(Ts&...); +template void g3(Ts...); +template void g4(T); +\end{codeblock} +Abbreviated function templates can be specialized like all function templates. +\begin{codeblock} +template<> void g1(const int*, const double&); // OK, specialization of \tcode{g1} +\end{codeblock} +\end{example} + +\pnum +An abbreviated function template can have a \grammarterm{template-head}. +The invented \grammarterm{type-parameter}{s} are +appended to the \grammarterm{template-parameter-list} after +the explicitly declared \grammarterm{template-parameter}{s}. +\begin{example} +\begin{codeblock} +template concept C = /* ... */; + +template + void g(T x, U y, C auto z); +\end{codeblock} + +This is functionally equivalent to each of the following two declarations. +\begin{codeblock} +template + void g(T x, U y, W z); + +template + requires C && C + void g(T x, U y, W z); +\end{codeblock} +\end{example} + +\pnum +A function declaration at block scope +shall not declare an abbreviated function template. + +\pnum +A \grammarterm{declarator-id} or \grammarterm{abstract-declarator} +containing an ellipsis shall only +be used in a \grammarterm{parameter-declaration}. +When it is part of a +\grammarterm{parameter-declaration-clause}, +the \grammarterm{parameter-declaration} declares a +function parameter pack\iref{temp.variadic}. +Otherwise, the \grammarterm{parameter-declaration} is part of a +\grammarterm{template-parameter-list} and declares a +template parameter pack; see~\ref{temp.param}. +A function parameter pack is a pack expansion\iref{temp.variadic}. +\begin{example} +\begin{codeblock} +template void f(T (* ...t)(int, int)); + +int add(int, int); +float subtract(int, int); + +void g() { + f(add, subtract); } -namespace C { - void f(int); - void f(double); - void f(char); +\end{codeblock} +\end{example} + +\pnum +There is a syntactic ambiguity when an ellipsis occurs at the end +of a \grammarterm{parameter-declaration-clause} without a preceding +comma. In this case, the ellipsis is parsed as part of the +\grammarterm{abstract-declarator} if the type of the parameter either names +a template parameter pack that has not been expanded or contains \keyword{auto}; +otherwise, it is +parsed as part of the \grammarterm{parameter-declaration-clause}. +\begin{footnote} +One can explicitly disambiguate the parse either by +introducing a comma (so the ellipsis will be parsed as part of the +\grammarterm{parameter-declaration-clause}) or by introducing a name for the +parameter (so the ellipsis will be parsed as part of the +\grammarterm{declarator-id}). +\end{footnote} +\indextext{declarator!function|)} + +\rSec3[dcl.fct.default]{Default arguments}% +\indextext{declaration!default argument|(} + +\pnum +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}. +\end{note} + +\pnum +\indextext{argument!example of default}% +\begin{example} +The declaration +\begin{codeblock} +void point(int = 3, int = 4); +\end{codeblock} +declares a function that can be called with zero, one, or two arguments of type +\tcode{int}. +It can be called in any of these ways: +\begin{codeblock} +point(1,2); point(1); point(); +\end{codeblock} + +The last two calls are equivalent to +\tcode{point(1,4)} +and +\tcode{point(3,4)}, +respectively. +\end{example} + +\pnum +A default argument shall be specified only in the +\grammarterm{parameter-declaration-clause} +of a function declaration +or \grammarterm{lambda-declarator}. +A default argument shall not be specified for +a function parameter pack. +A default argument shall not occur within a +\grammarterm{declarator} +or +\grammarterm{abstract-declarator} +of a +\grammarterm{parameter-declaration}. +\begin{footnote} +This means that default +arguments cannot appear, +for example, in declarations of pointers to functions, +references to functions, or +\tcode{typedef} +declarations. +\end{footnote} + +\pnum +For non-template functions, default arguments can be added in later +declarations of a +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. +In +a given function declaration, each parameter subsequent to a +parameter with a default argument shall have a default argument +supplied in this or a previous declaration, +unless the parameter was expanded from a parameter pack, +or shall be a function parameter pack. +\begin{note} +A default argument +cannot be redefined by a later declaration +(not even to the same value)\iref{basic.def.odr}. +\end{note} +\begin{example} +\begin{codeblock} +void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow + // a parameter with a default argument +void f(int, int); +void f(int, int = 7); +void h() { + f(3); // OK, calls \tcode{f(3, 7)} + void f(int = 1, int); // error: does not use default from surrounding scope +} +void m() { + void f(int, int); // has no defaults + f(4); // error: wrong number of arguments + void f(int, int = 5); // OK + f(4); // OK, calls \tcode{f(4, 5);} + void f(int, int = 5); // error: cannot redefine, even to same value } +void n() { + f(6); // OK, calls \tcode{f(6, 7)} +} +template struct C { + void f(int n = 0, T...); +}; +C c; // OK, instantiates declaration \tcode{void C::f(int n = 0, int)} +\end{codeblock} +\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. +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 +which is reachable from $D$ or from which $D$ is reachable. + +\pnum +\indextext{argument!type checking of default}% +\indextext{argument!binding of default}% +\indextext{argument!evaluation of default}% +The default argument has the +same semantic constraints as the initializer in a +declaration of a variable of the parameter type, using the +copy-initialization semantics\iref{dcl.init}. +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.imm} that +is a potentially-evaluated subexpression\iref{intro.execution} of +the \grammarterm{initializer-clause} in a \grammarterm{parameter-declaration} is +neither evaluated +nor checked for whether it is a constant expression at that point. +Name lookup and checking of semantic constraints for default +arguments of templated functions are performed as described in~\ref{temp.inst}. +\begin{example} +In the following code, +\indextext{argument!example of default}% +\tcode{g} +will be called with the value +\tcode{f(2)}: + +\begin{codeblock} +int a = 1; +int f(int); +int g(int x = f(a)); // default argument: \tcode{f(::a)} void h() { - using B::f; // \tcode{B::f(int)} and \tcode{B::f(double)} - using C::f; // \tcode{C::f(int)}, \tcode{C::f(double)}, and \tcode{C::f(char)} - f('h'); // calls \tcode{C::f(char)} - f(1); // error: ambiguous: \tcode{B::f(int)} or \tcode{C::f(int)}? - void f(int); // error: \tcode{f(int)} conflicts with \tcode{C::f(int)} and \tcode{B::f(int)} + a = 2; + { + int a = 3; + g(); // \tcode{g(f(::a))} + } } \end{codeblock} -\exitexample -\exitnote +\end{example} +\begin{note} +A default argument is a complete-class context\iref{class.mem}. +Access checking applies to names in default arguments as +described in \ref{class.access}. +\end{note} + +\pnum +Except for member functions of templated classes, the +default arguments in a member function definition that appears +outside of the class definition +are added to the set of default arguments provided by the +member function declaration in the class definition; +the program is ill-formed if a default constructor\iref{class.default.ctor}, +copy or move constructor\iref{class.copy.ctor}, or +copy or move assignment operator\iref{class.copy.assign} +is so declared. +Default arguments for a member function of a templated class +shall be specified on the initial declaration of the member +function within the templated class. +\begin{example} +\begin{codeblock} +class C { + void f(int i = 3); + void g(int i, int j = 99); +}; + +void C::f(int i = 3) {} // error: default argument already specified in class scope +void C::g(int i = 88, int j) {} // in this translation unit, \tcode{C::g} can be called with no arguments +\end{codeblock} +\end{example} \pnum -\indextext{name hiding!using-declaration and}% -When a \grammarterm{using-declaration} brings names from a base class into -a derived class scope, member functions and member function templates in -the derived class override and/or hide member functions and member -function templates with the same name, -parameter-type-list~(\ref{dcl.fct}), cv-qualification, and \grammarterm{ref-qualifier} (if any) in a base -class (rather than conflicting). -\enternote For \grammarterm{using-declaration}{s} that name a constructor, see~\ref{class.inhctor}. \exitnote -\enterexample +\begin{note} +A local variable cannot be odr-used\iref{term.odr.use} +in a default argument. +\end{note} +\begin{example} +\begin{codeblock} +void f() { + int i; + extern void g(int x = i); // error + extern void h(int x = sizeof(i)); // OK + // ... +} +\end{codeblock} +\end{example} +\pnum +\begin{note} +The keyword +\keyword{this} +cannot appear in a default argument of a member function; +see~\ref{expr.prim.this}. +\begin{example} \begin{codeblock} -struct B { - virtual void f(int); - virtual void f(char); - void g(int); - void h(int); +class A { + void f(A* p = this) { } // error }; +\end{codeblock} +\end{example} +\end{note} + +\pnum +\indextext{argument!evaluation of default}% +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 +in a default argument. +\indextext{argument and name hiding!default}% +\begin{note} +Parameters of a function declared before a default argument +are in scope and can hide namespace and class member names. +\end{note} +\begin{example} +\begin{codeblock} +int a; +int f(int a, int b = a); // error: parameter \tcode{a} used as default argument +typedef int I; +int g(float I, int b = I(2)); // error: parameter \tcode{I} found +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 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()} +in the following example is ill-formed because no object is supplied for the +non-static member +\tcode{X::a} +used as an initializer. +\begin{codeblock} +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} + 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} +The declaration of +\tcode{X::mem2()} +is meaningful, however, since no object is needed to access the static member +\tcode{X::b}. +Classes, objects, and members are described in \ref{class}. +\end{example} +A default argument is not part of the +type of a function. +\begin{example} +\begin{codeblock} +int f(int = 0); -struct D : B { - using B::f; - void f(int); // OK: \tcode{D::f(int)} overrides \tcode{B::f(int)}; - - using B::g; - void g(char); // OK +void h() { + int j = f(1); + int k = f(); // OK, means \tcode{f(0)} +} - using B::h; - void h(int); // OK: \tcode{D::h(int)} hides \tcode{B::h(int)} +int (*p1)(int) = &f; +int (*p2)() = &f; // error: type mismatch +\end{codeblock} +\end{example} +\begin{note} +When an overload set contains a declaration of a function +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. +\end{note} + +\pnum +\indextext{argument and virtual function!default}% +A virtual function call\iref{class.virtual} uses the default +arguments in the declaration of the virtual function determined +by the static type of the pointer or reference denoting the +object. +An overriding function in a derived class does not +acquire default arguments from the function it overrides. +\begin{example} +\begin{codeblock} +struct A { + virtual void f(int a = 7); }; +struct B : public A { + void f(int a); +}; +void m() { + B* pb = new B; + A* pa = pb; + pa->f(); // OK, calls \tcode{pa->B::f(7)} + pb->f(); // error: wrong number of arguments for \tcode{B::f()} +} +\end{codeblock} +\end{example} +\indextext{declaration!default argument|)}% +\indextext{declarator!meaning of|)} + +\rSec1[dcl.contract]{Function contract specifiers} +\rSec2[dcl.contract.func]{General} + +\indextext{contract assertion!function|(}% + +\begin{bnf} +\nontermdef{function-contract-specifier-seq}\br + function-contract-specifier \opt{function-contract-specifier-seq} +\end{bnf} + +\begin{bnf} +\nontermdef{function-contract-specifier}\br + precondition-specifier\br + postcondition-specifier +\end{bnf} + +\begin{bnf} +\nontermdef{precondition-specifier}\br + \terminal{pre} \opt{attribute-specifier-seq} \terminal{(} conditional-expression \terminal{)} +\end{bnf} + +\begin{bnf} +\nontermdef{postcondition-specifier}\br + \terminal{post} \opt{attribute-specifier-seq} \terminal{(} \opt{result-name-introducer} conditional-expression \terminal{)} +\end{bnf} + +\pnum +\indexdefn{contract assertion!postcondition|see{assertion, postcondition}} +\indexdefn{contract assertion!precondition|see{assertion, precondition}} +A \defnadj{function}{contract assertion} +is a contract assertion\iref{basic.contract.general} +associated with a function. +A \grammarterm{precondition-specifier} +introduces a \defnadj{precondition}{assertion}, +which is a function contract assertion +associated with entering a function. +A \grammarterm{postcondition-specifier} +introduces a \defnadj{postcondition}{assertion}, +which is a function contract assertion +associated with exiting a function normally. +\begin{note} +A postcondition assertion +is not associated with exiting a function +in any other fashion, +such as via an exception\iref{expr.throw} +or via a call to \tcode{longjmp}\iref{csetjmp.syn}. +\end{note} + +\pnum +The predicate\iref{basic.contract.general} +of a function contract assertion +is its \grammarterm{conditional-expression} +contextually converted to \tcode{bool}. + +\pnum +Each \grammarterm{function-contract-specifier} +of a \grammarterm{function-contract-specifier-seq} (if any) +of an unspecified first declaration\iref{basic.def} +of a function +introduces a corresponding function contract assertion for that function. +The optional \grammarterm{attribute-specifier-seq} +following \tcode{pre} or \tcode{post} +appertains to the introduced contract assertion. +\begin{note} +The \grammarterm{function-contract-specifier-seq} +of a \grammarterm{lambda-declarator} +applies to the function call operator or operator template +of the corresponding closure type\iref{expr.prim.lambda.closure}. +\end{note} + +\pnum +A declaration $D$ +of a function or function template \placeholder{f} +that is not a first declaration shall have either +no \grammarterm{function-contract-specifier-seq} +or the same \grammarterm{function-contract-specifier-seq} (see below) +as any first declaration $F$ reachable from $D$. +If $D$ and $F$ are +in different translation units, +a diagnostic is required only if $D$ is attached to a named module. +If a declaration $F_1$ is a +first declaration of \tcode{f} +in one translation unit and +a declaration $F_2$ is a +first declaration of \tcode{f} in another translation unit, +$F_1$ and $F_2$ shall specify the same +\grammarterm{function-contract-specifier-seq}, no diagnostic required. + +\pnum +A \grammarterm{function-contract-specifier-seq} $S_1$ +is the same as +a \grammarterm{function-contract-specifier-seq} $S_2$ +if $S_1$ and $S_2$ consist of +the same \grammarterm{function-contract-specifier}s +in the same order. +A \grammarterm{function-contract-specifier} $C_1$ +on a function declaration $D_1$ is +the same as +a \grammarterm{function-contract-specifier} $C_2$ +on a function declaration $D_2$ +if +\begin{itemize} +\item +their predicates $P_1$ and $P_2$ would +satisfy the one-definition rule\iref{basic.def.odr} +if placed in function definitions on +the declarations $D_1$ and $D_2$, respectively, except for +\begin{itemize} +\item +renaming of the parameters of \placeholder{f}, +\item +renaming of template parameters of +a template enclosing \placeholder{}, and +\item +renaming of the result binding\iref{dcl.contract.res}, if any, +\end{itemize} +and, +if $D_1$ and $D_2$ are in different translation units, +corresponding entities defined within each predicate +behave as if there is a single entity with a single definition, and +\item +both $C_1$ and $C_2$ +specify a \grammarterm{result-name-introducer} +or neither do. +\end{itemize} +If this condition is not met +solely due to the comparison of two \grammarterm{lambda-expression}s +that are contained within $P_1$ and $P_2$, +no diagnostic is required. + +\begin{note} +Equivalent +\grammarterm{function-contract-specifier-seq}s +apply to all uses and definitions +of a function across all translation units. +\end{note} +\begin{example} +\begin{codeblock} + +bool b1, b2; + +void f() pre (b1) pre ([]{ return b2; }()); +void f(); // OK, \grammarterm{function-contract-specifier}s omitted +void f() pre (b1) pre ([]{ return b2; }()); // error: closures have different types. +void f() pre (b1); // error: \grammarterm{function-contract-specifier}s only partially repeated + +int g() post(r : b1); +int g() post(b1); // error: mismatched \grammarterm{result-name-introducer} presence + +namespace N { + void h() pre (b1); + bool b1; + void h() pre (b1); // error: \grammarterm{function-contract-specifier}s differ according to + // the one-definition rule\iref{basic.def.odr}. +} +\end{codeblock} +\end{example} + +\pnum +A virtual function\iref{class.virtual}, +a deleted function\iref{dcl.fct.def.delete}, +or a function defaulted on its first declaration\iref{dcl.fct.def.default} +shall not have a \grammarterm{function-contract-specifier-seq}. + +\pnum +If the predicate of a postcondition assertion +of a function \placeholder{f} +odr-uses\iref{basic.def.odr} +a non-reference parameter of \placeholder{f}, +that parameter +and the corresponding parameter on all declarations of \placeholder{f} +shall have \keyword{const} type. +\begin{note} +This requirement applies +even to declarations that do not specify the \grammarterm{postcondition-specifier}. +Parameters with array or function type +will decay to non-\keyword{const} types +even if a \keyword{const} qualifier is present. +\begin{example} +\begin{codeblock} +int f(const int i[10]) + post(r : r == i[0]); // error: \tcode{i} has type \tcode{const int *} (not \tcode{int* const}). +\end{codeblock} +\end{example} +\end{note} + +\pnum +\begin{note} +The function contract assertions of a function +are evaluated even when invoked indirectly, +such as through a pointer to function or a pointer to member function. +A pointer to function, +pointer to member function, +or function type alias +cannot have a \grammarterm{function-contract-specifier-seq} +associated directly with it. +\end{note} + +\pnum +The function contract assertions of a function +are considered to be \defnx{needed}{needed!function contract assertion}\iref{temp.inst} when +\begin{itemize} +\item +the function is odr-used\iref{basic.def.odr} or +\item +the function is defined. +\end{itemize} +\begin{note} +Overload resolution does not consider +\grammarterm{function-contract-specifier}s\iref{temp.deduct,temp.inst}. +\begin{example} +\begin{codeblock} +template void f(T t) pre( t == "" ); +template void f(T&& t); +void g() +{ + f(5); // error: ambiguous +} +\end{codeblock} +\end{example} +\end{note} + + +\rSec2[dcl.contract.res]{Referring to the result object} + +\begin{bnf} +\nontermdef{attributed-identifier}\br + identifier \opt{attribute-specifier-seq} +\end{bnf} + +\begin{bnf} +\nontermdef{result-name-introducer}\br + attributed-identifier \terminal{:} +\end{bnf} + +\pnum +The \grammarterm{result-name-introducer} +of a \grammarterm{postcondition-specifier} +is a declaration. +The \grammarterm{result-name-introducer} +introduces the \grammarterm{identifier} +as the name of a \defn{result binding} +of the associated function. +If a postcondition assertion has a \grammarterm{result-name-introducer} +and the return type of the function is \cv{} \keyword{void}, +the program is ill-formed. +A result binding denotes +the object or reference returned by +invocation of that function. +The type of a result binding +is the return type of its associated function. +The optional \grammarterm{attribute-specifier-seq} +of the \grammarterm{attributed-identifier} +in the \grammarterm{result-name-introducer} +appertains to the result binding so introduced. +\begin{note} +An \grammarterm{id-expression} +that names a result binding is a \keyword{const} lvalue\iref{expr.prim.id.unqual}. +\end{note} + +\begin{example} +\begin{codeblock} +int f() + post(r : r == 1) +{ + return 1; +} +int i = f(); // Postcondition check succeeds. +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +struct A {}; +struct B { + B() {} + B(const B&) {} +}; + +template +T f(T* const ptr) + post(r: &r == ptr) +{ + return {}; +} + +int main() { + A a = f(&a); // The postcondition check can fail if the implementation introduces + // a temporary for the return value\iref{class.temporary}. + B b = f(&b); // The postcondition check succeeds, no temporary is introduced. +} +\end{codeblock} +\end{example} + + +\pnum +When the declared return type +of a non-templated function +contains a placeholder type, +a \grammarterm{postcondition-specifier} +with a \grammarterm{result-name-introducer} +shall be present only on a definition. +\begin{example} +\begin{codeblock} +auto g(auto&) + post (r: r >= 0); // OK, \tcode{g} is a template. + +auto h() + post (r: r >= 0); // error: cannot name the return value + +auto k() + post (r: r >= 0) // OK +{ + return 0; +} +\end{codeblock} +\end{example} + +\indextext{contract assertion!function|)}% + +\rSec1[dcl.init]{Initializers}% + +\rSec2[dcl.init.general]{General}% +\indextext{initialization|(} + +\pnum +The process of initialization described in \ref{dcl.init} applies to +all initializations regardless of syntactic context, including the +initialization of a function parameter\iref{expr.call}, the +initialization of a return value\iref{stmt.return}, or when an +initializer follows a declarator. + +\begin{bnf} +\nontermdef{initializer}\br + brace-or-equal-initializer\br + \terminal{(} expression-list \terminal{)} +\end{bnf} + +\begin{bnf} +\nontermdef{brace-or-equal-initializer}\br + \terminal{=} initializer-clause\br + braced-init-list +\end{bnf} + +\begin{bnf} +\nontermdef{initializer-clause}\br + assignment-expression\br + braced-init-list +\end{bnf} + +\begin{bnf} +\nontermdef{braced-init-list}\br + \terminal{\{} initializer-list \opt{\terminal{,}} \terminal{\}}\br + \terminal{\{} designated-initializer-list \opt{\terminal{,}} \terminal{\}}\br + \terminal{\{} \terminal{\}} +\end{bnf} + +\begin{bnf} +\nontermdef{initializer-list}\br + initializer-clause \opt{\terminal{...}}\br + initializer-list \terminal{,} initializer-clause \opt{\terminal{...}} +\end{bnf} + +\begin{bnf} +\nontermdef{designated-initializer-list}\br + designated-initializer-clause\br + designated-initializer-list \terminal{,} designated-initializer-clause +\end{bnf} + +\begin{bnf} +\nontermdef{designated-initializer-clause}\br + designator brace-or-equal-initializer +\end{bnf} + +\begin{bnf} +\nontermdef{designator}\br + \terminal{.} identifier +\end{bnf} + +\begin{bnf} +\nontermdef{expr-or-braced-init-list}\br + expression\br + braced-init-list +\end{bnf} + +\begin{note} +The rules in \ref{dcl.init} apply even if the grammar permits only +the \grammarterm{brace-or-equal-initializer} form +of \grammarterm{initializer} in a given context. +\end{note} + +\pnum +Except for objects declared with the \keyword{constexpr} specifier, for which see~\ref{dcl.constexpr}, +an \grammarterm{initializer} in the definition of a variable can consist of +arbitrary expressions involving literals and previously declared +variables and functions, +regardless of the variable's storage duration. +\begin{example} +\begin{codeblock} +int f(int); +int a = 2; +int b = f(a); +int c(b); +\end{codeblock} +\end{example} + +\pnum +\begin{note} +Default arguments are more restricted; see~\ref{dcl.fct.default}. +\end{note} + +\pnum +\begin{note} +The order of initialization of variables with static storage duration is described in~\ref{basic.start} +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: +\begin{itemize} +\item +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 +\tcode{0} +to a pointer type results in a null pointer value. +\end{footnote} + +\item +if +\tcode{T} +is a (possibly cv-qualified) non-union class type, +its padding bits\iref{term.padding.bits} are initialized to zero bits and +each non-static data member, +each non-virtual base class subobject, and, +if the object is not a base class subobject, +each virtual base class subobject +is zero-initialized; + +\item +if +\tcode{T} +is a (possibly cv-qualified) union type, +its padding bits\iref{term.padding.bits} are initialized to zero bits and +the +object's first non-static named +data member +is zero-initialized; + +\item +if +\tcode{T} +is an array type, +each element is zero-initialized; +\item +if +\tcode{T} +is a reference type, no initialization is performed. +\end{itemize} + +\pnum +To +\defnx{default-initialize}{default-initialization} +an object of type +\tcode{T} +means: + +\begin{itemize} +\item +If +\tcode{T} +is a (possibly cv-qualified) class type\iref{class}, +constructors are considered. The applicable constructors are +enumerated\iref{over.match.ctor}, and the best one for the +\grammarterm{initializer} \tcode{()} is chosen through +overload resolution\iref{over.match}. The constructor thus selected +is called, with an empty argument list, to initialize the object. + +\item +If +\tcode{T} +is an array type, +the semantic constraints of default-initializing a hypothetical element +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 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); +\item +\tcode{T} is a class type where +\begin{itemize} +\item +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, +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 +\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 type. + +\pnum +To +\defnx{value-initialize}{value-initialization} +an object of type +\tcode{T} +means: + +\begin{itemize} +\item +If +\tcode{T} +is a (possibly cv-qualified) class type\iref{class}, then +let \tcode{C} be the constructor selected to +default-initialize the object, if any. +If \tcode{C} is not user-provided, the object is first zero-initialized. +In all cases, the object is then default-initialized. + +\item +If +\tcode{T} +is an array type, +the semantic constraints of value-initializing a hypothetical element +shall be met and +each element is value-initialized. + +\item +Otherwise, the object is zero-initialized. +\end{itemize} + +\pnum +A program that calls for default-initialization +or value-initialization +of an entity +of reference type is ill-formed. + +\pnum +\begin{note} +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. +\end{note} + +\pnum +If no initializer is specified for an object, the object is default-initialized. + +\pnum +If the entity being initialized does not have class or array type, the +\grammarterm{expression-list} in a +parenthesized initializer shall be a single expression. + +\pnum +\indextext{initialization!copy}% +\indextext{initialization!direct}% +The initialization that occurs in the \tcode{=} form of a +\grammarterm{brace-or-equal-initializer} or +\grammarterm{condition}\iref{stmt.select}, +as well as in argument passing, function return, +throwing an exception\iref{except.throw}, +handling an exception\iref{except.handle}, +and aggregate member initialization other than by a +\grammarterm{designated-initializer-clause}\iref{dcl.init.aggr}, +is called +\defn{copy-initialization}. +\begin{note} +Copy-initialization can invoke a move\iref{class.copy.ctor}. +\end{note} + +\pnum +The initialization that occurs +\begin{itemize} +\item for an \grammarterm{initializer} that is a +parenthesized \grammarterm{expression-list} or a \grammarterm{braced-init-list}, +\item for a \grammarterm{new-initializer}\iref{expr.new}, +\item in a \keyword{static_cast} expression\iref{expr.static.cast}, +\item in a functional notation type conversion\iref{expr.type.conv}, and +\item in the \grammarterm{braced-init-list} form of a \grammarterm{condition} +\end{itemize} +is called +\defn{direct-initialization}. + +\pnum +The semantics of initializers are as follows. +The +\indextext{type!destination}% +\term{destination type} +is the cv-unqualified type of the object or reference being initialized and the +\term{source type} +is the type of the initializer expression. +If the initializer is not a single (possibly parenthesized) expression, the +source type is not defined. +\begin{itemize} +\item +If the initializer is a (non-parenthesized) \grammarterm{braced-init-list} +or is \tcode{=} \grammarterm{braced-init-list}, the object or reference +is list-initialized\iref{dcl.init.list}. +\item +If the destination type is a reference type, see~\ref{dcl.init.ref}. +\item +If the destination type is an array of characters, +an array of \keyword{char8_t}, +an array of \keyword{char16_t}, +an array of \keyword{char32_t}, +or an array of +\keyword{wchar_t}, +and the initializer is a \grammarterm{string-literal}, see~\ref{dcl.init.string}. +\item If the initializer is \tcode{()}, the object is value-initialized. +\indextext{ambiguity!function declaration}% +\begin{note} +Since +\tcode{()} +is not permitted by the syntax for +\grammarterm{initializer}, +\begin{codeblock} +X a(); +\end{codeblock} +is not the declaration of an object of class +\tcode{X}, +but the declaration of a function taking no arguments and returning an +\tcode{X}. +The form +\tcode{()} +can appear in certain other initialization contexts\iref{expr.new, +expr.type.conv,class.base.init}. +\end{note} + +\item +Otherwise, if the destination type is an array, +the object is initialized as follows. +The \grammarterm{initializer} shall be of the form +\tcode{(} \grammarterm{expression-list} \tcode{)}. +Let $x_1$, $\dotsc$, $x_k$ be +the elements of the \grammarterm{expression-list}. +If the destination type is an array of unknown bound, +it is defined as having $k$ elements. +Let $n$ denote the array size after this potential adjustment. +If $k$ is greater than $n$, +the program is ill-formed. +Otherwise, the $i^\text{th}$ array element is copy-initialized with +$x_i$ for each $1 \leq i \leq k$, and +value-initialized for each $k < i \leq n$. +For each $1 \leq i < j \leq n$, +every value computation and side effect associated with +the initialization of the $i^\text{th}$ element of the array +is sequenced before those associated with +the initialization of the $j^\text{th}$ element. +\item +Otherwise, if the destination type is a class type: + +\begin{itemize} +\item +If the initializer expression is a prvalue +and the cv-unqualified version of the source type +is the same 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}\iref{basic.lval,expr.type.conv}. +\end{example} +\item +Otherwise, if the initialization is direct-initialization, +or if it is copy-initialization where the cv-unqualified version of the source +type is the same as or is derived from the class of the destination type, +constructors are considered. +The applicable constructors +are enumerated\iref{over.match.ctor}, and the best one is chosen +through overload resolution\iref{over.match}. Then: +\begin{itemize} +\item +If overload resolution is successful, +the selected constructor +is called to initialize the object, with the initializer +expression or \grammarterm{expression-list} as its argument(s). +\item +Otherwise, if no constructor is viable, +the destination type is +an aggregate class, and +the initializer is a parenthesized \grammarterm{expression-list}, +the object is initialized as follows. +Let $e_1$, $\dotsc$, $e_n$ be the elements of the aggregate\iref{dcl.init.aggr}. +Let $x_1$, $\dotsc$, $x_k$ be the elements of the \grammarterm{expression-list}. +If $k$ is greater than $n$, the program is ill-formed. +The element $e_i$ is copy-initialized with +$x_i$ for $1 \leq i \leq k$. +The remaining elements are initialized with +their default member initializers, if any, and +otherwise are value-initialized. +For each $1 \leq i < j \leq n$, +every value computation and side effect +associated with the initialization of $e_i$ +is sequenced before those associated with the initialization of $e_j$. +\begin{note} +By contrast with direct-list-initialization, +narrowing conversions\iref{dcl.init.list} can appear, +designators are not permitted, +a temporary object bound to a reference +does not have its lifetime extended\iref{class.temporary}, and +there is no brace elision. +\begin{example} +\begin{codeblock} +struct A { + int a; + int&& r; +}; + +int f(); +int n = 10; + +A a1{1, f()}; // OK, lifetime is extended +A a2(1, f()); // well-formed, but dangling reference +A a3{1.0, 1}; // error: narrowing conversion +A a4(1.0, 1); // well-formed, but dangling reference +A a5(1.0, std::move(n)); // OK +\end{codeblock} +\end{example} +\end{note} +\item +Otherwise, the initialization is ill-formed. +\end{itemize} + +\item +Otherwise (i.e., for the remaining copy-initialization cases), +user-defined conversions that can convert from the +source type to the destination type or (when a conversion function +is used) to a derived class thereof are enumerated as described in~\ref{over.match.copy}, +and the best one is chosen through overload resolution\iref{over.match}. +If the conversion cannot be done or +is ambiguous, the initialization is ill-formed. The function +selected is called with the initializer expression as its +argument; if the function is a constructor, the call is a prvalue +of the cv-unqualified version of the +destination type whose result object is initialized by the constructor. +The call is used +to direct-initialize, according to the rules above, the object +that is the destination of the copy-initialization. +\end{itemize} + +\item +Otherwise, if the source type +is a (possibly cv-qualified) class type, conversion functions are +considered. +The applicable conversion functions are enumerated\iref{over.match.conv}, +and the best one is chosen through overload +resolution\iref{over.match}. +The user-defined conversion so selected +is called to convert the initializer expression into the +object being initialized. +If the conversion cannot be done or is +ambiguous, the initialization is ill-formed. +\item +Otherwise, if the initialization is direct-initialization, +the source type is \tcode{std::nullptr_t}, and +the destination type is \tcode{bool}, +the initial value of the object being initialized is \tcode{false}. +\item +Otherwise, the initial value of the object being initialized is +the (possibly converted) value of the initializer expression. +A standard conversion sequence\iref{conv} is used +to convert the initializer expression to +a prvalue of +the destination type; +no user-defined conversions are considered. +If the conversion cannot +be done, the initialization is ill-formed. +When initializing a bit-field with a value that it cannot represent, the +resulting value of the bit-field is +\impldefplain{value of bit-field that cannot represent!initializer}. +\indextext{initialization!\idxcode{const}}% +\begin{note} +An expression of type +``\cvqual{cv1} \tcode{T}'' +can initialize an object of type +``\cvqual{cv2} \tcode{T}'' +independently of +the cv-qualifiers +\cvqual{cv1} +and \cvqual{cv2}. + +\begin{codeblock} +int a; +const int b = a; +int c = b; +\end{codeblock} +\end{note} +\end{itemize} + +\pnum +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 +the enclosing \grammarterm{initializer} is used in +a function call, a constructor definition, or an aggregate initialization. + +\pnum +An \grammarterm{initializer-clause} followed by an ellipsis is a +pack expansion\iref{temp.variadic}. + +\pnum +Initialization includes +the evaluation of all subexpressions of +each \grammarterm{initializer-clause} of +the initializer (possibly nested within \grammarterm{braced-init-list}{s}) and +the creation of any temporary objects for +function arguments or return values\iref{class.temporary}. + +\pnum +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}. + +\pnum +The same \grammarterm{identifier} +shall not appear in multiple \grammarterm{designator}{s} of a +\grammarterm{designated-initializer-list}. + +\pnum +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. +\begin{note} +Such an object might have been value-initialized +or initialized by aggregate initialization\iref{dcl.init.aggr} +or by an inherited constructor\iref{class.inhctor.init}. +\end{note} +Destroying an object of class type invokes the destructor of the class. +Destroying a scalar type has no effect other than +ending the lifetime of the object\iref{basic.life}. +Destroying an array destroys each element in reverse subscript order. + +\pnum +A declaration that specifies the initialization of a variable, +whether from an explicit initializer or by default-initialization, +is called the \defn{initializing declaration} of that variable. +\begin{note} +In most cases +this is the defining declaration\iref{basic.def} of the variable, +but the initializing declaration +of a non-inline static data member\iref{class.static.data} +can be the declaration within the class definition +and not the definition (if any) outside it. +\end{note} + +\rSec2[dcl.init.aggr]{Aggregates}% +\indextext{aggregate}% +\indextext{initialization!aggregate}% +\indextext{aggregate initialization}% +\indextext{initialization!array}% +\indextext{initialization!class object}% +\indextext{class object initialization|see{constructor}}% +\indextext{\idxcode{\{\}}!initializer list} + +\pnum +An \defn{aggregate} is an array or a class\iref{class} with +\begin{itemize} +\item +no user-declared or inherited constructors\iref{class.ctor}, +\item +no private or protected direct non-static data members\iref{class.access}, +\item +no private or protected direct base classes\iref{class.access.base}, and +\item +no virtual functions\iref{class.virtual} or virtual base classes\iref{class.mi}. +\end{itemize} +\begin{note} +Aggregate initialization does not allow accessing +protected and private base class' members, including constructors. +\end{note} + +\pnum +The \defnx{elements}{aggregate!elements} of an aggregate are: +\begin{itemize} +\item +for an array, the array elements in increasing subscript order, or +\item +for a class, the direct base classes in declaration order, +followed by the direct non-static data members\iref{class.mem} +that are not members of an anonymous union, in declaration order. +\end{itemize} + +\pnum +When an aggregate is initialized by an initializer list +as specified in~\ref{dcl.init.list}, +the elements of the initializer list are taken as initializers +for the elements of the aggregate. +The \defnx{explicitly initialized elements}{explicitly initialized elements!aggregate} +of the aggregate are determined as follows: +\begin{itemize} +\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. +\item +If the initializer list is a brace-enclosed \grammarterm{initializer-list}, +the explicitly initialized elements of the aggregate +are 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. +\end{itemize} + +\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}, +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. +There shall be only one such \grammarterm{designated-initializer-clause}. +\begin{example} +\begin{codeblock} +struct C { + union { + int a; + const char* p; + }; + int x; +} c = { .a = 1, .x = 3 }; +\end{codeblock} +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}, +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 +\tcode{= }\grammarterm{assignment-expression} +and +a narrowing conversion\iref{dcl.init.list} is required +to convert the expression, the program is ill-formed. +\begin{note} +The form of the initializer determines +whether copy-initialization or direct-initialization is performed. +\end{note} +\item +Otherwise, +the initializer list is a brace-enclosed \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, +the aggregate element is copy-initialized +from a brace-enclosed \grammarterm{initializer-list} +consisting of all of the \grammarterm{initializer-clause}s +that appertain to subobjects of the aggregate element, +in the order of appearance. +\begin{note} +If an initializer is itself an initializer list, +the element is list-initialized, which will result in a recursive application +of the rules in this subclause if the element is an aggregate. +\end{note} +\begin{example} +\begin{codeblock} +struct A { + int x; + struct B { + int i; + int j; + } b; +} a = { 1, { 2, 3 } }; +\end{codeblock} +initializes +\tcode{a.x} +with 1, +\tcode{a.b.i} +with 2, +\tcode{a.b.j} +with 3. + +\begin{codeblock} +struct base1 { int b1, b2 = 42; }; +struct base2 { + base2() { + b3 = 42; + } + int b3; +}; +struct derived : base1, base2 { + int d; +}; + +derived d1{{1, 2}, {}, 4}; +derived d2{{}, {}, 4}; +\end{codeblock} +initializes +\tcode{d1.b1} with 1, +\tcode{d1.b2} with 2, +\tcode{d1.b3} with 42, +\tcode{d1.d} with 4, and +\tcode{d2.b1} with 0, +\tcode{d2.b2} with 42, +\tcode{d2.b3} with 42, +\tcode{d2.d} with 4. +\end{example} +\end{itemize} + +\pnum +For a non-union aggregate, +each element that is not an explicitly initialized element +is initialized as follows: +\begin{itemize} +\item +If the element has a default member initializer\iref{class.mem}, +the element is initialized from that initializer. +\item +Otherwise, if the element is not a reference, the element +is copy-initialized from an empty initializer list\iref{dcl.init.list}. +\item +Otherwise, the program is ill-formed. +\end{itemize} +If the aggregate is a union and the initializer list is empty, then +\begin{itemize} +\item +if any variant member has a default member initializer, +that member is initialized from its default member initializer; +\item +otherwise, the first member of the union (if any) +is copy-initialized from an empty initializer list. +\end{itemize} + +\pnum +\begin{example} +\begin{codeblock} +struct S { int a; const char* b; int c; int d = b[a]; }; +S ss = { 1, "asdf" }; +\end{codeblock} +initializes +\tcode{ss.a} +with 1, +\tcode{ss.b} +with \tcode{"asdf"}, +\tcode{ss.c} +with the value of an expression of the form +\tcode{int\{\}} +(that is, \tcode{0}), and \tcode{ss.d} with the value of \tcode{ss.b[ss.a]} +(that is, \tcode{'s'}). + +\begin{codeblock} +struct A { + string a; + int b = 42; + int c = -1; +}; +\end{codeblock} + +\tcode{A\{.c=21\}} has the following steps: +\begin{itemize} +\item Initialize \tcode{a} with \tcode{\{\}} +\item Initialize \tcode{b} with \tcode{= 42} +\item Initialize \tcode{c} with \tcode{= 21} +\end{itemize} +\end{example} + +\pnum +The initializations of the elements of the aggregate +are evaluated in the element order. +That is, +all value computations and side effects associated with a given element +are sequenced before +those of any element that follows it in order. + +\pnum +An aggregate that is a class can also be initialized with a single +expression not enclosed in braces, as described in~\ref{dcl.init}. + +\pnum +The destructor for each element of class type +other than an anonymous union member +is potentially invoked\iref{class.dtor} +from the context where the aggregate initialization occurs. +\begin{note} +This provision ensures that destructors can be called +for fully-constructed subobjects +in case an exception is thrown\iref{except.ctor}. +\end{note} + +\pnum +The number of elements\iref{dcl.array} in an array of unknown bound +initialized with a brace-enclosed \grammarterm{initializer-list} +is the number of explicitly initialized elements of the array. +\begin{example} +\begin{codeblock} +int x[] = { 1, 3, 5 }; +\end{codeblock} +declares and initializes +\tcode{x} +as a one-dimensional array that has three elements +since no size was specified and there are three initializers. +\end{example} +\begin{example} +In +\begin{codeblock} +struct X { int i, j, k; }; +X a[] = { 1, 2, 3, 4, 5, 6 }; +X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } }; +\end{codeblock} +\tcode{a} and \tcode{b} have the same value. +\end{example} +An array of unknown bound shall not be initialized with +an empty \grammarterm{braced-init-list} \tcode{\{\}}. +\begin{footnote} +The syntax provides for empty \grammarterm{braced-init-list}{s}, +but nonetheless \Cpp{} does not have zero length arrays. +\end{footnote} +\begin{note} +A default member initializer does not determine the bound for a member +array of unknown bound. Since the default member initializer is +ignored if a suitable \grammarterm{mem-initializer} is present\iref{class.base.init}, +the default member initializer is not +considered to initialize the array of unknown bound. +\begin{example} +\begin{codeblock} +struct S { + int y[] = { 0 }; // error: non-static data member of incomplete type +}; +\end{codeblock} +\end{example} +\end{note} + +\pnum +\begin{note} +Static data members, +non-static data members of anonymous union members, +and +unnamed bit-fields +are not considered elements of the aggregate. +\begin{example} +\begin{codeblock} +struct A { + int i; + static int s; + int j; + int :17; + int k; +} a = { 1, 2, 3 }; +\end{codeblock} + +Here, the second initializer 2 initializes +\tcode{a.j} +and not the static data member +\tcode{A::s}, and the third initializer 3 initializes \tcode{a.k} +and not the unnamed bit-field before it. +\end{example} +\end{note} + +\pnum +If a member has a default member initializer +and a potentially-evaluated subexpression thereof is an aggregate +initialization that would use that default member initializer, +the program is ill-formed. +\begin{example} +\begin{codeblock} +struct A; +extern A a; +struct A { + const A& a1 { A{a,a} }; // OK + const A& a2 { A{} }; // error +}; +A a{a,a}; // OK + +struct B { + int n = B{}.n; // error +}; +\end{codeblock} +\end{example} + +\pnum +When initializing a multidimensional array, +the +\grammarterm{initializer-clause}{s} +initialize the elements with the last (rightmost) index of the array +varying the fastest\iref{dcl.array}. +\begin{example} +\begin{codeblock} +int x[2][2] = { 3, 1, 4, 2 }; +\end{codeblock} +initializes +\tcode{x[0][0]} +to +\tcode{3}, +\tcode{x[0][1]} +to +\tcode{1}, +\tcode{x[1][0]} +to +\tcode{4}, +and +\tcode{x[1][1]} +to +\tcode{2}. +On the other hand, +\begin{codeblock} +float y[4][3] = { + { 1 }, { 2 }, { 3 }, { 4 } +}; +\end{codeblock} +initializes the first column of +\tcode{y} +(regarded as a two-dimensional array) +and leaves the rest zero. +\end{example} + +\pnum +Each \grammarterm{initializer-clause} in +a brace-enclosed \grammarterm{initializer-list} +is said to \defn{appertain} +to an element of the aggregate being initialized or +to an element of one of its subaggregates. +Considering the sequence of \grammarterm{initializer-clause}s, +and the sequence of aggregate elements +initially formed as the sequence of elements of the aggregate being initialized +and potentially modified as described below, +each \grammarterm{initializer-clause} appertains to +the corresponding aggregate element if +\begin{itemize} +\item +the aggregate element is not an aggregate, or +\item +the \grammarterm{initializer-clause} begins with a left brace, or +\item +the \grammarterm{initializer-clause} is an expression and +an implicit conversion sequence can be formed +that converts the expression to the type of the aggregate element, or +\item +the aggregate element is an aggregate that itself has no aggregate elements. +\end{itemize} +Otherwise, +the aggregate element is an aggregate and +that subaggregate is replaced in the list of aggregate elements by +the sequence of its own aggregate elements, and +the appertainment analysis resumes with +the first such element and the same \grammarterm{initializer-clause}. +\begin{note} +These rules apply recursively to the aggregate's subaggregates. +\begin{example} +In +\begin{codeblock} +struct S1 { int a, b; }; +struct S2 { S1 s, t; }; + +S2 x[2] = { 1, 2, 3, 4, 5, 6, 7, 8 }; +S2 y[2] = { + { + { 1, 2 }, + { 3, 4 } + }, + { + { 5, 6 }, + { 7, 8 } + } +}; +\end{codeblock} +\tcode{x} and \tcode{y} have the same value. +\end{example} +\end{note} +This process continues +until all \grammarterm{initializer-clause}s have been exhausted. +If any \grammarterm{initializer-clause} remains +that does not appertain to +an element of the aggregate or one of its subaggregates, +the program is ill-formed. +\begin{example} +\begin{codeblock} +char cv[4] = { 'a', 's', 'd', 'f', 0 }; // error: too many initializers +\end{codeblock} +\end{example} + +\pnum +\begin{example} +\begin{codeblock} +float y[4][3] = { + { 1, 3, 5 }, + { 2, 4, 6 }, + { 3, 5, 7 }, +}; +\end{codeblock} +is a completely-braced initialization: +1, 3, and 5 initialize the first row of the array +\tcode{y[0]}, +namely +\tcode{y[0][0]}, +\tcode{y[0][1]}, +and +\tcode{y[0][2]}. +Likewise the next two lines initialize +\tcode{y[1]} +and +\tcode{y[2]}. +The initializer ends early and therefore +\tcode{y[3]}'s +elements are initialized as if explicitly initialized with an +expression of the form +\tcode{float()}, +that is, are initialized with +\tcode{0.0}. +In the following example, braces in the +\grammarterm{initializer-list} +are elided; +however the +\grammarterm{initializer-list} +has the same effect as the completely-braced +\grammarterm{initializer-list} +of the above example, +\begin{codeblock} +float y[4][3] = { + 1, 3, 5, 2, 4, 6, 3, 5, 7 +}; +\end{codeblock} + +The initializer for +\tcode{y} +begins with a left brace, but the one for +\tcode{y[0]} +does not, +therefore three elements from the list are used. +Likewise the next three are taken successively for +\tcode{y[1]} +and +\tcode{y[2]}. +\end{example} + +\pnum +\begin{note} +The initializer for an empty subaggregate is needed +if any initializers are provided for subsequent elements. +\begin{example} +\begin{codeblock} +struct S { } s; +struct A { + S s1; + int i1; + S s2; + int i2; + S s3; + int i3; +} a = { + { }, // Required initialization + 0, + s, // Required initialization + 0 +}; // Initialization not required for \tcode{A::s3} because \tcode{A::i3} is also not initialized +\end{codeblock} +\end{example} +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +struct A { + int i; + operator int(); +}; +struct B { + A a1, a2; + int z; +}; +A a; +B b = { 4, a, a }; +\end{codeblock} +Braces are elided around the +\grammarterm{initializer-clause} +for +\tcode{b.a1.i}. +\tcode{b.a1.i} +is initialized with 4, +\tcode{b.a2} +is initialized with +\tcode{a}, +\tcode{b.z} +is initialized with whatever +\tcode{a.operator int()} +returns. +\end{example} + +\pnum +\indextext{initialization!array of class objects}% +\begin{note} +An aggregate array or an aggregate class can contain elements of a +class type with a user-declared constructor\iref{class.ctor}. +Initialization of these aggregate objects is described in~\ref{class.expl.init}. +\end{note} + +\pnum +\begin{note} +Whether the initialization of aggregates with static storage duration +is static or dynamic is specified +in~\ref{basic.start.static}, \ref{basic.start.dynamic}, and~\ref{stmt.dcl}. +\end{note} + +\pnum +\indextext{initialization!\idxcode{union}}% +When a union is initialized with an initializer list, +there shall not be more than one +explicitly initialized element. +\begin{example} +\begin{codeblock} +union u { int a; const char* b; }; +u a = { 1 }; +u b = a; +u c = 1; // error +u d = { 0, "asdf" }; // error +u e = { "asdf" }; // error +u f = { .b = "asdf" }; +u g = { .a = 1, .b = "asdf" }; // error +\end{codeblock} +\end{example} + +\pnum +\begin{note} +As described above, +the braces around the +\grammarterm{initializer-clause} +for a union member can be omitted if the +union is a member of another aggregate. +\end{note} + +\rSec2[dcl.init.string]{Character arrays}% +\indextext{initialization!character array} + +\pnum +\indextext{UTF-8}% +\indextext{UTF-16}% +\indextext{UTF-32}% +An array of ordinary character type\iref{basic.fundamental}, +\keyword{char8_t} array, +\keyword{char16_t} array, +\keyword{char32_t} array, +or \keyword{wchar_t} array +may be initialized by +an ordinary string literal, +UTF-8 string literal, +UTF-16 string literal, +UTF-32 string literal, or +wide string literal, +respectively, or by an appropriately-typed \grammarterm{string-literal} enclosed in +braces\iref{lex.string}. +Additionally, an array of \keyword{char} or +\tcode{\keyword{unsigned} \keyword{char}} +may be initialized by +a UTF-8 string literal, or by +such a string literal enclosed in braces. +\indextext{initialization!character array}% +Successive +characters of the +value of the \grammarterm{string-literal} +initialize the elements of the array, +with an integral conversion\iref{conv.integral} +if necessary for the source and destination value. +\begin{example} +\begin{codeblock} +char msg[] = "Syntax error on line %s\n"; +\end{codeblock} +shows a character array whose members are initialized +with a +\grammarterm{string-literal}. +Note that because +\tcode{'\textbackslash n'} +is a single character and +because a trailing +\tcode{'\textbackslash 0'} +is appended, +\tcode{sizeof(msg)} +is +\tcode{25}. +\end{example} + +\pnum +There shall not be more initializers than there are array elements. +\begin{example} +\begin{codeblock} +char cv[4] = "asdf"; // error +\end{codeblock} +is ill-formed since there is no space for the implied trailing +\tcode{'\textbackslash 0'}. +\end{example} + +\pnum +If there are fewer initializers than there are array elements, each element not +explicitly initialized shall be zero-initialized\iref{dcl.init}. + +\rSec2[dcl.init.ref]{References}% +\indextext{initialization!reference} + +\pnum +A variable whose declared type is +``reference to \tcode{T}''\iref{dcl.ref} +shall be initialized. +\begin{example} +\begin{codeblock} +int g(int) noexcept; +void f() { + int i; + int& r = i; // \tcode{r} refers to \tcode{i} + r = 1; // the value of \tcode{i} becomes \tcode{1} + int* p = &r; // \tcode{p} points to \tcode{i} + int& rr = r; // \tcode{rr} refers to what \tcode{r} refers to, that is, to \tcode{i} + int (&rg)(int) = g; // \tcode{rg} refers to the function \tcode{g} + rg(i); // calls function \tcode{g} + int a[3]; + int (&ra)[3] = a; // \tcode{ra} refers to the array \tcode{a} + ra[1] = i; // modifies \tcode{a[1]} +} +\end{codeblock} +\end{example} + +\pnum +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.assign}. +\end{note} +\indextext{argument passing!reference and}% +Argument passing\iref{expr.call} +\indextext{\idxcode{return}!reference and}% +and function value return\iref{stmt.return} are initializations. + +\pnum +The initializer can be omitted for a reference only in a parameter declaration\iref{dcl.fct}, +in the declaration of a function return type, in the declaration of +a class member within its class definition\iref{class.mem}, and where the +\keyword{extern} +specifier is explicitly used. +\indextext{declaration!extern@\tcode{extern} reference}% +\begin{example} +\begin{codeblock} +int& r1; // error: initializer missing +extern int& r2; // OK +\end{codeblock} +\end{example} + +\pnum +Given types ``\cvqual{cv1} \tcode{T1}'' and ``\cvqual{cv2} \tcode{T2}'', +``\cvqual{cv1} \tcode{T1}'' is \defn{reference-related} to +``\cvqual{cv2} \tcode{T2}'' if +\tcode{T1} is similar\iref{conv.qual} to \tcode{T2}, or +\tcode{T1} is a base class of \tcode{T2}. +``\cvqual{cv1} \tcode{T1}'' is \defn{reference-compatible} +with ``\cvqual{cv2} \tcode{T2}'' if +a prvalue of type ``pointer to \cvqual{cv2} \tcode{T2}'' can be converted to +the type ``pointer to \cvqual{cv1} \tcode{T1}'' +via a standard conversion sequence\iref{conv}. +In all cases where the reference-compatible relationship +of two types is used to establish the validity of a reference binding and +the standard conversion sequence would be ill-formed, +a program that necessitates such a binding is ill-formed. + +\pnum +A reference to type ``\cvqual{cv1} \tcode{T1}'' is initialized by +an expression of type ``\cvqual{cv2} \tcode{T2}'' as follows:% +\indextext{binding!reference} + +\begin{itemize} +\item +If the reference is an lvalue reference and the initializer expression +\begin{itemize} +\item +is an lvalue (but is not a +bit-field), and +``\cvqual{cv1} \tcode{T1}'' is reference-compatible with +``\cvqual{cv2} \tcode{T2}'', or +\item +has a class type (i.e., +\tcode{T2} +is a class type), where \tcode{T1} is not reference-related to \tcode{T2}, and can be converted +to an lvalue of type ``\cvqual{cv3} \tcode{T3}'', where +``\cvqual{cv1} \tcode{T1}'' is reference-compatible with +``\cvqual{cv3} \tcode{T3}'' +\begin{footnote} +This requires a conversion +function\iref{class.conv.fct} returning a reference type. +\end{footnote} +(this conversion is selected by enumerating the applicable conversion +functions\iref{over.match.ref} and choosing the best one through overload +resolution\iref{over.match}), +\end{itemize} +then the reference binds to the initializer expression lvalue in the +first case and to the lvalue result of the conversion +in the second case (or, in either case, to the appropriate base class subobject of the object). +\begin{note} +The usual lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, +and function-to-pointer\iref{conv.func} standard +conversions are not needed, and therefore are suppressed, when such +direct bindings to lvalues are done. +\end{note} + +\begin{example} +\begin{codeblock} +double d = 2.0; +double& rd = d; // \tcode{rd} refers to \tcode{d} +const double& rcd = d; // \tcode{rcd} refers to \tcode{d} + +struct A { }; +struct B : A { operator int&(); } b; +A& ra = b; // \tcode{ra} refers to \tcode{A} subobject in \tcode{b} +const A& rca = b; // \tcode{rca} refers to \tcode{A} subobject in \tcode{b} +int& ir = B(); // \tcode{ir} refers to the result of \tcode{B::operator int\&} +\end{codeblock} +\end{example} + +\item +Otherwise, +if the reference is an lvalue reference to a +type that is not const-qualified or is volatile-qualified, +the program is ill-formed. +\begin{example} +\begin{codeblock} +double& rd2 = 2.0; // error: not an lvalue and reference not \keyword{const} +int i = 2; +double& rd3 = i; // error: type mismatch and reference not \keyword{const} +\end{codeblock} +\end{example} + +\item Otherwise, if the initializer expression +\begin{itemize} +\item is an rvalue (but not a bit-field) or an lvalue of function type and +``\cvqual{cv1} \tcode{T1}'' is +reference-compatible with ``\cvqual{cv2} \tcode{T2}'', or + +\item has a class type (i.e., \tcode{T2} is a class type), where \tcode{T1} +is not reference-related to \tcode{T2}, and can be converted to +an rvalue of type ``\cvqual{cv3} \tcode{T3}'' or +an lvalue of function type ``\cvqual{cv3} \tcode{T3}'', +where ``\cvqual{cv1} \tcode{T1}'' is +reference-compatible with ``\cvqual{cv3} \tcode{T3}'' (see~\ref{over.match.ref}), +\end{itemize} +then +the initializer expression in the first case and +the converted expression in the second case +is called the converted initializer. +If the converted initializer is a prvalue, +let its type be denoted by \tcode{T4}; +the temporary materialization conversion\iref{conv.rval} is applied, +considering the type of the prvalue to be +``\cvqual{cv1} \tcode{T4}''\iref{conv.qual}. +In any case, +the reference binds to the resulting glvalue +(or to an appropriate base class subobject). + +\begin{example} +\begin{codeblock} +struct A { }; +struct B : A { } b; +extern B f(); +const A& rca2 = f(); // binds to the \tcode{A} subobject of the \tcode{B} rvalue. +A&& rra = f(); // same as above +struct X { + operator B(); + operator int&(); +} x; +const A& r = x; // binds to the \tcode{A} subobject of the result of the conversion +int i2 = 42; +int&& rri = static_cast(i2); // binds directly to \tcode{i2} +B&& rrb = x; // binds directly to the result of \tcode{operator B} + +constexpr int f() { + const int &x = 42; + const_cast(x) = 1; // undefined behavior + return x; +} +constexpr int z = f(); // error: not a constant expression + +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} + +\item +Otherwise, \tcode{T1} shall not be reference-related to \tcode{T2}. +\begin{itemize} +\item +If \tcode{T1} or \tcode{T2} is a class type, +user-defined conversions are considered +using the rules for copy-initialization of an object of type +``\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 $E$ of the call to the +conversion function, as described for the non-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, +the initializer expression is implicitly converted to a prvalue +of type ``\tcode{T1}''. +The temporary materialization conversion is applied, +considering the type of the prvalue to be ``\cvqual{cv1} \tcode{T1}'', +and the reference is bound to the result. +\end{itemize} + +\begin{example} +\begin{codeblock} +struct Banana { }; +struct Enigma { operator const Banana(); }; +struct Alaska { operator Banana&(); }; +void enigmatic() { + typedef const Banana ConstBanana; + Banana &&banana1 = ConstBanana(); // error + Banana &&banana2 = Enigma(); // error + Banana &&banana3 = Alaska(); // error +} + +const double& rcd2 = 2; // \tcode{rcd2} refers to temporary with type \tcode{const double} and value \tcode{2.0} +double&& rrd = 2; // \tcode{rrd} refers to temporary with value \tcode{2.0} +const volatile int cvi = 1; +const int& r2 = cvi; // error: cv-qualifier dropped +struct A { operator volatile int&(); } a; +const int& r3 = a; // error: cv-qualifier dropped + // from result of conversion function +double d2 = 1.0; +double&& rrd2 = d2; // error: initializer is lvalue of reference-related type +struct X { operator int&(); }; +int&& rri2 = X(); // error: result of conversion function is + // lvalue of reference-related type +int i3 = 2; +double&& rrd3 = i3; // \tcode{rrd3} refers to temporary with value \tcode{2.0} +\end{codeblock} +\end{example} +\end{itemize} + +In all cases except the last +(i.e., implicitly converting the initializer expression +to the referenced type), +the reference is said to \defn{bind directly} to the +initializer expression. + +\pnum +\begin{note} +\ref{class.temporary} describes the lifetime of temporaries bound to references. +\end{note} + +\rSec2[dcl.init.list]{List-initialization}% +\indextext{initialization!list-initialization|(} + +\pnum +\defnx{List-initialization}{list-initialization} is initialization of an object or reference from a +\grammarterm{braced-init-list}. +Such an initializer is called an \term{initializer list}, and +the comma-separated +\grammarterm{initializer-clause}{s} +of the \grammarterm{initializer-list} +or +\grammarterm{designated-initializer-clause}{s} +of the \grammarterm{designated-initializer-list} +are called the \term{elements} of the initializer list. An initializer list may be empty. +List-initialization can occur in direct-initialization or copy-initialization contexts; +list-initialization in a direct-initialization context is called +\defn{direct-list-initialization} and list-initialization in a +copy-initialization context is called \defn{copy-list-initialization}. +Direct-initialization that is not list-initialization is called +\defn{direct-non-list-initialization}. +\begin{note} +List-initialization can be used +\begin{itemize} +\item as the initializer in a variable definition\iref{dcl.init}, +\item as the initializer in a \grammarterm{new-expression}\iref{expr.new}, +\item in a \tcode{return} statement\iref{stmt.return}, +\item as a \grammarterm{for-range-initializer}\iref{stmt.iter}, +\item as a function argument\iref{expr.call}, +\item as a template argument\iref{temp.arg.nontype}, +\item as a subscript\iref{expr.sub}, +\item as an argument to a constructor invocation\iref{dcl.init,expr.type.conv}, +\item as an initializer for a non-static data member\iref{class.mem}, +\item in a \grammarterm{mem-initializer}\iref{class.base.init}, or +\item on the right-hand side of an assignment\iref{expr.assign}. +\end{itemize} + +\begin{example} +\begin{codeblock} +int a = {1}; +std::complex z{1,2}; +new std::vector{"once", "upon", "a", "time"}; // 4 string elements +f( {"Nicholas","Annemarie"} ); // pass list of two elements +return { "Norah" }; // return list of one element +int* e {}; // initialization to zero / null pointer +x = double{1}; // explicitly construct a \tcode{double} +std::map anim = { {"bear",4}, {"cassowary",2}, {"tiger",7} }; +\end{codeblock} +\end{example} +\end{note} + +\pnum +A constructor is an \defn{initializer-list constructor} if its first parameter is +of type \tcode{std::initializer_list} or reference to +\cv{}~\tcode{std::initializer_list} for some type \tcode{E}, and either there are no other +parameters or else all other parameters have default arguments\iref{dcl.fct.default}. +\begin{note} +Initializer-list constructors are favored over other constructors in +list-initialization\iref{over.match.list}. Passing an initializer list as the argument +to the constructor template \tcode{template C(T)} of a class \tcode{C} does not +create an initializer-list constructor, because an initializer list argument causes the +corresponding parameter to be a non-deduced context\iref{temp.deduct.call}. +\end{note} +The template +\tcode{std::initializer_list} is not predefined; +if a standard library declaration\iref{initializer.list.syn,std.modules} +of \tcode{std::initializer_list} is not reachable from\iref{module.reach} +a use of \tcode{std::initializer_list} --- +even an implicit use in which the type is not named\iref{dcl.spec.auto} --- +the program is ill-formed. + +\pnum +List-initialization of an object or reference of type \cvqual{cv} \tcode{T} is defined as follows: +\begin{itemize} +\item +If the \grammarterm{braced-init-list} +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} +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}. +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} +\end{codeblock} +\end{example} + +\item If \tcode{T} is an aggregate class and the initializer list has a single element +of type \cvqual{cv1} \tcode{U}, +where \tcode{U} is \tcode{T} or a class derived from \tcode{T}, +the object is initialized from that element (by copy-initialization for +copy-list-initialization, or by direct-initialization for +direct-list-initialization). + +\item Otherwise, if \tcode{T} is a character array and the initializer list has a +single element that is an appropriately-typed \grammarterm{string-literal}\iref{dcl.init.string}, +initialization is performed as described in that subclause. + +\item Otherwise, if \tcode{T} is an aggregate, aggregate initialization is +performed\iref{dcl.init.aggr}. + +\begin{example} +\begin{codeblock} +double ad[] = { 1, 2.0 }; // OK +int ai[] = { 1, 2.0 }; // error: narrowing + +struct S2 { + int m1; + double m2, m3; +}; +S2 s21 = { 1, 2, 3.0 }; // OK +S2 s22 { 1.0, 2, 3 }; // error: narrowing +S2 s23 { }; // OK, default to 0,0,0 +\end{codeblock} +\end{example} + +\item Otherwise, if the initializer list has no elements and \tcode{T} is a class type with a +default constructor, the object is value-initialized. + +\item Otherwise, if \tcode{T} is a specialization of \tcode{std::initializer_list}, +the object is constructed as described below. + +\item Otherwise, if \tcode{T} is a class type, constructors are considered. +The applicable constructors are enumerated and +the best one is chosen through overload resolution\iref{over.match,over.match.list}. If a narrowing +conversion (see below) is required to convert any of the arguments, the program is +ill-formed. + +\begin{example} +\begin{codeblock} +struct S { + S(std::initializer_list); // \#1 + S(std::initializer_list); // \#2 + S(std::initializer_list); // \#3 + S(); // \#4 + // ... +}; +S s1 = { 1.0, 2.0, 3.0 }; // invoke \#1 +S s2 = { 1, 2, 3 }; // invoke \#2 +S s3{s2}; // invoke \#3 (not the copy constructor) +S s4 = { }; // invoke \#4 +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +struct Map { + Map(std::initializer_list>); +}; +Map ship = {{"Sophie",14}, {"Surprise",28}}; +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +struct S { + // no initializer-list constructors + S(int, double, double); // \#1 + S(); // \#2 + // ... +}; +S s1 = { 1, 2, 3.0 }; // OK, invoke \#1 +S s2 { 1.0, 2, 3 }; // error: narrowing +S s3 { }; // OK, invoke \#2 +\end{codeblock} +\end{example} + +\item Otherwise, if \tcode{T} is an enumeration +with a fixed underlying type\iref{dcl.enum} \tcode{U}, +the \grammarterm{initializer-list} has a single element \tcode{v} of scalar type, +\tcode{v} can be implicitly converted to \tcode{U}, and +the initialization is direct-list-initialization, +the object is initialized with the value \tcode{T(v)}\iref{expr.type.conv}; +if a narrowing conversion is required to convert \tcode{v} +to \tcode{U}, the program is ill-formed. +\begin{example} +\begin{codeblock} +enum byte : unsigned char { }; +byte b { 42 }; // OK +byte c = { 42 }; // error +byte d = byte{ 42 }; // OK; same value as \tcode{b} +byte e { -1 }; // error + +struct A { byte b; }; +A a1 = { { 42 } }; // error +A a2 = { byte{ 42 } }; // OK + +void f(byte); +f({ 42 }); // error + +enum class Handle : uint32_t { Invalid = 0 }; +Handle h { 42 }; // OK +\end{codeblock} +\end{example} + +\item Otherwise, if +the initializer list +is not a \grammarterm{designated-initializer-list} and +has a single element of type \tcode{E} and either +\tcode{T} is not a reference type or its referenced type is +reference-related to \tcode{E}, the object or reference is initialized +from that element (by copy-initialization for copy-list-initialization, +or by direct-initialization for direct-list-initialization); +if a narrowing conversion (see below) is required +to convert the element to \tcode{T}, the program is ill-formed. + +\begin{example} +\begin{codeblock} +int x1 {2}; // OK +int x2 {2.0}; // error: narrowing +\end{codeblock} +\end{example} + +\item Otherwise, if \tcode{T} is a reference type, a prvalue is generated. +The prvalue initializes its result object by copy-list-initialization from the initializer list. +The prvalue is then used to direct-initialize the reference. +The type of the prvalue is the type referenced by \tcode{T}, +unless \tcode{T} is ``reference to array of unknown bound of \tcode{U}'', +in which case the type of the prvalue is +the type of \tcode{x} in the declaration \tcode{U x[] $H$}, +where $H$ is the initializer list. +\begin{note} +As usual, the binding will fail and the program is ill-formed if +the reference type is an lvalue reference to a non-const type. +\end{note} + +\begin{example} +\begin{codeblock} +struct S { + S(std::initializer_list); // \#1 + S(const std::string&); // \#2 + // ... +}; +const S& r1 = { 1, 2, 3.0 }; // OK, invoke \#1 +const S& r2 { "Spinach" }; // OK, invoke \#2 +S& r3 = { 1, 2, 3 }; // error: initializer is not an lvalue +const int& i1 = { 1 }; // OK +const int& i2 = { 1.1 }; // error: narrowing +const int (&iar)[2] = { 1, 2 }; // OK, \tcode{iar} is bound to temporary array + +struct A { } a; +struct B { explicit B(const A&); }; +const B& b2{a}; // error: cannot copy-list-initialize \tcode{B} temporary from \tcode{A} + +struct C { int x; }; +C&& c = { .x = 1 }; // OK +\end{codeblock} +\end{example} + +\item Otherwise, if the initializer list has no elements, the object is +value-initialized. + +\begin{example} +\begin{codeblock} +int** pp {}; // initialized to null pointer +\end{codeblock} +\end{example} + +\item Otherwise, the program is ill-formed. + +\begin{example} +\begin{codeblock} +struct A { int i; int j; }; +A a1 { 1, 2 }; // aggregate initialization +A a2 { 1.2 }; // error: narrowing +struct B { + B(std::initializer_list); +}; +B b1 { 1, 2 }; // creates \tcode{initializer_list} and calls constructor +B b2 { 1, 2.0 }; // error: narrowing +struct C { + C(int i, double j); +}; +C c1 = { 1, 2.2 }; // calls constructor with arguments (1, 2.2) +C c2 = { 1.1, 2 }; // error: narrowing + +int j { 1 }; // initialize to 1 +int k { }; // initialize to 0 +\end{codeblock} +\end{example} + +\end{itemize} + +\pnum +Within the \grammarterm{initializer-list} of a \grammarterm{braced-init-list}, +the \grammarterm{initializer-clause}{s}, including any that result from pack +expansions\iref{temp.variadic}, are evaluated in the order in which they +appear. That is, every value computation and side effect associated with a +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}. +\begin{note} +This evaluation ordering holds regardless of the semantics of the +initialization; for example, it applies when the elements of the +\grammarterm{initializer-list} are interpreted as arguments of a constructor +call, even though ordinarily there are no sequencing constraints on the +arguments of a call. +\end{note} + +\pnum +An object of type \tcode{std::initializer_list} is constructed from +an initializer list as if +the implementation generated and materialized\iref{conv.rval} +a prvalue of type ``array of $N$ \tcode{const E}'', +where $N$ is the number of elements in the initializer list; +this is called the initializer list's \defnadj{backing}{array}. +Each element of the backing array is copy-initialized with the +corresponding element of the initializer list, and the +\tcode{std::initializer_list} object is constructed to refer to that array. +\begin{note} +A constructor or conversion function selected for the copy needs to be +accessible\iref{class.access} in the context of the initializer list. +\end{note} +If a narrowing conversion is required to initialize any of the elements, +the program is ill-formed. +\begin{note} +Backing arrays are potentially non-unique objects\iref{intro.object}. +\end{note} + +\pnum +The backing array has the same lifetime as any other temporary +object\iref{class.temporary}, except that initializing an +\tcode{initializer_list} object from the array extends the lifetime of +the array exactly like binding a reference to a temporary. +\begin{example} +\begin{codeblock} +void f(std::initializer_list il); +void g(float x) { + f({1, x, 3}); +} +void h() { + f({1, 2, 3}); +} + +struct A { + mutable int i; +}; +void q(std::initializer_list); +void r() { + q({A{1}, A{2}, A{3}}); +} +\end{codeblock} + +The initialization will be implemented in a way roughly equivalent to this: +\begin{codeblock} +void g(float x) { + const double __a[3] = {double{1}, double{x}, double{3}}; // backing array + f(std::initializer_list(__a, __a+3)); +} +void h() { + static constexpr double __b[3] = {double{1}, double{2}, double{3}}; // backing array + f(std::initializer_list(__b, __b+3)); +} +void r() { + const A __c[3] = {A{1}, A{2}, A{3}}; // backing array + q(std::initializer_list(__c, __c+3)); +} +\end{codeblock} +assuming that the implementation +can construct an \tcode{initializer_list} object with a pair of pointers, and +with the understanding that \tcode{__b} does not outlive the call to \tcode{f}. +\end{example} + +\begin{example} +\begin{codeblock} +typedef std::complex cmplx; +std::vector v1 = { 1, 2, 3 }; + +void f() { + std::vector v2{ 1, 2, 3 }; + std::initializer_list i3 = { 1, 2, 3 }; +} + +struct A { + std::initializer_list i4; + A() : i4{ 1, 2, 3 } {} // ill-formed, would create a dangling reference +}; +\end{codeblock} + +For \tcode{v1} and \tcode{v2}, the \tcode{initializer_list} object +is a parameter in a function call, so the array created for +\tcode{\{ 1, 2, 3 \}} has full-expression lifetime. +For \tcode{i3}, the \tcode{initializer_list} object is a variable, +so the array persists for the lifetime of the variable. +For \tcode{i4}, the \tcode{initializer_list} object is initialized in +the constructor's \grammarterm{ctor-initializer} as if by binding +a temporary array to a reference member, so the program is +ill-formed\iref{class.base.init}. +\end{example} + +\pnum +A \defnadj{narrowing}{conversion} is an implicit conversion +\begin{itemize} +\item from a floating-point type to an integer type, or + +\item from a floating-point type \tcode{T} to another floating-point type +whose floating-point conversion rank is neither greater than nor equal to +that of \tcode{T}, +except where the result of the conversion is a constant expression and +either its value is finite and the conversion did not overflow, or +the values before and after the conversion are not finite, or + +\item from an integer type or unscoped enumeration type to a floating-point type, except +where the source is a constant expression and the actual value after conversion will fit +into the target type and will produce the original value when converted back to the +original type, or + +\item from an integer type or unscoped enumeration type to an integer type that cannot +represent all the values of the original type, except where +\begin{itemize} +\item +the source is a bit-field whose width $w$ is less than that of its type +(or, for an enumeration type, its underlying type) and +the target type can represent all the values +of a hypothetical extended integer type +with width $w$ and with the same signedness as the original type or +\item +the source is a constant +expression whose value after integral promotions will fit into the target type, or +\end{itemize} + +\item from a pointer type or a pointer-to-member type to \tcode{bool}. +\end{itemize} + +\begin{note} +As indicated above, such conversions are not allowed at the top level in +list-initializations. +\end{note} +\begin{example} +\begin{codeblock} +int x = 999; // \tcode{x} is not a constant expression +const int y = 999; +const int z = 99; +char c1 = x; // OK, though it potentially narrows (in this case, it does narrow) +char c2{x}; // error: potentially narrows +char c3{y}; // error: narrows (assuming \tcode{char} is 8 bits) +char c4{z}; // OK, no narrowing needed +unsigned char uc1 = {5}; // OK, no narrowing needed +unsigned char uc2 = {-1}; // error: narrows +unsigned int ui1 = {-1}; // error: narrows +signed int si1 = + { (unsigned int)-1 }; // error: narrows +int ii = {2.0}; // error: narrows +float f1 { x }; // error: potentially narrows +float f2 { 7 }; // OK, 7 can be exactly represented as a \tcode{float} +bool b = {"meow"}; // error: narrows +int f(int); +int a[] = { 2, f(2), f(2.0) }; // OK, the \tcode{double}-to-\tcode{int} conversion is not at the top level +\end{codeblock} +\end{example} +\indextext{initialization!list-initialization|)}% +\indextext{initialization|)}% +\indextext{declarator|)} + +\rSec1[dcl.fct.def]{Function definitions}% +\indextext{definition!function|(} + +\rSec2[dcl.fct.def.general]{General} + +\pnum +\indextext{body!function}% +Function definitions have the form +\indextext{\idxgram{function-definition}}% +% +\begin{bnf} +\nontermdef{function-definition}\br + \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} +\nontermdef{function-body}\br + \opt{ctor-initializer} compound-statement\br + function-try-block\br + \terminal{=} \keyword{default} \terminal{;}\br + deleted-function-body +\end{bnf} + +\begin{bnf} +\nontermdef{deleted-function-body}\br + \terminal{=} \keyword{delete} \terminal{;}\br + \terminal{=} \keyword{delete} \terminal{(} unevaluated-string \terminal{)} \terminal{;} +\end{bnf} + +Any informal reference to the body of a function should be interpreted as a reference to +the non-terminal \grammarterm{function-body}, +including, for a constructor, +default member initializers or default initialization +used to initialize +a base or member subobject in the absence of +a \grammarterm{mem-initializer-id}\iref{class.base.init}. +The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{function-definition} +appertains to the function. +A \grammarterm{function-definition} with a \grammarterm{virt-specifier-seq} +shall be a \grammarterm{member-declaration}\iref{class.mem}. +A \grammarterm{function-definition} with a \grammarterm{requires-clause} +shall define a templated function. + +\pnum +In a \grammarterm{function-definition}, +either \keyword{void} \grammarterm{declarator} \tcode{;} +or \grammarterm{declarator} \tcode{;} +shall be a well-formed function declaration +as described in~\ref{dcl.fct}. +A function shall be defined only in namespace or class scope. +The type of a parameter or the return type for a function +definition shall not be +a (possibly cv-qualified) class type that is +incomplete or abstract within the function body +unless the function is deleted\iref{dcl.fct.def.delete}. + +\pnum +\begin{example} +A simple example of a complete function definition is +\begin{codeblock} +int max(int a, int b, int c) { + int m = (a > b) ? a : b; + return (m > c) ? m : c; +} +\end{codeblock} + +Here +\tcode{int} +is the +\grammarterm{decl-specifier-seq}; +\tcode{max(int} +\tcode{a,} +\tcode{int} +\tcode{b,} +\tcode{int} +\tcode{c)} +is the +\grammarterm{declarator}; +\tcode{\{ \commentellip{} \}} +is the +\grammarterm{function-body}. +\end{example} + +\pnum +\indextext{initializer!base class}% +\indextext{initializer!member}% +\indextext{definition!constructor}% +A +\grammarterm{ctor-initializer} +is used only in a constructor; see~\ref{class.ctor} and~\ref{class.init}. + +\pnum +\begin{note} +A \grammarterm{cv-qualifier-seq} affects the type of \keyword{this} +in the body of a member function; see~\ref{expr.prim.this}. +\end{note} + +\pnum +\begin{note} +Unused parameters need not be named. +For example, + +\begin{codeblock} +void print(int a, int) { + std::printf("a = %d\n",a); +} +\end{codeblock} +\end{note} + +\pnum +A \defnadj{function-local predefined}{variable} is a variable with static +storage duration that is implicitly defined in a function parameter scope. + +\pnum +\indextext{__func__@\mname{func}}% +The function-local predefined variable \mname{func} is +defined as if a definition of the form +\begin{codeblock} +static const char __func__[] = "@\placeholder{function-name}@"; +\end{codeblock} +had been provided, where \tcode{\placeholder{function-name}} is an \impldef{string resulting +from \mname{func}} string. +It is unspecified whether such a variable has an address +distinct from that of any other object in the program. +\begin{footnote} +Implementations are +permitted to provide additional predefined variables with names that are reserved to the +implementation\iref{lex.name}. If a predefined variable is not +odr-used\iref{term.odr.use}, its string value need not be present in the program image. +\end{footnote} +\begin{example} +\begin{codeblock} +struct S { + S() : s(__func__) { } // OK + const char* s; +}; +void f(const char* s = __func__); // error: \mname{func} is undeclared +\end{codeblock} +\end{example} + +\rSec2[dcl.fct.def.default]{Explicitly-defaulted functions}% + +\pnum +A function definition whose +\grammarterm{function-body} +is of the form +\tcode{= default ;} +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 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: +\begin{itemize} +\item + $\tcode{F}_1$ and $\tcode{F}_2$ may have differing \grammarterm{ref-qualifier}{s}; +\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}'', + 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} +\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; +\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. +\end{itemize} + +\pnum +A function explicitly defaulted on its first declaration +is implicitly inline\iref{dcl.inline}, +and is implicitly constexpr\iref{dcl.constexpr} +if it is constexpr-suitable. +\begin{note} +Other defaulted functions are not implicitly constexpr. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +struct S { + S(int a = 0) = default; // error: default argument + void operator=(const S&) = default; // error: non-matching return type + ~S() noexcept(false) = default; // OK, despite mismatched exception specification +private: + int i; + S(S&); // OK, private copy constructor +}; +S::S(S&) = default; // OK, defines copy constructor + +struct T { + T(); + T(T &&) noexcept(false); +}; +struct U { + T t; + U(); + U(U &&) noexcept = default; +}; +U u1; +U u2 = static_cast(u1); // OK, calls \tcode{std::terminate} if \tcode{T::T(T\&\&)} throws +\end{codeblock} +\end{example} + +\pnum +Explicitly-defaulted functions and implicitly-declared functions are collectively +called \defn{defaulted} functions, and the implementation +shall provide implicit definitions +for them\iref{class.ctor,class.dtor,class.copy.ctor,class.copy.assign} as described below, +including possibly defining them as deleted. +A defaulted prospective destructor\iref{class.dtor} +that is not a destructor is defined as deleted. +A defaulted special member function +that is neither a prospective destructor nor +an eligible special member function\iref{special} +is defined as deleted. +A function is +\defn{user-provided} if it is user-declared and not explicitly +defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function +(i.e., explicitly defaulted after its first declaration) +is implicitly defined at the point where it is explicitly defaulted; if such a function is implicitly +defined as deleted, the program is ill-formed. +\begin{note} +Declaring a function as defaulted after its first declaration +can provide efficient execution and concise definition +while enabling a stable binary interface to an evolving code base. +\end{note} +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.defns}. +\begin{note} +The implicit definition of a non-user-provided defaulted function +does not bind any names. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +struct trivial { + trivial() = default; + trivial(const trivial&) = default; + trivial(trivial&&) = default; + trivial& operator=(const trivial&) = default; + trivial& operator=(trivial&&) = default; + ~trivial() = default; +}; + +struct nontrivial1 { + nontrivial1(); +}; +nontrivial1::nontrivial1() = default; // not first declaration +\end{codeblock} +\end{example} + +\rSec2[dcl.fct.def.delete]{Deleted definitions}% +\indextext{definition!function!deleted}% + +\pnum +A \defnadj{deleted}{definition} of a function is a function definition +whose \grammarterm{function-body} is a \grammarterm{deleted-function-body} +or an explicitly-defaulted definition of the function where the function is +defined as deleted. +A \defnadj{deleted}{function} is +a function with a +deleted definition or a function that is implicitly defined as deleted. + +\pnum +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 +the text of the \grammarterm{unevaluated-string}, +if one is supplied. + +\begin{note} +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 +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. +The \grammarterm{unevaluated-string}, if present, +can be used to explain the rationale for deletion and/or +to suggest an alternative. +\end{note} + +\pnum +\begin{example} +One can prevent default initialization and +initialization by non-\tcode{double}s with +\begin{codeblock} +struct onlydouble { + onlydouble() = delete; // OK, but redundant + template + onlydouble(T) = delete; + onlydouble(double); +}; +\end{codeblock} +\end{example} + +\begin{example} +One can prevent use of a +class in certain \grammarterm{new-expression}{s} by using deleted definitions +of a user-declared \tcode{operator new} for that class. +\begin{codeblock} +struct sometype { + void* operator new(std::size_t) = delete; + void* operator new[](std::size_t) = delete; +}; +sometype* p = new sometype; // error: deleted class \tcode{operator new} +sometype* q = new sometype[3]; // error: deleted class \tcode{operator new[]} +\end{codeblock} +\end{example} + +\begin{example} +One can make a class uncopyable, i.e., move-only, by using deleted +definitions of the copy constructor and copy assignment operator, and then +providing defaulted definitions of the move constructor and move assignment operator. +\begin{codeblock} +struct moveonly { + moveonly() = default; + moveonly(const moveonly&) = delete; + moveonly(moveonly&&) = default; + moveonly& operator=(const moveonly&) = delete; + moveonly& operator=(moveonly&&) = default; + ~moveonly() = default; +}; +moveonly* p; +moveonly q(*p); // error: deleted copy constructor +\end{codeblock} +\end{example} + +\pnum +A deleted function is implicitly an inline function\iref{dcl.inline}. +\begin{note} +The +one-definition rule\iref{basic.def.odr} applies to deleted definitions. +\end{note} +A deleted definition of a function shall be the first declaration of the function or, +for an explicit specialization of a function template, the first declaration of that +specialization. +An implicitly declared allocation or deallocation function\iref{basic.stc.dynamic} +shall not be defined as deleted. +\begin{example} +\begin{codeblock} +struct sometype { + sometype(); +}; +sometype::sometype() = delete; // error: not first declaration +\end{codeblock} +\end{example} +\indextext{definition!function|)} + +\rSec2[dcl.fct.def.coroutine]{Coroutine definitions}% +\indextext{definition!coroutine}% + +\pnum +A function is a \defn{coroutine} if its \grammarterm{function-body} encloses a +\grammarterm{coroutine-return-statement}\iref{stmt.return.coroutine}, +an \grammarterm{await-expression}\iref{expr.await}, +or a \grammarterm{yield-expression}\iref{expr.yield}. +The \grammarterm{parameter-declaration-clause} of the coroutine shall not +terminate with an ellipsis that is not part of +a \grammarterm{parameter-declaration}. + +\pnum +\begin{example} +\begin{codeblock} +task f(); + +task g1() { + int i = co_await f(); + std::cout << "f() => " << i << std::endl; +} + +template +task g2(Args&&...) { // OK, ellipsis is a pack expansion + int i = co_await f(); + std::cout << "f() => " << i << std::endl; +} + +task g3(int a, ...) { // error: variable parameter list not allowed + int i = co_await f(); + std::cout << "f() => " << i << std::endl; +} +\end{codeblock} +\end{example} + +\pnum +\indextext{promise type|see{coroutine, promise type}}% +The \defnx{promise type}{coroutine!promise type} of a coroutine is +\tcode{std::coroutine_traits::promise_type}, +where +\tcode{R} is the return type of the function, and +$\tcode{P}_1 \dotsc \tcode{P}_n$ is the sequence of types of the non-object function parameters, +preceded by the type of the object parameter\iref{dcl.fct} +if the coroutine is a non-static member function. +The promise type shall be a class type. + +\pnum +In the following, $\tcode{p}_i$ is an lvalue of type $\tcode{P}_i$, +where +$\tcode{p}_1$ denotes the object parameter and +$\tcode{p}_{i+1}$ denotes the $i^\text{th}$ non-object function parameter +for an implicit object member function, and +$\tcode{p}_i$ denotes +the $i^\text{th}$ function parameter otherwise. +For an implicit object member function, +$\tcode{q}_1$ is an lvalue that denotes \tcode{*this}; +any other $\tcode{q}_i$ is an lvalue +that denotes the parameter copy corresponding to $\tcode{p}_i$, +as described below. + +\pnum +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 +% FIXME: \bnfindent \exposid{promise}\terminal{.get_return_object()} \terminal{;} +% ... except that it's not a discarded-value expression +\bnfindent \terminal{try} \terminal{\{}\br +\bnfindent\bnfindent \terminal{co_await} \terminal{\exposid{promise}.initial_suspend()} \terminal{;}\br +\bnfindent\bnfindent function-body\br +\bnfindent \terminal{\} catch ( ... ) \{}\br +\bnfindent\bnfindent \terminal{if (!\exposid{initial-await-resume-called})}\br +\bnfindent\bnfindent\bnfindent \terminal{throw} \terminal{;}\br +\bnfindent\bnfindent \terminal{\exposid{promise}.unhandled_exception()} \terminal{;}\br +\bnfindent \terminal{\}}\br +\exposid{final-suspend} \terminal{:}\br +\bnfindent \terminal{co_await} \terminal{\exposid{promise}.final_suspend()} \terminal{;}\br +\terminal{\}} +\end{ncsimplebnf} +where +\begin{itemize} +\item +\indextext{coroutine!await expression}% +the \grammarterm{await-expression} containing +the call to \tcode{initial_suspend} +is the \defnadj{initial}{await expression}, and +\item +the \grammarterm{await-expression} containing +the call to \tcode{final_suspend} +is the \defnadj{final}{await expression}, and +\item +\placeholder{initial-await-resume-called} +is initially \tcode{false} and is set to \tcode{true} +immediately before the evaluation +of the \placeholder{await-resume} expression\iref{expr.await} +of the initial await expression, and +\item +\placeholder{promise-type} denotes the promise type, and +\item +the object denoted by the exposition-only name \exposid{promise} +is the \defn{promise object} of the coroutine, and +\item +the label denoted by the name \exposid{final-suspend} +is defined for exposition only\iref{stmt.return.coroutine}, and +\item +\placeholder{promise-constructor-arguments} is determined as follows: +overload resolution is performed on a promise constructor call created by +assembling an argument list $\tcode{q}_1 \dotsc \tcode{q}_n$. If a viable +constructor is found\iref{over.match.viable}, then +\placeholder{promise-constructor-arguments} is +\tcode{($\tcode{q}_1$, $\dotsc$, $\tcode{q}_n$)}, otherwise +\placeholder{promise-constructor-arguments} is empty, and +\item +a coroutine is suspended at the \defnadj{initial}{suspend point} if +it is suspended at the initial await expression, and +\item +a coroutine is suspended at a \defnadj{final}{suspend point} if +it is suspended +\begin{itemize} +\item +at a final await expression or +\item +due to an exception exiting from \tcode{unhandled_exception()}. +\end{itemize} +\end{itemize} + +\pnum +\begin{note} +An odr-use of a non-reference parameter +in a postcondition assertion +of a coroutine is ill-formed\iref{dcl.contract.func}. +\end{note} + +\pnum +If searches for the names \tcode{return_void} and \tcode{return_value} +in the scope of the promise type each find any declarations, +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}. +\end{note} + +\pnum +The expression \tcode{\exposid{promise}.get_return_object()} is used +to initialize +the returned reference or prvalue result object of a call to a coroutine. +The call to \tcode{get_return_object} +is sequenced before +the call to \tcode{initial_suspend} +and is invoked at most once. + +\pnum +A suspended coroutine can be resumed to continue execution by invoking +a resumption member function\iref{coroutine.handle.resumption} +of a coroutine handle\iref{coroutine.handle} +that refers to the coroutine. +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. + +\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} +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 +If the search finds any declarations, +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$ +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 +the amount of space required as a prvalue of type \tcode{std::size_t}. +\item +If the search finds no declarations, a search is performed in the global scope. +Overload resolution is performed on a function call created by +passing the amount of space required as a prvalue of type \tcode{std::size_t}. +\end{itemize} + +\pnum +If a search for the name \tcode{get_return_object_on_allocation_failure} +in the scope of the promise type\iref{class.member.lookup} finds +any declarations, then the result +of a call to an allocation function used to obtain storage for the coroutine +state is assumed to return \keyword{nullptr} if it fails to obtain storage, +and if a global allocation function is selected, +the \tcode{::operator new(size_t, nothrow_t)} form is used. +The allocation function used in this case shall have a non-throwing +\grammarterm{noexcept-specifier}. +If the allocation function returns \keyword{nullptr}, the coroutine transfers +control to the caller of the coroutine and the return value is obtained by a +call to \tcode{T::get_return_object_on_allocation_failure()}, where \tcode{T} +is the promise type. + +\begin{example} +\begin{codeblock} +#include +#include + +// \tcode{::operator new(size_t, nothrow_t)} will be used if allocation is needed +struct generator { + struct promise_type; + using handle = std::coroutine_handle; + struct promise_type { + int current_value; + static auto get_return_object_on_allocation_failure() { return generator{nullptr}; } + auto get_return_object() { return generator{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_void() {} + auto yield_value(int value) { + current_value = value; + return std::suspend_always{}; + } + }; + bool move_next() { return coro ? (coro.resume(), !coro.done()) : false; } + int current_value() { return coro.promise().current_value; } + generator(generator const&) = delete; + generator(generator && rhs) : coro(rhs.coro) { rhs.coro = nullptr; } + ~generator() { if (coro) coro.destroy(); } +private: + generator(handle h) : coro(h) {} + handle coro; +}; +generator f() { co_yield 1; co_yield 2; } +int main() { + auto g = f(); + while (g.move_next()) std::cout << g.current_value() << std::endl; +} +\end{codeblock} +\end{example} + +\pnum +The coroutine state is destroyed when control flows off the end of the +coroutine or the \tcode{destroy} member +function\iref{coroutine.handle.resumption} +of a coroutine handle\iref{coroutine.handle} +that refers to the coroutine +is invoked. +In the latter case, +control in the coroutine is considered +to be transferred out of the function\iref{stmt.dcl}. +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. + +\pnum +The deallocation function's name is looked up by searching for it in the scope of the promise type. +If nothing is found, a search is performed in the +global scope. If both a usual deallocation +function with only a pointer parameter and a usual deallocation function with +both a pointer parameter and a size parameter are found, then the selected deallocation +function shall be the one with two parameters. Otherwise, the selected +deallocation function shall be the function with one parameter. If no usual +deallocation function is found, the program is ill-formed. +The selected deallocation function shall be called with the address of the +block of storage to be reclaimed as its first argument. If a deallocation +function with a parameter of type \tcode{std::size_t} is used, the size of +the block is passed as the corresponding argument. + +\pnum +When a coroutine is invoked, +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 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 +coroutine promise constructor and indeterminately sequenced with respect to +each other. +The lifetime of parameter copies ends immediately after the lifetime of the +coroutine promise object ends. +\begin{note} +If a coroutine has a parameter passed by reference, resuming the coroutine +after the lifetime of the entity referred to by that parameter has ended is +likely to result in undefined behavior. +\end{note} + +\pnum +If the evaluation of the expression +\tcode{\exposid{promise}.unhandled_exception()} exits via an exception, +the coroutine is considered suspended at the final suspend point +and the exception propagates to the caller or resumer. + +\pnum +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. +\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}}% + +\pnum +A structured binding declaration introduces the \grammarterm{identifier}{s} +$\tcode{v}_0$, $\tcode{v}_1$, $\tcode{v}_2, \dotsc, \tcode{v}_{N-1}$ +of the +\grammarterm{sb-identifier-list} as names. +An \grammarterm{sb-identifier} that contains an ellipsis +introduces a structured binding pack\iref{temp.variadic}. +A \defn{structured binding} is either +an \grammarterm{sb-identifier} that does not contain an ellipsis or +an element of a structured binding pack. +The optional \grammarterm{attribute-specifier-seq} of +an \grammarterm{sb-identifier} +appertains to the associated structured bindings. +Let \cv{} denote the \grammarterm{cv-qualifier}{s} in +the \grammarterm{decl-specifier-seq} and +\placeholder{S} consist of +each \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq} +that is \tcode{constexpr}, \tcode{constinit}, or +a \grammarterm{storage-class-specifier}. +A \cv{} that includes \tcode{volatile} is deprecated; +see~\ref{depr.volatile.type}. +First, a variable with a unique name \exposid{e} is introduced. If the +\grammarterm{assignment-expression} in the \grammarterm{initializer} +has array type \cvqual{cv1} \tcode{A} and no \grammarterm{ref-qualifier} is present, +\exposid{e} is defined by +\begin{ncbnf} +\opt{attribute-specifier-seq} \placeholder{S} \cv{} \terminal{A} \exposid{e} \terminal{;} +\end{ncbnf} +and each element is copy-initialized or direct-initialized +from the corresponding element of the \grammarterm{assignment-expression} as specified +by the form of the \grammarterm{initializer}. +Otherwise, \exposid{e} +is defined as-if by +\begin{ncbnf} +\opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \exposid{e} initializer \terminal{;} +\end{ncbnf} +where +the declaration is never interpreted as a function declaration and +the parts of the declaration other than the \grammarterm{declarator-id} are taken +from the corresponding structured binding declaration. +The type of the \grammarterm{id-expression} +\exposid{e} is called \tcode{E}. +\begin{note} +\tcode{E} is never a reference type\iref{expr.prop}. +\end{note} + +\pnum +The \defn{structured binding size} of \tcode{E}, as defined below, +is the number of structured bindings +that need to be introduced by the structured binding declaration. +If there is no structured binding pack, +then the number of elements in the \grammarterm{sb-identifier-list} +shall be equal to the structured binding size of \tcode{E}. +Otherwise, the number of non-pack elements shall be no more than +the structured binding size of \tcode{E}; +the number of elements of the structured binding pack is +the structured binding size of \tcode{E} less +the number of non-pack elements in the \grammarterm{sb-identifier-list}. + +\pnum +Let $\textrm{SB}_i$ denote +the $i^\textrm{th}$ structured binding in the structured binding declaration +after expanding the structured binding pack, if any. +\begin{note} +If there is no structured binding pack, +then $\textrm{SB}_i$ denotes $\tcode{v}_i$. +\end{note} +\begin{example} +\begin{codeblock} +struct C { int x, y, z; }; + +template +void now_i_know_my() { + auto [a, b, c] = C(); // OK, $\textrm{SB}_0$ is \tcode{a}, $\textrm{SB}_1$ is \tcode{b}, and $\textrm{SB}_2$ is \tcode{c} + auto [d, ...e] = C(); // OK, $\textrm{SB}_0$ is \tcode{d}, the pack \tcode{e} $(\tcode{v}_1)$ contains two structured bindings: $\textrm{SB}_1$ and $\textrm{SB}_2$ + auto [...f, g] = C(); // OK, the pack \tcode{f} $(\tcode{v}_0)$ contains two structured bindings: $\textrm{SB}_0$ and $\textrm{SB}_1$, and $\textrm{SB}_2$ is \tcode{g} + auto [h, i, j, ...k] = C(); // OK, the pack \tcode{k} is empty + auto [l, m, n, o, ...p] = C(); // error: structured binding size is too small +} +\end{codeblock} +\end{example} + +\pnum +If a structured binding declaration appears as a \grammarterm{condition}, +the decision variable\iref{stmt.pre} of the condition is \exposid{e}. + +\pnum +If the \grammarterm{initializer} refers to +one of the names introduced by the structured binding declaration, +the program is ill-formed. + +\pnum +\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 +lvalue that refers to the element $i$ of the array and whose type +is \tcode{T}; the referenced type is \tcode{T}. +\begin{note} +The top-level cv-qualifiers of \tcode{T} are \cv. +\end{note} +\begin{example} +\begin{codeblock} +auto f() -> int(&)[2]; +auto [ x, y ] = f(); // \tcode{x} and \tcode{y} refer to elements in a copy of the array return value +auto& [ xr, yr ] = f(); // \tcode{xr} and \tcode{yr} refer to elements in the array referred to by \tcode{f}'s return value + +auto g() -> int(&)[4]; + +template +void h(int (&arr)[N]) { + auto [a, ...b, c] = arr; // \tcode{a} names the first element of the array, \tcode{b} is a pack referring to the second and + // third elements, and \tcode{c} names the fourth element + auto& [...e] = arr; // \tcode{e} is a pack referring to the four elements of the array +} + +void call_h() { + h(g()); +} +\end{codeblock} +\end{example} + +\pnum +Otherwise, if +the \grammarterm{qualified-id} \tcode{std::tuple_size} +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 +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 $\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 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}. +In either case, \tcode{get} is interpreted as a \grammarterm{template-id}. +\begin{note} +Ordinary unqualified lookup\iref{basic.lookup.unqual} is not performed. +\end{note} +In either case, \exposid{e} is an lvalue if the type of the entity \exposid{e} +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$ 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} +\placeholder{S} \terminal{U$_i$ r$_i$ =} initializer \terminal{;} +\end{ncbnf} + +Each $\textrm{SB}_i$ is the name of an lvalue of type $\tcode{T}_i$ +that refers to the object bound to $\tcode{r}_i$; +the referenced type is $\tcode{T}_i$. +The initialization of \exposid{e} and +any conversion of \exposid{e} considered as a decision variable\iref{stmt.pre} +is +sequenced before the initialization of any $\tcode{r}_i$. +The initialization of each $\tcode{r}_i$ is +sequenced before the initialization of any $\tcode{r}_j$ where $i < j$. + +\pnum +Otherwise, +all of \tcode{E}'s non-static data members +shall be direct members of \tcode{E} or +of the same base class of \tcode{E}, +well-formed when named as \tcode{\exposidnc{e}.\placeholder{name}} +in the context of the structured binding, +\tcode{E} shall not have an anonymous union member, and +the structured binding size of \tcode{E} is +equal to the number of non-static data members of \tcode{E}. +Designating the non-static data members of \tcode{E} as +$\tcode{m}_0$, $\tcode{m}_1$, $\tcode{m}_2, \dotsc$ +(in declaration order), +each $\textrm{SB}_i$ is the +name of an lvalue that refers to the member \tcode{m}$_i$ of \exposid{e} and +whose type is +that of \tcode{\exposidnc{e}.$\tcode{m}_i$}\iref{expr.ref}; +the referenced type is +the declared type of $\tcode{m}_i$ if that type is a reference type, or +the type of \tcode{\exposidnc{e}.$\tcode{m}_i$} otherwise. +The lvalue is a +bit-field if that member is a bit-field. +\begin{example} +\begin{codeblock} +struct S { mutable int x1 : 2; volatile double y1; }; +S f(); +const auto [ x, y ] = f(); +\end{codeblock} +The type of the \grammarterm{id-expression} \tcode{x} is ``\tcode{int}'', +the type of the \grammarterm{id-expression} \tcode{y} is ``\tcode{const volatile double}''. +\end{example} + +\rSec1[enum]{Enumerations}% + +\rSec2[dcl.enum]{Enumeration declarations}% +\indextext{enumeration}% +\indextext{\idxcode{\{\}}!enum declaration@\tcode{enum} declaration}% +\indextext{\idxcode{enum}!type of} + +\pnum +An enumeration is a distinct type\iref{basic.compound} with named +constants. Its name becomes an \grammarterm{enum-name} within its scope. + +\begin{bnf} +\nontermdef{enum-name}\br + identifier +\end{bnf} + +\begin{bnf} +\nontermdef{enum-specifier}\br + enum-head \terminal{\{} \opt{enumerator-list} \terminal{\}}\br + enum-head \terminal{\{} enumerator-list \terminal{,} \terminal{\}} +\end{bnf} + +\begin{bnf} +\nontermdef{enum-head}\br + enum-key \opt{attribute-specifier-seq} \opt{enum-head-name} \opt{enum-base} +\end{bnf} + +\begin{bnf} +\nontermdef{enum-head-name}\br + \opt{nested-name-specifier} identifier +\end{bnf} + +\begin{bnf} +\nontermdef{opaque-enum-declaration}\br + enum-key \opt{attribute-specifier-seq} enum-head-name \opt{enum-base} \terminal{;} +\end{bnf} + +\begin{bnf} +\nontermdef{enum-key}\br + \keyword{enum}\br + \keyword{enum} \keyword{class}\br + \keyword{enum} \keyword{struct} +\end{bnf} + +\begin{bnf} +\nontermdef{enum-base}\br + \terminal{:} type-specifier-seq +\end{bnf} + +\begin{bnf} +\nontermdef{enumerator-list}\br + enumerator-definition\br + enumerator-list \terminal{,} enumerator-definition +\end{bnf} + +\begin{bnf} +\nontermdef{enumerator-definition}\br + enumerator\br + enumerator \terminal{=} constant-expression +\end{bnf} + +\begin{bnf} +\nontermdef{enumerator}\br + identifier \opt{attribute-specifier-seq} +\end{bnf} + +The optional \grammarterm{attribute-specifier-seq} in the \grammarterm{enum-head} and +the \grammarterm{opaque-enum-declaration} appertains to the enumeration; the attributes +in that \grammarterm{attribute-specifier-seq} are thereafter considered attributes of the +enumeration whenever it is named. +A \tcode{:} following +``\keyword{enum} \opt{\grammarterm{nested-name-specifier}} \grammarterm{identifier}'' +within the \grammarterm{decl-specifier-seq} of a \grammarterm{member-declaration} +is parsed as part of an \grammarterm{enum-base}. +\begin{note} +This resolves a potential ambiguity between the declaration of an enumeration +with an \grammarterm{enum-base} and the declaration of an unnamed bit-field of enumeration +type. +\begin{example} +\begin{codeblock} +struct S { + enum E : int {}; + enum E : int {}; // error: redeclaration of enumeration +}; +\end{codeblock} + +\end{example} +\end{note} +The \grammarterm{identifier} in an \grammarterm{enum-head-name} +is not looked up and is introduced by +the \grammarterm{enum-specifier} or \grammarterm{opaque-enum-declaration}. +If the \grammarterm{enum-head-name} of an \grammarterm{opaque-enum-declaration} contains +a \grammarterm{nested-name-specifier}, +the declaration shall be an explicit specialization\iref{temp.expl.spec}. + +\pnum +\indextext{constant!enumeration}% +The enumeration type declared with an \grammarterm{enum-key} +of only \keyword{enum} is an \defnadj{unscoped}{enumeration}, +and its \grammarterm{enumerator}{s} are \defnx{unscoped enumerators}{enumerator!unscoped}. +The \grammarterm{enum-key}{s} \tcode{enum class} and +\tcode{enum struct} are semantically equivalent; an enumeration +type declared with one of these is a \defnadj{scoped}{enumeration}, +and its \grammarterm{enumerator}{s} are \defnx{scoped enumerators}{enumerator!scoped}. +The optional \grammarterm{enum-head-name} shall not be omitted in the declaration of a scoped enumeration. +The \grammarterm{type-specifier-seq} of an \grammarterm{enum-base} +shall name an integral type; any cv-qualification is ignored. +An \grammarterm{opaque-enum-declaration} declaring an unscoped enumeration shall +not omit the \grammarterm{enum-base}. +The identifiers in an \grammarterm{enumerator-list} are declared as +constants, and can appear wherever constants are required. +The same identifier shall not appear as +the name of multiple enumerators in an \grammarterm{enumerator-list}. +\indextext{enumerator!value of}% +An \grammarterm{enumerator-definition} with \tcode{=} gives the associated +\grammarterm{enumerator} the value indicated by the +\grammarterm{constant-expression}. +An \grammarterm{enumerator-definition} without \tcode{=} gives the associated +\grammarterm{enumerator} the value zero +if it is the first \grammarterm{enumerator-definition}, +and the value of the previous \grammarterm{enumerator} +increased by one otherwise. +\begin{example} +\begin{codeblock} +enum { a, b, c=0 }; +enum { d, e, f=e+2 }; +\end{codeblock} +defines \tcode{a}, \tcode{c}, and \tcode{d} to be zero, \tcode{b} and +\tcode{e} to be \tcode{1}, and \tcode{f} to be \tcode{3}. +\end{example} +The optional \grammarterm{attribute-specifier-seq} in an +\grammarterm{enumerator} appertains to that enumerator. + +\pnum +An \grammarterm{opaque-enum-declaration} is either a redeclaration +of an enumeration in the current scope or a declaration of a new enumeration. +\begin{note} +An enumeration declared by an +\grammarterm{opaque-enum-declaration} has a fixed underlying type and is a +complete type. The list of enumerators can be provided in a later redeclaration +with an \grammarterm{enum-specifier}. +\end{note} +A scoped enumeration +shall not be later redeclared as unscoped or with a different underlying type. +An unscoped enumeration shall not be later redeclared as scoped and each +redeclaration shall include an \grammarterm{enum-base} specifying the same +underlying type as in the original declaration. + +\pnum +If an \grammarterm{enum-head-name} contains a +\grammarterm{nested-name-specifier}, +the enclosing \grammarterm{enum-specifier} +or \grammarterm{opaque-enum-declaration} $D$ +shall not inhabit a class scope and +shall correspond to one or more declarations nominable +in the class, class template, or namespace +to which the \grammarterm{nested-name-specifier} refers\iref{basic.scope.scope}. +All those declarations shall have the same target scope; +the target scope of $D$ is that scope. + +\pnum +\indextext{\idxcode{enum}!type of}% +\indextext{\idxcode{enum}!underlying type|see{type, underlying}}% +Each enumeration defines a type that is different from all other types. +Each enumeration also has an \defnx{underlying type}{type!underlying!enumeration}. +The underlying type can be explicitly specified using an \grammarterm{enum-base}. +For a scoped enumeration type, the underlying type is \tcode{int} if it is not +explicitly specified. In both of these cases, the underlying type is said to be +\defnx{fixed}{type!underlying!fixed}. +Following the closing brace of an \grammarterm{enum-specifier}, each +enumerator has the type of its enumeration. +If the underlying type is fixed, the type of each enumerator +prior to the closing brace is the underlying +type +and the \grammarterm{constant-expression} in the \grammarterm{enumerator-definition} +shall be a converted constant expression of the underlying +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 +follows: + +\begin{itemize} +\item If an +initializer is specified for an enumerator, the +\grammarterm{constant-expression} shall be an integral constant +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. + +\item If no initializer is specified for the +first enumerator, its type is an unspecified signed integral type. + +\item Otherwise +the type of the enumerator is the same as that of the +preceding enumerator unless the incremented value is not representable +in that type, in which case the type is an unspecified integral type +sufficient to contain the incremented value. If no such type exists, the program +is ill-formed. +\end{itemize} + +\pnum +An enumeration whose underlying type is fixed is an incomplete type +until immediately after its +\grammarterm{enum-base} (if any), at which point it becomes a complete type. +An enumeration whose underlying type is not fixed is an incomplete type +until the closing \tcode{\}} of its +\grammarterm{enum-specifier}, at which point it becomes a complete type. + +\pnum +For an enumeration whose underlying type is not fixed, +the underlying type +is an +integral type that can represent all the enumerator values defined in +the enumeration. If no integral type can represent all the enumerator +values, the enumeration is ill-formed. It is \impldef{underlying type for enumeration} +which integral type is used as the underlying type +except that the underlying type shall not be larger than \tcode{int} +unless the value of an enumerator cannot fit in an \tcode{int} or +\tcode{unsigned int}. If the \grammarterm{enumerator-list} is empty, the +underlying type is as if the enumeration had a single enumerator with +value 0. + +\pnum +\indextext{signed integer representation!two's complement}% +For an enumeration whose underlying type is fixed, the values of +the enumeration are the values of the underlying type. Otherwise, +the values of the enumeration are the values representable by +a hypothetical integer type with minimal width $M$ +such that all enumerators can be represented. +The width of the smallest bit-field large enough to hold all the values of the +enumeration type is $M$. +It is possible to define an enumeration that has values not defined by +any of its enumerators. If the \grammarterm{enumerator-list} is empty, the +values of the enumeration are as if the enumeration had a single enumerator with +value 0. +\begin{footnote} +This set of values is used to define promotion and +conversion semantics for the enumeration type. It does not preclude an +expression of enumeration type from having a value that falls outside +this range. +\end{footnote} + +\pnum +An enumeration has +the same size, +value representation, and +alignment requirements\iref{basic.align} +as its underlying type. +Furthermore, each value of an enumeration has the same representation +as the corresponding value of the underlying type. + +\pnum +Two enumeration types are \defnx{layout-compatible enumerations}{layout-compatible!enumeration} +if they have the same underlying type. + +\pnum +The value of an enumerator or an object of an unscoped enumeration type is +converted to an integer by integral promotion\iref{conv.prom}. +\begin{example} +\begin{codeblock} +enum color { red, yellow, green=20, blue }; +color col = red; +color* cp = &col; +if (*cp == blue) // ... +\end{codeblock} +makes \tcode{color} a type describing various colors, and then declares +\tcode{col} as an object of that type, and \tcode{cp} as a pointer to an +object of that type. The possible values of an object of type +\tcode{color} are \tcode{red}, \tcode{yellow}, \tcode{green}, +\tcode{blue}; these values can be converted to the integral values +\tcode{0}, \tcode{1}, \tcode{20}, and \tcode{21}. Since enumerations are +distinct types, objects of type \tcode{color} can be assigned only +values of type \tcode{color}. +\begin{codeblock} +color c = 1; // error: type mismatch, no conversion from \tcode{int} to \tcode{color} +int i = yellow; // OK, \tcode{yellow} converted to integral value \tcode{1}, integral promotion +\end{codeblock} +Note that this implicit \keyword{enum} to \tcode{int} +conversion is not provided for a scoped enumeration: +\begin{codeblock} +enum class Col { red, yellow, green }; +int x = Col::red; // error: no \tcode{Col} to \tcode{int} conversion +Col y = Col::red; +if (y) { } // error: no \tcode{Col} to \tcode{bool} conversion +\end{codeblock} +\end{example} + +\pnum +\indextext{class!scope of enumerator}% +The name of each unscoped enumerator is also bound +in the scope that immediately contains the \grammarterm{enum-specifier}. +An unnamed enumeration +that does not have a typedef name for linkage purposes\iref{dcl.typedef} and +that has a first enumerator +is denoted, for linkage purposes\iref{basic.link}, +by its underlying type and its first enumerator; +such an enumeration is said to have +an enumerator as a name for linkage purposes. +\begin{note} +Each unnamed enumeration with no enumerators is a distinct type. +\end{note} +\begin{example} +\begin{codeblock} +enum direction { left='l', right='r' }; + +void g() { + direction d; // OK + d = left; // OK + d = direction::right; // OK +} + +enum class altitude { high='h', low='l' }; + +void h() { + altitude a; // OK + a = high; // error: \tcode{high} not in scope + a = altitude::low; // OK +} +\end{codeblock} +\end{example} + +\rSec2[enum.udecl]{The \tcode{using enum} declaration}% +\indextext{enumeration!using declaration}% + +\begin{bnf} +\nontermdef{using-enum-declaration}\br + \keyword{using} \keyword{enum} using-enum-declarator \terminal{;} +\end{bnf} + +\begin{bnf} +\nontermdef{using-enum-declarator}\br + \opt{nested-name-specifier} identifier\br + \opt{nested-name-specifier} simple-template-id\br + splice-type-specifier +\end{bnf} + +\pnum +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}. +The \grammarterm{using-enum-declarator} +shall designate a non-dependent type +with a reachable \grammarterm{enum-specifier}. +\begin{example} +\begin{codeblock} +enum E { x }; +void f() { + int E; + using enum E; // OK +} +using F = E; +using enum F; // OK +template using EE = T; +void g() { + using enum EE; // OK +} +\end{codeblock} +\end{example} + +\pnum +A \grammarterm{using-enum-declaration} +is equivalent to a \grammarterm{using-declaration} for each enumerator. + +\pnum +\begin{note} +A \grammarterm{using-enum-declaration} in class scope +makes the enumerators of the named enumeration available via member lookup. +\begin{example} +\begin{codeblock} +enum class fruit { orange, apple }; +struct S { + using enum fruit; // OK, introduces \tcode{orange} and \tcode{apple} into \tcode{S} +}; +void f() { + S s; + s.orange; // OK, names \tcode{fruit::orange} + S::orange; // OK, names \tcode{fruit::orange} +} +\end{codeblock} +\end{example} +\end{note} + +\pnum +\begin{note} +Two \grammarterm{using-enum-declaration}s +that introduce two enumerators of the same name conflict. +\begin{example} +\begin{codeblock} +enum class fruit { orange, apple }; +enum class color { red, orange }; +void f() { + using enum fruit; // OK + using enum color; // error: \tcode{color::orange} and \tcode{fruit::orange} conflict +} +\end{codeblock} +\end{example} +\end{note} + +\rSec1[basic.namespace]{Namespaces}% + +\rSec2[basic.namespace.general]{General}% +\indextext{namespaces|(} + +\pnum +A namespace is an optionally-named entity +whose scope can contain declarations of any kind of entity. +The name of a +namespace can be used to access entities that belong to that namespace; +that is, the \defnx{members}{member!namespace} of the namespace. +Unlike other entities, +the definition of a namespace can be split over several parts of one or +more translation units and modules. + +\pnum +\begin{note} +A \grammarterm{namespace-definition} is exported +if it contains any +\grammarterm{export-declaration}{s}\iref{module.interface}. +A namespace is never attached to a named module +and never has a name with module linkage. +\end{note} +\begin{example} +\begin{codeblock} +export module M; +namespace N1 {} // \tcode{N1} is not exported +export namespace N2 {} // \tcode{N2} is exported +namespace N3 { export int n; } // \tcode{N3} is exported +\end{codeblock} +\end{example} + +\pnum +There is a \defnadj{global}{namespace} with no declaration; +see~\ref{basic.scope.namespace}. +The global namespace belongs to the global scope; +it is not an unnamed namespace\iref{namespace.unnamed}. +\begin{note} +Lacking a declaration, it cannot be found by name lookup. +\end{note} + +\rSec2[namespace.def]{Namespace definition}% + +\rSec3[namespace.def.general]{General}% +\indextext{definition!namespace}% +\indextext{namespace!definition} + +\begin{bnf} +\nontermdef{namespace-name}\br + identifier\br + namespace-alias +\end{bnf} + +\begin{bnf} +\nontermdef{namespace-definition}\br + named-namespace-definition\br + unnamed-namespace-definition\br + nested-namespace-definition +\end{bnf} + +\begin{bnf} +\nontermdef{named-namespace-definition}\br + \opt{\keyword{inline}} \keyword{namespace} \opt{attribute-specifier-seq} identifier \terminal{\{} namespace-body \terminal{\}} +\end{bnf} + +\begin{bnf} +\nontermdef{unnamed-namespace-definition}\br + \opt{\keyword{inline}} \keyword{namespace} \opt{attribute-specifier-seq} \terminal{\{} namespace-body \terminal{\}} +\end{bnf} + +\begin{bnf} +\nontermdef{nested-namespace-definition}\br + \keyword{namespace} enclosing-namespace-specifier \terminal{::} \opt{\keyword{inline}} identifier \terminal{\{} namespace-body \terminal{\}} +\end{bnf} + +\begin{bnf} +\nontermdef{enclosing-namespace-specifier}\br + identifier\br + enclosing-namespace-specifier \terminal{::} \opt{\keyword{inline}} identifier +\end{bnf} + +\begin{bnf} +\nontermdef{namespace-body}\br + \opt{declaration-seq} +\end{bnf} + +\pnum +Every \grammarterm{namespace-definition} shall inhabit a namespace scope\iref{basic.scope.namespace}. + +\pnum +In a \grammarterm{named-namespace-definition} $D$, +the \grammarterm{identifier} is the name of the namespace. +The \grammarterm{identifier} is looked up +by searching for it in the scopes of the namespace $A$ +in which $D$ appears +and of every element of the inline namespace set of $A$. +If the lookup finds a \grammarterm{namespace-definition} for a namespace $N$, +\indextext{extend|see{namespace, extend}}% +$D$ \defnx{extends}{namespace!extend} $N$, +and the target scope of $D$ is the scope to which $N$ belongs. +If the lookup finds nothing, the \grammarterm{identifier} is introduced +as a \grammarterm{namespace-name} into $A$. + +\pnum +Because a \grammarterm{namespace-definition} contains +\grammarterm{declaration}{s} in its \grammarterm{namespace-body} and a +\grammarterm{namespace-definition} is itself a \grammarterm{declaration}, it +follows that \grammarterm{namespace-definition}{s} can be nested. +\begin{example} +\begin{codeblock} +namespace Outer { + int i; + namespace Inner { + void f() { i++; } // \tcode{Outer::i} + int i; + void g() { i++; } // \tcode{Inner::i} + } +} +\end{codeblock} +\end{example} + +\pnum +If the optional initial \keyword{inline} keyword appears in a +\grammarterm{namespace-definition} for a particular namespace, that namespace is +declared to be an \defnadj{inline}{namespace}. The \keyword{inline} keyword may be +used on a \grammarterm{namespace-definition} that extends a namespace +only if it was previously used on the \grammarterm{namespace-definition} +that initially declared the \grammarterm{namespace-name} for that namespace. + +\pnum +The optional \grammarterm{attribute-specifier-seq} +in a \grammarterm{named-namespace-definition} +appertains to the namespace being defined or extended. + +\pnum +Members of an inline namespace can be used in most respects as though they were members +of the innermost enclosing namespace. Specifically, the inline namespace and its enclosing +namespace are both added to the set of associated namespaces used in +argument-dependent lookup\iref{basic.lookup.argdep} whenever one of them is, +and a \grammarterm{using-directive}\iref{namespace.udir} that names the inline +namespace is implicitly inserted into the enclosing namespace as for an unnamed +namespace\iref{namespace.unnamed}. Furthermore, each +member of the inline namespace can subsequently be partially +specialized\iref{temp.spec.partial}, explicitly +instantiated\iref{temp.explicit}, or explicitly specialized\iref{temp.expl.spec} as +though it were a member of the enclosing namespace. Finally, looking up a name in the +enclosing namespace via explicit qualification\iref{namespace.qual} will include +members of the inline namespace even if +there are declarations of that name in the enclosing namespace. + +\pnum +These properties are transitive: if a namespace \tcode{N} contains an inline namespace +\tcode{M}, which in turn contains an inline namespace \tcode{O}, then the members of +\tcode{O} can be used as though they were members of \tcode{M} or \tcode{N}. +The \defn{inline namespace set} of \tcode{N} is the transitive closure of all +inline namespaces in \tcode{N}. + +\pnum +A \grammarterm{nested-namespace-definition} with an +\grammarterm{enclosing-namespace-specifier} \tcode{E}, +\grammarterm{identifier} \tcode{I} and +\grammarterm{namespace-body} \tcode{B} +is equivalent to +\begin{codeblock} +namespace E { @\opt{inline}@ namespace I { B } } +\end{codeblock} +where the optional \keyword{inline} is present if and only if +the \grammarterm{identifier} \tcode{I} is preceded by \keyword{inline}. +\begin{example} +\begin{codeblock} +namespace A::inline B::C { + int i; +} +\end{codeblock} +The above has the same effect as: +\begin{codeblock} +namespace A { + inline namespace B { + namespace C { + int i; + } + } +} +\end{codeblock} +\end{example} + +\rSec3[namespace.unnamed]{Unnamed namespaces}% +\indextext{namespace!unnamed} + +\pnum +An \grammarterm{unnamed-namespace-definition} behaves as if it were +replaced by +\begin{ncsimplebnf} +\opt{\keyword{inline}} \keyword{namespace} \exposid{unique} \terminal{\{} \terminal{/* empty body */} \terminal{\}}\br +\keyword{using} \keyword{namespace} \exposid{unique} \terminal{;}\br +\keyword{namespace} \exposid{unique} \terminal{\{} namespace-body \terminal{\}} +\end{ncsimplebnf} +where +\keyword{inline} appears if and only if it appears in the +\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 program. +The optional \grammarterm{attribute-specifier-seq} +in the \grammarterm{unnamed-namespace-definition} +appertains to \exposid{unique}. +\begin{example} +\begin{codeblock} +namespace { int i; } // \tcode{\exposid{unique}::i} +void f() { i++; } // \tcode{\exposid{unique}::i++} + +namespace A { + namespace { + int i; // \tcode{A::\exposid{unique}::i} + int j; // \tcode{A::\exposid{unique}::j} + } + void g() { i++; } // \tcode{A::\exposid{unique}::i++} +} -void k(D* p) -{ - p->f(1); // calls \tcode{D::f(int)} - p->f('a'); // calls \tcode{B::f(char)} - p->g(1); // calls \tcode{B::g(int)} - p->g('a'); // calls \tcode{D::g(char)} +using namespace A; +void h() { + i++; // error: \tcode{\exposid{unique}::i} or \tcode{A::\exposid{unique}::i} + A::i++; // \tcode{A::\exposid{unique}::i} + j++; // \tcode{A::\exposid{unique}::j} } \end{codeblock} -\exitexample +\end{example} -\pnum -\indextext{overloading!using-declaration and}% -For the purpose of overload resolution, the functions which are -introduced by a \grammarterm{using-declaration} into a derived class will -be treated as though they were members of the derived class. In -particular, the implicit \tcode{this} parameter shall be treated as if -it were a pointer to the derived class rather than to the base class. -This has no effect on the type of the function, and in all other -respects the function remains a member of the base class. +\rSec2[namespace.alias]{Namespace alias}% +\indextext{namespace!alias}% +\indextext{alias!namespace}% +\indextext{synonym} \pnum -\indextext{access control!using-declaration and}% -The access rules for inheriting constructors are specified -in~\ref{class.inhctor}; otherwise all instances of the name mentioned in a -\grammarterm{using-declaration} -shall be accessible. In particular, if a derived class uses a -\grammarterm{using-declaration} to access a member of a base class, the -member name shall be accessible. If the name is that of an overloaded -member function, then all functions named shall be accessible. The base -class members mentioned by a \grammarterm{using-declaration} shall be -visible in the scope of at least one of the direct base classes of the -class where the \grammarterm{using-declaration} is specified. \enternote -Because a \grammarterm{using-declaration} designates a base class member -(and not a member subobject or a member function of a base class -subobject), a \grammarterm{using-declaration} cannot be used to resolve -inherited member ambiguities. For example, +A \grammarterm{namespace-alias-definition} declares a \defnadj{namespace}{alias} +according to the following grammar: -\begin{codeblock} -struct A { int x(); }; -struct B : A { }; -struct C : A { - using A::x; - int x(int); -}; +\begin{bnf} +\nontermdef{namespace-alias}\br + identifier +\end{bnf} -struct D : B, C { - using C::x; - int x(double); -}; -int f(D* d) { - return d->x(); // ambiguous: \tcode{B::x} or \tcode{C::x} -} -\end{codeblock} -\exitnote +\begin{bnf} +\nontermdef{namespace-alias-definition}\br + \keyword{namespace} identifier \terminal{=} qualified-namespace-specifier \terminal{;}\br + \keyword{namespace} identifier \terminal{=} splice-specifier \terminal{;} +\end{bnf} -\pnum -The alias created by the \grammarterm{using-declaration} has the usual -accessibility for a \grammarterm{member-declaration}. -\enternote A \grammarterm{using-declaration} that names a constructor does not -create aliases; see~\ref{class.inhctor} for the pertinent accessibility rules. -\exitnote -\enterexample +\begin{bnf} +\nontermdef{qualified-namespace-specifier}\br + \opt{nested-name-specifier} namespace-name +\end{bnf} -\begin{codeblock} -class A { -private: - void f(char); -public: - void f(int); -protected: - void g(); -}; +\pnum +The \grammarterm{splice-specifier} (if any) +shall designate a namespace that is not the global namespace. -class B : public A { - using A::f; // error: \tcode{A::f(char)} is inaccessible -public: - using A::g; // \tcode{B::g} is a public synonym for \tcode{A::g} -}; -\end{codeblock} -\exitexample +\pnum +The \grammarterm{identifier} in a \grammarterm{namespace-alias-definition} +becomes a \grammarterm{namespace-alias}. \pnum -If a \grammarterm{using-declaration} uses the keyword \tcode{typename} and -specifies a dependent name~(\ref{temp.dep}), the name introduced by the -\grammarterm{using-declaration} is treated as a -\grammarterm{typedef-name}~(\ref{dcl.typedef}).% -\indextext{using-declaration|)} +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 +considered, see~\ref{basic.lookup.udir}. +\end{note} -\rSec2[namespace.udir]{Using directive}% +\rSec2[namespace.udir]{Using namespace directive}% \indextext{using-directive|(} \begin{bnf} \nontermdef{using-directive}\br - attribute-specifier-seq\opt \terminal{using namespace} nested-name-specifier\opt 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. -\enternote +\begin{note} When looking up a \grammarterm{namespace-name} in a \grammarterm{using-directive}, only namespace names are considered, see~\ref{basic.lookup.udir}. -\exitnote +\end{note} The optional \grammarterm{attribute-specifier-seq} appertains to the \grammarterm{using-directive}. \pnum -A \grammarterm{using-directive} specifies that the names in the nominated -namespace can be used in the scope in which the -\grammarterm{using-directive} appears after the \grammarterm{using-directive}. -During unqualified name lookup~(\ref{basic.lookup.unqual}), the names +\begin{note} +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. -\enternote -In this context, ``contains'' means ``contains directly or indirectly''. -\exitnote +\end{note} \pnum -A \grammarterm{using-directive} does not add any members to the declarative -region in which it appears. -\enterexample - +\begin{note} +A \grammarterm{using-directive} does not introduce any names. +\end{note} +\begin{example} \begin{codeblock} namespace A { int i; @@ -2962,21 +8548,19 @@ } } void f4() { - i = 5; // ill-formed; neither \tcode{i} is visible + i = 5; // error: neither \tcode{i} is visible } \end{codeblock} -\exitexample +\end{example} \pnum -For unqualified lookup~(\ref{basic.lookup.unqual}), the -\grammarterm{using-directive} is transitive: if a scope contains a -\grammarterm{using-directive} that nominates a second namespace that itself -contains \grammarterm{using-directive}{s}, the effect is as if the -\grammarterm{using-directive}{s} from the second namespace also appeared in -the first. -\enternote For qualified lookup, see~\ref{namespace.qual}. \exitnote -\enterexample - +\begin{note} +A \grammarterm{using-directive} is transitive: if a scope contains a +\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} \begin{codeblock} namespace M { int i; @@ -2994,7 +8578,6 @@ \end{codeblock} For another example, - \begin{codeblock} namespace A { int i; @@ -3017,22 +8600,21 @@ } } \end{codeblock} -\exitexample +\end{example} \pnum -If a namespace is extended~(\ref{namespace.def}) after a -\grammarterm{using-directive} for that namespace is given, the additional -members of the extended namespace and the members of namespaces -nominated by \grammarterm{using-directive}{s} in the -extending \grammarterm{namespace-definition} can be used after the -extending \grammarterm{namespace-definition}. +\begin{note} +Declarations in a namespace +that appear after a \grammarterm{using-directive} for that namespace +can be found through that \grammarterm{using-directive} after they appear. +\end{note} \pnum +\begin{note} If name lookup finds a declaration for a name in two different namespaces, and the declarations do not declare the same entity and do -not declare functions, the use of the name is ill-formed. -\enternote +not declare functions or function templates, the use of the name is ill-formed\iref{basic.lookup}. In particular, the name of a variable, function or enumerator does not hide the name of a class or enumeration declared in a different namespace. For example, @@ -3053,66 +8635,507 @@ void f() { X(1); // error: name \tcode{X} found in two namespaces - g(); // OK: name \tcode{g} refers to the same entity - h(); // OK: overload resolution selects \tcode{A::h} + g(); // OK, name \tcode{g} refers to the same entity + h(); // OK, overload resolution selects \tcode{A::h} +} +\end{codeblock} +\end{note} + +\pnum +\indextext{overloading!using directive and}% +\begin{note} +The order in which namespaces are considered and the +relationships among the namespaces implied by the +\grammarterm{using-directive}{s} do not affect overload resolution. +Neither is any function excluded because another has the same +signature, even if one is in a namespace reachable through +\grammarterm{using-directive}{s} in the namespace of the other. +\begin{footnote} +During +name lookup in a class hierarchy, some ambiguities can be +resolved by considering whether one member hides the other along some +paths\iref{class.member.lookup}. There is no such disambiguation when +considering the set of names found as a result of following +\grammarterm{using-directive}{s}. +\end{footnote} +\end{note} +\begin{example} +\begin{codeblock} +namespace D { + int d1; + void f(char); +} +using namespace D; + +int d1; // OK, no conflict with \tcode{D::d1} + +namespace E { + int e; + void f(int); +} + +namespace D { // namespace extension + int d2; + using namespace E; + void f(int); +} + +void f() { + d1++; // error: ambiguous \tcode{::d1} or \tcode{D::d1}? + ::d1++; // OK + D::d1++; // OK + d2++; // OK, \tcode{D::d2} + e++; // OK, \tcode{E::e} + f(1); // error: ambiguous: \tcode{D::f(int)} or \tcode{E::f(int)}? + f('a'); // OK, \tcode{D::f(char)} +} +\end{codeblock} +\end{example} +\indextext{using-directive|)}% +\indextext{namespaces|)} + +\rSec1[namespace.udecl]{The \tcode{using} declaration}% +\indextext{using-declaration|(} + +\begin{bnf} +\nontermdef{using-declaration}\br + \keyword{using} using-declarator-list \terminal{;} +\end{bnf} + +\begin{bnf} +\nontermdef{using-declarator-list}\br + using-declarator \opt{\terminal{...}}\br + using-declarator-list \terminal{,} using-declarator \opt{\terminal{...}} +\end{bnf} + +\begin{bnf} +\nontermdef{using-declarator}\br + \opt{\keyword{typename}} nested-name-specifier unqualified-id +\end{bnf} + +\pnum +\indextext{component name}% +The component names of a \grammarterm{using-declarator} are those +of its \grammarterm{nested-name-specifier} and \grammarterm{unqualified-id}. +Each \grammarterm{using-declarator} in a \grammarterm{using-declaration} +\begin{footnote} +A \grammarterm{using-declaration} with more than one +\grammarterm{using-declarator} is equivalent to a corresponding sequence +of \grammarterm{using-declaration}{s} with +one \grammarterm{using-declarator} each. +\end{footnote} +names the set of declarations found by lookup\iref{basic.lookup.qual} +for the \grammarterm{using-declarator}, +except that class and enumeration declarations that would be discarded +are merely ignored when checking for ambiguity\iref{basic.lookup}, +conversion function templates with a dependent return type are ignored, and +certain functions are hidden as described below. +If the terminal name of the \grammarterm{using-declarator} +is dependent\iref{temp.dep.type}, +the \grammarterm{using-declarator} is considered to name a constructor +if and only if the \grammarterm{nested-name-specifier} has a terminal name +that is the same as the \grammarterm{unqualified-id}. +If the lookup in any instantiation finds +that a \grammarterm{using-declarator} +that is not considered to name a constructor does do so, or +that a \grammarterm{using-declarator} +that is considered to name a constructor does not, +the program is ill-formed. + +\pnum +\indextext{inheritance!\idxgram{using-declaration} and}% +If the \grammarterm{using-declarator} names a constructor, +it declares that the class \defnx{inherits}{constructor!inherited} the named set of constructor declarations +from the nominated base class. +\begin{note} +Otherwise, +the \grammarterm{unqualified-id} in the \grammarterm{using-declarator} +is bound to the \grammarterm{using-declarator}, +which is replaced during name lookup +with the declarations it names\iref{basic.lookup}. +If such a declaration is of an enumeration, +the names of its enumerators are not bound. +For the keyword \keyword{typename}, see \ref{temp.res}. +\end{note} + +\pnum +In a \grammarterm{using-declaration} used as a +\grammarterm{member-declaration}, +each \grammarterm{using-declarator} +shall either name an enumerator +or have a \grammarterm{nested-name-specifier} +naming a base class of the current class\iref{expr.prim.this}. +\begin{example} +\begin{codeblock} +enum class button { up, down }; +struct S { + using button::up; + button b = up; // OK +}; +\end{codeblock} +\end{example} +If a +\grammarterm{using-declarator} names a constructor, +its \grammarterm{nested-name-specifier} shall name +a direct base class of the current class. +If the immediate (class) scope is associated with a class template, +it shall derive from the specified base class or +have at least one dependent base class. +\begin{example} +\begin{codeblock} +struct B { + void f(char); + enum E { e }; + union { int x; }; +}; + +struct C { + int f(); +}; + +struct D : B { + using B::f; // OK, \tcode{B} is a base of \tcode{D} + using B::e; // OK, \tcode{e} is an enumerator of base \tcode{B} + using B::x; // OK, \tcode{x} is a union member of base \tcode{B} + using C::f; // error: \tcode{C} isn't a base of \tcode{D} + void f(int) { f('c'); } // calls \tcode{B::f(char)} + void g(int) { g('c'); } // recursively calls \tcode{D::g(int)} +}; +template +struct X : bases... { + using bases::f...; +}; +X x; // OK, \tcode{B::f} and \tcode{C::f} named +\end{codeblock} +\end{example} + +\pnum +\begin{note} +Since destructors do not have names, a +\grammarterm{using-declaration} cannot refer to a +destructor for a base class. +\end{note} +\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}. +\begin{example} +\begin{codeblock} +struct A { + template void f(T); + template struct X { }; +}; +struct B : A { + using A::f; // error + using A::X; // error +}; +\end{codeblock} +\end{example} + +\pnum +A \grammarterm{using-declaration} shall not name a namespace. + +\pnum +A \grammarterm{using-declaration} that names a class member +other than an enumerator +shall be a +\grammarterm{member-declaration}. +\begin{example} +\begin{codeblock} +struct X { + int i; + static int s; +}; + +void f() { + using X::i; // error: \tcode{X::i} is a class member and this is not a member declaration. + using X::s; // error: \tcode{X::s} is a class member and this is not a member declaration. +} +\end{codeblock} +\end{example} + +\pnum +If a declaration is named by two \grammarterm{using-declarator}s +that inhabit the same class scope, the program is ill-formed. +\begin{example} +\begin{codeblock} +struct C { + int i; +}; + +struct D1 : C { }; +struct D2 : C { }; + +struct D3 : D1, D2 { + using D1::i; // OK, equivalent to \tcode{using C::i} + using D1::i; // error: duplicate + using D2::i; // error: duplicate, also names \tcode{C::i} +}; +\end{codeblock} +\end{example} + +\pnum +\begin{note} +A \grammarterm{using-declarator} +whose \grammarterm{nested-name-specifier} names a namespace +does not name declarations added to the namespace after it. Thus, additional +overloads added after the \grammarterm{using-declaration} are ignored, but +default function arguments\iref{dcl.fct.default}, default template +arguments\iref{temp.param}, and +template specializations\iref{temp.spec.partial,temp.expl.spec} are considered. +\end{note} +\begin{example} +\begin{codeblock} +namespace A { + void f(int); +} + +using A::f; // \tcode{f} is a synonym for \tcode{A::f}; that is, for \tcode{A::f(int)}. +namespace A { + void f(char); +} + +void foo() { + f('a'); // calls \tcode{f(int)}, even though \tcode{f(char)} exists. +} + +void bar() { + using A::f; // \tcode{f} is a synonym for \tcode{A::f}; that is, for \tcode{A::f(int)} and \tcode{A::f(char)}. + f('a'); // calls \tcode{f(char)} +} +\end{codeblock} +\end{example} + +\pnum +If a declaration named by a \grammarterm{using-declaration} +that inhabits the target scope of another declaration $B$ +potentially conflicts with it\iref{basic.scope.scope}, and +either is reachable from the other, the program is ill-formed +unless $B$ is name-independent and +the \grammarterm{using-declaration} precedes $B$. +\begin{example} +\begin{codeblock} +int _; +void f() { + int _; // B + _ = 0; + using ::_; // error: \grammarterm{using-declaration} does not precede B +} +\end{codeblock} +\end{example} +If two declarations named by \grammarterm{using-declaration}s +that inhabit the same scope potentially conflict, +either is reachable from the other, and +they do not both declare functions or function templates, +the program is ill-formed. +\begin{note} +Overload resolution possibly cannot distinguish +between conflicting function declarations. +\end{note} +\begin{example} +\begin{codeblock} +namespace A { + int x; + int f(int); + int g; + void h(); +} + +namespace B { + int i; + struct g { }; + struct x { }; + void f(int); + void f(double); + void g(char); // OK, hides \tcode{struct g} +} + +void func() { + int i; + using B::i; // error: conflicts + void f(char); + using B::f; // OK, each \tcode{f} is a function + using A::f; // OK, but interferes with \tcode{B::f(int)} + f(1); // error: ambiguous + static_cast(f)(1); // OK, calls \tcode{A::f} + f(3.5); // calls \tcode{B::f(double)} + using B::g; + g('a'); // calls \tcode{B::g(char)} + struct g g1; // \tcode{g1} has class type \tcode{B::g} + using A::g; // error: conflicts with \tcode{B::g} + void h(); + using A::h; // error: conflicts + using B::x; + using A::x; // OK, hides \tcode{struct B::x} + using A::x; // OK, does not conflict with previous \tcode{using A::x} + x = 99; // assigns to \tcode{A::x} + struct x x1; // \tcode{x1} has class type \tcode{B::x} +} +\end{codeblock} +\end{example} + +\pnum +\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, +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 { + virtual void f(int); + virtual void f(char); + void g(int); + void h(int); + void i(); + void j(); +}; + +struct D : B { + using B::f; + void f(int); // OK, \tcode{D::f(int)} overrides \tcode{B::f(int)}; + + using B::g; + void g(char); // OK + + 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) +{ + p->f(1); // calls \tcode{D::f(int)} + 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 { + B1(int); +}; + +struct B2 { + B2(int); +}; + +struct D1 : B1, B2 { + using B1::B1; + using B2::B2; +}; +D1 d1(0); // error: ambiguous + +struct D2 : B1, B2 { + using B1::B1; + using B2::B2; + D2(int); // OK, \tcode{D2::D2(int)} hides \tcode{B1::B1(int)} and \tcode{B2::B2(int)} +}; +D2 d2(0); // calls \tcode{D2::D2(int)} \end{codeblock} -\exitnote +\end{example} \pnum -\indextext{overloading!using directive and}% -During overload resolution, all functions from the transitive search are -considered for argument matching. The set of declarations found by the -transitive search is unordered. -\enternote -In particular, the order in which namespaces were considered and the -relationships among the namespaces implied by the -\grammarterm{using-directive}{s} do not cause preference to be given to any -of the declarations found by the search. -\exitnote -An ambiguity exists if the best match finds two functions with the same -signature, even if one is in a namespace reachable through -\grammarterm{using-directive}{s} in the namespace of the other.\footnote{During -name lookup in a class hierarchy, some ambiguities may be -resolved by considering whether one member hides the other along some -paths~(\ref{class.member.lookup}). There is no such disambiguation when -considering the set of names found as a result of following -\grammarterm{using-directive}{s}.} -\enterexample +\indextext{overloading!using-declaration and}% +\begin{note} +For the purpose of forming a set of candidates during overload resolution, +the functions +named by a \grammarterm{using-declaration} in a derived class +are treated as though they were direct members of the derived class. In +particular, the implicit object parameter is treated as if +it were a reference to the derived class rather than to the base class\iref{over.match.funcs}. +This has no effect on the type of the function, and in all other +respects the function remains part of the base class. +\end{note} -\begin{codeblock} -namespace D { - int d1; - void f(char); -} -using namespace D; +\pnum +Constructors that are named by a \grammarterm{using-declaration} +are treated as though they were constructors of the derived class +when looking up the constructors of the derived class\iref{class.qual} +or forming a set of overload candidates\iref{over.match.ctor,over.match.copy,over.match.list}. +\begin{note} +If such a constructor is selected to perform the initialization +of an object of class type, all subobjects other than the base class +from which the constructor originated +are implicitly initialized\iref{class.inhctor.init}. +A constructor of a derived class is sometimes preferred to a constructor of a base class +if they would otherwise be ambiguous\iref{over.match.best}. +\end{note} -int d1; // OK: no conflict with \tcode{D::d1} +\pnum +\indextext{access control!using-declaration and}% +In a \grammarterm{using-declarator} that does not name a constructor, +every declaration named shall be accessible. +In a \grammarterm{using-declarator} that names a constructor, +no access check is performed. -namespace E { - int e; - void f(int); -} +\pnum +\begin{note} +Because a \grammarterm{using-declarator} designates a base class member +(and not a member subobject or a member function of a base class +subobject), a \grammarterm{using-declarator} cannot be used to resolve +inherited member ambiguities. +\begin{example} +\begin{codeblock} +struct A { int x(); }; +struct B : A { }; +struct C : A { + using A::x; + int x(int); +}; -namespace D { // namespace extension - int d2; - using namespace E; - void f(int); +struct D : B, C { + using C::x; + int x(double); +}; +int f(D* d) { + return d->x(); // error: overload resolution selects \tcode{A::x}, but \tcode{A} is an ambiguous base class } +\end{codeblock} +\end{example} +\end{note} -void f() { - d1++; // error: ambiguous \tcode{::d1} or \tcode{D::d1}? - ::d1++; // OK - D::d1++; // OK - d2++; // OK: \tcode{D::d2} - e++; // OK: \tcode{E::e} - f(1); // error: ambiguous: \tcode{D::f(int)} or \tcode{E::f(int)}? - f('a'); // OK: \tcode{D::f(char)} -} +\pnum +A \grammarterm{using-declaration} has the usual +accessibility for a \grammarterm{member-declaration}. +Base-class constructors considered because of a \grammarterm{using-declarator} +are accessible if they would be accessible +when used to construct an object of the base class; +the accessibility of the \grammarterm{using-declaration} is ignored. +\begin{example} +\begin{codeblock} +class A { +private: + void f(char); +public: + void f(int); +protected: + void g(); +}; + +class B : public A { + using A::f; // error: \tcode{A::f(char)} is inaccessible +public: + using A::g; // \tcode{B::g} is a public synonym for \tcode{A::g} +}; \end{codeblock} -\exitexample% -\indextext{using-directive|)}% -\indextext{namespaces|)} +\end{example} + +\indextext{using-declaration|)} \rSec1[dcl.asm]{The \tcode{asm} declaration}% \indextext{declaration!\idxcode{asm}}% @@ -3121,39 +9144,42 @@ \pnum An \tcode{asm} declaration has the form - \begin{bnf} -\nontermdef{asm-definition}\br - \terminal{asm (} string-literal \terminal{) ;} +\nontermdef{asm-declaration}\br + \opt{attribute-specifier-seq} \keyword{asm} \terminal{(} balanced-token-seq \terminal{)} \terminal{;} \end{bnf} -The \tcode{asm} declaration is conditionally-supported; its meaning is -\impldef{meaning of \tcode{asm} declaration}. -\enternote +The \tcode{asm} declaration is conditionally-supported; +any restrictions on the \grammarterm{balanced-token-seq} and +its meaning are \impldef{meaning of \tcode{asm} declaration}. +The optional \grammarterm{attribute-specifier-seq} in +an \grammarterm{asm-declaration} appertains to the \tcode{asm} declaration. +\begin{note} Typically it is used to pass information through the implementation to an assembler. -\exitnote +\end{note} \rSec1[dcl.link]{Linkage specifications}% \indextext{specification!linkage|(} \pnum -All function types, function names with external linkage, and variable -names with external linkage have a \term{language linkage}. -\enternote +All functions and variables whose names have external linkage +and all function types +have a \defn{language linkage}. +\begin{note} Some of the properties associated with an entity with language linkage are specific to each implementation and are not described here. For -example, a particular language linkage may be associated with a +example, a particular language linkage might be associated with a particular form of representing names of objects and functions with external linkage, or with a particular calling convention, etc. -\exitnote -The default language linkage of all function types, function names, and -variable names is \Cpp language linkage. Two function types with +\end{note} +The default language linkage of all function types, functions, and +variables is \Cpp{} language linkage. Two function types with different language linkages are distinct types even if they are otherwise identical. \pnum -Linkage~(\ref{basic.link}) between \Cpp and non-\Cpp code fragments can +Linkage\iref{basic.link} between \Cpp{} and non-\Cpp{} code fragments can be achieved using a \grammarterm{linkage-specification}: \indextext{\idxgram{linkage-specification}}% @@ -3161,197 +9187,172 @@ % \begin{bnf} \nontermdef{linkage-specification}\br - \terminal{extern} string-literal \terminal{\{} declaration-seq\opt \terminal{\}}\br - \terminal{extern} string-literal declaration -\end{bnf} - -The \grammarterm{string-literal} indicates the required language linkage. -This International Standard specifies the semantics for the -\grammarterm{string-literal}{s} \tcode{"C"} and \tcode{"C++"}. Use of a -\grammarterm{string-literal} other than \tcode{"C"} or \tcode{"C++"} is -conditionally-supported, with \impldef{semantics of linkage specifiers} semantics. -\enternote -Therefore, a linkage-specification with a \grammarterm{string-literal} that -is unknown to the implementation requires a diagnostic. -\exitnote -\enternote -It is recommended that the spelling of the \grammarterm{string-literal} be -taken from the document defining that language. For example, \tcode{Ada} -(not \tcode{ADA}) and \tcode{Fortran} or \tcode{FORTRAN}, depending on -the vintage. -\exitnote + \keyword{extern} unevaluated-string \terminal{\{} \opt{declaration-seq} \terminal{\}}\br + \keyword{extern} unevaluated-string name-declaration +\end{bnf} + +The \grammarterm{unevaluated-string} indicates the required language linkage. +\begin{note} +Escape sequences and \grammarterm{universal-character-name}s +have been replaced\iref{lex.string.uneval}. +\end{note} +This document specifies the semantics for the +\grammarterm{unevaluated-string}{s} \tcode{"C"} and \tcode{"C++"}. +Use of an \grammarterm{unevaluated-string} +other than \tcode{"C"} or \tcode{"C++"} is conditionally-supported, +with \impldef{semantics of linkage specifiers} semantics. +\begin{note} +Therefore, a \grammarterm{linkage-specification} with a language linkage +that is unknown to the implementation requires a diagnostic. +\end{note} + +\recommended +The spelling of the language linkage should be taken +from the document defining that language. +For example, \tcode{Ada} (not \tcode{ADA}) and +\tcode{Fortran} or \tcode{FORTRAN}, depending on the vintage. \pnum \indextext{specification!linkage!implementation-defined}% -Every implementation shall provide for linkage to functions written in -the C programming language, -\indextext{C!linkage~to}% -\tcode{"C"}, and linkage to \Cpp functions, \tcode{"C++"}. -\enterexample - +Every implementation shall provide for linkage to the C programming language, +\indextext{C!linkage to}% +\tcode{"C"}, and \Cpp{}, \tcode{"C++"}. +\begin{example} \begin{codeblock} -complex sqrt(complex); // \Cpp linkage by default +complex sqrt(complex); // \Cpp{} language linkage by default extern "C" { - double sqrt(double); // C linkage + double sqrt(double); // C language linkage } \end{codeblock} -\exitexample +\end{example} + +\pnum +A \grammarterm{module-import-declaration} appearing in +a linkage specification with other than \Cpp{} language linkage +is conditionally-supported with +\impldef{support for \grammarterm{module-import-declaration}s +with non-\Cpp{} language linkage} semantics. \pnum \indextext{specification!linkage!nesting}% Linkage specifications nest. When linkage specifications nest, the -innermost one determines the language linkage. A linkage specification -does not establish a scope. A \grammarterm{linkage-specification} shall -occur only in namespace scope~(\ref{basic.scope}). In a -\grammarterm{linkage-specification}, the specified language linkage applies -to the function types of all function declarators, function names with -external linkage, and variable names with external linkage declared -within the \grammarterm{linkage-specification}. -\enterexample - -\begin{codeblock} -extern "C" void f1(void(*pf)(int)); - // the name \tcode{f1} and its function type have C language - // linkage; \tcode{pf} is a pointer to a C function +innermost one determines the language linkage. +\begin{note} +A linkage specification does not establish a scope. +\end{note} +A \grammarterm{linkage-specification} shall inhabit a namespace scope. +In a \grammarterm{linkage-specification}, +the specified language linkage applies +to the function types of all function declarators and +to all functions and variables whose names have external linkage. +\begin{example} +\begin{codeblock} +extern "C" // \tcode{f1} and its function type have C language linkage; + void f1(void(*pf)(int)); // \tcode{pf} is a pointer to a C function + extern "C" typedef void FUNC(); -FUNC f2; // the name \tcode{f2} has \Cpp language linkage and the - // function's type has C language linkage -extern "C" FUNC f3; // the name of function \tcode{f3} and the function's type - // have C language linkage -void (*pf2)(FUNC*); // the name of the variable \tcode{pf2} has \Cpp linkage and - // the type of \tcode{pf2} is pointer to \Cpp function that - // takes one parameter of type pointer to C function +FUNC f2; // \tcode{f2} has \Cpp{} language linkage and + // its type has C language linkage + +extern "C" FUNC f3; // \tcode{f3} and its type have C language linkage + +void (*pf2)(FUNC*); // the variable \tcode{pf2} has \Cpp{} language linkage; its type + // is ``pointer to \Cpp{} function that takes one parameter of type + // pointer to C function'' extern "C" { - static void f4(); // the name of the function f4 has - // internal linkage (not C language - // linkage) and the function's type - // has C language linkage. + static void f4(); // the name of the function \tcode{f4} has internal linkage, + // so \tcode{f4} has no language linkage; its type has C language linkage } extern "C" void f5() { - extern void f4(); // OK: Name linkage (internal) - // and function type linkage (C - // language linkage) obtained from - // previous declaration. + extern void f4(); // OK, name linkage (internal) and function type linkage (C language linkage) + // obtained from previous declaration. } -extern void f4(); // OK: Name linkage (internal) - // and function type linkage (C - // language linkage) obtained from - // previous declaration. +extern void f4(); // OK, name linkage (internal) and function type linkage (C language linkage) + // obtained from previous declaration. void f6() { - extern void f4(); // OK: Name linkage (internal) - // and function type linkage (C - // language linkage) obtained from - // previous declaration. + extern void f4(); // OK, name linkage (internal) and function type linkage (C language linkage) + // obtained from previous declaration. } \end{codeblock} -\exitexample -\indextext{class!linkage~specification}% +\end{example} +\indextext{class!linkage specification}% A C language linkage is ignored in determining the language linkage of -the names of class members and the -function type of class member functions. -\enterexample - +class members, +friend functions with a trailing \grammarterm{requires-clause}, and the +function type of non-static class member functions. +\begin{example} \begin{codeblock} extern "C" typedef void FUNC_c(); + class C { - void mf1(FUNC_c*); // the name of the function \tcode{mf1} and the member - // function's type have \Cpp language linkage; the - // parameter has type pointer to C function - FUNC_c mf2; // the name of the function \tcode{mf2} and the member - // function's type have \Cpp language linkage - static FUNC_c* q; // the name of the data member \tcode{q} has \Cpp language - // linkage and the data member's type is pointer to - // C function + void mf1(FUNC_c*); // the function \tcode{mf1} and its type have \Cpp{} language linkage; + // the parameter has type ``pointer to C function'' + + FUNC_c mf2; // the function \tcode{mf2} and its type have \Cpp{} language linkage + + static FUNC_c* q; // the data member \tcode{q} has \Cpp{} language linkage; + // its type is ``pointer to C function'' }; extern "C" { class X { - void mf(); // the name of the function \tcode{mf} and the member - // function's type have \Cpp language linkage - void mf2(void(*)()); // the name of the function \tcode{mf2} has \Cpp language - // linkage; the parameter has type pointer to - // C function + void mf(); // the function \tcode{mf} and its type have \Cpp{} language linkage + void mf2(void(*)()); // the function \tcode{mf2} has \Cpp{} language linkage; + // the parameter has type ``pointer to C function'' }; } \end{codeblock} -\exitexample - -\pnum -If two declarations declare functions with the same name and -\grammarterm{parameter-type-list}~(\ref{dcl.fct}) to be members of the same -namespace or declare objects with the same name to be members of the same -namespace and the declarations give the names different language linkages, the -program is ill-formed; no diagnostic is required if the declarations appear in -different translation units. -\indextext{consistency!linkage~specification}% -Except for functions with \Cpp linkage, a function declaration without a -linkage specification shall not precede the first linkage specification -for that function. A function can be declared without a linkage -specification after an explicit linkage specification has been seen; the -linkage explicitly specified in the earlier declaration is not affected -by such a function declaration. - -\pnum -\indextext{function!linkage~specification overloaded}% -At most one function with a particular name can have C language linkage. -Two declarations for a function with C language linkage with the same -function name (ignoring the namespace names that qualify it) that appear -in different namespace scopes refer to the same function. Two -declarations for a variable with C language linkage with the same name -(ignoring the namespace names that qualify it) that appear in different -namespace scopes refer to the same variable. -An entity with C language linkage shall not be declared with the same name -as a variable in global scope, unless both declarations denote the same entity; -no diagnostic is required if the declarations appear in different translation units. -A variable with C language linkage shall not be declared with the same name as a -function with C language linkage (ignoring the namespace names that qualify the -respective names); no diagnostic is required if the declarations appear in -different translation units. -\enternote -Only -one definition for an entity with a given name -with C language linkage may appear in the -program (see~\ref{basic.def.odr}); -this implies that such an entity -must not be defined in more -than one namespace scope.\exitnote -\enterexample +\end{example} + +\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. +\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. +\pnum +\indextext{function!linkage specification overloaded}% +Two declarations declare the same entity +if they (re)introduce the same name, +one declares a function or variable with C language linkage, +and the other declares such an entity or declares a variable +that belongs to the global scope. +\begin{example} \begin{codeblock} int x; namespace A { extern "C" int f(); extern "C" int g() { return 1; } extern "C" int h(); - extern "C" int x(); // ill-formed: same name as global-space object \tcode{x} + extern "C" int x(); // error: same name as global-space object \tcode{x} } namespace B { extern "C" int f(); // \tcode{A::f} and \tcode{B::f} refer to the same function - extern "C" int g() { return 1; } // ill-formed, the function \tcode{g} - // with C language linkage has two definitions + extern "C" int g() { return 1; } // error: the function \tcode{g} with C language linkage has two definitions } -int A::f() { return 98; } //definition for the function \tcode{f} with C language linkage +int A::f() { return 98; } // definition for the function \tcode{f} with C language linkage extern "C" int h() { return 97; } // definition for the function \tcode{h} with C language linkage // \tcode{A::h} and \tcode{::h} refer to the same function \end{codeblock} -\exitexample +\end{example} \pnum A declaration directly contained in a \grammarterm{linkage-specification} is treated as if it contains the -\tcode{extern} -specifier~(\ref{dcl.stc}) for the purpose of determining the linkage of the +\keyword{extern} +specifier\iref{dcl.stc} for the purpose of determining the linkage of the declared name and whether it is a definition. Such a declaration shall -not specify a storage class. -\enterexample - +not have a \grammarterm{storage-class-specifier}. +\begin{example} \begin{codeblock} extern "C" double f(); static double f(); // error @@ -3361,20 +9362,20 @@ } extern "C" static void g(); // error \end{codeblock} -\exitexample +\end{example} \pnum -\enternote +\begin{note} Because the language linkage is part of a function type, when indirecting through a pointer to C function, the function to which the resulting lvalue refers is considered a C function. -\exitnote +\end{note} \pnum -\indextext{object!linkage~specification}% +\indextext{object!linkage specification}% \indextext{linkage!implementation-defined object}% -Linkage from \Cpp to objects defined in other languages and to objects -defined in \Cpp from other languages is implemen\-tation-defined and +Linkage from \Cpp{} to entities defined in other languages and to entities +defined in \Cpp{} from other languages is \impldef{linkage of entities between \Cpp{} and other languages} and language-dependent. Only where the object layout strategies of two language implementations are similar enough can such linkage be achieved.% @@ -3387,37 +9388,54 @@ \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 - attribute-specifier-seq\opt attribute-specifier + attribute-specifier \opt{attribute-specifier-seq} \end{bnf} \begin{bnf} \nontermdef{attribute-specifier}\br - \terminal{[} \terminal{[} attribute-list \terminal{]} \terminal{]}\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 - \terminal{alignas (} type-id \terminal{...}\opt \terminal{)}\br - \terminal{alignas (} constant-expression \terminal{...}\opt \terminal{)} + \keyword{alignas} \terminal{(} type-id \opt{\terminal{...}} \terminal{)}\br + \keyword{alignas} \terminal{(} constant-expression \opt{\terminal{...}} \terminal{)} +\end{bnf} + +\begin{bnf} +\nontermdef{attribute-using-prefix}\br + \keyword{using} attribute-namespace \terminal{:} \end{bnf} \begin{bnf} \nontermdef{attribute-list}\br - attribute\opt\br - attribute-list \terminal{,} attribute\opt\br + \opt{attribute}\br + attribute-list \terminal{,} \opt{attribute}\br attribute \terminal{...}\br 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 attribute-argument-clause\opt + attribute-token \opt{attribute-argument-clause} +\end{bnf} + +\begin{bnf} +\nontermdef{annotation}\br + \terminal{=} constant-expression \end{bnf} \begin{bnf} @@ -3438,132 +9456,194 @@ \begin{bnf} \nontermdef{attribute-argument-clause}\br - \terminal{(} balanced-token-seq \terminal{)} + \terminal{(} \opt{balanced-token-seq} \terminal{)} \end{bnf} \begin{bnf} \nontermdef{balanced-token-seq}\br - balanced-token\opt\br - balanced-token-seq balanced-token + balanced-token \opt{balanced-token-seq} \end{bnf} \begin{bnf} +\microtypesetup{protrusion=false} \nontermdef{balanced-token}\br - \terminal{(} balanced-token-seq \terminal{)}\br - \terminal{[} balanced-token-seq \terminal{]}\br - \terminal{\{} 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 + \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 \terminal{(}, \terminal{)}, \terminal{[}, \terminal{]}, \terminal{\{}, \terminal{\}}, \terminal{[:}, or \terminal{:]}} \end{bnf} \pnum -\enternote For each individual attribute, the form of the -\grammarterm{balanced-token-seq} will be specified. \exitnote +If an \grammarterm{attribute-specifier} +contains an \grammarterm{attribute-using-prefix}, +the \grammarterm{attribute-list} following that \grammarterm{attribute-using-prefix} +shall not contain an \grammarterm{attribute-scoped-token} +and every \grammarterm{attribute-token} in that \grammarterm{attribute-list} +is treated as if +its \grammarterm{identifier} were prefixed with \tcode{N::}, +where \tcode{N} is the \grammarterm{attribute-namespace} +specified in the \grammarterm{attribute-using-prefix}. +\begin{note} +This rule imposes no constraints on how +an \grammarterm{attribute-using-prefix} +affects the tokens in an \grammarterm{attribute-argument-clause}. +\end{note} +\begin{example} +\begin{codeblock} +[[using CC: opt(1), debug]] // same as \tcode{[[CC::opt(1), CC::debug]]} + void f() {} +[[using CC: opt(1)]] [[CC::debug]] // same as \tcode{[[CC::opt(1)]] [[CC::debug]]} + void g() {} +[[using CC: CC::opt(1)]] // error: cannot combine \tcode{using} and scoped attribute token + void h() {} +\end{codeblock} +\end{example} + +\pnum +\begin{note} +For each individual attribute, the form of the +\grammarterm{balanced-token-seq} will be specified. +\end{note} \pnum 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~(\ref{temp.variadic}). -An \grammarterm{attribute-specifier} that contains no \grammarterm{attribute}{s} has no -effect. The order in which the \grammarterm{attribute-tokens} appear in an +by an ellipsis is a pack expansion\iref{temp.variadic}. +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~(\ref{lex.key}) -or an alternative token~(\ref{lex.digraph}) that satisfies the syntactic requirements -of an \grammarterm{identifier}~(\ref{lex.name}) is +keyword\iref{lex.key} +or an alternative token\iref{lex.digraph} that satisfies the syntactic requirements +of an \grammarterm{identifier}\iref{lex.name} is contained in an \grammarterm{attribute-token}, it is considered an identifier. No name -lookup~(\ref{basic.lookup}) is performed on any of the identifiers contained in an +lookup\iref{basic.lookup} is performed on any of the identifiers contained in an \grammarterm{attribute-token}. The \grammarterm{attribute-token} determines additional -requirements on the \grammarterm{attribute-argument-clause} (if any). The use of an -\grammarterm{attribute-scoped-token} is conditionally-supported, with -\impldef{behavior of attribute scoped token} behavior. \enternote Each implementation -should choose a distinctive name for the \grammarterm{attribute-namespace} in an -\grammarterm{attribute-scoped-token}. \exitnote +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 -(Clause~\ref{stmt.stmt}, Clause~\ref{dcl.dcl}, -Clause~\ref{dcl.decl}). If an \grammarterm{attribute-specifier-seq} that appertains to some -entity or statement contains an \grammarterm{attribute} that +statement, identified by the syntactic context +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 entity or statement, the program is ill-formed. If an \grammarterm{attribute-specifier-seq} -appertains to a friend declaration~(\ref{class.friend}), that declaration shall be a -definition. No \grammarterm{attribute-specifier-seq} shall appertain to an explicit -instantiation~(\ref{temp.explicit}). - -\pnum -For an \grammarterm{attribute-token} not specified in this International Standard, the -behavior is \impldef{behavior of non-standard attributes}. +appertains to a friend declaration\iref{class.friend}, that declaration shall be a +definition. +\begin{note} +An \grammarterm{attribute-specifier-seq} cannot appertain to +an explicit instantiation\iref{temp.explicit}. +\end{note} + +\pnum +For an \grammarterm{attribute-token} +(including an \grammarterm{attribute-scoped-token}) +not specified in this document, the +behavior is \impldef{behavior of non-standard attributes}; +any such \grammarterm{attribute-token} that is not recognized by the implementation +is ignored. +\begin{note} +A program is ill-formed if it contains an \grammarterm{attribute} +specified in \ref{dcl.attr} that violates +the rules specifying to which entity or statement the attribute can apply or +the syntax rules for the attribute's \grammarterm{attribute-argument-clause}, if any. +\end{note} +\begin{note} +The \grammarterm{attribute}{s} specified in \ref{dcl.attr} +have optional semantics: +given a well-formed program, +removing all instances of any one of those \grammarterm{attribute}{s} +results in a program whose set of possible executions\iref{intro.abstract} +for a given input is +a subset of those of the original program for the same input, +absent implementation-defined guarantees +with respect to that \grammarterm{attribute}. +\end{note} +An \grammarterm{attribute-token} is reserved for future standardization if +\begin{itemize} +\item it is not an \grammarterm{attribute-scoped-token} and +is not specified in this document, or +\item it is an \grammarterm{attribute-scoped-token} and +its \grammarterm{attribute-namespace} is +\tcode{std} followed by zero or more digits. +\end{itemize} +Each implementation should choose a distinctive name for the +\grammarterm{attribute-namespace} in an \grammarterm{attribute-scoped-token}. \pnum -Two consecutive left square bracket tokens shall appear only when introducing an -\grammarterm{attribute-specifier}. \enternote If two consecutive left square brackets appear +Two consecutive left square bracket tokens shall appear only +when introducing an \grammarterm{attribute-specifier} or +within the \grammarterm{balanced-token-seq} of +an \grammarterm{attribute-argument-clause}. +\begin{note} +If two consecutive left square brackets appear where an \grammarterm{attribute-specifier} is not allowed, the program is ill-formed even -if the brackets match an alternative grammar production. \exitnote \enterexample +if the brackets match an alternative grammar production. +\end{note} +\begin{example} \begin{codeblock} int p[10]; void f() { int x = 42, y[5]; - int(p[[x] { return x; }()]); // error: invalid attribute on a nested - // \grammarterm{declarator-id} and not a function-style cast of - // an element of \tcode{p}. - y[[] { return 2; }()] = 2; // error even though attributes are not allowed - // in this context. + int(p[[x] { return x; }()]); // error: invalid attribute on a nested \grammarterm{declarator-id} and + // not a function-style cast of an element of \tcode{p}. + y[[] { return 2; }()] = 2; // error even though attributes are not allowed in this context. + int i [[vendor::attr([[]])]]; // well-formed implementation-defined attribute. } \end{codeblock} -\exitexample +\end{example} \rSec2[dcl.align]{Alignment specifier}% \indextext{attribute!alignment} +\indextext{\idxcode{alignas}} \pnum An \grammarterm{alignment-specifier} may be applied to a variable or to a class data member, but it shall not be applied to a bit-field, a function -parameter, an \grammarterm{exception-declaration}~(\ref{except.handle}), or a variable -declared with the \tcode{register} storage class specifier. -An \grammarterm{alignment-specifier} may also be applied to the declaration or -definition of a class (in an -\grammarterm{elaborated-type-specifier}~(\ref{dcl.type.elab}) or -\grammarterm{class-head} (Clause~\ref{class}), respectively) and to the -declaration or definition of an enumeration (in an -\grammarterm{opaque-enum-declaration} or \grammarterm{enum-head}, -respectively~(\ref{dcl.enum})). -An \grammarterm{alignment-specifier} with an ellipsis is a pack expansion~(\ref{temp.variadic}). +parameter, or an \grammarterm{exception-declaration}\iref{except.handle}. +An \grammarterm{alignment-specifier} may also be applied to the declaration +of a class (in an +\grammarterm{elaborated-type-specifier}\iref{dcl.type.elab} or +\grammarterm{class-head}\iref{class}, respectively). +An \grammarterm{alignment-specifier} with an ellipsis is a pack expansion\iref{temp.variadic}. \pnum When the \grammarterm{alignment-specifier} is of the form \tcode{alignas(} \grammarterm{constant-expression} \tcode{)}: - \begin{itemize} \item the \grammarterm{constant-expression} shall be an integral constant expression -\item if the constant expression evaluates to a fundamental alignment, -the alignment requirement of the declared entity shall be the specified -fundamental alignment - -\item if the constant expression evaluates to an extended alignment and -the implementation supports that alignment in the context of the declaration, -the alignment of the declared entity shall be that alignment - -\item if the constant expression evaluates to an extended alignment and +\item if the constant expression does not evaluate to an alignment +value\iref{basic.align}, or evaluates to an extended alignment and the implementation does not support that alignment in the context of the -declaration, the program is ill-formed - -\item if the constant expression evaluates to zero, the alignment specifier -shall have no effect - -\item otherwise, the program is ill-formed. +declaration, the program is ill-formed. \end{itemize} \pnum -When the \grammarterm{alignment-specifier}{} is of the form -\tcode{alignas(} \grammarterm{type-id} \tcode{)}, it shall have the same -effect as \tcode{alignas(\brk{}alignof(}\grammarterm{type-id}\tcode{))}~(\ref{expr.alignof}). +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}. \pnum -When multiple \grammarterm{alignment-specifier}{s} are specified for an entity, the -alignment requirement shall be set to the strictest specified alignment. +The alignment requirement of an entity is the strictest nonzero alignment +specified by its \grammarterm{alignment-specifier}{s}, if any; +otherwise, the \grammarterm{alignment-specifier}{s} have no effect. \pnum The combined effect of all \grammarterm{alignment-specifier}{s} in a declaration shall not @@ -3571,15 +9651,14 @@ be required for the entity being declared if all \grammarterm{alignment-specifier}{s} appertaining to that entity were omitted. -\enterexample +\begin{example} \begin{codeblock} struct alignas(8) S {}; struct alignas(1) U { S s; -}; // Error: \tcode{U} specifies an alignment that is less strict than - // if the \tcode{alignas(1)} were omitted. +}; // error: \tcode{U} specifies an alignment that is less strict than if the \tcode{alignas(1)} were omitted. \end{codeblock} -\exitexample +\end{example} \pnum If the defining declaration of an entity has an @@ -3593,200 +9672,657 @@ No diagnostic is required if declarations of an entity have different \grammarterm{alignment-specifier}{s} in different translation units. - -\enterexample +\begin{example} \begin{codeblock} // Translation unit \#1: -struct S { int x; } s, p = &s; +struct S { int x; } s, *p = &s; // Translation unit \#2: -struct alignas(16) S; // error: definition of \tcode{S} lacks alignment; no -extern S* p; // diagnostic required +struct alignas(16) S; // ill-formed, no diagnostic required: definition of \tcode{S} lacks alignment +extern S* p; \end{codeblock} -\exitexample +\end{example} \pnum -\enterexample An aligned buffer with an alignment requirement -of \tcode{A} and holding \tcode{N} elements of type \tcode{T} other than -\tcode{char}, \tcode{signed char}, or \tcode{unsigned char} +\begin{example} +An aligned buffer with an alignment requirement +of \tcode{A} and holding \tcode{N} elements of type \tcode{T} can be declared as: - \begin{codeblock} alignas(T) alignas(A) T buffer[N]; \end{codeblock} Specifying \tcode{alignas(T)} ensures that the final requested alignment will not be weaker than \tcode{alignof(T)}, and therefore the program will not be ill-formed. -\exitexample +\end{example} \pnum -\enterexample +\begin{example} \begin{codeblock} -alignas(double) void f(); // error: alignment applied to function -alignas(double) unsigned char c[sizeof(double)]; // array of characters, suitably aligned for a \tcode{double} -extern unsigned char c[sizeof(double)]; // no \tcode{alignas} necessary +alignas(double) void f(); // error: alignment applied to function +alignas(double) unsigned char c[sizeof(double)]; // array of characters, suitably aligned for a \tcode{double} +extern unsigned char c[sizeof(double)]; // no \tcode{alignas} necessary alignas(float) - extern unsigned char c[sizeof(double)]; // error: different alignment in declaration + extern unsigned char c[sizeof(double)]; // error: different alignment in declaration \end{codeblock} -\exitexample +\end{example} -\rSec2[dcl.attr.noreturn]{Noreturn attribute}% -\indextext{attribute!noreturn} +\rSec2[dcl.attr.assume]{Assumption attribute} \pnum -The \grammarterm{attribute-token} \tcode{noreturn} specifies that a function does not return. It -shall appear at most once in each \grammarterm{attribute-list} and no -\grammarterm{attribute-argument-clause} shall be present. The attribute may be applied to the -\grammarterm{declarator-id} in a function declaration. The first declaration of a function shall -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. +The \grammarterm{attribute-token} \tcode{assume} may be applied to a null statement; +such a statement is an \defn{assumption}. +An \grammarterm{attribute-argument-clause} shall be present and +shall have the form: +\begin{ncsimplebnf} +\terminal{(} conditional-expression \terminal{)} +\end{ncsimplebnf} +The expression is contextually converted to \tcode{bool}\iref{conv.general}. +The expression is not evaluated. +If the converted expression would evaluate to \tcode{true} +at the point where the assumption appears, +the assumption has no effect. +Otherwise, +evaluation of the assumption has runtime-undefined behavior. \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. \enternote The function may -terminate by throwing an exception. \exitnote \enternote Implementations are encouraged to issue a -warning if a function marked \tcode{[[noreturn]]} might return. \exitnote +\begin{note} +The expression is potentially evaluated\iref{basic.def.odr}. +The use of assumptions is intended to allow implementations +to analyze the form of the expression and +deduce information used to optimize the program. +Implementations are not required to deduce +any information from any particular assumption. +It is expected that the value of +a \grammarterm{has-attribute-expression} for the \tcode{assume} attribute +is \tcode{0} +if an implementation does not attempt to deduce +any such information from assumptions. +\end{note} \pnum -\enterexample +\begin{example} \begin{codeblock} -[[ noreturn ]] void f() { - throw "error"; // OK +int divide_by_32(int x) { + [[assume(x >= 0)]]; + return x/32; // The instructions produced for the division + // may omit handling of negative values. } - -[[ noreturn ]] void q(int i) { // behavior is undefined if called with an argument \tcode{<= 0} - if (i > 0) - throw "positive"; +int f(int y) { + [[assume(++y == 43)]]; // \tcode{y} is not incremented + return y; // statement may be replaced with \tcode{return 42;} } \end{codeblock} -\exitexample +\end{example} -\rSec2[dcl.attr.depend]{Carries dependency attribute}% -\indextext{attribute!carries dependency} +\rSec2[dcl.attr.deprecated]{Deprecated attribute}% +\indextext{attribute!deprecated} \pnum -The \grammarterm{attribute-token} \tcode{carries_dependency} specifies -dependency propagation into and out of functions. It shall appear at most once -in each \grammarterm{attribute-list} and no -\grammarterm{attribute-argument-clause} shall be present. The attribute may be -applied to the \grammarterm{declarator-id} of a -\grammarterm{parameter-declaration} in a function declaration or lambda, in -which case it specifies that the initialization of the parameter carries a -dependency to~(\ref{intro.multithread}) each lvalue-to-rvalue -conversion~(\ref{conv.lval}) of that object. The attribute may also be applied -to the \grammarterm{declarator-id} of a function declaration, in which case it -specifies that the return value, if any, carries a dependency to the evaluation -of the function call expression. +The \grammarterm{attribute-token} \tcode{deprecated} can be used to mark names and entities +whose use is still allowed, but is discouraged for some reason. +\begin{note} +In particular, +\tcode{deprecated} is appropriate for names and entities that are deemed obsolescent or +unsafe. +\end{note} +An +\grammarterm{attribute-argument-clause} may be present and, if present, it shall have the form: +\begin{ncbnf} +\terminal{(} unevaluated-string \terminal{)} +\end{ncbnf} +\begin{note} +The \grammarterm{unevaluated-string} in the \grammarterm{attribute-argument-clause} +can be used to explain the rationale for deprecation and/or to suggest a replacing entity. +\end{note} \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. +The attribute may be applied to the declaration of +a class, +a type alias, +a variable, +a non-static data member, +a function, +a namespace, +an enumeration, +an enumerator, +a concept, or +a template specialization. \pnum -\enternote The \tcode{carries_dependency} attribute does not change the meaning of the -program, but may result in generation of more efficient code. \exitnote +An entity declared without the \tcode{deprecated} attribute can later be redeclared +with the attribute and vice-versa. +\begin{note} +Thus, an entity initially declared without the +attribute can be marked as deprecated by a subsequent redeclaration. However, after an entity +is marked as deprecated, later redeclarations do not un-deprecate the entity. +\end{note} +Redeclarations using different forms of the attribute (with or without the +\grammarterm{attribute-argument-clause} or with different +\grammarterm{attribute-argument-clause}{s}) are allowed. \pnum -\enterexample +\recommended +Implementations should use the \tcode{deprecated} attribute to produce a diagnostic +message in case the program refers to a name or entity other than to declare it, after a +declaration that specifies the attribute. The diagnostic message should include the text provided +within the \grammarterm{attribute-argument-clause} of any \tcode{deprecated} attribute applied +to the name or entity. +The value of +a \grammarterm{has-attribute-expression} for the \tcode{deprecated} attribute +should be \tcode{0} +unless the implementation can issue such diagnostic messages. + +\rSec2[dcl.attr.fallthrough]{Fallthrough attribute} +\indextext{attribute!fallthrough} + +\pnum +The \grammarterm{attribute-token} \tcode{fallthrough} +may be applied to a null statement\iref{stmt.expr}; +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}. +The next statement that would be executed after a fallthrough statement +shall be a labeled statement whose label is a case label or +default label for the same \keyword{switch} statement and, +if the fallthrough statement is contained in an iteration statement, +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 +The use of a fallthrough statement should suppress +a warning that an implementation might otherwise issue +for a case or default label that is reachable +from another case or default label along some path of execution. +The value of +a \grammarterm{has-attribute-expression} for the \tcode{fallthrough} attribute +should be \tcode{0} +if the attribute does not cause suppression of such warnings. +Implementations should issue a warning +if a fallthrough statement is not dynamically reachable. + +\pnum +\begin{example} \begin{codeblock} -/* Translation unit A. */ +void f(int n) { + void g(), h(), i(); + switch (n) { + case 1: + case 2: + g(); + [[fallthrough]]; + case 3: // warning on fallthrough discouraged + do { + [[fallthrough]]; // error: next statement is not part of the same substatement execution + } while (false); + case 6: + do { + [[fallthrough]]; // error: next statement is not part of the same substatement execution + } while (n--); + case 7: + while (false) { + [[fallthrough]]; // error: next statement is not part of the same substatement execution + } + case 5: + h(); + case 4: // implementation may warn on fallthrough + i(); + [[fallthrough]]; // error + } +} +\end{codeblock} +\end{example} + +\rSec2[dcl.attr.indet]{Indeterminate storage} +\indextext{attribute!indeterminate} + +\pnum +The \grammarterm{attribute-token} \tcode{indeterminate} may be applied +to the definition of a block variable with automatic storage duration or +to a \grammarterm{parameter-declaration} of a function declaration. +No \grammarterm{attribute-argument-clause} shall be present. +The attribute specifies +that the storage of an object with automatic storage duration +is initially indeterminate rather than erroneous\iref{basic.indet}. + +\pnum +If a function parameter is declared with the \tcode{indeterminate} attribute, +it shall be so declared in the first declaration of its function. +If a function parameter is declared with +the \tcode{indeterminate} attribute in the first declaration of its function +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. -struct foo { int* a; int* b; }; -std::atomic foo_head[10]; -int foo_array[10][10]; +\pnum +\begin{note} +Reading from an uninitialized variable +that is marked \tcode{[[indeterminate]]} can cause undefined behavior. +\begin{codeblock} +void f(int); +void g() { + int x [[indeterminate]], y; + f(y); // erroneous behavior\iref{basic.indet} + f(x); // undefined behavior +} -[[carries_dependency]] struct foo* f(int i) { - return foo_head[i].load(memory_order_consume); +struct T { + T() {} + int x; +}; +int h(T t [[indeterminate]]) { + f(t.x); // undefined behavior when called below + return 0; } +int _ = h(T()); +\end{codeblock} +\end{note} + +\rSec2[dcl.attr.likelihood]{Likelihood attributes}% +\indextext{attribute!likely} +\indextext{attribute!unlikely} + +\pnum +The \grammarterm{attribute-token}s +\tcode{likely} and \tcode{unlikely} +may be applied to labels or statements. +No \grammarterm{attribute-argument-clause} shall be present. +The \grammarterm{attribute-token} \tcode{likely} +shall not appear in an \grammarterm{attribute-specifier-seq} +that contains the \grammarterm{attribute-token} \tcode{unlikely}. + +\pnum +\begin{note} +The use of the \tcode{likely} attribute +is intended to allow implementations to optimize for +the case where paths of execution including it +are arbitrarily more likely +than any alternative path of execution +that does not include such an attribute on a statement or label. +The use of the \tcode{unlikely} attribute +is intended to allow implementations to optimize for +the case where paths of execution including it +are arbitrarily more unlikely +than any alternative path of execution +that does not include such an attribute on a statement or label. +It is expected that the value of a \grammarterm{has-attribute-expression} +for the \tcode{likely} and \tcode{unlikely} attributes +is \tcode{0} +if the implementation does not attempt to use these attributes +for such optimizations. +A path of execution includes a label +if and only if it contains a jump to that label. +\end{note} +\begin{note} +Excessive usage of either of these attributes +is liable to result in performance degradation. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +void g(int); +int f(int n) { + if (n > 5) [[unlikely]] { // \tcode{n > 5} is considered to be arbitrarily unlikely + g(0); + return n * 2 + 1; + } + + switch (n) { + case 1: + g(1); + [[fallthrough]]; -int g(int* x, int* y [[carries_dependency]]) { - return kill_dependency(foo_array[*x][*y]); + [[likely]] case 2: // \tcode{n == 2} is considered to be arbitrarily more + g(2); // likely than any other value of \tcode{n} + break; + } + return 3; } +\end{codeblock} +\end{example} + +\rSec2[dcl.attr.unused]{Maybe unused attribute}% +\indextext{attribute!maybe unused} + +\pnum +The \grammarterm{attribute-token} \tcode{maybe_unused} +indicates that a name, label, or entity is possibly intentionally unused. +No \grammarterm{attribute-argument-clause} shall be present. -/* Translation unit B. */ +\pnum +The attribute may be applied to the declaration of a class, +type alias, +variable (including a structured binding declaration), +structured binding, +result binding\iref{dcl.contract.res}, +non-static data member, +function, +enumeration, or +enumerator, or +to an \grammarterm{identifier} label\iref{stmt.label}. -[[carries_dependency]] struct foo* f(int i); -int g(int* x, int* y [[carries_dependency]]); +\pnum +A name or entity declared without the \tcode{maybe_unused} attribute +can later be redeclared with the attribute +and vice versa. +An entity is considered marked +after the first declaration that marks it. -int c = 3; +\pnum +\recommended +For an entity marked \tcode{maybe_unused}, +implementations should not emit a warning +that the entity or its structured bindings (if any) +are used or unused. +For a structured binding declaration not marked \tcode{maybe_unused}, +implementations should not emit such a warning unless +all of its structured bindings are unused. +For a label to which \tcode{maybe_unused} is applied, +implementations should not emit a warning that the label is used or unused. +The value of +a \grammarterm{has-attribute-expression} for the \tcode{maybe_unused} attribute +should be \tcode{0} +if the attribute does not cause suppression of such warnings. -void h(int i) { - struct foo* p; +\pnum +\begin{example} +\begin{codeblock} +[[maybe_unused]] void f([[maybe_unused]] bool thing1, + [[maybe_unused]] bool thing2) { + [[maybe_unused]] bool b = thing1 && thing2; + assert(b); +#ifdef NDEBUG + goto x; +#endif + [[maybe_unused]] x: +} +\end{codeblock} +Implementations should not warn that \tcode{b} or \tcode{x} is unused, +whether or not \tcode{NDEBUG} is defined. +\end{example} + +\rSec2[dcl.attr.nodiscard]{Nodiscard attribute}% +\indextext{attribute!nodiscard} + +\pnum +The \grammarterm{attribute-token} \tcode{nodiscard} +may be applied to a function or a lambda call operator or +to the declaration of a class or enumeration. +An \grammarterm{attribute-argument-clause} may be present +and, if present, shall have the form: + +\begin{ncbnf} +\terminal{(} unevaluated-string \terminal{)} +\end{ncbnf} + +\pnum +A name or entity declared without the \tcode{nodiscard} attribute +can later be redeclared with the attribute and vice-versa. +\begin{note} +Thus, an entity initially declared without the attribute +can be marked as \tcode{nodiscard} +by a subsequent redeclaration. +However, after an entity is marked as \tcode{nodiscard}, +later redeclarations do not remove the \tcode{nodiscard} +from the entity. +\end{note} +Redeclarations using different forms of the attribute +(with or without the \grammarterm{attribute-argument-clause} +or with different \grammarterm{attribute-argument-clause}s) +are allowed. + +\pnum +A \defnadj{nodiscard}{type} is +a (possibly cv-qualified) class or enumeration type +marked \tcode{nodiscard} in a reachable declaration. +A \defnadj{nodiscard}{call} is either +\begin{itemize} +\item + a function call expression\iref{expr.call} + that calls a function declared \tcode{nodiscard} in a reachable declaration or + whose return type is a nodiscard type, or +\item + an explicit type + conversion\iref{expr.type.conv,expr.static.cast,expr.cast} + that constructs an object through + a constructor declared \tcode{nodiscard} in a reachable declaration, or + that initializes an object of a nodiscard type. +\end{itemize} - p = f(i); - do_something_with(g(&c, p->a)); - do_something_with(g(p->a, &c)); +\pnum +\recommended +Appearance of a nodiscard call as +a potentially evaluated discarded-value expression\iref{expr.prop} +of non-void type +is discouraged unless explicitly cast to \keyword{void}. +Implementations should issue a warning in such cases. +The value of +a \grammarterm{has-attribute-expression} for the \tcode{nodiscard} attribute +should be \tcode{0} unless the implementation can issue such warnings. +\begin{note} +This is typically because discarding the return value +of a nodiscard call has surprising consequences. +\end{note} +The \grammarterm{unevaluated-string} +in a \tcode{nodiscard} \grammarterm{attribute-argument-clause} +should be used in the message of the warning +as the rationale for why the result should not be discarded. + +\pnum +\begin{example} +\begin{codeblock} +struct [[nodiscard]] my_scopeguard { @\commentellip@ }; +struct my_unique { + my_unique() = default; // does not acquire resource + [[nodiscard]] my_unique(int fd) { @\commentellip@ } // acquires resource + ~my_unique() noexcept { @\commentellip@ } // releases resource, if any + @\commentellip@ +}; +struct [[nodiscard]] error_info { @\commentellip@ }; +error_info enable_missile_safety_mode(); +void launch_missiles(); +void test_missiles() { + my_scopeguard(); // warning encouraged + (void)my_scopeguard(), // warning not encouraged, cast to \keyword{void} + launch_missiles(); // comma operator, statement continues + my_unique(42); // warning encouraged + my_unique(); // warning not encouraged + enable_missile_safety_mode(); // warning encouraged + launch_missiles(); } +error_info &foo(); +void f() { foo(); } // warning not encouraged: not a nodiscard call, because neither + // the (reference) return type nor the function is declared nodiscard \end{codeblock} +\end{example} + +\rSec2[dcl.attr.noreturn]{Noreturn attribute}% +\indextext{attribute!noreturn} \pnum -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). +The \grammarterm{attribute-token} \tcode{noreturn} specifies that a function does not return. +No \grammarterm{attribute-argument-clause} shall be present. +The attribute may be applied to a function or a lambda call operator. +The first declaration of a function shall +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. \pnum -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}. +If a function \tcode{f} is invoked where \tcode{f} was previously declared with the \tcode{noreturn} +attribute and that invocation eventually returns, +the behavior is runtime-undefined. +\begin{note} +The function can +terminate by throwing an exception. +\end{note} -\exitexample% -\indextext{attribute|)}% -\indextext{declaration|)} +\pnum +\recommended +Implementations should issue a +warning if a function marked \tcode{[[noreturn]]} might return. +The value of +a \grammarterm{has-attribute-expression} for the \tcode{noreturn} attribute +should be \tcode{0} unless the implementation can issue such warnings. -\rSec2[dcl.attr.deprecated]{Deprecated attribute}% -\indextext{attribute!deprecated} +\pnum +\begin{example} +\begin{codeblock} +[[ noreturn ]] void f() { + throw "error"; // OK +} + +[[ noreturn ]] void q(int i) { // behavior is undefined if called with an argument \tcode{<= 0} + if (i > 0) + throw "positive"; +} +\end{codeblock} +\end{example} + +\rSec2[dcl.attr.nouniqueaddr]{No unique address attribute}% +\indextext{attribute!no unique address} \pnum -The \grammarterm{attribute-token} \tcode{deprecated} can be used to mark names and entities -whose use is still allowed, but is discouraged for some reason. \enternote in particular, -\tcode{deprecated} is appropriate for names and entities that are deemed obsolescent or -unsafe. \exitnote It shall appear at most once in each \grammarterm{attribute-list}. An -\grammarterm{attribute-argument-clause} may be present and, if present, it shall have the form: +The \grammarterm{attribute-token} \tcode{no_unique_address} +specifies that a non-static data member +is a potentially-overlapping subobject\iref{intro.object}. +No \grammarterm{attribute-argument-clause} shall be present. +The attribute may appertain to a non-static data member +other than a bit-field. + +\pnum +\begin{note} +The non-static data member can share the address of +another non-static data member or that of a base class, +and any padding that would normally be inserted +at the end of the object +can be reused as storage for other members. +\end{note} + +\recommended +The value of a \grammarterm{has-attribute-expression} +for the \tcode{no_unique_address} attribute +should be \tcode{0} for a given implementation +unless this attribute can cause a potentially-overlapping subobject +to have zero size. +\begin{example} +\begin{codeblock} +template +class hash_map { + [[no_unique_address]] Hash hasher; + [[no_unique_address]] Pred pred; + [[no_unique_address]] Allocator alloc; + Bucket *buckets; + // ... +public: + // ... +}; +\end{codeblock} +Here, \tcode{hasher}, \tcode{pred}, and \tcode{alloc} +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} -( @\grammarterm{string-literal}@ ) +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} -\enternote the \grammarterm{string-literal} in the \grammarterm{attribute-argument-clause} -could be used to explain the rationale for deprecation and/or to suggest a replacing entity. -\exitnote +\end{example} +\end{note} \pnum -The attribute may be applied to the declaration of -a class, -a \grammarterm{typedef-name}, -a variable, -a non-static data member, -a function, -a namespace, -an enumeration, -an enumerator, or -a template specialization. +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 -A name or entity declared without the \tcode{deprecated} attribute can later be re-declared -with the attribute and vice-versa. \enternote Thus, an entity initially declared without the -attribute can be marked as deprecated by a subsequent redeclaration. However, after an entity -is marked as deprecated, later redeclarations do not un-deprecate the entity. \exitnote -Redeclarations using different forms of the attribute (with or without the -\grammarterm{attribute-argument-clause} or with different -\grammarterm{attribute-argument-clause}{s}) are allowed. +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 -\enternote Implementations may use the \tcode{deprecated }attribute to produce a diagnostic -message in case the program refers to a name or entity other than to declare it, after a -declaration that specifies the attribute. The diagnostic message may include the text provided -within the \grammarterm{attribute-argument-clause} of any \tcode{deprecated} attribute applied -to the name or entity. \exitnote +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/declarators.tex b/source/declarators.tex deleted file mode 100644 index 14566135cd..0000000000 --- a/source/declarators.tex +++ /dev/null @@ -1,3884 +0,0 @@ -%!TEX root = std.tex -\rSec0[dcl.decl]{Declarators}% -\indextext{declarator|(} - -%gram: \rSec1[gram.decl]{Declarators} -%gram: - -\indextext{initialization!class~object|seealso{constructor}}% -\indextext{\idxcode{*}|see{declarator, pointer}} -\indextext{\idxcode{\&}|see{declarator, reference}}% -\indextext{\idxcode{::*}|see{declarator, pointer to member}}% -\indextext{\idxcode{[]}|see{declarator, array}}% -\indextext{\idxcode{()}|see{declarator, function}}% - -\pnum -A declarator declares a single variable, function, or type, within a declaration. -The -\grammarterm{init-declarator-list} -appearing in a declaration -is a comma-separated sequence of declarators, -each of which can have an initializer. - -\begin{bnf} -\nontermdef{init-declarator-list}\br - init-declarator\br - init-declarator-list \terminal{,} init-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{init-declarator}\br - declarator initializer\opt -\end{bnf} - -\pnum -The three components of a -\grammarterm{simple-declaration} -are the -attributes~(\ref{dcl.attr}), the -specifiers -(\grammarterm{decl-specifier-seq}; -\ref{dcl.spec}) and the declarators -(\grammarterm{init-declarator-list}). -The specifiers indicate the type, storage class or other properties of -the entities being declared. -The declarators specify the names of these entities -and (optionally) modify the type of the specifiers with operators such as -\tcode{*} -(pointer -to) -and -\tcode{()} -(function returning). -Initial values can also be specified in a declarator; -initializers are discussed in~\ref{dcl.init} and~\ref{class.init}. - -\pnum -Each -\grammarterm{init-declarator} -in a declaration is analyzed separately as if it was in a declaration by -itself.\footnote{A declaration with several declarators is usually equivalent -to the corresponding sequence of declarations each with a single declarator. -That is - -\tcode{T D1, D2, ... Dn;} - -\noindent is usually equivalent to - -\tcode{T D1; T D2; ... T Dn;} - -\noindent where -\tcode{T} -is a -\grammarterm{decl-specifier-seq} -and each -\tcode{Di} -is an -\grammarterm{init-declarator}. -An exception occurs when a name introduced by one of the -\grammarterm{declarator}{s} -hides a type name used by the -\grammarterm{decl-specifiers}, -so that when the same -\grammarterm{decl-specifiers} -are used in a subsequent declaration, they do not have the same meaning, -as in - -\tcode{struct S { ... };}\\ -\indent\tcode{S S, T; \textrm{// declare two instances of \tcode{struct S}}} - -\noindent which is not equivalent to - -\tcode{struct S { ... };}\\ -\indent\tcode{S S;}\\ -\indent\tcode{S T; \textrm{// error}} - -\noindent Another exception occurs when \tcode{T} is \tcode{auto}~(\ref{dcl.spec.auto}), -for example: - -\tcode{auto i = 1, j = 2.0; \textrm{// error: deduced types for \tcode{i} and \tcode{j} do not match}}\\ -\noindent as opposed to\\ -\indent\tcode{auto i = 1; \textrm{// OK: \tcode{i} deduced to have type \tcode{int}}}\\ -\indent\tcode{auto j = 2.0; \textrm{// OK: \tcode{j} deduced to have type \tcode{double}}} -} - -\pnum -Declarators have the syntax - -\begin{bnf} -\nontermdef{declarator}\br - ptr-declarator\br - noptr-declarator parameters-and-qualifiers trailing-return-type -\end{bnf} - -\begin{bnf} -\nontermdef{ptr-declarator}\br - noptr-declarator\br - ptr-operator ptr-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{noptr-declarator}\br - declarator-id attribute-specifier-seq\opt\br - noptr-declarator parameters-and-qualifiers\br - noptr-declarator \terminal{[} constant-expression\opt \terminal{]} attribute-specifier-seq\opt\br - \terminal{(} ptr-declarator \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{parameters-and-qualifiers}\br - \terminal{(} parameter-declaration-clause \terminal{)} cv-qualifier-seq\opt\br -\hspace*{\bnfindentinc}ref-qualifier\opt exception-specification\opt attribute-specifier-seq\opt -\end{bnf} - -\begin{bnf} -\nontermdef{trailing-return-type}\br - \terminal{->} trailing-type-specifier-seq abstract-declarator\opt -\end{bnf} - -\begin{bnf} -\nontermdef{ptr-operator}\br - \terminal{*} attribute-specifier-seq\opt cv-qualifier-seq\opt\br - \terminal{\&} attribute-specifier-seq\opt\br - \terminal{\&\&} attribute-specifier-seq\opt\br - nested-name-specifier \terminal{*} attribute-specifier-seq\opt cv-qualifier-seq\opt -\end{bnf} - -\begin{bnf} -\nontermdef{cv-qualifier-seq}\br - cv-qualifier cv-qualifier-seq\opt -\end{bnf} - -\begin{bnf} -\nontermdef{cv-qualifier}\br - \terminal{const}\br - \terminal{volatile} -\end{bnf} - -\begin{bnf} -\nontermdef{ref-qualifier}\br - \terminal{\&}\br - \terminal{\&\&} -\end{bnf} - -\begin{bnf} -\nontermdef{declarator-id}\br - \terminal{...}\opt id-expression -\end{bnf} - -\pnum -The optional \grammarterm{attribute-specifier-seq} in a -\grammarterm{trailing-return-type} appertains to the indicated return type. The -\grammarterm{type-id} in a \grammarterm{trailing-return-type} includes the longest -possible sequence of \grammarterm{abstract-declarator}{s}. \enternote This resolves the -ambiguous binding of array and function declarators. \enterexample - -\begin{codeblock} -auto f()->int(*)[4]; // function returning a pointer to array[4] of \tcode{int} - // not function returning array[4] of pointer to \tcode{int} -\end{codeblock} -\exitexample \exitnote - -\rSec1[dcl.name]{Type names} - -\pnum -\indextext{type~name}% -To specify type conversions explicitly, -\indextext{operator!cast}% -and as an argument of -\tcode{sizeof}, -\tcode{alignof}, -\tcode{new}, -or -\tcode{typeid}, -the name of a type shall be specified. -This can be done with a -\grammarterm{type-id}, -which is syntactically a declaration for a variable or function -of that type that omits the name of the entity. - -\begin{bnf} -\nontermdef{type-id}\br - type-specifier-seq abstract-declarator\opt -\end{bnf} - -\begin{bnf} -\nontermdef{abstract-declarator}\br - ptr-abstract-declarator\br - noptr-abstract-declarator\opt parameters-and-qualifiers trailing-return-type\br - abstract-pack-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{ptr-abstract-declarator}\br - noptr-abstract-declarator\br - ptr-operator ptr-abstract-declarator\opt -\end{bnf} - -\begin{bnf} -\nontermdef{noptr-abstract-declarator}\br - noptr-abstract-declarator\opt parameters-and-qualifiers\br - noptr-abstract-declarator\opt \terminal{[} constant-expression\opt{} \terminal{]} attribute-specifier-seq\opt\br - \terminal{(} ptr-abstract-declarator \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{abstract-pack-declarator}\br - noptr-abstract-pack-declarator\br - ptr-operator abstract-pack-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{noptr-abstract-pack-declarator}\br - noptr-abstract-pack-declarator parameters-and-qualifiers\br - noptr-abstract-pack-declarator \terminal{[} constant-expression\opt\ \terminal{]} attribute-specifier-seq\opt\br - \terminal{...} -\end{bnf} - -It is possible to identify uniquely the location in the -\grammarterm{abstract-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 -hypothetical identifier. -\enterexample - -\indextext{example!type~name}% -\indextext{example!declarator}% -\begin{codeblock} -int // \tcode{int i} -int * // \tcode{int *pi} -int *[3] // \tcode{int *p[3]} -int (*)[3] // \tcode{int (*p3i)[3]} -int *() // \tcode{int *f()} -int (*)(double) // \tcode{int (*pf)(double)} -\end{codeblock} - -name respectively the types -``\tcode{int},'' -``pointer to -\tcode{int},'' -``array of 3 pointers to -\tcode{int},'' -``pointer to array of 3 -\tcode{int},'' -``function of (no parameters) returning pointer to -\tcode{int},'' -and ``pointer to a function of -(\tcode{double}) -returning -\tcode{int}.'' -\exitexample - -\pnum -A type can also be named (often more easily) by using a -\grammarterm{typedef} -(\ref{dcl.typedef}). - -\rSec1[dcl.ambig.res]{Ambiguity resolution}% -\indextext{ambiguity!declaration~versus cast}% -\indextext{declaration!parentheses~in} - -\pnum -The ambiguity arising from the similarity between a function-style cast and -a declaration mentioned in~\ref{stmt.ambig} can also occur in the context of a declaration. -In that context, the choice is between a function declaration with -a redundant set of parentheses around a parameter name and an object declaration -with a function-style cast as the initializer. -Just as for the ambiguities mentioned in~\ref{stmt.ambig}, -the resolution is to consider any construct that could possibly -be a declaration a declaration. -\enternote -A declaration can be explicitly disambiguated by a nonfunction-style -cast, by an -\tcode{=} -to indicate initialization or -by removing the redundant parentheses around the parameter name. -\exitnote -\enterexample - -\begin{codeblock} -struct S { - S(int); -}; - -void foo(double a) { - S w(int(a)); // function declaration - S x(int()); // function declaration - S y((int)a); // object declaration - S z = int(a); // object declaration -} -\end{codeblock} -\exitexample - -\pnum -The ambiguity arising from the similarity between a function-style -cast and a -\grammarterm{type-id} -can occur in different contexts. -The ambiguity appears as a choice between a function-style cast -expression and a declaration of a type. -The resolution is that any construct that could possibly be a -\grammarterm{type-id} -in its syntactic context shall be considered a -\grammarterm{type-id}. - -\pnum -\enterexample - -\begin{codeblock} -#include -char* p; -void* operator new(std::size_t, int); -void foo() { - const int x = 63; - new (int(*p)) int; // new-placement - new (int(*[x])); // parenthesized type-id -} -\end{codeblock} - -\pnum -For another example, - -\begin{codeblock} -template -struct S { - T* p; -}; -S x; // type-id -S y; // expression (ill-formed) -\end{codeblock} - -\pnum -For another example, - -\begin{codeblock} -void foo() { - sizeof(int(1)); // expression - sizeof(int()); // type-id (ill-formed) -} -\end{codeblock} - -\pnum -For another example, - -\begin{codeblock} -void foo() { - (int(1)); // expression - (int())1; // type-id (ill-formed) -} -\end{codeblock} -\exitexample - -\pnum -Another ambiguity arises in a -\grammarterm{parameter-declaration-clause} -of a function declaration, or in a -\grammarterm{type-id} -that is the operand of a -\tcode{sizeof} -or -\tcode{typeid} -operator, when a -\grammarterm{type-name} -is nested in parentheses. -In this case, the choice is between the declaration of a parameter of type -pointer to function and the declaration of a parameter with redundant -parentheses around the -\grammarterm{declarator-id}. -The resolution is to consider the -\grammarterm{type-name} -as a -\grammarterm{simple-type-specifier} -rather than a -\grammarterm{declarator-id}. -\enterexample - -\begin{codeblock} -class C { }; -void f(int(C)) { } // \tcode{void f(int(*fp)(C c)) \{ \}} - // not: \tcode{void f(int C)}; - -int g(C); - -void foo() { - f(1); // error: cannot convert \tcode{1} to function pointer - f(g); // OK -} -\end{codeblock} - -For another example, - -\begin{codeblock} -class C { }; -void h(int *(C[10])); // \tcode{void h(int *(*_fp)(C _parm[10]));} - // not: \tcode{void h(int *C[10]);} -\end{codeblock} -\exitexample - -\rSec1[dcl.meaning]{Meaning of declarators}% -\indextext{declarator!meaning~of|(} - -\pnum -A list of declarators appears after an optional (Clause~\ref{dcl.dcl}) -\grammarterm{decl-specifier-seq} -(\ref{dcl.spec}). -\indextext{declaration!type}% -Each declarator contains exactly one -\grammarterm{declarator-id}; -it names the identifier that is declared. -An -\grammarterm{unqualified-id} -occurring in -a -\grammarterm{declarator-id} -shall be a simple -\grammarterm{identifier} -except for the declaration of some special functions~(\ref{class.ctor}, -\ref{class.conv}, \ref{class.dtor}, \ref{over.oper}) and -for the declaration of template specializations -or partial specializations~(\ref{temp.spec}). -When the -\grammarterm{declarator-id} -is qualified, the declaration shall refer to a previously declared member -of the class or namespace to which the qualifier refers (or, -in the case of a namespace, -of an element of the inline namespace -set of that namespace~(\ref{namespace.def})) or to a specialization thereof; the member -shall not merely have been introduced by a -\grammarterm{using-declaration} -in the scope of the class or namespace nominated by the -\grammarterm{nested-name-specifier} -of the -\grammarterm{declarator-id}. -The \grammarterm{nested-name-specifier} of a qualified \grammarterm{declarator-id} shall not -begin with a \grammarterm{decltype-specifier}. -\enternote -If the qualifier is the global -\tcode{::} -scope resolution operator, the -\grammarterm{declarator-id} -refers to a name declared in the global namespace scope. -\exitnote -The optional \grammarterm{attribute-specifier-seq} following a \grammarterm{declarator-id} appertains to the entity that is declared. - -\pnum -A -\tcode{static}, -\tcode{thread_local}, -\tcode{extern}, -\tcode{register}, -\tcode{mutable}, -\tcode{friend}, -\tcode{inline}, -\tcode{virtual}, -or -\tcode{typedef} -specifier applies directly to each -\grammarterm{declarator-id} -in an -\grammarterm{init-declarator-list}; -the type specified for each -\grammarterm{declarator-id} -depends on both the -\grammarterm{decl-specifier-seq} -and its -\grammarterm{declarator}. - -\pnum -Thus, a declaration of a particular identifier has the form - -\begin{codeblock} -T D -\end{codeblock} - -where -\tcode{T} -is of the form \grammarterm{attribute-specifier-seq\opt} -\grammarterm{decl-specifier-seq} -and -\tcode{D} -is a declarator. -Following is a recursive procedure for determining -the type specified for the contained -\grammarterm{declarator-id} -by such a declaration. - -\pnum -First, the -\grammarterm{decl-specifier-seq} -determines a type. -In a declaration - -\begin{codeblock} -T D -\end{codeblock} - -the -\grammarterm{decl-specifier-seq} -\tcode{T} -determines the type -\tcode{T}. -\enterexample -in the declaration - -\begin{codeblock} -int unsigned i; -\end{codeblock} - -the type specifiers -\tcode{int} -\tcode{unsigned} -determine the type -``\tcode{unsigned int}'' -(\ref{dcl.type.simple}). -\exitexample - -\pnum -In a declaration -\grammarterm{attribute-specifier-seq\opt} -\tcode{T} -\tcode{D} -where -\tcode{D} -is an unadorned identifier the type of this identifier is -``\tcode{T}''. - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form - -\begin{ncsimplebnf} -( D1 ) -\end{ncsimplebnf} - -the type of the contained -\grammarterm{declarator-id} -is the same as that of the contained -\grammarterm{declarator-id} -in the declaration - -\begin{codeblock} -T D1 -\end{codeblock} - -\indextext{declaration!parentheses~in}% -Parentheses do not alter the type of the embedded -\grammarterm{declarator-id}, -but they can alter the binding of complex declarators. - -\rSec2[dcl.ptr]{Pointers}% -\indextext{declarator!pointer}% - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form - -\begin{ncsimplebnf} -\terminal{*} attribute-specifier-seq\opt cv-qualifier-seq\opt \terminal{D1} -\end{ncsimplebnf} - -and the type of the identifier in the declaration -\tcode{T} -\tcode{D1} -is ``\nonterminal{derived-declarator-type-list} -\tcode{T},'' -then the type of the identifier of -\tcode{D} -is ``\nonterminal{derived-declarator-type-list cv-qualifier-seq} pointer to -\tcode{T}.'' -\indextext{declaration!pointer}% -\indextext{declaration!constant~pointer}% -The -\grammarterm{cv-qualifier}{s} -apply to the pointer and not to the object pointed to. -Similarly, the optional \grammarterm{attribute-specifier-seq}~(\ref{dcl.attr.grammar}) appertains to the pointer and not to the object pointed to. - -\pnum -\enterexample -the declarations -\indextext{example!\idxcode{const}}% -\indextext{example!constant pointer}% -\begin{codeblock} -const int ci = 10, *pc = &ci, *const cpc = pc, **ppc; -int i, *p, *const cp = &i; -\end{codeblock} - -declare -\tcode{ci}, -a constant integer; -\tcode{pc}, -a pointer to a constant integer; -\tcode{cpc}, -a constant pointer to a constant integer; -\tcode{ppc}, -a pointer to a pointer to a constant integer; -\tcode{i}, -an integer; -\tcode{p}, -a pointer to integer; and -\tcode{cp}, -a constant pointer to integer. -The value of -\tcode{ci}, -\tcode{cpc}, -and -\tcode{cp} -cannot be changed after initialization. -The value of -\tcode{pc} -can be changed, and so can the object pointed to by -\tcode{cp}. -Examples of -some correct operations are - -\begin{codeblock} -i = ci; -*cp = ci; -pc++; -pc = cpc; -pc = p; -ppc = &pc; -\end{codeblock} - -Examples of ill-formed operations are - -\begin{codeblock} -ci = 1; // error -ci++; // error -*pc = 2; // error -cp = &ci; // error -cpc++; // error -p = pc; // error -ppc = &p; // error -\end{codeblock} - -Each is unacceptable because it would either change the value of an object declared -\tcode{const} -or allow it to be changed through a cv-unqualified pointer later, for example: - -\begin{codeblock} -*ppc = &ci; // OK, but would make \tcode{p} point to \tcode{ci} ... - // ... because of previous error -*p = 5; // clobber \tcode{ci} -\end{codeblock} -\exitexample - -\pnum -See also~\ref{expr.ass} and~\ref{dcl.init}. - -\pnum -\enternote -Forming a pointer to reference type is ill-formed; see~\ref{dcl.ref}. -Forming a pointer to function type is ill-formed if the function type has -\grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier}; -see~\ref{dcl.fct}. -Since the address of a bit-field (\ref{class.bit}) cannot be taken, -a pointer can never point to a bit-field. -\exitnote - -\rSec2[dcl.ref]{References}% -\indextext{declarator!reference} - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has either of the forms - -\begin{ncsimplebnf} -\terminal{\&} attribute-specifier-seq\opt \terminal{D1}\br -\terminal{\&\&} attribute-specifier-seq\opt \terminal{D1} -\end{ncsimplebnf} - -and the type of the identifier in the declaration -\tcode{T} -\tcode{D1} -is ``\nonterminal{derived-declarator-type-list} -\tcode{T},'' -then the type of the identifier of -\tcode{D} -is ``\nonterminal{derived-declarator-type-list} reference to -\tcode{T}.'' -The optional \grammarterm{attribute-specifier-seq} appertains to the reference type. -Cv-qualified references are ill-formed except when the cv-qualifiers -are introduced through the use of a -\grammarterm{typedef-name}~(\ref{dcl.typedef}, \ref{temp.param}) or -\grammarterm{decltype-specifier}~(\ref{dcl.type.simple}), -in which case the cv-qualifiers are ignored. -\enterexample - -\begin{codeblock} -typedef int& A; -const A aref = 3; // ill-formed; lvalue reference to non-\tcode{const} initialized with rvalue -\end{codeblock} - -The type of -\tcode{aref} -is ``lvalue reference to \tcode{int}'', -not ``lvalue reference to \tcode{const int}''. -\exitexample -\indextext{\idxcode{void\&}}% -\enternote -A reference can be thought of as a name of an object. -\exitnote -A declarator that specifies the type -``reference to \textit{cv} \tcode{void}'' -is ill-formed. - - -\pnum -\indextext{lvalue~reference}% -\indextext{rvalue~reference}% -A reference type that is declared using \tcode{\&} is called an -\term{lvalue reference}, and a reference type that -is declared using \tcode{\&\&} is called an -\term{rvalue reference}. Lvalue references and -rvalue references are distinct types. Except where explicitly noted, they are -semantically equivalent and commonly referred to as references. - -\pnum -\indextext{declaration!reference}% -\indextext{parameter!reference}% -\enterexample - -\begin{codeblock} -void f(double& a) { a += 3.14; } -// ... -double d = 0; -f(d); -\end{codeblock} - -declares -\tcode{a} -to be a reference parameter of -\tcode{f} -so the call -\tcode{f(d)} -will add -\tcode{3.14} -to -\tcode{d}. - -\begin{codeblock} -int v[20]; -// ... -int& g(int i) { return v[i]; } -// ... -g(3) = 7; -\end{codeblock} - -declares the function -\tcode{g()} -to return a reference to an integer so -\tcode{g(3)=7} -will assign -\tcode{7} -to the fourth element of the array -\tcode{v}. -For another example, - -\begin{codeblock} -struct link { - link* next; -}; - -link* first; - -void h(link*& p) { // \tcode{p} is a reference to pointer - p->next = first; - first = p; - p = 0; -} - -void k() { - link* q = new link; - h(q); -} -\end{codeblock} - -declares -\tcode{p} -to be a reference to a pointer to -\tcode{link} -so -\tcode{h(q)} -will leave -\tcode{q} -with the value zero. -See also~\ref{dcl.init.ref}. -\exitexample - -\pnum -It is unspecified whether or not -a reference requires storage (\ref{basic.stc}). - -\pnum -\indextext{restriction!reference}% -There shall be no references to references, -no arrays of references, and no pointers to references. -\indextext{initialization!reference}% -The declaration of a reference shall contain an -\grammarterm{initializer} -(\ref{dcl.init.ref}) -except when the declaration contains an explicit -\tcode{extern} -specifier (\ref{dcl.stc}), -is a class member (\ref{class.mem}) declaration within a class definition, -or is the declaration of a parameter or a return type (\ref{dcl.fct}); see~\ref{basic.def}. -A reference shall be initialized to refer to a valid object or function. -\enternote -\indextext{reference!null}% -in particular, a null reference cannot exist in a well-defined program, -because the only way to create such a reference would be to bind it to -the ``object'' obtained by indirection through a null pointer, -which causes undefined behavior. -As described in~\ref{class.bit}, a reference cannot be bound directly -to a bit-field. -\exitnote - -\pnum -\indextext{reference collapsing}% -If a \grammarterm{typedef-name}~(\ref{dcl.typedef}, \ref{temp.param}) -or a \grammarterm{decltype-specifier}~(\ref{dcl.type.simple}) denotes a type \tcode{TR} that -is a reference to a type \tcode{T}, an attempt to create the type ``lvalue reference to \cv\ -\tcode{TR}'' creates the type ``lvalue reference to \tcode{T}'', while an attempt to create -the type ``rvalue reference to \cv\ \tcode{TR}'' creates the type \tcode{TR}. \enterexample - -\begin{codeblock} -int i; -typedef int& LRI; -typedef int&& RRI; - -LRI& r1 = i; // \tcode{r1} has the type \tcode{int\&} -const LRI& r2 = i; // \tcode{r2} has the type \tcode{int\&} -const LRI&& r3 = i; // \tcode{r3} has the type \tcode{int\&} - -RRI& r4 = i; // \tcode{r4} has the type \tcode{int\&} -RRI&& r5 = 5; // \tcode{r5} has the type \tcode{int\&\&} - -decltype(r2)& r6 = i; // \tcode{r6} has the type \tcode{int\&} -decltype(r2)&& r7 = i; // \tcode{r7} has the type \tcode{int\&} -\end{codeblock} -\exitexample - -\pnum -\enternote Forming a reference to function type is ill-formed if the function -type has \grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier}; -see~\ref{dcl.fct}. -\exitnote - -\rSec2[dcl.mptr]{Pointers to members}% -\indextext{declarator!pointer to member} - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form - -\begin{ncsimplebnf} -nested-name-specifier \terminal{*} attribute-specifier-seq\opt cv-qualifier-seq\opt \tcode{D1} -\end{ncsimplebnf} - -and the -\grammarterm{nested-name-specifier} -denotes a class, -and the type of the identifier in the declaration -\tcode{T} -\tcode{D1} -is ``\nonterminal{derived-declarator-type-list} -\tcode{T}'', -then the type of the identifier of -\tcode{D} -is ``\nonterminal{derived-declarator-type-list cv-qualifier-seq} pointer to member of class -\nonterminal{nested-name-specifier} of type -\tcode{T}''. -The optional \grammarterm{attribute-specifier-seq}~(\ref{dcl.attr.grammar}) appertains to the -pointer-to-member. - -\pnum -\enterexample% -\indextext{example!pointer~to~member} - -\begin{codeblock} -struct X { - void f(int); - int a; -}; -struct Y; - -int X::* pmi = &X::a; -void (X::* pmf)(int) = &X::f; -double X::* pmd; -char Y::* pmc; -\end{codeblock} - -declares -\tcode{pmi}, -\tcode{pmf}, -\tcode{pmd} -and -\tcode{pmc} -to be a pointer to a member of -\tcode{X} -of type -\tcode{int}, -a pointer to a member of -\tcode{X} -of type -\tcode{void(int)}, -a pointer to a member of -\tcode{X} -of type -\tcode{double} -and a pointer to a member of -\tcode{Y} -of type -\tcode{char} -respectively. -The declaration of -\tcode{pmd} -is well-formed even though -\tcode{X} -has no members of type -\tcode{double}. -Similarly, the declaration of -\tcode{pmc} -is well-formed even though -\tcode{Y} -is an incomplete type. -\tcode{pmi} -and -\tcode{pmf} -can be used like this: - -\begin{codeblock} -X obj; -// ... -obj.*pmi = 7; // assign \tcode{7} to an integer - // member of \tcode{obj} -(obj.*pmf)(7); // call a function member of \tcode{obj} - // with the argument \tcode{7} -\end{codeblock} -\exitexample - -\pnum -A pointer to member shall not point to a static member -of a class (\ref{class.static}), -a member with reference type, -or -``\textit{cv} -\tcode{void}.'' - -\enternote -See also~\ref{expr.unary} and~\ref{expr.mptr.oper}. -The type ``pointer to member'' is distinct from the type ``pointer'', -that is, a pointer to member is declared only by the pointer to member -declarator syntax, and never by the pointer declarator syntax. -There is no ``reference-to-member'' type in \Cpp. -\exitnote - -\rSec2[dcl.array]{Arrays}% -\indextext{declarator!array} - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form - -\begin{ncsimplebnf} -\terminal{D1 [} constant-expression\opt \terminal{]} attribute-specifier-seq\opt -\end{ncsimplebnf} - -and the type of the identifier in the declaration -\tcode{T} -\tcode{D1} -is -``\grammarterm{derived-declarator-type-list} -\tcode{T}'', -then the type of the identifier of -\tcode{D} -is an array type; if the type of the identifier of \tcode{D} -contains the \tcode{auto} \nonterminal{type-specifier}, -the program is ill-formed. -\tcode{T} -is called the array -\term{element type}; -this type shall not be a reference type, the (possibly cv-qualified) type -\tcode{void}, -a function type or an abstract class type. -\indextext{declaration!array}% -If the -\grammarterm{constant-expression} -(\ref{expr.const}) is present, it shall be a converted constant -expression of type \tcode{std\colcol{}size_t} and -its value shall be greater than zero. -The constant expression specifies the -\indextext{array!bound}% -\indextext{bound,~of~array}% -\term{bound} -of (number of elements in) the array. -If the value of the constant expression is -\tcode{N}, -the array has -\tcode{N} -elements numbered -\tcode{0} -to -\tcode{N-1}, -and the type of the identifier of -\tcode{D} -is ``\nonterminal{derived-declarator-type-list} array of -\tcode{N} -\tcode{T}''. -An object of array type contains a contiguously allocated non-empty set of -\tcode{N} -subobjects of type -\tcode{T}. -Except as noted below, if -the constant expression is omitted, the type of the identifier of -\tcode{D} -is ``\nonterminal{derived-declarator-type-list} array of unknown bound of -\tcode{T}'', -an incomplete object type. -The type ``\nonterminal{derived-declarator-type-list} array of -\tcode{N} -\tcode{T}'' -is a different type from the type -``\nonterminal{derived-declarator-type-list} array of unknown bound of -\tcode{T}'', -see~\ref{basic.types}. -Any type of the form -``\nonterminal{cv-qualifier-seq} array of -\tcode{N} -\tcode{T}'' -is adjusted to -``array of -\tcode{N} -\nonterminal{cv-qualifier-seq} -\tcode{T}'', -and similarly for -``array of unknown bound of -\tcode{T}''. -The optional \grammarterm{attribute-specifier-seq} appertains to the array. -\enterexample - -\begin{codeblock} -typedef int A[5], AA[2][3]; -typedef const A CA; // type is ``array of 5 \tcode{const int}'' -typedef const AA CAA; // type is ``array of 2 array of 3 \tcode{const int}'' -\end{codeblock} -\exitexample -\enternote -An -``array of -\tcode{N} -\nonterminal{cv-qualifier-seq} -\tcode{T}'' -has cv-qualified type; see~\ref{basic.type.qualifier}. -\exitnote - -\pnum -An array can be constructed from one of the fundamental types -(except -\tcode{void}), -from a pointer, -from a pointer to member, from a class, -from an enumeration type, -or from another array. - -\pnum -When several ``array of'' specifications are adjacent, a multidimensional -array is created; -only the first of -the constant expressions that specify the bounds -of the arrays may be omitted. -In addition to declarations in which an incomplete object type is allowed, -an array bound may be omitted in some cases in the declaration of a function -parameter~(\ref{dcl.fct}). -An array bound may -also be omitted -when the declarator is followed by an -\grammarterm{initializer} -(\ref{dcl.init}). -In this case the bound is calculated from the number -\indextext{array~size!default}% -of initial elements (say, -\tcode{N}) -supplied -(\ref{dcl.init.aggr}), and the type of the identifier of -\tcode{D} -is ``array of -\tcode{N} -\tcode{T}.'' -Furthermore, if there is a preceding declaration of the entity in the same -scope in which the bound was specified, 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. - -\pnum -\enterexample -\indextext{example!subscripting}% -\indextext{example!array}% -\begin{codeblock} -float fa[17], *afp[17]; -\end{codeblock} - -declares an array of -\tcode{float} -numbers and an array of -pointers to -\tcode{float} -numbers. -\indextext{declarator!multidimensional array}% -For another example, - -\begin{codeblock} -static int x3d[3][5][7]; -\end{codeblock} - -declares a static three-dimensional array of integers, -with rank $3 \times 5 \times 7$. -In complete detail, -\tcode{x3d} -is an array of three items; -each item is an array of five arrays; -each of the latter arrays is an array of seven -integers. -Any of the expressions -\tcode{x3d}, -\tcode{x3d[i]}, -\tcode{x3d[i][j]}, -\tcode{x3d[i][j][k]} -can reasonably appear in an expression. Finally, -\begin{codeblock} -extern int x[10]; -struct S { - static int y[10]; -}; - -int x[]; // OK: bound is 10 -int S::y[]; // OK: bound is 10 - -void f() { - extern int x[]; - int i = sizeof(x); // error: incomplete object type -} -\end{codeblock} -\exitexample - -\pnum -\enternote -conversions affecting expressions of array type are described in~\ref{conv.array}. -Objects of array types cannot be modified, see~\ref{basic.lval}. -\exitnote - -\pnum -\enternote -Except where it has been declared for a class (\ref{over.sub}), -the subscript operator -\tcode{[]} -is interpreted -in such a way that -\tcode{E1[E2]} -is identical to -\tcode{*((E1)+(E2))}. -Because of the conversion rules -that apply to -\tcode{+}, -if -\tcode{E1} -is an array and -\tcode{E2} -an integer, -then -\tcode{E1[E2]} -refers to the -\tcode{E2}-th -member of -\tcode{E1}. -Therefore, -despite its asymmetric -appearance, subscripting is a commutative operation. - -\pnum -A consistent rule is followed for -\indextext{array!multidimensional}% -multidimensional arrays. -If -\tcode{E} -is an -\textit{n}-dimensional -array -of rank -$i \times j \times \ldots \times k$, -then -\tcode{E} -appearing in an expression -that is subject to the array-to-pointer conversion~(\ref{conv.array}) -is converted to -a pointer to an $(n-1)$-dimensional -array with rank -$j \times \ldots \times k$. -If the -\tcode{*} -operator, either explicitly -or implicitly as a result of subscripting, -is applied to this pointer, -the result is the pointed-to $(n-1)$-dimensional array, -which itself is immediately converted into a pointer. - -\pnum -\enterexample -consider - -\begin{codeblock} -int x[3][5]; -\end{codeblock} - -Here -\tcode{x} -is a $3 \times 5$ array of integers. -When -\tcode{x} -appears in an expression, it is converted -to a pointer to (the first of three) five-membered arrays of integers. -In the expression -\tcode{x[i]} -which is equivalent to -\tcode{*(x+i)}, -\tcode{x} -is first converted to a pointer as described; -then -\tcode{x+i} -is converted to the type of -\tcode{x}, -which involves multiplying -\tcode{i} -by the -length of the object to which the pointer points, -namely five integer objects. -The results are added and indirection applied to -yield an array (of five integers), which in turn is converted to -a pointer to the first of the integers. -If there is another subscript the same argument applies -again; this time the result is an integer. -\exitexample -\exitnote - -\pnum -\enternote -It follows from all this that arrays in \Cpp are stored -row-wise (last subscript varies fastest) -\indextext{array!storage~of}% -and that the first subscript in the declaration helps determine -the amount of storage consumed by an array -but plays no other part in subscript calculations. -\exitnote - -\rSec2[dcl.fct]{Functions}% -\indextext{declarator!function|(} - -\pnum -\indextext{type!function}% -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form - -\begin{ncsimplebnf} -\terminal{D1 (} parameter-declaration-clause \terminal{)} cv-qualifier-seq\opt\br -\hspace*{\bnfindentinc}ref-qualifier\opt exception-specification\opt attribute-specifier-seq\opt -\end{ncsimplebnf} - -and the type of the contained -\grammarterm{declarator-id} -in the declaration -\tcode{T} -\tcode{D1} -is -``\grammarterm{derived-declarator-type-list} -\tcode{T}'', -the type of the -\grammarterm{declarator-id} -in -\tcode{D} -is ``\nonterminal{derived-declarator-type-list} function of -(\nonterminal{parameter-declaration-clause} ) -\nonterminal{cv-qualifier-seq\opt} \nonterminal{ref-qualifier\opt} returning -\tcode{T}''. -The optional \grammarterm{attribute-specifier-seq} appertains to the function type. - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form - -\begin{ncsimplebnf} -\terminal{D1 (} parameter-declaration-clause \terminal{)} cv-qualifier-seq\opt\br -\hspace*{\bnfindentinc}ref-qualifier\opt exception-specification\opt attribute-specifier-seq\opt trailing-return-type -\end{ncsimplebnf} - -and the type of the contained \grammarterm{declarator-id} in the declaration \tcode{T} -\tcode{D1} is ``\grammarterm{derived-declarator-type-list} \tcode{T}'', \tcode{T} shall -be the single \grammarterm{type-specifier} \tcode{auto}. The type of the -\grammarterm{declarator-id} in \tcode{D} is -``\grammarterm{derived-declarator-type-list} function of -(\grammarterm{parameter-declaration-clause}) \grammarterm{cv-qualifier-seq}\opt -\grammarterm{ref-qualifier}\opt returning \grammarterm{trailing-return-type}''. The -optional \grammarterm{attribute-specifier-seq} appertains to the function type. - -\pnum -\indextext{type!function}% -A type of either form is a \term{function type}.\footnote{As indicated by syntax, cv-qualifiers are a significant component in function return types.} - -\indextext{declaration!function}% -\begin{bnf} -\nontermdef{parameter-declaration-clause}\br -parameter-declaration-list\opt \terminal{...}\opt\br - parameter-declaration-list \terminal{, ...} -\end{bnf} - -\begin{bnf} -\nontermdef{parameter-declaration-list}\br - parameter-declaration\br - parameter-declaration-list \terminal{,} parameter-declaration -\end{bnf} - -\begin{bnf} -\nontermdef{parameter-declaration}\br - attribute-specifier-seq\opt decl-specifier-seq declarator\br - attribute-specifier-seq\opt decl-specifier-seq declarator \terminal{=} initializer-clause\br - attribute-specifier-seq\opt decl-specifier-seq abstract-declarator\opt\br - attribute-specifier-seq\opt decl-specifier-seq abstract-declarator\opt \terminal{=} initializer-clause -\end{bnf} - -The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{parameter-declaration} -appertains to the parameter. - -\pnum -\indextext{declaration!parameter}% -The -\grammarterm{parameter-declaration-clause} -determines the arguments that can be specified, and their processing, when the function is called. -\enternote -\indextext{conversion!argument}% -the -\grammarterm{parameter-declaration-clause} -is used to convert the arguments specified on the function call; -see~\ref{expr.call}. -\exitnote -\indextext{argument~list!empty}% -If the -\grammarterm{parameter-declaration-clause} -is empty, the function takes no arguments. -A parameter list consisting of a single unnamed parameter of -non-dependent type \tcode{void} is equivalent to an empty parameter -list. -\indextext{parameter!\idxcode{void}}% -Except for this special case, a parameter shall not have type \term{cv} -\tcode{void}. -If the -\grammarterm{parameter-declaration-clause} -\indextext{argument~type!unknown}% -\indextext{\idxcode{...}|see{ellipsis}}% -\indextext{declaration!ellipsis~in function}% -\indextext{argument~list!variable}% -\indextext{parameter~list!variable}% -terminates with an ellipsis or a function parameter -pack~(\ref{temp.variadic}), the number of arguments shall be equal -to or greater than the number of parameters that do not have a default -argument and are not function parameter packs. -Where syntactically correct and where ``\tcode{...}'' is not -part of an \grammarterm{abstract-declarator}, -``\tcode{, ...}'' -is synonymous with -``\tcode{...}''. -\enterexample -\indextext{example!ellipsis}% -\indextext{example!variable parameter~list}% -the declaration - -\begin{codeblock} -int printf(const char*, ...); -\end{codeblock} - -declares a function that can be called with varying numbers and types of arguments. - -\begin{codeblock} -printf("hello world"); -printf("a=%d b=%d", a, b); -\end{codeblock} - -However, the first argument must be of a type -that can be converted to a -\tcode{const} -\tcode{char*} -\exitexample -\enternote -The standard header -\tcode{} -\indextext{\idxhdr{cstdarg}}% -contains a mechanism for accessing arguments passed using the ellipsis -(see~\ref{expr.call} and~\ref{support.runtime}). -\exitnote - -\pnum -\indextext{overloading}% -\indextext{type!function}% -A single name can be used for several different functions in a single scope; -this is function overloading (Clause~\ref{over}). -All declarations for a function shall agree exactly -in both the return type and the parameter-type-list. -The type of a function is determined using the following rules. -The type of each parameter (including function parameter packs) is -determined from its own -\grammarterm{decl-specifier-seq} -and -\grammarterm{declarator}. -After determining the type of each parameter, any parameter of type ``array of -\indextext{array}% -\indextext{type!array}% -\tcode{T}'' -\indextext{function}% -\indextext{type!function}% -or ``function returning -\tcode{T}'' -is adjusted to be ``pointer to -\tcode{T}'' -or ``pointer to function returning -\tcode{T},'' -respectively. -After producing the list of parameter types, -any top-level -\grammarterm{cv-qualifier}{s} -modifying a parameter type are deleted -when forming the function type. -The resulting list of transformed parameter types -and the presence or absence of the ellipsis or a function parameter pack -is the function's -\grammarterm{parameter-type-list}. -\enternote This transformation does not affect the types of the parameters. -For example, \tcode{int(*)(const int p, decltype(p)*)} and -\tcode{int(*)(int, const int*)} are identical types. \exitnote - -\pnum -A function type with a \grammarterm{cv-qualifier-seq} or a -\grammarterm{ref-qualifier} (including a type named by -\grammarterm{typedef-name}~(\ref{dcl.typedef}, \ref{temp.param})) -shall appear only as: -\begin{itemize} -\item the function type for a non-static member function, - -\item the function type to which a pointer to member refers, - -\item the top-level function type of a function typedef declaration -or \grammarterm{alias-declaration}, - -\item the \grammarterm{type-id} in the default argument of a -\grammarterm{type-parameter}~(\ref{temp.param}), or - -\item the \grammarterm{type-id} of a \grammarterm{template-argument} for a -\grammarterm{type-parameter}~(\ref{temp.arg.type}). -\end{itemize} -\enterexample - -\begin{codeblock} -typedef int FIC(int) const; -FIC f; // ill-formed: does not declare a member function -struct S { - FIC f; // OK -}; -FIC S::*pm = &S::f; // OK -\end{codeblock} -\exitexample - -\pnum -The effect of a -\grammarterm{cv-qualifier-seq} -in a function declarator is not the same as -adding cv-qualification on top of the function type. -In the latter case, the cv-qualifiers are ignored. -\enternote a function type that has a \grammarterm{cv-qualifier-seq} is not a -cv-qualified type; there are no cv-qualified function types. \exitnote -\enterexample - -\begin{codeblock} -typedef void F(); -struct S { - const F f; // OK: equivalent to: \tcode{void f();} -}; -\end{codeblock} -\exitexample - -\pnum -The return type, the parameter-type-list, the \grammarterm{ref-qualifier}, and the -\grammarterm{cv-qualifier-seq}, -but not the default arguments (\ref{dcl.fct.default}) -or the exception specification (\ref{except.spec}), -are part of the function type. -\enternote -Function types are checked during the assignments and initializations of -pointers to functions, references to functions, and pointers to member functions. -\exitnote - -\pnum -\enterexample -\indextext{example!function declaration}% -the declaration - -\begin{codeblock} -int fseek(FILE*, long, int); -\end{codeblock} - -declares a function taking three arguments of the specified types, -and returning -\tcode{int} -(\ref{dcl.type}). -\exitexample - -\pnum -\indextext{function~return~type|see{return~type}}% -\indextext{return~type}% -Functions shall not have a return type of type array or function, -although they may have a return type of type pointer or reference to such things. -There shall be no arrays of functions, although there can be arrays of pointers -to functions. - -\pnum -Types shall not be defined in return or parameter types. -The type of a parameter or the return type for a function -definition shall not be an incomplete -(possibly cv-qualified) class type -in the context of the function definition -unless the function is -deleted~(\ref{dcl.fct.def.delete}). - -\pnum -\indextext{typedef!function}% -A typedef of function type may be used to declare a function but shall not be -used to define a function (\ref{dcl.fct.def}). -\enterexample - -\begin{codeblock} -typedef void F(); -F fv; // OK: equivalent to \tcode{void fv();} -F fv { } // ill-formed -void fv() { } // OK: definition of \tcode{fv} -\end{codeblock} -\exitexample - -\pnum -An identifier can optionally be provided as a parameter name; -if present in a function definition (\ref{dcl.fct.def}), it names a parameter. -\enternote -In particular, parameter names are also optional in function definitions -and names used for a parameter in different declarations and the definition -of a function need not be the same. -If a parameter name is present in a function declaration that is not a definition, -it cannot be used outside of -its function declarator because that is the extent of its potential scope~(\ref{basic.scope.proto}). -\exitnote - -\pnum -\enterexample -the declaration - -\indextext{example!declaration}% -\begin{codeblock} -int i, - *pi, - f(), - *fpi(int), - (*pif)(const char*, const char*), - (*fpif(int))(int); -\end{codeblock} - -declares an integer -\tcode{i}, -a pointer -\tcode{pi} -to an integer, -a function -\tcode{f} -taking no arguments and returning an integer, -a function -\tcode{fpi} -taking an integer argument and returning a pointer to an integer, -a pointer -\tcode{pif} -to a function which -takes two pointers to constant characters and returns an integer, -a function -\tcode{fpif} -taking an integer argument and returning a pointer to a function that takes an integer argument and returns an integer. -It is especially useful to compare -\tcode{fpi} -and -\tcode{pif}. -The binding of -\tcode{*fpi(int)} -is -\tcode{*(fpi(int))}, -so the declaration suggests, -and the same construction in an expression -requires, the calling of a function -\tcode{fpi}, -and then using indirection through the (pointer) result -to yield an integer. -In the declarator -\tcode{(*pif)(const char*, const char*)}, -the extra parentheses are necessary to indicate that indirection through -a pointer to a function yields a function, which is then called. -\exitexample -\enternote -Typedefs and \grammarterm{trailing-return-type}{s} are sometimes convenient when the return type of a function is complex. -For example, -the function -\tcode{fpif} -above could have been declared - -\begin{codeblock} -typedef int IFUNC(int); -IFUNC* fpif(int); -\end{codeblock} - -or - -\begin{codeblock} -auto fpif(int)->int(*)(int); -\end{codeblock} - -A \grammarterm{trailing-return-type} is most useful for a type that would be more complicated to specify before the \grammarterm{declarator-id}: - -\begin{codeblock} -template auto add(T t, U u) -> decltype(t + u); -\end{codeblock} - -rather than - -\begin{codeblock} -template decltype((*(T*)0) + (*(U*)0)) add(T t, U u); -\end{codeblock} -\exitnote - -\pnum -A \term{non-template function} is a function that is not a function template -specialization. \enternote A function template is not a function. \exitnote - -\pnum -A \grammarterm{declarator-id} or \grammarterm{abstract-declarator} -containing an ellipsis shall only -be used in a \grammarterm{parameter-declaration}. Such a -\grammarterm{parameter-declaration} is a parameter -pack~(\ref{temp.variadic}). When it is part of a -\grammarterm{parameter-declaration-clause}, the parameter pack is a -function parameter pack~(\ref{temp.variadic}). \enternote -Otherwise, the \grammarterm{parameter-declaration} is part of a -\grammarterm{template-parameter-list} and the parameter pack is a -template parameter pack; see~\ref{temp.param}. \exitnote -A function parameter pack is a pack expansion~(\ref{temp.variadic}). -\enterexample - -\begin{codeblock} -template void f(T (* ...t)(int, int)); - -int add(int, int); -float subtract(int, int); - -void g() { - f(add, subtract); -} -\end{codeblock} -\exitexample - -\pnum -There is a syntactic ambiguity when an ellipsis occurs at the end -of a \grammarterm{parameter-declaration-clause} without a preceding -comma. In this case, the ellipsis is parsed as part of the -\grammarterm{abstract-declarator} if the type of the parameter either names -a template parameter pack that has not been expanded or contains \tcode{auto}; -otherwise, it is -parsed as part of the \grammarterm{parameter-declaration-clause}.\footnote{One can explicitly disambiguate the parse either by -introducing a comma (so the ellipsis will be parsed as part of the -\grammarterm{parameter-declaration-clause}) or by introducing a name for the -parameter (so the ellipsis will be parsed as part of the -\grammarterm{declarator-id}).}% -\indextext{declarator!function|)} - -\rSec2[dcl.fct.default]{Default arguments}% -\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. -Default arguments will be used in calls where trailing arguments are missing. - -\pnum -\indextext{argument!example~of default}% -\enterexample -the declaration - -\begin{codeblock} -void point(int = 3, int = 4); -\end{codeblock} - -declares a function that can be called with zero, one, or two arguments of type -\tcode{int}. -It can be called in any of these ways: - -\begin{codeblock} -point(1,2); point(1); point(); -\end{codeblock} - -The last two calls are equivalent to -\tcode{point(1,4)} -and -\tcode{point(3,4)}, -respectively. -\exitexample - -\pnum -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} -(\ref{temp.param}); -in the latter case, the \grammarterm{initializer-clause} shall be an -\grammarterm{assignment-expression}. -A default argument shall not be specified for a parameter pack. -If it is specified in a -\grammarterm{parameter-declaration-clause}, -it shall not occur within a -\grammarterm{declarator} -or -\grammarterm{abstract-declarator} -of a -\grammarterm{parameter-declaration}.\footnote{This means that default -arguments cannot appear, -for example, in declarations of pointers to functions, -references to functions, or -\tcode{typedef} -declarations. -} - -\pnum -For non-template functions, default arguments can be added in later -declarations of a -function in the same scope. -Declarations in different -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. -In -a given function declaration, each parameter subsequent to a -parameter with a default argument shall have a default argument -supplied in this or a previous declaration -or shall be a function parameter pack. -A default argument -shall not be redefined by a later declaration (not even to the -same value). -\enterexample - -\begin{codeblock} -void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow - // a parameter with a default argument -void f(int, int); -void f(int, int = 7); -void h() { - f(3); // OK, calls \tcode{f(3, 7)} - void f(int = 1, int); // error: does not use default - // from surrounding scope -} -void m() { - void f(int, int); // has no defaults - f(4); // error: wrong number of arguments - void f(int, int = 5); // OK - f(4); // OK, calls \tcode{f(4, 5);} - void f(int, int = 5); // error: cannot redefine, even to - // same value -} -void n() { - f(6); // OK, calls \tcode{f(6, 7)} -} -\end{codeblock} -\exitexample -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; -see~\ref{basic.def.odr}. -If a friend declaration specifies a default argument expression, -that declaration shall be a definition and shall be the only -declaration of the function or function template in the translation unit. - -\pnum -\indextext{argument!type~checking~of default}% -\indextext{argument!binding~of default}% -\indextext{argument!evaluation~of default}% -The default argument has the -same semantic constraints as the initializer in a -declaration of a variable of the parameter type, using the -copy-initialization semantics (\ref{dcl.init}). -The names in the -default argument are bound, and the semantic constraints are checked, -at the point where the default argument appears. -Name lookup and checking of semantic constraints for default -arguments in function templates and in member functions of -class templates are performed as described in~\ref{temp.inst}. -\enterexample -in the following code, -\indextext{argument!example~of default}% -\tcode{g} -will be called with the value -\tcode{f(2)}: - -\begin{codeblock} -int a = 1; -int f(int); -int g(int x = f(a)); // default argument: \tcode{f(::a)} - -void h() { - a = 2; - { - int a = 3; - g(); // \tcode{g(f(::a))} - } -} -\end{codeblock} -\exitexample -\enternote -In member function declarations, -names in default arguments are looked up -as described in~\ref{basic.lookup.unqual}. -Access checking applies to names in default arguments as -described in Clause~\ref{class.access}. -\exitnote - -\pnum -Except for member functions of class templates, the -default arguments in a member function definition that appears -outside of the class definition -are added to the set of default arguments provided by the -member function declaration in the class definition; -the program is ill-formed if a default constructor~(\ref{class.ctor}), -copy or move constructor, or copy or move assignment operator~(\ref{class.copy}) -is so declared. -Default arguments for a member function of a class template -shall be specified on the initial declaration of the member -function within the class template. -\enterexample - -\begin{codeblock} -class C { - void f(int i = 3); - void g(int i, int j = 99); -}; - -void C::f(int i = 3) { // error: default argument already -} // specified in class scope -void C::g(int i = 88, int j) { // in this translation unit, -} // \tcode{C::g} can be called with no argument -\end{codeblock} -\exitexample - -\pnum -Local variables shall not be used in a default argument. -\enterexample - -\begin{codeblock} -void f() { - int i; - extern void g(int x = i); //error - // ... -} -\end{codeblock} -\exitexample - -\pnum -The keyword -\tcode{this} -shall not be used in a default argument of a member function. -\enterexample - -\begin{codeblock} -class A { - void f(A* p = this) { } // error -}; -\end{codeblock} -\exitexample - -\pnum -\indextext{argument!evaluation~of default}% -A default argument is evaluated each time the function is called -with no argument for the corresponding parameter. -The order of evaluation of function arguments is -unspecified. -\indextext{arguments!implementation-defined order~of~evaluation~of function}% -\indextext{argument!scope~of default}% -Consequently, -parameters of a function shall not be used in a default argument, -even if they are not evaluated. -\indextext{argument~and~name~hiding!default}% -Parameters of a function declared before a default argument -are in scope and can hide namespace and class member names. -\enterexample - -\begin{codeblock} -int a; -int f(int a, int b = a); // error: parameter \tcode{a} - // used as default argument -typedef int I; -int g(float I, int b = I(2)); // error: parameter \tcode{I} found -int h(int a, int b = sizeof(a)); // error, parameter \tcode{a} used - // in default argument -\end{codeblock} -\exitexample -Similarly, a non-static member shall not be used in a default argument, even if it is not evaluated, unless it appears as -the \grammarterm{id-expression} of a class member access expression (\ref{expr.ref}) or -unless it is used to form a pointer to member (\ref{expr.unary.op}). -\enterexample -the declaration of -\tcode{X::mem1()} -in the following example is ill-formed because no object is supplied for the -non-static member -\tcode{X::a} -used as an initializer. - -\begin{codeblock} -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} - static int b; -}; -\end{codeblock} - -The declaration of -\tcode{X::mem2()} -is meaningful, however, since no object is needed to access the static member -\tcode{X::b}. -Classes, objects, and members are described in Clause~\ref{class}. -\exitexample -A default argument is not part of the -type of a function. -\enterexample - -\begin{codeblock} -int f(int = 0); - -void h() { - int j = f(1); - int k = f(); // OK, means \tcode{f(0)} -} - -int (*p1)(int) = &f; -int (*p2)() = &f; // error: type mismatch -\end{codeblock} -\exitexample -When a declaration of a function is introduced by way of a -\grammarterm{using-declaration} -(\ref{namespace.udecl}), any default argument information associated -with the declaration is made known as well. -If the function is redeclared -thereafter in the namespace with additional default arguments, -the additional arguments are also known at any point following -the redeclaration where the -\grammarterm{using-declaration} -is in scope. - -\pnum -\indextext{argument~and~virtual~function!default}% -A virtual function call (\ref{class.virtual}) uses the default -arguments in the declaration of the virtual function determined -by the static type of the pointer or reference denoting the -object. -An overriding function in a derived class does not -acquire default arguments from the function it overrides. -\enterexample - -\begin{codeblock} -struct A { - virtual void f(int a = 7); -}; -struct B : public A { - void f(int a); -}; -void m() { - B* pb = new B; - A* pa = pb; - pa->f(); // OK, calls \tcode{pa->B::f(7)} - pb->f(); // error: wrong number of arguments for \tcode{B::f()} -} -\end{codeblock} -\exitexample% -\indextext{declaration!default argument|)}% -\indextext{declarator!meaning~of|)} - -\rSec1[dcl.fct.def]{Function definitions}% -\indextext{definition!function|(} - -\rSec2[dcl.fct.def.general]{In general} - -\pnum -\indextext{body!function}% -Function definitions have the form - -\indextext{\idxgram{function-definition}}% -% -\begin{bnf} -\nontermdef{function-definition}\br - attribute-specifier-seq\opt decl-specifier-seq\opt declarator virt-specifier-seq\opt function-body -\end{bnf} - -\begin{bnf} -function-body:\br - ctor-initializer\opt compound-statement\br - function-try-block\br - \terminal{= default ;}\br - \terminal{= delete ;} -\end{bnf} - -Any informal reference to the body of a function should be interpreted as a reference to -the non-terminal \grammarterm{function-body}. -The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{function-definition} -appertains to the function. -A \grammarterm{virt-specifier-seq} can be part of a \grammarterm{function-definition} -only if it is a \grammarterm{member-declaration}~(\ref{class.mem}). - -\pnum -The -\grammarterm{declarator} -in a -\grammarterm{function-definition} -shall have the form - -\begin{ncsimplebnf} -\terminal{D1 (} parameter-declaration-clause \terminal{)} cv-qualifier-seq\opt\br - \hspace*{\bnfindentinc}ref-qualifier\opt exception-specification\opt attribute-specifier-seq\opt trailing-return-type\opt -\end{ncsimplebnf} - -as described in~\ref{dcl.fct}. -A function shall be defined only in namespace or class scope. - -\pnum -\enterexample -a simple example of a complete function definition is - -\indextext{example!function definition}% -\begin{codeblock} -int max(int a, int b, int c) { - int m = (a > b) ? a : b; - return (m > c) ? m : c; -} -\end{codeblock} - -Here -\tcode{int} -is the -\grammarterm{decl-specifier-seq}; -\tcode{max(int} -\tcode{a,} -\tcode{int} -\tcode{b,} -\tcode{int} -\tcode{c)} -is the -\grammarterm{declarator}; -\tcode{\{ /* ... */ \}} -is the -\grammarterm{function-body}. -\exitexample - -\pnum -\indextext{initializer!base~class}% -\indextext{initializer!member}% -\indextext{definition!constructor}% -A -\grammarterm{ctor-initializer} -is used only in a constructor; see~\ref{class.ctor} and~\ref{class.init}. - -\pnum -\enternote -A \grammarterm{cv-qualifier-seq} affects the type of \tcode{this} -in the body of a member function; see~\ref{dcl.ref}. -\exitnote - -\pnum -\enternote -Unused parameters need not be named. -For example, - -\indextext{example!unnamed parameter}% -\begin{codeblock} -void print(int a, int) { - std::printf("a = %d\n",a); -} -\end{codeblock} -\exitnote - -\pnum -In the \grammarterm{function-body}, a -\grammarterm{function-local predefined variable} denotes a block-scope object of static -storage duration that is implicitly defined (see~\ref{basic.scope.block}). - -\pnum -The function-local predefined variable \tcode{__func__} is -defined as if a definition of the form - -\begin{codeblock} -static const char __func__[] = "@\grammarterm{function-name}@"; -\end{codeblock} - -had been provided, where \grammarterm{function-name} is an \impldef{string resulting -from \tcode{__func__}} string. It is unspecified whether such a variable has an address -distinct from that of any other object in the program.\footnote{Implementations are -permitted to provide additional predefined variables with names that are reserved to the -implementation~(\ref{lex.name}). If a predefined variable is not -odr-used~(\ref{basic.def.odr}), its string value need not be present in the program image.} - -\enterexample -\begin{codeblock} -struct S { - S() : s(__func__) { } // OK - const char* s; -}; -void f(const char* s = __func__); // error: \tcode{__func__} is undeclared -\end{codeblock} -\exitexample - -\rSec2[dcl.fct.def.default]{Explicitly-defaulted functions}% -\indextext{definition!function!explicitly-defaulted} - -\pnum -A function definition of the form: - -\begin{ncbnf} - attribute-specifier-seq\opt decl-specifier-seq\opt declarator virt-specifier-seq\opt \terminal{ = default ;} -\end{ncbnf} - -is called an \grammarterm{explicitly-defaulted} definition. -A function that is explicitly defaulted shall - -\begin{itemize} -\item be a special member function, - -\item have the same declared function type (except for possibly differing -\grammarterm{ref-qualifier}{s} and except that in the case of a copy constructor or -copy assignment operator, the parameter type may be ``reference to non-const \tcode{T}'', -where \tcode{T} is the name of the member function's class) as if it had been implicitly -declared, and - -\item not have default arguments. -\end{itemize} - -\pnum -An explicitly-defaulted function that is not defined as deleted may be declared -\tcode{constexpr} only if it would have been implicitly declared as -\tcode{constexpr}. If -a function is explicitly defaulted on its first declaration, - -\begin{itemize} -\item it is implicitly considered to be \tcode{constexpr} if the implicit -declaration would be, and, -\item it has the same exception specification -as if it had been implicitly declared~(\ref{except.spec}). -\end{itemize} - -\pnum -If a function that is explicitly defaulted is declared with an -\grammarterm{exception-specification} that is not compatible~(\ref{except.spec}) -with the exception specification of the implicit declaration, then - -\begin{itemize} -\item if the function is explicitly defaulted on its first declaration, it is defined as deleted; -\item otherwise, the program is ill-formed. -\end{itemize} - -\pnum -\enterexample -\begin{codeblock} -struct S { - constexpr S() = default; // ill-formed: implicit \tcode{S()} is not \tcode{constexpr} - S(int a = 0) = default; // ill-formed: default argument - void operator=(const S&) = default; // ill-formed: non-matching return type - ~S() throw(int) = default; // deleted: exception specification does not match -private: - int i; - S(S&); // OK: private copy constructor -}; -S::S(S&) = default; // OK: defines copy constructor -\end{codeblock} -\exitexample - -\pnum -Explicitly-defaulted functions and implicitly-declared functions are collectively -called \defn{defaulted} functions, and the implementation -shall provide implicit definitions -for them~(\ref{class.ctor} -\ref{class.dtor}, \ref{class.copy}), which might mean defining them as deleted. -A function is -\defn{user-provided} if it is user-declared and not explicitly -defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function -(i.e., explicitly defaulted after its first declaration) -is defined at the point where it is explicitly defaulted; if such a function is implicitly -defined as deleted, the program is ill-formed. -\enternote -Declaring a function as defaulted after its first declaration can provide -efficient execution and concise -definition while enabling a stable binary interface to an evolving code -base.\exitnote - -\pnum -\enterexample - -\begin{codeblock} -struct trivial { - trivial() = default; - trivial(const trivial&) = default; - trivial(trivial&&) = default; - trivial& operator=(const trivial&) = default; - trivial& operator=(trivial&&) = default; - ~trivial() = default; -}; - -struct nontrivial1 { - nontrivial1(); -}; -nontrivial1::nontrivial1() = default; // not first declaration -\end{codeblock} -\exitexample - -\rSec2[dcl.fct.def.delete]{Deleted definitions}% -\indextext{definition!function!deleted} - -\pnum -A function definition of the form: - -\begin{ncbnf} - attribute-specifier-seq\opt decl-specifier-seq\opt declarator virt-specifier-seq\opt \terminal{ = delete ;} -\end{ncbnf} - -is called a \term{deleted definition}. A function with a -deleted definition is also called a \term{deleted function}. - -\pnum -A program that refers to a deleted function implicitly or explicitly, other -than to declare it, is ill-formed. \enternote 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. If a function is overloaded, it is referenced only if the -function is selected by overload resolution. \exitnote - -\pnum -\enterexample One can enforce non-default initialization and non-integral -initialization with - -\begin{codeblock} -struct onlydouble { - onlydouble() = delete; // OK, but redundant - onlydouble(std::intmax_t) = delete; - onlydouble(double); -}; -\end{codeblock} - -\exitexample - -\enterexample One can prevent use of a -class in certain \grammarterm{new-expression}{s} by using deleted definitions -of a user-declared \tcode{operator new} for that class. - -\begin{codeblock} -struct sometype { - void* operator new(std::size_t) = delete; - void* operator new[](std::size_t) = delete; -}; -sometype* p = new sometype; // error, deleted class \tcode{operator new} -sometype* q = new sometype[3]; // error, deleted class \tcode{operator new[]} -\end{codeblock} -\exitexample - -\enterexample One can make a class uncopyable, i.e. move-only, by using deleted -definitions of the copy constructor and copy assignment operator, and then -providing defaulted definitions of the move constructor and move assignment operator. - -\begin{codeblock} -struct moveonly { - moveonly() = default; - moveonly(const moveonly&) = delete; - moveonly(moveonly&&) = default; - moveonly& operator=(const moveonly&) = delete; - moveonly& operator=(moveonly&&) = default; - ~moveonly() = default; -}; -moveonly* p; -moveonly q(*p); // error, deleted copy constructor -\end{codeblock} -\exitexample - -\pnum -A deleted function is implicitly inline. \enternote The -one-definition rule~(\ref{basic.def.odr}) applies to deleted definitions. \exitnote -A deleted definition of a function shall be the first declaration of the function or, -for an explicit specialization of a function template, the first declaration of that -specialization. -\enterexample -\begin{codeblock} -struct sometype { - sometype(); -}; -sometype::sometype() = delete; // ill-formed; not first declaration -\end{codeblock} -\exitexample% -\indextext{definition!function|)} - -\rSec1[dcl.init]{Initializers}% -\indextext{initialization|(} - -\pnum -A declarator can specify an initial value for the -identifier being declared. -The identifier designates a variable being initialized. -The process of initialization described in the -remainder of~\ref{dcl.init} -applies also to initializations -specified by other syntactic contexts, such as the initialization -of function parameters with argument expressions (\ref{expr.call}) or -the initialization of return values (\ref{stmt.return}). - -\begin{bnf} -\nontermdef{initializer}\br - brace-or-equal-initializer\br - \terminal{(} expression-list \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{brace-or-equal-initializer}\br - \terminal{=} initializer-clause\br - braced-init-list -\end{bnf} - -\begin{bnf} -\nontermdef{initializer-clause}\br - assignment-expression\br - braced-init-list -\end{bnf} - -\begin{bnf} -\nontermdef{initializer-list}\br - initializer-clause \terminal{...}\opt\br - initializer-list \terminal{,} initializer-clause \terminal{...}\opt -\end{bnf} - -\begin{bnf} -\nontermdef{braced-init-list}\br - \terminal{\{} initializer-list \terminal{,\opt} \terminal{\}}\br - \terminal{\{} \terminal{\}} -\end{bnf} - -\pnum -Except for objects declared with the \tcode{constexpr} specifier, for which see~\ref{dcl.constexpr}, -an \grammarterm{initializer} in the definition of a variable can consist of -arbitrary -\indextext{initialization!automatic object}% -\indextext{initialization!static object@\tcode{static} object}% -expressions involving literals and previously declared -variables and functions, -regardless of the variable's storage duration. -\enterexample - -\begin{codeblock} -int f(int); -int a = 2; -int b = f(a); -int c(b); -\end{codeblock} -\exitexample - -\pnum -\enternote -Default arguments are more restricted; see~\ref{dcl.fct.default}. - -\pnum -The order of initialization of variables with static storage duration is described in~\ref{basic.start} -and~\ref{stmt.dcl}. -\exitnote - -\pnum -A declaration of a block-scope variable with external or internal -linkage that has an \grammarterm{initializer} is ill-formed. - -\pnum -\indextext{initialization!static object@\tcode{static} object}% -\indextext{initialization!default}% -\indextext{variable!indeterminate uninitialized}% -\indextext{zero-initialization}% -To -\grammarterm{zero-initialize} -an object or reference of type -\tcode{T} -means: - -\begin{itemize} -\item -if -\tcode{T} -is a scalar type (\ref{basic.types}), the -object -is initialized to the value obtained by converting the integer literal \tcode{0} -(zero) to -\tcode{T};\footnote{As specified in~\ref{conv.ptr}, converting an integer -literal whose value is -\tcode{0} -to a pointer type results in a null pointer value. -} - -\item -if -\tcode{T} -is a (possibly cv-qualified) non-union class type, -each non-static data member and each -base-class subobject is zero-initialized and padding is initialized to zero bits; - -\item -if -\tcode{T} -is a (possibly cv-qualified) union type, -the -object's first non-static named -data member -is zero-initialized and padding is initialized to zero bits; - -\item -if -\tcode{T} -is an array type, -each element is zero-initialized; -\item -if -\tcode{T} -is a reference type, no initialization is performed. -\end{itemize} - -\pnum -\indextext{default-initialization}% -To -\grammarterm{default-initialize} -an object of type -\tcode{T} -means: - -\begin{itemize} -\item -If -\tcode{T} -is a (possibly cv-qualified) class type (Clause~\ref{class}), -constructors are considered. The applicable constructors are -enumerated~(\ref{over.match.ctor}), and the best one for the -\grammarterm{initializer} \tcode{()} is chosen through -overload resolution~(\ref{over.match}). The constructor thus selected -is called, with an empty argument list, to initialize the object. - -\item -If -\tcode{T} -is an array type, each element is default-initialized. - -\item -Otherwise, -no initialization is performed. -\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 class type with a user-provided default constructor. - -\pnum -\indextext{value-initialization}% -To -\grammarterm{value-initialize} -an object of type -\tcode{T} -means: - -\begin{itemize} -\item -if -\tcode{T} -is a (possibly cv-qualified) class type (Clause~\ref{class}) with -either no default constructor~(\ref{class.ctor}) or a default -constructor that is user-provided or deleted, then the object is default-initialized; - -\item -if -\tcode{T} -is a (possibly cv-qualified) class type without a -user-provided or deleted default constructor, -then the object is zero-initialized and the semantic constraints for -default-initialization are checked, and if \tcode{T} has a -non-trivial default constructor, the object is default-initialized; - -\item -if -\tcode{T} -is an array type, then each element is value-initialized; - -\item -otherwise, the object is zero-initialized. -\end{itemize} - -An object that is value-initialized is deemed to be constructed and thus subject to -provisions of this International Standard applying to ``constructed'' objects, objects -``for which the constructor has completed,'' etc., even if no constructor is invoked -for the object's initialization. - -\pnum -A program that calls for default-initialization -or value-initialization -of an entity -of reference type is ill-formed. - -\pnum -\enternote Every -object of static storage duration is -zero-initialized at program startup before any other initialization -takes place. -In some cases, additional initialization is done later. -\exitnote - -\pnum -An object whose initializer is an empty set of parentheses, i.e., -\tcode{()}, -shall be -value-initialized. - -\indextext{ambiguity!function declaration}% -\enternote -Since -\tcode{()} -is not permitted by the syntax for -\grammarterm{initializer}, - -\begin{codeblock} -X a(); -\end{codeblock} - -is not the declaration of an object of class -\tcode{X}, -but the declaration of a function taking no argument and returning an -\tcode{X}. -The form -\tcode{()} -is permitted in certain other initialization contexts (\ref{expr.new}, -\ref{expr.type.conv}, \ref{class.base.init}). -\exitnote - -\pnum -\indextext{value!indeterminate}% -\indextext{indeterminate~value}% -If no initializer is specified for an object, the object is default-initialized. -When storage for an object with automatic or dynamic storage duration -is obtained, the object has an \term{indeterminate value}, and if -no initialization is performed for the object, that object retains an -indeterminate value until that value is replaced~(\ref{expr.ass}). -\enternote Objects with static or thread storage duration are zero-initialized, -see~\ref{basic.start.init}. \exitnote -If an indeterminate value is produced by an evaluation, the behavior is -undefined except in the following cases: - -\begin{itemize} -\item -If an indeterminate value of unsigned narrow character -type~(\ref{basic.fundamental}) is produced by the evaluation of: -\begin{itemize} -\item the second or third operand of a conditional expression~(\ref{expr.cond}), -\item the right operand of a comma expression~(\ref{expr.comma}), -\item the operand of a cast or conversion to an unsigned narrow character -type~(\ref{conv.integral}, \ref{expr.type.conv}, \ref{expr.static.cast}, -\ref{expr.cast}), or -\item a discarded-value expression (Clause~\ref{expr}), -\end{itemize} -then the result of the operation is an indeterminate value. - -\item -If an indeterminate value of unsigned narrow character -type is produced by the evaluation of the right -operand of a simple assignment operator~(\ref{expr.ass}) whose first operand -is an lvalue of unsigned narrow character type, an indeterminate value replaces -the value of the object referred to by the left operand. - -\item -If an indeterminate value of unsigned narrow character type is produced by the -evaluation of the initialization expression when initializing an object of -unsigned narrow character type, that object is initialized to an indeterminate -value. -\end{itemize} -\enterexample -\begin{codeblock} - int f(bool b) { - unsigned char c; - unsigned char d = c; // OK, \tcode{d} has an indeterminate value - int e = d; // undefined behavior - return b ? d : 0; // undefined behavior if \tcode{b} is \tcode{true} - } -\end{codeblock} -\exitexample - -\pnum -\indextext{initialization!class~member}% -An initializer for a static member is in the scope of the member's class. -\enterexample - -\begin{codeblock} -int a; - -struct X { - static int a; - static int b; -}; - -int X::a = 1; -int X::b = a; // \tcode{X::b = X::a} -\end{codeblock} -\exitexample - -\pnum -If the entity being initialized does not have class type, the -\grammarterm{expression-list} in a -parenthesized initializer shall be a single expression. - -\pnum -\indextext{initialization!copy}% -\indextext{initialization!direct}% -The initialization that occurs in the \tcode{=} form of a -\grammarterm{brace-or-equal-initializer} or -\grammarterm{condition} (\ref{stmt.select}), -as well as in argument passing, function return, -throwing an exception (\ref{except.throw}), -handling an exception (\ref{except.handle}), -and aggregate member initialization~(\ref{dcl.init.aggr}), -is called -\defn{copy-initialization}. -\enternote Copy-initialization may invoke a move~(\ref{class.copy}). \exitnote - -\pnum -The initialization that occurs in the forms - -\begin{codeblock} -T x(a); -T x{a}; -\end{codeblock} - -as well as in -\tcode{new} -expressions~(\ref{expr.new}), -\tcode{static_cast} -expressions~(\ref{expr.static.cast}), -functional notation type conversions~(\ref{expr.type.conv}), -\grammarterm{mem-initializer}{s}~(\ref{class.base.init}), and -the \grammarterm{braced-init-list} form of a \grammarterm{condition} -is called -\grammarterm{direct-initialization}. - -\pnum -The semantics of initializers are as follows. -The -\indextext{type!destination}% -\term{destination type} -is the type of the object or reference being initialized and the -\term{source type} -is the type of the initializer expression. -If the initializer is not a single (possibly parenthesized) expression, the -source type is not defined. - -\begin{itemize} -\item -If the initializer is a (non-parenthesized) \grammarterm{braced-init-list}, the object or reference -is list-initialized~(\ref{dcl.init.list}). -\item -If the destination type is a reference type, see~\ref{dcl.init.ref}. -\item -If the destination type is an array of characters, -an array of \tcode{char16_t}, -an array of \tcode{char32_t}, -or an array of -\tcode{wchar_t}, -and the initializer is a string literal, see~\ref{dcl.init.string}. -\item If the initializer is \tcode{()}, the object is value-initialized. -\item -Otherwise, if the destination type is an array, the program is ill-formed. -\item -If the destination type is a (possibly cv-qualified) class type: - -\begin{itemize} -\item -If the initialization is direct-initialization, -or if it is copy-initialization where the cv-unqualified version of the source -type is the same class as, or a derived class of, the class of the destination, -constructors are considered. -The applicable constructors -are enumerated (\ref{over.match.ctor}), and the best one is chosen -through overload resolution (\ref{over.match}). -The constructor so selected -is called to initialize the object, with the initializer -expression or \grammarterm{expression-list} as its argument(s). -If no constructor applies, or the overload resolution is -ambiguous, the initialization is ill-formed. -\item -Otherwise (i.e., for the remaining copy-initialization cases), -user-defined conversion sequences that can convert from the -source type to the destination type or (when a conversion function -is used) to a derived class thereof are enumerated as described in~\ref{over.match.copy}, and the best one is chosen through overload -resolution (\ref{over.match}). If the conversion cannot be done or -is ambiguous, the initialization is ill-formed. The function -selected is called with the initializer expression as its -argument; if the function is a constructor, the call initializes -a temporary of the cv-unqualified version of the -destination type. The temporary is a prvalue. The result of the call -(which is the temporary for the constructor case) is then used -to direct-initialize, according to the rules above, the object -that is the destination of the copy-initialization. In certain -cases, an implementation is permitted to eliminate the copying -inherent in this direct-initialization by constructing the -intermediate result directly into the object being initialized; -see~\ref{class.temporary}, \ref{class.copy}. -\end{itemize} - -\item -Otherwise, if the source type -is a (possibly cv-qualified) class type, conversion functions are -considered. -The applicable conversion functions are enumerated -(\ref{over.match.conv}), and the best one is chosen through overload -resolution (\ref{over.match}). -The user-defined conversion so selected -is called to convert the initializer expression into the -object being initialized. -If the conversion cannot be done or is -ambiguous, the initialization is ill-formed. -\item -Otherwise, the initial value of the object being initialized is -the (possibly converted) value of the initializer expression. -Standard conversions (Clause~\ref{conv}) will be used, if necessary, -to convert the initializer expression to the cv-unqualified version of -the destination type; -no user-defined conversions are considered. -If the conversion cannot -be done, the initialization is ill-formed. -When initializing a bit-field with a value that it cannot represent, the -resulting value of the bit-field is -\impldef{value of bit-field that cannot represent!initializer}. -\indextext{initialization!\idxcode{const}}% -\enternote -An expression of type -``\nonterminal{cv1} \tcode{T}'' -can initialize an object of type -``\nonterminal{cv2} \tcode{T}'' -independently of -the cv-qualifiers -\nonterminal{cv1} -and \nonterminal{cv2}. - -\begin{codeblock} -int a; -const int b = a; -int c = b; -\end{codeblock} -\exitnote -\end{itemize} - -\pnum -An \grammarterm{initializer-clause} followed by an ellipsis is a -pack expansion~(\ref{temp.variadic}). - -\rSec2[dcl.init.aggr]{Aggregates}% -\indextext{aggregate}% -\indextext{initialization!aggregate}% -\indextext{aggregate~initialization}% -\indextext{initialization!array}% -\indextext{initialization!class~object}% -\indextext{class~object~initialization|see{constructor}}% -\indextext{\idxcode{\{\}}!initializer list} - -\pnum -An -\term{aggregate} -is an array or a class (Clause~\ref{class}) with no -user-provided constructors (\ref{class.ctor}), -no private or protected non-static data members (Clause~\ref{class.access}), -no base classes (Clause~\ref{class.derived}), -and no virtual functions (\ref{class.virtual}). - -\pnum -When an aggregate is initialized by an initializer list, as specified in~\ref{dcl.init.list}, the elements of the initializer list are taken as initializers -for the members of the aggregate, -in increasing subscript or member order. -Each member is copy-initialized from the corresponding \grammarterm{initializer-clause}. If the \grammarterm{initializer-clause} is an expression and a narrowing conversion~(\ref{dcl.init.list}) is required to convert the expression, the program is ill-formed. \enternote If an \grammarterm{initializer-clause} is itself an initializer list, the member is list-initialized, which will result in a recursive application of the rules in this section if the member is an aggregate. \exitnote -\enterexample -\begin{codeblock} -struct A { - int x; - struct B { - int i; - int j; - } b; -} a = { 1, { 2, 3 } }; -\end{codeblock} - -initializes -\tcode{a.x} -with 1, -\tcode{a.b.i} -with 2, -\tcode{a.b.j} -with 3. -\exitexample - -\pnum -An aggregate that is a class can also be initialized with a single -expression not enclosed in braces, as described in~\ref{dcl.init}. - -\pnum -An array of unknown size initialized with a -brace-enclosed -\grammarterm{initializer-list} -containing -\tcode{n} -\grammarterm{initializer-clause}{s}, -where -\tcode{n} -shall be greater than zero, is defined as having -\tcode{n} -elements (\ref{dcl.array}). -\enterexample - -\begin{codeblock} -int x[] = { 1, 3, 5 }; -\end{codeblock} - -declares and initializes -\tcode{x} -as a one-dimensional array that has three elements -since no size was specified and there are three initializers. -\exitexample -An empty initializer list -\tcode{\{\}} -shall not be used as the \grammarterm{initializer-clause } -for an array of unknown bound.\footnote{The syntax provides for empty -\grammarterm{initializer-list}{s}, -but nonetheless \Cpp does not have zero length arrays.} - -\pnum -Static data members and anonymous bit-fields are not considered -members of the class for purposes of aggregate initialization. -\enterexample - -\begin{codeblock} -struct A { - int i; - static int s; - int j; - int :17; - int k; -} a = { 1, 2, 3 }; -\end{codeblock} - -Here, the second initializer 2 initializes -\tcode{a.j} -and not the static data member -\tcode{A::s}, and the third initializer 3 initializes \tcode{a.k} -and not the anonymous bit-field before it. -\exitexample - -\pnum -An -\grammarterm{initializer-list} -is ill-formed if the number of -\grammarterm{initializer-clause}{s} -exceeds the number of members or elements to initialize. -\enterexample - -\begin{codeblock} -char cv[4] = { 'a', 's', 'd', 'f', 0 }; // error -\end{codeblock} - -is ill-formed. -\exitexample - -\pnum -If there are fewer \grammarterm{initializer-clause}{s} in the list than there -are members in the aggregate, then each member not explicitly initialized -shall be initialized from its \grammarterm{brace-or-equal-initializer} or, -if there is no \grammarterm{brace-or-equal-initializer}, from an empty -initializer list~(\ref{dcl.init.list}). -\enterexample - -\begin{codeblock} -struct S { int a; const char* b; int c; int d = b[a]; }; -S ss = { 1, "asdf" }; -\end{codeblock} - -initializes -\tcode{ss.a} -with 1, -\tcode{ss.b} -with \tcode{"asdf"}, -\tcode{ss.c} -with the value of an expression of the form -\tcode{int\{\}} -(that is, \tcode{0}), and \tcode{ss.d} with the value of \tcode{ss.b[ss.a]} -(that is, \tcode{'s'}), and in - -\begin{codeblock} -struct X { int i, j, k = 42; }; -X a[] = { 1, 2, 3, 4, 5, 6 }; -X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } }; -\end{codeblock} - -\tcode{a} and \tcode{b} have the same value -\exitexample - -\pnum -If a reference member is initialized from its \grammarterm{brace-or-equal-initializer} -and a potentially-evaluated subexpression thereof is an aggregate -initialization that would use that \grammarterm{brace-or-equal-initializer}, -the program is ill-formed. -\enterexample -\begin{codeblock} - struct A; - extern A a; - struct A { - const A& a1 { A{a,a} }; // OK - const A& a2 { A{} }; // error - }; - A a{a,a}; // OK -\end{codeblock} -\exitexample - -\pnum -If an aggregate class \tcode{C} contains a subaggregate member -\tcode{m} that has no members for purposes of aggregate initialization, -the \grammarterm{initializer-clause} for \tcode{m} shall not be -omitted from an \grammarterm{initializer-list} for an object of type -\tcode{C} unless the \grammarterm{initializer-clause}{s} for all -members of \tcode{C} following \tcode{m} are also omitted. -\enterexample - -\begin{codeblock} -struct S { } s; -struct A { - S s1; - int i1; - S s2; - int i2; - S s3; - int i3; -} a = { - { }, // Required initialization - 0, - s, // Required initialization - 0 -}; // Initialization not required for \tcode{A::s3} because \tcode{A::i3} is also not initialized -\end{codeblock} -\exitexample - -\pnum -If an incomplete or empty -\grammarterm{initializer-list} -leaves a member of reference type uninitialized, the program is ill-formed. - -\pnum -When initializing a multi-dimensional array, -the -\grammarterm{initializer-clause}{s} -initialize the elements with the last (rightmost) index of the array -varying the fastest (\ref{dcl.array}). -\enterexample - -\begin{codeblock} -int x[2][2] = { 3, 1, 4, 2 }; -\end{codeblock} - -initializes -\tcode{x[0][0]} -to -\tcode{3}, -\tcode{x[0][1]} -to -\tcode{1}, -\tcode{x[1][0]} -to -\tcode{4}, -and -\tcode{x[1][1]} -to -\tcode{2}. -On the other hand, - -\begin{codeblock} -float y[4][3] = { - { 1 }, { 2 }, { 3 }, { 4 } -}; -\end{codeblock} - -initializes the first column of -\tcode{y} -(regarded as a two-dimensional array) -and leaves the rest zero. -\exitexample - -\pnum -Braces can be elided in an -\grammarterm{initializer-list} -as follows. -If the -\grammarterm{initializer-list} -begins with a left brace, -then the succeeding comma-separated list of -\grammarterm{initializer-clause}{s} -initializes the members of a subaggregate; -it is erroneous for there to be more -\grammarterm{initializer-clause}{s} -than members. -If, however, the -\grammarterm{initializer-list} -for a subaggregate does not begin with a left brace, -then only enough -\grammarterm{initializer-clause}{s} -from the list are taken to initialize the members of the subaggregate; -any remaining -\grammarterm{initializer-clause}{s} -are left to initialize the next member of the aggregate -of which the current subaggregate is a member. -\enterexample - -\begin{codeblock} -float y[4][3] = { - { 1, 3, 5 }, - { 2, 4, 6 }, - { 3, 5, 7 }, -}; -\end{codeblock} - -is a completely-braced initialization: -1, 3, and 5 initialize the first row of the array -\tcode{y[0]}, -namely -\tcode{y[0][0]}, -\tcode{y[0][1]}, -and -\tcode{y[0][2]}. -Likewise the next two lines initialize -\tcode{y[1]} -and -\tcode{y[2]}. -The initializer ends early and therefore -\tcode{y[3]}s -elements are initialized as if explicitly initialized with an -expression of the form -\tcode{float()}, -that is, are initialized with -\tcode{0.0}. -In the following example, braces in the -\grammarterm{initializer-list} -are elided; -however the -\grammarterm{initializer-list} -has the same effect as the completely-braced -\grammarterm{initializer-list} -of the above example, - -\begin{codeblock} -float y[4][3] = { - 1, 3, 5, 2, 4, 6, 3, 5, 7 -}; -\end{codeblock} - -The initializer for -\tcode{y} -begins with a left brace, but the one for -\tcode{y[0]} -does not, -therefore three elements from the list are used. -Likewise the next three are taken successively for -\tcode{y[1]} -and -\tcode{y[2]}. -\exitexample - -\pnum -All implicit type conversions (Clause~\ref{conv}) are considered when -initializing the aggregate member with an \grammarterm{assignment-expression}. -If the -\grammarterm{assignment-expression} -can initialize a member, the member is initialized. -Otherwise, if the member is itself a subaggregate, -brace elision is assumed and the -\grammarterm{assignment-expression} -is considered for the initialization of the first member of the subaggregate. -\enternote As specified above, brace elision cannot apply to -subaggregates with no members for purposes of aggregate initialization; an -\grammarterm{initializer-clause} for the entire subobject is -required.\exitnote - -\enterexample - -\begin{codeblock} -struct A { - int i; - operator int(); -}; -struct B { - A a1, a2; - int z; -}; -A a; -B b = { 4, a, a }; -\end{codeblock} - -Braces are elided around the -\grammarterm{initializer-clause} -for -\tcode{b.a1.i}. -\tcode{b.a1.i} -is initialized with 4, -\tcode{b.a2} -is initialized with -\tcode{a}, -\tcode{b.z} -is initialized with whatever -\tcode{a.operator int()} -returns. -\exitexample - -\pnum -\indextext{initialization!array~of class~objects}% -\enternote -An aggregate array or an aggregate class may contain members of a -class type with a user-provided constructor (\ref{class.ctor}). -Initialization of these aggregate objects is described in~\ref{class.expl.init}. -\exitnote - -\pnum -\enternote Whether the initialization of aggregates with static storage duration is static or dynamic is specified in~\ref{basic.start.init} and~\ref{stmt.dcl}. \exitnote - -\pnum -\indextext{initialization!\idxcode{union}}% -When a union is initialized with a brace-enclosed initializer, -the braces shall only contain an -\grammarterm{initializer-clause} -for the first non-static data member of the union. -\enterexample - -\begin{codeblock} -union u { int a; const char* b; }; -u a = { 1 }; -u b = a; -u c = 1; // error -u d = { 0, "asdf" }; // error -u e = { "asdf" }; // error -\end{codeblock} -\exitexample - -\pnum -\enternote -As described above, -the braces around the -\grammarterm{initializer-clause} -for a union member can be omitted if the -union is a member of another aggregate. -\exitnote - -\rSec2[dcl.init.string]{Character arrays}% -\indextext{initialization!character array} - -\pnum -An array of narrow character type~(\ref{basic.fundamental}), -\tcode{char16_t} array, -\tcode{char32_t} array, -or \tcode{wchar_t} array -can be initialized by a -narrow string literal, \tcode{char16_t} string literal, \tcode{char32_t} string -literal, or wide string literal, -respectively, or by an appropriately-typed string literal enclosed in -braces~(\ref{lex.string}). -\indextext{initialization!character~array}% -Successive -characters of the -value of the string literal -initialize the elements of the array. -\enterexample - -\begin{codeblock} -char msg[] = "Syntax error on line %s\n"; -\end{codeblock} - -shows a character array whose members are initialized -with a -\grammarterm{string-literal}. -Note that because -\tcode{'\textbackslash n'} -is a single character and -because a trailing -\tcode{'\textbackslash 0'} -is appended, -\tcode{sizeof(msg)} -is -\tcode{25}. -\exitexample - -\pnum -There shall not be more initializers than there are array elements. -\enterexample - -\begin{codeblock} -char cv[4] = "asdf"; // error -\end{codeblock} - -is ill-formed since there is no space for the implied trailing -\tcode{'\textbackslash 0'}. -\exitexample - -\pnum -If there are fewer initializers than there are array elements, each element not -explicitly initialized shall be zero-initialized~(\ref{dcl.init}). - -\rSec2[dcl.init.ref]{References}% -\indextext{initialization!reference} - -\pnum -A variable declared to be a -\tcode{T\&} or \tcode{T\&\&}, -that is, ``reference to type -\tcode{T}'' -(\ref{dcl.ref}), -shall be initialized by an object, or function, of type -\tcode{T} -or by an object that can be converted into a -\tcode{T}. -\enterexample - -\begin{codeblock} -int g(int); -void f() { - int i; - int& r = i; // \tcode{r} refers to \tcode{i} - r = 1; // the value of \tcode{i} becomes \tcode{1} - int* p = &r; // \tcode{p} points to \tcode{i} - int& rr = r; // \tcode{rr} refers to what \tcode{r} refers to, that is, to \tcode{i} - int (&rg)(int) = g; // \tcode{rg} refers to the function \tcode{g} - rg(i); // calls function \tcode{g} - int a[3]; - int (&ra)[3] = a; // \tcode{ra} refers to the array \tcode{a} - ra[1] = i; // modifies \tcode{a[1]} -} -\end{codeblock} -\exitexample - -\pnum -A reference cannot be changed to refer to another object after initialization. -\indextext{assignment!reference}% -Note that initialization of a reference is treated very differently from assignment -to it. -\indextext{argument~passing!reference~and}% -Argument passing (\ref{expr.call}) -\indextext{\idxcode{return}!reference~and}% -and function value return (\ref{stmt.return}) are initializations. - -\pnum -The initializer can be omitted for a reference only in a parameter declaration -(\ref{dcl.fct}), in the declaration of a function return type, in the declaration of -a class member within its class definition (\ref{class.mem}), and where the -\tcode{extern} -specifier is explicitly used. -\indextext{declaration!extern@\tcode{extern} reference}% -\enterexample - -\begin{codeblock} -int& r1; // error: initializer missing -extern int& r2; // OK -\end{codeblock} -\exitexample - -\pnum -Given types ``\nonterminal{cv1} \tcode{T1}'' and ``\nonterminal{cv2} \tcode{T2},'' -``\nonterminal{cv1} \tcode{T1}'' is \nonterminal{reference-related} to -\indextext{reference-related}% -``\nonterminal{cv2} \tcode{T2}'' if -\tcode{T1} -is the same type as -\tcode{T2}, -or -\tcode{T1} -is a base class of -\tcode{T2}. -``\nonterminal{cv1} \tcode{T1}'' is \nonterminal{reference-compatible} -\indextext{reference-compatible}% -with ``\nonterminal{cv2} \tcode{T2}'' if -\tcode{T1} -is reference-related to -\tcode{T2} -and -\textit{cv1} -is the same cv-qualification as, or greater cv-qualification than, -\textit{cv2}. -In all cases where the reference-related or reference-compatible relationship -of two types is used to establish the validity of a reference binding, and -\tcode{T1} -is a base class of -\tcode{T2}, -a program that necessitates such a binding is ill-formed if -\tcode{T1} -is an inaccessible (Clause~\ref{class.access}) or ambiguous (\ref{class.member.lookup}) -base class of -\tcode{T2}. - -\pnum -A reference to type ``\cvqual{cv1} \tcode{T1}'' is initialized by -an expression of type ``\cvqual{cv2} \tcode{T2}'' as follows:% -\indextext{binding!reference} - -\begin{itemize} -\item -If the reference is an lvalue reference and the initializer expression - -\begin{itemize} -\item -is an lvalue (but is not a -bit-field), and -``\nonterminal{cv1} \tcode{T1}'' is reference-compatible with -``\nonterminal{cv2} \tcode{T2},'' or -\item -has a class type (i.e., -\tcode{T2} -is a class type), where \tcode{T1} is not reference-related to \tcode{T2}, and can be converted -to an lvalue of type ``\nonterminal{cv3} \tcode{T3},'' where -``\nonterminal{cv1} \tcode{T1}'' is reference-compatible with -``\nonterminal{cv3} \tcode{T3}''\footnote{This requires a conversion -function~(\ref{class.conv.fct}) returning a reference type.} -(this conversion is selected by enumerating the applicable conversion -functions (\ref{over.match.ref}) and choosing the best one through overload -resolution (\ref{over.match})), -\end{itemize} -then the reference is bound to the initializer expression lvalue in the -first case and to the lvalue result of the conversion -in the second case (or, in either case, to the appropriate base class subobject of the object). -\enternote -The usual lvalue-to-rvalue (\ref{conv.lval}), array-to-pointer -(\ref{conv.array}), and function-to-pointer (\ref{conv.func}) standard -conversions are not needed, and therefore are suppressed, when such -direct bindings to lvalues are done. -\exitnote - -\enterexample - -\begin{codeblock} -double d = 2.0; -double& rd = d; // \tcode{rd} refers to \tcode{d} -const double& rcd = d; // \tcode{rcd} refers to \tcode{d} - -struct A { }; -struct B : A { operator int&(); } b; -A& ra = b; // \tcode{ra} refers to \tcode{A} subobject in \tcode{b} -const A& rca = b; // \tcode{rca} refers to \tcode{A} subobject in \tcode{b} -int& ir = B(); // \tcode{ir} refers to the result of \tcode{B::operator int\&} -\end{codeblock} -\exitexample - -\item -Otherwise, the reference shall be an lvalue reference to a non-volatile -const type (i.e., -\textit{cv1} -shall be -\tcode{const}), or the reference shall be an rvalue reference. -\enterexample - -\begin{codeblock} -double& rd2 = 2.0; // error: not an lvalue and reference not \tcode{const} -int i = 2; -double& rd3 = i; // error: type mismatch and reference not \tcode{const} -\end{codeblock} -\exitexample - -\begin{itemize} -\item If the initializer expression - -\begin{itemize} -\item is an xvalue (but not a bit-field), class prvalue, array prvalue or function lvalue and -``\cvqual{cv1} \tcode{T1}'' is -reference-compatible with ``\cvqual{cv2} \tcode{T2}'', or - -\item has a class type (i.e., \tcode{T2} is a class type), where \tcode{T1} -is not reference-related to \tcode{T2}, and can be converted to -an xvalue, class prvalue, or function lvalue of type ``\cvqual{cv3} \tcode{T3}'', -where ``\cvqual{cv1} \tcode{T1}'' is -reference-compatible with ``\cvqual{cv3} \tcode{T3}'' (see~\ref{over.match.ref}), - -\end{itemize} - -then the reference is bound to the value of the initializer expression in the first -case and to the result of the conversion in the second case (or, in either case, to -an appropriate base class subobject). - -\enterexample - -\begin{codeblock} -struct A { }; -struct B : A { } b; -extern B f(); -const A& rca2 = f(); // bound to the \tcode{A} subobject of the \tcode{B} rvalue. -A&& rra = f(); // same as above -struct X { - operator B(); - operator int&(); -} x; -const A& r = x; // bound to the \tcode{A} subobject of the result of the conversion -int i2 = 42; -int&& rri = static_cast(i2); // bound directly to \tcode{i2} -B&& rrb = x; // bound directly to the result of \tcode{operator B} -\end{codeblock} -\exitexample - -\item -Otherwise: -\begin{itemize} -\item -If \tcode{T1} or \tcode{T2} is a class type and -\tcode{T1} is not reference-related to \tcode{T2}, -user-defined conversions are considered -using the rules for copy-initialization of an object of type -``\nonterminal{cv1} \tcode{T1}'' by -user-defined conversion -(\ref{dcl.init}, \ref{over.match.copy}, \ref{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 -conversion function, as described for the non-reference -copy-initialization, is then used to direct-initialize the reference. -For this direct-initialization, user-defined conversions are not considered. -\item -Otherwise, -a temporary of type ``\nonterminal{cv1} \tcode{T1}'' is created and -copy-initialized~(\ref{dcl.init}) from the initializer expression. -The reference is then bound to the temporary. -\end{itemize} - -If -\tcode{T1} -is reference-related to -\tcode{T2}: -\begin{itemize} -\item -\textit{cv1} -shall be the same cv-qualification as, or greater cv-qualification than, -\textit{cv2}; and -\item -if the reference is an rvalue reference, -the initializer expression shall not be an lvalue. -\end{itemize} - -\enterexample -\begin{codeblock} -struct Banana { }; -struct Enigma { operator const Banana(); }; -struct Alaska { operator Banana&(); }; -void enigmatic() { - typedef const Banana ConstBanana; - Banana &&banana1 = ConstBanana(); // ill-formed - Banana &&banana2 = Enigma(); // ill-formed - Banana &&banana3 = Alaska(); // ill-formed -} - -const double& rcd2 = 2; // \tcode{rcd2} refers to temporary with value \tcode{2.0} -double&& rrd = 2; // \tcode{rrd} refers to temporary with value \tcode{2.0} -const volatile int cvi = 1; -const int& r2 = cvi; // error: type qualifiers dropped -struct A { operator volatile int&(); } a; -const int& r3 = a; // error: type qualifiers dropped - // from result of conversion function -double d2 = 1.0; -double&& rrd2 = d2; // error: initializer is lvalue of related type -struct X { operator int&(); }; -int&& rri2 = X(); // error: result of conversion function is lvalue of related type -int i3 = 2; -double&& rrd3 = i3; // \tcode{rrd3} refers to temporary with value \tcode{2.0} -\end{codeblock} -\exitexample -\end{itemize} -\end{itemize} - -In all cases except the last (i.e., creating and initializing a temporary from the -initializer expression), the reference is said to \defn{bind directly} to the -initializer expression. - -\pnum -\enternote -\ref{class.temporary} describes the lifetime of temporaries bound to references. -\exitnote - -\rSec2[dcl.init.list]{List-initialization}% -\indextext{initialization!list-initialization|(} - -\pnum -\grammarterm{List-initialization} is initialization of an object or reference from a -\grammarterm{braced-init-list}. Such an initializer is called an \term{initializer -list}, and the comma-separated \grammarterm{initializer-clause}{s} of the list are -called the \term{elements} of the initializer list. An initializer list may be empty. -List-initialization can occur in direct-initialization or copy-initialization contexts; -list-initialization in a direct-initialization context is called -\grammarterm{direct-list-initialization} and list-initialization in a -copy-initialization context is called \grammarterm{copy-list-initialization}. \enternote -List-initialization can be used - -\begin{itemize} -\item as the initializer in a variable definition~(\ref{dcl.init}) -\item as the initializer in a \grammarterm{new-expression}~(\ref{expr.new}) -\item in a return statement~(\ref{stmt.return}) -\item as a \grammarterm{for-range-initializer}~(\ref{stmt.iter}) -\item as a function argument~(\ref{expr.call}) -\item as a subscript~(\ref{expr.sub}) -\item as an argument to a constructor invocation~(\ref{dcl.init},~\ref{expr.type.conv}) -\item as an initializer for a non-static data member~(\ref{class.mem}) -\item in a \grammarterm{mem-initializer}~(\ref{class.base.init}) -\item on the right-hand side of an assignment (\ref{expr.ass}) -\end{itemize} - -\enterexample -\begin{codeblock} -int a = {1}; -std::complex z{1,2}; -new std::vector{"once", "upon", "a", "time"}; // 4 string elements -f( {"Nicholas","Annemarie"} ); // pass list of two elements -return { "Norah" }; // return list of one element -int* e {}; // initialization to zero / null pointer -x = double{1}; // explicitly construct a double -std::map anim = { {"bear",4}, {"cassowary",2}, {"tiger",7} }; -\end{codeblock} -\exitexample \exitnote - -\pnum -A constructor is an \grammarterm{initializer-list constructor} if its first parameter is -of type \tcode{std::initializer_list} or reference to possibly cv-qualified -\tcode{std::initializer_list} for some type \tcode{E}, and either there are no other -parameters or else all other parameters have default arguments (\ref{dcl.fct.default}). -\enternote Initializer-list constructors are favored over other constructors in -list-initialization~(\ref{over.match.list}). Passing an initializer list as the argument -to the constructor template \tcode{template C(T)} of a class \tcode{C} does not -create an initializer-list constructor, because an initializer list argument causes the -corresponding parameter to be a non-deduced context~(\ref{temp.deduct.call}). \exitnote -The template -\tcode{std::initializer_list} is not predefined; if the header -\tcode{} is not included prior to a use of -\tcode{std::initializer_list} --- even an implicit use in which the type is not -named~(\ref{dcl.spec.auto}) --- the program is ill-formed. - -\pnum -List-initialization of an object or reference of type \tcode{T} is defined as follows: -\begin{itemize} - -\item If \tcode{T} is a class type and the initializer list has a single element -of type \cvqual{cv} \tcode{U}, -where \tcode{U} is \tcode{T} or a class derived from \tcode{T}, -the object is initialized from that element (by copy-initialization for -copy-list-initialization, or by direct-initialization for -direct-list-initialization). - -\item Otherwise, if \tcode{T} is a character array and the initializer list has a -single element that is an appropriately-typed string literal~(\ref{dcl.init.string}), -initialization is performed as described in that section. - -\item Otherwise, if \tcode{T} is an aggregate, aggregate initialization is -performed~(\ref{dcl.init.aggr}). - -\enterexample -\begin{codeblock} -double ad[] = { 1, 2.0 }; // OK -int ai[] = { 1, 2.0 }; // error: narrowing - -struct S2 { - int m1; - double m2, m3; -}; -S2 s21 = { 1, 2, 3.0 }; // OK -S2 s22 { 1.0, 2, 3 }; // error: narrowing -S2 s23 { }; // OK: default to 0,0,0 -\end{codeblock} -\exitexample - -\item Otherwise, if the initializer list has no elements and \tcode{T} is a class type with a -default constructor, the object is value-initialized. - -\item Otherwise, if \tcode{T} is a specialization of \tcode{std::initializer_list}, -a prvalue \tcode{initializer_list} object is constructed as described below and used to -initialize the object according to the rules for initialization of an object from a -class of the same type~(\ref{dcl.init}). - -\item Otherwise, if \tcode{T} is a class type, constructors are considered. -The applicable constructors are enumerated and -the best one is chosen through overload resolution (\ref{over.match},~\ref{over.match.list}). If a narrowing -conversion (see below) is required to convert any of the arguments, the program is -ill-formed. - -\enterexample -\begin{codeblock} -struct S { - S(std::initializer_list); // \#1 - S(std::initializer_list); // \#2 - S(); // \#3 - // ... -}; -S s1 = { 1.0, 2.0, 3.0 }; // invoke \#1 -S s2 = { 1, 2, 3 }; // invoke \#2 -S s3 = { }; // invoke \#3 -\end{codeblock} -\exitexample - -\enterexample -\begin{codeblock} -struct Map { - Map(std::initializer_list>); -}; -Map ship = {{"Sophie",14}, {"Surprise",28}}; -\end{codeblock} -\exitexample - -\enterexample -\begin{codeblock} -struct S { - // no initializer-list constructors - S(int, double, double); // \#1 - S(); // \#2 - // ... -}; -S s1 = { 1, 2, 3.0 }; // OK: invoke \#1 -S s2 { 1.0, 2, 3 }; // error: narrowing -S s3 { }; // OK: invoke \#2 -\end{codeblock} -\exitexample - -\item Otherwise, if -the initializer list has a single element of type \tcode{E} and either -\tcode{T} is not a reference type or its referenced type is -reference-related to \tcode{E}, the object or reference is initialized -from that element (by copy-initialization for copy-list-initialization, -or by direct-initialization for direct-list-initialization); -if a narrowing conversion (see below) is required -to convert the element to \tcode{T}, the program is ill-formed. - -\enterexample -\begin{codeblock} -int x1 {2}; // OK -int x2 {2.0}; // error: narrowing -\end{codeblock} -\exitexample - -\item Otherwise, if \tcode{T} is a reference type, a prvalue temporary of the type -referenced by \tcode{T} is copy-list-initialized or direct-list-initialized, -depending on the kind of initialization for the reference, and the reference is -bound to that temporary. -\enternote As usual, the binding will fail and the program is ill-formed if -the reference type is an lvalue reference to a non-const type. \exitnote - -\enterexample -\begin{codeblock} -struct S { - S(std::initializer_list); // \#1 - S(const std::string&); // \#2 - // ... -}; -const S& r1 = { 1, 2, 3.0 }; // OK: invoke \#1 -const S& r2 { "Spinach" }; // OK: invoke \#2 -S& r3 = { 1, 2, 3 }; // error: initializer is not an lvalue -const int& i1 = { 1 }; // OK -const int& i2 = { 1.1 }; // error: narrowing -const int (&iar)[2] = { 1, 2 }; // OK: \tcode{iar} is bound to temporary array -\end{codeblock} -\exitexample - -\item Otherwise, if the initializer list has no elements, the object is -value-initialized. - -\enterexample -\begin{codeblock} -int** pp {}; // initialized to null pointer -\end{codeblock} -\exitexample - -\item Otherwise, the program is ill-formed. - -\enterexample -\begin{codeblock} -struct A { int i; int j; }; -A a1 { 1, 2 }; // aggregate initialization -A a2 { 1.2 }; // error: narrowing -struct B { - B(std::initializer_list); -}; -B b1 { 1, 2 }; // creates \tcode{initializer_list} and calls constructor -B b2 { 1, 2.0 }; // error: narrowing -struct C { - C(int i, double j); -}; -C c1 = { 1, 2.2 }; // calls constructor with arguments (1, 2.2) -C c2 = { 1.1, 2 }; // error: narrowing - -int j { 1 }; // initialize to 1 -int k { }; // initialize to 0 -\end{codeblock} -\exitexample - -\end{itemize} - -\pnum -Within the \grammarterm{initializer-list} of a \grammarterm{braced-init-list}, -the \grammarterm{initializer-clause}{s}, including any that result from pack -expansions~(\ref{temp.variadic}), are evaluated in the order in which they -appear. That is, every value computation and side effect associated with a -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}. -\enternote This evaluation ordering holds regardless of the semantics of the -initialization; for example, it applies when the elements of the -\grammarterm{initializer-list} are interpreted as arguments of a constructor -call, even though ordinarily there are no sequencing constraints on the -arguments of a call. \exitnote - -\pnum -An object of type \tcode{std::initializer_list} is constructed from -an initializer list as if the implementation allocated a temporary array of $N$ -elements of type \tcode{const E}, where $N$ is the number of elements in the -initializer list. Each element of that array is copy-initialized with the -corresponding element of the initializer list, and the -\tcode{std::initializer_list} object is constructed to refer to that array. -\enternote A constructor or conversion function selected for the copy shall be -accessible (Clause~\ref{class.access}) in the context of the initializer list. -\exitnote -If a narrowing conversion is required to initialize any of the elements, the program is ill-formed.\enterexample -\begin{codeblock} -struct X { - X(std::initializer_list v); -}; -X x{ 1,2,3 }; -\end{codeblock} - -The initialization will be implemented in a way roughly equivalent to this: - -\begin{codeblock} -const double __a[3] = {double{1}, double{2}, double{3}}; -X x(std::initializer_list(__a, __a+3)); -\end{codeblock} - -assuming that the implementation can construct an \tcode{initializer_list} object with a pair of pointers. \exitexample - -\pnum -The array has the same lifetime as any other temporary -object~(\ref{class.temporary}), except that initializing an -\tcode{initializer_list} object from the array extends the lifetime of -the array exactly like binding a reference to a temporary. -\enterexample - -\begin{codeblock} -typedef std::complex cmplx; -std::vector v1 = { 1, 2, 3 }; - -void f() { - std::vector v2{ 1, 2, 3 }; - std::initializer_list i3 = { 1, 2, 3 }; -} - -struct A { - std::initializer_list i4; - A() : i4{ 1, 2, 3 } {} // creates an \tcode{A} with a dangling reference -}; -\end{codeblock} - -For \tcode{v1} and \tcode{v2}, the \tcode{initializer_list} object -is a parameter in a function call, so the array created for -\tcode{\{ 1, 2, 3 \}} has full-expression lifetime. -For \tcode{i3}, the \tcode{initializer_list} object is a variable, -so the array persists for the lifetime of the variable. -For \tcode{i4}, the \tcode{initializer_list} object is initialized in -a constructor's \grammarterm{ctor-initializer}, so the array persists -only until the constructor exits, and so any use of the elements of -\tcode{i4} after the constructor exits produces undefined behavior. -\exitexample -\enternote -The implementation is free to allocate the array in read-only memory if an explicit array with the same initializer could be so allocated. \exitnote - -\pnum -A -\indextext{narrowing conversion}% -\indextext{conversion!narrowing}% -\term{narrowing conversion} is an implicit conversion - -\begin{itemize} -\item from a floating-point type to an integer type, or - -\item from \tcode{long double} to \tcode{double} or \tcode{float}, or from -\tcode{double} to \tcode{float}, except where the source is a constant expression and -the actual value after conversion -is within the range of values that can be represented (even if it cannot be represented exactly), -or - -\item from an integer type or unscoped enumeration type to a floating-point type, except -where the source is a constant expression and the actual value after conversion will fit -into the target type and will produce the original value when converted back to the -original type, or - -\item from an integer type or unscoped enumeration type to an integer type that cannot -represent all the values of the original type, except where the source is a constant -expression whose value after integral promotions will fit into the target type. -\end{itemize} - -\enternote As indicated above, such conversions are not allowed at the top level in -list-initializations.\exitnote \enterexample - -\begin{codeblock} -int x = 999; // x is not a constant expression -const int y = 999; -const int z = 99; -char c1 = x; // OK, though it might narrow (in this case, it does narrow) -char c2{x}; // error: might narrow -char c3{y}; // error: narrows (assuming \tcode{char} is 8 bits) -char c4{z}; // OK: no narrowing needed -unsigned char uc1 = {5}; // OK: no narrowing needed -unsigned char uc2 = {-1}; // error: narrows -unsigned int ui1 = {-1}; // error: narrows -signed int si1 = - { (unsigned int)-1 }; // error: narrows -int ii = {2.0}; // error: narrows -float f1 { x }; // error: might narrow -float f2 { 7 }; // OK: 7 can be exactly represented as a float -int f(int); -int a[] = - { 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level -\end{codeblock} -\exitexample% -\indextext{initialization!list-initialization|)}% -\indextext{initialization|)}% -\indextext{declarator|)} diff --git a/source/derived.tex b/source/derived.tex deleted file mode 100644 index 74216d52d6..0000000000 --- a/source/derived.tex +++ /dev/null @@ -1,1024 +0,0 @@ -%!TEX root = std.tex -\rSec0[class.derived]{Derived classes}% -\indextext{derived~class|(} - -%gram: \rSec1[gram.derived]{Derived classes} -%gram: - -\indextext{base~class~virtual|see{virtual~base~class}} -\indextext{function, virtual|see{virtual~function}} -\indextext{dynamic binding|see{virtual~function}} - -\pnum -\indextext{base~class}% -\indextext{inheritance}% -\indextext{multiple~inheritance}% -A list of base classes can be specified in a class definition using -the notation: - -\begin{bnf} -\nontermdef{base-clause}\br - \terminal{:} base-specifier-list -\end{bnf} - - -\begin{bnf} -\nontermdef{base-specifier-list}\br - base-specifier \terminal{...}\opt\br - base-specifier-list \terminal{,} base-specifier \terminal{...}\opt -\end{bnf} - -\begin{bnf} -\nontermdef{base-specifier}\br - attribute-specifier-seq\opt base-type-specifier\br - attribute-specifier-seq\opt \terminal{virtual} access-specifier\opt base-type-specifier\br - attribute-specifier-seq\opt access-specifier \terminal{virtual}\opt base-type-specifier -\end{bnf} - -\begin{bnf} -\nontermdef{class-or-decltype}\br - nested-name-specifier\opt class-name\br - decltype-specifier -\end{bnf} - -\begin{bnf} -\nontermdef{base-type-specifier}\br - class-or-decltype -\end{bnf} - -\indextext{specifier~access|see{access~specifier}}% -% -\begin{bnf} -\nontermdef{access-specifier}\br - \terminal{private}\br - \terminal{protected}\br - \terminal{public} -\end{bnf} - -The optional \grammarterm{attribute-specifier-seq} appertains to the \grammarterm{base-specifier}. - -\pnum -\indextext{type!incomplete}% -The type denoted by a \grammarterm{base-type-specifier} shall be -a class type that is not -an -incompletely defined class (Clause~\ref{class}); this class is called a -\indextext{base~class!direct}% -\term{direct base class} -for the class being defined. -\indextext{base~class}% -\indextext{derivation|see{inheritance}}% -During the lookup for a base class name, non-type names are -ignored~(\ref{basic.scope.hiding}). If the name found is not a -\grammarterm{class-name}, the program is ill-formed. A class \tcode{B} is a -base class of a class \tcode{D} if it is a direct base class of -\tcode{D} or a direct base class of one of \tcode{D}'s base classes. -\indextext{base~class!indirect}% -A class is an \term{indirect} base class of another if it is a base -class but not a direct base class. A class is said to be (directly or -indirectly) \term{derived} from its (direct or indirect) base -classes. -\enternote -See Clause~\ref{class.access} for the meaning of -\grammarterm{access-specifier}. -\exitnote -\indextext{access control!base~class member}% -Unless redeclared in the derived class, members of a base class are also -considered to be members of the derived class. The base class members -are said to be -\indextext{inheritance}% -\term{inherited} -by the derived class. Inherited members can be referred to in -expressions in the same manner as other members of the derived class, -unless their names are hidden or ambiguous~(\ref{class.member.lookup}). -\indextext{operator!scope~resolution}% -\enternote -The scope resolution operator \tcode{::}~(\ref{expr.prim}) can be used -to refer to a direct or indirect base member explicitly. This allows -access to a name that has been redeclared in the derived class. A -derived class can itself serve as a base class subject to access -control; see~\ref{class.access.base}. A pointer to a derived class can be -implicitly converted to a pointer to an accessible unambiguous base -class~(\ref{conv.ptr}). An lvalue of a derived class type can be bound -to a reference to an accessible unambiguous base -class~(\ref{dcl.init.ref}). -\exitnote - -\pnum -The \grammarterm{base-specifier-list} specifies the type of the -\term{base class subobjects} contained in an -object of the derived class type. -\enterexample -\indextext{example!derived~class}% -\begin{codeblock} -struct Base { - int a, b, c; -}; -\end{codeblock} - -\begin{codeblock} -struct Derived : Base { - int b; -}; -\end{codeblock} - -\begin{codeblock} -struct Derived2 : Derived { - int c; -}; -\end{codeblock} - -Here, an object of class \tcode{Derived2} will have a subobject of class -\tcode{Derived} which in turn will have a subobject of class -\tcode{Base}. -\exitexample - -\pnum -A \grammarterm{base-specifier} followed by an ellipsis is a pack -expansion~(\ref{temp.variadic}). - -\pnum -The order in which the base class subobjects are allocated in the most -derived object~(\ref{intro.object}) is unspecified. -\enternote -\indextext{directed~acyclic~graph|see{DAG}}% -\indextext{lattice|see{DAG, subobject}}% -a derived class and its base class subobjects can be represented by a -directed acyclic graph (DAG) where an arrow means ``directly derived -from.'' A DAG of subobjects is often referred to as a ``subobject -lattice.'' - -\begin{importgraphic} -{Directed acyclic graph} -{fig:dag} -{figdag.pdf} -\end{importgraphic} - -\pnum -The arrows need not have a physical representation in memory. -\exitnote - -\pnum -\enternote -Initialization of objects representing base classes can be specified in -constructors; see~\ref{class.base.init}. -\exitnote - -\pnum -\enternote -A base class subobject might have a layout~(\ref{basic.stc}) different -from the layout of a most derived object of the same type. A base class -subobject might have a polymorphic behavior~(\ref{class.cdtor}) -different from the polymorphic behavior of a most derived object of the -same type. A base class subobject may be of zero size (Clause~\ref{class}); -however, two subobjects that have the same class type and that belong to -the same most derived object must not be allocated at the same -address~(\ref{expr.eq}). -\exitnote - -\rSec1[class.mi]{Multiple base classes} -\indextext{multiple~inheritance}% -\indextext{base~class}% - -\pnum -A class can be derived from any number of base classes. -\enternote -The use of more than one direct base class is often called multiple inheritance. -\exitnote -\enterexample -\begin{codeblock} -class A { /* ... */ }; -class B { /* ... */ }; -class C { /* ... */ }; -class D : public A, public B, public C { /* ... */ }; -\end{codeblock} -\exitexample - -\pnum -\indextext{layout!class~object}% -\indextext{initialization!order~of}% -\enternote -The order of derivation is not significant except as specified by the -semantics of initialization by constructor~(\ref{class.base.init}), -cleanup~(\ref{class.dtor}), and storage -layout~(\ref{class.mem},~\ref{class.access.spec}). -\exitnote - -\pnum -A class shall not be specified as a direct base class of a derived class -more than once. -\enternote -A class can be an indirect base class more than once and can be a direct -and an indirect base class. There are limited things that can be done -with such a class. The non-static data members and member functions of -the direct base class cannot be referred to in the scope of the derived -class. However, the static members, enumerations and types can be -unambiguously referred to. -\exitnote -\enterexample -\begin{codeblock} -class X { /* ... */ }; -class Y : public X, public X { /* ... */ }; // ill-formed - -\end{codeblock} -\begin{codeblock} -class L { public: int next; /* ... */ }; -class A : public L { /* ... */ }; -class B : public L { /* ... */ }; -class C : public A, public B { void f(); /* ... */ }; // well-formed -class D : public A, public L { void f(); /* ... */ }; // well-formed -\end{codeblock} -\exitexample - -\pnum -\indextext{virtual~base~class}% -A base class specifier that does not contain the keyword -\tcode{virtual}, specifies a \grammarterm{non-virtual} base class. A base -class specifier that contains the keyword \tcode{virtual}, specifies a -\term{virtual} base class. For each distinct occurrence of a -non-virtual base class in the class lattice of the most derived class, -the most derived object~(\ref{intro.object}) shall contain a -corresponding distinct base class subobject of that type. For each -distinct base class that is specified virtual, the most derived object -shall contain a single base class subobject of that type. -\enterexample -for an object of class type \tcode{C}, each distinct occurrence of a -(non-virtual) base class \tcode{L} in the class lattice of \tcode{C} -corresponds one-to-one with a distinct \tcode{L} subobject within the -object of type \tcode{C}. Given the class \tcode{C} defined above, an -object of class \tcode{C} will have two subobjects of class \tcode{L} as -shown below. - -\begin{importgraphic} -{Non-virtual base} -{fig:nonvirt} -{fignonvirt.pdf} -\end{importgraphic} - -\pnum -In such lattices, explicit qualification can be used to specify which -subobject is meant. The body of function \tcode{C::f} could refer to the -member \tcode{next} of each \tcode{L} subobject: -\begin{codeblock} -void C::f() { A::next = B::next; } // well-formed -\end{codeblock} -Without the \tcode{A::} or \tcode{B::} qualifiers, the definition of -\tcode{C::f} above would be ill-formed because of -ambiguity~(\ref{class.member.lookup}). - -\pnum -For another example, -\begin{codeblock} -class V { /* ... */ }; -class A : virtual public V { /* ... */ }; -class B : virtual public V { /* ... */ }; -class C : public A, public B { /* ... */ }; -\end{codeblock} -for an object \tcode{c} of class type \tcode{C}, a single subobject of -type \tcode{V} is shared by every base subobject of \tcode{c} that has a -\tcode{virtual} base class of type \tcode{V}. Given the class \tcode{C} -defined above, an object of class \tcode{C} will have one subobject of -class \tcode{V}, as shown below. - -\indextext{DAG!multiple~inheritance}% -\indextext{DAG!virtual~base~class}% -\begin{importgraphic} -{Virtual base} -{fig:virt} -{figvirt.pdf} -\end{importgraphic} - - -\pnum -A class can have both virtual and non-virtual base classes of a given -type. -\begin{codeblock} -class B { /* ... */ }; -class X : virtual public B { /* ... */ }; -class Y : virtual public B { /* ... */ }; -class Z : public B { /* ... */ }; -class AA : public X, public Y, public Z { /* ... */ }; -\end{codeblock} -For an object of class \tcode{AA}, all \tcode{virtual} occurrences of -base class \tcode{B} in the class lattice of \tcode{AA} correspond to a -single \tcode{B} subobject within the object of type \tcode{AA}, and -every other occurrence of a (non-virtual) base class \tcode{B} in the -class lattice of \tcode{AA} corresponds one-to-one with a distinct -\tcode{B} subobject within the object of type \tcode{AA}. Given the -class \tcode{AA} defined above, class \tcode{AA} has two subobjects of -class \tcode{B}: \tcode{Z}'s \tcode{B} and the virtual \tcode{B} shared -by \tcode{X} and \tcode{Y}, as shown below. - -\indextext{DAG!virtual~base~class}% -\indextext{DAG!non-virtual~base~class}% -\indextext{DAG!multiple~inheritance}% -\begin{importgraphic} -{Virtual and non-virtual base} -{fig:virtnonvirt} -{figvirtnonvirt.pdf} -\end{importgraphic} - -\exitexample - -\rSec1[class.member.lookup]{Member name lookup}% -\indextext{lookup!member name}% -\indextext{ambiguity!base~class~member}% -\indextext{ambiguity!member access} - -\pnum -Member name lookup determines the meaning of a name -(\grammarterm{id-expression}) in a class scope~(\ref{basic.scope.class}). -Name lookup can result in an \term{ambiguity}, in which case the -program is ill-formed. For an \grammarterm{id-expression}, name lookup -begins in the class scope of \tcode{this}; for a -\grammarterm{qualified-id}, name lookup begins in the scope of the -\grammarterm{nested-name-specifier}. Name lookup takes place before access -control~(\ref{basic.lookup}, Clause~\ref{class.access}). - -\pnum -The following steps define the result of name lookup for a member name -\tcode{f} in a class scope \tcode{C}. - -\pnum -The \term{lookup set} for \tcode{f} in \tcode{C}, called $S(f,C)$, -consists of two component sets: the \term{declaration set}, a set of -members named \tcode{f}; and the \term{subobject set}, a set of -subobjects where declarations of these members (possibly including -\grammarterm{using-declaration}{s}) were found. In the declaration set, -\grammarterm{using-declaration}{s} are replaced by the -set of designated members that are not hidden or overridden by members of the -derived class~(\ref{namespace.udecl}), -and type declarations (including injected-class-names) are -replaced by the types they designate. $S(f,C)$ is calculated as follows: - -\pnum -If \tcode{C} contains a declaration of the name \tcode{f}, the -declaration set contains every declaration of \tcode{f} declared in -\tcode{C} that satisfies the requirements of the language construct in -which the lookup occurs. -\enternote -Looking up a name in an -\grammarterm{elaborated-type-specifier}~(\ref{basic.lookup.elab}) or -\grammarterm{base-specifier} (Clause~\ref{class.derived}), for instance, -ignores all non-type declarations, while looking up a name in a -\grammarterm{nested-name-specifier}~(\ref{basic.lookup.qual}) ignores -function, variable, and enumerator declarations. As another example, -looking up a name in a -\grammarterm{using-declaration}~(\ref{namespace.udecl}) includes the -declaration of a class or enumeration that would ordinarily be hidden by -another declaration of that name in the same scope. -\exitnote -If the resulting declaration set is not empty, the subobject set -contains \tcode{C} itself, and calculation is complete. - -\pnum -Otherwise (i.e., \tcode{C} does not contain a declaration of \tcode{f} -or the resulting declaration set is empty), $S(f,C)$ is initially empty. -If \tcode{C} has base classes, calculate the lookup set for \tcode{f} in -each direct base class subobject $B_i$, and merge each such lookup set -$S(f,B_i)$ in turn into $S(f,C)$. - -\pnum -The following steps define the result of merging lookup set $S(f,B_i)$ -into the intermediate $S(f,C)$: - -\begin{itemize} -\item If each of the subobject members of $S(f,B_i)$ is a base class -subobject of at least one of the subobject members of $S(f,C)$, or if -$S(f,B_i)$ is empty, $S(f,C)$ is unchanged and the merge is complete. -Conversely, if each of the subobject members of $S(f,C)$ is a base class -subobject of at least one of the subobject members of $S(f,B_i)$, or if -$S(f,C)$ is empty, the new $S(f,C)$ is a copy of $S(f,B_i)$. - -\item Otherwise, if the declaration sets of $S(f,B_i)$ and $S(f,C)$ -differ, the merge is ambiguous: the new $S(f,C)$ is a lookup set with an -invalid declaration set and the union of the subobject sets. In -subsequent merges, an invalid declaration set is considered different -from any other. - -\item Otherwise, the new $S(f,C)$ is a lookup set with the shared set of -declarations and the union of the subobject sets. -\end{itemize} - -\pnum -The result of name lookup for \tcode{f} in \tcode{C} is the declaration -set of $S(f,C)$. If it is an invalid set, the program is ill-formed. -\enterexample -\begin{codeblock} -struct A { int x; }; // S(x,A) = \{ \{ \tcode{A::x} \}, \{ \tcode{A} \} \} -struct B { float x; }; // S(x,B) = \{ \{ \tcode{B::x} \}, \{ \tcode{B} \} \} -struct C: public A, public B { }; // S(x,C) = \{ invalid, \{ \tcode{A} in \tcode{C}, \tcode{B} in \tcode{C} \} \} -struct D: public virtual C { }; // S(x,D) = S(x,C) -struct E: public virtual C { char x; }; // S(x,E) = \{ \{ \tcode{E::x} \}, \{ \tcode{E} \} \} -struct F: public D, public E { }; // S(x,F) = S(x,E) -int main() { - F f; - f.x = 0; // OK, lookup finds \tcode{E::x} -} -\end{codeblock} - -$S(x,F)$ is unambiguous because the \tcode{A} and \tcode{B} base -subobjects of \tcode{D} are also base subobjects of \tcode{E}, so -$S(x,D)$ is discarded in the first merge step. -\exitexample - -\pnum -\indextext{access~control!overloading~resolution~and}% -If the name of an overloaded function is unambiguously found, -overloading resolution~(\ref{over.match}) also takes place before access -control. -\indextext{example!scope~resolution operator}% -\indextext{example!explicit~qualification}% -\indextext{overloading!resolution!scoping ambiguity}% -Ambiguities can often be resolved by qualifying a name with its class name. -\enterexample -\begin{codeblock} -struct A { - int f(); -}; - -\end{codeblock} -\begin{codeblock} -struct B { - int f(); -}; - -\end{codeblock} -\begin{codeblock} -struct C : A, B { - int f() { return A::f() + B::f(); } -}; -\end{codeblock} -\exitexample - -\pnum -\enternote -A static member, a nested type or an enumerator defined in a base class -\tcode{T} can unambiguously be found even if an object has more than one -base class subobject of type \tcode{T}. Two base class subobjects share -the non-static member subobjects of their common virtual base classes. -\exitnote -\enterexample -\begin{codeblock} -struct V { - int v; -}; -struct A { - int a; - static int s; - enum { e }; -}; -struct B : A, virtual V { }; -struct C : A, virtual V { }; -struct D : B, C { }; - -void f(D* pd) { - pd->v++; // OK: only one \tcode{v} (virtual) - pd->s++; // OK: only one \tcode{s} (static) - int i = pd->e; // OK: only one \tcode{e} (enumerator) - pd->a++; // error, ambiguous: two \tcode{a}{s} in \tcode{D} -} -\end{codeblock} -\exitexample - -\pnum -\enternote -\indextext{dominance!virtual~base~class}% -When virtual base classes are used, a hidden declaration can be reached -along a path through the subobject lattice that does not pass through -the hiding declaration. This is not an ambiguity. The identical use with -non-virtual base classes is an ambiguity; in that case there is no -unique instance of the name that hides all the others. -\exitnote -\enterexample -\begin{codeblock} -struct V { int f(); int x; }; -struct W { int g(); int y; }; -struct B : virtual V, W { - int f(); int x; - int g(); int y; -}; -struct C : virtual V, W { }; - -struct D : B, C { void glorp(); }; -\end{codeblock} - -\begin{importgraphic} -{Name lookup} -{fig:name} -{figname.pdf} -\end{importgraphic} - -\pnum -\enternote -The names declared in \tcode{V} and the left-hand instance of \tcode{W} -are hidden by those in \tcode{B}, but the names declared in the -right-hand instance of \tcode{W} are not hidden at all. -\exitnote -\begin{codeblock} -void D::glorp() { - x++; // OK: \tcode{B::x} hides \tcode{V::x} - f(); // OK: \tcode{B::f()} hides \tcode{V::f()} - y++; // error: \tcode{B::y} and \tcode{C}'s \tcode{W::y} - g(); // error: \tcode{B::g()} and \tcode{C}'s \tcode{W::g()} -} -\end{codeblock} -\exitexample -\indextext{ambiguity!class conversion}% - -\pnum -An explicit or implicit conversion from a pointer to or -an expression designating an object -of a -derived class to a pointer or reference to one of its base classes shall -unambiguously refer to a unique object representing the base class. -\enterexample -\begin{codeblock} -struct V { }; -struct A { }; -struct B : A, virtual V { }; -struct C : A, virtual V { }; -struct D : B, C { }; - -void g() { - D d; - B* pb = &d; - A* pa = &d; // error, ambiguous: \tcode{C}'s \tcode{A} or \tcode{B}'s \tcode{A}? - V* pv = &d; // OK: only one \tcode{V} subobject -} -\end{codeblock} -\exitexample - -\pnum -\enternote -Even if the result of name lookup is unambiguous, use of a name found in -multiple subobjects might still be -ambiguous~(\ref{conv.mem},~\ref{expr.ref}, \ref{class.access.base}).\exitnote -\enterexample -\begin{codeblock} -struct B1 { - void f(); - static void f(int); - int i; -}; -struct B2 { - void f(double); -}; -struct I1: B1 { }; -struct I2: B1 { }; - -struct D: I1, I2, B2 { - using B1::f; - using B2::f; - void g() { - f(); // Ambiguous conversion of \tcode{this} - f(0); // Unambiguous (static) - f(0.0); // Unambiguous (only one \tcode{B2}) - int B1::* mpB1 = &D::i; // Unambiguous - int D::* mpD = &D::i; // Ambiguous conversion - } -}; -\end{codeblock}\exitexample - -\rSec1[class.virtual]{Virtual functions}% -\indextext{virtual~function|(}% -\indextext{type!polymorphic}% -\indextext{class!polymorphic} - -\pnum -Virtual functions support dynamic binding and object-oriented -programming. A class that declares or inherits a virtual function is -called a \term{polymorphic class}. - -\pnum -If a virtual member function \tcode{vf} is declared in a class -\tcode{Base} and in a class \tcode{Derived}, derived directly or -indirectly from \tcode{Base}, a member function \tcode{vf} with the same -name, parameter-type-list~(\ref{dcl.fct}), cv-qualification, and ref-qualifier -(or absence of same) as -\tcode{Base::vf} is declared, then \tcode{Derived::vf} is also virtual -(whether or not it is so declared) and it \term{overrides}\footnote{A function with the same name but a different parameter list -(Clause~\ref{over}) as a virtual function is not necessarily virtual and -does not override. The use of the \tcode{virtual} specifier in the -declaration of an overriding function is legal but redundant (has empty -semantics). Access control (Clause~\ref{class.access}) is not considered in -determining overriding.} -\tcode{Base::vf}. For convenience we say that any virtual function -overrides itself. -\indextext{overrider!final}% -A virtual member function \tcode{C::vf} of a class object \tcode{S} is a \defn{final -overrider} unless the most derived class~(\ref{intro.object}) of which \tcode{S} is a -base class subobject (if any) declares or inherits another member function that overrides -\tcode{vf}. In a derived class, if a virtual member function of a base class subobject -has more than one final overrider the program is ill-formed. -\enterexample -\begin{codeblock} -struct A { - virtual void f(); -}; -struct B : virtual A { - virtual void f(); -}; -struct C : B , virtual A { - using A::f; -}; - -void foo() { - C c; - c.f(); // calls \tcode{B::f}, the final overrider - c.C::f(); // calls \tcode{A::f} because of the using-declaration -} -\end{codeblock} -\exitexample - -\enterexample -\begin{codeblock} -struct A { virtual void f(); }; -struct B : A { }; -struct C : A { void f(); }; -struct D : B, C { }; // OK: \tcode{A::f} and \tcode{C::f} are the final overriders - // for the \tcode{B} and \tcode{C} subobjects, respectively -\end{codeblock} -\exitexample - -\pnum -\enternote -A virtual member function does not have to be visible to be overridden, -for example, -\begin{codeblock} -struct B { - virtual void f(); -}; -struct D : B { - void f(int); -}; -struct D2 : D { - void f(); -}; -\end{codeblock} -the function \tcode{f(int)} in class \tcode{D} hides the virtual -function \tcode{f()} in its base class \tcode{B}; \tcode{D::f(int)} is -not a virtual function. However, \tcode{f()} declared in class -\tcode{D2} has the same name and the same parameter list as -\tcode{B::f()}, and therefore is a virtual function that overrides the -function \tcode{B::f()} even though \tcode{B::f()} is not visible in -class \tcode{D2}. -\exitnote - -\pnum -If a virtual function \tcode{f} in some class \tcode{B} is marked with the -\grammarterm{virt-specifier} \tcode{final} and in a class \tcode{D} derived from \tcode{B} -a function \tcode{D::f} overrides \tcode{B::f}, the program is ill-formed. \enterexample -\begin{codeblock} -struct B { - virtual void f() const final; -}; - -struct D : B { - void f() const; // error: \tcode{D::f} attempts to override \tcode{final} \tcode{B::f} -}; -\end{codeblock} -\exitexample - -\pnum -If a virtual function is marked with the \grammarterm{virt-specifier} \tcode{override} and -does not override a member function of a base class, the program is ill-formed. \enterexample -\begin{codeblock} -struct B { - virtual void f(int); -}; - -struct D : B { - virtual void f(long) override; // error: wrong signature overriding \tcode{B::f} - virtual void f(int) override; // OK -}; -\end{codeblock} -\exitexample - -\pnum -Even though destructors are not inherited, a destructor in a derived -class overrides a base class destructor declared virtual; -see~\ref{class.dtor} and~\ref{class.free}. - -\pnum -The return type of an overriding function shall be either identical to -the return type of the overridden function or \term{covariant} with -the classes of the functions. If a function \tcode{D::f} overrides a -function \tcode{B::f}, the return types of the functions are covariant -if they satisfy the following criteria: -\begin{itemize} -\item both are pointers to classes, both are lvalue references to -classes, or both are rvalue references to classes\footnote{Multi-level pointers to classes or references to multi-level pointers to -classes are not allowed.% -} - -\item the class in the return type of \tcode{B::f} is the same class as -the class in the return type of \tcode{D::f}, or is an unambiguous and -accessible direct or indirect base class of the class in the return type -of \tcode{D::f} - -\item both pointers or references have the same cv-qualification and the -class type in the return type of \tcode{D::f} has the same -cv-qualification as or less cv-qualification than the class type in the -return type of \tcode{B::f}. -\end{itemize} - -\pnum -If the class type in the covariant return type of \tcode{D::f} differs from that of -\tcode{B::f}, the class type in the return type of \tcode{D::f} shall be -complete at the point of declaration of \tcode{D::f} or shall be the -class type \tcode{D}. When the overriding function is called as the -final overrider of the overridden function, its result is converted to -the type returned by the (statically chosen) overridden -function~(\ref{expr.call}). -\enterexample -\indextext{example!virtual~function}% -\begin{codeblock} -class B { }; -class D : private B { friend class Derived; }; -struct Base { - virtual void vf1(); - virtual void vf2(); - virtual void vf3(); - virtual B* vf4(); - virtual B* vf5(); - void f(); -}; - -struct No_good : public Base { - D* vf4(); // error: \tcode{B} (base class of \tcode{D}) inaccessible -}; - -class A; -struct Derived : public Base { - void vf1(); // virtual and overrides \tcode{Base::vf1()} - void vf2(int); // not virtual, hides \tcode{Base::vf2()} - char vf3(); // error: invalid difference in return type only - D* vf4(); // OK: returns pointer to derived class - A* vf5(); // error: returns pointer to incomplete class - void f(); -}; - -void g() { - Derived d; - Base* bp = &d; // standard conversion: - // \tcode{Derived*} to \tcode{Base*} - bp->vf1(); // calls \tcode{Derived::vf1()} - bp->vf2(); // calls \tcode{Base::vf2()} - bp->f(); // calls \tcode{Base::f()} (not virtual) - B* p = bp->vf4(); // calls \tcode{Derived::pf()} and converts the - // result to \tcode{B*} - Derived* dp = &d; - D* q = dp->vf4(); // calls \tcode{Derived::pf()} and does not - // convert the result to \tcode{B*} - dp->vf2(); // ill-formed: argument mismatch -} -\end{codeblock} -\exitexample - -\pnum -\enternote -The interpretation of the call of a virtual function depends on the type -of the object for which it is called (the dynamic type), whereas the -interpretation of a call of a non-virtual member function depends only -on the type of the pointer or reference denoting that object (the static -type)~(\ref{expr.call}). -\exitnote - -\pnum -\enternote -The \tcode{virtual} specifier implies membership, so a virtual function -cannot be a nonmember~(\ref{dcl.fct.spec}) function. Nor can a virtual -function be a static member, since a virtual function call relies on a -specific object for determining which function to invoke. A virtual -function declared in one class can be declared a \tcode{friend} in -another class. -\exitnote - -\pnum -\indextext{definition!virtual~function}% -A virtual function declared in a class shall be defined, or declared -pure~(\ref{class.abstract}) in that class, or both; but no diagnostic is -required~(\ref{basic.def.odr}). -\indextext{friend!\tcode{virtual}~and}% - -\pnum -\indextext{multiple~inheritance!\tcode{virtual}~and}% -\enterexample -here are some uses of virtual functions with multiple base classes: -\indextext{example!virtual~function}% -\begin{codeblock} -struct A { - virtual void f(); -}; - -struct B1 : A { // note non-virtual derivation - void f(); -}; - -struct B2 : A { - void f(); -}; - -struct D : B1, B2 { // \tcode{D} has two separate \tcode{A} subobjects -}; - -void foo() { - D d; -//\tcode{ A* ap = \&d;} // would be ill-formed: ambiguous - B1* b1p = &d; - A* ap = b1p; - D* dp = &d; - ap->f(); // calls \tcode{D::B1::f} - dp->f(); // ill-formed: ambiguous -} -\end{codeblock} -In class \tcode{D} above there are two occurrences of class \tcode{A} -and hence two occurrences of the virtual member function \tcode{A::f}. -The final overrider of \tcode{B1::A::f} is \tcode{B1::f} and the final -overrider of \tcode{B2::A::f} is \tcode{B2::f}. - -\pnum -The following example shows a function that does not have a unique final -overrider: -\begin{codeblock} -struct A { - virtual void f(); -}; - -struct VB1 : virtual A { // note virtual derivation - void f(); -}; - -struct VB2 : virtual A { - void f(); -}; - -struct Error : VB1, VB2 { // ill-formed -}; - -struct Okay : VB1, VB2 { - void f(); -}; -\end{codeblock} -Both \tcode{VB1::f} and \tcode{VB2::f} override \tcode{A::f} but there -is no overrider of both of them in class \tcode{Error}. This example is -therefore ill-formed. Class \tcode{Okay} is well formed, however, -because \tcode{Okay::f} is a final overrider. - -\pnum -The following example uses the well-formed classes from above. -\begin{codeblock} -struct VB1a : virtual A { // does not declare \tcode{f} -}; - -struct Da : VB1a, VB2 { -}; - -void foe() { - VB1a* vb1ap = new Da; - vb1ap->f(); // calls \tcode{VB2::f} -} -\end{codeblock} -\exitexample - -\pnum -\indextext{operator!scope~resolution}% -\indextext{virtual~function~call}% -Explicit qualification with the scope operator~(\ref{expr.prim}) -suppresses the virtual call mechanism. -\enterexample -\begin{codeblock} -class B { public: virtual void f(); }; -class D : public B { public: void f(); }; - -void D::f() { /* ... */ B::f(); } -\end{codeblock} - -Here, the function call in -\tcode{D::f} -really does call -\tcode{B::f} -and not -\tcode{D::f}. -\exitexample - -\pnum -A function with a deleted definition~(\ref{dcl.fct.def}) shall -not override a function that does not have a deleted definition. Likewise, -a function that does not have a deleted definition shall not override a -function with a deleted definition.% -\indextext{virtual~function|)} - -\rSec1[class.abstract]{Abstract classes}% -\indextext{class!abstract} - -\pnum -The abstract class mechanism supports the notion of a general concept, -such as a \tcode{shape}, of which only more concrete variants, such as -\tcode{circle} and \tcode{square}, can actually be used. An abstract -class can also be used to define an interface for which derived classes -provide a variety of implementations. - -\pnum -An \term{abstract class} is a class that can be used only -as a base class of some other class; no objects of an abstract class can -be created except as subobjects of a class derived from it. A class is -abstract if it has at least one \term{pure virtual function}. -\enternote -Such a function might be inherited: see below. -\exitnote -\indextext{virtual~function!pure}% -A virtual function is specified \term{pure} by using a -\grammarterm{pure-specifier}~(\ref{class.mem}) in the function declaration -in the class definition. -\indextext{definition!pure virtual~function}% -A pure virtual function need be defined only if called with, or as if -with~(\ref{class.dtor}), the \grammarterm{qualified-id} -syntax~(\ref{expr.prim}). -\enterexample -\indextext{example!pure virtual~function}% -\begin{codeblock} -class point { /* ... */ }; -class shape { // abstract class - point center; -public: - point where() { return center; } - void move(point p) { center=p; draw(); } - virtual void rotate(int) = 0; // pure virtual - virtual void draw() = 0; // pure virtual -}; -\end{codeblock} -\exitexample -\enternote -A function declaration cannot provide both a \grammarterm{pure-specifier} -and a definition -\exitnote -\enterexample -\begin{codeblock} -struct C { - virtual void f() = 0 { }; // ill-formed -}; -\end{codeblock} -\exitexample - -\pnum -\indextext{class!pointer~to abstract}% -An abstract class shall not be used as a parameter type, as a function -return type, or as the type of an explicit conversion. Pointers and -references to an abstract class can be declared. -\enterexample -\begin{codeblock} -shape x; // error: object of abstract class -shape* p; // OK -shape f(); // error -void g(shape); // error -shape& h(shape&); // OK -\end{codeblock} -\exitexample - -\pnum -\indextext{virtual~function!pure}% -A class is abstract if it contains or inherits at least one pure virtual -function for which the final overrider is pure virtual. -\enterexample -\begin{codeblock} -class ab_circle : public shape { - int radius; -public: - void rotate(int) { } - // \tcode{ab_circle::draw()} is a pure virtual -}; -\end{codeblock} - -Since \tcode{shape::draw()} is a pure virtual function -\tcode{ab_circle::draw()} is a pure virtual by default. The alternative -declaration, -\begin{codeblock} -class circle : public shape { - int radius; -public: - void rotate(int) { } - void draw(); // a definition is required somewhere -}; -\end{codeblock} -would make class \tcode{circle} nonabstract and a definition of -\tcode{circle::draw()} must be provided. -\exitexample - -\pnum -\enternote -An abstract class can be derived from a class that is not abstract, and -a pure virtual function may override a virtual function which is not -pure. -\exitnote - -\pnum -\indextext{class!constructor~and abstract}% -Member functions can be called from a constructor (or destructor) of an -abstract class; -\indextext{virtual~function~call!undefined pure}% -the effect of making a virtual call~(\ref{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.% -\indextext{derived~class|)} diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 931199e701..d842475bd9 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -4,28 +4,33 @@ \rSec1[diagnostics.general]{General} \pnum -This Clause describes components that \Cpp programs may use to detect and +This Clause describes components that \Cpp{} programs may use to detect and report error conditions. \pnum The following subclauses describe components for reporting several kinds of exceptional conditions, -documenting program assertions, and +documenting program assertions, +obtaining stacktraces, and a global variable for error number codes, -as summarized in Table~\ref{tab:diagnostics.lib.summary}. +as summarized in \tref{diagnostics.summary}. -\begin{libsumtab}{Diagnostics library summary}{tab:diagnostics.lib.summary} +\begin{libsumtab}{Diagnostics library summary}{diagnostics.summary} \ref{std.exceptions} & Exception classes & \tcode{} \\ \rowsep \ref{assertions} & Assertions & \tcode{} \\ \rowsep \ref{errno} & Error numbers & \tcode{} \\ \rowsep \ref{syserr} & System error support & \tcode{} \\ \rowsep +\ref{stacktrace} & Stacktrace & \tcode{} \\ \rowsep +\ref{debugging} & Debugging & \tcode{} \\ \end{libsumtab} \rSec1[std.exceptions]{Exception classes} +\rSec2[std.exceptions.general]{General} + \pnum -The Standard \Cpp library provides classes to be used to report certain errors~(\ref{res.on.exception.handling}) in -\Cpp programs. +The \Cpp{} standard library provides classes to be used to report certain errors\iref{res.on.exception.handling} in +\Cpp{} programs. In the error model reflected in these classes, errors are divided into two broad categories: \term{logic} @@ -41,25 +46,21 @@ \pnum By contrast, runtime errors are due to events beyond the scope of the program. They cannot be easily predicted in advance. -The header -\tcode{} -\indextext{\idxhdr{stdexcept}}% -\indexlibrary{\idxhdr{stdexcept}}% -defines several types of predefined exceptions for reporting errors in a \Cpp program. +The header \libheaderdef{stdexcept} +defines several types of predefined exceptions for reporting errors in a \Cpp{} program. These exceptions are related by inheritance. -\synopsis{Header \tcode{} synopsis} - -\indexlibrary{\idxhdr{stdexcept}}% -\indexlibrary{\idxcode{logic_error}}% -\indexlibrary{\idxcode{domain_error}}% -\indexlibrary{\idxcode{invalid_argument}}% -\indexlibrary{\idxcode{length_error}}% -\indexlibrary{\idxcode{out_of_range_error}}% -\indexlibrary{\idxcode{runtime_error}}% -\indexlibrary{\idxcode{range_error}}% -\indexlibrary{\idxcode{overflow_error}}% -\indexlibrary{\idxcode{underflow_error}}% +\rSec2[stdexcept.syn]{Header \tcode{} synopsis} + +\indexlibraryglobal{logic_error}% +\indexlibraryglobal{domain_error}% +\indexlibraryglobal{invalid_argument}% +\indexlibraryglobal{length_error}% +\indexlibraryglobal{out_of_range}% +\indexlibraryglobal{runtime_error}% +\indexlibraryglobal{range_error}% +\indexlibraryglobal{overflow_error}% +\indexlibraryglobal{underflow_error}% \begin{codeblock} namespace std { class logic_error; @@ -76,13 +77,13 @@ \rSec2[logic.error]{Class \tcode{logic_error}} -\indexlibrary{\idxcode{logic_error}}% +\indexlibraryglobal{logic_error}% \begin{codeblock} 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} @@ -95,47 +96,37 @@ the program executes, such as violations of logical preconditions or class invariants. -\indexlibrary{\idxcode{logic_error}!\tcode{logic_error}}% +\indexlibraryctor{logic_error}% \begin{itemdecl} -logic_error(const string& what_arg); +constexpr logic_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{logic_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} -\indexlibrary{\idxcode{logic_error}!\tcode{logic_error}}% +\indexlibraryctor{logic_error}% \begin{itemdecl} -logic_error(const char* what_arg); +constexpr logic_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{logic_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} \rSec2[domain.error]{Class \tcode{domain_error}} -\indexlibrary{\idxcode{domain_error}}% +\indexlibraryglobal{domain_error}% \begin{codeblock} 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} @@ -146,47 +137,37 @@ defines the type of objects thrown as exceptions by the implementation to report domain errors. -\indexlibrary{\idxcode{domain_error}!\tcode{domain_error}}% +\indexlibraryctor{domain_error}% \begin{itemdecl} -domain_error(const string& what_arg); +constexpr domain_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{domain_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} -\indexlibrary{\idxcode{domain_error}!\tcode{domain_error}}% +\indexlibraryctor{domain_error}% \begin{itemdecl} -domain_error(const char* what_arg); +constexpr domain_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{domain_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} \rSec2[invalid.argument]{Class \tcode{invalid_argument}} -\indexlibrary{\idxcode{invalid_argument}}% +\indexlibraryglobal{invalid_argument}% \begin{codeblock} 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} @@ -196,47 +177,37 @@ \tcode{invalid_argument} defines the type of objects thrown as exceptions to report an invalid argument. -\indexlibrary{\idxcode{invalid_argument}!\tcode{invalid_argument}}% +\indexlibraryctor{invalid_argument}% \begin{itemdecl} -invalid_argument(const string& what_arg); +constexpr invalid_argument(const string& what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{invalid_argument}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} -\indexlibrary{\idxcode{invalid_argument}!\tcode{invalid_argument}}% +\indexlibraryctor{invalid_argument}% \begin{itemdecl} -invalid_argument(const char* what_arg); +constexpr invalid_argument(const char* what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{invalid_argument}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} \rSec2[length.error]{Class \tcode{length_error}} -\indexlibrary{\idxcode{length_error}}% +\indexlibraryglobal{length_error}% \begin{codeblock} 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} @@ -248,47 +219,37 @@ to report an attempt to produce an object whose length exceeds its maximum allowable size. -\indexlibrary{\idxcode{length_error}!\tcode{length_error}}% +\indexlibraryctor{length_error}% \begin{itemdecl} -length_error(const string& what_arg); +constexpr length_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{length_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} -\indexlibrary{\idxcode{length_error}!\tcode{length_error}}% +\indexlibraryctor{length_error}% \begin{itemdecl} -length_error(const char* what_arg); +constexpr length_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{length_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} \rSec2[out.of.range]{Class \tcode{out_of_range}} -\indexlibrary{\idxcode{out_of_range}}% +\indexlibraryglobal{out_of_range}% \begin{codeblock} 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} @@ -300,47 +261,37 @@ argument value not in its expected range. \indextext{argument} -\indexlibrary{\idxcode{out_of_range}!\tcode{out_of_range}}% +\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} \pnum -\effects -Constructs an object of class -\tcode{out_of_range}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} -\indexlibrary{\idxcode{out_of_range}!\tcode{out_of_range}}% +\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} \pnum -\effects -Constructs an object of class -\tcode{out_of_range}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} \rSec2[runtime.error]{Class \tcode{runtime_error}} -\indexlibrary{\idxcode{runtime_error}}% +\indexlibraryglobal{runtime_error}% \begin{codeblock} 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} @@ -351,47 +302,37 @@ defines the type of objects thrown as exceptions to report errors presumably detectable only when the program executes. -\indexlibrary{\idxcode{runtime_error}!\tcode{runtime_error}}% +\indexlibraryctor{runtime_error}% \begin{itemdecl} -runtime_error(const string& what_arg); +constexpr runtime_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{runtime_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} -\indexlibrary{\idxcode{runtime_error}!\tcode{runtime_error}}% +\indexlibraryctor{runtime_error}% \begin{itemdecl} -runtime_error(const char* what_arg); +constexpr runtime_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{runtime_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} \rSec2[range.error]{Class \tcode{range_error}} -\indexlibrary{\idxcode{range_error}}% +\indexlibraryglobal{range_error}% \begin{codeblock} 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} @@ -402,47 +343,37 @@ defines the type of objects thrown as exceptions to report range errors in internal computations. -\indexlibrary{\idxcode{range_error}!\tcode{range_error}}% +\indexlibraryctor{range_error}% \begin{itemdecl} -range_error(const string& what_arg); +constexpr range_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{range_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} -\indexlibrary{\idxcode{range_error}!\tcode{range_error}}% +\indexlibraryctor{range_error}% \begin{itemdecl} -range_error(const char* what_arg); +constexpr range_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{range_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} \rSec2[overflow.error]{Class \tcode{overflow_error}} -\indexlibrary{\idxcode{overflow_error}}% +\indexlibraryglobal{overflow_error}% \begin{codeblock} 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} @@ -452,47 +383,37 @@ \tcode{overflow_error} defines the type of objects thrown as exceptions to report an arithmetic overflow error. -\indexlibrary{\idxcode{overflow_error}!\tcode{overflow_error}}% +\indexlibraryctor{overflow_error}% \begin{itemdecl} -overflow_error(const string& what_arg); +constexpr overflow_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{overflow_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} -\indexlibrary{\idxcode{overflow_error}!\tcode{overflow_error}}% +\indexlibraryctor{overflow_error}% \begin{itemdecl} -overflow_error(const char* what_arg); +constexpr overflow_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{overflow_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} \rSec2[underflow.error]{Class \tcode{underflow_error}} -\indexlibrary{\idxcode{overflow_error}}% +\indexlibraryglobal{underflow_error}% \begin{codeblock} 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} @@ -502,186 +423,226 @@ \tcode{underflow_error} defines the type of objects thrown as exceptions to report an arithmetic underflow error. -\indexlibrary{\idxcode{underflow_error}!\tcode{underflow_error}}% +\indexlibraryctor{underflow_error}% \begin{itemdecl} -underflow_error(const string& what_arg); +constexpr underflow_error(const string& what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{underflow_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg.c_str()) == 0}. \end{itemdescr} -\indexlibrary{\idxcode{underflow_error}!\tcode{underflow_error}}% +\indexlibraryctor{underflow_error}% \begin{itemdecl} -underflow_error(const char* what_arg); +constexpr underflow_error(const char* what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{underflow_error}. - -\pnum -\postcondition +\ensures \tcode{strcmp(what(), what_arg) == 0}. \end{itemdescr} \rSec1[assertions]{Assertions} +\rSec2[assertions.general]{General} + \pnum -The header -\tcode{}, described in -(Table~\ref{tab:diagnostics.hdr.cassert}), -provides a macro for documenting \Cpp program assertions and a mechanism -for disabling the assertion checks. +The header \libheaderdef{cassert} +provides a macro for documenting \Cpp{} program assertions and a mechanism +for disabling the assertion checks through defining the macro \tcode{NDEBUG}. -\begin{libsyntab2}{cassert}{tab:diagnostics.hdr.cassert} -\macro & \tcode{assert} \\ -\end{libsyntab2} +\rSec2[cassert.syn]{Header \tcode{} synopsis} + +\begin{codeblock} +#define @\libmacro{assert}@(...) @\seebelow@ +\end{codeblock} + +\rSec2[assertions.assert]{The \tcode{assert} macro} \pnum -The contents are the same as the Standard C library header -\tcode{}. +If \tcode{NDEBUG} is defined as a macro name +at the point in the source file where \tcode{} is included, +the \tcode{assert} macro is defined as +\begin{codeblock} +#define @\libmacro{assert}@(...) ((void)0) +\end{codeblock} -\xref -ISO C 7.2. +\pnum +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: + +\begin{itemize} +\item +\mname{VA_ARGS} is evaluated and contextually converted to \tcode{bool}. +\item +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 (\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 +information on +the name of the source file, +the source line number, and +the name of the enclosing function +(such as provided by \tcode{source_location::current()}). +\end{itemize} + +\pnum +If \mname{VA_ARGS} does not expand to +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 +the current state of \tcode{NDEBUG} each time that +\tcode{} is included. + +\pnum +An expression \tcode{assert(E)} +is a constant subexpression\iref{defns.const.subexpr}, if +\begin{itemize} +\item +\tcode{NDEBUG} is defined at the point where \tcode{assert} +is last defined or redefined, or +\item +\tcode{E} contextually converted to \tcode{bool}\iref{conv} +is a constant subexpression that evaluates to the value \tcode{true}. +\end{itemize} \rSec1[errno]{Error numbers} +\rSec2[errno.general]{General} + \pnum -The header \tcode{} is described in Table~\ref{tab:diagnostics.hdr.cerrno}. Its contents are the same as the POSIX header \tcode{}, except that \tcode{errno} shall be defined as a macro. \enternote The intent is to remain in close alignment with the POSIX standard. \exitnote A separate \tcode{errno} value shall be provided for each thread. - -\begin{libsyntab6}{cerrno}{tab:diagnostics.hdr.cerrno} - -\macros & -\tcode{ECONNREFUSED} & -\tcode{EIO} & -\tcode{ENODEV} & -\tcode{ENOTEMPTY} & -\tcode{ERANGE} \\ - -\tcode{E2BIG} & -\tcode{ECONNRESET} & -\tcode{EISCONN} & -\tcode{ENOENT} & -\tcode{ENOTRECOVERABLE} & -\tcode{EROFS} \\ - -\tcode{EACCES} & -\tcode{EDEADLK} & -\tcode{EISDIR} & -\tcode{ENOEXEC} & -\tcode{ENOTSOCK} & -\tcode{ESPIPE} \\ - -\tcode{EADDRINUSE} & -\tcode{EDESTADDRREQ} & -\tcode{ELOOP} & -\tcode{ENOLCK} & -\tcode{ENOTSUP} & -\tcode{ESRCH} \\ - -\tcode{EADDRNOTAVAIL} & -\tcode{EDOM} & -\tcode{EMFILE} & -\tcode{ENOLINK} & -\tcode{ENOTTY} & -\tcode{ETIME} \\ - -\tcode{EAFNOSUPPORT} & -\tcode{EEXIST} & -\tcode{EMLINK} & -\tcode{ENOMEM} & -\tcode{ENXIO} & -\tcode{ETIMEDOUT} \\ - -\tcode{EAGAIN} & -\tcode{EFAULT} & -\tcode{EMSGSIZE} & -\tcode{ENOMSG} & -\tcode{EOPNOTSUPP} & -\tcode{ETXTBSY} \\ - -\tcode{EALREADY} & -\tcode{EFBIG} & -\tcode{ENAMETOOLONG} & -\tcode{ENOPROTOOPT} & -\tcode{EOVERFLOW} & -\tcode{EWOULDBLOCK} \\ - -\tcode{EBADF} & -\tcode{EHOSTUNREACH} & -\tcode{ENETDOWN} & -\tcode{ENOSPC} & -\tcode{EOWNERDEAD} & -\tcode{EXDEV} \\ - -\tcode{EBADMSG} & -\tcode{EIDRM} & -\tcode{ENETRESET} & -\tcode{ENOSR} & -\tcode{EPERM} & -\tcode{errno} \\ - -\tcode{EBUSY} & -\tcode{EILSEQ} & -\tcode{ENETUNREACH} & -\tcode{ENOSTR} & -\tcode{EPIPE} & \\ - -\tcode{ECANCELED} & -\tcode{EINPROGRESS} & -\tcode{ENFILE} & -\tcode{ENOSYS} & -\tcode{EPROTO} & \\ - -\tcode{ECHILD} & -\tcode{EINTR} & -\tcode{ENOBUFS} & -\tcode{ENOTCONN} & -\tcode{EPROTONOSUPPORT} & \\ - -\tcode{ECONNABORTED} & -\tcode{EINVAL} & -\tcode{ENODATA} & -\tcode{ENOTDIR} & -\tcode{EPROTOTYPE} & \\ - -\end{libsyntab6} +The contents of the header \libheaderdef{cerrno} are the same as the POSIX header +\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} +A separate \tcode{errno} value is provided for each thread. + +\rSec2[cerrno.syn]{Header \tcode{} synopsis} + +\begin{codeblock} +#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 +The meaning of the macros in this header is defined by the POSIX standard. + +\xrefc{7.5} \rSec1[syserr]{System error support} +\rSec2[syserr.general]{General} + \pnum -This subclause describes components that the standard library and -\Cpp programs may use to report error conditions originating from +Subclause \ref{syserr} describes components that the standard library and +\Cpp{} programs may use to report error conditions originating from the operating system or other low-level application program interfaces. \pnum -Components described in this subclause shall not change the value of -\tcode{errno}~(\ref{errno}). +Components described in \ref{syserr} do not change the value of +\tcode{errno}\iref{errno}. + +\recommended Implementations should leave the error states provided by other libraries unchanged. -\synopsis{Header \tcode{} synopsis} - -\indexlibrary{\idxcode{error_category}}% -\indexlibrary{\idxcode{error_code}}% -\indexlibrary{\idxcode{error_condition}}% -\indexlibrary{\idxcode{system_error}}% -\indexlibrary{\idxcode{is_error_code_enum}}% -\indexlibrary{\idxcode{is_error_condition_enum}}% -\indexlibrary{\idxcode{errc}}% -\indexlibrary{\idxcode{make_error_code}}% -\indexlibrary{\idxcode{make_error_condition}}% +\rSec2[system.error.syn]{Header \tcode{} synopsis} + +\indexheader{system_error}% +\indexlibraryglobal{error_category}% +\indexlibraryglobal{error_code}% +\indexlibraryglobal{error_condition}% +\indexlibraryglobal{system_error}% \begin{codeblock} +#include // see \ref{compare.syn} + namespace std { class error_category; const error_category& generic_category() noexcept; @@ -691,145 +652,157 @@ class error_condition; class system_error; - template - struct is_error_code_enum : public false_type {}; - - template - struct is_error_condition_enum : public false_type {}; - - enum class errc { - 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_available, // \tcode{ENODATA} - no_message, // \tcode{ENOMSG} - no_protocol_option, // \tcode{ENOPROTOOPT} - no_space_on_device, // \tcode{ENOSPC} - no_stream_resources, // \tcode{ENOSR} - 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_a_stream, // \tcode{ENOSTR} - 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} - stream_timeout, // \tcode{ETIME} - 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} + template + struct @\libglobal{is_error_code_enum}@ : public false_type {}; + + template + struct @\libglobal{is_error_condition_enum}@ : public false_type {}; + + enum class @\libglobal{errc}@ { // freestanding + @\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 { } + template<> struct is_error_condition_enum : true_type {}; + + // \ref{syserr.errcode.nonmembers}, non-member functions error_code make_error_code(errc e) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const error_code& ec); + + // \ref{syserr.errcondition.nonmembers}, non-member functions error_condition make_error_condition(errc e) noexcept; - // \ref{syserr.compare} Comparison operators: + // \ref{syserr.compare}, comparison operator functions bool operator==(const error_code& lhs, const error_code& rhs) noexcept; bool operator==(const error_code& lhs, const error_condition& rhs) noexcept; - bool operator==(const error_condition& lhs, const error_code& rhs) noexcept; bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept; - bool operator!=(const error_code& lhs, const error_code& rhs) noexcept; - bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept; - bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; - bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept; - - // \ref{syserr.hash} Hash support - template struct hash; - template <> struct hash; -} // namespace std + strong_ordering operator<=>(const error_code& lhs, const error_code& rhs) noexcept; + strong_ordering operator<=>(const error_condition& lhs, const error_condition& rhs) noexcept; + + // \ref{syserr.hash}, hash support + template struct hash; + template<> struct hash; + template<> struct hash; + + // \ref{syserr}, system error support + template + constexpr bool @\libglobal{is_error_code_enum_v}@ = is_error_code_enum::value; + template + constexpr bool @\libglobal{is_error_condition_enum_v}@ = is_error_condition_enum::value; +} \end{codeblock} -\pnum The value of each \tcode{enum errc} constant shall be the same as -the value of the \tcode{} macro shown in the above synopsis. Whether -or not the \tcode{} implementation exposes the \tcode{} -macros is unspecified. +\pnum +The value of each \tcode{enum errc} enumerator is the same as +the value of the \libheader{cerrno} macro shown in the above synopsis. +Whether or not the \libheader{system_error} implementation +exposes the \libheader{cerrno} macros is unspecified. \pnum -The \tcode{is_error_code_enum} and \tcode{is_error_condition_enum} may be -specialized for user-defined types to indicate that such types are eligible -for \tcode{class error_code} and \tcode{class error_condition} automatic +The \tcode{is_error_code_enum} and \tcode{is_error_condition_enum} templates may be +specialized for program-defined types to indicate that such types are eligible +for \tcode{class error_code} and \tcode{class error_condition} implicit conversions, respectively. \rSec2[syserr.errcat]{Class \tcode{error_category}} -\rSec3[syserr.errcat.overview]{Class \tcode{error_category} overview} +\rSec3[syserr.errcat.overview]{Overview} \pnum The class \tcode{error_category} serves as a base class for types used to identify the source and encoding of a particular category of error code. Classes may be derived from \tcode{error_category} to support -categories of errors in addition to those defined in this International -Standard. -Such classes shall behave as specified in this -subclause. \enternote \tcode{error_category} objects are +categories of errors in addition to those defined in this document. +Such classes shall behave as specified in subclause~\ref{syserr.errcat}. +\begin{note} +\tcode{error_category} objects are passed by reference, and two such objects -are equal if they have the same address. This means that applications using -custom \tcode{error_category} types should create a single object of each -such type. \exitnote - -\indexlibrary{\idxcode{error_category}}% -\indexlibrary{\idxcode{generic_category}}% -\indexlibrary{\idxcode{system_category}}% +are equal if they have the same address. +If there is more than a single object of a custom \tcode{error_category} type, +such equality comparisons can evaluate to \tcode{false} +even for objects holding the same value. +\end{note} + +\indexlibraryglobal{error_category}% +\indexlibraryctor{error_category}% +\indexlibrarydtor{error_category}% +\indexlibraryglobal{generic_category}% +\indexlibraryglobal{system_category}% \begin{codeblock} namespace std { class error_category { @@ -843,43 +816,30 @@ virtual bool equivalent(int code, const error_condition& condition) const noexcept; virtual bool equivalent(const error_code& code, int condition) const noexcept; virtual string message(int ev) const = 0; - + bool operator==(const error_category& rhs) const noexcept; - bool operator!=(const error_category& rhs) const noexcept; - bool operator<(const error_category& rhs) const noexcept; + strong_ordering operator<=>(const error_category& rhs) const noexcept; }; const error_category& generic_category() noexcept; const error_category& system_category() noexcept; - -} // namespace std +} \end{codeblock} -\rSec3[syserr.errcat.virtuals]{Class \tcode{error_category} virtual members} - -\indexlibrary{\idxcode{error_category}!destructor}% -\begin{itemdecl} -virtual ~error_category(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Destroys an object of class \tcode{error_category}. -\end{itemdescr} +\rSec3[syserr.errcat.virtuals]{Virtual members} -\indexlibrary{\idxcode{name}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{name}} +\indexlibrarymember{name}{error_category}% \begin{itemdecl} virtual const char* name() const noexcept = 0; \end{itemdecl} \begin{itemdescr} \pnum -\returns A string naming the error category. +\returns +A string naming the error category. \end{itemdescr} -\indexlibrary{\idxcode{default_error_condition}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{default_error_condition}} +\indexlibrarymember{default_error_condition}{error_category}% \begin{itemdecl} virtual error_condition default_error_condition(int ev) const noexcept; \end{itemdecl} @@ -890,201 +850,194 @@ \tcode{error_condition(ev, *this)}. \end{itemdescr} -\indexlibrary{\idxcode{equivalent}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{equivalent}} +\indexlibrarymember{equivalent}{error_category}% \begin{itemdecl} virtual bool equivalent(int code, const error_condition& condition) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{default_error_condition(code) == condition}. +\returns +\tcode{default_error_condition(code) == condition}. \end{itemdescr} -\indexlibrary{\idxcode{equivalent}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{equivalent}} +\indexlibrarymember{equivalent}{error_category}% \begin{itemdecl} virtual bool equivalent(const error_code& code, int condition) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{*this == code.category() \&\& code.value() == condition}. +\returns +\tcode{*this == code.category() \&\& code.value() == condition}. \end{itemdescr} -\indexlibrary{\idxcode{message}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{message}} +\indexlibrarymember{message}{error_category}% \begin{itemdecl} virtual string message(int ev) const = 0; \end{itemdecl} \begin{itemdescr} \pnum -\returns A string that describes the error condition denoted by \tcode{ev}. +\returns +A string that describes the error condition denoted by \tcode{ev}. \end{itemdescr} -\rSec3[syserr.errcat.nonvirtuals]{Class \tcode{error_category} non-virtual members} - -\indexlibrary{\idxcode{error_category}!constructor}% -\begin{itemdecl} -constexpr error_category() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Constructs an object of class \tcode{error_category}. -\end{itemdescr} +\rSec3[syserr.errcat.nonvirtuals]{Non-virtual members} -\indexlibrary{\idxcode{operator==}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{operator==}} +\indexlibrarymember{operator==}{error_category}% \begin{itemdecl} bool operator==(const error_category& rhs) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{this == \&rhs}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator"!=}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{operator"!=}} -\begin{itemdecl} -bool operator!=(const error_category& rhs) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(*this == rhs)}. +\returns +\tcode{this == \&rhs}. \end{itemdescr} -\indexlibrary{\idxcode{operator<}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{operator<}} +\indexlibrarymember{operator<=>}{error_category}% \begin{itemdecl} -bool operator<(const error_category& rhs) const noexcept; +strong_ordering operator<=>(const error_category& rhs) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{less()(this, \&rhs)}. +\returns +\tcode{compare_three_way()(this, \&rhs)}. -\enternote \tcode{less}~(\ref{comparisons}) provides a total ordering for pointers. \exitnote +\begin{note} +\tcode{compare_three_way}\iref{comparisons.three.way} provides a total ordering for pointers. +\end{note} \end{itemdescr} -\rSec3[syserr.errcat.derived]{Program defined classes derived from \tcode{error_category}} +\rSec3[syserr.errcat.derived]{Program-defined classes derived from \tcode{error_category}} -\indexlibrary{\idxcode{name}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{name}} +\indexlibrarymember{name}{error_category}% \begin{itemdecl} virtual const char* name() const noexcept = 0; \end{itemdecl} \begin{itemdescr} \pnum -\returns A string naming the error category. +\returns +A string naming the error category. \end{itemdescr} -\indexlibrary{\idxcode{default_error_condition}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{default_error_condition}} +\indexlibrarymember{default_error_condition}{error_category}% \begin{itemdecl} virtual error_condition default_error_condition(int ev) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns An object of type \tcode{error_condition} that corresponds to \tcode{ev}. +\returns +An object of type \tcode{error_condition} that corresponds to \tcode{ev}. \end{itemdescr} -\indexlibrary{\idxcode{equivalent}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{equivalent}} +\indexlibrarymember{equivalent}{error_category}% \begin{itemdecl} virtual bool equivalent(int code, const error_condition& condition) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{true} if, for the category of error represented by \tcode{*this}, \tcode{code} is considered equivalent to \tcode{condition}; otherwise, \tcode{false}. +\returns +\tcode{true} if, for the category of error represented by \tcode{*this}, \tcode{code} is considered equivalent to \tcode{condition}; otherwise, \tcode{false}. \end{itemdescr} -\indexlibrary{\idxcode{equivalent}!\idxcode{error_category}} -\indexlibrary{\idxcode{error_category}!\idxcode{equivalent}} +\indexlibrarymember{equivalent}{error_category}% \begin{itemdecl} virtual bool equivalent(const error_code& code, int condition) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{true} if, for the category of error represented by \tcode{*this}, \tcode{code} is considered equivalent to \tcode{condition}; otherwise, \tcode{false}. +\returns +\tcode{true} if, for the category of error represented by \tcode{*this}, \tcode{code} is considered equivalent to \tcode{condition}; otherwise, \tcode{false}. \end{itemdescr} \rSec3[syserr.errcat.objects]{Error category objects} -\indexlibrary{\idxcode{generic_category}} +\indexlibraryglobal{generic_category}% \begin{itemdecl} const error_category& generic_category() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns A reference to an object of a type derived from class \tcode{error_category}. +\returns +A reference to an object of a type derived from class \tcode{error_category}. All calls to this function shall return references to the same object. \pnum -\notes The object's \tcode{default_error_condition} and \tcode{equivalent} virtual functions shall behave as specified for the class \tcode{error_category}. The object's \tcode{name} virtual function shall return a pointer to the string \tcode{"generic"}. +\remarks +The object's \tcode{default_error_condition} and \tcode{equivalent} virtual functions shall behave as specified for the class \tcode{error_category}. The object's \tcode{name} virtual function shall return a pointer to the string \tcode{"generic"}. \end{itemdescr} -\indexlibrary{\idxcode{system_category}} +\indexlibraryglobal{system_category}% \begin{itemdecl} const error_category& system_category() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns A reference to an object of a type derived from class \tcode{error_category}. +\returns +A reference to an object of a type derived from class \tcode{error_category}. All calls to this function shall return references to the same object. \pnum -\notes The object's \tcode{equivalent} virtual functions shall behave as specified for +\remarks +The object's \tcode{equivalent} virtual functions shall behave as specified for class \tcode{error_category}. The object's \tcode{name} virtual function shall return a pointer to the string \tcode{"system"}. The object's \tcode{default_error_condition} virtual function shall behave as follows: -If the argument \tcode{ev} corresponds to a POSIX \tcode{errno} value \tcode{posv}, the -function shall return \tcode{error_condition(posv, generic_category())}. -Otherwise, the function shall return \tcode{error_condition(ev, -system_category())}. What constitutes correspondence for any given operating -system is unspecified. \enternote The number of potential system error codes is large -and unbounded, and some may not correspond to any POSIX \tcode{errno} value. Thus -implementations are given latitude in determining correspondence. \exitnote +If the argument \tcode{ev} is equal to 0, +the function returns \tcode{error_condition(0, generic_category())}. +Otherwise, +if \tcode{ev} corresponds to a POSIX \tcode{errno} value \tcode{pxv}, +the function returns \tcode{error_condition(pxv, generic_category())}. +Otherwise, the function returns \tcode{error_condition(ev, system_category())}. +What constitutes correspondence for any given operating system is unspecified. +\begin{note} +The number of potential system error codes is large +and unbounded, and some might not correspond to any POSIX \tcode{errno} value. Thus +implementations are given latitude in determining correspondence. +\end{note} \end{itemdescr} \rSec2[syserr.errcode]{Class \tcode{error_code}} -\rSec3[syserr.errcode.overview]{Class \tcode{error_code} overview} +\rSec3[syserr.errcode.overview]{Overview} \pnum The class \tcode{error_code} describes an object used to hold error code values, such as those originating from the operating system or other low-level -application program interfaces. \enternote Class \tcode{error_code} is an -adjunct to error reporting by exception. \exitnote +application program interfaces. +\begin{note} +Class \tcode{error_code} is an +adjunct to error reporting by exception. +\end{note} -\indexlibrary{\idxcode{error_code}}% +\indexlibraryglobal{error_code}% \begin{codeblock} namespace std { class error_code { public: - // \ref{syserr.errcode.constructors} constructors: + // \ref{syserr.errcode.constructors}, constructors error_code() noexcept; error_code(int val, const error_category& cat) noexcept; - template + template error_code(ErrorCodeEnum e) noexcept; - // \ref{syserr.errcode.modifiers} modifiers: + // \ref{syserr.errcode.modifiers}, modifiers void assign(int val, const error_category& cat) noexcept; - template - error_code& operator=(ErrorCodeEnum e) noexcept; + template + error_code& operator=(ErrorCodeEnum e) noexcept; void clear() noexcept; - // \ref{syserr.errcode.observers} observers: + // \ref{syserr.errcode.observers}, observers int value() const noexcept; const error_category& category() const noexcept; error_condition default_error_condition() const noexcept; @@ -1092,489 +1045,480 @@ explicit operator bool() const noexcept; private: - int val_; // \expos - const error_category* cat_; // \expos + int @\exposid{val_}@; // \expos + const error_category* @\exposid{cat_}@; // \expos }; - // \ref{syserr.errcode.nonmembers} non-member functions: + // \ref{syserr.errcode.nonmembers}, non-member functions error_code make_error_code(errc e) noexcept; - bool operator<(const error_code& lhs, const error_code& rhs) noexcept; - template - basic_ostream& - operator<<(basic_ostream& os, const error_code& ec); -} // namespace std + template + basic_ostream& + operator<<(basic_ostream& os, const error_code& ec); +} \end{codeblock} -\rSec3[syserr.errcode.constructors]{Class \tcode{error_code} constructors} +\rSec3[syserr.errcode.constructors]{Constructors} -\indexlibrary{\idxcode{error_code}!\idxcode{error_code}} -\indexlibrary{\idxcode{error_code}!\idxcode{error_code}} +\indexlibraryctor{error_code}% \begin{itemdecl} error_code() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of type \tcode{error_code}. - -\pnum -\postconditions \tcode{val_ == 0} and \tcode{cat_ == \&system_category()}. +\effects +Initializes \exposid{val_} with \tcode{0} +and \exposid{cat_} with \tcode{\&system_category()}. \end{itemdescr} -\indexlibrary{\idxcode{error_code}!\idxcode{error_code}} -\indexlibrary{\idxcode{error_code}!\idxcode{error_code}} +\indexlibraryctor{error_code}% \begin{itemdecl} error_code(int val, const error_category& cat) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of type \tcode{error_code}. - -\pnum -\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}. +\effects +Initializes \exposid{val_} with \tcode{val} +and \exposid{cat_} with \tcode{\&cat}. \end{itemdescr} -\indexlibrary{\idxcode{error_code}!\idxcode{error_code}} -\indexlibrary{\idxcode{error_code}!\idxcode{error_code}} +\indexlibraryctor{error_code}% \begin{itemdecl} -template +template error_code(ErrorCodeEnum e) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of type \tcode{error_code}. - -\pnum -\postconditions \tcode{*this == make_error_code(e)}. +\constraints +\tcode{is_error_code_enum_v} is \tcode{true}. \pnum -\remarks This constructor shall not participate in overload resolution unless\linebreak -\tcode{is_error_code_enum::value} is \tcode{true}. +\effects +Equivalent to: +\begin{codeblock} +error_code ec = make_error_code(e); +assign(ec.value(), ec.category()); +\end{codeblock} \end{itemdescr} -\rSec3[syserr.errcode.modifiers]{Class \tcode{error_code} modifiers} +\rSec3[syserr.errcode.modifiers]{Modifiers} -\indexlibrary{\idxcode{assign}!\idxcode{error_code}} -\indexlibrary{\idxcode{error_code}!\idxcode{assign}} +\indexlibrarymember{assign}{error_code}% \begin{itemdecl} void assign(int val, const error_category& cat) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}. +\ensures +\tcode{\exposid{val_} == val} and \tcode{\exposid{cat_} == \&cat}. \end{itemdescr} -\indexlibrary{\idxcode{operator=}!\idxcode{error_code}} -\indexlibrary{\idxcode{error_code}!\idxcode{operator=}} +\indexlibrarymember{operator=}{error_code}% \begin{itemdecl} -template - error_code& operator=(ErrorCodeEnum e) noexcept; +template + error_code& operator=(ErrorCodeEnum e) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\postconditions \tcode{*this == make_error_code(e)}. +\constraints +\tcode{is_error_code_enum_v} is \tcode{true}. \pnum -\returns \tcode{*this}. +\effects +Equivalent to: +\begin{codeblock} +error_code ec = make_error_code(e); +assign(ec.value(), ec.category()); +\end{codeblock} \pnum -\remarks This operator shall not participate in overload resolution unless\linebreak -\tcode{is_error_code_enum::value} is \tcode{true}. +\returns +\tcode{*this}. \end{itemdescr} -\indexlibrary{\idxcode{clear}!\idxcode{error_code}} -\indexlibrary{\idxcode{error_code}!\idxcode{clear}} +\indexlibrarymember{clear}{error_code}% \begin{itemdecl} void clear() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\postconditions \tcode{value() == 0} and \tcode{category() == system_category()}. +\ensures +\tcode{value() == 0} and \tcode{category() == system_category()}. \end{itemdescr} -\rSec3[syserr.errcode.observers]{Class \tcode{error_code} observers} +\rSec3[syserr.errcode.observers]{Observers} -\indexlibrary{\idxcode{value}!\idxcode{error_code}} -\indexlibrary{\idxcode{error_code}!\idxcode{value}} +\indexlibrarymember{value}{error_code}% \begin{itemdecl} int value() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{val_}. +\returns +\exposid{val_}. \end{itemdescr} -\indexlibrary{\idxcode{category}!\idxcode{error_code}} -\indexlibrary{\idxcode{error_code}!\idxcode{category}} +\indexlibrarymember{category}{error_code}% \begin{itemdecl} const error_category& category() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{*cat_}. +\returns +\tcode{*\exposid{cat_}}. \end{itemdescr} -\indexlibrary{\idxcode{default_error_condition}!\idxcode{error_code}} -\indexlibrary{\idxcode{error_code}!\idxcode{default_error_condition}} +\indexlibrarymember{default_error_condition}{error_code}% \begin{itemdecl} error_condition default_error_condition() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{category().default_error_condition(value())}. +\returns +\tcode{category().default_error_condition(value())}. \end{itemdescr} -\indexlibrary{\idxcode{message}!\idxcode{error_code}} -\indexlibrary{\idxcode{error_code}!\idxcode{message}} +\indexlibrarymember{message}{error_code}% \begin{itemdecl} string message() const; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{category().message(value())}. +\returns +\tcode{category().message(value())}. \end{itemdescr} -\indexlibrary{\idxcode{operator bool}!\idxcode{error_code}} -\indexlibrary{\idxcode{error_code}!\idxcode{operator bool}} +\indexlibrarymember{operator bool}{error_code}% \begin{itemdecl} explicit operator bool() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{value() != 0}. +\returns +\tcode{value() != 0}. \end{itemdescr} -\rSec3[syserr.errcode.nonmembers]{Class \tcode{error_code} non-member functions} +\rSec3[syserr.errcode.nonmembers]{Non-member functions} -\indexlibrary{\idxcode{make_error_code}} +\indexlibrarymember{make_error_code}{errc}% \begin{itemdecl} error_code make_error_code(errc e) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{error_code(static_cast(e), generic_category())}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator<}!\idxcode{error_code}}% -\indexlibrary{\idxcode{error_code}!\idxcode{operator<}}% -\begin{itemdecl} -bool operator<(const error_code& lhs, const error_code& rhs) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{lhs.category() < rhs.category() || lhs.category() == rhs.category() \&\& lhs.value() < rhs.value()}. +\returns +\tcode{error_code(static_cast(e), generic_category())}. \end{itemdescr} -\indexlibrary{\idxcode{operator\shl}!\idxcode{error_code}}% -\indexlibrary{\idxcode{error_code}!\idxcode{operator\shl}}% +\indexlibrarymember{operator<<}{error_code}% \begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const error_code& ec); +template + basic_ostream& operator<<(basic_ostream& os, const error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum -\effects \tcode{os <{<} ec.category().name() <{<} ':' <{<} ec.value()}. +\effects +Equivalent to: \tcode{return os << ec.category().name() << ':' << ec.value();} \end{itemdescr} \rSec2[syserr.errcondition]{Class \tcode{error_condition}} -\rSec3[syserr.errcondition.overview]{Class \tcode{error_condition} overview} +\rSec3[syserr.errcondition.overview]{Overview} \pnum The class \tcode{error_condition} describes an object used to hold values identifying -error conditions. \enternote \tcode{error_condition} values are portable abstractions, -while \tcode{error_code} values~(\ref{syserr.errcode}) are implementation specific. \exitnote +error conditions. +\begin{note} +\tcode{error_condition} values are portable abstractions, +while \tcode{error_code} values\iref{syserr.errcode} are implementation specific. +\end{note} -\indexlibrary{\idxcode{error_code}}% +\indexlibraryglobal{error_condition}% \begin{codeblock} namespace std { class error_condition { public: - // \ref{syserr.errcondition.constructors} constructors: + // \ref{syserr.errcondition.constructors}, constructors error_condition() noexcept; error_condition(int val, const error_category& cat) noexcept; - template + template error_condition(ErrorConditionEnum e) noexcept; - // \ref{syserr.errcondition.modifiers} modifiers: + // \ref{syserr.errcondition.modifiers}, modifiers void assign(int val, const error_category& cat) noexcept; template - error_condition& operator=(ErrorConditionEnum e) noexcept; + error_condition& operator=(ErrorConditionEnum e) noexcept; void clear() noexcept; - // \ref{syserr.errcondition.observers} observers: + // \ref{syserr.errcondition.observers}, observers int value() const noexcept; const error_category& category() const noexcept; string message() const; explicit operator bool() const noexcept; private: - int val_; // \expos - const error_category* cat_; // \expos + int @\exposid{val_}@; // \expos + const error_category* @\exposid{cat_}@; // \expos }; - - // \ref{syserr.errcondition.nonmembers} non-member functions: - bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept; -} // namespace std +} \end{codeblock} -\rSec3[syserr.errcondition.constructors]{Class \tcode{error_condition} constructors} +\rSec3[syserr.errcondition.constructors]{Constructors} -\indexlibrary{\idxcode{error_condition}!constructor}% +\indexlibraryctor{error_condition}% \begin{itemdecl} error_condition() noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of type \tcode{error_condition}. - -\pnum -\postconditions \tcode{val_ == 0} and \tcode{cat_ == \&generic_category()}. +\effects +Initializes \exposid{val_} with \tcode{0} +and \exposid{cat_} with \tcode{\&generic_category()}. \end{itemdescr} -\indexlibrary{\idxcode{error_condition}!constructor}% +\indexlibraryctor{error_condition}% \begin{itemdecl} error_condition(int val, const error_category& cat) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of type \tcode{error_condition}. - -\pnum -\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}. +\effects +Initializes \exposid{val_} with \tcode{val} +and \exposid{cat_} with \tcode{\&cat}. \end{itemdescr} -\indexlibrary{\idxcode{error_condition}!constructor}% +\indexlibraryctor{error_condition}% \begin{itemdecl} -template +template error_condition(ErrorConditionEnum e) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of type \tcode{error_condition}. - -\pnum -\postcondition \tcode{*this == make_error_condition(e)}. +\constraints +\tcode{is_error_condition_enum_v} is \tcode{true}. \pnum -\remarks This constructor shall not participate in overload resolution unless\linebreak -\tcode{is_error_condition_enum::value} is \tcode{true}. +\effects +Equivalent to: +\begin{codeblock} +error_condition ec = make_error_condition(e); +assign(ec.value(), ec.category()); +\end{codeblock} \end{itemdescr} -\rSec3[syserr.errcondition.modifiers]{Class \tcode{error_condition} modifiers} +\rSec3[syserr.errcondition.modifiers]{Modifiers} -\indexlibrary{\idxcode{assign}!\idxcode{error_condition}} -\indexlibrary{\idxcode{error_condition}!\idxcode{assign}} +\indexlibrarymember{assign}{error_condition}% \begin{itemdecl} void assign(int val, const error_category& cat) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\postconditions \tcode{val_ == val} and \tcode{cat_ == \&cat}. +\ensures +\tcode{\exposid{val_} == val} and \tcode{\exposid{cat_} == \&cat}. \end{itemdescr} -\indexlibrary{\idxcode{operator=}!\idxcode{error_condition}} -\indexlibrary{\idxcode{error_condition}!\idxcode{operator=}} +\indexlibrarymember{operator=}{error_condition}% \begin{itemdecl} -template - error_condition& operator=(ErrorConditionEnum e) noexcept; +template + error_condition& operator=(ErrorConditionEnum e) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\postcondition \tcode{*this == make_error_condition(e)}. +\constraints +\tcode{is_error_condition_enum_v} is \tcode{true}. \pnum -\returns \tcode{*this}. +\effects +Equivalent to: +\begin{codeblock} +error_condition ec = make_error_condition(e); +assign(ec.value(), ec.category()); +\end{codeblock} \pnum -\remarks This operator shall not participate in overload resolution unless\linebreak -\tcode{is_error_condition_enum::value} is \tcode{true}. +\returns +\tcode{*this}. \end{itemdescr} -\indexlibrary{\idxcode{clear}!\idxcode{error_condition}} -\indexlibrary{\idxcode{error_condition}!\idxcode{clear}} +\indexlibrarymember{clear}{error_condition}% \begin{itemdecl} void clear() noexcept; \end{itemdecl} \begin{itemdescr} -\postconditions \tcode{value() == 0} and \tcode{category() == generic_category()}. +\pnum +\ensures +\tcode{value() == 0} and \tcode{category() == generic_category()}. \end{itemdescr} -\rSec3[syserr.errcondition.observers]{Class \tcode{error_condition} observers} +\rSec3[syserr.errcondition.observers]{Observers} -\indexlibrary{\idxcode{value}!\idxcode{error_condition}} -\indexlibrary{\idxcode{error_condition}!\idxcode{value}} +\indexlibrarymember{value}{error_condition}% \begin{itemdecl} int value() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{val_}. +\returns +\exposid{val_}. \end{itemdescr} -\indexlibrary{\idxcode{category}!\idxcode{error_condition}} -\indexlibrary{\idxcode{error_condition}!\idxcode{category}} +\indexlibrarymember{category}{error_condition}% \begin{itemdecl} const error_category& category() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{*cat_}. +\returns +\tcode{*\exposid{cat_}}. \end{itemdescr} -\indexlibrary{\idxcode{message}!\idxcode{error_condition}} -\indexlibrary{\idxcode{error_condition}!\idxcode{message}} +\indexlibrarymember{message}{error_condition}% \begin{itemdecl} string message() const; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{category().message(value())}. +\returns +\tcode{category().message(value())}. \end{itemdescr} -\indexlibrary{\idxcode{operator bool}!\idxcode{error_condition}} -\indexlibrary{\idxcode{error_condition}!\idxcode{operator bool}} +\indexlibrarymember{operator bool}{error_condition}% \begin{itemdecl} explicit operator bool() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{value() != 0}. +\returns +\tcode{value() != 0}. \end{itemdescr} -\rSec3[syserr.errcondition.nonmembers]{Class \tcode{error_condition} non-member functions} +\rSec3[syserr.errcondition.nonmembers]{Non-member functions} -\indexlibrary{\idxcode{make_error_condition}} +\indexlibrarymember{make_error_condition}{errc}% \begin{itemdecl} error_condition make_error_condition(errc e) noexcept; \end{itemdecl} -\begin{itemdescr} -\returns \tcode{error_condition(static_cast(e), generic_category())}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator<}!\idxcode{error_condition}}% -\indexlibrary{\idxcode{error_condition}!\idxcode{operator<}}% -\begin{itemdecl} -bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept; -\end{itemdecl} - \begin{itemdescr} \pnum -\returns \tcode{lhs.category() < rhs.category() || lhs.category() == rhs.category() \&\&\\ -lhs.value() < rhs.value()}. +\returns +\tcode{error_condition(static_cast(e), generic_category())}. \end{itemdescr} -\rSec2[syserr.compare]{Comparison operators} +\rSec2[syserr.compare]{Comparison operator functions} -\indexlibrary{\idxcode{operator==}!\idxcode{error_code}}% -\indexlibrary{\idxcode{error_code}!\idxcode{operator==}}% +\indexlibrarymember{operator==}{error_code}% \begin{itemdecl} bool operator==(const error_code& lhs, const error_code& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{lhs.category() == rhs.category() \&\& lhs.value() == rhs.value()}. +\returns +\begin{codeblock} +lhs.category() == rhs.category() && lhs.value() == rhs.value() +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{operator==}!\idxcode{error_condition}}% -\indexlibrary{\idxcode{error_condition}!\idxcode{operator==}}% -\indexlibrary{\idxcode{operator==}!\idxcode{error_code}}% -\indexlibrary{\idxcode{error_code}!\idxcode{operator==}}% +\indexlibrarymember{operator==}{error_condition}% +\indexlibrarymember{operator==}{error_code}% \begin{itemdecl} bool operator==(const error_code& lhs, const error_condition& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{lhs.category().equivalent(lhs.value(), rhs) || rhs.category().equivalent(lhs, -rhs.value())}. +\returns +\begin{codeblock} +lhs.category().equivalent(lhs.value(), rhs) || rhs.category().equivalent(lhs, rhs.value()) +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{operator==}!\idxcode{error_condition}}% -\indexlibrary{\idxcode{error_condition}!\idxcode{operator==}}% -\indexlibrary{\idxcode{operator==}!\idxcode{error_code}}% -\indexlibrary{\idxcode{error_code}!\idxcode{operator==}}% +\indexlibrarymember{operator==}{error_condition}% \begin{itemdecl} -bool operator==(const error_condition& lhs, const error_code& rhs) noexcept; +bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{rhs.category().equivalent(rhs.value(), lhs) || lhs.category().equivalent(rhs, lhs.value())}. +\returns +\begin{codeblock} +lhs.category() == rhs.category() && lhs.value() == rhs.value() +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{operator==}!\idxcode{error_condition}}% -\indexlibrary{\idxcode{error_condition}!\idxcode{operator==}}% +\indexlibrarymember{operator<=>}{error_code}% \begin{itemdecl} -bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept; +strong_ordering operator<=>(const error_code& lhs, const error_code& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{lhs.category() == rhs.category() \&\& lhs.value() == rhs.value()}. +\effects +Equivalent to: +\begin{codeblock} +if (auto c = lhs.category() <=> rhs.category(); c != 0) return c; +return lhs.value() <=> rhs.value(); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{operator"!=}!\idxcode{error_code}}% -\indexlibrary{\idxcode{error_code}!\idxcode{operator"!=}}% -\indexlibrary{\idxcode{operator"!=}!\idxcode{error_condition}}% -\indexlibrary{\idxcode{error_condition}!\idxcode{operator"!=}}% +\indexlibrarymember{operator<=>}{error_condition}% \begin{itemdecl} -bool operator!=(const error_code& lhs, const error_code& rhs) noexcept; -bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept; -bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; -bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept; +strong_ordering operator<=>(const error_condition& lhs, const error_condition& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{!(lhs == rhs)}. +\returns +\begin{codeblock} +if (auto c = lhs.category() <=> rhs.category(); c != 0) return c; +return lhs.value() <=> rhs.value(); +\end{codeblock} \end{itemdescr} \rSec2[syserr.hash]{System error hash support} -\indexlibrary{\idxcode{hash}}% +\indexlibrarymember{hash}{error_code}% \begin{itemdecl} -template <> struct hash; +template<> struct hash; +template<> struct hash; \end{itemdecl} \begin{itemdescr} -\pnum The template specialization shall meet the requirements of class template -\tcode{hash}~(\ref{unord.hash}). +\pnum +The specializations are enabled\iref{unord.hash}. \end{itemdescr} \rSec2[syserr.syserr]{Class \tcode{system_error}} -\rSec3[syserr.syserr.overview]{Class \tcode{system_error} overview} +\rSec3[syserr.syserr.overview]{Overview} \pnum The class \tcode{system_error} describes an exception object used to @@ -1583,11 +1527,12 @@ application program interfaces. \pnum -\enternote If an error represents an out-of-memory condition, implementations are -encouraged to throw an exception object of type \tcode{bad_alloc}~\ref{bad.alloc} rather -than \tcode{system_error}. \exitnote - -\indexlibrary{\idxcode{system_error}}% +\begin{note} +If an error represents an out-of-memory condition, implementations are +encouraged to throw an exception object of type \tcode{bad_alloc}\iref{bad.alloc} rather +than \tcode{system_error}. +\end{note} +\indexlibraryglobal{system_error}% \begin{codeblock} namespace std { class system_error : public runtime_error { @@ -1595,135 +1540,969 @@ system_error(error_code ec, const string& what_arg); system_error(error_code ec, const char* what_arg); system_error(error_code ec); - system_error(int ev, const error_category& ecat, - const string& what_arg); - system_error(int ev, const error_category& ecat, - const char* what_arg); + system_error(int ev, const error_category& ecat, const string& what_arg); + system_error(int ev, const error_category& ecat, const char* what_arg); system_error(int ev, const error_category& ecat); const error_code& code() const noexcept; - const char* what() const noexcept; + const char* what() const noexcept override; }; -} // namespace std +} \end{codeblock} -\rSec3[syserr.syserr.members]{Class \tcode{system_error} members} +\rSec3[syserr.syserr.members]{Members} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} +\indexlibraryctor{system_error}% \begin{itemdecl} system_error(error_code ec, const string& what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of class \tcode{system_error}. - -\pnum -\postconditions \tcode{code() == ec}. - -\tcode{string(what()).find(what_arg) != string::npos}. +\ensures +\tcode{code() == ec} and\newline +\tcode{string_view(what()).find(what_arg.c_str()) != string_view::npos}. \end{itemdescr} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} +\indexlibraryctor{system_error}% \begin{itemdecl} system_error(error_code ec, const char* what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of class \tcode{system_error}. - -\pnum -\postconditions \tcode{code() == ec}. - -\tcode{string(what()).find(what_arg) != string::npos}. +\ensures +\tcode{code() == ec} and +\tcode{string_view(what()).find(what_arg) != string_view::npos}. \end{itemdescr} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} +\indexlibraryctor{system_error}% \begin{itemdecl} system_error(error_code ec); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of class \tcode{system_error}. - -\pnum -\postconditions \tcode{code() == ec}. +\ensures +\tcode{code() == ec}. \end{itemdescr} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} +\indexlibraryctor{system_error}% \begin{itemdecl} -system_error(int ev, const error_category& ecat, - const string& what_arg); +system_error(int ev, const error_category& ecat, const string& what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of class \tcode{system_error}. - -\pnum -\postconditions \tcode{code() == error_code(ev, ecat)}. - -\tcode{string(what()).find(what_arg) != string::npos}. +\ensures +\raggedright \tcode{code() == error_code(ev, ecat)} and\linebreak +\tcode{string_view(what()).find(what_arg.c_str()) != string_view::npos}. \end{itemdescr} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} +\indexlibraryctor{system_error}% \begin{itemdecl} -system_error(int ev, const error_category& ecat, - const char* what_arg); +system_error(int ev, const error_category& ecat, const char* what_arg); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of class \tcode{system_error}. - -\pnum -\postconditions \tcode{code() == error_code(ev, ecat)}. - -\tcode{string(what()).find(what_arg) != string::npos}. +\ensures +\raggedright \tcode{code() == error_code(ev, ecat)} and\linebreak +\tcode{string_view(what()).find(what_arg) != string_view::npos}. \end{itemdescr} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} -\indexlibrary{\idxcode{system_error}!\idxcode{system_error}} +\indexlibraryctor{system_error}% \begin{itemdecl} system_error(int ev, const error_category& ecat); \end{itemdecl} \begin{itemdescr} \pnum -\effects Constructs an object of class \tcode{system_error}. - -\pnum -\postconditions \tcode{code() == error_code(ev, ecat)}. +\ensures +\tcode{code() == error_code(ev, ecat)}. \end{itemdescr} -\indexlibrary{\idxcode{code}!\idxcode{system_error}} -\indexlibrary{\idxcode{system_error}!\idxcode{code}} +\indexlibrarymember{code}{system_error}% \begin{itemdecl} const error_code& code() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{ec} or \tcode{error_code(ev, ecat)}, from the constructor, +\returns +\tcode{ec} or \tcode{error_code(ev, ecat)}, from the constructor, as appropriate. \end{itemdescr} -\indexlibrary{\idxcode{what}!\idxcode{system_error}} -\indexlibrary{\idxcode{system_error}!\idxcode{what}} +\indexlibrarymember{what}{system_error}% \begin{itemdecl} -const char* what() const noexcept; +const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} \pnum -\returns An \ntbs incorporating the arguments supplied in the constructor. +\returns +An \ntbs{} incorporating the arguments supplied in the constructor. + +\begin{note} +The returned \ntbs{} might be the contents of \tcode{what_arg + ": " + +code.message()}. +\end{note} +\end{itemdescr} + +\rSec1[stacktrace]{Stacktrace} + +\rSec2[stacktrace.general]{General} + +\pnum +Subclause \ref{stacktrace} describes components +that \Cpp{} programs may use to store +the stacktrace of the current thread of execution and +query information about the stored stacktrace at runtime. + +\pnum +The \defn{invocation sequence} of the current evaluation $x_0$ +in the current thread of execution +is a sequence $(x_0, \ldots, x_n)$ of evaluations such that, for $i \geq 0$, +$x_i$ is within the function invocation $x_{i+1}$\iref{intro.execution}. + +\pnum +A \defn{stacktrace} is an approximate representation of +an invocation sequence and consists of stacktrace entries. +A \defn{stacktrace entry} represents an evaluation in a stacktrace. + +\rSec2[stacktrace.syn]{Header \tcode{} synopsis} + +\indexheader{stacktrace}% +\begin{codeblock} +#include // see \ref{compare.syn} + +namespace std { + // \ref{stacktrace.entry}, class \tcode{stacktrace_entry} + class stacktrace_entry; + + // \ref{stacktrace.basic}, class template \tcode{basic_stacktrace} + template + class basic_stacktrace; + + // \tcode{basic_stacktrace} \grammarterm{typedef-name}s + using stacktrace = basic_stacktrace>; + + // \ref{stacktrace.basic.nonmem}, non-member functions + template + void swap(basic_stacktrace& a, basic_stacktrace& b) + noexcept(noexcept(a.swap(b))); + + string to_string(const stacktrace_entry& f); + + template + string to_string(const basic_stacktrace& st); + + ostream& operator<<(ostream& os, const stacktrace_entry& f); + template + ostream& operator<<(ostream& os, const basic_stacktrace& st); + + // \ref{stacktrace.format}, formatting support + template<> struct formatter; + template struct formatter>; + + namespace pmr { + using stacktrace = basic_stacktrace>; + } + + // \ref{stacktrace.basic.hash}, hash support + template struct hash; + template<> struct hash; + template struct hash>; +} +\end{codeblock} + +\rSec2[stacktrace.entry]{Class \tcode{stacktrace_entry}} + +\rSec3[stacktrace.entry.overview]{Overview} + +\begin{codeblock} +namespace std { + class @\libglobal{stacktrace_entry}@ { + public: + using native_handle_type = @\impdefx{\tcode{stacktrace_entry::native_handle_type}}@; + + // \ref{stacktrace.entry.cons}, constructors + constexpr stacktrace_entry() noexcept; + constexpr stacktrace_entry(const stacktrace_entry& other) noexcept; + constexpr stacktrace_entry& operator=(const stacktrace_entry& other) noexcept; + + ~stacktrace_entry(); + + // \ref{stacktrace.entry.obs}, observers + constexpr native_handle_type native_handle() const noexcept; + constexpr explicit operator bool() const noexcept; + + // \ref{stacktrace.entry.query}, query + string description() const; + string source_file() const; + uint_least32_t source_line() const; + + // \ref{stacktrace.entry.cmp}, comparison + friend constexpr bool operator==(const stacktrace_entry& x, + const stacktrace_entry& y) noexcept; + friend constexpr strong_ordering operator<=>(const stacktrace_entry& x, + const stacktrace_entry& y) noexcept; + }; +} +\end{codeblock} + +\pnum +An object of type \tcode{stacktrace_entry} is either empty, +or represents a stacktrace entry and +provides operations for querying information about it. +The class \tcode{stacktrace_entry} models +\libconcept{regular}\iref{concepts.object} and +\tcode{\libconcept{three_way_comparable}}\iref{cmp.concept}. + +\rSec3[stacktrace.entry.cons]{Constructors} + +\indexlibraryctor{stacktrace_entry}% +\begin{itemdecl} +constexpr stacktrace_entry() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{*this} is empty. +\end{itemdescr} + +\rSec3[stacktrace.entry.obs]{Observers} + +\indexlibrarymember{native_handle}{stacktrace_entry}% +\begin{itemdecl} +constexpr native_handle_type native_handle() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The semantics of this function are +\impldef{semantics of \tcode{stacktrace_entry::native_handle}}. + +\pnum +\remarks +Successive invocations of the \tcode{native_handle} function +for an unchanged \tcode{stacktrace_entry} object return identical values. +\end{itemdescr} + +\indexlibrarymember{operator bool}{stacktrace_entry}% +\begin{itemdecl} +constexpr explicit operator bool() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{false} if and only if \tcode{*this} is empty. +\end{itemdescr} + +\rSec3[stacktrace.entry.query]{Query} + +\pnum +\begin{note} +All the \tcode{stacktrace_entry} query functions treat +errors other than memory allocation errors +as ``no information available'' and do not throw in that case. +\end{note} + +\indexlibrarymember{description}{stacktrace_entry}% +\begin{itemdecl} +string description() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A description of the evaluation represented by \tcode{*this}, +or an empty string. + +\pnum +\throws +\tcode{bad_alloc} if memory for +the internal data structures or the resulting string cannot be allocated. +\end{itemdescr} + +\indexlibrarymember{source_file}{stacktrace_entry}% +\begin{itemdecl} +string source_file() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The presumed or actual name of the source file\iref{cpp.predefined} +that lexically contains the expression or statement +whose evaluation is represented by \tcode{*this}, or an empty string. + +\pnum +\throws +\tcode{bad_alloc} if memory for +the internal data structures or the resulting string cannot be allocated. +\end{itemdescr} + +\indexlibrarymember{source_line}{stacktrace_entry}% +\begin{itemdecl} +uint_least32_t source_line() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{0}, or a 1-based line number that lexically relates to the evaluation +represented by \tcode{*this}. +If \tcode{source_file} returns the presumed name of the source file, +returns the presumed line number; +if \tcode{source_file} returns the actual name of the source file, +returns the actual line number. + +\pnum +\throws +\tcode{bad_alloc} if memory for +the internal data structures cannot be allocated. +\end{itemdescr} + +\rSec3[stacktrace.entry.cmp]{Comparison} + +\indexlibrarymember{operator==}{stacktrace_entry}% +\begin{itemdecl} +friend constexpr bool operator==(const stacktrace_entry& x, const stacktrace_entry& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if and only if \tcode{x} and \tcode{y} represent +the same stacktrace entry or both \tcode{x} and \tcode{y} are empty. +\end{itemdescr} + +\rSec2[stacktrace.basic]{Class template \tcode{basic_stacktrace}} + +\rSec3[stacktrace.basic.overview]{Overview} + +\begin{codeblock} +namespace std { + template + class @\libglobal{basic_stacktrace}@ { + public: + using value_type = stacktrace_entry; + using const_reference = const value_type&; + using reference = value_type&; + using const_iterator = @\impdefx{type of \tcode{basic_stacktrace::const_iterator}}@; // see \ref{stacktrace.basic.obs} + using iterator = const_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using difference_type = @\impdefx{type of \tcode{basic_stacktrace::difference_type}}@; + using size_type = @\impdefx{type of \tcode{basic_stacktrace::size_type}}@; + using allocator_type = Allocator; + + // \ref{stacktrace.basic.cons}, creation and assignment + static basic_stacktrace current(const allocator_type& alloc = allocator_type()) noexcept; + static basic_stacktrace current(size_type skip, + const allocator_type& alloc = allocator_type()) noexcept; + static basic_stacktrace current(size_type skip, size_type max_depth, + const allocator_type& alloc = allocator_type()) noexcept; + + basic_stacktrace() noexcept(is_nothrow_default_constructible_v); + explicit basic_stacktrace(const allocator_type& alloc) noexcept; + + basic_stacktrace(const basic_stacktrace& other); + basic_stacktrace(basic_stacktrace&& other) noexcept; + basic_stacktrace(const basic_stacktrace& other, const allocator_type& alloc); + basic_stacktrace(basic_stacktrace&& other, const allocator_type& alloc); + basic_stacktrace& operator=(const basic_stacktrace& other); + basic_stacktrace& operator=(basic_stacktrace&& other) + noexcept(allocator_traits::propagate_on_container_move_assignment::value || + allocator_traits::is_always_equal::value); + + ~basic_stacktrace(); + + // \ref{stacktrace.basic.obs}, observers + allocator_type get_allocator() const noexcept; + + const_iterator begin() const noexcept; + const_iterator end() const noexcept; + const_reverse_iterator rbegin() const 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; + + bool empty() const noexcept; + size_type size() const noexcept; + size_type max_size() const noexcept; + + const_reference operator[](size_type) const; + const_reference at(size_type) const; + + // \ref{stacktrace.basic.cmp}, comparisons + template + friend bool operator==(const basic_stacktrace& x, + const basic_stacktrace& y) noexcept; + template + friend strong_ordering operator<=>(const basic_stacktrace& x, + const basic_stacktrace& y) noexcept; + + // \ref{stacktrace.basic.mod}, modifiers + void swap(basic_stacktrace& other) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); + + private: + vector @\exposid{frames_}@; // \expos + }; +} +\end{codeblock} + +\pnum +The class template \tcode{basic_stacktrace} satisfies +the requirements +of a reversible container\iref{container.rev.reqmts}, +of an allocator-aware container\iref{container.alloc.reqmts}, and +of a sequence container\iref{sequence.reqmts}, +except that +\begin{itemize} +\item +only move, assignment, swap, and +operations defined for const-qualified sequence containers are supported and, +\item +the semantics of comparison functions +are different from those required for a container. +\end{itemize} + +\rSec3[stacktrace.basic.cons]{Creation and assignment} + +\indexlibrarymember{current}{basic_stacktrace}% +\begin{itemdecl} +static basic_stacktrace current(const allocator_type& alloc = allocator_type()) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{basic_stacktrace} object +with \exposid{frames_} storing +the stacktrace of the current evaluation in the current thread of execution, or +an empty \tcode{basic_stacktrace} object +if the initialization of \exposid{frames_} failed. +\tcode{alloc} is passed to the constructor of the \exposid{frames_} object. + +\begin{note} +If the stacktrace was successfully obtained, +then \tcode{\exposid{frames_}.front()} is the \tcode{stacktrace_entry} +representing approximately the current evaluation, and +\tcode{\exposid{frames_}.back()} is the \tcode{stacktrace_entry} +representing approximately the initial function of +the current thread of execution. +\end{note} +\end{itemdescr} + +\indexlibrarymember{current}{basic_stacktrace}% +\begin{itemdecl} +static basic_stacktrace current(size_type skip, + const allocator_type& alloc = allocator_type()) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{t} be a stacktrace +as-if obtained via \tcode{basic_stacktrace::current(alloc)}. +Let \tcode{n} be \tcode{t.size()}. + +\pnum +\returns +A \tcode{basic_stacktrace} object +where \exposid{frames_} is direct-non-list-initialized from arguments +\tcode{t.begin() + min(n, skip)}, \tcode{t.end()}, and \tcode{alloc}, +or an empty \tcode{basic_stacktrace} object +if the initialization of \exposid{frames_} failed. +\end{itemdescr} + +\indexlibrarymember{current}{basic_stacktrace}% +\begin{itemdecl} +static basic_stacktrace current(size_type skip, size_type max_depth, + const allocator_type& alloc = allocator_type()) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{t} be a stacktrace +as-if obtained via \tcode{basic_stacktrace::current(alloc)}. +Let \tcode{n} be \tcode{t.size()}. + +\pnum +\hardexpects +\tcode{skip <= skip + max_depth} is \tcode{true}. + +\pnum +\returns +A \tcode{basic_stacktrace} object +where \exposid{frames_} is direct-non-list-initialized from arguments +\tcode{t.begin() + min(n, skip)}, \tcode{t.begin() + min(n, skip + max_depth)}, +and \tcode{alloc}, +or an empty \tcode{basic_stacktrace} object +if the initialization of \exposid{frames_} failed. +\end{itemdescr} + +\indexlibraryctor{basic_stacktrace}% +\begin{itemdecl} +basic_stacktrace() noexcept(is_nothrow_default_constructible_v); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{empty()} is \tcode{true}. +\end{itemdescr} + +\indexlibraryctor{basic_stacktrace}% +\begin{itemdecl} +explicit basic_stacktrace(const allocator_type& alloc) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\tcode{alloc} is passed to the \exposid{frames_} constructor. + +\pnum +\ensures +\tcode{empty()} is \tcode{true}. +\end{itemdescr} + +\indexlibraryctor{basic_stacktrace}% +\indexlibrarymember{operator=}{basic_stacktrace}% +\begin{itemdecl} +basic_stacktrace(const basic_stacktrace& other); +basic_stacktrace(const basic_stacktrace& other, const allocator_type& alloc); +basic_stacktrace(basic_stacktrace&& other, const allocator_type& alloc); +basic_stacktrace& operator=(const basic_stacktrace& other); +basic_stacktrace& operator=(basic_stacktrace&& other) + noexcept(allocator_traits::propagate_on_container_move_assignment::value || + allocator_traits::is_always_equal::value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +Implementations may strengthen the exception specification +for these functions\iref{res.on.exception.handling} +by ensuring that \tcode{empty()} is \tcode{true} on failed allocation. +\end{itemdescr} + +\rSec3[stacktrace.basic.obs]{Observers} + +\indexlibrarymember{const_iterator}{basic_stacktrace}% +\begin{itemdecl} +using const_iterator = @\impdef@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The type models +\libconcept{random_access_iterator}\iref{iterator.concept.random.access} and +meets the +\oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators}. +\end{itemdescr} + +\indexlibrarymember{get_allocator}{basic_stacktrace}% +\begin{itemdecl} +allocator_type get_allocator() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{frames_}.get_allocator()}. +\end{itemdescr} + +\indexlibrarymember{begin}{basic_stacktrace}% +\indexlibrarymember{cbegin}{basic_stacktrace}% +\begin{itemdecl} +const_iterator begin() const noexcept; +const_iterator cbegin() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An iterator referring to the first element in \exposid{frames_}. +If \tcode{empty()} is \tcode{true}, +then it returns the same value as \tcode{end()}. +\end{itemdescr} + +\indexlibrarymember{end}{basic_stacktrace}% +\indexlibrarymember{cend}{basic_stacktrace}% +\begin{itemdecl} +const_iterator end() const noexcept; +const_iterator cend() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The end iterator. +\end{itemdescr} + +\indexlibrarymember{rbegin}{basic_stacktrace}% +\indexlibrarymember{crbegin}{basic_stacktrace}% +\begin{itemdecl} +const_reverse_iterator rbegin() const noexcept; +const_reverse_iterator crbegin() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{reverse_iterator(cend())}. +\end{itemdescr} + +\indexlibrarymember{rend}{basic_stacktrace}% +\indexlibrarymember{crend}{basic_stacktrace}% +\begin{itemdecl} +const_reverse_iterator rend() const noexcept; +const_reverse_iterator crend() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{reverse_iterator(cbegin())}. +\end{itemdescr} + +\indexlibrarymember{empty}{basic_stacktrace}% +\begin{itemdecl} +bool empty() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{frames_}.empty()}. +\end{itemdescr} + +\indexlibrarymember{size}{basic_stacktrace}% +\begin{itemdecl} +size_type size() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{frames_}.size()}. +\end{itemdescr} + +\indexlibrarymember{max_size}{basic_stacktrace}% +\begin{itemdecl} +size_type max_size() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{frames_}.max_size()}. +\end{itemdescr} + +\indexlibrarymember{operator[]}{basic_stacktrace}% +\begin{itemdecl} +const_reference operator[](size_type frame_no) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\hardexpects +\tcode{frame_no < size()} is \tcode{true}. + +\pnum +\returns +\tcode{\exposid{frames_}[frame_no]}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\indexlibrarymember{at}{basic_stacktrace}% +\begin{itemdecl} +const_reference at(size_type frame_no) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{frames_}[frame_no]}. + +\pnum +\throws +\tcode{out_of_range} if \tcode{frame_no >= size()}. +\end{itemdescr} + +\rSec3[stacktrace.basic.cmp]{Comparisons} + +\indexlibrarymember{operator==}{basic_stacktrace}% +\begin{itemdecl} +template +friend bool operator==(const basic_stacktrace& x, const basic_stacktrace& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{equal(x.begin(), x.end(), y.begin(), y.end())}. +\end{itemdescr} + +\indexlibrarymember{operator<=>}{basic_stacktrace}% +\begin{itemdecl} +template +friend strong_ordering + operator<=>(const basic_stacktrace& x, const basic_stacktrace& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{x.size() <=> y.size()} if \tcode{x.size() != y.size()}; +\tcode{lexicographical_compare_three_way(x.begin(), x.end(), y.begin(), y.end())} +otherwise. +\end{itemdescr} + +\rSec3[stacktrace.basic.mod]{Modifiers} + +\indexlibrarymember{swap}{basic_stacktrace}% +\begin{itemdecl} +void swap(basic_stacktrace& other) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Exchanges the contents of \tcode{*this} and \tcode{other}. +\end{itemdescr} + +\rSec3[stacktrace.basic.nonmem]{Non-member functions} + +\indexlibrarymember{swap}{basic_stacktrace}% +\begin{itemdecl} +template + void swap(basic_stacktrace& a, basic_stacktrace& b) + noexcept(noexcept(a.swap(b))); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{a.swap(b)}. +\end{itemdescr} + +\indexlibrarymember{to_string}{basic_stacktrace}% +\begin{itemdecl} +string to_string(const stacktrace_entry& f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A string with a description of \tcode{f}. + +\pnum +\recommended +The description should provide information about the contained evaluation, +including information from +\tcode{f.source_file()} and \tcode{f.source_line()}. +\end{itemdescr} + +\indexlibrarymember{to_string}{basic_stacktrace}% +\begin{itemdecl} +template + string to_string(const basic_stacktrace& st); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A string with a description of \tcode{st}. +\begin{note} +The number of lines is not guaranteed to be equal to \tcode{st.size()}. +\end{note} +\end{itemdescr} + +\indexlibrarymember{operator<<}{stacktrace_entry}% +\begin{itemdecl} +ostream& operator<<(ostream& os, const stacktrace_entry& f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return os << to_string(f);} +\end{itemdescr} + +\indexlibrarymember{operator<<}{basic_stacktrace}% +\begin{itemdecl} +template + ostream& operator<<(ostream& os, const basic_stacktrace& st); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return os << to_string(st);} +\end{itemdescr} + +\rSec2[stacktrace.format]{Formatting support} + +\begin{itemdecl} +template<> struct formatter; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{formatter} interprets \fmtgrammarterm{format-spec} +as a \fmtgrammarterm{stacktrace-entry-format-spec}. +The syntax of format specifications is as follows: + +\begin{ncbnf} +\fmtnontermdef{stacktrace-entry-format-spec}\br + \opt{fill-and-align} \opt{width} +\end{ncbnf} + +\begin{note} +The productions \fmtgrammarterm{fill-and-align} and \fmtgrammarterm{width} +are described in \ref{format.string.std}. +\end{note} + +\pnum +A \tcode{stacktrace_entry} object \tcode{se} is formatted as if by +copying \tcode{to_string(se)} through the output iterator of the context +with additional padding and adjustments as specified by the format specifiers. +\end{itemdescr} + +\begin{itemdecl} +template struct formatter>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +For \tcode{formatter>}, +\fmtgrammarterm{format-spec} is empty. + +\pnum +A \tcode{basic_stacktrace} object \tcode{s} is formatted as if by +copying \tcode{to_string(s)} through the output iterator of the context. +\end{itemdescr} + +\rSec2[stacktrace.basic.hash]{Hash support} + +\begin{itemdecl} +template<> struct hash; +template struct hash>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The specializations are enabled\iref{unord.hash}. +\end{itemdescr} + +\rSec1[debugging]{Debugging} + +\rSec2[debugging.general]{General} + +\pnum +Subclause \ref{debugging} describes functionality to introspect and +interact with the execution of the program. + +\begin{note} +The facilities provided by the debugging functionality interact with a program +that could be tracing the execution of a \Cpp{} program, such as a debugger. +\end{note} + +\rSec2[debugging.syn]{Header \tcode{} synopsis} + +\indexheader{debugging}% +\begin{codeblock} +// all freestanding +namespace std { + // \ref{debugging.utility}, utility + void breakpoint() noexcept; + void breakpoint_if_debugging() noexcept; + bool is_debugger_present() noexcept; +} +\end{codeblock} + +\rSec2[debugging.utility]{Utility} + +\indexlibraryglobal{breakpoint}% +\begin{itemdecl} +void breakpoint() noexcept; +\end{itemdecl} + +\begin{itemdescr} + +\pnum +The semantics of this function are \impldef{semantics of \tcode{breakpoint}}. + +\begin{note} +It is intended that, when invoked with a debugger present, the execution of the +program temporarily halts and execution is handed to the debugger until the +program is either terminated by the debugger or the debugger resumes execution +of the program as if the function was not invoked. In particular, there is no +intent for a call to this function to accomodate resumption of the program in a +different manner. If there is no debugger present, execution of the program can +end abnormally. +\end{note} + +\end{itemdescr} + +\indexlibraryglobal{breakpoint_if_debugging}% +\begin{itemdecl} +void breakpoint_if_debugging() noexcept; +\end{itemdecl} + +\begin{itemdescr} + +\pnum +\effects +Equivalent to: +\begin{codeblock} +if (is_debugger_present()) breakpoint(); +\end{codeblock} + +\end{itemdescr} + +\indexlibraryglobal{is_debugger_present}% +\begin{itemdecl} +bool is_debugger_present() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\required +This function has no preconditions. + +\pnum +\default +\impldef{default semantics of \tcode{is_debugger_present}}. + +\begin{note} +It is intended that, using an immediate (uncached) query to determine if the +program is being traced by a debugger, an implementation returns \tcode{true} +only when tracing the execution of the program with a debugger. On Windows or +equivalent systems, this can be achieved by calling the +\tcode{::IsDebuggerPresent()} Win32 function. For systems compatible with +ISO/IEC 23360:2021, this can be achieved by checking for a tracing process, with +a best-effort determination that such a tracing process is a debugger. +\end{note} + +\pnum +\remarks +This function is replaceable\iref{term.replaceable.function}. -\enternote The returned NTBS might be the contents of \tcode{what_arg + ": " + -code.message()}.\exitnote \end{itemdescr} diff --git a/source/exceptions.tex b/source/exceptions.tex index f1e81995ef..df3b639dc0 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -2,11 +2,12 @@ \rSec0[except]{Exception handling}% \indextext{exception handling|(} -%gram: \rSec1[gram.except]{Exception handling} -%gram: +\gramSec[gram.except]{Exception handling} \indextext{exception object|see{exception handling, exception object}}% -\indextext{object, exception|see{exception handling, exception object}} +\indextext{object!exception|see{exception handling, exception object}} + +\rSec1[except.pre]{Preamble} \pnum Exception handling provides a way of transferring control and information @@ -20,47 +21,49 @@ % \begin{bnf} \nontermdef{try-block}\br - \terminal{try} compound-statement handler-seq + \keyword{try} compound-statement handler-seq \end{bnf} \indextext{\idxcode{try}}% % \begin{bnf} \nontermdef{function-try-block}\br - \terminal{try} ctor-initializer\opt compound-statement handler-seq + \keyword{try} \opt{ctor-initializer} compound-statement handler-seq \end{bnf} \begin{bnf} \nontermdef{handler-seq}\br - handler handler-seq\opt + handler \opt{handler-seq} \end{bnf} \indextext{\idxcode{catch}}% % \begin{bnf} \nontermdef{handler}\br - \terminal{catch (} exception-declaration \terminal{)} compound-statement + \keyword{catch} \terminal{(} exception-declaration \terminal{)} compound-statement \end{bnf} \begin{bnf} \nontermdef{exception-declaration}\br - attribute-specifier-seq\opt type-specifier-seq declarator\br - attribute-specifier-seq\opt type-specifier-seq abstract-declarator\opt\br + \opt{attribute-specifier-seq} type-specifier-seq declarator\br + \opt{attribute-specifier-seq} type-specifier-seq \opt{abstract-declarator}\br \terminal{...} \end{bnf} The optional \grammarterm{attribute-specifier-seq} in an \grammarterm{exception-declaration} -appertains to the parameter of the catch clause~(\ref{except.handle}). +appertains to the parameter of the catch clause\iref{except.handle}. \pnum \indextext{exception handling!try block}% \indextext{exception handling!handler}% \indextext{try block|see{exception handling, try block}}% \indextext{handler|see{exception handling, handler}}% -A \grammarterm{try-block} is a \grammarterm{statement} (Clause~\ref{stmt.stmt}). -\enternote Within this Clause +A \grammarterm{try-block} is a \grammarterm{statement}\iref{stmt.pre}. +\begin{note} +Within this Clause ``try block'' is taken to mean both \grammarterm{try-block} and -\grammarterm{function-try-block}. \exitnote +\grammarterm{function-try-block}. +\end{note} \pnum \indextext{exception handling!\idxcode{goto}}% @@ -69,26 +72,26 @@ \indextext{\idxcode{switch}!and try block}% \indextext{\idxcode{goto}!and handler}% \indextext{\idxcode{switch}!and handler}% -A \tcode{goto} or \tcode{switch} statement shall not be used to transfer control -into a try block or into a handler. -\enterexample +The \grammarterm{compound-statement} of a try block or of a handler is a +control-flow-limited statement\iref{stmt.label}. +\begin{example} \begin{codeblock} void f() { - goto l1; // Ill-formed - goto l2; // Ill-formed + goto l1; // error + goto l2; // error try { goto l1; // OK - goto l2; // Ill-formed + goto l2; // error l1: ; } catch (...) { l2: ; - goto l1; // Ill-formed + goto l1; // error goto l2; // OK } } \end{codeblock} -\exitexample +\end{example} \indextext{\idxcode{goto}!and try block}% \indextext{\idxcode{switch}!and try block}% \indextext{\idxcode{return}!and try block}% @@ -98,27 +101,26 @@ \indextext{\idxcode{return}!and handler}% \indextext{\idxcode{continue}!and handler}% A -\tcode{goto}, -\tcode{break}, -\tcode{return}, +\keyword{goto}, +\keyword{break}, +\keyword{return}, or -\tcode{continue} +\keyword{continue} statement can be used to transfer control out of a try block or handler. When this happens, each variable declared in the try block will be destroyed in the context that directly contains its declaration. -\enterexample - +\begin{example} \begin{codeblock} lab: try { T1 t1; try { T2 t2; - if (@\textit{condition}@) + if (@\grammarterm{condition}@) goto lab; - } catch(...) { /* @\textit{handler 2}@ */ } - } catch(...) { /* @\textit{handler 1}@ */ } + } catch(...) { @\tcode{/* handler 2 */}@ } + } catch(...) { @\tcode{/* handler 1 */}@ } \end{codeblock} Here, executing @@ -130,15 +132,15 @@ assuming the \grammarterm{condition} does not declare a variable. -Any exception raised while destroying +Any exception thrown while destroying \tcode{t2} will result in executing -\textit{handler 2}; -any exception raised while destroying +\tcode{handler 2}; +any exception thrown while destroying \tcode{t1} will result in executing -\textit{handler 1}. -\exitexample +\tcode{handler 1}. +\end{example} \pnum \indextext{function try block|see{exception handling, function try block}}% @@ -161,7 +163,7 @@ in the same way as an exception thrown during the execution of a \grammarterm{try-block} transfers control to other handlers. -\enterexample +\begin{example} \begin{codeblock} int f(int); class C { @@ -174,15 +176,15 @@ C::C(int ii, double id) try : i(f(ii)), d(id) { // constructor statements +} catch (...) { + // handles exceptions thrown from the \grammarterm{ctor-initializer} and from the constructor statements } -catch (...) { - // handles exceptions thrown from the ctor-initializer - // and from the constructor statements -} - \end{codeblock} -\exitexample +\end{example} +\pnum +In this Clause, ``before'' and ``after'' refer to the +``sequenced before'' relation\iref{intro.execution}. \rSec1[except.throw]{Throwing an exception}% \indextext{exception handling!throwing}% @@ -190,32 +192,31 @@ \pnum Throwing an exception transfers control to a handler. -\enternote +\begin{note} An exception can be thrown from one of the following contexts: -\grammarterm{throw-expression}{s}~(\ref{expr.throw}), -allocation functions~(\ref{basic.stc.dynamic.allocation}), -\tcode{dynamic_cast}~(\ref{expr.dynamic.cast}), -\tcode{typeid}~(\ref{expr.typeid}), -\grammarterm{new-expression}{s}~(\ref{expr.new}), and standard library -functions~(\ref{structure.specifications}). -\exitnote +\grammarterm{throw-expression}{s}\iref{expr.throw}, +allocation functions\iref{basic.stc.dynamic.allocation}, +\keyword{dynamic_cast}\iref{expr.dynamic.cast}, +\keyword{typeid}\iref{expr.typeid}, +\grammarterm{new-expression}{s}\iref{expr.new}, and standard library +functions\iref{structure.specifications}. +\end{note} An object is passed and the type of that object determines which handlers can catch it. -\enterexample +\begin{example} \begin{codeblock} throw "Help!"; \end{codeblock} can be caught by a -\term{handler} +\grammarterm{handler} of -\tcode{const} -\tcode{char*} +\keyword{const} +\tcode{\keyword{char}*} type: \begin{codeblock} try { // ... -} -catch(const char* p) { +} catch(const char* p) { // handle character string exceptions here } \end{codeblock} @@ -231,7 +232,7 @@ } \end{codeblock} can be caught by a handler for exceptions of type -\tcode{Overflow} +\tcode{Overflow}: \begin{codeblock} try { f(1.2); @@ -239,33 +240,32 @@ // handle exceptions of type \tcode{Overflow} here } \end{codeblock} -\exitexample +\end{example} \pnum \indextext{exception handling!throwing}% \indextext{exception handling!handler}% \indextext{exception handling!nearest handler}% When an exception is thrown, control is transferred to the nearest handler with -a matching type~(\ref{except.handle}); ``nearest'' means the handler +a matching type\iref{except.handle}; ``nearest'' means the handler for which the \grammarterm{compound-statement} or \grammarterm{ctor-initializer} following the -\tcode{try} +\keyword{try} keyword was most recently entered by the thread of control and not yet exited. \pnum Throwing an exception -copy-initializes~(\ref{dcl.init}, \ref{class.copy}) a temporary object, +initializes an object with dynamic storage duration, called the -\indextext{exception handling!exception object}\term{exception object}. -The temporary is an lvalue and is used to initialize the -variable declared in the matching -\term{handler}~(\ref{except.handle}). -If the type of the exception object would -be an incomplete type or a pointer to an incomplete -type other than (possibly cv-qualified) -\tcode{void} the program is ill-formed. +\defnx{exception object}{exception handling!exception object}. +If the type of the exception object would be +an incomplete type\iref{basic.types.general}, +an abstract class type\iref{class.abstract}, +or a pointer to an incomplete type other than +\cv{}~\keyword{void}\iref{basic.compound}, +the program is ill-formed. \pnum \indextext{exception handling!memory}% @@ -274,123 +274,225 @@ The memory for the exception object is allocated in an unspecified way, except as noted in~\ref{basic.stc.dynamic.allocation}. If a handler exits by rethrowing, control is passed to another handler for -the same exception. -The exception object is destroyed after either -the last remaining active handler for the exception exits by +the same exception object. +The points of potential destruction for the exception object are: +\begin{itemize} +\item +when an active handler for the exception exits by any means other than -rethrowing, or the last object of type \tcode{std::exception_ptr}~(\ref{propagation}) -that refers to the exception object is destroyed, whichever is later. In the former -case, the destruction occurs when the handler exits, immediately after the destruction -of the object declared in the \grammarterm{exception-declaration} in the handler, if any. -In the latter case, the destruction occurs before the destructor of \tcode{std::exception_ptr} -returns. +rethrowing, +immediately after the destruction of the object (if any) +declared in the \grammarterm{exception-declaration} in the handler; + +\item +when an object of type \tcode{std::exception_ptr}\iref{propagation} +that refers to the exception object is destroyed, +before the destructor of \tcode{std::exception_ptr} returns. +\end{itemize} + +Among all points of potential destruction for the exception object, +there is an unspecified last one +where the exception object is destroyed. +All other points happen before that last one\iref{intro.races}. +\begin{note} +No other thread synchronization is implied in exception handling. +\end{note} The implementation may then deallocate the memory for the exception object; any such deallocation is done in an unspecified way. -\enternote a thrown exception does not +\begin{note} +A thrown exception does not propagate to other threads unless caught, stored, and rethrown using -appropriate library functions; see~\ref{propagation} and~\ref{futures}. \exitnote +appropriate library functions; see~\ref{propagation} and~\ref{futures}. +\end{note} \pnum \indextext{exception handling!exception object!constructor}% \indextext{exception handling!exception object!destructor}% -When the thrown object is a class object, the constructor selected for -the copy-initialization and the -destructor shall be accessible, even if the copy/move operation is -elided~(\ref{class.copy}). +Let \tcode{T} denote the type of the exception object. +Copy-initialization of an object of type \tcode{T} from +an lvalue of type \tcode{const T} in a context unrelated to \tcode{T} +shall be well-formed. +If \tcode{T} is a class type, +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}}% -\indextext{reraise|see{exception handling, rethrow}}% An exception is considered caught when a handler for that exception -becomes active~(\ref{except.handle}). -\enternote +becomes active\iref{except.handle}. +\begin{note} An exception can have active handlers and still be considered uncaught if it is rethrown. -\exitnote +\end{note} \pnum -\indextext{exception handling!terminate called@\tcode{terminate()} called}% -\indextext{\idxcode{terminate()}!called}% -If the exception handling mechanism, after completing the initialization of the -exception object but before the activation of a handler for the exception, -calls a function that exits via an -exception, \tcode{std::terminate} is called~(\ref{except.terminate}). \enterexample - +\indextext{exception handling!terminate called@\tcode{terminate} called}% +\indextext{\idxcode{terminate}!called}% +If the exception handling mechanism +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} \begin{codeblock} struct C { C() { } C(const C&) { if (std::uncaught_exceptions()) { - throw 0; // throw during copy to handler's \grammarterm{exception-declaration} object~(\ref{except.handle}) + throw 0; // throw during copy to handler's \grammarterm{exception-declaration} object\iref{except.handle} } } }; int main() { try { - throw C(); // calls \tcode{std::terminate()} if construction of the handler's - // \grammarterm{exception-declaration} object is not elided~(\ref{class.copy}) + throw C(); // calls \tcode{std::terminate} if construction of the handler's + // \grammarterm{exception-declaration} object is not elided\iref{class.copy.elision} } catch(C) { } } \end{codeblock} - -\exitexample +\end{example} +\begin{note} +If a destructor directly invoked by stack unwinding exits via an exception, +\tcode{std::terminate} is invoked. +\end{note} -\rSec1[except.ctor]{Constructors and destructors}% +\rSec1[except.ctor]{Stack unwinding}% \indextext{exception handling!constructors and destructors}% -\indextext{stack unwinding!see exception handling, constructors and destructors}% -\indextext{constructor!exception~handling|see{exception handling, constructors and destructors}}% -\indextext{destructor!exception~handling|see{exception handling, constructors and destructors}} +\indextext{constructor!exception handling|see{exception handling, constructors and destructors}}% +\indextext{destructor!exception handling|see{exception handling, constructors and destructors}} \pnum \indextext{unwinding!stack}% As control passes from the point where an exception is thrown to a handler, -destructors are invoked by a process, specified in this section, called -\defn{stack unwinding}. If a destructor directly invoked by stack unwinding -exits with an exception, \tcode{std::terminate} is called~(\ref{except.terminate}). -\enternote -Consequently, destructors should generally catch exceptions and not let them -propagate out of the destructor. -\exitnote +objects are destroyed by a process, +specified in this subclause, called \defn{stack unwinding}. \pnum -The destructor is invoked for each automatic object of class type constructed +Each object with automatic storage duration is destroyed if it has been +constructed, but not yet destroyed, since the try block was entered. -The automatic objects are destroyed in the reverse order of the completion +If an exception is thrown during the destruction of temporaries or +local variables for a \keyword{return} statement\iref{stmt.return}, +the destructor for the returned object (if any) is also invoked. +The objects are destroyed in the reverse order of the completion of their construction. +\begin{example} +\begin{codeblock} +struct A { }; + +struct Y { ~Y() noexcept(false) { throw 0; } }; + +A f() { + try { + A a; + Y y; + A b; + return {}; // \#1 + } catch (...) { + } + return {}; // \#2 +} +\end{codeblock} +At \#1, the returned object of type \tcode{A} is constructed. +Then, the local variable \tcode{b} is destroyed\iref{stmt.jump}. +Next, the local variable \tcode{y} is destroyed, +causing stack unwinding, +resulting in the destruction of the returned object, +followed by the destruction of the local variable \tcode{a}. +Finally, the returned object is constructed again at \#2. +\end{example} \pnum -For an object of class type -of any storage duration whose initialization or destruction is terminated by an exception, -the destructor is invoked for each of the object's fully constructed -subobjects, -that is, for each subobject for which the principal -constructor~(\ref{class.base.init}) has completed execution -and the destructor has not yet begun execution, -except that in the case of destruction, the variant members of a -union-like class are not destroyed. +If the initialization of an object +other than by delegating constructor +is terminated by an exception, +the destructor is invoked for +each of the object's subobjects +that were known to be initialized by the object's initialization and +whose initialization has completed\iref{dcl.init}. +\begin{note} +If such an object has a reference member +that extends the lifetime of a temporary object, +this ends the lifetime of the reference member, +so the lifetime of the temporary object is effectively not extended. +\end{note} +\indextext{subobject!initialized, known to be}% +A subobject is \defn{known to be initialized} +if it is not an anonymous union member and +its initialization is specified +\begin{itemize} +\item in \ref{class.base.init} for initialization by constructor, +\item in \ref{class.copy.ctor} for initialization by defaulted copy/move constructor, +\item in \ref{class.inhctor.init} for initialization by inherited constructor, +\item in \ref{dcl.init.aggr} for aggregate initialization, +\item in \ref{expr.prim.lambda.capture} for the initialization of +the closure object when evaluating a \grammarterm{lambda-expression}, +\item in \ref{dcl.init.general} for +default-initialization, value-initialization, or direct-initialization +of an array. +\end{itemize} +\begin{note} +This includes virtual base class subobjects +if the initialization +is for a complete object, and +can include variant members +that were nominated explicitly by +a \grammarterm{mem-initializer} or \grammarterm{designated-initializer-clause} or +that have a default member initializer. +\end{note} +If the destructor of an object is terminated by an exception, +each destructor invocation +that would be performed after executing the body of the destructor\iref{class.dtor} and +that has not yet begun execution +is performed. +\begin{note} +This includes virtual base class subobjects if +the destructor was invoked for a complete object. +\end{note} The subobjects are destroyed in the reverse order of the completion of their construction. Such destruction is sequenced before entering a handler of the \grammarterm{function-try-block} of the constructor or destructor, if any. \pnum -Similarly, if the non-delegating constructor for an object has -completed execution and a delegating constructor for that object exits with +If the \grammarterm{compound-statement} +of the \grammarterm{function-body} +of a delegating constructor +for an object exits via an exception, the object's destructor is invoked. Such destruction is sequenced before entering a handler of the \grammarterm{function-try-block} of a delegating constructor for that object, if any. \pnum -\enternote -If the object was allocated by a \grammarterm{new-expression}~(\ref{expr.new}), -the matching deallocation function~(\ref{basic.stc.dynamic.deallocation}), +\begin{note} +If the object was allocated by a \grammarterm{new-expression}\iref{expr.new}, +the matching deallocation function\iref{basic.stc.dynamic.deallocation}, if any, is called to free the storage occupied by the object. -\exitnote +\end{note} \rSec1[except.handle]{Handling an exception} @@ -400,10 +502,10 @@ The \grammarterm{exception-declaration} in a -\term{handler} +\grammarterm{handler} describes the type(s) of exceptions that can cause that -\term{handler} +\grammarterm{handler} to be entered. \indextext{exception handling!handler!incomplete type in}% \indextext{exception handling!handler!rvalue reference in}% @@ -415,33 +517,21 @@ The \grammarterm{exception-declaration} shall not denote a pointer or reference to an -incomplete type, other than -\tcode{void*}, -\tcode{const} -\tcode{void*}, -\tcode{volatile} -\tcode{void*}, -or -\tcode{const} -\tcode{volatile} -\tcode{void*}. +incomplete type, other than ``pointer to \cv{}~\keyword{void}''. \pnum -A handler of type ``array of -\tcode{T}'' -or ``function returning -\tcode{T}'' -is adjusted to be of type ``pointer to -\tcode{T}'' -or ``pointer to function -returning -\tcode{T}'', -respectively. +A handler of type +\indextext{array!handler of type}% +``array of \tcode{T}'' or +\indextext{function!handler of type}% +function type \tcode{T} +is adjusted to be of type +``pointer to \tcode{T}''. \pnum \indextext{exception handling!handler!match|(}% A -\term{handler} +\grammarterm{handler} is a match for an exception object of type @@ -449,82 +539,59 @@ if \begin{itemize} \item% -The -\term{handler} -is of type -\textit{cv} -\tcode{T} -or -\textit{cv} -\tcode{T\&} -and -\tcode{E} -and -\tcode{T} -are the same type (ignoring the top-level -\grammarterm{cv-qualifiers}), -or +The \grammarterm{handler} is of type \cv{}~\tcode{T} or +\cv{}~\tcode{T\&} and +\tcode{E} and \tcode{T} +are the same type (ignoring the top-level \grammarterm{cv-qualifier}{s}), or \item% -the -\term{handler} -is of type -\textit{cv} -\tcode{T} -or -\textit{cv} -\tcode{T\&} -and -\tcode{T} -is an unambiguous public base class of -\tcode{E}, -or +the \grammarterm{handler} is of type \cv{}~\tcode{T} or +\cv{}~\tcode{T\&} and +\tcode{T} is an unambiguous public base class of \tcode{E}, or \item% -the -\term{handler} -is of type -\textit{cv} -\tcode{T} or \tcode{const T\&} where \tcode{T} is a pointer type -and -\tcode{E} -is a pointer type that can be -converted to \tcode{T} -by either or both of +the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&} +where \tcode{T} is a pointer or pointer-to-member type and +\tcode{E} is a pointer or pointer-to-member type +that can be converted to \tcode{T} by one or more of \begin{itemize} \item% -a standard pointer conversion~(\ref{conv.ptr}) not involving conversions -to pointers to private or protected or ambiguous classes +a standard pointer conversion\iref{conv.ptr} not involving conversions +to pointers to private or protected or ambiguous classes, +\item% +a function pointer conversion\iref{conv.fctptr}, \item% -a qualification conversion, or +a qualification conversion\iref{conv.qual}, or \end{itemize} \item -the \term{handler} is of type \textit{cv} \tcode{T} or \tcode{const T\&} where \tcode{T} is a pointer or pointer to member type and \tcode{E} is \tcode{std::nullptr_t}. +the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&} where \tcode{T} is a pointer or pointer-to-member type and \tcode{E} is \tcode{std::nullptr_t}. \end{itemize} -\enternote +\begin{note} A \grammarterm{throw-expression} whose operand is an integer literal with value zero does not match a handler of -pointer or pointer to member type. -\exitnote +pointer or pointer-to-member type. +A handler of reference to array or function type +is never a match for any exception object\iref{expr.throw}. +\end{note} -\enterexample +\begin{example} \begin{codeblock} -class Matherr { /* ... */ virtual void vf(); }; -class Overflow: public Matherr { /* ... */ }; -class Underflow: public Matherr { /* ... */ }; -class Zerodivide: public Matherr { /* ... */ }; +class Matherr { @\commentellip@ virtual void vf(); }; +class Overflow: public Matherr { @\commentellip@ }; +class Underflow: public Matherr { @\commentellip@ }; +class Zerodivide: public Matherr { @\commentellip@ }; void f() { try { g(); } catch (Overflow oo) { - // ... + // ... } catch (Matherr mm) { - // ... + // ... } } \end{codeblock} @@ -542,23 +609,22 @@ \tcode{Underflow} and \tcode{Zerodivide}. -\exitexample +\end{example} \pnum The handlers for a try block are tried in order of appearance. -That makes it possible to write handlers that can never be -executed, for example by placing a handler for a derived class after -a handler for a corresponding base class. +\begin{note} +This makes it possible to write handlers that can never be +executed, for example by placing a handler for a final derived class after +a handler for a corresponding unambiguous public base class. +\end{note} \pnum A \tcode{...} in a handler's \grammarterm{exception-declaration} -functions similarly to -\tcode{...} -in a function parameter declaration; -it specifies a match for any exception. +specifies a match for any exception. If present, a \tcode{...} handler shall be the last handler for its try block. @@ -570,34 +636,55 @@ of the same thread. \pnum -A handler is considered active when initialization is complete for -the parameter (if any) of the catch clause. -\enternote +\indextext{exception handling!terminate called@\tcode{terminate} called}% +\indextext{\idxcode{terminate}!called}% +If the search for a handler +exits the function body of a function with a +non-throwing exception specification, +the function \tcode{std::terminate}\iref{except.terminate} is invoked. +\begin{note} +An implementation is not permitted to reject an expression merely because, when +executed, it throws or might +throw an exception from a function with a non-throwing exception specification. +\end{note} +\begin{example} +\begin{codeblock} +extern void f(); // potentially-throwing + +void g() noexcept { + f(); // valid, even if \tcode{f} throws + throw 42; // valid, effectively a call to \tcode{std::terminate} +} +\end{codeblock} +The call to +\tcode{f} +is well-formed despite the possibility for it to throw an exception. +\end{example} + +\pnum +If no matching handler is found, +the function \tcode{std::terminate} is invoked; +whether or not the stack is unwound before this invocation of +\tcode{std::terminate} +is \impldef{stack unwinding before invocation of +\tcode{std::terminate}}\iref{except.terminate}. + +\pnum +A handler is considered \defnx{active}{exception handling!handler!active} when +initialization is complete for the parameter (if any) of the catch clause. +\begin{note} The stack will have been unwound at that point. -\exitnote +\end{note} Also, an implicit handler is considered active when -\tcode{std::terminate()} -or -\tcode{std::unexpected()} +the function \tcode{std::terminate} is entered due to a throw. A handler is no longer considered active when the -catch clause exits or when -\tcode{std::unexpected()} -exits after being entered due to a throw. +catch clause exits. \pnum +\indextext{currently handled exception|see{exception handling, currently handled exception}}% The exception with the most recently activated handler that is still active is called the -\term{currently handled exception}. - -\pnum -If no matching handler is found, -the function -\tcode{std::terminate()} -is called; -whether or not the stack is unwound before this call to -\tcode{std::terminate()} -is \impldef{stack unwinding before call to -\tcode{std::terminate()}}~(\ref{except.terminate}). +\defnx{currently handled exception}{exception handling!currently handled exception}. \pnum Referring to any non-static member or base class of an object @@ -605,22 +692,18 @@ \grammarterm{function-try-block} of a constructor or destructor for that object results in undefined behavior. -\pnum -The scope and lifetime of the parameters of a function or constructor -extend into the handlers of a -\grammarterm{function-try-block}. - \pnum Exceptions thrown in destructors of objects with static storage duration or in -constructors of namespace-scope objects with static storage duration are not caught by a +constructors of objects associated with non-block variables with static storage duration are not caught by a \grammarterm{function-try-block} on -\tcode{main()}. Exceptions thrown in destructors of objects with thread storage duration or in constructors of namespace-scope objects with thread storage duration are not caught by a +the \tcode{main} function\iref{basic.start.main}. +Exceptions thrown in destructors of objects with thread storage duration or in constructors of objects associated with non-block variables with thread storage duration are not caught by a \grammarterm{function-try-block} on the initial function of the thread. \pnum -If a return statement appears in a handler of the +If a \keyword{return} statement\iref{stmt.return} appears in a handler of the \grammarterm{function-try-block} of a constructor, the program is ill-formed. @@ -630,42 +713,42 @@ is rethrown if control reaches the end of a handler of the \grammarterm{function-try-block} of a constructor or destructor. -Otherwise, a -function returns when control reaches the end of a handler for -the -\grammarterm{function-try-block}~(\ref{stmt.return}). -Flowing off the end of a -\grammarterm{function-try-block} -is equivalent to a -\tcode{return} -with no value; -this results in undefined behavior in a value-returning function~(\ref{stmt.return}). +Otherwise, flowing off the end of +the \grammarterm{compound-statement} +of a \grammarterm{handler} +of a \grammarterm{function-try-block} +is equivalent to flowing off the end of +the \grammarterm{compound-statement} +of that function (see \ref{stmt.return}). \pnum The variable declared by the \grammarterm{exception-declaration}, of type -\cv{} \tcode{T} or \cv{} \tcode{T\&}, is initialized from the exception object, +\cv{}~\tcode{T} or \cv{}~\tcode{T\&}, is initialized from the exception object, of type \tcode{E}, as follows: - \begin{itemize} \item -if \tcode{T} is a base class of \tcode{E}, the variable is -copy-initialized~(\ref{dcl.init}) from the corresponding base class subobject +if \tcode{T} is a base class of \tcode{E}, +the variable is copy-initialized\iref{dcl.init} +from an lvalue of type \tcode{T} designating the corresponding base class subobject of the exception object; -\item otherwise, the variable is copy-initialized~(\ref{dcl.init}) -from the exception object. +\item otherwise, the variable is copy-initialized\iref{dcl.init} +from an lvalue of type \tcode{E} designating the exception object. \end{itemize} The lifetime of the variable ends when the handler exits, after the -destruction of any automatic objects initialized +destruction of any objects with automatic storage duration initialized 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|)} @@ -673,741 +756,419 @@ \indextext{exception specification|(} \pnum +The predicate indicating whether a function cannot exit via an exception +is called the \defn{exception specification} of the function. +If the predicate is false, +the function has a +\indextext{exception specification!potentially-throwing}% +\defnx{potentially-throwing exception specification}% +{potentially-throwing!exception specification}, +otherwise it has a \indextext{exception specification!non-throwing}% -The \defn{exception specification} of a function -is a (possibly empty) set of types, -indicating that the function might exit -via an exception -that matches a handler of one of the types in the set; -the (conceptual) set of all types is used -to denote that the function might exit -via an exception -of arbitrary type. -If the set is empty, -the function is said to have -a \defn{non-throwing exception specification}. -The exception specification -is either defined explicitly -by using an \grammarterm{exception-specification} -as a suffix of a function declaration's declarator~(\ref{dcl.fct}) -or implicitly. - -\begin{bnf} -\nontermdef{exception-specification}\br - dynamic-exception-specification\br - noexcept-specification -\end{bnf} - -\begin{bnf} -\nontermdef{dynamic-exception-specification}\br - \terminal{throw (} type-id-list\opt \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{type-id-list}\br - type-id \terminal{...}\opt\br - type-id-list \terminal{,} type-id \terminal{...}\opt -\end{bnf} +\defn{non-throwing exception specification}. +The exception specification is either defined implicitly, +or defined explicitly +by using a \grammarterm{noexcept-specifier} +as a suffix of a function declarator\iref{dcl.fct}. \begin{bnf} -\nontermdef{noexcept-specification}\br - \terminal{noexcept} \terminal{(} constant-expression \terminal{)}\br - \terminal{noexcept} +\nontermdef{noexcept-specifier}\br + \keyword{noexcept} \terminal{(} constant-expression \terminal{)}\br + \keyword{noexcept} \end{bnf} -\indextext{exception specification!noexcept!constant expression and}% -In a \grammarterm{noexcept-specification}, the \grammarterm{constant-expression}, -if supplied, shall be a constant expression~(\ref{expr.const}) that is contextually -converted to \tcode{bool} (Clause~\ref{conv}). -A \tcode{(} token that follows \tcode{noexcept} is part of the -\grammarterm{noexcept-specification} and does not commence an -initializer~(\ref{dcl.init}). - \pnum -An -\grammarterm{exception-specification} -shall appear only on a function declarator for a function type, -pointer to function type, reference to function type, or pointer to -member function type that is the top-level type of a declaration or -definition, or on such a type appearing as a parameter or return type -in a function declarator. -An -\grammarterm{exception-specification} -shall not appear in a typedef declaration or \grammarterm{alias-declaration}. -\enterexample +\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.const}; +that constant expression is the exception specification of +the function type in which the \grammarterm{noexcept-specifier} appears. +A \tcode{(} token that follows \keyword{noexcept} is part of the +\grammarterm{noexcept-specifier} and does not commence an +initializer\iref{dcl.init}. +The \grammarterm{noexcept-specifier} \keyword{noexcept} +without a \grammarterm{constant-expression} +is +equivalent to the \grammarterm{noexcept-specifier} +\tcode{\keyword{noexcept}(\keyword{true})}. +\begin{example} \begin{codeblock} -void f() throw(int); // OK -void (*fp)() throw (int); // OK -void g(void pfa() throw(int)); // OK -typedef int (*pf)() throw(int); // ill-formed +void f() noexcept(sizeof(char[2])); // error: narrowing conversion of value 2 to type \keyword{bool} +void g() noexcept(sizeof(char)); // OK, conversion of value 1 to type \keyword{bool} is non-narrowing \end{codeblock} - -\exitexample - -\indextext{exception specification!incomplete type and}% -A type denoted -in a \grammarterm{dynamic-exception-specification} -shall not denote an incomplete type or an rvalue reference type. -A type denoted -in a \grammarterm{dynamic-exception-specification} -shall not denote a pointer or reference to an incomplete type, other than -``pointer to \cv\ \tcode{void}''. -A type -\cv\ \tcode{T}, -``array of \tcode{T}'', or -``function returning \tcode{T}'' -denoted in a \grammarterm{dynamic-exception-specification} -is adjusted to type \tcode{T}, -``pointer to \tcode{T}'', or ``pointer to function returning \tcode{T}'', respectively. -A \grammarterm{dynamic-exception-specification} -denotes an exception specification -that is the set of adjusted types specified thereby. +\end{example} \pnum -The \grammarterm{exception-specification} -\tcode{noexcept} or \tcode{noexcept(}\grammarterm{constant-expression}{}\tcode{)}, -where the \grammarterm{constant-expression} yields \tcode{true}, -denotes an exception specification -that is the empty set. -The \grammarterm{exception-specification} -\tcode{noexcept(}\grammarterm{constant-expression}{}\tcode{)}, -where the \grammarterm{constant-expression} yields \tcode{false}, -or the absence of an \grammarterm{exception-specification} -in a function declarator other than that -for a destructor~(\ref{class.dtor}) -or a deallocation function~(\ref{basic.stc.dynamic.deallocation}) -denotes an exception specification -that is the set of all types. - -\pnum -\indextext{exception specification!compatible}% -Two \grammarterm{exception-specification}{s} are -\defnx{compatible}{compatible|see{exception specification, compatible}} if -the sets of types they denote are the same. - -\pnum -If any declaration of a function has an -\grammarterm{exception-specification} -that is not a \grammarterm{noexcept-specification} allowing all exceptions, -all declarations, including the definition and any explicit specialization, -of that function shall have a compatible -\grammarterm{exception-specification}. -If any declaration of a pointer to function, reference to function, -or pointer to member function has an -\grammarterm{exception-specification}, -all occurrences of that declaration shall have a compatible -\grammarterm{exception-specification}. -If a declaration of a function has an implicit -exception specification, -other declarations of the function shall not specify an -\grammarterm{exception-specification}. -In an explicit instantiation an -\grammarterm{exception-specification} -may be specified, but is not required. -If an -\grammarterm{exception-specification} -is specified in an explicit instantiation directive, it shall -be compatible with the \grammarterm{exception-specification}{s} of -other declarations of that function. +If a declaration of a function +does not have a \grammarterm{noexcept-specifier}, +the declaration has a potentially throwing exception specification +unless it is a destructor or a deallocation function +or is defaulted on its first declaration, +in which cases the exception specification +is as specified below +and no other declaration for that function +shall have a \grammarterm{noexcept-specifier}. +In an explicit instantiation\iref{temp.explicit} +a \grammarterm{noexcept-specifier} may be specified, +but is not required. +If a \grammarterm{noexcept-specifier} is specified +in an explicit instantiation, +the exception specification shall be the same as +the exception specification of all other declarations of that function. A diagnostic is required only if the -\grammarterm{exception-specification}{s} are not compatible +exception specifications are not the same within a single translation unit. \pnum \indextext{exception specification!virtual function and}% -If a virtual function has an -exception specification, +If a virtual function has a +non-throwing exception specification, all declarations, including the definition, of any function that overrides that virtual function in any derived class -shall only allow exceptions that are allowed by the -exception specification -of the base class virtual function, +shall have a non-throwing +exception specification, unless the overriding function is defined as deleted. -\enterexample +\begin{example} \begin{codeblock} struct B { - virtual void f() throw (int, double); + virtual void f() noexcept; virtual void g(); + virtual void h() noexcept = delete; }; struct D: B { - void f(); // ill-formed - void g() throw (int); // OK + void f(); // error + void g() noexcept; // OK + void h() = delete; // OK }; \end{codeblock} The declaration of \tcode{D::f} -is ill-formed because it allows all exceptions, whereas +is ill-formed because it +has a potentially-throwing exception specification, +whereas \tcode{B::f} -allows only -\tcode{int} -and -\tcode{double}. -\exitexample -A similar restriction applies to assignment to and -initialization of pointers to functions, pointers -to member functions, and references to functions: -the target entity shall allow at least the exceptions -allowed by the source value in the assignment or -initialization. -\enterexample -\begin{codeblock} -class A { /* ... */ }; -void (*pf1)(); // no exception specification -void (*pf2)() throw(A); - -void f() { - pf1 = pf2; // OK: \tcode{pf1} is less restrictive - pf2 = pf1; // error: \tcode{pf2} is more restrictive -} -\end{codeblock} -\exitexample - -\pnum -In such an assignment or initialization, -\grammarterm{exception-specification}{s} -on return types and parameter types shall be compatible. -In other assignments or initializations, -\grammarterm{exception-specification}{s} -shall be compatible. - -\pnum -An -\grammarterm{exception-specification} -can include the same type more than once -and can include classes that are related by inheritance, -even though doing so is redundant. -\enternote An -\grammarterm{exception-specification} -can also include the class -\tcode{std::bad_exception}~(\ref{bad.exception}). -\exitnote - -\pnum -\indextext{allowing an exception|see{exception specification, allowing an exception}}% -A function is said to -\defnx{allow an exception}{exception specification!allowing an exception} -of type -\tcode{E} -if -its exception specification -contains a type -\tcode{T} -for which a handler of type -\tcode{T} -would be a match~(\ref{except.handle}) for an exception of type -\tcode{E}. -\indextext{allowing all exceptions|see{exception specification, allowing all exceptions}}% -A function is said to \defnx{allow all exceptions}{exception specification!allowing all exceptions} -if its exception specification -is the set of all types. - -\pnum -\indextext{exception handling!unexpected called@\tcode{unexpected()} called}% -\indextext{\idxcode{unexpected()}!called}% -Whenever an exception of type \tcode{E} is thrown -and the search for a handler~(\ref{except.handle}) -encounters the outermost block of a function with an -exception specification that does not allow \tcode{E}, then, - -\begin{itemize} -\item if the function definition has a -\grammarterm{dynamic-exception-specification}, the function -\tcode{std::unexpected()} is called~(\ref{except.unexpected}), - -\indextext{exception handling!terminate called@\tcode{terminate()} called}% -\indextext{\idxcode{terminate()}!called}% -\item otherwise, the function \tcode{std::terminate()} is called~(\ref{except.terminate}). -\end{itemize} - -\enterexample -\begin{codeblock} -class X { }; -class Y { }; -class Z: public X { }; -class W { }; - -void f() throw (X, Y) { - int n = 0; - if (n) throw X(); // OK - if (n) throw Z(); // also OK - throw W(); // will call \tcode{std::unexpected()} -} -\end{codeblock} -\exitexample - -\enternote A function can have multiple declarations with different non-throwing -\grammarterm{exception-specification}{s}; for this purpose, the one on the -function definition is used. \exitnote - -\pnum -An implementation shall not reject an expression merely because when -executed it throws or might -throw an exception that the containing function does not allow. -\enterexample -\begin{codeblock} -extern void f() throw(X, Y); - -void g() throw(X) { - f(); // OK -} - -\end{codeblock} -the call to -\tcode{f} -is well-formed even though when called, -\tcode{f} -might throw exception -\tcode{Y} -that -\tcode{g} -does not allow. -\exitexample - -\pnum -\enternote -An -exception specification -is not considered part of a function's type; -see~\ref{dcl.fct}. -\exitnote - -\pnum -A \defn{potential exception} of a given context is either a type that might be -thrown as an exception or a pseudo-type, denoted by ``any'', that -represents the situation where an exception of an arbitrary type might -be thrown. A subexpression \tcode{e1} of an expression \tcode{e} is an -\defn{immediate subexpression} if there is no subexpression \tcode{e2} of \tcode{e} -such that \tcode{e1} is a subexpression of \tcode{e2}. - -\pnum -The \defn{set of potential exceptions of a function, function pointer, or -member function pointer} \tcode{f} is defined as follows: -\begin{itemize} -\item -If the exception specification of \tcode{f} is the set of all types, -the set consists of the pseudo-type ``any''. -\item -Otherwise, the set consists of -every type in the exception specification of \tcode{f}. -\end{itemize} +has a non-throwing exception specification. +\end{example} \pnum -The \defn{set of potential exceptions of an expression} \tcode{e} is empty -if \tcode{e} is a core constant expression (\ref{expr.const}). -Otherwise, it is the union of the sets of potential exceptions of -the immediate subexpressions of \tcode{e}, -including default argument expressions used in a function call, -combined with a set \placeholder{S} defined by the form of \tcode{e}, as follows: - +An expression $E$ is +\defnx{potentially-throwing}{potentially-throwing!expression} if \begin{itemize} \item -If \tcode{e} is a function call (\ref{expr.call}): -\begin{itemize} -\item -If its \grammarterm{postfix-expression} is a (possibly parenthesized) -\grammarterm{id-expression}~(\ref{expr.prim.general}), class member access -(\ref{expr.ref}), or pointer-to-member operation~(\ref{expr.mptr.oper}) -whose \grammarterm{cast-expression} is an \grammarterm{id-expression}, -\placeholder{S} is the set of potential exceptions of the entity selected by the -contained \grammarterm{id-expression} (after overload resolution, if applicable). -\item -Otherwise, \placeholder{S} contains the pseudo-type ``any''. -\end{itemize} - +$E$ is a function call\iref{expr.call} +whose \grammarterm{postfix-expression} +has a function type, +or a pointer-to-function type, +with a potentially-throwing exception specification, +or \item -If \tcode{e} implicitly invokes a function (such as an overloaded operator, -an allocation function in a \grammarterm{new-expression}, or a destructor -if \tcode{e} is a full-expression~(\ref{intro.execution})), -\placeholder{S} is the set of potential exceptions of the function. +$E$ implicitly invokes a function +(such as an overloaded operator, +an allocation function in a \grammarterm{new-expression}, +a constructor for a function argument, +or a destructor) +that has a potentially-throwing exception specification, +or \item -if \tcode{e} is a \grammarterm{throw-expression}~(\ref{expr.throw}), -\placeholder{S} consists of the type of the exception object that would be -initialized by the operand, if present, or the pseudo-type ``any'' otherwise. +$E$ is a \grammarterm{throw-expression}\iref{expr.throw}, +or \item -if \tcode{e} is a \tcode{dynamic_cast} expression that casts to a reference type and -requires a run-time check~(\ref{expr.dynamic.cast}), -\placeholder{S} consists of the type \tcode{std::bad_cast}. +$E$ is a \keyword{dynamic_cast} expression that casts to a reference type and +requires a runtime check\iref{expr.dynamic.cast}, +or \item -if \tcode{e} is a \tcode{typeid} expression applied to a glvalue expression whose -type is a polymorphic class type (\ref{expr.typeid}), -\placeholder{S} consists of the type \tcode{std::bad_typeid}. +$E$ is a \keyword{typeid} expression applied to a +(possibly parenthesized) built-in unary \tcode{*} operator +applied to a pointer to a +polymorphic class type\iref{expr.typeid}, +or \item -if \tcode{e} is a \grammarterm{new-expression} with a non-constant -\grammarterm{expression} in the \grammarterm{noptr-new-declarator}~(\ref{expr.new}), -\placeholder{S} consists of the type \tcode{std::bad_array_new_length}. +any of the immediate subexpressions\iref{intro.execution} +of $E$ that is not an unevaluated operand is potentially-throwing. \end{itemize} -\enterexample -Given the following declarations -\begin{codeblock} - void f() throw(int); - void g(); - struct A { A(); }; - struct B { B() noexcept; }; - struct D() { D() throw (double); }; -\end{codeblock} -the set of potential exceptions for some sample expressions is: +\pnum +An implicitly-declared constructor for a class \tcode{X}, +or a constructor without a \grammarterm{noexcept-specifier} +that is defaulted on its first declaration, +has a potentially-throwing exception specification +if and only if +any of the following constructs is potentially-throwing: \begin{itemize} \item -for \tcode{f()}, the set consists of \tcode{int}; -\item -for \tcode{g()}, the set consists of ``any''; -\item -for \tcode{new A}, the set consists of ``any''; +the invocation of a constructor selected by overload resolution +in the implicit definition of the constructor +for class \tcode{X} +to initialize a potentially constructed subobject, or \item -for \tcode{B()}, the set is empty; +a subexpression of such an initialization, +such as a default argument expression, or, \item -for \tcode{new D}, the set consists of ``any'' and \tcode{double}. +for a default constructor, a default member initializer. \end{itemize} -\exitexample +\begin{note} +Even though destructors for fully-constructed subobjects +are invoked when an exception is thrown +during the execution of a constructor\iref{except.ctor}, +their exception specifications do not contribute +to the exception specification of the constructor, +because an exception thrown from such a destructor +would call the function \tcode{std::terminate} +rather than escape the constructor\iref{except.throw,except.terminate}. +\end{note} \pnum -Given a member function \tcode{f} of some class \tcode{X}, where \tcode{f} is -an inheriting constructor~(\ref{class.inhctor}) or an implicitly-declared special -member function, -the \defn{set of potential exceptions of the implicitly-declared member function} \tcode{f} -consists of all the members from the following sets: +The exception specification for an implicitly-declared destructor, +or a destructor without a \grammarterm{noexcept-specifier}, +is potentially-throwing if and only if +any of the destructors +for any of its potentially constructed subobjects +has a potentially-throwing exception specification or +the destructor is virtual and the destructor of any virtual base class +has a potentially-throwing exception specification. -\begin{itemize} -\item -if \tcode{f} is a constructor, -\begin{itemize} -\item -the sets of potential exceptions of the constructor invocations -\begin{itemize} -\item -for \tcode{X}'s non-variant non-static data members, -\item -for \tcode{X}'s direct base classes, and -\item -if \tcode{X} is non-abstract (\ref{class.abstract}), for \tcode{X}'s virtual base -classes, -\end{itemize} -(including default argument expressions used in such invocations) as selected -by overload resolution for the implicit definition of \tcode{f} (\ref{class.ctor}). -\enternote -Even though destructors for fully-constructed subobjects are invoked -when an exception is thrown during the execution of a constructor (\ref{except.ctor}), -their exception specifications do not contribute to the -exception specification of the constructor, because -an exception thrown from such a destructor could never escape the constructor -(\ref{except.throw}, \ref{except.terminate}). -\exitnote -\item -the sets of potential exceptions of the initialization of non-static data members -from \grammarterm{brace-or-equal-initializer}{s} that are not ignored (\ref{class.base.init}); -\end{itemize} - -\item -if \tcode{f} is an assignment operator, the sets of potential exceptions of -the assignment operator invocations for \tcode{X}'s non-variant non-static -data members and for \tcode{X}'s direct base classes (including default -argument expressions used in such invocations), as selected by overload resolution -for the implicit definition of \tcode{f} (\ref{class.copy}); +\pnum +The exception specification for an implicitly-declared assignment operator, +or an assignment-operator without a \grammarterm{noexcept-specifier} +that is defaulted on its first declaration, +is potentially-throwing if and only if +the invocation of any assignment operator +in the implicit definition is potentially-throwing. -\item -if \tcode{f} is a destructor, the sets of potential exceptions of the -destructor invocations for \tcode{X}'s non-variant non-static data members -and for \tcode{X}'s virtual and direct base classes. -\end{itemize} +\pnum +A deallocation function\iref{basic.stc.dynamic.deallocation} +with no explicit \grammarterm{noexcept-specifier} +has a non-throwing exception specification. \pnum -An inheriting constructor~(\ref{class.inhctor}) and an implicitly-declared -special member function (Clause~\ref{special}) are considered to have an -implicit exception specification, as follows, where -\placeholder{S} is the set of potential exceptions of the -implicitly-declared member function: -\begin{itemize} -\item -if \placeholder{S} contains the pseudo-type ``any'', -the implicit exception specification is the set of all types; -\item -otherwise, the implicit exception specification -contains all the types in \placeholder{S}. -\end{itemize} +The exception specification for a comparison operator function\iref{over.binary} +without a \grammarterm{noexcept-specifier} +that is defaulted on its first declaration +is potentially-throwing if and only if +any expression +in the implicit definition is potentially-throwing. -\enternote An instantiation of an inheriting constructor template has -an implied exception specification as if it were a non-template -inheriting constructor.\exitnote -\enterexample +\pnum +\begin{example} \begin{codeblock} struct A { A(int = (A(5), 0)) noexcept; - A(const A&) throw(); - A(A&&) throw(); - ~A() throw(X); + A(const A&) noexcept; + A(A&&) noexcept; + ~A(); }; struct B { - B() throw(); - B(const B&) = default; // exception specification contains no types - B(B&&, int = (throw Y(), 0)) noexcept; - ~B() throw(Y); + B() noexcept; + B(const B&) = default; // implicit exception specification is \tcode{\keyword{noexcept}(\keyword{true})} + B(B&&, int = (throw 42, 0)) noexcept; + ~B() noexcept(false); }; int n = 7; struct D : public A, public B { - int * p = new (std::nothrow) int[n]; - // exception specification of \tcode{D::D()} contains \tcode{X} and \tcode{std::bad_array_new_length} - // exception specification of \tcode{D::D(const D\&)} contains no types - // exception specification of \tcode{D::D(D\&\&)} contains \tcode{Y} - // exception specification of \tcode{D::\~D()} contains \tcode{X} and \tcode{Y} + int * p = new int[n]; + // \tcode{D::D()} potentially-throwing, as the \keyword{new} operator may throw \tcode{bad_alloc} or \tcode{bad_array_new_length} + // \tcode{D::D(const D\&)} non-throwing + // \tcode{D::D(D\&\&)} potentially-throwing, as the default argument for \tcode{B}'s constructor may throw + // \tcode{D::\~D()} potentially-throwing }; \end{codeblock} - Furthermore, if \tcode{A::\~{}A()} -or -\tcode{B::\~{}B()} were virtual, -\tcode{D::\~{}D()} -would not be as restrictive as that of -\tcode{A::\~{}A}, -and the program would be ill-formed since a function that overrides a virtual -function from a base class shall have an \grammarterm{exception-specification} - at least as restrictive as that in the base class. -\exitexample - -\pnum -A deallocation function~(\ref{basic.stc.dynamic.deallocation}) -with no explicit \grammarterm{exception-specification} -has an exception specification that is the empty set. +the program would be ill-formed since a function that overrides a virtual +function from a base class +shall not have a potentially-throwing exception specification +if the base class function has a non-throwing exception specification. +\end{example} \pnum -An \grammarterm{exception-specification} is considered to be \term{needed} when: - +An exception specification is considered to be \defnx{needed}{needed!exception specification} when: \begin{itemize} -\item in an expression, the function is the unique lookup result or the selected -member of a set of overloaded functions~(\ref{basic.lookup}, \ref{over.match}, \ref{over.over}); +\item in an expression, the function is selected by +overload resolution\iref{over.match,over.over}; -\item the function is odr-used~(\ref{basic.def.odr}) 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 \grammarterm{exception-specification} is compared to that of another +\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 \grammarterm{exception-specification} is needed for a defaulted -special member function that calls the function. -\enternote A defaulted declaration does not require the -\grammarterm{exception-specification} of a base member function to be evaluated -until the implicit \grammarterm{exception-specification} of the derived -function is needed, but an explicit \grammarterm{exception-specification} needs -the implicit \grammarterm{exception-specification} to compare against. -\exitnote -\end{itemize} - -The \grammarterm{exception-specification} of a defaulted special member -function is evaluated as described above only when needed; similarly, the -\grammarterm{exception-specification} of a specialization of a function -template or member function of a class template is instantiated only when -needed. +\item the function is defined; +\item the function is represented by a reflection; or - -\pnum -In a \grammarterm{dynamic-exception-specification}, a -\grammarterm{type-id} followed by an ellipsis is a -pack expansion~(\ref{temp.variadic}). - -\pnum -\enternote The use of \grammarterm{dynamic-exception-specification}{s} is deprecated -(see Annex~\ref{depr}). \exitnote% +\item the exception specification is needed for a defaulted +function that calls the function. +\begin{note} +A defaulted declaration does not require the +exception specification of a base member function to be evaluated +until the implicit exception specification of the derived +function is needed, but an explicit \grammarterm{noexcept-specifier} needs +the implicit exception specification to compare against. +\end{note} +\end{itemize} +The exception specification of a defaulted +function is evaluated as described above only when needed. +% \indextext{exception specification|)} \rSec1[except.special]{Special functions} +\rSec2[except.special.general]{General} + \pnum -The functions \tcode{std::terminate()}~(\ref{except.terminate}) and -\tcode{std::unexpected()}~(\ref{except.unexpected}) are used by the exception +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()}~(\ref{propagation}) and the class -\tcode{std::nested_exception}~(\ref{except.nested}) can be used by a program to +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. -\rSec2[except.terminate]{The \tcode{std::terminate()} function} +\rSec2[except.terminate]{The \tcode{std::terminate} function} \pnum -\indextext{\idxcode{terminate()}}% -In some situations exception handling must be abandoned -for less subtle error handling techniques. \enternote These situations are: - -\indextext{\idxcode{terminate()}!called}% +\indextext{\idxcode{terminate}}% +Some errors in a program cannot be recovered from, such as when an exception +is not handled or a \tcode{std::thread} object is destroyed while its thread +function is still executing. In such cases, +the function \tcode{std::terminate}\iref{exception.terminate} is invoked. +\begin{note} +These situations are: +\indextext{\idxcode{terminate}!called}% \begin{itemize} \item% when the exception handling mechanism, after completing the initialization of the exception object but before -activation of a handler for the exception~(\ref{except.throw}), +activation of a handler for the exception\iref{except.throw}, calls a function that exits via an exception, or \item% -when the exception handling mechanism cannot find a handler for a thrown exception~(\ref{except.handle}), or - -\item when the search for a handler~(\ref{except.handle}) encounters the -outermost block of a function with a \grammarterm{noexcept-specification} -that does not allow the exception~(\ref{except.spec}), or +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} +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~(\ref{except.ctor}) +when the destruction of an object during stack unwinding\iref{except.ctor} terminates by throwing an exception, or \item% -when initialization of a non-local -variable with static or thread storage duration~(\ref{basic.start.init}) +when initialization of a non-block +variable with static or thread storage duration\iref{basic.start.dynamic} exits via an exception, or \item% when destruction of an object with static or thread storage duration exits -via an exception~(\ref{basic.start.term}), or +via an exception\iref{basic.start.term}, or \item% when execution of a function registered with \tcode{std::atexit} or \tcode{std::at_quick_exit} -exits via an exception~(\ref{support.start.term}), or +exits via an exception\iref{support.start.term}, or \item% when a -\grammarterm{throw-expression}~(\ref{expr.throw}) +\grammarterm{throw-expression}\iref{expr.throw} with no operand attempts to rethrow an exception and no exception is being -handled~(\ref{except.throw}), or +handled\iref{except.throw}, or \item% -when -\tcode{std::unexpected} -exits via an exception -of a type -that is not allowed by the previously violated -exception specification, -and -\tcode{std::bad_exception} -is not included in that -exception specification~(\ref{except.unexpected}), or +when the function \tcode{std::nested_exception::rethrow_nested} is called for an object +that has captured no exception\iref{except.nested}, or \item% -when the implementation's default -unexpected exception handler -is called~(\ref{unexpected.handler}), or +when execution of the initial function of a thread exits via +an exception\iref{thread.thread.constr}, or \item% -when the function \tcode{std::nested_exception::rethrow_nested} is called for an object -that has captured no exception~(\ref{except.nested}), or +for a parallel algorithm whose \tcode{ExecutionPolicy} specifies such +behavior\iref{execpol.seq,execpol.par,execpol.parunseq}, +when execution of an element access function\iref{algorithms.parallel.defns} +of the parallel algorithm exits via an exception\iref{algorithms.parallel.exceptions}, or \item% -when execution of the initial function of a thread exits via -an exception~(\ref{thread.thread.constr}), or +when the destructor or the move assignment operator is invoked on an object +of type \tcode{std::thread} that refers to +a joinable thread\iref{thread.thread.destr,thread.thread.assign}, or \item% -when the destructor or the copy assignment operator is invoked on an object -of type \tcode{std::thread} that refers to a joinable thread -(\ref{thread.thread.destr},~\ref{thread.thread.assign}). +when a call to a \tcode{wait()}, \tcode{wait_until()}, or \tcode{wait_for()} +function on a condition variable\iref{thread.condition.condvar,thread.condition.condvarany} +fails to meet a postcondition, or -\end{itemize} +\item% +when a callback invocation exits via an exception +when requesting stop on +a \tcode{std::stop_source} or +a \tcode{std::in\-place_stop_source}\iref{stopsource.mem,stopsource.inplace.mem}, +or in the constructor of +\tcode{std::stop_callback} or +\tcode{std::inplace_stop_callback}\iref{stopcallback.cons,stopcallback.inplace.cons} +when a callback invocation exits via an exception, or + +\item% +when a \tcode{run_loop} object is destroyed +that is still in the \tcode{running} state\iref{exec.run.loop}, or + +\item% +when \tcode{unhandled_stopped} is called on +a \tcode{with_awaitable_senders} object\iref{exec.with.awaitable.senders} +whose continuation is not a handle to a coroutine +whose promise type has an \tcode{unhandled_stopped} member function, or + +\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 -\exitnote +\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 -\indextext{\idxcode{terminate()}}% -In such cases, -\tcode{std::terminate()} -is called~(\ref{exception.terminate}). +\indextext{\idxcode{terminate}}% In the situation where no matching handler is found, it is -\impldef{stack unwinding before call to \tcode{std::terminate()}} whether or not the -stack is unwound -before -\tcode{std::terminate()} -is called. -In the situation where the search for a handler~(\ref{except.handle}) encounters the -outermost block of a function with a \grammarterm{noexcept-specification} -that does not allow the exception~(\ref{except.spec}), it is -\impldef{whether stack is unwound before calling \tcode{std::terminate()} -when a \tcode{noexcept} specification -is violated} +\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} +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} whether the stack is unwound, unwound partially, or not unwound at all -before \tcode{std::terminate()} is called. +before the function \tcode{std::terminate} is invoked. In all other situations, the stack shall not be unwound before -\tcode{std::terminate()} -is called. +the function \tcode{std::terminate} +is invoked. An implementation is not permitted to finish stack unwinding prematurely based on a determination that the unwind process -will eventually cause a call to -\tcode{std::terminate()}. - -\rSec2[except.unexpected]{The \tcode{std::unexpected()} function} - -\pnum -\indextext{\idxcode{unexpected()}}% -If a function with -a \grammarterm{dynamic-exception-specification} -exits via an exception -of a type that is not allowed by its exception specification, -the function -\tcode{std::unexpected()} -is called~(\ref{exception.unexpected}) immediately after completing -the stack unwinding for the former function. - -\pnum -\enternote By default, \tcode{std::unexpected()} calls \tcode{std::terminate()}, but a -program can install its own handler function~(\ref{set.unexpected}). In either case, the -constraints in the following paragraph apply. \exitnote - -\pnum -The -\tcode{std::unexpected()} -function shall not return, but it can throw (or rethrow) an exception. -If it throws a new exception which is allowed by the exception specification -which previously was violated, then the search for another handler -will continue at the call of the function whose exception specification was violated. -If it exits via an exception of a type that the -\grammarterm{dynamic-exception-specification} -does not allow, -then the following happens: -\indextext{\idxcode{bad_exception}}% -If the -\grammarterm{dynamic-exception-specification} -does not include the class -\tcode{std::bad_exception}~(\ref{bad.exception}) -then the function -\tcode{std::terminate()} -is called, otherwise the thrown exception is replaced by an -implementation-defined object of type -\tcode{std::bad_exception} -and the search for another handler will continue at the call of the function -whose -\grammarterm{dynamic-exception-specification} -was violated. - -\pnum -\enternote -Thus, -a \grammarterm{dynamic-exception-specification} -guarantees that a function exits only via an exception of one of the listed types. -If the -\grammarterm{dynamic-exception-specification} -includes the type -\tcode{std::bad_exception} -then any exception type not on the list may be replaced by -\tcode{std\-::\-bad_ex\-cep\-tion} -within the function -\tcode{std::unexpected()}. -\exitnote - -\rSec2[except.uncaught]{The \tcode{std::uncaught_exceptions()} function}% -\indexlibrary{\idxcode{uncaught_exceptions}} - -\pnum -An exception is considered uncaught -after completing the initialization of the exception object~(\ref{except.throw}) -until completing the activation of a handler for the exception~(\ref{except.handle}). -This includes stack unwinding. -If the exception is rethrown~(\ref{expr.throw}), -it is considered uncaught from the point of rethrow -until the rethrown exception is caught again. -The function \tcode{std::uncaught_exceptions()}~(\ref{uncaught.exceptions}) -returns the number of uncaught exceptions.% +will eventually cause an invocation of the function +\tcode{std::terminate}. \indextext{exception handling|)} diff --git a/source/exec.tex b/source/exec.tex new file mode 100644 index 0000000000..4f7f72b01c --- /dev/null +++ b/source/exec.tex @@ -0,0 +1,9470 @@ +%!TEX root = std.tex +\rSec0[exec]{Execution control library} + +\rSec1[exec.general]{General} + +\pnum +This Clause describes components +supporting execution of function objects\iref{function.objects}. + +\pnum +The following subclauses describe +the requirements, concepts, and components +for execution control primitives as summarized in \tref{exec.summary}. + +\begin{libsumtab}{Execution control library summary}{exec.summary} +\ref{exec.sched} & Schedulers & \tcode{} \\ +\ref{exec.recv} & Receivers & \\ +\ref{exec.opstate} & Operation states & \\ +\ref{exec.snd} & Senders & \\ +\end{libsumtab} + +\pnum +\tref{exec.pos} shows +the types of customization point objects\iref{customization.point.object} +used in the execution control library. + +\begin{floattable}{Types of customization point objects in the execution control library}{exec.pos}{lx{0.23\hsize}x{0.45\hsize}} +\topline +\lhdr{Customization point} & \chdr{Purpose} & \rhdr{Examples} \\ +\lhdr{object type} & & \\ +\capsep +core & + provide core execution functionality, and connection between core components & + e.g., \tcode{connect}, \tcode{start} \\ +completion functions & + called by senders to announce the completion of the work (success, error, or cancellation) & + \tcode{set_value}, \tcode{set_error}, \tcode{set_stopped} \\ +senders & + allow the specialization of the provided sender algorithms & + \begin{itemize} + \item sender factories (e.g., \tcode{schedule}, \tcode{just}, \tcode{read_env}) + \item sender adaptors (e.g., \tcode{continues_on}, \tcode{then}, \tcode{let_value}) + \item sender consumers (e.g., \tcode{sync_wait}) + \end{itemize} + \\ +queries & + allow querying different properties of objects & + \begin{itemize} + \item general queries (e.g., \tcode{get_allocator}, \tcode{get_stop_token}) + \item environment queries (e.g., \tcode{get_scheduler}, \tcode{get_delegation_scheduler}) + \item scheduler queries (e.g., \tcode{get_forward_progress_guarantee}) + \item sender attribute queries (e.g., \tcode{get_completion_scheduler}) + \end{itemize} + \\ +\end{floattable} + +\pnum +This clause makes use of the following exposition-only entities. + +\pnum +For a subexpression \tcode{expr}, +let \tcode{\exposid{MANDATE-NOTHROW}(expr)} be +expression-equivalent to \tcode{expr}. + +\mandates +\tcode{noexcept(expr)} is \tcode{true}. + +\pnum +\begin{codeblock} +namespace std { + template + concept @\defexposconcept{movable-value}@ = // \expos + @\libconcept{move_constructible}@> && + @\libconcept{constructible_from}@, T> && + (!is_array_v>); +} +\end{codeblock} + +\pnum +For function types \tcode{F1} and \tcode{F2} denoting +\tcode{R1(Args1...)} and \tcode{R2(Args2...)}, respectively, +\tcode{\exposid{MATCHING-SIG}(F1, F2)} is \tcode{true} if and only if +\tcode{\libconcept{same_as}} +is \tcode{true}. + +\pnum +For a subexpression \tcode{err}, +let \tcode{Err} be \tcode{decltype((err))} and +let \tcode{\exposid{AS-EXCEPT-PTR}(err)} be: +\begin{itemize} +\item +\tcode{err} if \tcode{decay_t} denotes the type \tcode{exception_ptr}. + +\expects +\tcode{!err} is \tcode{false}. +\item +Otherwise, +\tcode{make_exception_ptr(system_error(err))} +if \tcode{decay_t} denotes the type \tcode{error_code}. +\item +Otherwise, \tcode{make_exception_ptr(err)}. +\end{itemize} + +\pnum +For a subexpression \tcode{expr}, +let \tcode{\exposid{AS-CONST}(expr)} be expression-equivalent to +\begin{codeblock} +[](const auto& x) noexcept -> const auto& { return x; }(expr) +\end{codeblock} + +\rSec1[exec.queryable]{Queries and queryables} + +\rSec2[exec.queryable.general]{General} + +\pnum +A \defnadj{queryable}{object} is +a read-only collection of key/value pair +where each key is a customization point object known as a \defn{query object}. +A \defn{query} is an invocation of a query object +with a queryable object as its first argument and +a (possibly empty) set of additional arguments. +A query imposes syntactic and semantic requirements on its invocations. + +\pnum +Let \tcode{q} be a query object, +let \tcode{args} be a (possibly empty) pack of subexpressions, +let \tcode{env} be a subexpression +that refers to a queryable object \tcode{o} of type \tcode{O}, and +let \tcode{cenv} be a subexpression referring to \tcode{o} +such that \tcode{decltype((cenv))} is \tcode{const O\&}. +The expression \tcode{q(env, args...)} is equal to\iref{concepts.equality} +the expression \tcode{q(cenv, args...)}. + +\pnum +The type of a query expression cannot be \tcode{void}. + +\pnum +The expression \tcode{q(env, args...)} is +equality-preserving\iref{concepts.equality} and +does not modify the query object or the arguments. + +\pnum +If the expression \tcode{env.query(q, args...)} is well-formed, +then it is expression-equivalent to \tcode{q(env, args...)}. + +\pnum +Unless otherwise specified, +the result of a query is valid as long as the queryable object is valid. + +\rSec2[exec.queryable.concept]{\tcode{queryable} concept} + +\begin{codeblock} +namespace std { + template + concept @\defexposconcept{queryable}@ = @\libconcept{destructible}@; // \expos +} +\end{codeblock} + +\pnum +The exposition-only \exposconcept{queryable} concept specifies +the constraints on the types of queryable objects. + +\pnum +Let \tcode{env} be an object of type \tcode{Env}. +The type \tcode{Env} models \exposconcept{queryable} +if for each callable object \tcode{q} and a pack of subexpressions \tcode{args}, +if \tcode{requires \{ q(env, args...) \}} is \tcode{true} then +\tcode{q(env, args...)} meets any semantic requirements imposed by \tcode{q}. + +\rSec1[exec.async.ops]{Asynchronous operations} + +\pnum +An \defnadj{execution}{resource} is a program entity that manages +a (possibly dynamic) set of execution agents\iref{thread.req.lockable.general}, +which it uses to execute parallel work on behalf of callers. +\begin{example} +The currently active thread, +a system-provided thread pool, and +uses of an API associated with an external hardware accelerator +are all examples of execution resources. +\end{example} +Execution resources execute asynchronous operations. +An execution resource is either valid or invalid. + +\pnum +An \defnadj{asynchronous}{operation} is +a distinct unit of program execution that +\begin{itemize} +\item +is explicitly created; +\item +can be explicitly started once at most; +\item +once started, eventually completes exactly once +with a (possibly empty) set of result datums and +in exactly one of three \defnx{dispositions}{disposition}: +success, failure, or cancellation; +\begin{itemize} +\item +A successful completion, also known as a \defnadj{value}{completion}, +can have an arbitrary number of result datums. +\item +A failure completion, also known as an \defnadj{error}{completion}, +has a single result datum. +\item +A cancellation completion, also known as a \defnadj{stopped}{completion}, +has no result datum. +\end{itemize} +An asynchronous operation's \defnadj{async}{result} +is its disposition and its (possibly empty) set of result datums. +\item +can complete on a different execution resource +than the execution resource on which it started; and +\item +can create and start other asynchronous operations +called \defnadj{child}{operations}. +A child operation is an asynchronous operation +that is created by the parent operation and, +if started, completes before the parent operation completes. +A \defnadj{parent}{operation} is the asynchronous operation +that created a particular child operation. +\end{itemize} +\begin{note} +An asynchronous operation can execute synchronously; +that is, it can complete during the execution of its start operation +on the thread of execution that started it. +\end{note} + +\pnum +An asynchronous operation has associated state +known as its \defnadj{operation}{state}. + +\pnum +An asynchronous operation has an associated environment. +An \defn{environment} is a queryable object\iref{exec.queryable} +representing the execution-time properties of the operation's caller. +The caller of an asynchronous operation is +its parent operation or the function that created it. + +\pnum +An asynchronous operation has an associated receiver. +A \defn{receiver} is an aggregation of three handlers +for the three asynchronous completion dispositions: +\begin{itemize} +\item a value completion handler for a value completion, +\item an error completion handler for an error completion, and +\item a stopped completion handler for a stopped completion. +\end{itemize} +A receiver has an associated environment. +An asynchronous operation's operation state owns the operation's receiver. +The environment of an asynchronous operation +is equal to its receiver's environment. + +\pnum +For each completion disposition, there is a \defnadj{completion}{function}. +A completion function is +a customization point object\iref{customization.point.object} +that accepts an asynchronous operation's receiver as the first argument and +the result datums of the asynchronous operation as additional arguments. +The value completion function invokes +the receiver's value completion handler with the value result datums; +likewise for the error completion function and the stopped completion function. +A completion function has +an associated type known as its \defnadj{completion}{tag} +that is the unqualified type of the completion function. +A valid invocation of a completion function is called +a \defnadj{completion}{operation}. + +\pnum +The \defn{lifetime of an asynchronous operation}, +also known as the operation's \defn{async lifetime}, +begins when its start operation begins executing and +ends when its completion operation begins executing. +If the lifetime of an asynchronous operation's associated operation state +ends before the lifetime of the asynchronous operation, +the behavior is undefined. +After an asynchronous operation executes a completion operation, +its associated operation state is invalid. +Accessing any part of an invalid operation state is undefined behavior. + +\pnum +An asynchronous operation shall not execute a completion operation +before its start operation has begun executing. +After its start operation has begun executing, +exactly one completion operation shall execute. +The lifetime of an asynchronous operation's operation state can end +during the execution of the completion operation. + +\pnum +A \defn{sender} is a factory for one or more asynchronous operations. +\defnx{Connecting}{connect} a sender and a receiver creates +an asynchronous operation. +The asynchronous operation's associated receiver is equal to +the receiver used to create it, and +its associated environment is equal to +the environment associated with the receiver used to create it. +The lifetime of an asynchronous operation's associated operation state +does not depend on the lifetimes of either the sender or the receiver +from which it was created. +A sender is started when it is connected to a receiver and +the resulting asynchronous operation is started. +A sender's async result is the async result of the asynchronous operation +created by connecting it to a receiver. +A sender sends its results by way of the asynchronous operation(s) it produces, +and a receiver receives those results. +A sender is either valid or invalid; +it becomes invalid when its parent sender (see below) becomes invalid. + +\pnum +A \defn{scheduler} is an abstraction of an execution resource +with a uniform, generic interface for scheduling work onto that resource. +It is a factory for senders +whose asynchronous operations execute value completion operations +on an execution agent belonging to +the scheduler's associated execution resource. +A \defn{schedule-expression} obtains such a sender from a scheduler. +A \defn{schedule sender} is the result of a schedule expression. +On success, an asynchronous operation produced by a schedule sender executes +a value completion operation with an empty set of result datums. +Multiple schedulers can refer to the same execution resource. +A scheduler can be valid or invalid. +A scheduler becomes invalid when the execution resource to which it refers +becomes invalid, +as do any schedule senders obtained from the scheduler, and +any operation states obtained from those senders. + +\pnum +An asynchronous operation has one or more associated completion schedulers +for each of its possible dispositions. +A \defn{completion scheduler} is a scheduler +whose associated execution resource is used to execute +a completion operation for an asynchronous operation. +A value completion scheduler is a scheduler +on which an asynchronous operation's value completion operation can execute. +Likewise for error completion schedulers and stopped completion schedulers. + +\pnum +A sender has an associated queryable object\iref{exec.queryable} +known as its \defnx{attributes}{attribute} +that describes various characteristics of the sender and +of the asynchronous operation(s) it produces. +For each disposition, +there is a query object for reading the associated completion scheduler +from a sender's attributes; +i.e., a value completion scheduler query object +for reading a sender's value completion scheduler, etc. +If a completion scheduler query is well-formed, +the returned completion scheduler is unique +for that disposition for any asynchronous operation the sender creates. +A schedule sender is required to have a value completion scheduler attribute +whose value is equal to the scheduler that produced the schedule sender. + +\pnum +A \defn{completion signature} is a function type +that describes a completion operation. +An asynchronous operation has a finite set of possible completion signatures +corresponding to the completion operations +that the asynchronous operation potentially evaluates\iref{basic.def.odr}. +For a completion function \tcode{set}, +receiver \tcode{rcvr}, and +pack of arguments \tcode{args}, +let \tcode{c} be the completion operation \tcode{set(rcvr, args...)}, and +let \tcode{F} be +the function type \tcode{decltype(auto(set))(decltype((args))...)}. +A completion signature \tcode{Sig} is associated with \tcode{c} +if and only if +\tcode{\exposid{MATCHING-SIG}(Sig, F)} is \tcode{true}\iref{exec.general}. +Together, a sender type and an environment type \tcode{Env} determine +the set of completion signatures of an asynchronous operation +that results from connecting the sender with a receiver +that has an environment of type \tcode{Env}. +The type of the receiver does not affect +an asynchronous operation's completion signatures, +only the type of the receiver's environment. +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. +There are three categories of sender algorithms: +\begin{itemize} +\item +A \defn{sender factory} is a function +that takes non-senders as arguments and that returns a sender. +\item +A \defn{sender adaptor} is a function +that constructs and returns a parent sender +from a set of one or more child senders and +a (possibly empty) set of additional arguments. +An asynchronous operation created by a parent sender is +a parent operation to the child operations created by the child senders. +\item +A \defn{sender consumer} is a function +that takes one or more senders and +a (possibly empty) set of additional arguments, and +whose return type is not the type of a sender. +\end{itemize} + +\rSec1[execution.syn]{Header \tcode{} synopsis} + +\indexheader{execution}% +\begin{codeblock} +namespace std { + // \ref{execpol.type}, execution policy type trait + template struct is_execution_policy; // freestanding + template constexpr bool @\libglobal{is_execution_policy_v}@ = // freestanding + is_execution_policy::value; +} + +namespace std::execution { + // \ref{execpol.seq}, sequenced execution policy + class sequenced_policy; + + // \ref{execpol.par}, parallel execution policy + class parallel_policy; + + // \ref{execpol.parunseq}, parallel and unsequenced execution policy + class parallel_unsequenced_policy; + + // \ref{execpol.unseq}, unsequenced execution policy + class unsequenced_policy; + + // \ref{execpol.objects}, execution policy objects + inline constexpr sequenced_policy seq{ @\unspec@ }; + inline constexpr parallel_policy par{ @\unspec@ }; + inline constexpr parallel_unsequenced_policy par_unseq{ @\unspec@ }; + inline constexpr unsequenced_policy unseq{ @\unspec@ }; +} + +namespace std { + // \ref{exec.general}, helper concepts + template + concept @\exposconceptnc{movable-value}@ = @\seebelownc@; // \expos + + template + concept @\defexposconceptnc{decays-to}@ = @\libconcept{same_as}@, To>; // \expos + + template + concept @\defexposconceptnc{class-type}@ = @\exposconceptnc{decays-to}@ && is_class_v; // \expos + + // \ref{exec.queryable}, queryable objects + template + concept @\exposconceptnc{queryable}@ = @\seebelownc@; // \expos + + // \ref{exec.queries}, queries + struct @\libglobal{forwarding_query_t}@ { @\unspec@ }; + struct @\libglobal{get_allocator_t}@ { @\unspec@ }; + struct @\libglobal{get_stop_token_t}@ { @\unspec@ }; + + inline constexpr forwarding_query_t @\libglobal{forwarding_query}@{}; + inline constexpr get_allocator_t @\libglobal{get_allocator}@{}; + inline constexpr get_stop_token_t @\libglobal{get_stop_token}@{}; + + template + using stop_token_of_t = remove_cvref_t()))>; + + template + concept @\defexposconceptnc{forwarding-query}@ = forwarding_query(T{}); // \expos +} + +namespace std::execution { + // \ref{exec.queries}, queries + struct @\libglobal{get_domain_t}@ { @\unspec@ }; + struct @\libglobal{get_scheduler_t}@ { @\unspec@ }; + struct @\libglobal{get_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}@{}; + + template + using @\libglobal{env_of_t}@ = decltype(get_env(declval())); + + // \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_tag}@ {}; + + template + concept @\libconcept{scheduler}@ = @\seebelow@; + + // \ref{exec.recv}, receivers + struct @\libglobal{receiver_tag}@ {}; + + template + concept @\libconcept{receiver}@ = @\seebelow@; + + template + concept @\exposconceptnc{receiver-of}@ = @\seebelownc@; // \expos + + template + concept @\libconcept{inlinable_receiver}@ = @\seebelow@; + + struct @\libglobal{set_value_t}@ { @\unspec@ }; + struct @\libglobal{set_error_t}@ { @\unspec@ }; + struct @\libglobal{set_stopped_t}@ { @\unspec@ }; + + inline constexpr set_value_t @\libglobal{set_value}@{}; + inline constexpr set_error_t @\libglobal{set_error}@{}; + inline constexpr set_stopped_t @\libglobal{set_stopped}@{}; + + // \ref{exec.opstate}, operation states + struct @\libglobal{operation_state_tag}@ {}; + + template + concept @\libconcept{operation_state}@ = @\seebelow@; + + struct @\libglobal{start_t}@; + inline constexpr start_t @\libglobal{start}@{}; + + // \ref{exec.snd}, senders + struct @\libglobal{sender_tag}@ {}; + + template + inline constexpr bool enable_sender = @\seebelow@; + + template + concept @\libconcept{sender}@ = @\seebelow@; + + template + concept @\libconcept{sender_in}@ = @\seebelow@; + + template + concept @\libconcept{dependent_sender}@ = @\seebelow@; + + template + concept @\exposconceptnc{sender-to}@ = @\seebelownc@; // \expos + + template + struct @\exposidnc{type-list}@; // \expos + + template + using @\exposidnc{decayed-tuple}@ = tuple...>; // \expos + + template + using @\exposidnc{variant-or-empty}@ = @\seebelownc@; // \expos + + template, + template class Tuple = @\exposid{decayed-tuple}@, + template class Variant = @\exposid{variant-or-empty}@> + requires @\libconcept{sender_in}@ + using value_types_of_t = @\seebelow@; + + template, + template class Variant = @\exposid{variant-or-empty}@> + requires @\libconcept{sender_in}@ + using error_types_of_t = @\seebelow@; + + template> + requires @\libconcept{sender_in}@ + constexpr bool sends_stopped = @\seebelow@; + + template + using @\exposidnc{single-sender-value-type}@ = @\seebelownc@; // \expos + + template + concept @\exposconceptnc{single-sender}@ = @\seebelownc@; // \expos + + template<@\libconcept{sender}@ Sndr> + using tag_of_t = @\seebelow@; + + // \ref{exec.snd.transform}, sender transformations + 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}@{}; + + template + using @\libglobal{connect_result_t}@ = + decltype(connect(declval(), declval())); + + // \ref{exec.factories}, sender factories + struct @\libglobal{just_t}@ { @\unspec@ }; + struct @\libglobal{just_error_t}@ { @\unspec@ }; + struct @\libglobal{just_stopped_t}@ { @\unspec@ }; + struct @\libglobal{schedule_t}@ { @\unspec@ }; + + inline constexpr just_t @\libglobal{just}@{}; + inline constexpr just_error_t @\libglobal{just_error}@{}; + inline constexpr just_stopped_t @\libglobal{just_stopped}@{}; + inline constexpr schedule_t @\libglobal{schedule}@{}; + inline constexpr @\unspec@ @\libglobal{read_env}@{}; + + template<@\libconcept{scheduler}@ Sch> + using @\libglobal{schedule_result_t}@ = decltype(schedule(declval())); + + // \ref{exec.adapt}, sender adaptors + template<@\exposconcept{class-type}@ D> + struct @\libglobal{sender_adaptor_closure}@ { }; + + struct @\libglobal{starts_on_t}@ { @\unspec@ }; + struct @\libglobal{continues_on_t}@ { @\unspec@ }; + struct @\libglobal{on_t}@ { @\unspec@ }; + struct @\libglobal{schedule_from_t}@ { @\unspec@ }; + struct @\libglobal{then_t}@ { @\unspec@ }; + struct @\libglobal{upon_error_t}@ { @\unspec@ }; + struct @\libglobal{upon_stopped_t}@ { @\unspec@ }; + struct @\libglobal{let_value_t}@ { @\unspec@ }; + struct @\libglobal{let_error_t}@ { @\unspec@ }; + struct @\libglobal{let_stopped_t}@ { @\unspec@ }; + struct @\libglobal{bulk_t}@ { @\unspec@ }; + struct @\libglobal{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}@{}; + inline constexpr schedule_from_t @\libglobal{schedule_from}@{}; + inline constexpr then_t @\libglobal{then}@{}; + inline constexpr upon_error_t @\libglobal{upon_error}@{}; + inline constexpr upon_stopped_t @\libglobal{upon_stopped}@{}; + inline constexpr let_value_t @\libglobal{let_value}@{}; + inline constexpr let_error_t @\libglobal{let_error}@{}; + inline constexpr let_stopped_t @\libglobal{let_stopped}@{}; + inline constexpr bulk_t @\libglobal{bulk}@{}; + inline constexpr 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.cmplsig}, completion signatures + template + concept @\exposconceptnc{completion-signature}@ = @\seebelownc@; // \expos + + template<@\exposconcept{completion-signature}@... Fns> + struct @\libglobal{completion_signatures}@; + + template + concept @\exposconceptnc{valid-completion-signatures}@ = @\seebelownc@; // \expos + + struct dependent_sender_error : exception {}; + + // \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.run.loop}, run_loop + class run_loop; + + // \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}, 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} + +\pnum +The exposition-only type \tcode{\exposid{variant-or-empty}} +is defined as follows: +\begin{itemize} +\item +If \tcode{sizeof...(Ts)} is greater than zero, +\tcode{\exposid{variant-or-empty}} denotes \tcode{variant} +where \tcode{Us...} is the pack \tcode{decay_t...} +with duplicate types removed. +\item +Otherwise, \tcode{\exposid{variant-or-empty}} denotes +the exposition-only class type: +\begin{codeblock} +namespace std::execution { + struct @\exposidnc{empty-variant}@ { // \expos + @\exposidnc{empty-variant}@() = delete; + }; +} +\end{codeblock} +\end{itemize} + +\pnum +For 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{\exposid{gather-signatures}} +if that type is well-formed, +\item +Otherwise, \tcode{void} +if \tcode{\exposid{gather-signatures}} is +\tcode{variant>} or \tcode{variant<>}, +\item +Otherwise, \tcode{\exposid{gather-signatures}} +if that\linebreak{} type is well-formed, +\item +Otherwise, \tcode{\exposid{single-sender-value-type}} is ill-formed. +\end{itemize} + +\pnum +The exposition-only concept \exposconcept{single-sender} is defined as follows: +\begin{codeblock} +namespace std::execution { + template + concept @\defexposconcept{single-sender}@ = @\libconcept{sender_in}@ && + requires { + typename @\exposid{single-sender-value-type}@; + }; +} +\end{codeblock} + +\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 +\tcode{forwarding_query} asks a query object +whether it should be forwarded through queryable adaptors. + +\pnum +The name \tcode{forwarding_query} denotes a query object. +For some query object \tcode{q} of type \tcode{Q}, +\tcode{forwarding_query(q)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{\exposid{MANDATE-NOTHROW}(q.query(forwarding_query))} +if that expression is well-formed. + +\mandates +The expression above has type \tcode{bool} and +is a core constant expression if \tcode{q} is a core constant expression. +\item +Otherwise, \tcode{true} if \tcode{\libconcept{derived_from}} is \tcode{true}. +\item +Otherwise, \tcode{false}. +\end{itemize} + +\rSec2[exec.get.allocator]{\tcode{get_allocator}} + +\pnum +\tcode{get_allocator} asks a queryable object for its associated allocator. + +\pnum +The name \tcode{get_allocator} denotes a query object. +For a subexpression \tcode{env}, +\tcode{get_allocator(env)} is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_allocator))}. + +\mandates +If the expression above is well-formed, +its type satisfies +\exposconcept{simple-allocator}\iref{allocator.requirements.general}. + +\pnum +\tcode{forwarding_query(get_allocator)} is a core constant expression and +has value \tcode{true}. + +\rSec2[exec.get.stop.token]{\tcode{get_stop_token}} + +\pnum +\tcode{get_stop_token} asks a queryable object for an associated stop token. + +\pnum +The name \tcode{get_stop_token} denotes a query object. +For a subexpression \tcode{env}, +\tcode{get_stop_token(env)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_stop_token))} +if that expression is well-formed. + +\mandates +The type of the expression above satisfies \libconcept{stoppable_token}. + +\item +Otherwise, \tcode{never_stop_token\{\}}. +\end{itemize} + +\pnum +\tcode{forwarding_query(get_stop_token)} is a core constant expression and +has value \tcode{true}. + +\rSec2[exec.get.env]{\tcode{execution::get_env}} + +\pnum +\tcode{execution::get_env} is a customization point object. +For a subexpression \tcode{o}, +\tcode{execution::get_env(o)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(o).get_env())} +if that expression is well-formed. + +\mandates +The type of the expression above satisfies +\exposconcept{queryable}\iref{exec.queryable}. +\item +Otherwise, \tcode{env<>\{\}}. +\end{itemize} + +\pnum +The value of \tcode{get_env(o)} shall be valid while \tcode{o} is valid. + +\pnum +\begin{note} +When passed a sender object, +\tcode{get_env} returns the sender's associated attributes. +When passed a receiver, +\tcode{get_env} returns the receiver's associated execution environment. +\end{note} + +\rSec2[exec.get.domain]{\tcode{execution::get_domain}} + +\pnum +\tcode{get_domain} asks a queryable object +for its associated execution domain tag. + +\pnum +The name \tcode{get_domain} denotes a query object. +For a subexpression \tcode{env}, +\tcode{get_domain(env)} is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(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 +a core constant expression and has value \tcode{true}. + +\rSec2[exec.get.scheduler]{\tcode{execution::get_scheduler}} + +\pnum +\tcode{get_scheduler} asks a queryable object for its associated scheduler. + +\pnum +The name \tcode{get_scheduler} denotes a query object. +For a subexpression \tcode{env}, +\tcode{get_scheduler(env)} is expression-equivalent to +\tcode{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, +its type satisfies \libconcept{scheduler}. + +\pnum +\tcode{forwarding_query(execution::get_scheduler)} is +a core constant expression and has value \tcode{true}. + +\rSec2[exec.get.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 +\tcode{get_delegation_scheduler} asks a queryable object for a scheduler +that can be used to delegate work to +for the purpose of forward progress delegation\iref{intro.progress}. + +\pnum +The name \tcode{get_delegation_scheduler} denotes a query object. +For a subexpression \tcode{env}, +\tcode{get_delegation_scheduler(env)} is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(\exposid{AS-CONST}(env).query(get_delegation_scheduler))}. + +\mandates +If the expression above is well-formed, +its type satisfies \libconcept{scheduler}. + +\pnum +\tcode{forwarding_query(execution::get_delegation_scheduler)} is +a core constant expression and has value \tcode{true}. + +\rSec2[exec.get.fwd.progress]{\tcode{execution::get_forward_progress_guarantee}} + +\begin{codeblock} +namespace std::execution { + enum class @\libglobal{forward_progress_guarantee}@ { + concurrent, + parallel, + weakly_parallel + }; +} +\end{codeblock} + +\pnum +\tcode{get_forward_progress_guarantee} asks a scheduler about +the forward progress guarantee of execution agents +created by that scheduler's associated execution resource\iref{intro.progress}. + +\pnum +The name \tcode{get_forward_progress_guarantee} denotes a query object. +For a subexpression \tcode{sch}, let \tcode{Sch} be \tcode{decltype((sch))}. +If \tcode{Sch} does not satisfy \libconcept{scheduler}, +\tcode{get_forward_progress_guarantee} is ill-formed. +Otherwise, +\tcode{get_forward_progress_guarantee(sch)} is expression-equivalent to: +\begin{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}. + +\pnum +If \tcode{get_forward_progress_guarantee(sch)} for some scheduler \tcode{sch} +returns \tcode{forward_progress_guaran\-tee::concurrent}, +all execution agents created by that scheduler's associated execution resource +shall provide the concurrent forward progress guarantee. +If it returns \tcode{forward_progress_guarantee::parallel}, +all such execution agents +shall provide at least the parallel forward progress guarantee. + +\rSec2[exec.get.compl.sched]{\tcode{execution::get_completion_scheduler}} + +\pnum +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 +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, the expression +is expression-equivalent to: +\begin{itemize} +\item +\begin{codeblock} +@\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 \tcode{get_completion_scheduler<\exposid{completion-fn-tag}>(q, envs...)} +is well-formed, +its type satisfies \libconcept{scheduler}. + +\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_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...)}, +the behavior is undefined +unless the evaluation happens on an execution agent +that belongs to \tcode{sch}'s associated execution resource. + +\pnum +The expression +\tcode{forwarding_query(get_completion_scheduler<\exposid{completion-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} + +\pnum +The \libconcept{scheduler} concept defines +the requirements of a scheduler type\iref{exec.async.ops}. +\tcode{schedule} is a customization point object +that accepts a scheduler. +A valid invocation of \tcode{schedule} is a schedule-expression. +\begin{codeblock} +namespace std::execution { + template + concept @\deflibconcept{scheduler}@ = + @\libconcept{derived_from}@::scheduler_concept, scheduler_tag> && + @\exposconcept{queryable}@ && + requires(Sch&& sch) { + { schedule(std::forward(sch)) } -> @\libconcept{sender}@; + { get_forward_progress_guarantee(sch) } -> @\libconcept{same_as}@; + } && + @\libconcept{equality_comparable}@> && + @\libconcept{copyable}@>; +} +\end{codeblock} + +\pnum +Let \tcode{Sch} be the type of a scheduler and +let \tcode{Env} be the type of an execution environment +for which \tcode{\libconcept{sender_in}, Env>} +is satisfied. +Then \tcode{\exposconcept{sender-in-of}, Env>} +shall be modeled. + +\pnum +No operation required by +\tcode{\libconcept{copyable}>} and +\tcode{\libconcept{equality_comparable}>} +shall exit via an exception. +None of these operations, +nor a scheduler type's \tcode{schedule} function, +shall introduce data races +as a result of potentially concurrent\iref{intro.races} invocations +of those operations from different threads. + +\pnum +For any two values \tcode{sch1} and \tcode{sch2} +of some scheduler type \tcode{Sch}, +\tcode{sch1 == sch2} shall return \tcode{true} +only if both \tcode{sch1} and \tcode{sch2} share +the same associated execution resource. + +\pnum +For a given scheduler expression \tcode{sch}, +if the expression +\tcode{get_completion_scheduler(get_env(schedule(sch)))} +is well-formed, +it shall compare equal to \tcode{sch}. + +\pnum +For a given scheduler expression \tcode{sch}, +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}. + +\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} + +\rSec2[exec.recv.concepts]{Receiver concepts} + +\pnum +A receiver represents the continuation of an asynchronous operation. +The \libconcept{receiver} concept defines +the requirements for a receiver type\iref{exec.async.ops}. +The 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. +The \tcode{get_env} customization point object is used to access +a receiver's associated environment. +\begin{codeblock} +namespace std::execution { + template + concept @\deflibconcept{receiver}@ = + @\libconcept{derived_from}@::receiver_concept, receiver_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, and + is_nothrow_move_constructible_v>; // no-throw-movable + + template + concept @\defexposconceptnc{valid-completion-for}@ = // \expos + requires (Signature* sig) { + [](Tag(*)(Args...)) + requires @\exposconcept{callable}@, Args...> + {}(sig); + }; + + template + concept @\defexposconceptnc{has-completions}@ = // \expos + requires (Completions* completions) { + []<@\exposconcept{valid-completion-for}@...Sigs>(completion_signatures*) + {}(completions); + }; + + template + concept @\defexposconceptnc{receiver-of}@ = // \expos + @\libconcept{receiver}@ && @\exposconcept{has-completions}@; +} +\end{codeblock} + +\pnum +Class types that are marked \tcode{final} do not model the \libconcept{receiver} concept. + +\pnum +Let \tcode{rcvr} be a receiver and +let \tcode{op_state} be an operation state associated with +an asynchronous operation created by connecting \tcode{rcvr} with a sender. +Let \tcode{token} be a stop token equal to +\tcode{get_stop_token(get_env(rcvr))}. +\tcode{token} shall remain valid +for the duration of the asynchronous operation's lifetime\iref{exec.async.ops}. +\begin{note} +This means that, unless it knows about further guarantees +provided by the type of \tcode{rcvr}, +the implementation of \tcode{op_state} cannot use \tcode{token} +after it executes a completion operation. +This also implies that any stop callbacks registered on token +must be destroyed before the invocation of the completion operation. +\end{note} + +\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 +\tcode{set_value} is a value completion function\iref{exec.async.ops}. +Its associated completion tag is \tcode{set_value_t}. +The expression \tcode{set_value(rcvr, vs...)} +for a subexpression \tcode{rcvr} and +pack of subexpressions \tcode{vs} is ill-formed +if \tcode{rcvr} is an lvalue or an rvalue of const type. +Otherwise, it is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(rcvr.set_value(vs...))}. + +\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 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 +\tcode{set_stopped} is a stopped completion function\iref{exec.async.ops}. +Its associated completion tag is \tcode{set_stopped_t}. +The expression \tcode{set_stopped(rcvr)} +for a subexpression \tcode{rcvr} is ill-formed +if \tcode{rcvr} is an lvalue or an rvalue of const type. +Otherwise, it is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(rcvr.set_stopped())}. + +\mandates +If the expression above is well-formed, its type is \tcode{void}. + +\rSec1[exec.opstate]{Operation states} + +\rSec2[exec.opstate.general]{General} + +\pnum +The \libconcept{operation_state} concept defines +the requirements of an operation state type\iref{exec.async.ops}. +\begin{codeblock} +namespace std::execution { + template + concept @\deflibconcept{operation_state}@ = + @\libconcept{derived_from}@ && + requires (O& o) { + start(o); + }; +} +\end{codeblock} + +\pnum +If an \libconcept{operation_state} object is destroyed +during the lifetime of its asynchronous operation\iref{exec.async.ops}, +the behavior is undefined. +\begin{note} +The \libconcept{operation_state} concept does not impose requirements +on any operations other than destruction and \tcode{start}, +including copy and move operations. +Invoking any such operation on an object +whose type models \libconcept{operation_state} can lead to undefined behavior. +\end{note} + +\pnum +The program is ill-formed +if it performs a copy or move construction or assignment operation on +an operation state object created by connecting a library-provided sender. + +\rSec2[exec.opstate.start]{\tcode{execution::start}} + +\pnum +The name \tcode{start} denotes a customization point object +that starts\iref{exec.async.ops} +the asynchronous operation associated with the operation state object. +For a subexpression \tcode{op}, +the expression \tcode{start(op)} is ill-formed +if \tcode{op} is an rvalue. +Otherwise, it is expression-equivalent to +\tcode{\exposid{MANDATE-NOTHROW}(op.start())}. + +\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}, +the behavior of calling \tcode{start(op)} is undefined. + +\rSec1[exec.snd]{Senders} + +\rSec2[exec.snd.general]{General} + +\pnum +Subclauses \ref{exec.factories} and \ref{exec.adapt} define +customizable algorithms that return senders. +Each algorithm has a default implementation. +Let \tcode{sndr} be the result of an invocation of such an algorithm or +an object equal to the result\iref{concepts.equality}, and +let \tcode{Sndr} be \tcode{decltype((sndr))}. +Let \tcode{rcvr} be a receiver of type \tcode{Rcvr} +with associated environment \tcode{env} of type \tcode{Env} +such that \tcode{\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, 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.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: + +\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} +such that for a query object \tcode{q} and +a pack of subexpressions \tcode{as}, +the expression \tcode{\exposid{FWD-ENV}(env).query(q, as...)} is ill-formed +if \tcode{forwarding_query(q)} is \tcode{false}; +otherwise, it is expression-equivalent to \tcode{env.query(q, as...)}. +\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}, +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, args...)} has +a value equal to \tcode{v}\iref{concepts.equality}. +Unless otherwise stated, +the object to which \tcode{env.query(q, args...)} refers remains valid +while \tcode{env} remains valid. + +\pnum +For two queryable objects \tcode{env1} and \tcode{env2}, +a query object \tcode{q}, and +a pack of subexpressions \tcode{as}, +\tcode{\exposid{JOIN-ENV}(env1, env2)} is an expression \tcode{env3} +whose type satisfies \exposconcept{queryable} +such that \tcode{env3.query(q, as...)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{env1.query(q, as...)} if that expression is well-formed, +\item +otherwise, \tcode{env2.query(q, as...)} if that expression is well-formed, +\item +otherwise, \tcode{env3.query(q, as...)} is ill-formed. +\end{itemize} + +\pnum +The results of \exposid{FWD-ENV}, \exposid{MAKE-ENV}, and \exposid{JOIN-ENV} +can be context-dependent; +i.e., they can evaluate to expressions +with different types and value categories +in different contexts for the same arguments. + +\pnum +For a 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-ENV}(sch)} is an expression \tcode{o} +whose type satisfies \exposconcept{queryable} +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{o.query(get_domain)} is expression-equivalent to +\tcode{sch.query(get_domain)}. + +\pnum +For two subexpressions \tcode{rcvr} and \tcode{expr}, +\tcode{\exposid{SET-VALUE}(rcvr, expr)} is expression-equivalent to +\tcode{(expr, set_value(std::move(rcvr)))} +if the type of \tcode{expr} is \tcode{void}; +otherwise, \tcode{set_value(std::move(rcvr), expr)}. +\tcode{\exposid{TRY-EVAL}(rcvr, expr)} is equivalent to: +\begin{codeblock} +try { + expr; +} catch(...) { + set_error(std::move(rcvr), current_exception()); +} +\end{codeblock} +if \tcode{expr} is potentially-throwing; otherwise, \tcode{expr}. +\tcode{\exposid{TRY-SET-VALUE}(rcvr, expr)} is +\begin{codeblock} +@\exposid{TRY-EVAL}@(rcvr, @\exposid{SET-VALUE}@(rcvr, expr)) +\end{codeblock} +except that \tcode{rcvr} is evaluated only once. + +\begin{itemdecl} +template + constexpr decltype(auto) @\exposid{query-with-default}@( + Tag, const Env& env, Default&& value) noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{e} be the expression \tcode{Tag()(env)} +if that expression is well-formed; +otherwise, it is \tcode{static_cast(std::forward(value))}. + +\pnum +\returns +\tcode{e}. + +\pnum +\remarks +The expression in the noexcept clause is \tcode{noexcept(e)}. +\end{itemdescr} + +\pnum +\begin{codeblock} +template<@\exposconcept{callable}@ Fun> + requires is_nothrow_move_constructible_v +struct @\exposid{emplace-from}@ { + Fun @\exposid{fun}@; // \expos + using type = @\exposid{call-result-t}@; + + constexpr operator type() && noexcept(@\exposconcept{nothrow-callable}@) { + return std::move(fun)(); + } + + constexpr type operator()() && noexcept(@\exposconcept{nothrow-callable}@) { + return std::move(fun)(); + } +}; +\end{codeblock} +\begin{note} +\exposid{emplace-from} is used to emplace non-movable types +into \tcode{tuple}, \tcode{optional}, \tcode{variant}, and similar types. +\end{note} + +\pnum +\begin{codeblock} +struct @\exposid{on-stop-request}@ { + inplace_stop_source& @\exposid{stop-src}@; // \expos + void operator()() noexcept { @\exposid{stop-src}@.request_stop(); } +}; +\end{codeblock} + +\pnum +\begin{codeblock} +template +struct @\exposid{product-type}@ { // \expos + T@$_0$@ t@$_0$@; // \expos + T@$_1$@ t@$_1$@; // \expos + @\vdots@ + T@$_n$@ t@$_n$@; // \expos + + template + constexpr decltype(auto) @\exposid{get}@(this Self&& self) noexcept; // \expos + + template + constexpr decltype(auto) @\exposid{apply}@(this Self&& self, Fn&& fn) // \expos + noexcept(@\seebelow@); +}; +\end{codeblock} + +\pnum +\begin{note} +\exposid{product-type} is presented here in pseudo-code form +for the sake of exposition. +It can be approximated in standard \Cpp{} with a tuple-like implementation +that takes care to keep the type an aggregate +that can be used as the initializer of a structured binding declaration. +\end{note} +\begin{note} +An expression of type \exposid{product-type} is usable as +the initializer of a structured binding declaration\iref{dcl.struct.bind}. +\end{note} + +\begin{itemdecl} +template +constexpr decltype(auto) @\exposid{get}@(this Self&& self) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto& [...ts] = self; +return std::forward_like(ts...[I]); +\end{codeblock} +\end{itemdescr} + +\begin{codeblock} +template +constexpr decltype(auto) @\exposid{apply}@(this Self&& self, Fn&& fn) noexcept(@\seebelow@); +\end{codeblock} + +\begin{itemdescr} +\pnum +\constraints +The expression in the \tcode{return} statement below is well-formed. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto& [...ts] = self; +return std::forward(fn)(std::forward_like(ts)...); +\end{codeblock} + +\pnum +\remarks +The expression in the \tcode{noexcept} clause is \tcode{true} +if the \tcode{return} statement above is not potentially throwing; +otherwise, \tcode{false}. +\end{itemdescr} + +\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 + constexpr auto @\exposid{make-sender}@(Tag tag, Data&& data, Child&&... child); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +The following expressions are \tcode{true}: +\begin{itemize} +\item \tcode{\libconcept{semiregular}} +\item \tcode{\exposconcept{movable-value}} +\item \tcode{(\libconcept{sender} \&\& ...)} +\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 +\returns +A prvalue of +type \tcode{\exposid{basic-sender}, decay_t...>} +that has been direct-list-initialized with the forwarded arguments, +where \exposid{basic-sender} is the following exposition-only class template except as noted below. + +\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 // \expos + using @\exposid{state-type}@ = decay_t<@\exposid{call-result-t}@< + decltype(@\exposid{impls-for}@>::@\exposid{get-state}@), Sndr, Rcvr&>>; + + template // \expos + using @\exposid{env-type}@ = @\exposid{call-result-t}@< + decltype(@\exposid{impls-for}@>::@\exposid{get-env}@), Index, + @\exposid{state-type}@&, const Rcvr&>; + + template + using @\exposidnc{data-type}@ = decltype(declval().template @\exposidnc{get}@<1>()); // \expos + + template + using @\exposidnc{child-type}@ = decltype(declval().template @\exposidnc{get}@()); // \expos + + template + using @\exposidnc{indices-for}@ = remove_reference_t::@\exposidnc{indices-for}@; // \expos + + template + 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 @\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 @\exposidnc{basic-receiver}@ { // \expos + using receiver_concept = receiver_tag; + + 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 + void set_value(Args&&... args) && noexcept { + @\exposid{complete}@(Index(), @\exposidnc{op}@->@\exposid{state}@, @\exposidnc{op}@->@\exposid{rcvr}@, set_value_t(), std::forward(args)...); + } + + template + void set_error(Error&& err) && noexcept { + @\exposid{complete}@(Index(), @\exposidnc{op}@->@\exposid{state}@, @\exposidnc{op}@->@\exposid{rcvr}@, set_error_t(), std::forward(err)); + } + + 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{tag-t}@>::@\exposid{get-env}@(Index(), @\exposidnc{op}@->@\exposid{state}@, @\exposidnc{op}@->@\exposid{rcvr}@); + } + + @\exposidnc{basic-state}@* @\exposidnc{op}@; // \expos + }; +} +\end{codeblock} + +\begin{codeblock} +namespace std::execution { + constexpr auto @\exposidnc{connect-all}@ = @\seebelownc@; // \expos + + template + using @\exposidnc{connect-all-result}@ = @\exposidnc{call-result-t}@< // \expos + decltype(@\exposid{connect-all}@), @\exposid{basic-state}@*, Sndr, @\exposid{indices-for}@>; +} +\end{codeblock} + +\pnum +The object \exposid{connect-all} is initialized with +a callable object equivalent to the following lambda: +\begin{itemdecl} +[]( + @\exposid{basic-state}@* op, Sndr&& sndr, index_sequence) noexcept(@\seebelow@) + -> decltype(auto) { + auto& [_, data, ...child] = sndr; + return @\exposid{product-type}@{connect( + std::forward_like(child), + @\exposid{basic-receiver}@>{op})...}; + } +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression in the \tcode{return} statement is well-formed. + +\pnum +\remarks +The expression in the \tcode{noexcept} clause is \tcode{true} +if the \tcode{return} statement is not potentially throwing; +otherwise, \tcode{false}. +\end{itemdescr} + +\pnum +\begin{codeblock} +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 constructor of \exposid{basic-operation} is: +\begin{codeblock} +is_nothrow_constructible_v<@\exposid{basic-state}@, Self, Rcvr> && +noexcept(@\exposid{connect-all}@(this, std::forward(sndr), @\exposid{indices-for}@())) +\end{codeblock} + +\pnum +\begin{codeblock} +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} + +\pnum +The member \tcode{\exposid{default-impls}::\exposid{get-env}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](auto, auto&, const auto& rcvr) noexcept -> decltype(auto) { + return @\exposid{FWD-ENV}@(get_env(rcvr)); +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{default-impls}::\exposid{get-state}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](Sndr&& sndr, Rcvr& rcvr) noexcept -> decltype(auto) { + auto& [_, data, ...child] = sndr; + return @\exposid{allocator-aware-forward}@(std::forward_like(data), rcvr); +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{default-impls}::\exposid{start}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](auto&, auto&, auto&... ops) noexcept -> void { + (execution::start(ops), ...); +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{default-impls}::\exposid{complete}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[]( + Index, auto& state, Rcvr& rcvr, Tag, Args&&... args) noexcept + -> void requires @\exposconcept{callable}@ { + static_assert(Index::value == 0); + Tag()(std::move(rcvr), std::forward(args)...); +} +\end{codeblock} + +\indexlibrarymember{\exposid{check-types}}{\exposid{default-impls}}% +\begin{itemdecl} +template + static consteval void @\exposid{default-impls}@::@\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} +((void)get_completion_signatures<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)...>(), ...); +\end{codeblock} + +\pnum +\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{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} +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 +\begin{codeblock} +namespace std::execution { + template + struct @\exposidnc{basic-sender}@ : @\exposidnc{product-type}@ { // \expos + using sender_concept = sender_tag; + using @\exposidnc{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> + 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}@ = + enable_sender> && + requires (const remove_cvref_t& sndr) { + { get_env(sndr) } -> @\exposconcept{queryable}@; + } && + @\libconcept{move_constructible}@> && + @\libconcept{constructible_from}@, Sndr>; + + template + concept @\deflibconcept{sender_in}@ = + @\libconcept{sender}@ && + (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 @\defexposconcept{sender-to}@ = // \expos + @\libconcept{sender_in}@> && + @\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 +let \tcode{rcvr} be a receiver +with an associated environment whose type is \tcode{Env}. +A completion operation is a \defnadj{permissible}{completion} +for \tcode{Sndr} and \tcode{Env} +if its completion signature appears in the argument list of the specialization of \tcode{completion_signatures} denoted by +\tcode{completion_signatures_of_t}. +\tcode{Sndr} and \tcode{Env} model \tcode{\libconcept{sender_in}} +if all the completion operations +that are potentially evaluated by connecting \tcode{sndr} to \tcode{rcvr} and +starting the resulting operation state +are permissible completions for \tcode{Sndr} and \tcode{Env}. + +\pnum +\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 +\exposconcept{sender-of} and \exposconcept{sender-in-of} +define the requirements for a sender type +that completes with a given unique set of value result types. +\begin{codeblock} +namespace std::execution { + template + using @\exposid{value-signature}@ = set_value_t(As...); // \expos + + template + concept @\defexposconcept{sender-in-of-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}@ = // \expos + @\exposconcept{sender-in-of-impl}@; + + template + concept @\defexposconcept{sender-of}@ = // \expos + @\exposconcept{sender-in-of-impl}@; +} +\end{codeblock} + +\pnum +Let \tcode{sndr} be an expression +such that \tcode{decltype((sndr))} is \tcode{Sndr}. +The type \tcode{tag_of_t} is as follows: +\begin{itemize} +\item +If the declaration +\begin{codeblock} +auto&& [tag, data, ...children] = sndr; +\end{codeblock} +would be well-formed, \tcode{tag_of_t} is +an alias for \tcode{decltype(auto(tag))}. +\item +Otherwise, \tcode{tag_of_t} is ill-formed. +\end{itemize} + +\pnum +Let \exposconcept{sender-for} be an exposition-only concept defined as follows: +\begin{codeblock} +namespace std::execution { + template + concept @\defexposconcept{sender-for}@ = + @\libconcept{sender}@ && + @\libconcept{same_as}@, Tag>; +} +\end{codeblock} + +\pnum +For a type \tcode{T}, +\tcode{\exposid{SET-VALUE-SIG}(T)} denotes the type \tcode{set_value_t()} +if \tcode{T} is \cv{} \tcode{void}; +otherwise, it denotes the type \tcode{set_value_t(T)}. + +\pnum +Library-provided sender types +\begin{itemize} +\item +always expose an overload of a member \tcode{connect} +that accepts an rvalue sender and +\item +only expose an overload of a member \tcode{connect} +that accepts an lvalue sender if they model \libconcept{copy_constructible}. +\end{itemize} + +\rSec2[exec.awaitable]{Awaitable helpers} + +\pnum +The sender concepts recognize awaitables as senders. +For \ref{exec}, an \defn{awaitable} is an expression +that would be well-formed as the operand of a \tcode{co_await} expression +within a given context. + +\pnum +For a subexpression \tcode{c}, +let \tcode{\exposid{GET-AWAITER}(c, p)} be expression-equivalent to +the series of transformations and conversions applied to \tcode{c} +as the operand of an \grammarterm{await-expression} in a coroutine, +resulting in lvalue \tcode{e} as described by \ref{expr.await}, +where \tcode{p} is an lvalue referring to the coroutine's promise, +which has type \tcode{Promise}. +\begin{note} +This includes the invocation of +the promise type's \tcode{await_transform} member if any, +the invocation of the \tcode{operator co_await} +picked by overload resolution if any, and +any necessary implicit conversions and materializations. +\end{note} + +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} +namespace std { + template + concept @\exposconcept{await-suspend-result}@ = @\seebelow@; // \expos + + template + concept @\defexposconcept{is-awaiter}@ = // \expos + requires (A& a, coroutine_handle h) { + a.await_ready() ? 1 : 0; + { a.await_suspend(h) } -> @\exposconcept{await-suspend-result}@; + a.await_resume(); + }; + + template + concept @\defexposconcept{is-awaitable}@ = // \expos + requires (C (*fc)() noexcept, Promise&... p) { + { @\exposid{GET-AWAITER}@(fc(), p...) } -> @\exposconcept{is-awaiter}@; + }; +} +\end{codeblock} + +\tcode{\defexposconcept{await-suspend-result}} is \tcode{true} +if and only if one of the following is \tcode{true}: +\begin{itemize} +\item \tcode{T} is \tcode{void}, or +\item \tcode{T} is \tcode{bool}, or +\item \tcode{T} is a specialization of \tcode{coroutine_handle}. +\end{itemize} + +\pnum +For a subexpression \tcode{c} +such that \tcode{decltype((c))} is type \tcode{C}, and +an lvalue \tcode{p} of type \tcode{Promise}, +\tcode{\exposid{await-result-\newline type}} denotes +the type \tcode{decltype(\exposid{GET-AWAITER}(c, p).await_resume())} 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: +\begin{codeblock} +namespace std::execution { + template + concept @\defexposconcept{has-as-awaitable}@ = // \expos + requires (T&& t, Promise& p) { + { std::forward(t).as_awaitable(p) } -> @\exposconcept{is-awaitable}@; + }; + + template + struct @\exposid{with-await-transform}@ { // \expos + template + T&& await_transform(T&& value) noexcept { + return std::forward(value); + } + + template<@\exposconcept{has-as-awaitable}@ T> + 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)); + } + }; +} +\end{codeblock} + +\pnum +Let \exposid{env-promise} be the exposition-only class template: +\begin{codeblock} +namespace std::execution { + template + struct @\exposid{env-promise}@ : @\exposid{with-await-transform}@<@\exposid{env-promise}@> { // \expos + @\unspec@ get_return_object() noexcept; + @\unspec@ initial_suspend() noexcept; + @\unspec@ final_suspend() noexcept; + void unhandled_exception() noexcept; + void return_void() noexcept; + coroutine_handle<> unhandled_stopped() noexcept; + + const Env& get_env() const noexcept; + }; +} +\end{codeblock} +\begin{note} +Specializations of \exposid{env-promise} are used only for the purpose of type computation; +its members need not be defined. +\end{note} + +\rSec2[exec.domain.indeterminate]{\tcode{execution::indeterminate_domain}} + +\pnum +\indexlibraryglobal{indeterminate_domain}% +\indexlibraryctor{indeterminate_domain}% +\begin{codeblock} +namespace std::execution { + template + struct indeterminate_domain { + indeterminate_domain() = default; + constexpr indeterminate_domain(auto&&) noexcept {} + + template + static constexpr decltype(auto) transform_sender(Tag, Sndr&& sndr, const Env& env) + noexcept(@\seebelow@); + }; +} +\end{codeblock} + +\indexlibrarymember{transform_sender}{indeterminate_domain}% +\begin{itemdecl} +template + static constexpr decltype(auto) transform_sender(Tag, Sndr&& sndr, const Env& env) + noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +For each type \tcode{D} in \tcode{Domains...}, +the expression +\begin{codeblock} +D().transform_sender(Tag(), std::forward(sndr), env) +\end{codeblock} +is either ill-formed or has the same decayed type as +\tcode{default_domain().transform_sender(Tag(), std::forward(sndr), env)}. + +\pnum +\returns +\tcode{default_domain().transform_sender(Tag(), std::forward(sndr), env)}. + +\pnum +\remarks +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} + +\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 +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_sender(Tag(), std::forward(sndr), env) +\end{codeblock} +if that expression is well-formed; +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}% +\begin{itemdecl} +template +constexpr decltype(auto) apply_sender(Tag, Sndr&& sndr, Args&&... args) + noexcept(@\seebelow@); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{e} be the expression +\begin{codeblock} + Tag().apply_sender(std::forward(sndr), std::forward(args)...) +\end{codeblock} + +\pnum +\constraints +\tcode{e} is a well-formed expression. + +\pnum +\returns +\tcode{e}. + +\pnum +\remarks +The exception specification is equivalent to \tcode{noexcept(e)}. +\end{itemdescr} + +\rSec2[exec.snd.transform]{\tcode{execution::transform_sender}} + +\indexlibraryglobal{transform_sender}% +\begin{itemdecl} +namespace std::execution { + template<@\libconcept{sender}@ Sndr, @\exposconcept{queryable}@ Env> + constexpr decltype(auto) transform_sender(Sndr&& sndr, const Env& env) + noexcept(@\seebelow@); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +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(tag, s, env) +\end{codeblock} +if that expression is well-formed; otherwise, +\begin{codeblock} +default_domain().transform_sender(tag, s, env) +\end{codeblock} +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{\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. + +Let \exposid{tmp-sndr} be the expression +\begin{codeblock} +@\exposid{transform-recurse}@(@\exposid{completion-domain}@(sndr), set_value, sndr) +\end{codeblock} +and let \exposid{final-sndr} be the expression +\begin{codeblock} +@\exposid{transform-recurse}@(@\exposid{start-domain}@, start, @\exposid{tmp-sndr}@) +\end{codeblock} + +\pnum +\returns +\exposid{final-sndr}. + +\pnum +\remarks +The exception specification is equivalent to +\tcode{noexcept(\exposid{final-sndr})}. +\end{itemdescr} + +\rSec2[exec.snd.apply]{\tcode{execution::apply_sender}} + +\indexlibraryglobal{apply_sender}% +\begin{itemdecl} +namespace std::execution { + template + constexpr decltype(auto) apply_sender(Domain dom, Tag, Sndr&& sndr, Args&&... args) + noexcept(@\seebelow@); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $e$ be the expression +\begin{codeblock} +dom.apply_sender(Tag(), std::forward(sndr), std::forward(args)...) +\end{codeblock} +if that expression is well-formed; otherwise, +\begin{codeblock} +default_domain().apply_sender(Tag(), std::forward(sndr), std::forward(args)...) +\end{codeblock} + +\pnum +\constraints +The expression $e$ is well-formed. + +\pnum +\returns +$e$. + +\pnum +\remarks +The exception specification is equivalent to \tcode{noexcept($e$)}. +\end{itemdescr} + +\rSec2[exec.getcomplsigs]{\tcode{execution::get_completion_signatures}} + +\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 +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{\placeholder{CHECKED-COMPLSIGS}(\placeholder{get-complsigs}())} +if \tcode{\placeholder{get-complsigs}()} +is a well-formed expression. + +\item +Otherwise, +\tcode{\placeholder{CHECKED-COMPLSIGS}(\placeholder{get-complsigs}())} +if \tcode{\placeholder{get-complsigs}()} +is a well-formed expression. + +\item +Otherwise, +\begin{codeblock} +completion_signatures< + @\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{(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 +whose type \tcode{Rcvr} models \libconcept{receiver}, and +let \tcode{Sndr} be the type of a sender +such that \tcode{\libconcept{sender_in}>} is \tcode{true}. +Let \tcode{Sigs...} be the template arguments of +the \tcode{completion_signatures} specialization +named by \tcode{completion_signatures_of_t>}. +Let \tcode{CSO} be a completion function. +If sender \tcode{Sndr} or its operation state cause +the expression \tcode{CSO(rcvr, args...)} +to be potentially evaluated\iref{basic.def.odr} +then there shall be a signature \tcode{Sig} in \tcode{Sigs...} +such that +\begin{codeblock} +@\exposid{MATCHING-SIG}@(@\exposid{decayed-typeof}@(decltype(args)...), Sig) +\end{codeblock} +is \tcode{true}\iref{exec.general}. + +\rSec2[exec.connect]{\tcode{execution::connect}} + +\pnum +\tcode{connect} connects\iref{exec.async.ops} a sender with a receiver. + +\pnum +The name \tcode{connect} denotes a customization point object. +For subexpressions \tcode{sndr} and \tcode{rcvr}, +let \tcode{Sndr} be \tcode{decltype((sndr))} and +\tcode{Rcvr} be \tcode{decltype((rcvr))}, +let \tcode{new_sndr} be the expression +\tcode{transform_sender(\newline sndr, get_env(rcvr))} +and let \tcode{DS} and \tcode{DR} be +\tcode{decay_t} and \tcode{decay_t}, respectively. + +\pnum +Let \exposid{connect-awaitable-promise} be the following exposition-only class: + +\begin{codeblock} +namespace std::execution { + struct @\exposid{connect-awaitable-promise}@ : @\exposid{with-await-transform}@<@\exposid{connect-awaitable-promise}@> { + + @\exposid{connect-awaitable-promise}@(DS&, DR& rcvr) noexcept : @\exposid{rcvr}@(rcvr) {} + + suspend_always initial_suspend() noexcept { return {}; } + [[noreturn]] suspend_always final_suspend() noexcept { terminate(); } + [[noreturn]] void unhandled_exception() noexcept { terminate(); } + [[noreturn]] void return_void() noexcept { terminate(); } + + coroutine_handle<> unhandled_stopped() noexcept { + set_stopped(std::move(@\exposid{rcvr}@)); + return noop_coroutine(); + } + + @\exposid{operation-state-task}@ get_return_object() noexcept { + return @\exposid{operation-state-task}@{ + coroutine_handle<@\exposid{connect-awaitable-promise}@>::from_promise(*this)}; + } + + env_of_t get_env() const noexcept { + return execution::get_env(@\exposid{rcvr}@); + } + + private: + DR& @\exposid{rcvr}@; // \expos + }; +} +\end{codeblock} + +\pnum +Let \exposid{operation-state-task} be the following exposition-only class: +\begin{codeblock} +namespace std::execution { + struct @\exposid{operation-state-task}@ { // \expos + using operation_state_concept = operation_state_tag; + using promise_type = @\exposid{connect-awaitable-promise}@; + + explicit @\exposid{operation-state-task}@(coroutine_handle<> h) noexcept : coro(h) {} + @\exposid{operation-state-task}@(@\exposid{operation-state-task}@&&) = delete; + ~@\exposid{operation-state-task}@() { @\exposid{coro}@.destroy(); } + + void start() & noexcept { + @\exposid{coro}@.resume(); + } + + private: + coroutine_handle<> @\exposid{coro}@; // \expos + }; +} +\end{codeblock} + +\pnum +Let \tcode{V} name the type +\tcode{\exposid{await-result-type}}, +let \tcode{Sigs} name the type +\begin{codeblock} +completion_signatures< + @\exposid{SET-VALUE-SIG}@(V), // see~\ref{exec.snd.concepts} + set_error_t(exception_ptr), + set_stopped_t()> +\end{codeblock} +and let \exposid{connect-awaitable} be an exposition-only coroutine +defined as follows: +\begin{codeblock} +namespace std::execution { + template + auto @\exposid{suspend-complete}@(Fun fun, Ts&&... as) noexcept { // \expos + auto fn = [&, fun]() noexcept { fun(std::forward(as)...); }; + + struct awaiter { + decltype(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{fn}; + } + + @\exposid{operation-state-task}@ @\exposid{connect-awaitable}@(DS sndr, DR rcvr) requires @\exposconcept{receiver-of}@ { + exception_ptr ep; + try { + if constexpr (@\libconcept{same_as}@) { + co_await std::move(sndr); + co_await @\exposid{suspend-complete}@(set_value, std::move(rcvr)); + } else { + co_await @\exposid{suspend-complete}@(set_value, std::move(rcvr), co_await std::move(sndr)); + } + } catch(...) { + ep = current_exception(); + } + co_await @\exposid{suspend-complete}@(set_error, std::move(rcvr), std::move(ep)); + } +} +\end{codeblock} + +\pnum +The expression \tcode{connect(sndr, rcvr)} is expression-equivalent to: +\begin{itemize} +\item +\tcode{new_sndr.connect(rcvr)} if that expression is well-formed. + +\mandates +The type of the expression above satisfies \libconcept{operation_state}. + +\item +Otherwise, \tcode{\exposid{connect-awaitable}(new_sndr, rcvr)}. +\end{itemize} +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 +The following are \tcode{true}: +\begin{itemize} +\item +\tcode{\libconcept{sender_in}>} +\item +\tcode{\exposconcept{receiver-of}>>} +\end{itemize} + +\rSec2[exec.factories]{Sender factories} + +\rSec3[exec.schedule]{\tcode{execution::schedule}} + +\pnum +\tcode{schedule} obtains a schedule sender\iref{exec.async.ops} +from a scheduler. + +\pnum +The name \tcode{schedule} denotes a customization point object. +For a subexpression \tcode{sch}, +the expression \tcode{schedule(sch)} is expression-equivalent to +\tcode{sch.schedule()}. + +\pnum +\mandates +The type of \tcode{sch.schedule()} satisfies \libconcept{sender}. + +\rSec3[exec.just]{\tcode{execution::just}, \tcode{execution::just_error}, \tcode{execution::just_stopped}} + +\pnum +\tcode{just}, \tcode{just_error}, and \tcode{just_stopped} are sender factories +whose asynchronous operations complete synchronously in their start operation +with a value completion operation, +an error completion operation, or +a stopped completion operation, respectively. + +\pnum +The names \tcode{just}, \tcode{just_error}, and \tcode{just_stopped} denote +customization point objects. +Let \exposid{just-cpo} be one of +\tcode{just}, \tcode{just_error}, or \tcode{just_stopped}. +For a pack of subexpressions \tcode{ts}, +let \tcode{Ts} be the pack of types \tcode{decltype((ts))}. +The expression \tcode{\exposid{just-cpo}(ts...)} is ill-formed if +\begin{itemize} +\item +\tcode{(\exposconcept{movable-value} \&\&...)} is \tcode{false}, or +\item +\exposid{just-cpo} is \tcode{just_error} and +\tcode{sizeof...(ts) == 1} is \tcode{false}, or +\item +\exposid{just-cpo} is \tcode{just_stopped} and +\tcode{sizeof...(ts) == 0} is \tcode{false}. +\end{itemize} + +Otherwise, it is expression-equivalent to +\tcode{\exposid{make-sender}(\exposid{just-cpo}, \exposid{product-type}\{ts...\})}. + +For \tcode{just}, \tcode{just_error}, and \tcode{just_stopped}, +let \exposid{set-cpo} be +\tcode{set_value}, \tcode{set_error}, and \tcode{set_stopped}, respectively. +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \exposid{just-cpo} as follows: +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@<@\exposid{decayed-typeof}@<@\exposid{just-cpo}@>> : @\exposid{default-impls}@ { + static constexpr auto @\exposid{start}@ = + [](auto& state, auto& rcvr) noexcept -> void { + auto& [...ts] = state; + @\exposid{set-cpo}@(std::move(rcvr), std::move(ts)...); + }; + }; +} +\end{codeblock} + +\rSec3[exec.read.env]{\tcode{execution::read_env}} + +\pnum +\tcode{read_env} is a sender factory for a sender +whose asynchronous operation completes synchronously in its start operation +with a value completion result equal to +a value read from the receiver's associated environment. + +\pnum +\tcode{read_env} is a customization point object. +For some query object \tcode{q}, +the expression \tcode{read_env(q)} is expression-equivalent to +\tcode{\exposid{make-sender}(read_env, q)}. + +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \tcode{read_env} as follows: +\indexlibraryglobal{\exposid{impls-for}<\exposid{decayed-typeof}>} +\begin{codeblock} +namespace std::execution { + template<> + struct @\exposid{impls-for}@<@\exposid{decayed-typeof}@> : @\exposid{default-impls}@ { + static constexpr auto start = + [](auto query, auto& rcvr) noexcept -> void { + @\exposid{TRY-SET-VALUE}@(rcvr, query(get_env(rcvr))); + }; + }; + + 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} + +\pnum +Subclause \ref{exec.adapt} specifies a set of sender adaptors. + +\pnum +The bitwise inclusive \logop{or} operator is overloaded +for the purpose of creating sender chains. +The adaptors also support function call syntax with equivalent semantics. + +\pnum +Unless otherwise specified: +\begin{itemize} +\item +A sender adaptor is prohibited from causing observable effects, +apart from moving and copying its arguments, +before the returned sender is connected with a receiver using \tcode{connect}, +and \tcode{start} is called on the resulting operation state. +\item +A parent sender\iref{exec.async.ops} with a single child sender \tcode{sndr} has +an associated attribute object equal to +\tcode{\exposid{FWD-ENV}(get_env(sndr))}\iref{exec.fwd.env} +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<>\{\}} +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 +If a sender returned from a sender adaptor specified in \ref{exec.adapt} +is specified to include \tcode{set_error_t(Err)} +among its set of completion signatures +where \tcode{decay_t} denotes the type \tcode{exception_ptr}, +but the implementation does not potentially evaluate +an error completion operation with an \tcode{exception_ptr} argument, +the implementation is allowed to omit +the \tcode{exception_ptr} error completion signature from the set. + +\rSec3[exec.adapt.obj]{Closure objects} + +\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}. +For a pipeable sender adaptor closure object \tcode{c} and +an expression \tcode{sndr} +such that \tcode{decltype((sndr))} models \libconcept{sender}, +the following expressions are equivalent and yield a \libconcept{sender}: +\begin{codeblock} +c(sndr) +sndr | c +\end{codeblock} +Given an additional pipeable sender adaptor closure object \tcode{d}, +the expression \tcode{c | d} produces +another pipeable sender adaptor closure object \tcode{e}: + +\tcode{e} is a perfect forwarding call wrapper\iref{func.require} +with the following properties: +\begin{itemize} +\item +Its target object is an object \tcode{d2} of type \tcode{decltype(auto(d))} +direct-non-list-initialized with \tcode{d}. +\item +It has one bound argument entity, +an object \tcode{c2} of type \tcode{decltype(auto(c))} +direct-non-list-initialized with \tcode{c}. +\item +Its call pattern is \tcode{d2(c2(arg))}, +where \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} +are all well-formed. + +\pnum +An object \tcode{t} of type \tcode{T} is +a pipeable sender adaptor closure object +if \tcode{T} models \tcode{\libconcept{derived_from}>}, +\tcode{T} has no other base classes +of type \tcode{sender_adaptor_closure} for any other type \tcode{U}, and +\tcode{T} does not satisfy \libconcept{sender}. + +\pnum +The template parameter \tcode{D} for \tcode{sender_adaptor_closure} can be +an incomplete type. +Before any expression of type \cv{} \tcode{D} appears as +an operand to the \tcode{|} operator, +\tcode{D} shall be complete and +model \tcode{\libconcept{derived_from}>}. +The behavior of an expression involving an object of type \cv{} \tcode{D} +as an operand to the \tcode{|} operator is undefined +if overload resolution selects a program-defined \tcode{operator|} function. + +\pnum +A \defnadj{pipeable}{sender adaptor object} is a customization point object +that accepts a \libconcept{sender} as its first argument and +returns a \libconcept{sender}. +If a pipeable sender adaptor object accepts only one argument, +then it is a pipeable sender adaptor closure object. + +\pnum +If a pipeable sender adaptor object adaptor accepts more than one argument, +then let \tcode{sndr} be an expression +such that \tcode{decltype((sndr))} models \libconcept{sender}, +let \tcode{args...} be arguments +such that \tcode{adaptor(sndr, args...)} is a well-formed expression +as specified below, and +let \tcode{BoundArgs} be a pack that denotes \tcode{decltype(auto(args))...}. +The expression \tcode{adaptor(args...)} produces +a pipeable sender adaptor closure object \tcode{f} +that is a perfect forwarding call wrapper with the following properties: +\begin{itemize} +\item +Its target object is a copy of adaptor. +\item +Its bound argument entities \tcode{bound_args} consist of +objects of types \tcode{BoundArgs...} direct-non-list-initialized with +\tcode{std::forward(args)...}, respectively. +\item +Its call pattern is \tcode{adaptor(rcvr, bound_args...)}, +where \tcode{rcvr} is +the argument used in a function call expression of \tcode{f}. +\end{itemize} +The expression \tcode{adaptor(args...)} is well-formed if and only if +the initializations of the bound argument entities of the result, +as specified above, are all well-formed. + +\rSec3[exec.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 +\tcode{starts_on} adapts an input sender into a sender +that will start on an execution agent belonging to +a particular scheduler's associated execution resource. + +\pnum +The name \tcode{starts_on} denotes a customization point object. +For subexpressions \tcode{sch} and \tcode{sndr}, +if \tcode{decltype((\newline sch))} does not satisfy \libconcept{scheduler}, or +\tcode{decltype((sndr))} does not satisfy \libconcept{sender}, +\tcode{starts_on(sch, sndr)} is ill-formed. + +\pnum +Otherwise, +the expression \tcode{starts_on(sch, sndr)} is expression-equivalent to: +\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 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( + continues_on(just(), sch), + [sndr = std::forward_like(sndr)]() mutable + noexcept(is_nothrow_move_constructible_v>) { + return std::move(sndr); + }); +\end{codeblock} + +\pnum +Let \tcode{out_sndr} be a subexpression denoting +a sender returned from \tcode{starts_on(sch, sndr)} or one equal to such, and +let \tcode{OutSndr} be the type \tcode{decltype((out_sndr))}. +Let \tcode{out_rcvr} be a subexpression denoting a receiver +that has an environment of type \tcode{Env} +such that \tcode{\libconcept{sender_in}} is \tcode{true}. +Let \tcode{op} be an lvalue referring to the operation state +that results from connecting \tcode{out_sndr} with \tcode{out_rcvr}. +Calling \tcode{start(op)} shall start \tcode{sndr} +on an execution agent of the associated execution resource of \tcode{sch}. +If scheduling onto \tcode{sch} fails, +an error completion on \tcode{out_rcvr} shall be executed +on an unspecified execution agent. + +\rSec3[exec.continues.on]{\tcode{execution::continues_on}} + +\pnum +\tcode{continues_on} schedules work dependent on the completion of a sender +onto a scheduler's associated execution resource. + +\pnum +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{continues_on(sndr, sch)} is ill-formed. + +\pnum +Otherwise, +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.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-state}@ = @\seebelow@; + static constexpr auto @\exposid{complete}@ = @\seebelow@; + + template + static consteval void @\exposid{check-types}@(); + }; +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{get-state}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](Sndr&& sndr, Rcvr& rcvr) noexcept(@\seebelow@) + requires @\libconcept{sender_in}@<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(env_of_t)> { + auto& [_, sch, child] = sndr; + + using sched_t = decltype(auto(sch)); + using variant_t = @\seebelow@; + using receiver_t = @\seebelow@; + using operation_t = connect_result_t, receiver_t>; + constexpr bool nothrow = noexcept(connect(schedule(sch), receiver_t{nullptr})); + + struct @\exposid{state-type}@ { + Rcvr& @\exposid{rcvr}@; // \expos + variant_t @\exposid{async-result}@; // \expos + operation_t @\exposid{op-state}@; // \expos + + explicit @\exposid{state-type}@(sched_t sch, Rcvr& rcvr) noexcept(nothrow) + : @\exposid{rcvr}@(rcvr), @\exposid{op-state}@(connect(schedule(sch), receiver_t{this})) {} + }; + + return @\exposid{state-type}@{sch, rcvr}; +} +\end{codeblock} + +\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. + +\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}, \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..., \exposid{error-completion}...>}, +except with duplicate types removed. + +\pnum +\tcode{receiver_t} is an alias for the following exposition-only class: +\begin{codeblock} +namespace std::execution { + struct @\exposid{receiver-type}@ { + using receiver_concept = receiver_tag; + @\exposid{state-type}@* @\exposid{state}@; // \expos + + void set_value() && noexcept { + visit( + [this](Tuple& result) noexcept -> void { + if constexpr (!@\libconcept{same_as}@) { + auto& [tag, ...args] = result; + tag(std::move(@\exposid{state}@->@\exposid{rcvr}@), std::move(args)...); + } + }, + @\exposid{state}@->@\exposid{async-result}@); + } + + template + void set_error(Error&& err) && noexcept { + execution::set_error(std::move(@\exposid{state}@->@\exposid{rcvr}@), std::forward(err)); + } + + void set_stopped() && noexcept { + execution::set_stopped(std::move(@\exposid{state}@->@\exposid{rcvr}@)); + } + + decltype(auto) get_env() const noexcept { + return @\exposid{FWD-ENV}@(execution::get_env(@\exposid{state}@->@\exposid{rcvr}@)); + } + }; +} +\end{codeblock} + +\pnum +The expression in the \tcode{noexcept} clause of the lambda is \tcode{true} +if the construction of the returned \exposid{state-type} object +is not potentially throwing; +otherwise, \tcode{false}. + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{complete}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](auto, auto& state, auto& rcvr, Tag, Args&&... args) noexcept + -> void { + using result_t = @\exposid{decayed-tuple}@; + constexpr bool nothrow = (is_nothrow_constructible_v, Args> && ...); + + try { + state.@\exposid{async-result}@.template emplace(Tag(), std::forward(args)...); + } catch (...) { + if constexpr (!nothrow) + state.@\exposid{async-result}@.template emplace>(set_error, current_exception()); + } + start(state.@\exposid{op-state}@); +}; +\end{codeblock} + +\pnum +Let \tcode{out_sndr} be a subexpression denoting +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} +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 +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 +The \tcode{on} sender adaptor has two forms: +\begin{itemize} +\item +\tcode{on(sch, sndr)}, +which starts a sender \tcode{sndr} on an execution agent +belonging to a scheduler \tcode{sch}'s associated execution resource and +that, upon \tcode{sndr}'s completion, +transfers execution back to the execution resource +on which the \tcode{on} sender was started. +\item +\tcode{on(sndr, sch, closure)}, +which upon completion of a sender \tcode{sndr}, +transfers execution to an execution agent +belonging to a scheduler \tcode{sch}'s associated execution resource, +then executes a sender adaptor closure \tcode{closure} +with the async results of the sender, and +that then transfers execution back to the execution resource +on which \tcode{sndr} completed. +\end{itemize} + +\pnum +The name \tcode{on} denotes a pipeable sender adaptor object. +For subexpressions \tcode{sch} and \tcode{sndr}, +\tcode{on(sch, sndr)} is ill-formed if any of the following is \tcode{true}: +\begin{itemize} +\item +\tcode{decltype((sch))} does not satisfy \libconcept{scheduler}, or +\item +\tcode{decltype((sndr))} does not satisfy \libconcept{sender} and +\tcode{sndr} is not +a pipeable sender adaptor closure object\iref{exec.adapt.obj}, or +\item +\tcode{decltype((sndr))} satisfies \libconcept{sender} and +\tcode{sndr }is also a pipeable sender adaptor closure object. +\end{itemize} + +\pnum +Otherwise, if \tcode{decltype((sndr))} satisfies \libconcept{sender}, +the expression \tcode{on(sch, sndr)} is expression-equivalent to +\tcode{\exposid{make-sender}(on, sch, sndr)}. + +\pnum +For subexpressions \tcode{sndr}, \tcode{sch}, and \tcode{closure}, if +\begin{itemize} +\item +\tcode{decltype((sch))} does not satisfy \libconcept{scheduler}, or +\item +\tcode{decltype((sndr))} does not satisfy \libconcept{sender}, or +\item +\tcode{closure} is not a pipeable sender adaptor closure object\iref{exec.adapt.obj}, +\end{itemize} +the expression \tcode{on(sndr, sch, closure)} is ill-formed; +otherwise, it is expression-equivalent to +\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 expression \tcode{on.transform_sender(set_value, out_sndr, env)} is ill-formed. + +\pnum +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{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{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 +Let \tcode{out_sndr} be a subexpression denoting +a sender returned from \tcode{on(sch, sndr)} or one equal to such, and +let \tcode{OutSndr} be the type \tcode{decltype((out_sndr))}. +Let \tcode{out_rcvr} be a subexpression denoting a receiver +that has an environment of type \tcode{Env} +such that \tcode{\libconcept{sender_in}} is \tcode{true}. +Let \tcode{op} be an lvalue referring to the operation state +that results from connecting \tcode{out_sndr} with \tcode{out_rcvr}. +Calling \tcode{start(op)} shall +\begin{itemize} +\item +remember the current scheduler, +which is obtained by \tcode{get_start_scheduler(get_env(rcvr))}; +\item +start \tcode{sndr} on an execution agent belonging to +\tcode{sch}'s associated execution resource; +\item +upon \tcode{sndr}'s completion, +transfer execution back to the execution resource +associated with the scheduler remembered in step 1; and +\item +forward \tcode{sndr}'s async result to \tcode{out_rcvr}. +\end{itemize} +If any scheduling operation fails, +an error completion on \tcode{out_rcvr} shall be executed +on an unspecified execution agent. + +\pnum +Let \tcode{out_sndr} be a subexpression denoting +a sender returned from \tcode{on(sndr, sch, closure)} or one equal to such, and +let \tcode{OutSndr} be the type \tcode{decltype((out_sndr))}. +Let \tcode{out_rcvr} be a subexpression denoting a receiver +that has an environment of type \tcode{Env} +such that \tcode{\libconcept{sender_in}} is \tcode{true}. +Let \tcode{op} be an lvalue referring to the operation state +that results from connecting \tcode{out_sndr} with \tcode{out_rcvr}. +Calling \tcode{start(op)} shall +\begin{itemize} +\item +remember the current scheduler, +which is +\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 \tcode{sch}'s associated execution resource; +\item +forward \tcode{sndr}'s async result as if by +connecting and starting a sender \tcode{closure(S)}, +where \tcode{S} is a sender +that completes synchronously with \tcode{sndr}'s async result; and +\item +upon completion of the operation started in the previous step, +transfer execution back to the execution resource +associated with the scheduler remembered in step 1 and +forward the operation's async result to \tcode{out_rcvr}. +\end{itemize} +If any scheduling operation fails, +an error completion on \tcode{out_rcvr} shall be executed on +an unspecified execution agent. + +\rSec3[exec.then]{\tcode{execution::then}, \tcode{execution::upon_error}, \tcode{execution::upon_stopped}} + +\pnum +\tcode{then} attaches an invocable as a continuation +for an input sender's value completion operation. +\tcode{upon_error} and \tcode{upon_stopped} do the same +for the error and stopped completion operations, respectively, +sending the result of the invocable as a value completion. + +\pnum +The names \tcode{then}, \tcode{upon_error}, and \tcode{upon_stopped} +denote pipeable sender adaptor objects. +Let the expression \exposid{then-cpo} be one of +\tcode{then}, \tcode{upon_error}, or \tcode{upon_stopped}. +For subexpressions \tcode{sndr} and \tcode{f}, +if \tcode{decltype((sndr))} does not satisfy \libconcept{sender}, or +\tcode{decltype((f))} does not satisfy \exposconcept{movable-value}, +\tcode{\exposid{then-cpo}(\linebreak sndr, f) }is ill-formed. + +\pnum +Otherwise, +the expression \tcode{\exposid{then-cpo}(sndr, f)} is expression-equivalent to +\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.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<> + struct @\exposid{impls-for}@<@\exposid{decayed-typeof}@<@\exposid{then-cpo}@>> : @\exposid{default-impls}@ { + static constexpr auto @\exposid{complete}@ = + [] + (auto, auto& fn, auto& rcvr, Tag, Args&&... args) noexcept -> void { + if constexpr (@\libconcept{same_as}@>) { + @\exposid{TRY-SET-VALUE}@(rcvr, + invoke(std::move(fn), std::forward(args)...)); + } else { + Tag()(std::move(rcvr), std::forward(args)...); + } + }; + + 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 +\begin{itemize} +\item +invokes \tcode{f} or a copy of such +with the value, error, or stopped result datums of \tcode{sndr} +for \tcode{then}, \tcode{upon_error}, and \tcode{upon_stopped}, respectively, +using the result value of \tcode{f} as \tcode{out_sndr}'s value completion, and +\item +forwards all other completion operations unchanged. +\end{itemize} + +\rSec3[exec.let]{\tcode{execution::let_value}, \tcode{execution::let_error}, \tcode{execution::let_stopped}} + +\pnum +\tcode{let_value}, \tcode{let_error}, and \tcode{let_stopped} transform +a sender's value, error, and stopped completions, respectively, +into a new child asynchronous operation +by passing the sender's result datums to a user-specified callable, +which returns a new sender that is connected and started. + +\pnum +For \tcode{let_value}, \tcode{let_error}, and \tcode{let_stopped}, +let \exposid{set-cpo} be +\tcode{set_value}, \tcode{set_error}, and \tcode{set_stopped}, respectively. +Let the expression \exposid{let-cpo} be one of +\tcode{let_value}, \tcode{let_error}, or \tcode{let_stopped}. +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{\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_completion_domain<\exposid{decayed-typeof}<\exposid{set-cpo}>>(get_env(sndr),\newline \exposid{FWD-ENV}(env)))} +\item +\tcode{(void(sndr), env<>\{\})} +\end{itemize} + +\pnum +The names \tcode{let_value}, \tcode{let_error}, and \tcode{let_stopped} denote +pipeable sender adaptor objects. +For subexpressions \tcode{sndr} and \tcode{f}, +let \tcode{F} be the decayed type of \tcode{f}. +If \tcode{decltype((sndr))} does not satisfy \libconcept{sender} or +if \tcode{decltype((f))} does not satisfy \exposconcept{movable-value}, +the expression \tcode{\exposid{let-cpo}(sndr, f)} is ill-formed. +If \tcode{F} does not satisfy \libconcept{invocable}, +the expression \tcode{let_stopped(sndr, f)} is ill-formed. + +\pnum +Otherwise, +the expression \tcode{\exposid{let-cpo}(sndr, f)} is expression-equivalent to +\tcode{\exposid{make-sender}(\exposid{let-cpo}, f, sndr)}. + +\pnum +Let \exposid{let-data} denote the following exposition-only class template: +\begin{codeblock} +template +struct @\exposid{let-data}@ { + Sndr @\exposid{sndr}@; // \expos + Fn @\exposid{fn}@; // \expos +}; +\end{codeblock} + +\pnum +Then let the expression \tcode{\exposid{let-cpo}.transform_sender(s, es...)} +be expression-equivalent to: +\begin{codeblock} +@\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{let-tag}@> : @\exposid{default-impls}@ { + static constexpr auto @\exposid{get-state}@ = @\seebelow@; + static constexpr auto @\exposid{start}@ = @\seebelow@; + + template + static consteval void @\exposid{check-types}@(); + }; +} +\end{codeblock} + +\pnum +Let \exposid{receiver2} denote the following exposition-only class template: +\begin{codeblock} +namespace std::execution { + template + struct @\exposid{receiver2}@ { + using receiver_concept = receiver_tag; + + template + void set_value(Args&&... args) && noexcept { + execution::set_value(std::move(@\exposid{rcvr}@), std::forward(args)...); + } + + template + void set_error(Error&& err) && noexcept { + execution::set_error(std::move(@\exposid{rcvr}@), std::forward(err)); + } + + void set_stopped() && noexcept { + execution::set_stopped(std::move(@\exposid{rcvr}@)); + } + + decltype(auto) get_env() const noexcept { + return @\seebelow@; + } + + Rcvr& @\exposid{rcvr}@; // \expos + Env @\exposid{env}@; // \expos + }; +} +\end{codeblock} +Invocation of the function \tcode{\exposid{receiver2}::get_env} +returns an object \tcode{e} such that +\begin{itemize} +\item +\tcode{decltype(e)} models \exposconcept{queryable} and +\item +given a query object \tcode{q} 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 +\effects +Equivalent to: +\begin{codeblock} +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}, \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}} denotes +the type \tcode{\exposid{decayed-tuple}}. +Then \tcode{args_variant_t} denotes +the type \tcode{variant...>} +except with duplicate types removed. + +\pnum +Given a type \tcode{Tag} and a pack \tcode{Args}, +let \exposid{as-sndr2} be an alias template +such that \tcode{\exposid{as-sndr2}} denotes +the type \tcode{\exposid{call-result-t}\&...>}. +Then \tcode{ops_variant_t} denotes +the type +\begin{codeblock} +variant, + connect_result_t<@\exposid{as-sndr2}@, @\exposid{receiver2}@>...> +\end{codeblock} +except with duplicate types removed. + +\pnum +The \grammarterm{requires-clause} constraining the above lambda is satisfied +if and only if +the types \tcode{args_variant_t} and \tcode{ops2_variant_t} are well-formed. + +\pnum +\tcode{\exposid{impls-for}<\exposid{let-tag}>::\exposid{start}} +is initialized with a callable object equivalent to the following: +\begin{codeblock} +[](State& state, Rcvr&) noexcept { + start(get(state.@\exposid{ops}@)); +} +\end{codeblock} + +\pnum +Let the subexpression \tcode{out_sndr} denote +the result of the invocation \tcode{\exposid{let-cpo}(sndr, f)} or +an object equal to such, and +let the subexpression \tcode{rcvr} denote a receiver +such that the expression \tcode{connect(out_sndr, rcvr)} is well-formed. +The expression \tcode{connect(out_sndr, rcvr)} has undefined behavior +unless it creates an asynchronous operation\iref{exec.async.ops} that, +when started: +\begin{itemize} +\item +invokes \tcode{f} when \exposid{set-cpo} is called +with \tcode{sndr}'s result datums, +\item +makes its completion dependent on +the completion of a sender returned by \tcode{f}, and +\item +propagates the other completion operations sent by \tcode{sndr}. +\end{itemize} + +\rSec3[exec.bulk]{\tcode{execution::bulk}, \tcode{execution::bulk_chunked}, and \tcode{execution::bulk_unchunked}} + +\pnum +\tcode{bulk}, \tcode{bulk_chunked}, and \tcode{bulk_unchunked} +run a task repeatedly for every index in an index space. + +\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{Func} does not model \libconcept{copy_constructible}, +\end{itemize} +\tcode{\placeholder{bulk-algo}(sndr, policy, shape, f)} is ill-formed. + +\pnum +Otherwise, +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} +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} +\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.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}@ { + 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 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@ { + if constexpr (@\libconcept{same_as}@) { + 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) { + f(auto(i), 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), 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{\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: + +\begin{itemize} +\item +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 +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} + +\pnum +\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} + +\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 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 +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 { + 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@; + + template + static consteval void @\exposid{check-types}@(); + }; +} +\end{codeblock} + +\pnum +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} +template + constexpr auto @\exposid{make-when-all-env}@(inplace_stop_source& stop_src, // \expos + Env&& env) noexcept; +\end{codeblock} + +\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} + +\pnum +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} +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} +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 +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 @\exposid{make-when-all-env}@(state.@\exposid{stop-src}@, get_env(rcvr)); +} +\end{codeblock} + +\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(noexcept(@$e$@)) -> decltype(@$e$@) { + return @$e$@; +} +\end{codeblock} +where $e$ is the expression +\begin{codeblock} +std::forward(sndr).@\exposid{apply}@(@\exposid{make-state}@()) +\end{codeblock} +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 + +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 + if (0 == --count) { + @\exposid{complete}@(rcvr); + } + } + + void @\exposid{complete}@(Rcvr& rcvr) noexcept; // \expos + + atomic @\exposid{count}@{sizeof...(sndrs)}; // \expos + inplace_stop_source @\exposid{stop_src}@{}; // \expos + atomic<@\exposid{disposition}@> disp{@\exposidnc{disposition}@::@\exposidnc{started}@}; // \expos + errors_variant @\exposid{errors}@{}; // \expos + values_tuple @\exposid{values}@{}; // \expos + optional @\exposid{on_stop}@{nullopt}; // \expos + }; + + return @\exposid{state-type}@{}; + } +}; +\end{codeblock} + +\pnum +Let \exposid{copy-fail} be \tcode{exception_ptr} +if decay-copying any of the child senders' result datums can potentially throw; +otherwise, \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>...> +\end{codeblock} +if that type is well-formed; otherwise, \tcode{tuple<>}. + +\pnum +The alias \tcode{errors_variant} denotes +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. + +\pnum +The member +\tcode{void \exposid{state-type}::\exposid{complete}(Rcvr\& rcvr) noexcept} +behaves as follows: +\begin{itemize} +\item +If \tcode{disp} is equal to \tcode{\exposid{disposition}::\exposid{started}}, +evaluates: +\begin{codeblock} +auto tie = [](tuple& t) noexcept { return tuple(t); }; +auto set = [&](auto&... t) noexcept { set_value(std::move(rcvr), std::move(t)...); }; + +@\exposid{on_stop}@.reset(); +apply( + [&](auto&... opts) noexcept { + apply(set, tuple_cat(tie(*opts)...)); + }, + values); +\end{codeblock} +\item +Otherwise, +if \tcode{disp} is equal to \tcode{\exposid{disposition}::\exposid{error}}, +evaluates: +\begin{codeblock} +@\exposid{on_stop}@.reset(); +visit( + [&](Error& error) noexcept { + if constexpr (!@\libconcept{same_as}@) { + set_error(std::move(rcvr), std::move(error)); + } + }, + errors); +\end{codeblock} +\item +Otherwise, evaluates: +\begin{codeblock} +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 +The member \tcode{\exposid{impls-for}::\exposid{start}} +is initialized with a callable object +equivalent to the following lambda expression: +\begin{codeblock} +[]( + State& state, Rcvr& rcvr, Ops&... ops) noexcept -> void { + state.@\exposid{on_stop}@.emplace( + get_stop_token(get_env(rcvr)), + @\exposid{on-stop-request}@{state.@\exposid{stop_src}@}); + (start(ops), ...); +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{complete}} +is initialized with a callable object +equivalent to the following lambda expression: +\begin{codeblock} +[]( + this auto& complete, Index, State& state, Rcvr& rcvr, Set, Args&&... args) noexcept -> void { + if constexpr (@\libconcept{same_as}@) { + if (@\exposid{disposition}@::@\exposid{error}@ != state.disp.exchange(@\exposid{disposition}@::@\exposid{error}@)) { + state.@\exposid{stop_src}@.request_stop(); + @\exposid{TRY-EMPLACE-ERROR}@(state.errors, std::forward(args)...); + } + } else if constexpr (@\libconcept{same_as}@) { + auto expected = @\exposid{disposition}@::@\exposid{started}@; + if (state.disp.compare_exchange_strong(expected, @\exposid{disposition}@::@\exposid{stopped}@)) { + state.@\exposid{stop_src}@.request_stop(); + } + } else if constexpr (!@\libconcept{same_as}@>) { + if (state.disp == @\exposid{disposition}@::@\exposid{started}@) { + auto& opt = get(state.values); + @\exposid{TRY-EMPLACE-VALUE}@(complete, opt, std::forward(args)...); + } + } + state.@\exposid{arrive}@(rcvr); +} +\end{codeblock} +where \tcode{\exposid{TRY-EMPLACE-ERROR}(v, e)}, +for subexpressions \tcode{v} and \tcode{e}, is equivalent to: +\begin{codeblock} +try { + v.template emplace(e); +} catch (...) { + v.template emplace(current_exception()); +} +\end{codeblock} +if the expression \tcode{decltype(auto(e))(e)} is potentially throwing; +otherwise, \tcode{v.template emplace(e)}; +and where \tcode{\exposid{TRY-EMPLACE-VALUE}(c, o, as...)}, +for subexpressions \tcode{c}, \tcode{o}, and pack of subexpressions \tcode{as}, +is equivalent to: +\begin{codeblock} +try { + o.emplace(as...); +} catch (...) { + c(Index(), state, rcvr, set_error, current_exception()); + return; +} +\end{codeblock} +if the expression \tcode{\exposid{decayed-tuple}\{as...\}} +is potentially throwing; +otherwise, \tcode{o.emplace(\linebreak as...)}. + +\pnum +The expression \tcode{when_all_with_variant(sndrs...)} +is expression-equivalent to +\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(set_value, sndr, env)} +is ill-formed; +otherwise, it is equivalent to: +\begin{codeblock} +auto&& [_, _, ...child] = sndr; +return when_all(into_variant(std::forward_like(child))...); +\end{codeblock} +\begin{note} +This causes the \tcode{when_all_with_variant(sndrs...)} sender +to become \tcode{when_all(into_variant(sndrs)...)} +when it is connected with a receiver +whose execution domain does not customize \tcode{when_all_with_variant}. +\end{note} + +\rSec3[exec.into.variant]{\tcode{execution::into_variant}} + +\pnum +\tcode{into_variant} adapts a sender with multiple value completion signatures +into a sender with just one value completion signature +consisting of a \tcode{variant} of \tcode{tuple}s. + +\pnum +The name \tcode{into_variant} denotes a pipeable sender adaptor object. +For a subexpression \tcode{sndr}, let \tcode{Sndr} be \tcode{decltype((sndr))}. +If \tcode{Sndr} does not satisfy \libconcept{sender}, +\tcode{into_variant(sndr)} is ill-formed. + +\pnum +Otherwise, the expression \tcode{into_variant(sndr)} +is expression-equivalent to +\tcode{\exposid{make-sender}(into_variant, \{\}, sndr)}. + +\pnum +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} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{get-state}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](Sndr&& sndr, Rcvr& rcvr) noexcept + -> type_identity, @\exposid{FWD-ENV-T}@(env_of_t)>> { + return {}; +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{complete}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[]( + auto, State, Rcvr& rcvr, Tag, Args&&... args) noexcept -> void { + if constexpr (@\libconcept{same_as}@) { + using variant_type = State::type; + @\exposid{TRY-SET-VALUE}@(rcvr, variant_type(@\exposid{decayed-tuple}@{std::forward(args)...})); + } else { + Tag()(std::move(rcvr), std::forward(args)...); + } +} +\end{codeblock} + +\rSec3[exec.stopped.opt]{\tcode{execution::stopped_as_optional}} + +\pnum +\tcode{stopped_as_optional} maps a sender's stopped completion operation +into a value completion operation as a disengaged \tcode{optional}. +The sender's value completion operation +is also converted into an \tcode{optional}. +The result is a sender that never completes with stopped, +reporting cancellation by completing with a disengaged \tcode{optional}. + +\pnum +The name \tcode{stopped_as_optional} denotes a pipeable sender adaptor object. +For a subexpression \tcode{sndr}, let \tcode{Sndr} be \tcode{decltype((sndr))}. +The expression \tcode{stopped_as_optional(sndr)} is expression-equivalent to +\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} +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} + +\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_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(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}@<@\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()); }); +\end{codeblock} + +\rSec3[exec.stopped.err]{\tcode{execution::stopped_as_error}} + +\pnum +\tcode{stopped_as_error} maps an input sender's stopped completion operation +into an error completion operation as a custom error type. +The result is a sender that never completes with stopped, +reporting cancellation by completing with an error. + +\pnum +The name \tcode{stopped_as_error} denotes a pipeable sender adaptor object. +For some subexpressions \tcode{sndr} and \tcode{err}, +let \tcode{Sndr} be \tcode{decltype((sndr))} and +let \tcode{Err} be \tcode{decltype((err))}. +If the type \tcode{Sndr} does not satisfy \libconcept{sender} or +if the type \tcode{Err} does not satisfy \exposconcept{movable-value}, +\tcode{stopped_as_error(sndr, err)} is ill-formed. +Otherwise, the expression \tcode{stopped_as_error(sndr, err)} +is expression-equivalent to +\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(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)); + }); +\end{codeblock} + +\rSec3[exec.associate]{\tcode{execution::associate}} + +\pnum +\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{associate-data} be the following exposition-only class template: + +\indexlibraryglobal{execution::\exposid{associate-data}}% +\begin{codeblock} +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; + }()) {} + + @\exposid{associate-data}@(const @\exposid{associate-data}@& other) + noexcept(is_nothrow_copy_constructible_v<@\exposid{wrap-sender}@> && + noexcept(other.@\exposid{assoc}@.try_associate())); + + @\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 +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}. + +\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 +\constraints +\exposid{wrap-sender} models \libconcept{copy_constructible}. + +\pnum +\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} +@\exposid{associate-data}@(pair<@\exposid{assoc-t}@, @\exposid{sender-ref}@> parts); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +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} +~@\exposid{associate-data}@(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{bool(\exposid{assoc})} is \tcode{true}, destroys \exposid{sndr}. +\end{itemdescr} + +\indexlibrarymember{release}{execution::\exposid{associate-data}}% +\begin{itemdecl} +pair<@\exposid{assoc-t}@, @\exposid{sender-ref}@> release() && noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +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 +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} + +\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(); + } + }; +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{get-state}} +is initialized with a callable object equivalent to the following lambda: + +\begin{codeblock} +[](Sndr&& sndr, Rcvr& rcvr) noexcept(@\seebelow@) { + 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 expression in the \tcode{noexcept} clause of +\tcode{\exposid{impls-for}::\exposid{get-state}} is +\begin{codeblock} +(is_same_v> || + is_nothrow_constructible_v, Sndr>) && +@\exposconcept{nothrow-callable}@ +\end{codeblock} +where \exposid{wrap-sender} is the type +\tcode{remove_cvref_t<\exposid{data-type}>::\exposid{wrap-sender}}. + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{start}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](auto& state, auto&) noexcept -> void { + state.@\exposid{run}@(); +} +\end{codeblock} + +\pnum +%%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 +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 +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 +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 +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 +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} + +\rSec3[exec.spawn.future]{\tcode{execution::spawn_future}} + +\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 +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 +Let \exposid{try-cancelable} be the exposition-only class: + +\indexlibraryglobal{execution::\exposid{try-cancelable}}% +\begin{codeblock} +namespace std::execution { + struct @\exposid{try-cancelable}@ { // \expos + virtual void @\exposid{try-cancel}@() noexcept = 0; // \expos + }; +} +\end{codeblock} + +\pnum +Let \exposid{spawn-future-state-base} be the exposition-only class template: + +\indexlibraryglobal{execution::\exposid{spawn-future-state-base}}% +\begin{codeblock} +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 +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 +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 +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} +namespace std::execution { + template + struct @\exposid{spawn-future-receiver}@ { // \expos + using receiver_concept = receiver_tag; + + @\exposid{spawn-future-state-base}@* @\exposid{state}@; // \expos + + template + void set_value(T&&... t) && noexcept { + @\exposid{set-complete}@(std::forward(t)...); + } + + 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} + +\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} +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 +Let \exposid{spawn-future-state} be the exposition-only class template: + +\indexlibraryglobal{execution::\exposid{spawn-future-state}}% +\begin{codeblock} +namespace std::execution { + template + struct @\exposidnc{spawn-future-state}@ // \expos + : @\exposid{spawn-future-state-base}@>> { + using @\exposidnc{sigs-t}@ = // \expos + completion_signatures_of_t<@\exposid{future-spawned-sender}@>; + 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)); + } + + 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 + + private: + using @\exposidnc{assoc-t}@ = // \expos + remove_cvref_t().try_associate())>; + + 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} + +\pnum +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. + +\indexlibrarymember{\exposid{complete}}{execution::\exposid{spawn-future-state}}% +\begin{itemdecl} +void @\exposid{complete}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\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} + +\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} +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} + +\indexlibrarymember{\exposid{try-set-stopped}}{execution::\exposid{spawn-future-state}}% +\begin{itemdecl} +void @\exposid{try-set-stopped}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\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}()}; + +\item +otherwise, no effects. +\end{itemize} +\end{itemdescr} + +\indexlibrarymember{\exposid{abandon}}{execution::\exposid{spawn-future-state}}% +\begin{itemdecl} +void @\exposid{abandon}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\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} +@\exposid{ssource}@.request_stop(); +\end{codeblock} +\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} +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} +\end{itemdescr} + +\pnum +Let \exposid{future-operation} be the exposition-only class template: + +\begin{codeblock} +namespace std::execution { + template + struct @\exposid{future-operation}@ { // \expos + struct @\exposid{callback}@ { // \expos + @\exposid{try-cancelable}@* @\exposid{state}@; // \expos + + 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 + void @\exposid{set-complete}@(T&&... ts) noexcept { // \expos + @\exposid{stopCallback}@.reset(); + CPO{}(std::move(@\exposid{rcvr}@), std::forward(ts)...); + } + }; +} +\end{codeblock} + +\pnum +The exposition-only class template \exposid{impls-for}\iref{exec.snd.expos} +is specialized for \tcode{spawn_future_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{start}@ = @\seebelow@; // \expos + static constexpr auto @\exposid{get-state}@ = @\seebelow@; // \expos + }; +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{start}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](auto& state, auto&) noexcept -> void { + state.@\exposid{run}@(); +} +\end{codeblock} + +\pnum +The member \tcode{\exposid{impls-for}::\exposid{get-state}} +is initialized with a callable object equivalent to the following lambda: +\begin{codeblock} +[](Sndr sndr, Rcvr& rcvr) noexcept { + auto& [_, data] = sndr; + using state_ptr = remove_cvref_t; + return @\exposid{future-operation}@(std::move(data), std::move(rcvr)); +} +\end{codeblock} + +\pnum +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 +The expression \tcode{spawn_future(sndr, token, env)} +has the following effects: + +\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 +The expression \tcode{spawn_future(sndr, token)} is expression-equivalent to +\tcode{spawn_future(sndr, token, ex\-ecution::env<>())}. + +\rSec2[exec.consumers]{Sender consumers} + +\rSec3[exec.sync.wait]{\tcode{this_thread::sync_wait}} + +\pnum +\tcode{this_thread::sync_wait} and \tcode{this_thread::sync_wait_with_variant} +are used +to block the current thread of execution +until the specified sender completes and +to return its async result. +\tcode{sync_wait} mandates +that the input sender has exactly one value completion signature. + +\pnum +Let \exposid{sync-wait-env} be the following exposition-only class type: +\begin{codeblock} +namespace std::this_thread { + struct @\exposid{sync-wait-env}@ { + execution::run_loop* @\exposid{loop}@; // \expos + + auto query(execution::get_scheduler_t) const noexcept { + return @\exposid{loop}@->get_scheduler(); + } + + auto query(execution::get_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, 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}))} +is potentially-throwing if and only if \exposid{sndr} is potentially-throwing, +has type \exposid{run-loop-scheduler}, and +compares equal to the \exposid{run-loop-\newline scheduler} instance +from which \exposid{sndr} was obtained. +\end{itemize} + +\begin{itemdecl} +template + struct @\exposid{run-loop-opstate}@; +\end{itemdecl} + +\pnum +\tcode{\exposid{run-loop-opstate}} +inherits privately and unambiguously from \exposid{run-loop-opstate-base}. + +\pnum +Let $o$ be a non-const lvalue of type \tcode{\exposid{run-loop-opstate}}, +and let \tcode{REC($o$)} be a non-const lvalue reference to an instance of type \tcode{Rcvr} +that was initialized with the expression \exposid{rcvr} +passed to the invocation of connect that returned $o$. +Then: +\begin{itemize} +\item +The object to which \tcode{\exposid{REC}($o$)} refers +remains valid for the lifetime of the object to which $o$ refers. +\item +The type \tcode{\exposid{run-loop-opstate}} overrides +\tcode{\exposid{run-loop-opstate-base}::\exposid{execute}()} +such that \tcode{$o$.\exposid{exe\-cute}()} is equivalent to: +\begin{codeblock} +if (get_stop_token(@\exposid{REC}@(@$o$@)).stop_requested()) { + set_stopped(std::move(@\exposid{REC}@(@$o$@))); +} else { + set_value(std::move(@\exposid{REC}@(@$o$@))); +} +\end{codeblock} +\item +The expression \tcode{start($o$)} is equivalent to: +\begin{codeblock} +@$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{p} is an lvalue, +\tcode{Expr} names the type \tcode{decltype((expr))} and +\tcode{Promise} names the type \tcode{decay_t}, +\tcode{as_awaitable(expr, p)} is expression-equivalent to, +except that the evaluations of \tcode{expr} and \tcode{p} +are indeterminately sequenced: +\begin{itemize} +\item +\tcode{expr.as_awaitable(p)} if that expression is well-formed. + +\mandates +\tcode{\exposconcept{is-awaitable}} is \tcode{true}, +where \tcode{A} is the type of the expression above. +\item +Otherwise, +\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 \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 +\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 +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 +\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} + +\indexlibrarymember{return_void}{task::promise_type}% +\begin{itemdecl} +void return_void(); +\end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Does nothing. +\end{itemdescr} + +\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} + +\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 +\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 +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 +\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 +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 { + 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}@)); + } + }; + + 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.simple.counting.token}, token + struct token; + + 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} + +\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} +token get_token() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An object \tcode{t} of type \tcode{simple_counting_scope::token} such that +\tcode{t.\exposid{scope} == this} is \tcode{true}. +\end{itemdescr} + +\indexlibrarymember{close}{execution::simple_counting_scope}% +\begin{itemdecl} +void close() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\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 +\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} +@\libconcept{sender}@ auto join() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{\exposid{make-sender}(\exposid{scope-join-t}(), this)}. +\end{itemdescr} + +\indexlibrarymember{\exposid{try-associate}}{execution::simple_counting_scope}% +\begin{itemdecl} +@\exposid{assoc-t}@ @\exposid{try-associate}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \exposid{count} is equal to \tcode{max_associations}, then no effects. +Otherwise, if \exposid{state} is +\begin{itemize} +\item +\exposid{unused}, +then increments \exposid{count} and changes \exposid{state} to \exposid{open}; +\item +\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} +void @\exposid{disassociate}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\exposid{count} is greater than zero. + +\pnum +\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 +\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 +\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} +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} + +\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} +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} + +\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}. + +\indexlibrarymember{get_token}{execution::counting_scope}% +\begin{itemdecl} +token get_token() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An object \tcode{t} of type \tcode{counting_scope::token} such that +\tcode{t.\exposid{scope} == this} is \tcode{true}. +\end{itemdescr} + +\indexlibrarymember{request_stop}{execution::counting_scope}% +\begin{itemdecl} +void request_stop() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{\exposid{s_source}.request_stop()}. + +\pnum +\remarks +Calls to \tcode{request_stop} do not introduce data races. +\end{itemdescr} + +\indexlibrarymember{\exposid{try-associate}}{execution::counting_scope}% +\begin{itemdecl} +@\exposid{assoc-t}@ @\exposid{try-associate}@() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \exposid{count} is equal to \tcode{max_associations}, +then no effects. +Otherwise, if \exposid{state} is +\begin{itemize} +\item +\exposid{unused}, then increments \exposid{count} and +changes \exposid{state} to \exposid{open}; +\item +\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} +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 +Equivalent to: +\begin{codeblock} +return @\exposid{stop-when}@(std::forward(snd), @\exposid{scope}@->@\exposid{s_source}@.get_token()); +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{wrap}{execution::counting_scope::token}% +\begin{itemdecl} +@\exposid{assoc-t}@ counting_scope::token::try_associate() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return \exposid{scope}->\exposid{try-associate}();} +\end{itemdescr} + +\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} +parallel_scheduler get_parallel_scheduler(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\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 +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} +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 +\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. + +\begin{itemdecl} +template + optional

@\libglobal{try_query}@(Query q) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{P} is a cv-unqualified non-array object type. + +\pnum +\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 +\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} + +\rSec2[exec.parschedrepl.query]{\tcode{query_parallel_scheduler_backend}} + +\indexlibraryglobal{query_parallel_scheduler_backend}% +\begin{itemdecl} +shared_ptr query_parallel_scheduler_backend(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{query_parallel_scheduler_backend()} returns +the implementation object for a parallel scheduler. + +\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 +\remarks +This function is replaceable\iref{term.replaceable.function}. +\end{itemdescr} + +\rSec2[exec.parschedrepl.psb]{Class \tcode{parallel_scheduler_backend}} + +\begin{codeblock} +namespace std::execution::parallel_scheduler_replacement { + struct @\libglobal{parallel_scheduler_backend}@ { + virtual ~parallel_scheduler_backend() = default; + + 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 +\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 +\effects +A derived class shall implement this function such that: +\begin{itemize} +\item +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 +Any call to \tcode{r.set_value()} happens on +an execution agent 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} + +\indexlibrarymember{schedule_bulk_chunked}{parallel_scheduler_backend}% +\begin{itemdecl} +virtual void schedule_bulk_chunked(size_t n, bulk_item_receiver_proxy& r, + span s) noexcept = 0; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\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 +\effects +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} 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} + +\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} + +\indexlibrarymember{schedule_bulk_unchunked}{parallel_scheduler_backend}% +\begin{itemdecl} +virtual void schedule_bulk_unchunked(size_t n, bulk_item_receiver_proxy& r, + span s) noexcept = 0; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\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 +\effects +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 ddaed4c189..eec3be900e 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1,57 +1,60 @@ %!TEX root = std.tex \rSec0[expr]{Expressions} -%gram: \rSec1[gram.expr]{Expressions} -%gram: +\gramSec[gram.expr]{Expressions} \indextext{\idxcode{operator new}|seealso{\tcode{new}}}% \indextext{\idxcode{operator delete}|seealso{\tcode{delete}}}% \indextext{usual arithmetic conversions|see{conversion, usual arithmetic}}% -\indextext{\idxcode{==}|see{equality~operator}}% -\indextext{\idxcode{"!=}|see{inequality~operator}} +\indextext{\idxcode{==}|see{operator, equality}}% +\indextext{\idxcode{"!=}|see{operator, inequality}} \indextext{\idxcode{static_cast}|see{cast, static}}% \indextext{\idxcode{dynamic_cast}|see{cast, dynamic}}% \indextext{\idxcode{const_cast}|see{cast, const}}% \indextext{\idxcode{reinterpret_cast}|see{cast, reinterpret}} +\rSec1[expr.pre]{Preamble} + \pnum \indextext{expression|(}% -\enternote -Clause~\ref{expr} defines the syntax, order of evaluation, and meaning -of expressions.\footnote{The precedence of operators is not directly specified, but it can be -derived from the syntax.} +\begin{note} +\ref{expr} defines the syntax, order of evaluation, and meaning +of expressions. +\begin{footnote} +The precedence of operators is not directly specified, but it can be +derived from the syntax. +\end{footnote} An expression is a sequence of operators and operands that specifies a computation. An expression can result in a value and can cause side effects. -\exitnote +\end{note} \pnum \indextext{operator!overloaded}% -\enternote +\begin{note} Operators can be overloaded, that is, given meaning when applied to -expressions of class type~(Clause \ref{class}) or enumeration -type~(\ref{dcl.enum}). Uses of overloaded operators are transformed into +expressions of class type\iref{class} or enumeration +type\iref{dcl.enum}. Uses of overloaded operators are transformed into function calls as described in~\ref{over.oper}. Overloaded operators -obey the rules for syntax specified in Clause~\ref{expr}, but the -requirements of operand type, value category, and evaluation order are replaced +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 -operators~(\ref{over.oper}), and are not guaranteed for operands of type -\tcode{bool}. -\exitnote +\tcode{++a} meaning \tcode{a += 1}, are not guaranteed for overloaded +operators\iref{over.oper}. +\end{note} \pnum -Clause~\ref{expr} defines the effects of operators when applied to types +Subclause \ref{expr.compound} defines the effects of operators when applied to types for which they have not been overloaded. Operator overloading shall not -modify the rules for the \term{built-in operators}, that -is, for operators applied to types for which they are defined by this +modify the rules for the \defnadj{built-in}{operators}, +that is, for operators applied to types for which they are defined by this Standard. However, these built-in operators participate in overload resolution, and as part of that process user-defined conversions will be considered where necessary to convert the operands to types appropriate for the built-in operator. If a built-in operator is selected, such conversions will be applied to the operands before the operation is -considered further according to the rules in Clause~\ref{expr}; -see~\ref{over.match.oper},~\ref{over.built}. +considered further according to the rules in \ref{expr.compound}; +see~\ref{over.match.oper}, \ref{over.built}. \pnum \indextext{exception!arithmetic}% @@ -62,50 +65,155 @@ 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. -\enternote +\begin{note} \indextext{overflow}% -most existing implementations of \Cpp ignore integer overflows. Treatment of division by zero, forming a remainder using a zero divisor, -and all floating point exceptions vary among machines, and is usually +and all floating-point exceptions varies among machines, and is sometimes adjustable by a library function. -\exitnote +\end{note} + +\pnum +\indextext{operator!precedence of}% +\indextext{expression!order of evaluation of}% +\begin{note} +The implementation can regroup operators according to +the usual mathematical rules only +where the operators really are associative or commutative. +\begin{footnote} +Overloaded +operators are never assumed to be associative or commutative. +\end{footnote} +For example, in the following fragment +\begin{codeblock} +int a, b; +@\commentellip@ +a = a + 32760 + b + 5; +\end{codeblock} +the expression statement behaves exactly the same as +\begin{codeblock} +a = (((a + 32760) + b) + 5); +\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 \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 +expression as +\begin{codeblock} +a = ((a + b) + 32765); +\end{codeblock} +since if the values for \tcode{a} and \tcode{b} were, respectively, +$-32754$ and $-15$, the sum \tcode{a + b} would produce an exception while +the original expression would not; nor can the expression be rewritten +as either +\begin{codeblock} +a = ((a + 32765) + b); +\end{codeblock} +or +\begin{codeblock} +a = (a + (b + 32765)); +\end{codeblock} +since the values for \tcode{a} and \tcode{b} might have been, +respectively, 4 and $-8$ or $-17$ and 12. However on a machine in which +overflows do not produce an exception and in which the results of +overflows are reversible, the above expression statement can be +rewritten by the implementation in any of the above ways because the +same result will occur. +\end{note} + +\pnum +The values of the floating-point operands and +the results of floating-point expressions +may be represented in greater precision and range than that +required by the type; the types are not changed\ +thereby. +\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.assign}. +\end{footnote} -\pnum -\indextext{expression!reference}% -If an expression initially has the type ``reference to -\tcode{T}''~(\ref{dcl.ref},~\ref{dcl.init.ref}), the type is adjusted to -\tcode{T} prior to any further analysis. The expression designates the -object or function denoted by the reference, and the expression -is an lvalue or an xvalue, depending on the expression. +\rSec1[expr.prop]{Properties of expressions} +\rSec2[basic.lval]{Value category} \pnum -If a prvalue initially has the type ``\cv{} \tcode{T},'' where -\tcode{T} is a cv-unqualified non-class, non-array type, the type of -the expression is adjusted to \tcode{T} prior to any further analysis. +Expressions are categorized according to the taxonomy in \fref{basic.lval}. + +\begin{importgraphic} +{Expression category taxonomy} +{basic.lval} +{valuecategories.pdf} +\end{importgraphic} + +\begin{itemize} +\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, +or an expression that has type \cv{}~\keyword{void}. +\item An \defn{xvalue} is a glvalue that denotes an object whose resources can be reused (usually because it is near the end of its lifetime). +\item An \defn{lvalue} is a glvalue that is not an xvalue. +\item An \defn{rvalue} is a prvalue or an xvalue. +\end{itemize} \pnum -\indextext{expression!rvalue~reference}% -\enternote +Every expression belongs to exactly one of the fundamental categories in this +taxonomy: lvalue, xvalue, or prvalue. This property of an expression is called +its \defn{value category}. +\begin{note} +The discussion of each built-in operator in +\ref{expr.compound} indicates the category of the value it yields and the value categories +of the operands it expects. For example, the built-in assignment operators expect that +the left operand is an lvalue and that the right operand is a prvalue and yield an +lvalue as the result. User-defined operators are functions, and the categories of +values they expect and yield are determined by their parameter and return types. +\end{note} + +\pnum +\begin{note} +Historically, lvalues and rvalues were so-called +because they could appear on the left- and right-hand side of an assignment +(although this is no longer generally true); +glvalues are ``generalized'' lvalues, +prvalues are ``pure'' rvalues, +and xvalues are ``eXpiring'' lvalues. +Despite their names, these terms apply to expressions, not values. +\end{note} + +\pnum +\indextext{expression!rvalue reference}% +\begin{note} An expression is an xvalue if it is: \begin{itemize} +\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, +whose return type is an rvalue reference to object type\iref{expr.call}, -\item a cast to an rvalue reference to object type, +\item a cast to an rvalue reference to +object type\iref{expr.type.conv,expr.dynamic.cast,expr.static.cast, +expr.reinterpret.cast,expr.const.cast,expr.cast}, + +\item a subscripting operation with an xvalue array operand\iref{expr.sub}, \item a class member access expression designating a non-static data member of non-reference type -in which the object expression is an xvalue, or +in which the object expression is an xvalue\iref{expr.ref}, or \item a \tcode{.*} pointer-to-member expression in which the first operand is -an xvalue and the second operand is a pointer to data member. +an xvalue and the second operand is a pointer to data member\iref{expr.mptr.oper}. \end{itemize} In general, the effect of this rule is that named rvalue references are treated as lvalues and unnamed rvalue references to objects are treated as xvalues; rvalue references to functions are treated as lvalues whether named or not. -\exitnote +\end{note} -\enterexample +\begin{example} \begin{codeblock} struct A { int m; @@ -117,150 +225,144 @@ A&& ar = static_cast(a); \end{codeblock} -The expressions \tcode{f()}, \tcode{f().m}, \tcode{static_cast(a)}, and \tcode{a + a} +The expressions \tcode{f()}, \tcode{f().m}, \tcode{\keyword{static_cast}(a)}, and \tcode{a + a} are xvalues. The expression \tcode{ar} is an lvalue. -\exitexample - -\pnum -In some contexts, \defnx{unevaluated operands}{unevaluated operand} -appear~(\ref{expr.typeid}, \ref{expr.sizeof}, \ref{expr.unary.noexcept}, \ref{dcl.type.simple}). -An unevaluated operand is not evaluated. An unevaluated operand is -considered a full-expression. -\enternote -In an unevaluated operand, a non-static class member may be -named~(\ref{expr.prim}) and naming of objects or functions does not, by -itself, require that a definition be provided~(\ref{basic.def.odr}). -\exitnote - -\pnum -Whenever a glvalue expression appears as an operand of an operator that -expects a prvalue for that operand, the -lvalue-to-rvalue~(\ref{conv.lval}), array-to-pointer~(\ref{conv.array}), -or function-to-pointer~(\ref{conv.func}) standard conversions are +\end{example} + +\pnum +The \defnx{result}{result!glvalue} of a glvalue is the entity denoted by the expression. +The \defnx{result}{result!prvalue} of a prvalue +is the value that the expression stores into its context; +a prvalue that has type \cv{}~\keyword{void} has no result. +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 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 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} + +\pnum +Whenever a glvalue appears as an operand of an operator that +requires a prvalue for that operand, the +lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, +or function-to-pointer\iref{conv.func} standard conversions are applied to convert the expression to a prvalue. -\enternote -because cv-qualifiers are removed from the type of an expression of +\begin{note} +An attempt to bind an rvalue reference to an lvalue is not such a context; see~\ref{dcl.init.ref}. +\end{note} +\begin{note} +Because cv-qualifiers are removed from the type of an expression of non-class type when the expression is converted to a prvalue, an lvalue -expression of type \tcode{const int} can, for example, be used where -a prvalue expression of type \tcode{int} is required. -\exitnote - -\pnum -\indextext{conversion!usual arithmetic}% -Many binary operators that expect operands of arithmetic or enumeration -type cause conversions and yield result types in a similar way. The -purpose is to yield a common type, which is also the type of the result. -This pattern is called the \term{usual arithmetic conversions}, -which are defined as follows: - -\begin{itemize} -\item If either operand is of scoped enumeration type~(\ref{dcl.enum}), no conversions -are performed; if the other operand does not have the same type, the expression is -ill-formed. - -\item If either operand is of type \tcode{long} \tcode{double}, the -other shall be converted to \tcode{long} \tcode{double}. - -\item Otherwise, if either operand is \tcode{double}, the other shall be -converted to \tcode{double}. - -\item Otherwise, if either operand is \tcode{float}, the other shall be -converted to \tcode{float}. - -\item Otherwise, the integral promotions~(\ref{conv.prom}) shall be -performed on both operands.\footnote{As a consequence, operands of type \tcode{bool}, \tcode{char16_t}, -\tcode{char32_t}, \tcode{wchar_t}, or an enumerated type are converted -to some integral type.} -Then the following rules shall be applied to the promoted operands: - +of type \tcode{\keyword{const} \keyword{int}} can, for example, be used where +a prvalue of type \keyword{int} is required. +\end{note} +\begin{note} +There are no prvalue bit-fields; if a bit-field is converted to a +prvalue\iref{conv.lval}, a prvalue of the type of the bit-field is +created, which might then be promoted\iref{conv.prom}. +\end{note} + +\pnum +Unless otherwise specified\iref{expr.reinterpret.cast, expr.const.cast}, +whenever a prvalue +that is not the result of the lvalue-to-rvalue conversion\iref{conv.lval} +appears as an operand of an operator, +the temporary materialization conversion\iref{conv.rval} is +applied to convert the expression to an xvalue. + +\pnum +\begin{note} +The discussion of reference initialization in~\ref{dcl.init.ref} and of +temporaries in~\ref{class.temporary} indicates the behavior of lvalues +and rvalues in other significant contexts. +\end{note} + +\pnum +Unless otherwise indicated\iref{dcl.type.decltype}, +a prvalue shall always have complete type or the \keyword{void} type; +if it has a class type or (possibly multidimensional) array of class type, +that class shall not be an abstract class\iref{class.abstract}. +A glvalue shall not have type \cv{}~\keyword{void}. +\begin{note} +A glvalue can have complete or incomplete non-\keyword{void} type. +Class and array prvalues can have cv-qualified types; other prvalues +always have cv-unqualified types. See \ref{expr.type}. +\end{note} + +\pnum +An lvalue is \defn{modifiable} unless its type is const-qualified +or is a function type. +\begin{note} +A program that attempts +to modify an object through a nonmodifiable lvalue or through an rvalue +is ill-formed\iref{expr.assign,expr.post.incr,expr.pre.incr}. +\end{note} + +\pnum +An object of dynamic type $\tcode{T}_\text{obj}$ is +\defn{type-accessible} through a glvalue of type $\tcode{T}_\text{ref}$ +if $\tcode{T}_\text{ref}$ is similar\iref{conv.qual} to: \begin{itemize} +\item $\tcode{T}_\text{obj}$, -\item If both operands have the same type, no further conversion is -needed. - -\item Otherwise, if both operands have signed integer types or both have -unsigned integer types, the operand with the type of lesser integer -conversion rank shall be converted to the type of the operand with -greater rank. - -\item Otherwise, if the operand that has unsigned integer type has rank -greater than or equal to the rank of the type of the other operand, the -operand with signed integer type shall be converted to the type of the -operand with unsigned integer type. - -\item Otherwise, if the type of the operand with signed integer type can -represent all of the values of the type of the operand with unsigned -integer type, the operand with unsigned integer type shall be converted -to the type of the operand with signed integer type. - -\item Otherwise, both operands shall be converted to the unsigned -integer type corresponding to the type of the operand with signed -integer type. -\end{itemize} -\end{itemize} - -\pnum -In some contexts, an expression only appears for its side effects. Such an -expression is called a \defn{discarded-value expression}. The expression is -evaluated and its value is discarded. The array-to-pointer~(\ref{conv.array}) -and function-to-pointer~(\ref{conv.func}) standard conversions are not -applied. The lvalue-to-rvalue conversion~(\ref{conv.lval}) is applied -if and only if -the expression is a glvalue of volatile-qualified type and it is one of the -following: +\item a type that is the signed or unsigned type corresponding to $\tcode{T}_\text{obj}$, or -\begin{itemize} -\item \tcode{(} \grammarterm{expression} \tcode{)}, where - \grammarterm{expression} is one of these expressions, -\item \grammarterm{id-expression}~(\ref{expr.prim.general}), -\item subscripting~(\ref{expr.sub}), -\item class member access~(\ref{expr.ref}), -\item indirection~(\ref{expr.unary.op}), -\item pointer-to-member operation~(\ref{expr.mptr.oper}), -\item conditional expression~(\ref{expr.cond}) where both the second and the - third operands are one of these expressions, or -\item comma expression~(\ref{expr.comma}) where the right operand is one of - these expressions. +\item a \keyword{char}, \tcode{\keyword{unsigned} \keyword{char}}, or \tcode{std::byte} type. \end{itemize} +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. +\begin{footnote} +The intent of this list is to specify those circumstances in which an +object can or cannot be aliased. +\end{footnote} +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{}~\tcode{U} within its lifetime, +the behavior is undefined. +\begin{note} +In C, an entire object of structure type can be accessed, e.g., using assignment. +By contrast, \Cpp{} has no notion of accessing an object of class type +through an lvalue of class type. +\end{note} -\enternote Using an overloaded operator causes a function call; the -above covers only operators with built-in meaning. If the lvalue is of -class type, it must have a volatile copy constructor to initialize the -temporary that is the result of the lvalue-to-rvalue -conversion. \exitnote +\rSec2[expr.type]{Type} \pnum -The values of the floating operands and the results of floating -expressions may be represented in greater precision and range than that -required by the type; the types are not changed\ -thereby.\footnote{The cast and assignment operators must still perform their specific -conversions as described in~\ref{expr.cast},~\ref{expr.static.cast} -and~\ref{expr.ass}.} +\indextext{expression!reference}% +If an expression initially has the type ``reference to +\tcode{T}''\iref{dcl.ref,dcl.init.ref}, the type is adjusted to +\tcode{T} prior to any further analysis; +the value category of the expression is not altered. +Let $X$ be the object or function denoted by the reference. +If a pointer to $X$ would be valid in +the context of the evaluation of the expression\iref{basic.fundamental}, +the result designates $X$; +otherwise, the behavior is undefined. +\begin{note} +Before the lifetime of the reference has started or after it has ended, +the behavior is undefined (see~\ref{basic.life}). +\end{note} + +\pnum +If a prvalue initially has the type ``\cv{}~\tcode{T}'', where +\tcode{T} is a cv-unqualified non-class, non-array type, the type of +the expression is adjusted to \tcode{T} prior to any further analysis. \pnum -The \term{cv-combined type} of two types \tcode{T1} and \tcode{T2} -is a type \tcode{T3} -similar to \tcode{T1} whose cv-qualification signature~(\ref{conv.qual}) is: -\begin{itemize} -\item -for every $j > 0$, \cv$_{3,j}$ is the union of -\cv$_{1,j}$ and \cv$_{2,j}$; - -\item -if the resulting \cv$_{3,j}$ is different from -\cv$_{1,j}$ or \cv$_{2,j}$, then -\tcode{const} is added to every \cv$_{3,k}$ for $0 < k < j$. -\end{itemize} - -\enternote Given similar types \tcode{T1} and \tcode{T2}, this -construction ensures that -both can be converted to \tcode{T3}. \exitnote -The \term{composite pointer type} of +\indextext{pointer!composite pointer type}% +The \defn{composite pointer type} of two operands \tcode{p1} and \tcode{p2} having types \tcode{T1} and \tcode{T2}, respectively, where at least one is a -pointer or pointer to member type or +pointer or pointer-to-member type or \tcode{std::nullptr_t}, is: - \begin{itemize} \item if both \tcode{p1} and \tcode{p2} are null pointer constants, @@ -271,27 +373,49 @@ respectively; \item -if \tcode{T1} or \tcode{T2} is ``pointer to \cvqual{cv1} \tcode{void}'' and the -other type is ``pointer to \cvqual{cv2} T'', ``pointer to \cvqual{cv12} -\tcode{void}'', where \cvqual{cv12} is the union of \cvqual{cv1} -and \cvqual{cv2}; +if \tcode{T1} or \tcode{T2} is ``pointer to \cvqual{cv1} \keyword{void}'' and the +other type is ``pointer to \cvqual{cv2} \tcode{T}'', +where \tcode{T} is an object type or \keyword{void}, +``pointer to \cvqual{cv12} \keyword{void}'', +where \cvqual{cv12} is the union of \cvqual{cv1} and \cvqual{cv2}; + +\item +if \tcode{T1} or \tcode{T2} is ``pointer to \keyword{noexcept} function'' and the +other type is ``pointer to function'', where the function types are otherwise the same, +``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 -reference-related to \tcode{C1}~(\ref{dcl.init.ref}), the cv-combined type -of \tcode{T1} and \tcode{T2} or the cv-combined type of \tcode{T2} and \tcode{T1}, +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}, respectively; \item -if \tcode{T1} is ``pointer to member of \tcode{C1} of type \cvqual{cv1} \tcode{U1}'' and \tcode{T2} is -``pointer to member of \tcode{C2} of type \cvqual{cv2} \tcode{U2}'' where \tcode{C1} is +if \tcode{T1} or \tcode{T2} is +``pointer to member of \tcode{C1} of type function'', +the other type is +``pointer to member of \tcode{C2} of type \keyword{noexcept} function'', and +\tcode{C1} is reference-related to \tcode{C2} or +\tcode{C2} is reference-related to \tcode{C1}\iref{dcl.init.ref}, +where the function types are otherwise the same, +``pointer to member of \tcode{C2} of type function'' or +``pointer to member of \tcode{C1} of type function'', respectively; + +\item +if \tcode{T1} is +``pointer to member of \tcode{C1} of type \cvqual{cv1} \tcode{U}'' and +\tcode{T2} is +``pointer to member of \tcode{C2} of type \cvqual{cv2} \tcode{U}'', +for some non-function type \tcode{U}, +where \tcode{C1} is reference-related to \tcode{C2} or \tcode{C2} is reference-related to -\tcode{C1}~(\ref{dcl.init.ref}), the cv-combined type of \tcode{T2} and \tcode{T1} or the cv-combined type +\tcode{C1}\iref{dcl.init.ref}, the qualification-combined type of \tcode{T2} and \tcode{T1} or the qualification-combined type of \tcode{T1} and \tcode{T2}, respectively; \item -if \tcode{T1} and \tcode{T2} are similar types~(\ref{conv.qual}), the cv-combined type of \tcode{T1} and +if \tcode{T1} and \tcode{T2} are similar types\iref{conv.qual}, the qualification-combined type of \tcode{T1} and \tcode{T2}; \item @@ -299,7 +423,7 @@ composite pointer type is ill-formed. \end{itemize} -\enterexample +\begin{example} \begin{codeblock} typedef void *p; typedef const int *q; @@ -307,4603 +431,9275 @@ typedef const int **pci; \end{codeblock} -The composite pointer type of \tcode{p} and \tcode{q} is ``pointer to \tcode{const void}''; the -composite pointer type of \tcode{pi} and \tcode{pci} is ``pointer to \tcode{const} pointer to -\tcode{const int}''. -\exitexample +The composite pointer type of \tcode{p} and \tcode{q} is ``pointer to \tcode{\keyword{const} \keyword{void}}''; the +composite pointer type of \tcode{pi} and \tcode{pci} is ``pointer to \tcode{\keyword{const}} pointer to +\tcode{\keyword{const} \keyword{int}}''. +\end{example} -\rSec1[expr.prim]{Primary expressions}% -\indextext{expression!primary|(} +\rSec2[expr.context]{Context dependence} -\rSec2[expr.prim.general]{General} +\pnum +\label{term.unevaluated.operand}% +In some contexts, \defnx{unevaluated operands}{unevaluated operand} +appear\iref{expr.prim.req.simple, +expr.prim.req.compound, +expr.typeid, +expr.sizeof, +expr.unary.noexcept, +expr.reflect, +dcl.type.decltype, +temp.pre, +temp.concept}. +An unevaluated operand is not evaluated. +\begin{note} +In an unevaluated operand, a non-static class member can be +named\iref{expr.prim.id} and naming of objects or functions does not, by +itself, require that a definition be provided\iref{basic.def.odr}. +An unevaluated operand is considered a full-expression\iref{intro.execution}. +\end{note} -\begin{bnf} -\nontermdef{primary-expression}\br - literal\br - \terminal{this}\br - \terminal{(} expression \terminal{)}\br - id-expression\br - lambda-expression\br - fold-expression -\end{bnf} +\pnum +In some contexts, an expression only appears for its side effects. Such an +expression is called a \defn{discarded-value expression}. +The array-to-pointer\iref{conv.array} +and function-to-pointer\iref{conv.func} standard conversions are not +applied. The lvalue-to-rvalue conversion\iref{conv.lval} is applied +if and only if +the expression is a glvalue of volatile-qualified type and it is one of the +following: -\begin{bnf} -\nontermdef{id-expression}\br - unqualified-id\br - qualified-id -\end{bnf} +\begin{itemize} +\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}, +\item pointer-to-member operation\iref{expr.mptr.oper}, +\item conditional expression\iref{expr.cond} where both the second and the + third operands are one of these expressions, or +\item comma expression\iref{expr.comma} where the right operand is one of + these expressions. +\end{itemize} -\begin{bnf} -\nontermdef{unqualified-id}\br - identifier\br - operator-function-id\br - conversion-function-id\br - literal-operator-id\br - \terminal{\tilde} class-name\br - \terminal{\tilde} decltype-specifier\br - template-id -\end{bnf} +\begin{note} +Using an overloaded operator causes a function call; the +above covers only operators with built-in meaning. +\end{note} +The temporary materialization conversion\iref{conv.rval} is applied +if the (possibly converted) expression is a prvalue of object type. +\begin{note} +If the original expression is an lvalue of class type, +it must have a volatile copy constructor to initialize the temporary object +that is the result object of the temporary materialization conversion. +\end{note} +The expression is evaluated and its result (if any) is discarded. -\pnum -A -\indextext{literal}% -\indextext{constant}% -\grammarterm{literal} -is a primary expression. -Its type depends on its form~(\ref{lex.literal}). -A string literal is an lvalue; all other literals are prvalues. +\rSec1[conv]{Standard conversions} -\pnum -\indextext{\idxcode{this}}% -The keyword \tcode{this} names a pointer to the object for which a non-static member -function~(\ref{class.this}) is invoked or a non-static data member's -initializer~(\ref{class.mem}) is evaluated. +\rSec2[conv.general]{General} -\pnum -If a declaration declares a member function or member function template of a -class \tcode{X}, the expression \tcode{this} is a prvalue of type ``pointer to -\grammarterm{cv-qualifier-seq} \tcode{X}'' between the optional -\grammarterm{cv-qualifer-seq} and the end of the \grammarterm{function-definition}, -\grammarterm{member-declarator}, or \grammarterm{declarator}. It shall not appear -before the optional \grammarterm{cv-qualifier-seq} and it shall not appear within -the declaration of a static member function (although its type and value category -are defined within a static member function as they are within a non-static -member function). \enternote this is because declaration matching does not -occur until the complete declarator is known. \exitnote Unlike the object -expression in other contexts, \tcode{*this} is not required to be of complete -type for purposes of class member access~(\ref{expr.ref}) outside the member -function body. \enternote only class members declared prior to the declaration -are visible. \exitnote -\enterexample -\begin{codeblock} -struct A { - char g(); - template auto f(T t) -> decltype(t + g()) - { return t + g(); } -}; -template auto A::f(int t) -> decltype(t + g()); -\end{codeblock} -\exitexample +\indextext{implicit conversion|see{conversion, implicit}} +\indextext{contextually converted to \tcode{bool}|see{conversion, contextual to \tcode{bool}}} +\indextext{rvalue!lvalue conversion to|see{conversion, lvalue-to-rvalue}}% \pnum -Otherwise, if a \grammarterm{member-declarator} declares a non-static data -member~(\ref{class.mem}) of a class \tcode{X}, the expression \tcode{this} is -a prvalue of type ``pointer to \tcode{X}'' within the -optional \grammarterm{brace-or-equal-initializer}. It shall not appear elsewhere -in the \grammarterm{member-declarator}. +\indextext{conversion!standard|(}% +\indextext{conversion!implicit}% +Standard conversions are implicit conversions with built-in meaning. +\ref{conv} enumerates the full set of such conversions. A +\defnx{standard conversion sequence}{conversion sequence!standard} is a sequence of standard +conversions in the following order: + +\begin{itemize} +\item Zero or one conversion from the following set: lvalue-to-rvalue +conversion, array-to-pointer conversion, and function-to-pointer +conversion. + +\item Zero or one conversion from the following set: integral +promotions, floating-point promotion, integral conversions, floating-point +conversions, floating-integral conversions, pointer conversions, +pointer-to-member conversions, and boolean conversions. + +\item Zero or one function pointer conversion. + +\item Zero or one qualification conversion. +\end{itemize} + +\begin{note} +A standard conversion sequence can be empty, i.e., it can consist of no +conversions. +\end{note} +A standard conversion sequence will be applied to +an expression if necessary to convert it to an expression having +a required destination type and value category. \pnum -The expression \tcode{this} shall not appear in any other context. -\enterexample -\begin{codeblock} -class Outer { - int a[sizeof(*this)]; // error: not inside a member function - unsigned int sz = sizeof(*this); // OK: in \grammarterm{brace-or-equal-initializer} +\begin{note} +Expressions with a given type will be implicitly converted to other +types in several contexts: - void f() { - int b[sizeof(*this)]; // OK +\begin{itemize} +\item When used as operands of operators. The operator's requirements +for its operands dictate the destination type\iref{expr.compound}. - struct Inner { - int c[sizeof(*this)]; // error: not inside a member function of \tcode{Inner} - }; - } -}; -\end{codeblock} -\exitexample +\item When used in the condition of an \keyword{if} statement\iref{stmt.if} or +iteration statement\iref{stmt.iter}. The destination type is +\keyword{bool}. + +\item When used in the expression of a \keyword{switch} statement\iref{stmt.switch}. +The destination type is integral. + +\item When used as the source expression for an initialization (which +includes use as an argument in a function call and use as the expression +in a \keyword{return} statement). The type of the entity being initialized +is (generally) the destination type. +See~\ref{dcl.init}, \ref{dcl.init.ref}. +\end{itemize} +\end{note} \pnum -\indextext{expression!parenthesized}% -A parenthesized expression is a primary expression whose type and value -are identical to those of the enclosed expression. The presence of -parentheses does not affect whether the expression is an lvalue. The -parenthesized expression can be used in exactly the same contexts as -those where the enclosed expression can be used, and with the same -meaning, except as otherwise indicated. +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 +variable \tcode{t}\iref{dcl.init}. \pnum -\indextext{name}% -\indextext{id-expression}% -An \grammarterm{id-expression} is a restricted form of a -\grammarterm{primary-expression}. -\enternote -an \grammarterm{id-expression} can appear after \tcode{.} and \tcode{->} -operators~(\ref{expr.ref}). -\exitnote +Certain language constructs require that an expression be converted to a Boolean +value. An expression $E$ appearing in such a context is said to be +\defnx{contextually converted to \tcode{bool}}{conversion!contextual to \tcode{bool}} and is well-formed if and only if +the declaration \tcode{\keyword{bool} t($E$);} is well-formed, for some invented temporary +variable \tcode{t}\iref{dcl.init}. \pnum -\indextext{identifier}% -An \grammarterm{identifier} is an \grammarterm{id-expression} provided it has -been suitably declared (Clause~\ref{dcl.dcl}). -\enternote -for \grammarterm{operator-function-id}{s}, see~\ref{over.oper}; for -\grammarterm{conversion-function-id}{s}, see~\ref{class.conv.fct}; for -\grammarterm{literal-operator-id}{s}, see~\ref{over.literal}; for -\grammarterm{template-id}{s}, see~\ref{temp.names}. A \grammarterm{class-name} -or \grammarterm{decltype-specifier} -prefixed by \tcode{\tilde} denotes a destructor; see~\ref{class.dtor}. -Within the definition of a non-static member function, an -\grammarterm{identifier} that names a non-static member is transformed to a -class member access expression~(\ref{class.mfct.non-static}). -\exitnote -The type of the expression is the type of the \grammarterm{identifier}. The -result is the entity denoted by the identifier. The result is an lvalue -if the entity is a function, variable, or data member and a prvalue otherwise. -\clearpage - -\indextext{operator!scope~resolution}% -\indextext{\idxcode{::}|see{scope~resolution~operator}}% -% -\begin{bnf} -\nontermdef{qualified-id}\br - nested-name-specifier \terminal{template}\opt unqualified-id -\end{bnf} +Certain language constructs require conversion to a value having +one of a specified set of types appropriate to the construct. An +expression $E$ of class type \tcode{C} appearing in such a +context is said to be +\indextext{conversion!contextual}% +\defn{contextually implicitly converted} to a specified type \tcode{T} and is +well-formed if and only if $E$ can be implicitly converted to a type \tcode{T} +that is determined as follows: +\tcode{C} is searched for non-explicit conversion functions +whose return type is \cv{} \tcode{T} or reference to \cv{} +\tcode{T} such that \tcode{T} is allowed by the context. +There shall be exactly one such \tcode{T}. -\indextext{operator!scope~resolution}% -\indextext{name~hiding}% -% -\begin{bnf} -\nontermdef{nested-name-specifier}\br - \terminal{::}\br - type-name \terminal{::}\br - namespace-name \terminal{::}\br - decltype-specifier \terminal{::}\br - nested-name-specifier identifier \terminal{::}\br - nested-name-specifier \terminal{template}\opt simple-template-id \terminal{::} -\end{bnf} +\pnum +The effect of any implicit +conversion is the same as performing the corresponding declaration and initialization +and then using the temporary variable as the result of the conversion. +The result is an lvalue if \tcode{T} is an lvalue reference +type or an rvalue reference to function type\iref{dcl.ref}, +an xvalue if \tcode{T} is an rvalue reference to object type, +and a prvalue otherwise. The expression $E$ +is used as a glvalue if and only if the initialization uses it as a glvalue. -The type denoted by a \grammarterm{decltype-specifier} in a -\grammarterm{nested-name-specifier} shall be a class or enumeration -type. +\pnum +\begin{note} +For class types, user-defined conversions are considered as well; +see~\ref{class.conv}. In general, an implicit conversion +sequence\iref{over.best.ics} consists of a standard conversion +sequence followed by a user-defined conversion followed by another +standard conversion sequence. +\end{note} \pnum -A \grammarterm{nested-name-specifier} that denotes a class, optionally -followed by the keyword \tcode{template}~(\ref{temp.names}), and then -followed by the name of a member of either that class~(\ref{class.mem}) -or one of its base classes (Clause~\ref{class.derived}), is a -\indextext{id!qualified}% -\grammarterm{qualified-id};~\ref{class.qual} describes name lookup for -class members that appear in \grammarterm{qualified-ids}. The result is the -member. The type of the result is the type of the member. The result is -an lvalue if the member is a static member function or a data member and a -prvalue otherwise. -\enternote -a class member can be referred to using a \grammarterm{qualified-id} at any -point in its potential scope~(\ref{basic.scope.class}). -\exitnote -Where -\grammarterm{class-name} \tcode{::\tilde}~\grammarterm{class-name} is used, -the two \grammarterm{class-name}{s} shall refer to the same class; this -notation names the destructor~(\ref{class.dtor}). -The form \tcode{\tilde}~\grammarterm{decltype-specifier} also denotes the destructor, -but it shall not be used as the \grammarterm{unqualified-id} in a \grammarterm{qualified-id}. -\enternote -a \grammarterm{typedef-name} that names a class is a -\grammarterm{class-name}~(\ref{class.name}). -\exitnote - -\pnum -The \grammarterm{nested-name-specifier} \tcode{::} names the global namespace. -A \grammarterm{nested-name-specifier} that names a -namespace~(\ref{basic.namespace}), followed by the name of a member of -that namespace (or the name of a member of a namespace made visible by a -\grammarterm{using-directive}), is a -\indextext{id!qualified}% -\grammarterm{qualified-id};~\ref{namespace.qual} describes name lookup for -namespace members that appear in \grammarterm{qualified-ids}. The result is -the member. The type of the result is the type of the member. The result -is an lvalue if the member is a function or a variable and a prvalue otherwise. - -\pnum -A \grammarterm{nested-name-specifier} that denotes an -enumeration~(\ref{dcl.enum}), followed by the name of an -enumerator of that enumeration, is a \grammarterm{qualified-id} -that refers to the enumerator. The result is the enumerator. The type -of the result is the type of the enumeration. The result is a prvalue. - -\pnum -In a \grammarterm{qualified-id}, if the -\grammarterm{unqualified-id} -is a -\grammarterm{conversion-function-id}, its \grammarterm{conversion-type-id} -shall denote the same type in both the context in which the entire -\grammarterm{qualified-id} occurs and in the context of the class denoted -by the \grammarterm{nested-name-specifier}. - -\pnum -An \grammarterm{id-expression} that denotes a non-static data member or -non-static member function of a class can only be used: +\begin{note} +There are some contexts where certain conversions are suppressed. For +example, the lvalue-to-rvalue conversion is not done on the operand of +the unary \tcode{\&} operator. Specific exceptions are given in the +descriptions of those operators and contexts. +\end{note} +\rSec2[conv.lval]{Lvalue-to-rvalue conversion} + +\pnum +\indextext{conversion!lvalue-to-rvalue}% +\indextext{type!incomplete}% +A glvalue\iref{basic.lval} of a non-function, non-array type \tcode{T} +can be converted to +a prvalue. +\begin{footnote} +For historical reasons, this conversion is called the ``lvalue-to-rvalue'' +conversion, even though that name does not accurately reflect the taxonomy +of expressions described in~\ref{basic.lval}. +\end{footnote} +If \tcode{T} is an incomplete type, a +program that necessitates this conversion is ill-formed. If \tcode{T} +is a non-class type, the type of the prvalue is +the cv-unqualified version of \tcode{T}. Otherwise, the type of the +prvalue is \tcode{T}. +\begin{footnote} +In \Cpp{} class and array prvalues can have cv-qualified types. +This differs from C, in which non-lvalues never have +cv-qualified types. +\end{footnote} + +\pnum +When an lvalue-to-rvalue conversion +is applied to an expression $E$, and either \begin{itemize} -\item as part of a class member access~(\ref{expr.ref}) in which the -object expression -refers to the member's class\footnote{This also applies when the object expression -is an implicit \tcode{(*this)}~(\ref{class.mfct.non-static}).} or a class derived from -that class, or +\item $E$ is not potentially evaluated, or +\item the evaluation of $E$ results in the evaluation of a member + $E_\tcode{x}$ of the set of potential results of $E$, and $E_\tcode{x}$ + names a variable \tcode{x} that is not odr-used by + $E_\tcode{x}$\iref{basic.def.odr}, +\end{itemize} +the value contained in the referenced object is not accessed. +\begin{example} +\begin{codeblock} +struct S { int n; }; +auto f() { + S x { 1 }; + constexpr S y { 2 }; + return [&](bool b) { return (b ? y : x).n; }; +} +auto g = f(); +int m = g(false); // undefined behavior: access of \tcode{x.n} outside its lifetime +int n = g(true); // OK, does not access \tcode{y.n} +\end{codeblock} +\end{example} -\item to form a pointer to member~(\ref{expr.unary.op}), or +\pnum +The result of the conversion is determined according to the +following rules: -\item if that \grammarterm{id-expression} denotes a non-static data member -and it appears in an unevaluated operand. -\enterexample +\begin{itemize} +\item If \tcode{T} is \cv{}~\tcode{std::nullptr_t}, the result is a +null pointer constant\iref{conv.ptr}. +\begin{note} +Since the conversion does not access the object to which the glvalue refers, +there is no side effect even if \tcode{T} is volatile-qualified\iref{intro.execution}, and +the glvalue can refer to an inactive member of a union\iref{class.union}. +\end{note} + +\item Otherwise, if \tcode{T} has a class +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.compound}, 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. +\begin{example} \begin{codeblock} -struct S { - int m; -}; -int i = sizeof(S::m); // OK -int j = sizeof(S::m + 42); // OK +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} -\exitexample +\end{example} + +\item Otherwise, the object indicated by the glvalue is read\iref{defns.access}. +Let \tcode{V} be the value contained in the object. +If \tcode{T} is an integer type, +the prvalue result is +the value of type \tcode{T} congruent\iref{basic.fundamental} to \tcode{V}, and +\tcode{V} otherwise. \end{itemize} -\rSec2[expr.prim.lambda]{Lambda expressions}% -\indextext{expression!lambda|(} +\pnum +\begin{note} +See also~\ref{basic.lval}. +\end{note} + +\rSec2[conv.array]{Array-to-pointer conversion} \pnum -Lambda expressions provide a concise way to create simple function objects. -\enterexample +\indextext{conversion!array-to-pointer}% +\indextext{decay!array|see{conversion, array-to-pointer}}% +\indextext{decay!function|see{conversion, function-to-pointer}}% +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}''. +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} +\pnum +\indextext{conversion!function-to-pointer}% +An lvalue of function type \tcode{T} can be converted to a prvalue of +type ``pointer to \tcode{T}''. The result is a pointer to the +function. +\begin{footnote} +This conversion never applies to non-static member functions because an +lvalue that refers to a non-static member function cannot be obtained. +\end{footnote} + +\rSec2[conv.rval]{Temporary materialization conversion} +\indextext{conversion!temporary materialization}% + +\pnum +A prvalue of type \tcode{T} can be converted to an xvalue of type \tcode{T}. +This conversion initializes a temporary object\iref{class.temporary} of type \tcode{T} from the prvalue +by evaluating the prvalue with the temporary object as its result object, +and produces an xvalue denoting the temporary object. +\tcode{T} shall be a complete type. +\begin{note} +If \tcode{T} is a class type (or array thereof), +it must have an accessible and non-deleted destructor; +see~\ref{class.dtor}. +\end{note} +\begin{example} \begin{codeblock} -#include -#include -void abssort(float* x, unsigned N) { - std::sort(x, x + N, - [](float a, float b) { - return std::abs(a) < std::abs(b); - }); -} +struct X { int n; }; +int k = X().n; // OK, \tcode{X()} prvalue is converted to xvalue \end{codeblock} -\exitexample +\end{example} -\begin{bnf} -\nontermdef{lambda-expression}\br - lambda-introducer lambda-declarator\opt compound-statement -\end{bnf} +\rSec2[conv.qual]{Qualification conversions} -\begin{bnf} -\nontermdef{lambda-introducer}\br - \terminal{[} lambda-capture\opt \terminal{]} -\end{bnf} +\indextext{conversion!qualification|(}% +\pnum +A \defn{qualification-decomposition} of a type \tcode{T} +is a sequence of +$\cv{}_i$ and $P_i$ +such that \tcode{T} is +\begin{indented} +``$\cv{}_0$ $P_0$ $\cv{}_1$ $P_1$ $\cdots$ $\cv{}_{n-1}$ $P_{n-1}$ $\cv{}_n$ \tcode{U}'' for $n \geq 0$, +\end{indented} +where +each $\cv{}_i$ is a set of cv-qualifiers\iref{basic.type.qualifier}, and +each $P_i$ is +``pointer to''\iref{dcl.ptr}, +``pointer to member of class $C_i$ of type''\iref{dcl.mptr}, +``array of $N_i$'', or +``array of unknown bound of''\iref{dcl.array}. +If $P_i$ designates an array, +the cv-qualifiers $\cv{}_{i+1}$ on the element type are also taken as +the cv-qualifiers $\cv{}_i$ of the array. +\begin{example} +The type denoted by the \grammarterm{type-id} \tcode{const int **} +has three qualification-decompositions, +taking \tcode{U} +as ``\keyword{int}'', +as ``pointer to \tcode{\keyword{const} \keyword{int}}'', and +as ``pointer to pointer to \tcode{\keyword{const} \keyword{int}}''. +\end{example} + +\pnum +\indextext{type!similar|see{similar types}}% +Two types \tcode{T1} and \tcode{T2} are \defnx{similar}{similar types} if +they have qualification-decompositions with the same $n$ +such that corresponding $P_i$ components are either the same +or one is ``array of $N_i$'' and the other is ``array of unknown bound of'', +and the types denoted by \tcode{U} are the same. + +\pnum +The \defnadj{qualification-combined}{type} of two types \tcode{T1} and \tcode{T2} +is the type \tcode{T3} +similar to \tcode{T1} whose qualification-decomposition is such that: +\begin{itemize} +\item +for every $i > 0$, $\cv{}^3_i$ is the union of +$\cv{}^1_i$ and $\cv{}^2_i$, +\item +if either $P^1_i$ or $P^2_i$ is ``array of unknown bound of'', +$P^3_i$ is ``array of unknown bound of'', otherwise it is $P^1_i$, and +\item +if the resulting $\cv{}^3_i$ is different from $\cv{}^1_i$ or $\cv{}^2_i$, +or the resulting $P^3_i$ is different from $P^1_i$ or $P^2_i$, +then \keyword{const} is added to every $\cv{}^3_k$ for $0 < k < i$, +\end{itemize} +where $\cv{}^j_i$ and $P^j_i$ are the components of +the qualification-decomposition of $\tcode{T}j$. +A prvalue of type \tcode{T1} +can be converted to type \tcode{T2} +if the qualification-combined type of \tcode{T1} and \tcode{T2} is \tcode{T2}. +\begin{note} +If a program could assign a pointer of type \tcode{T**} to a pointer of +type \keyword{const} \tcode{T**} (that is, if line \#1 below were +allowed), a program could inadvertently modify a const object +(as it is done on line \#2). For example, +\begin{codeblock} +int main() { + const char c = 'c'; + char* pc; + const char** pcc = &pc; // \#1: not allowed + *pcc = &c; + *pc = 'C'; // \#2: modifies a const object +} +\end{codeblock} +\end{note} +\begin{note} +Given similar types \tcode{T1} and \tcode{T2}, this +construction ensures that +both can be converted to the qualification-combined type of \tcode{T1} and \tcode{T2}. +\end{note} -\begin{bnf} -\nontermdef{lambda-capture}\br - capture-default\br - capture-list\br - capture-default \terminal{,} capture-list -\end{bnf} +\pnum +\begin{note} +A prvalue of type ``pointer to \cvqual{cv1} \tcode{T}'' can be +converted to a prvalue of type ``pointer to \cvqual{cv2} \tcode{T}'' if +``\cvqual{cv2} \tcode{T}'' is more cv-qualified than ``\cvqual{cv1} +\tcode{T}''. +A prvalue of type ``pointer to member of \tcode{X} of type \cvqual{cv1} +\tcode{T}'' can be converted to a prvalue of type ``pointer to member +of \tcode{X} of type \cvqual{cv2} \tcode{T}'' if ``\cvqual{cv2} +\tcode{T}'' is more cv-qualified than ``\cvqual{cv1} \tcode{T}''. +\end{note} -\begin{bnf} -\nontermdef{capture-default}\br - \terminal{\&}\br - \terminal{=} -\end{bnf} +\pnum +\begin{note} +Function types (including those used in pointer-to-member-function types) +are never cv-qualified\iref{dcl.fct}. +\end{note} +\indextext{conversion!qualification|)} -\begin{bnf} -\nontermdef{capture-list}\br - capture \terminal{...\opt}\br - capture-list \terminal{,} capture \terminal{...\opt} -\end{bnf} +\rSec2[conv.prom]{Integral promotions} -\begin{bnf} -\nontermdef{capture}\br - simple-capture\br - init-capture -\end{bnf} +\pnum +For the purposes of \ref{conv.prom}, +a \defnadj{converted}{bit-field} is a prvalue that is the result of +an lvalue-to-rvalue conversion\iref{conv.lval} applied to +a bit-field\iref{class.bit}. -\begin{bnf} -\nontermdef{simple-capture}\br - identifier\br - \terminal{\&} identifier\br - \terminal{this} -\end{bnf} +\pnum +\indextext{promotion!integral}% +A prvalue that is not a converted bit-field and has an integer type other than +\keyword{bool}, \keyword{char8_t}, \keyword{char16_t}, +\keyword{char32_t}, or \keyword{wchar_t} whose integer conversion +rank\iref{conv.rank} is less than the rank of \keyword{int} can be +converted to a prvalue of type \keyword{int} if \keyword{int} can represent +all the values of the source type; otherwise, the source prvalue can be +converted to a prvalue of type \tcode{\keyword{unsigned} \keyword{int}}. -\begin{bnf} -\nontermdef{init-capture}\br - identifier initializer\br - \terminal{\&} identifier initializer -\end{bnf} +\pnum +\indextext{type!underlying!enumeration}% +A prvalue of an unscoped enumeration type whose underlying type is not +fixed can be converted to a prvalue of the first of the following +types that can represent all the values of the enumeration\iref{dcl.enum}: \keyword{int}, +\tcode{\keyword{unsigned} \keyword{int}}, \tcode{\keyword{long} \keyword{int}}, \tcode{\keyword{unsigned} \keyword{long} \keyword{int}}, +\tcode{\keyword{long} \keyword{long} \keyword{int}}, or \tcode{\keyword{unsigned} \keyword{long} \keyword{long} \keyword{int}}. If none of the types in that +list can represent all the values of the enumeration, a prvalue of an unscoped +enumeration type can be converted to a prvalue of the extended integer type with lowest +integer conversion rank\iref{conv.rank} greater than the rank of \tcode{long long} +in which all the values of the enumeration can be represented. If there are +two such extended types, the signed one is chosen. -\begin{bnf} -\nontermdef{lambda-declarator}\br - \terminal{(} parameter-declaration-clause \terminal{)} \terminal{mutable}\opt\br - \hspace*{\bnfindentinc}exception-specification\opt attribute-specifier-seq\opt trailing-return-type\opt -\end{bnf} +\pnum +A prvalue of an unscoped enumeration type whose underlying type is +fixed\iref{dcl.enum} can be converted to a prvalue of its underlying type. Moreover, +if integral promotion can be applied to its underlying type, a prvalue of an unscoped +enumeration type whose underlying type is fixed can also be converted to a prvalue of +the promoted underlying type. +\begin{note} +A converted bit-field of enumeration type is treated as +any other value of that type for promotion purposes. +\end{note} \pnum -The evaluation of a \grammarterm{lambda-expression} results in a prvalue -temporary~(\ref{class.temporary}). This temporary is called the \defn{closure object}. A -\grammarterm{lambda-expression} shall not appear in an unevaluated operand -(Clause~\ref{expr}), in a \grammarterm{template-argument}, -in an \grammarterm{alias-declaration}, -in a typedef declaration, or in the declaration of a function or function -template outside its function body and default arguments. -\enternote -The intention is to prevent lambdas from appearing in a signature. -\exitnote -\enternote -A closure object behaves like a function -object~(\ref{function.objects}).\exitnote +A converted bit-field of integral type can be converted +to a prvalue of type \keyword{int} if \keyword{int} can represent all the +values of the bit-field; otherwise, it can be converted to +\tcode{\keyword{unsigned} \keyword{int}} if \tcode{\keyword{unsigned} \keyword{int}} can represent all the +values of the bit-field. \pnum -The type of the \grammarterm{lambda-expression} (which is also the type of the -closure object) is a unique, unnamed non-union class type --- called the \defn{closure -type} --- whose properties are described below. This class type is neither an -aggregate~(\ref{dcl.init.aggr}) nor a literal type~(\ref{basic.types}). -The closure type is declared in the smallest block -scope, class scope, or namespace scope that contains the corresponding -\grammarterm{lambda-expression}. \enternote This determines the set of namespaces and -classes associated with the closure type~(\ref{basic.lookup.argdep}). The parameter -types of a \grammarterm{lambda-declarator} do not affect these associated namespaces and -classes. \exitnote An implementation may define the closure type differently from what -is described below provided this does not alter the observable behavior of the program -other than by changing: +\indextext{type!underlying!\idxcode{wchar_t}}% +\indextext{type!underlying!\idxcode{char16_t}}% +\indextext{type!underlying!\idxcode{char32_t}}% +A prvalue of type +\keyword{char8_t}, \keyword{char16_t}, \keyword{char32_t}, or +\keyword{wchar_t}\iref{basic.fundamental} +(including a converted bit-field that was not +already promoted to \keyword{int} or \tcode{\keyword{unsigned} \keyword{int}} +according to the rules above) +can be converted to a prvalue +of the first of the following types that can represent all the values of +its underlying type: +\keyword{int}, +\tcode{\keyword{unsigned} \keyword{int}}, +\tcode{\keyword{long} \keyword{int}}, +\tcode{\keyword{unsigned} \keyword{long} \keyword{int}}, +\tcode{\keyword{long} \keyword{long} \keyword{int}}, +\tcode{\keyword{unsigned} \keyword{long} \keyword{long} \keyword{int}}, or +its underlying type. -\begin{itemize} -\item the size and/or alignment of the closure type, +\pnum +\indextext{promotion!bool to int}% +A prvalue of type \keyword{bool} can be converted to a prvalue of type +\keyword{int}, with \keyword{false} becoming zero and \keyword{true} becoming +one. -\item whether the closure type is trivially copyable (Clause~\ref{class}), +\pnum +These conversions are called \defnx{integral promotions}{integral promotion}. -\item whether the closure type is a standard-layout class (Clause~\ref{class}), -or +\rSec2[conv.fpprom]{Floating-point promotion} -\item whether the closure type is a POD class (Clause~\ref{class}). -\end{itemize} +\pnum +\indextext{promotion!floating-point}% +A prvalue of type \keyword{float} can be converted to a prvalue of type +\keyword{double}. The value is unchanged. + +\pnum +This conversion is called \defn{floating-point promotion}. -An implementation shall not add members of rvalue reference type to the closure -type. +\rSec2[conv.integral]{Integral conversions} \pnum -If a \grammarterm{lambda-expression} does not include a -\grammarterm{lambda-declarator}, it is as if the \grammarterm{lambda-declarator} were -\tcode{()}. -The lambda return type is \tcode{auto}, which is replaced by the -\grammarterm{trailing-return-type} if provided and/or deduced from -\tcode{return} statements as described in~\ref{dcl.spec.auto}. -\enterexample -\begin{codeblock} -auto x1 = [](int i){ return i; }; // OK: return type is \tcode{int} -auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from \grammarterm{braced-init-list} -int j; -auto x3 = []()->auto&& { return j; }; // OK: return type is \tcode{int\&} -\end{codeblock} -\exitexample +\indextext{conversion!integral}% +A prvalue of an integer type can be converted to a prvalue of another +integer type. A prvalue of an unscoped enumeration type can be converted to +a prvalue of an integer type. \pnum -The closure type for a non-generic \grammarterm{lambda-expression} has a public -inline function call operator~(\ref{over.call}) whose parameters and return type -are described by the \grammarterm{lambda-expression}'s -\grammarterm{parameter-declaration-clause} and \grammarterm{trailing-return-type} -respectively. -For a generic lambda, the closure type has a public inline function call -operator member template~(\ref{temp.mem}) whose -\grammarterm{template-parameter-list} consists of one invented type -\grammarterm{template-parameter} for each occurrence of \tcode{auto} in the -lambda's \grammarterm{parameter-declaration-clause}, in order of appearance. -The invented type \grammarterm{template-parameter} is a parameter pack if -the corresponding \grammarterm{parameter-declaration} declares a function -parameter pack~(\ref{dcl.fct}). The return type and function parameters of the -function call operator template are derived from the -\grammarterm{lambda-expression}{'s} \grammarterm{trailing-return-type} and -\grammarterm{parameter-declaration-clause} by replacing each occurrence of -\tcode{auto} in the \grammarterm{decl-specifier}{s} of the -\grammarterm{parameter-declaration-clause} with the name of the corresponding -invented \grammarterm{template-parameter}. -\enterexample -\begin{codeblock} - auto glambda = [](auto a, auto&& b) { return a < b; }; - bool b = glambda(3, 3.14); // OK - auto vglambda = [](auto printer) { - return [=](auto&& ... ts) { // OK: \tcode{ts} is a function parameter pack - printer(std::forward(ts)...); - - return [=]() { - printer(ts ...); - }; - }; - }; - auto p = vglambda( [](auto v1, auto v2, auto v3) - { std::cout << v1 << v2 << v3; } ); - auto q = p(1, 'a', 3.14); // OK: outputs \tcode{1a3.14} - q(); // OK: outputs \tcode{1a3.14} -\end{codeblock} -\exitexample -This function call operator or operator template is declared -\tcode{const}~(\ref{class.mfct.non-static}) if and only if the -\grammarterm{lambda-expression}'s \grammarterm{parameter-declaration-clause} is not -followed by \tcode{mutable}. It is neither virtual nor declared \tcode{volatile}. Any -\grammarterm{exception-specification} 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. -\enternote Names referenced in -the \grammarterm{lambda-declarator} are looked up in the context in which the -\grammarterm{lambda-expression} appears. \exitnote +\indextext{conversion!bool@\tcode{bool}}% +If the destination type is \keyword{bool}, see~\ref{conv.bool}. If the +source type is \keyword{bool}, the value \keyword{false} is converted to +zero and the value \keyword{true} is converted to one. + +\pnum +\indextext{conversion!to unsigned}% +\indextext{conversion!to signed}% +Otherwise, the result is the unique value of the destination type +that is congruent to the source integer modulo $2^N$, +where $N$ is the width of the destination type. + +\pnum +The conversions allowed as integral promotions are excluded from the set +of integral conversions. + +\rSec2[conv.double]{Floating-point conversions} + +\pnum +\indextext{conversion!floating-point}% +A prvalue of floating-point type can be converted to a prvalue of +another floating-point type +with a greater or equal conversion rank\iref{conv.rank}. +A prvalue of standard floating-point type can be converted to +a prvalue of another standard floating-point type. + +\pnum +If the source value can be exactly +represented in the destination type, the result of the conversion is +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. \pnum -The closure type for a non-generic \grammarterm{lambda-expression} with no -\grammarterm{lambda-capture} -has a public non-virtual non-explicit const conversion function to pointer to -function with \Cpp language linkage~(\ref{dcl.link}) having -the same parameter and return types as the closure type's function call operator. The -value returned by this conversion function shall be the address of a function that, when -invoked, has the same effect as invoking the closure type's function call operator. -For a generic lambda with no \grammarterm{lambda-capture}, the closure type has a -public non-virtual non-explicit const conversion function template to -pointer to function. The conversion function template has the same invented -\grammarterm{template-parameter-list}, and the pointer to function has the same -parameter types, as the function call operator template. The return type of -the pointer to function shall behave as if it were a -\grammarterm{decltype-specifier} denoting the return type of the corresponding -function call operator template specialization. -\enternote If the generic lambda has no \grammarterm{trailing-return-type} or -the \grammarterm{trailing-return-type} contains a placeholder type, return type -deduction of the corresponding function call operator template specialization -has to be done. The corresponding specialization is that instantiation of the -function call operator template with the same template arguments as those -deduced for the conversion function template. Consider the following: -\begin{codeblock} -auto glambda = [](auto a) { return a; }; -int (*fp)(int) = glambda; -\end{codeblock} -The behavior of the conversion function of \tcode{glambda} above is like -that of the following conversion function: -\begin{codeblock} -struct Closure { - template auto operator()(T t) const { ... } - template static auto lambda_call_operator_invoker(T a) { - // forwards execution to \tcode{operator()(a)} and therefore has - // the same return type deduced - ... - } - template using fptr_t = - decltype(lambda_call_operator_invoker(declval())) (*)(T); +The conversions allowed as floating-point promotions are excluded from +the set of floating-point conversions. - template operator fptr_t() const - { return &lambda_call_operator_invoker; } -}; -\end{codeblock} -\exitnote -\enterexample -\begin{codeblock} -void f1(int (*)(int)) { } -void f2(char (*)(int)) { } +\rSec2[conv.fpint]{Floating-integral conversions} -void g(int (*)(int)) { } // \#1 -void g(char (*)(char)) { } // \#2 +\pnum +\indextext{conversion!floating to integral}% +A prvalue of a floating-point type can be converted to a prvalue of an +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 +in the destination type. +\begin{note} +If the destination type is \keyword{bool}, see~\ref{conv.bool}. +\end{note} -void h(int (*)(int)) { } // \#3 -void h(char (*)(int)) { } // \#4 +\pnum +\indextext{conversion!integral to floating}% +\indextext{truncation}% +\indextext{rounding}% +A prvalue of an integer type or of an unscoped enumeration type can be converted to +a prvalue of a floating-point type. The result is exact if possible. If the value being +converted is in the range of values that can be represented but the value cannot be +represented exactly, it is an \impldef{value of result of inexact integer to +floating-point conversion} choice of either the next lower or higher representable +value. +\begin{note} +Loss of precision occurs if the integral value cannot be represented +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 +source type is \keyword{bool}, the value \keyword{false} is converted to zero and the value +\keyword{true} is converted to one. -auto glambda = [](auto a) { return a; }; -f1(glambda); // OK -f2(glambda); // error: ID is not convertible -g(glambda); // error: ambiguous -h(glambda); // OK: calls \#3 since it is convertible from ID -int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK -\end{codeblock} -\exitexample -The value returned by any given specialization of this conversion function -template shall be the address of a function that, when invoked, has the same -effect as invoking the generic lambda's corresponding function call operator -template specialization. -\enternote -This will result in the implicit instantiation of the generic lambda's body. -The instantiated generic lambda's return type and parameter types shall match -the return type and parameter types of the pointer to function. -\exitnote -\enterexample -\begin{codeblock} -auto GL = [](auto a) { std::cout << a; return a; }; -int (*GL_int)(int) = GL; // OK: through conversion function template -GL_int(3); // OK: same as \tcode{GL(3)} -\end{codeblock} -\exitexample +\rSec2[conv.ptr]{Pointer conversions} \pnum -The \grammarterm{lambda-expression}'s \grammarterm{compound-statement} yields the -\grammarterm{function-body}~(\ref{dcl.fct.def}) of the function call operator, but for -purposes of name lookup~(\ref{basic.lookup}), determining the type and value of -\tcode{this}~(\ref{class.this}) and transforming \grammarterm{id-expression}{s} -referring to non-static class members into class member access expressions using -\tcode{(*this)}~(\ref{class.mfct.non-static}), the \grammarterm{compound-statement} is -considered in the context of the \grammarterm{lambda-expression}. \enterexample - +\indextext{conversion!pointer}% +\indextext{null pointer conversion|see{conversion, null pointer}}% +\indextext{pointer!zero|see{value, null pointer}}% +\indextext{value!null pointer}% +A \defnx{null pointer constant}{constant!null pointer} is an integer literal\iref{lex.icon} with +value zero +or a prvalue of type \tcode{std::nullptr_t}. A null pointer constant can be +converted to a pointer type; the +result is the null pointer value of that type\iref{basic.compound} and is +distinguishable from every other value of +object pointer or function pointer +type. +Such a conversion is called a \defnx{null pointer conversion}{conversion!null pointer}. +The conversion of a null pointer constant to a pointer to +cv-qualified type is a single conversion, and not the sequence of a +pointer conversion followed by a qualification +conversion\iref{conv.qual}. A null pointer constant of integral type +can be converted to a prvalue of type \tcode{std::nullptr_t}. +\begin{note} +The resulting prvalue is not a null pointer value. +\end{note} + +\pnum +A prvalue of type ``pointer to \cv{} \tcode{T}'', where \tcode{T} +is an object type, can be converted to a prvalue of type ``pointer to +\cv{} \keyword{void}''. +The pointer value\iref{basic.compound} is unchanged by this conversion. + +\pnum +A prvalue \tcode{v} of type ``pointer to \cv{} \tcode{D}'', where \tcode{D} +is a complete class type, can be converted to a prvalue of type ``pointer to +\cv{} \tcode{B}'', where \tcode{B} is a base class\iref{class.derived} +of \tcode{D}. If \tcode{B} is an +inaccessible\iref{class.access} or +ambiguous\iref{class.member.lookup} base class of \tcode{D}, a program +that necessitates this conversion is ill-formed. +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} +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. +Otherwise, +the result is a pointer to the base class subobject of +the derived class object. + +\rSec2[conv.mem]{Pointer-to-member conversions} + +\pnum +\indextext{conversion!pointer-to-member}% +\indextext{null member pointer conversion|see{conversion, null member pointer}}% +\indextext{constant!null pointer}% +A null pointer constant\iref{conv.ptr} can be converted to a +pointer-to-member +type; the result is the \defnx{null member pointer value}{value!null member pointer} +of that type and is distinguishable from any pointer to member not +created from a null pointer constant. +Such a conversion is called a \defnx{null member pointer conversion}{conversion!null member pointer}. +The conversion of a null pointer +constant to a pointer to member of cv-qualified type is a single +conversion, and not the sequence of a pointer-to-member conversion +followed by a qualification conversion\iref{conv.qual}. + +\pnum +A prvalue of type ``pointer to member of \tcode{B} of type \cv{} +\tcode{T}'', where \tcode{B} is a class type, can be converted to +a prvalue of type ``pointer to member of \tcode{D} of type \cv{} +\tcode{T}'', where \tcode{D} is a complete class derived\iref{class.derived} +from \tcode{B}. If \tcode{B} is an +inaccessible\iref{class.access}, +ambiguous\iref{class.member.lookup}, or virtual\iref{class.mi} base +class of \tcode{D}, or a base class of a virtual base class of +\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 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 +the member in \tcode{D}'s instance of \tcode{B}. Since the result has +type ``pointer to member of \tcode{D} of type \cv{} \tcode{T}'', +indirection through it with a \tcode{D} object is valid. The result is the same +as if indirecting through the pointer to member of \tcode{B} with the +\tcode{B} subobject of \tcode{D}. The null member pointer value is +converted to the null member pointer value of the destination +type. +\begin{footnote} +The rule for conversion of pointers to members (from pointer to member +of base to pointer to member of derived) appears inverted compared to +the rule for pointers to objects (from pointer to derived to pointer to +base)\iref{conv.ptr,class.derived}. This inversion is +necessary to ensure type safety. Note that a pointer to member is not +an object pointer or a function pointer +and the rules for conversions +of such pointers do not apply to pointers to members. +\indextext{conversion!pointer-to-member!\idxcode{void*}}% +In particular, a pointer to member cannot be converted to a +\tcode{\keyword{void}*}. +\end{footnote} + +\rSec2[conv.fctptr]{Function pointer conversions} + +\pnum +\indextext{conversion!function pointer}% +A prvalue of type ``pointer to \keyword{noexcept} function'' +can be converted to a prvalue of type ``pointer to function''. +The result is a pointer to the function. +A prvalue of type ``pointer to member of type \keyword{noexcept} function'' +can be converted to a prvalue of type ``pointer to member of type function''. +The result designates the member function. + +\begin{example} \begin{codeblock} -struct S1 { - int x, y; - int operator()(int); - void f() { - [=]()->int { - return operator()(this->x + y); // equivalent to \tcode{S1::operator()(this->x + (*this).y)} - // \tcode{this} has type \tcode{S1*} - }; - } -}; +void (*p)(); +void (**pp)() noexcept = &p; // error: cannot convert to pointer to \keyword{noexcept} function + +struct S { typedef void (*p)(); operator p(); }; +void (*q)() noexcept = S(); // error: cannot convert to pointer to \keyword{noexcept} function \end{codeblock} -\exitexample -Further, a variable \tcode{__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}. +\end{example} + +\rSec2[conv.bool]{Boolean conversions} \pnum -If a \grammarterm{lambda-capture} includes a \grammarterm{capture-default} that -is \tcode{\&}, no identifier in a \grammarterm{simple-capture} of that -\grammarterm{lambda-capture} shall be preceded -by \tcode{\&}. If a \grammarterm{lambda-capture} includes a -\grammarterm{capture-default} that is \tcode{=}, each -\grammarterm{simple-capture} of that \grammarterm{lambda-capture} shall -be of the form ``\tcode{\&} \grammarterm{identifier}''. Ignoring appearances in -\grammarterm{initializer}{s} of \grammarterm{init-capture}{s}, an identifier or -\tcode{this} shall not appear more than once in a -\grammarterm{lambda-capture}. \enterexample +\indextext{conversion!boolean}% +A prvalue of arithmetic, unscoped enumeration, pointer, or pointer-to-member +type can be converted to a prvalue of type \keyword{bool}. A zero value, null +pointer value, or null member pointer value is converted to \keyword{false}; any +other value is converted to \keyword{true}. -\begin{codeblock} -struct S2 { void f(int i); }; -void S2::f(int i) { - [&, i]{ }; // OK - [&, &i]{ }; // error: \tcode{i} preceded by \tcode{\&} when \tcode{\&} is the default - [=, this]{ }; // error: \tcode{this} when \tcode{=} is the default - [i, i]{ }; // error: \tcode{i} repeated -} -\end{codeblock} -\exitexample +\indextext{conversion!standard|)} -\pnum -A \grammarterm{lambda-expression} whose smallest enclosing scope is a block -scope~(\ref{basic.scope.block}) is a \defn{local lambda expression}; any other -\grammarterm{lambda-expression} shall not have a \grammarterm{capture-default} or -\grammarterm{simple-capture} in its -\grammarterm{lambda-introducer}. The \defn{reaching scope} of a local lambda expression -is the set of enclosing scopes up to and including the innermost enclosing function and -its parameters. \enternote This reaching scope includes any intervening -\grammarterm{lambda-expression}{s}. \exitnote +\rSec1[expr.arith.conv]{Usual arithmetic conversions} \pnum -The \grammarterm{identifier} in a \grammarterm{simple-capture} is looked up using the -usual rules for unqualified name lookup~(\ref{basic.lookup.unqual}); each such lookup -shall find an entity. An entity that is designated by a -\grammarterm{simple-capture} -is said to be \defn{explicitly captured}, and shall be \tcode{this} or -a variable with automatic storage duration declared in -the reaching scope of the local lambda expression. +Many binary operators that expect operands of arithmetic or enumeration +type cause conversions and yield result types in a similar way. The +purpose is to yield a common type, which is also the type of the result. +This pattern is called the \defnx{usual arithmetic conversions}{conversion!usual arithmetic}, +which are defined as follows: -\pnum -An \grammarterm{init-capture} behaves as if it declares and explicitly captures a -variable of -the form ``\tcode{auto} \grammarterm{init-capture} \tcode{;}'' -whose declarative region is the \grammarterm{lambda-expression}'s -\grammarterm{compound-statement}, except that: \begin{itemize} -\item if the capture is by copy (see below), the non-static data member -declared for the capture and the variable are treated as two different ways -of referring to the same object, which has the lifetime of the non-static -data member, and no additional copy and destruction is performed, and -\item if the capture is by reference, the variable's lifetime ends when the -closure object's lifetime ends. +\item The lvalue-to-rvalue conversion\iref{conv.lval} +is applied to each operand and +the resulting prvalues are used in place of the original operands +for the remainder of this section. +\item If either operand is of scoped enumeration type\iref{dcl.enum}, no conversions +are performed; if the other operand does not have the same type, the expression is +ill-formed. +\item Otherwise, if one operand is of enumeration type and the other operand is +of a different enumeration type or a floating-point type, the expression is +ill-formed. +\item Otherwise, if either operand is of floating-point type, +the following rules are applied: +\begin{itemize} +\item +If both operands have the same type, no further conversion is performed. +\item +Otherwise, if one of the operands is of a non-floating-point type, +that operand is converted to the type of +the operand with the floating-point type. +\item +Otherwise, if the floating-point conversion ranks\iref{conv.rank} of +the types of the operands are ordered but not equal, +then the operand of the type with the lesser floating-point conversion rank +is converted to the type of the other operand. +\item +Otherwise, if the floating-point conversion ranks of the types of +the operands are equal, +then the operand with the lesser floating-point conversion subrank\iref{conv.rank} +is converted to the type of the other operand. +\item +Otherwise, the expression is ill-formed. \end{itemize} -\enternote -This enables an \grammarterm{init-capture} like -``\tcode{x = std::move(x)}''; the second ``\tcode{x}'' must bind to a -declaration in the surrounding context. -\exitnote -\enterexample -\begin{codeblock} -int x = 4; -auto y = [&r = x, x = x+1]()->int { - r += 2; - return x+2; - }(); // Updates \tcode{::x} to 6, and initializes \tcode{y} to 7. -\end{codeblock} -\exitexample +\item Otherwise, each operand is converted to a common type \tcode{C}. +The integral promotion rules\iref{conv.prom} are used +to determine a type \tcode{T1} and type \tcode{T2} for each operand. +\begin{footnote} +As a consequence, operands of type \keyword{bool}, \keyword{char8_t}, \keyword{char16_t}, +\keyword{char32_t}, \keyword{wchar_t}, or of enumeration type are converted +to some integral type. +\end{footnote} +Then the following rules are applied to determine \tcode{C}: -\pnum -A \grammarterm{lambda-expression} with an associated -\grammarterm{capture-default} that does not explicitly capture \tcode{this} or -a variable with automatic storage duration (this excludes any \grammarterm{id-expression} -that has been found to refer to an \grammarterm{init-capture}{'s} associated -\indextext{implicit capture!definition of}% -non-static data member), is said to \term{implicitly capture} the entity (i.e., -\tcode{this} or a variable) if the \grammarterm{compound-statement}: \begin{itemize} -\item odr-uses~(\ref{basic.def.odr}) the entity, or -\item names the entity in a potentially-evaluated -expression~(\ref{basic.def.odr}) where the enclosing full-expression depends on -a generic lambda parameter declared within the reaching scope of the -\grammarterm{lambda-expression}. + +\item If \tcode{T1} and \tcode{T2} are the same type, \tcode{C} is that type. + +\item Otherwise, if \tcode{T1} and \tcode{T2} are both signed integer types or +are both unsigned integer types, +\tcode{C} is the type with greater rank. + +\item Otherwise, let \tcode{U} be the unsigned integer type and +\tcode{S} be the signed integer type. +\begin{itemize} +\item If \tcode{U} has rank greater than or equal to the rank of \tcode{S}, +\tcode{C} is \tcode{U}. +\item Otherwise, if \tcode{S} can represent all of the values of \tcode{U}, +\tcode{C} is \tcode{S}. +\item Otherwise, +\tcode{C} is the unsigned integer type corresponding to \tcode{S}. +\end{itemize} +\end{itemize} \end{itemize} -\enterexample -\begin{codeblock} -void f(int, const int (&)[2] = {}) { } // \#1 -void f(const int&, const int (&)[1]) { } // \#2 -void test() { - const int x = 17; - auto g = [](auto a) { - f(x); // OK: calls \#1, does not capture \tcode{x} - }; - auto g2 = [=](auto a) { - int selector[sizeof(a) == 1 ? 1 : 2]{}; - f(x, selector); // OK: is a dependent expression, so captures \tcode{x} - }; -} -\end{codeblock} -\exitexample -All such implicitly captured -entities shall be declared within the reaching scope of the lambda expression. -\enternote The implicit capture of an entity by a nested -\grammarterm{lambda-expression} can cause its implicit capture by the containing -\grammarterm{lambda-expression} (see below). Implicit odr-uses of \tcode{this} can result -in implicit capture. \exitnote +\rSec1[expr.prim]{Primary expressions}% +\indextext{expression!primary|(} -\pnum -An entity is \defn{captured} if it is captured explicitly or implicitly. An entity -captured by a \grammarterm{lambda-expression} is odr-used~(\ref{basic.def.odr}) in the scope -containing the \grammarterm{lambda-expression}. If \tcode{this} is captured by a local -lambda expression, its nearest enclosing function shall be a non-static member function. -If a \grammarterm{lambda-expression} or an instantiation of the function call -operator template of a generic lambda odr-uses~(\ref{basic.def.odr}) \tcode{this} or a -variable with automatic storage duration from its reaching scope, that -entity shall be captured by the \grammarterm{lambda-expression}. If a -\grammarterm{lambda-expression} captures an entity and that entity is not defined or -captured in the immediately enclosing lambda expression or function, the program is -ill-formed. \enterexample -\begin{codeblock} -void f1(int i) { - int const N = 20; - auto m1 = [=]{ - int const M = 30; - auto m2 = [i]{ - int x[N][M]; // OK: \tcode{N} and \tcode{M} are not odr-used - x[0][0] = i; // OK: \tcode{i} is explicitly captured by \tcode{m2} - // and implicitly captured by \tcode{m1} - }; - }; - struct s1 { - int f; - void work(int n) { - int m = n*n; - int j = 40; - auto m3 = [this,m] { - auto m4 = [&,j] { // error: \tcode{j} not captured by \tcode{m3} - int x = n; // error: \tcode{n} implicitly captured by \tcode{m4} - // but not captured by \tcode{m3} - x += m; // OK: \tcode{m} implicitly captured by \tcode{m4} - // and explicitly captured by \tcode{m3} - x += i; // error: \tcode{i} is outside of the reaching scope - x += f; // OK: \tcode{this} captured implicitly by \tcode{m4} - // and explicitly by \tcode{m3} - }; - }; - } - }; -} -\end{codeblock} -\exitexample +\rSec2[expr.prim.grammar]{Grammar} -\pnum -A \grammarterm{lambda-expression} appearing in a default argument shall not -implicitly or explicitly capture any entity. \enterexample +\begin{bnf} +\nontermdef{primary-expression}\br + literal\br + \keyword{this}\br + \terminal{(} expression \terminal{)}\br + id-expression\br + lambda-expression\br + fold-expression\br + requires-expression\br + splice-expression +\end{bnf} -\begin{codeblock} -void f2() { - int i = 1; - void g1(int = ([i]{ return i; })()); // ill-formed - void g2(int = ([i]{ return 0; })()); // ill-formed - void g3(int = ([=]{ return i; })()); // ill-formed - void g4(int = ([=]{ return 0; })()); // OK - void g5(int = ([]{ return sizeof i; })()); // OK -} -\end{codeblock} -\exitexample +\rSec2[expr.prim.literal]{Literals} \pnum -An entity is \indexdefn{captured!by copy}\term{captured by copy} if it is implicitly captured and the -\grammarterm{capture-default} is \tcode{=} or if it is explicitly captured with a -capture that is not of the form \tcode{\&} \grammarterm{identifier} or -\tcode{\&} \grammarterm{identifier} \grammarterm{initializer}. -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 type of the -corresponding captured entity if the entity is not a reference to an object, or the -referenced type otherwise. \enternote If the captured entity is a reference to a -function, the corresponding data member is also a reference to a function. \exitnote -A member of an anonymous union shall not be captured by copy. +\indextext{literal}% +\indextext{constant}% +The type of a \grammarterm{literal} +is determined based on its form as specified in \ref{lex.literal}. +A \grammarterm{string-literal} is an lvalue +designating a corresponding string literal object\iref{lex.string}, +a \grammarterm{user-defined-literal} +has the same value category +as the corresponding operator call expression described in \ref{lex.ext}, +and any other \grammarterm{literal} is a prvalue. + +\rSec2[expr.prim.this]{This} \pnum -An entity is \indexdefn{captured!by reference}\term{captured by reference} if it is implicitly or explicitly -captured but not captured by copy. It is unspecified whether additional unnamed -non-static data members are declared in the closure type for entities captured by -reference. A member of an anonymous union shall not be captured by reference. +\indextext{\idxcode{this}}% +The keyword \keyword{this} names a pointer to the object for which an implicit object member +function\iref{class.mfct.non.static} is invoked or a non-static data member's +initializer\iref{class.mem} is evaluated. \pnum -If a \grammarterm{lambda-expression} \tcode{m2} captures an entity and that entity is -captured by an immediately enclosing \grammarterm{lambda-expression} -\tcode{m1}, then -\tcode{m2}'s capture is transformed as follows: +The \defnadj{current}{class} at a program point is +the class associated with the innermost class scope containing that point. +\begin{note} +A \grammarterm{lambda-expression} does not introduce a class scope. +\end{note} -\begin{itemize} -\item if \tcode{m1} captures the entity by copy, -\tcode{m2} captures the corresponding -non-static data member of \tcode{m1}'s closure type; +\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). -\item if \tcode{m1} captures the entity by reference, -\tcode{m2} captures the same -entity captured by \tcode{m1}. -\end{itemize} -\enterexample the nested lambda expressions and invocations below will output -\tcode{123234}. +\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 +\grammarterm{cv-qualifier-seq} \tcode{X}'' +wherever \tcode{X} is the current class +between the optional +\grammarterm{cv-qualifier-seq} and the end of the \grammarterm{function-definition}, +\grammarterm{member-declarator}, or \grammarterm{declarator}. It shall not appear within +the declaration of +a static or explicit object member function +of the current class (although its type and value category +are defined within such member functions as they are within an implicit object +member function). +\begin{note} +This is because declaration matching does not +occur until the complete declarator is known. +\end{note} +\begin{note} +In a \grammarterm{trailing-return-type}, +the class being defined is not required to be complete +for purposes of class member access\iref{expr.ref}. +Class members declared later are not visible. +\begin{example} \begin{codeblock} -int a = 1, b = 1, c = 1; -auto m1 = [a, &b, &c]() mutable { - auto m2 = [a, b, &c]() mutable { - std::cout << a << b << c; - a = 4; b = 4; c = 4; - }; - a = 3; b = 3; c = 3; - m2(); +struct A { + char g(); + template auto f(T t) -> decltype(t + g()) + { return t + g(); } }; -a = 2; b = 2; c = 2; -m1(); -std::cout << a << b << c; +template auto A::f(int t) -> decltype(t + g()); \end{codeblock} -\exitexample +\end{example} +\end{note} +\pnum +Otherwise, if a \grammarterm{member-declarator} declares a non-static data +member\iref{class.mem} of a class \tcode{X}, the expression \keyword{this} is +a prvalue of type ``pointer to \tcode{X}'' +wherever \tcode{X} is the current class +within the +optional default member initializer\iref{class.mem}. \pnum -Every \grammarterm{id-expression} within the \grammarterm{compound-statement} of a -\grammarterm{lambda-expression} that is an odr-use~(\ref{basic.def.odr}) of an -entity captured by copy is transformed into an access to the corresponding unnamed data -member of the closure type. -\enternote An \grammarterm{id-expression} that is not an odr-use refers to -the original entity, never to a member of the closure type. Furthermore, such -an \grammarterm{id-expression} does not cause the implicit capture of the -entity. \exitnote -If \tcode{this} is captured, each odr-use of \tcode{this} is -transformed into an access to the corresponding unnamed data member of the closure type, -cast~(\ref{expr.cast}) to the type of \tcode{this}. \enternote The cast ensures that the -transformed expression is a prvalue. \exitnote \enterexample +The expression \keyword{this} shall not appear in any other context. +\begin{example} \begin{codeblock} -void f(const int*); -void g() { - const int N = 10; - [=] { - int arr[N]; // OK: not an odr-use, refers to automatic variable - f(&N); // OK: causes \tcode{N} to be captured; \tcode{\&N} points to the - // corresponding member of the closure type - }; -} -\end{codeblock} -\exitexample +class Outer { + int a[sizeof(*this)]; // error: not inside a member function + unsigned int sz = sizeof(*this); // OK, in default member initializer -\pnum -Every occurrence of \tcode{decltype((x))} where \tcode{x} is a possibly -parenthesized \grammarterm{id-expression} that names an entity of automatic storage -duration is treated as if \tcode{x} were transformed into an access to a corresponding -data member of the closure type that would have been declared if \tcode{x} were an odr-use of -the denoted entity. \enterexample + void f() { + int b[sizeof(*this)]; // OK -\begin{codeblock} -void f3() { - float x, &r = x; - [=] { // \tcode{x} and \tcode{r} are not captured (appearance in a \tcode{decltype} operand is not an odr-use) - decltype(x) y1; // \tcode{y1} has type \tcode{float} - decltype((x)) y2 = y1; // \tcode{y2} has type \tcode{float const\&} because this lambda - // is not \tcode{mutable} and \tcode{x} is an lvalue - decltype(r) r1 = y1; // \tcode{r1} has type \tcode{float\&} (transformation not considered) - decltype((r)) r2 = y2; // \tcode{r2} has type \tcode{float const\&} - }; -} + struct Inner { + int c[sizeof(*this)]; // error: not inside a member function of \tcode{Inner} + }; + } +}; \end{codeblock} -\exitexample +\end{example} -\pnum -The closure type associated with a \grammarterm{lambda-expression} has no -default constructor and a deleted copy assignment operator. It has a -defaulted copy constructor and a defaulted move constructor~(\ref{class.copy}). -\enternote These special member functions are implicitly defined as -usual, and might therefore be defined as deleted. \exitnote +\rSec2[expr.prim.paren]{Parentheses} \pnum -The closure type associated with a \grammarterm{lambda-expression} has an -implicitly-declared destructor~(\ref{class.dtor}). +\indextext{expression!parenthesized}% +A parenthesized expression \tcode{($E$)} +is a primary expression whose type, result, and value category are identical to those of $E$. +The parenthesized expression can be used in exactly the same contexts as +those where $E$ can be used, and with the same +meaning, except as otherwise indicated. -\pnum -A member of a closure type shall not be -explicitly instantiated~(\ref{temp.inst}), -explicitly specialized~(\ref{temp.explicit}), or -named in a \tcode{friend} declaration~(\ref{class.friend}). +\rSec2[expr.prim.id]{Names} -\pnum -When the \grammarterm{lambda-expression} is evaluated, 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. \enternote -This ensures that the destructions will occur in the reverse order of the constructions. -\exitnote +\rSec3[expr.prim.id.general]{General} + +\begin{bnf} +\nontermdef{id-expression}\br + unqualified-id\br + qualified-id\br + pack-index-expression +\end{bnf} \pnum -\enternote If an entity is implicitly or explicitly captured by reference, -invoking the function call operator of the corresponding \grammarterm{lambda-expression} -after the lifetime of the entity has ended is likely to result in undefined behavior. -\exitnote +\indextext{name}% +An \grammarterm{id-expression} is a restricted form of a +\grammarterm{primary-expression}. +\begin{note} +An \grammarterm{id-expression} can appear after \tcode{.} and \tcode{->} +operators\iref{expr.ref}. +\end{note} \pnum -A \grammarterm{simple-capture} followed by an ellipsis is a pack -expansion~(\ref{temp.variadic}). An \grammarterm{init-capture} followed by an -ellipsis is ill-formed. -\enterexample +If an \grammarterm{id-expression} $E$ denotes +a non-static non-type member of some class \tcode{C} at a point where +the current class\iref{expr.prim.this} is \tcode{X} and +\begin{itemize} +\item +$E$ is potentially evaluated or +\tcode{C} is \tcode{X} or a base class of \tcode{X}, and +\item +$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. +Also, if the \grammarterm{id-expression} occurs within +a static or explicit object member function, +the class member access is ill-formed. +\end{note} +This transformation does not apply in +the template definition context\iref{temp.dep.type}. +\begin{example} \begin{codeblock} -template -void f(Args... args) { - auto lm = [&, args...] { return g(args...); }; - lm(); -} +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} -\exitexample% -\indextext{expression!lambda|)}% -\indextext{expression!primary|)} +\end{example} -\rSec2[expr.prim.fold]{Fold expressions}% -\indextext{expression!fold|(} +\pnum +If an \grammarterm{id-expression} $E$ denotes +a variant member $M$ of an anonymous union\iref{class.union.anon} $U$: +\begin{itemize} +\item +If $U$ is a non-static data member, +$E$ refers to $M$ as a member of the lookup context of the terminal name of $E$ +(after any implicit transformation to +a class member access expression). +\begin{example} +\tcode{o.x} is interpreted as \tcode{o.$u$.x}, +where $u$ names the anonymous union member. +\end{example} +\item +Otherwise, $E$ is interpreted as a class member access\iref{expr.ref} +that designates the member subobject $M$ of +the anonymous union variable for $U$. +\begin{note} +Under this interpretation, $E$ no longer denotes a non-static data member. +\end{note} +\begin{example} +\tcode{N::x} is interpreted as \tcode{N::$u$.x}, +where $u$ names the anonymous union variable. +\end{example} +\end{itemize} \pnum -A fold expression performs a fold of a template parameter -pack~(\ref{temp.variadic}) over a binary operator. +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 +(after any implicit transformation (see above)) +in which the +object expression +refers to the member's class +or a class derived from +that class, or -\begin{bnf} -\nontermdef{fold-expression}\br - \terminal{(} cast-expression fold-operator \terminal{...} \terminal{)}\br - \terminal{(} \terminal{...} fold-operator cast-expression \terminal{)}\br - \terminal{(} cast-expression fold-operator \terminal{...} fold-operator cast-expression \terminal{)} -\end{bnf} +\item to form a pointer to member\iref{expr.unary.op}, or -\begin{bnf} -\nontermdef{fold-operator} \textnormal{one of}\br - \terminal{+ }\quad\terminal{- }\quad\terminal{* }\quad\terminal{/ }\quad\terminal{\% }\quad\terminal{\^{} }\quad\terminal{\& }\quad\terminal{| }\quad\terminal{\shl\ }\quad\terminal{\shr }\br - \terminal{+=}\quad\terminal{-=}\quad\terminal{*=}\quad\terminal{/=}\quad\terminal{\%=}\quad\terminal{\^{}=}\quad\terminal{\&=}\quad\terminal{|=}\quad\terminal{\shl=}\quad\terminal{\shr=}\quad\terminal{=}\br - \terminal{==}\quad\terminal{!=}\quad\terminal{< }\quad\terminal{> }\quad\terminal{<=}\quad\terminal{>=}\quad\terminal{\&\&}\quad\terminal{||}\quad\terminal{, }\quad\terminal{.* }\quad\terminal{->*} -\end{bnf} +\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} +struct S { + int m; +}; +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 -\indextext{fold!unary}% -An expression of the form -\tcode{(...} \placeholder{op} \tcode{e)} -where \placeholder{op} is a \grammarterm{fold-operator} -is called a \defn{unary left fold}. -An expression of the form -\tcode{(e} \placeholder{op} \tcode{...)} -where \placeholder{op} is a \grammarterm{fold-operator} -is called a \defn{unary right fold}. -Unary left folds and unary right folds -are collectively called \defnx{unary folds}{unary fold}. -In a unary fold, -the \grammarterm{cast-expression} -shall contain an unexpanded parameter pack~(\ref{temp.variadic}). +A \grammarterm{splice-expression} that designates a direct base class relationship +shall appear only as the second operand of a class member access. \pnum -\indextext{fold!binary}% -An expression of the form -\tcode{(e1} \placeholder{op1} \tcode{...} \placeholder{op2} \tcode{e2)} -where \placeholder{op1} and \placeholder{op2} are \grammarterm{fold-operator}{s} -is called a \defn{binary fold}. -In a binary fold, -\placeholder{op1} and \placeholder{op2} -shall be the same \grammarterm{fold-operator}, -and either \tcode{e1} -shall contain an unexpanded parameter pack -or \tcode{e2} -shall contain an unexpanded parameter pack, -but not both. -If \tcode{e2} contains an unexpanded parameter pack, -the expression is called a \defn{binary left fold}. -If \tcode{e1} contains an unexpanded parameter pack, -the expression is called a \defn{binary right fold}. -\enterexample +For an \grammarterm{id-expression} that denotes an overload set, +overload resolution is performed +to select a unique function\iref{over.match,over.over}. +\begin{note} +A program cannot refer to a function +with a trailing \grammarterm{requires-clause} +whose \grammarterm{constraint-expression} is not satisfied, +because such functions are never selected by overload resolution. +\begin{example} \begin{codeblock} -template -bool f(Args ...args) { - return (true && ... && args); // OK -} +template struct A { + static void f(int) requires false; +}; -template -bool f(Args ...args) { - return (args + ... + args); // error: both operands contain unexpanded parameter packs +void g() { + A::f(0); // error: cannot call \tcode{f} + void (*p1)(int) = A::f; // error: cannot take the address of \tcode{f} + decltype(A::f)* p2 = nullptr; // error: the type \tcode{decltype(A::f)} is invalid } \end{codeblock} -\exitexample -\indextext{expression!fold|)} - -\rSec1[expr.post]{Postfix expressions}% -\indextext{expression!postfix|(} - -\pnum -Postfix expressions group left-to-right. - -\begin{bnf} -\nontermdef{postfix-expression}\br - primary-expression\br - postfix-expression \terminal{[} expression \terminal{]}\br - postfix-expression \terminal{[} braced-init-list \terminal{]}\br - postfix-expression \terminal{(} expression-list\opt \terminal{)}\br - simple-type-specifier \terminal{(} expression-list\opt \terminal{)}\br - typename-specifier \terminal{(} expression-list\opt \terminal{)}\br - simple-type-specifier braced-init-list\br - typename-specifier braced-init-list\br - postfix-expression \terminal{. template}\opt id-expression\br - postfix-expression \terminal{-> template}\opt id-expression\br - postfix-expression \terminal{.} pseudo-destructor-name\br - postfix-expression \terminal{->} pseudo-destructor-name\br - postfix-expression \terminal{++}\br - postfix-expression \terminal{-{-}}\br - \terminal{dynamic_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{static_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{reinterpret_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{const_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{typeid (} expression \terminal{)}\br - \terminal{typeid (} type-id \terminal{)} -\end{bnf} - - -\begin{bnf} -\nontermdef{expression-list}\br - initializer-list -\end{bnf} +In each case, the constraints of \tcode{f} are not satisfied. +In the declaration of \tcode{p2}, +those constraints need to be satisfied +even though +\tcode{f} is an unevaluated operand\iref{term.unevaluated.operand}. +\end{example} +\end{note} +\rSec3[expr.prim.id.unqual]{Unqualified names} \begin{bnf} -\nontermdef{pseudo-destructor-name}\br - nested-name-specifier\opt type-name \terminal{::\,\tilde} type-name\br - nested-name-specifier \terminal{template} simple-template-id \terminal{::\,\tilde} type-name\br - \terminal{\tilde} type-name\br - \terminal{\tilde} decltype-specifier +\nontermdef{unqualified-id}\br + identifier\br + operator-function-id\br + conversion-function-id\br + literal-operator-id\br + \terminal{\~} type-name\br + \terminal{\~} computed-type-specifier\br + template-id \end{bnf} \pnum -\enternote The \tcode{>} token following the -\nonterminal{type-id} in a \tcode{dynamic_cast}, -\tcode{static_cast}, \tcode{reinterpret_cast}, or -\tcode{const_cast} may be the product of replacing a -\tcode{>{>}} token by two consecutive \tcode{>} -tokens~(\ref{temp.names}).\exitnote +\indextext{identifier}% +An \grammarterm{identifier} is only +an \grammarterm{id-expression} if it has +been suitably declared\iref{dcl} +or if it appears as part of a \grammarterm{declarator-id}\iref{dcl.decl}. +\begin{note} +For \grammarterm{operator-function-id}{s}, see~\ref{over.oper}; for +\grammarterm{conversion-function-id}{s}, see~\ref{class.conv.fct}; for +\grammarterm{literal-operator-id}{s}, see~\ref{over.literal}; for +\grammarterm{template-id}{s}, see~\ref{temp.names}. +A \grammarterm{type-name} or \grammarterm{computed-type-specifier} +prefixed by \tcode{\~} denotes the destructor of the type so named; +see~\ref{expr.prim.id.dtor}. +\end{note} -\rSec2[expr.sub]{Subscripting} +\pnum +A \defn{component name} of an \grammarterm{unqualified-id} $U$ is +\begin{itemize} +\item +$U$ if it is a name or +\item +the component name of +the \grammarterm{template-id} or \grammarterm{type-name} of $U$, if any. +\end{itemize} +\begin{note} +Other constructs that contain names to look up can have several +component names\iref{expr.prim.id.qual,dcl.type.simple,dcl.type.elab, +dcl.mptr,namespace.udecl,temp.param,temp.names,temp.res}. +\end{note} +The \defnadj{terminal}{name} of a construct is +the component name of that construct that appears lexically last. \pnum -\indextext{operator!subscripting}% -\indextext{\idxcode{[]}|see{operator, subscripting}}% -A postfix expression followed by an expression in square brackets is a -postfix expression. One of the expressions shall have the type ``array of -\tcode{T}'' or ``pointer -to \tcode{T}'' and the other shall have unscoped enumeration or integral type. -The result is of type ``\tcode{T}.'' -\indextext{type!incomplete}% -The type ``\tcode{T}'' shall be a completely-defined object type.\footnote{This -is true even if the subscript operator is used in the following common idiom: -\tcode{\&x[0]}.} -The expression \tcode{E1[E2]} is identical (by definition) to -\tcode{*((E1)+(E2))} -\enternote -see~\ref{expr.unary} and~\ref{expr.add} for details of \tcode{*} and -\tcode{+} and~\ref{dcl.array} for details of arrays. -\exitnote, except that in the case of an array operand, the result is an lvalue -if that operand is an lvalue and an xvalue otherwise. +The result is the entity denoted by +the \grammarterm{unqualified-id}\iref{basic.lookup.unqual}. \pnum -A \grammarterm{braced-init-list} shall not be used with the built-in subscript operator. +If +\begin{itemize} +\item +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 +that would be declared for such a capture +in the object parameter\iref{dcl.fct} of the function call operator of $E$. +\begin{note} +If $E$ is not declared \keyword{mutable}, +the type of such an identifier will typically be \keyword{const} qualified. +\end{note} + +\begin{example} +\begin{codeblock} +void f() { + float x, &r = x; -\rSec2[expr.call]{Function call} + [=]() -> decltype((x)) { // lambda returns \tcode{float const\&} because this lambda is not \tcode{mutable} and + // \tcode{x} is an lvalue + decltype(x) y1; // \tcode{y1} has type \tcode{float} + decltype((x)) y2 = y1; // \tcode{y2} has type \tcode{float const\&} + decltype(r) r1 = y1; // \tcode{r1} has type \tcode{float\&} + decltype((r)) r2 = y2; // \tcode{r2} has type \tcode{float const\&} + return y2; + }; -\pnum -\indextext{expression!function~call}% -\indextext{operator!function~call}% -\indextext{\idxcode{()}|see{operator, function~call}}% -A function call is a postfix expression followed by parentheses -containing a possibly empty, comma-separated list of -\grammarterm{initializer-clause}{s} which -constitute the arguments to the function. The postfix expression shall -have function type or pointer to function type. -For a call to a non-member function or to a static member function, -the postfix expression shall be either an lvalue that refers to a -function (in which case the function-to-pointer standard -conversion~(\ref{conv.func}) is suppressed on the postfix expression), -or it shall have pointer to function type. Calling a function through an -expression whose function type has a language linkage that is different -from the language linkage of the function type of the called function's -definition is undefined~(\ref{dcl.link}). For a call to a non-static -member function, -the postfix expression shall be an -implicit~(\ref{class.mfct.non-static},~\ref{class.static}) or explicit -class member access~(\ref{expr.ref}) whose \grammarterm{id-expression} is a -function member name, or a pointer-to-member -expression~(\ref{expr.mptr.oper}) selecting a function member; the call is as a member of -the class object referred to by the -object expression. In the case of an implicit class -member access, the implied object is the one pointed to by \tcode{this}. -\enternote -a member function call of the form \tcode{f()} is interpreted as -\tcode{(*this).f()} (see~\ref{class.mfct.non-static}). -\exitnote -If a function or member function name is used, the name can be -overloaded (Clause~\ref{over}), in which case the appropriate function -shall be selected according to the rules in~\ref{over.match}. If the selected -function is non-virtual, or if the \grammarterm{id-expression} in the class -member access expression is a \grammarterm{qualified-id}, that function is -called. Otherwise, its final overrider~(\ref{class.virtual}) in the dynamic type -of the object expression is called; such a call is referred to as a -\term{virtual function call}. -\enternote -the dynamic type is the type of the object referred to by the -current value of the object expression. \ref{class.cdtor}~describes the -behavior of virtual function calls when the object expression -refers to -an object under construction or destruction. -\exitnote + [=](decltype((x)) y) { + decltype((x)) z = x; // OK, \tcode{y} has type \tcode{float\&}, \tcode{z} has type \tcode{float const\&} + }; -\pnum -\enternote -If a function or member function name is used, and name -lookup~(\ref{basic.lookup}) does not find a declaration of that name, -the program is ill-formed. No function is implicitly declared by such a -call. -\exitnote + [=] { + [](decltype((x)) y) {}; // OK, lambda takes a parameter of type \tcode{float const\&} + + [x=1](decltype((x)) y) { + decltype((x)) z = x; // OK, \tcode{y} has type \tcode{int\&}, \tcode{z} has type \tcode{int const\&} + }; + }; +} +\end{codeblock} +\end{example} \pnum -If the \grammarterm{postfix-expression} designates a destructor~(\ref{class.dtor}), -the type of the function call expression is \tcode{void}; otherwise, the -type of the function call expression is the return type of the -statically chosen function (i.e., ignoring the \tcode{virtual} keyword), -even if the type of the function actually called is different. -\indextext{type!incomplete}% -This return type shall be an object type, a reference type or \cv{} -\tcode{void}. +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 -\indextext{function~argument|see{argument}}% -\indextext{function~parameter|see{parameter}}% -\indextext{initialization!parameter}% -When a function is called, each parameter~(\ref{dcl.fct}) shall be -initialized~(\ref{dcl.init},~\ref{class.copy},~\ref{class.ctor}) with -its corresponding argument. -\enternote Such initializations are indeterminately sequenced -with respect to each other~(\ref{intro.execution}) \exitnote -If the function is a non-static member -function, the \tcode{this} parameter of the function~(\ref{class.this}) -shall be initialized with a pointer to the object of the call, converted -as if by an explicit type conversion~(\ref{expr.cast}). -\enternote -There is no access or ambiguity checking on this conversion; the access -checking and disambiguation are done as part of the (possibly implicit) -class member access operator. -See~\ref{class.member.lookup},~\ref{class.access.base}, -and~\ref{expr.ref}. -\exitnote -When a function is called, the parameters that have object type shall -have completely-defined object type. -\enternote -this still allows a parameter to be a pointer or reference to an -incomplete class type. However, it prevents a passed-by-value parameter -to have an incomplete class type. -\exitnote -During the initialization of a parameter, an implementation may avoid -the construction of extra temporaries by combining the conversions on -the associated argument and/or the construction of temporaries with the -initialization of the parameter (see~\ref{class.temporary}). The -lifetime of a parameter ends when the function in which it is defined -returns. The initialization and destruction of each parameter occurs -within the context of the calling function. -\enterexample -the access of the constructor, conversion functions or destructor is -checked at the point of call in the calling function. If a constructor -or destructor for a function parameter throws an exception, the search -for a handler starts in the scope of the calling function; in -particular, if the function called has a \grammarterm{function-try-block} -(Clause~\ref{except}) with a handler that could handle the exception, -this handler is not considered. -\exitexample -The value of a function call is the value returned by the called -function except in a virtual function call if the return type of the -final overrider is different from the return type of the statically -chosen function, the value returned from the final overrider is -converted to the return type of the statically chosen function. +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 -\enternote -\indextext{type~checking!argument}% -\indextext{function~call}% -\indextext{argument~passing}% -\indextext{value!call~by}% -\indextext{reference!call~by}% -\indextext{argument!reference}% -a function can change the values of its non-const parameters, but these -changes cannot affect the values of the arguments except where a -parameter is of a reference type~(\ref{dcl.ref}); if the reference is to -a const-qualified type, \tcode{const_cast} is required to be used to -cast away the constness in order to modify the argument's value. Where a -parameter is of \tcode{const} reference type a temporary object is -introduced if -needed~(\ref{dcl.type},~\ref{lex.literal},~\ref{lex.string},~\ref{dcl.array},~\ref{class.temporary}). -In addition, it is possible to modify the values of nonconstant objects through -pointer parameters. -\exitnote +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 -\indextext{declaration!ellipsis~in function}% -\indextext{parameter~list!variable}% -A function can be declared to accept fewer arguments (by declaring default -arguments~(\ref{dcl.fct.default})) or more arguments (by using the ellipsis, -\tcode{...}, or a function parameter pack~(\ref{dcl.fct})) than the number of -parameters in the function definition~(\ref{dcl.fct.def}). -\enternote -this implies that, except where the ellipsis (\tcode{...}) or a function -parameter pack is used, a parameter is available for each argument. -\exitnote +\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 -\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}~(\ref{support.runtime}). -\enternote This paragraph does not apply to arguments passed to a function parameter pack. -Function parameter packs are expanded during template instantiation~(\ref{temp.variadic}), -thus each such argument has a corresponding parameter when a function template -specialization is actually called. \exitnote -The -lvalue-to-rvalue~(\ref{conv.lval}), array-to-pointer~(\ref{conv.array}), -and function-to-pointer~(\ref{conv.func}) standard conversions are -performed on the argument expression. -An argument that has (possibly cv-qualified) type \tcode{std::nullptr_t} is converted -to type \tcode{void*}~(\ref{conv.ptr}). -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 of class type (Clause~\ref{class}) having a non-trivial -copy constructor, a non-trivial move constructor, -or a -non-trivial destructor, with no corresponding parameter, is conditionally-supported with -\impldef{passing argument of class type through ellipsis} semantics. If the argument has -integral or enumeration type that is subject to the integral -promotions~(\ref{conv.prom}), or a floating point type that is subject to the floating -point promotion~(\ref{conv.fpprom}), the value of the argument is converted to the -promoted type before the call. These promotions are referred to as the \term{default -argument promotions}. - -\pnum -\indextext{evaluation!order~of argument}% -\indextext{evaluation!unspecified order~of function~call}% -\enternote -The evaluations of the postfix expression and of the arguments -are all unsequenced relative to one another. -\indextext{evaluation!unspecified order~of argument}% -All side effects of -argument evaluations are sequenced before the function is -entered (see~\ref{intro.execution}). -\exitnote +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 -\indextext{function~call!recursive}% -Recursive calls are permitted, except to the \tcode{main} -function~(\ref{basic.start.main}). +In all other cases, the type of the expression is the type of the entity. \pnum -A function call is an lvalue -if the result type is an lvalue reference type or an rvalue reference to function type, -an xvalue if the result type is an rvalue reference to object type, and a prvalue -otherwise. +\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 -If a function call is a prvalue of object type: +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 function call is either -\begin{itemize} -\item the operand of a \grammarterm{decltype-specifier} or -\item the right operand of a comma operator that is the operand of a -\grammarterm{decltype-specifier}, -\end{itemize} -a temporary object is not introduced for the prvalue. The type of the prvalue -may be incomplete. \enternote as a result, storage is not allocated for the -prvalue and it is not destroyed; thus, a class type is not instantiated as a -result of being the type of a function call in this context. This is true -regardless of whether the expression uses function call notation or operator -notation~(\ref{over.match.oper}). \exitnote \enternote unlike the rule for -a \grammarterm{decltype-specifier} that considers whether an \grammarterm{id-expression} -is parenthesized~(\ref{dcl.type.simple}), parentheses have no special meaning -in this context. \exitnote - -\item otherwise, the type of the prvalue shall be complete. +\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} -\rSec2[expr.type.conv]{Explicit type conversion (functional notation)} +\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 -\indextext{expression!cast} -\indextext{explicit~type~conversion|see{casting}}% -\indextext{type~conversion,~explicit|see{casting}}% -\indextext{conversion~explicit~type|see{casting}}% -\indextext{casting}% -A \grammarterm{simple-type-specifier}~(\ref{dcl.type.simple}) or -\grammarterm{typename-specifier}~(\ref{temp.res}) followed by a -parenthesized \grammarterm{expression-list} constructs a value of the -specified type given the expression list. If the expression list is a -single expression, the type conversion expression is equivalent (in -definedness, and if defined in meaning) to the corresponding cast -expression~(\ref{expr.cast}). -\indextext{type!incomplete}% -If the type specified is a class type, the -class type shall be complete. If the expression list specifies more than -a single value, the type shall be a class with a suitably declared -constructor~(\ref{dcl.init},~\ref{class.ctor}), and the expression -\tcode{T(x1, x2, ...)} is equivalent in effect to the declaration -\tcode{T t(x1, x2, ...);} for some invented temporary variable -\tcode{t}, with the result being the value of \tcode{t} as a prvalue. - -\pnum -The expression \tcode{T()}, where \tcode{T} is a -\grammarterm{simple-type-specifier} or \grammarterm{typename-specifier} for a non-array complete object -type or the (possibly cv-qualified) \tcode{void} type, creates a prvalue of the -specified type, whose value is that produced by -value-initializing~(\ref{dcl.init}) an object of type \tcode{T}; no -initialization is done for the \tcode{void()} case. -\enternote -if \tcode{T} is a non-class type that is cv-qualified, the -\grammarterm{cv-qualifier}{s} are discarded when determining the type of the -resulting prvalue (Clause~\ref{expr}). -\exitnote - -\pnum -Similarly, a \grammarterm{simple-type-specifier} or -\grammarterm{typename-specifier} followed by a \grammarterm{braced-init-list} -creates a temporary object of the specified type -direct-list-initialized~(\ref{dcl.init.list}) with the specified -\grammarterm{braced-init-list}, and its value is that temporary object as a -prvalue. - -\rSec2[expr.pseudo]{Pseudo destructor call} - -\pnum -\indextext{expression!pseudo-destructor~call} -\indextext{call!pseudo~destructor}% -\indextext{pseudo-destructor-name}% -The use of a \grammarterm{pseudo-destructor-name} after a dot \tcode{.} or -arrow \tcode{->} operator represents the destructor for the non-class -type denoted by \grammarterm{type-name} or \grammarterm{decltype-specifier}. -The result shall only be used as the -operand for the function call operator \tcode{()}, and the result of -such a call has type \tcode{void}. The only effect is the evaluation of -the \grammarterm{postfix-expression} before the dot or arrow. - -\pnum -The left-hand side of the dot operator shall be of scalar type. The -left-hand side of the arrow operator shall be of pointer to scalar type. -This scalar type is the object type. The \cvqual{cv}-unqualified -versions of the object type and of the type designated by the -\grammarterm{pseudo-destructor-name} shall be the same type. Furthermore, -the two \grammarterm{type-name}{s} in a \grammarterm{pseudo-destructor-name} of -the form +An \defnadj{implicitly movable}{entity} is +a variable with automatic storage duration +that is either a non-volatile object or +an rvalue reference to a non-volatile object type. +An \grammarterm{id-expression} or +\grammarterm{splice-expression}\iref{expr.prim.splice} +is \defn{move-eligible} if +\begin{itemize} +\item +it designates an implicitly movable entity, +\item +it is the (possibly parenthesized) +operand of a \tcode{return}\iref{stmt.return} or +\keyword{co_return}\iref{stmt.return.coroutine} statement or +of a \grammarterm{throw-expression}\iref{expr.throw}, and +\item +each intervening scope between +the declaration of the entity and +the innermost enclosing scope of the 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} -\begin{ncbnf} -nested-name-specifier\opt type-name \terminal{::\,\tilde} type-name -\end{ncbnf} +\rSec3[expr.prim.id.qual]{Qualified names} -shall designate the same scalar type. +\indextext{operator!scope resolution}% +\indextext{\idxcode{::}|see{operator, scope resolution}}% +% +\begin{bnf} +\nontermdef{qualified-id}\br + nested-name-specifier \opt{\keyword{template}} unqualified-id +\end{bnf} -\rSec2[expr.ref]{Class member access} +\indextext{operator!scope resolution}% +\indextext{name hiding}% +% +\begin{bnf} +\nontermdef{nested-name-specifier}\br + \terminal{::}\br + 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{expression!class~member~access}% -\indextext{access control!class member}% -\indextext{syntax!class~member}% -\indextext{semantics!class~member}% -\indextext{operator!class~member~access}% -\indextext{\idxcode{.}|see{operator, class~member~access}}% -\indextext{dot~operator|see{operator, class~member~access}}% -\indextext{operator!class~member~access}% -\indextext{\idxcode{->}|see{operator, class~member~access}}% -\indextext{arrow~operator|see{operator, class~member~access}}% -A postfix expression followed by a dot \tcode{.} or an arrow \tcode{->}, -optionally followed by the keyword -\tcode{template}~(\ref{temp.names}), and then followed by an -\grammarterm{id-expression}, is a postfix expression. The postfix -expression before the dot or arrow is evaluated;\footnote{If the class member -access expression is evaluated, the subexpression evaluation happens even if the -result is unnecessary to determine -the value of the entire postfix expression, for example if the -\grammarterm{id-expression} denotes a static member.} -the result of that evaluation, together with the -\grammarterm{id-expression}, determines the result of the entire postfix -expression. +\indextext{component name}% +The component names of a \grammarterm{qualified-id} are those of +its \grammarterm{nested-name-specifier} and \grammarterm{unqualified-id}. +The component names of a \grammarterm{nested-name-specifier} are +its \grammarterm{identifier} (if any) and those of its +\grammarterm{type-name}, +\grammarterm{namespace-name}, +\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 -\indextext{type!incomplete}% -For the first option (dot) the first expression -shall have complete class type. -For the second option (arrow) the first expression -shall have pointer to complete class 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).\footnote{Note that -\tcode{(*(E1))} is an lvalue.} -In either case, the -\grammarterm{id-expression} shall name a member of the class or of one of -its base classes. -\enternote -because the name of a class is inserted in its class scope -(Clause~\ref{class}), the name of a class is also considered a nested -member of that class. -\exitnote -\enternote -\ref{basic.lookup.classref} describes how names are looked up after the -\tcode{.} and \tcode{->} operators. -\exitnote +A \grammarterm{nested-name-specifier} is \defn{declarative} if it is part of +\begin{itemize} +\item +a \grammarterm{class-head-name}\iref{class.pre}, +\item +an \grammarterm{enum-head-name}\iref{dcl.enum}, +\item +a \grammarterm{qualified-id} +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} 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 -Abbreviating \term{postfix-expression.id-expression} -as \tcode{E1.E2}, -\tcode{E1} is called the \defn{object expression}. The -type and value category of \tcode{E1.E2} are determined as follows. -In the remainder of~\ref{expr.ref}, \cvqual{cq} represents either -\tcode{const} or the absence of \tcode{const} and \cvqual{vq} represents -either \tcode{volatile} or the absence of \tcode{volatile}. \cvqual{cv} -represents an arbitrary set of cv-qualifiers, as defined -in~\ref{basic.type.qualifier}. +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} +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$ +that involves a template parameter, +let $T$ be the template nominated by $N$ without $A$. +$T$ shall be a class template. +\begin{itemize} +\item +If $A$ is the template argument list\iref{temp.arg} of +the corresponding \grammarterm{template-head} $H$\iref{temp.mem}, +$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$ 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} +\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 -If \tcode{E2} is declared to have type ``reference to \tcode{T},'' then -\tcode{E1.E2} is an lvalue; the type of \tcode{E1.E2} is \tcode{T}. -Otherwise, one of the following rules applies. +A \grammarterm{qualified-id} shall not be of the form +\grammarterm{nested-name-specifier} \opt{\keyword{template}} \tcode{\~} +\grammarterm{computed-type-specifier} +nor of the form +\grammarterm{computed-type-specifier} \tcode{::} \tcode{\~} \grammarterm{type-name}. + +\pnum +The result of a \grammarterm{qualified-id} $Q$ is +the entity it denotes\iref{basic.lookup.qual}. +\pnum +If $Q$ appears +in the predicate of a contract assertion $C$\iref{basic.contract} +and the entity is \begin{itemize} -\item If \tcode{E2} is 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 +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}. -\item If \tcode{E2} is 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 named -member of the object designated by the first expression. 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 -\cvqual{vq1} and \cvqual{vq2}; that is, if \cvqual{vq1} or \cvqual{vq2} -is \tcode{volatile}, then \cvqual{vq12} is \tcode{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 -\tcode{const}, then \cvqual{cq12} is \tcode{const}. If \tcode{E2} is -declared to be a \tcode{mutable} member, then the type of \tcode{E1.E2} -is ``\cvqual{vq12} \tcode{T}''. If \tcode{E2} is not declared to be a -\tcode{mutable} member, then the type of \tcode{E1.E2} is -``\cvqual{cq12} \cvqual{vq12} \tcode{T}''. -\item If \tcode{E2} is a (possibly overloaded) member function, function -overload resolution~(\ref{over.match}) is used to determine whether -\tcode{E1.E2} refers to a static or a non-static member function. +\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 If it refers to a static member function and the type of -\tcode{E2} is ``function of parameter-type-list returning \tcode{T}'', -then \tcode{E1.E2} is an lvalue; the expression designates the static -member function. The type of \tcode{E1.E2} is the same type as that of -\tcode{E2}, namely ``function of parameter-type-list returning -\tcode{T}''. - -\item Otherwise, if \tcode{E1.E2} refers to a non-static member -function and the type of \tcode{E2} is ``function of -parameter-type-list \cvqual{cv} \grammarterm{ref-qualifier\opt} returning \tcode{T}'', then -\tcode{E1.E2} is a prvalue. The expression designates a -non-static member function. The expression can be used only as the -left-hand operand of a member function call~(\ref{class.mfct}). -\enternote Any redundant set of parentheses surrounding the expression -is ignored~(\ref{expr.prim}). \exitnote The type of \tcode{E1.E2} is -``function of parameter-type-list \cvqual{cv} returning \tcode{T}''. +\item +a function other than a non-static member function, +\item +a non-static member function +if $Q$ is the operand of a unary \tcode{\&} operator, +\item +a variable, +\item +a structured binding\iref{dcl.struct.bind}, or +\item +a data member, \end{itemize} +and a prvalue otherwise. -\item If \tcode{E2} is a nested type, the expression \tcode{E1.E2} is -ill-formed. +\rSec3[expr.prim.pack.index]{Pack indexing expression} -\item If \tcode{E2} is a member enumerator and the type of \tcode{E2} -is \tcode{T}, the expression \tcode{E1.E2} is a prvalue. The type of -\tcode{E1.E2} is \tcode{T}. -\end{itemize} +\begin{bnf} +\nontermdef{pack-index-expression}\br + id-expression \terminal{...} \terminal{[} constant-expression \terminal{]} +\end{bnf} \pnum -If \tcode{E2} is a non-static data member or a non-static member -function, the program is ill-formed if the class of which \tcode{E2} is -directly a member is an ambiguous base~(\ref{class.member.lookup}) of -the naming class~(\ref{class.access.base}) of \tcode{E2}. -\enternote -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}. -\exitnote - -\rSec2[expr.post.incr]{Increment and decrement} +The \grammarterm{id-expression} $P$ in a \grammarterm{pack-index-expression} +shall be an \grammarterm{identifier} that denotes a pack. \pnum -\indextext{expression!increment}% -\indextext{operator!increment}% -\indextext{\idxcode{++}|see{operator, increment}}% -\indextext{postfix~\tcode{++}}% -The value of a postfix \tcode{++} expression is the value of its -operand. -\enternote -the value obtained is a copy of the original value -\exitnote -The operand shall be a modifiable lvalue. The type of the operand shall -be an arithmetic type or a pointer to a complete object type. The value -of the operand object is modified by adding \tcode{1} to it, -\indextext{increment!\idxcode{bool}}% -\indextext{deprecated~features}% -unless the object is of type \tcode{bool}, in which case it is set to -\tcode{true}. -\enternote -this use is deprecated, see Annex~\ref{depr}. -\exitnote -The -\indextext{value computation}% -value computation of the \tcode{++} expression is sequenced before the -modification of the operand object. With respect to an -indeterminately-sequenced function call, the operation of postfix -\tcode{++} is -a single evaluation. -\enternote -Therefore, a function call shall not intervene between the -lvalue-to-rvalue conversion and the side effect associated with any -single postfix ++ operator. -\exitnote -The result is a prvalue. The type of the result is the cv-unqualified -version of the type of the operand. -If the operand is a bit-field that cannot represent the incremented value, the -resulting value of the bit-field is -\impldef{value of bit-field that cannot represent!incremented value}. -See also~\ref{expr.add} -and~\ref{expr.ass}. +The \grammarterm{constant-expression} shall be +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$)}$. \pnum -\indextext{expression!decrement}% -\indextext{operator!decrement}% -\indextext{\idxcode{\dcr}|see{operator, decrement}}% -\indextext{postfix~\tcode{\dcr}}% -The operand of postfix \tcode{\dcr} is decremented analogously to the -postfix \tcode{++} operator, except that the operand shall not be of -type \tcode{bool}. -\enternote -For prefix increment and decrement, see~\ref{expr.pre.incr}. -\exitnote - -\rSec2[expr.dynamic.cast]{Dynamic cast} +A \grammarterm{pack-index-expression} is a pack expansion\iref{temp.variadic}. \pnum -\indextext{expression!dynamic~cast}% -\indextext{cast!dynamic}% -The result of the expression \tcode{dynamic_cast(v)} is the result of -converting the expression \tcode{v} to type \tcode{T}. -\indextext{type!incomplete}% -\tcode{T} shall be a pointer or reference to a complete class type, or -``pointer to \cvqual{cv} \tcode{void}.'' The \tcode{dynamic_cast} operator shall not cast -away constness~(\ref{expr.const.cast}). +\begin{note} +A \grammarterm{pack-index-expression} denotes +the $V^\text{th}$ element of the pack. +\end{note} -\pnum -If \tcode{T} is a pointer type, \tcode{v} shall be a prvalue of a -pointer to complete class type, and the result is a prvalue of type -\tcode{T}. If \tcode{T} is an lvalue reference type, \tcode{v} shall be -an lvalue of a complete class type, and the result is an lvalue of the -type referred to by \tcode{T}. If \tcode{T} is an rvalue reference type, -\tcode{v} shall be an expression having a complete class type, and the -result is an xvalue of the type referred to by \tcode{T}. +\rSec3[expr.prim.id.dtor]{Destruction} \pnum -If the type of \tcode{v} is the same as \tcode{T}, or it is -the same as \tcode{T} except that the class object type in \tcode{T} is -more cv-qualified than the class object type in \tcode{v}, the result is -\tcode{v} (converted if necessary). +\indextext{expression!destructor call}% +\indextext{expression!pseudo-destructor call}% +An \grammarterm{id-expression} that denotes the destructor of a type \tcode{T} +names the destructor of \tcode{T} +if \tcode{T} is a class type\iref{class.dtor}, +otherwise the \grammarterm{id-expression} is said +to name a \defn{pseudo-destructor}. \pnum -If the value of \tcode{v} is a null pointer value in the pointer case, -the result is the null pointer value of type \tcode{T}. +If the \grammarterm{id-expression} names a pseudo-destructor, +\tcode{T} shall be a scalar type and +the \grammarterm{id-expression} shall appear +as the right operand of a class member access\iref{expr.ref} that forms +the \grammarterm{postfix-expression} of a function call\iref{expr.call}. +\begin{note} +Such a call ends the lifetime of the object\iref{expr.call,basic.life}. +\end{note} \pnum -If \tcode{T} is ``pointer to \cvqual{cv1} \tcode{B}'' and \tcode{v} has -type ``pointer to \cvqual{cv2} \tcode{D}'' such that \tcode{B} is a base -class of \tcode{D}, the result is a pointer to the unique \tcode{B} -subobject of the \tcode{D} object pointed to by \tcode{v}. Similarly, if -\tcode{T} is ``reference to \cvqual{cv1} \tcode{B}'' and \tcode{v} has -type \cvqual{cv2} \tcode{D} such that \tcode{B} is a base class of -\tcode{D}, the result is the unique \tcode{B} subobject of the \tcode{D} -object referred to by \tcode{v}. -\footnote{The most derived object~(\ref{intro.object}) pointed or referred to by -\tcode{v} can contain other \tcode{B} objects as base classes, but these -are ignored.} -The result is an lvalue if \tcode{T} is an lvalue reference, or an -xvalue if \tcode{T} is an rvalue reference. In both the pointer and -reference cases, the program is ill-formed if \cvqual{cv2} has greater -cv-qualification than \cvqual{cv1} or if \tcode{B} is an inaccessible or -ambiguous base class of \tcode{D}. -\enterexample - +\begin{example} \begin{codeblock} -struct B { }; -struct D : B { }; -void foo(D* dp) { - B* bp = dynamic_cast(dp); // equivalent to \tcode{B* bp = dp;} +struct C { }; +void f() { + C * pc = new C; + using C2 = C; + pc->C::~C2(); // OK, destroys \tcode{*pc} + C().C::~C(); // undefined behavior: temporary of type \tcode{C} destroyed twice + using T = int; + 0 .T::~T(); // OK, no effect + 0.T::~T(); // error: \tcode{0.T} is a \grammarterm{user-defined-floating-point-literal}\iref{lex.ext} } \end{codeblock} -\exitexample - -\pnum -Otherwise, \tcode{v} shall be a pointer to or a glvalue of a polymorphic -type~(\ref{class.virtual}). +\end{example} -\pnum -If \tcode{T} is ``pointer to \cvqual{cv} \tcode{void},'' then the result -is a pointer to the most derived object pointed to by \tcode{v}. -Otherwise, a run-time check is applied to see if the object pointed or -referred to by \tcode{v} can be converted to the type pointed or -referred to by \tcode{T}. +\rSec2[expr.prim.lambda]{Lambda expressions}% -\pnum -If \tcode{C} is the class type to which \tcode{T} points or refers, the run-time -check logically executes as follows: +\rSec3[expr.prim.lambda.general]{General}% +\indextext{expression!lambda|(} -\begin{itemize} -\item If, in the most derived object pointed (referred) to by \tcode{v}, -\tcode{v} points (refers) to a \tcode{public} base class subobject of a -\tcode{C} object, and if only one object of type \tcode{C} is derived -from the subobject pointed (referred) to by \tcode{v} the result points (refers) to that \tcode{C} object. +\begin{bnf} +\nontermdef{lambda-expression}\br + lambda-introducer \opt{attribute-specifier-seq} lambda-declarator compound-statement\br + lambda-introducer \terminal{<} template-parameter-list \terminal{>} \opt{requires-clause} \opt{attribute-specifier-seq}\br + \bnfindent lambda-declarator compound-statement +\end{bnf} -\item Otherwise, if \tcode{v} points (refers) to a \tcode{public} base -class subobject of the most derived object, and the type of the most -derived object has a base class, of type \tcode{C}, that is unambiguous -and \tcode{public}, the result points (refers) to the -\tcode{C} subobject of the most derived object. +\begin{bnf} +\nontermdef{lambda-introducer}\br + \terminal{[} \opt{lambda-capture} \terminal{]} +\end{bnf} -\item Otherwise, the -run-time check \term{fails}. -\end{itemize} +\begin{bnf} +\nontermdef{lambda-declarator}\br + lambda-specifier-seq \opt{noexcept-specifier} \opt{attribute-specifier-seq} \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} \opt{function-contract-specifier-seq} +\end{bnf} -\pnum -The value of a failed cast to pointer type is the null pointer value of -the required result type. A failed cast to reference type throws -an exception~(\ref{except.throw}) of a type that would match a -handler~(\ref{except.handle}) of type \tcode{std::bad_cast}~(\ref{bad.cast}). +\begin{bnf} +\nontermdef{lambda-specifier}\br + \keyword{consteval}\br + \keyword{constexpr}\br + \keyword{mutable}\br + \keyword{static} +\end{bnf} -\indextext{\idxcode{bad_cast}}% -\indexlibrary{\idxcode{bad_cast}}% -\enterexample +\begin{bnf} +\nontermdef{lambda-specifier-seq}\br + lambda-specifier \opt{lambda-specifier-seq} +\end{bnf} +\pnum +A \grammarterm{lambda-expression} provides +a concise way to create a simple function object. +\begin{example} \begin{codeblock} -class A { virtual void f(); }; -class B { virtual void g(); }; -class D : public virtual A, private B { }; -void g() { - D d; - B* bp = (B*)&d; // cast needed to break protection - A* ap = &d; // public derivation, no cast needed - D& dr = dynamic_cast(*bp); // fails - ap = dynamic_cast(bp); // fails - bp = dynamic_cast(ap); // fails - ap = dynamic_cast(&d); // succeeds - bp = dynamic_cast(&d); // ill-formed (not a run-time check) -} - -class E : public D, public B { }; -class F : public E, public D { }; -void h() { - F f; - A* ap = &f; // succeeds: finds unique \tcode{A} - D* dp = dynamic_cast(ap); // fails: yields \tcode{0} - // \tcode{f} has two \tcode{D} subobjects - E* ep = (E*)ap; // ill-formed: cast from virtual base - E* ep1 = dynamic_cast(ap); // succeeds +#include +#include +void abssort(float* x, unsigned N) { + std::sort(x, x + N, [](float a, float b) { return std::abs(a) < std::abs(b); }); } \end{codeblock} -\exitexample -\enternote -\ref{class.cdtor} describes the behavior of a \tcode{dynamic_cast} -applied to an object under construction or destruction. -\exitnote +\end{example} -\rSec2[expr.typeid]{Type identification} +\pnum +A \grammarterm{lambda-expression} is a prvalue +whose result object is called the \defn{closure object}. +\begin{note} +A closure object behaves like a function +object\iref{function.objects}. +\end{note} + +\pnum +An ambiguity can arise +because a \grammarterm{requires-clause} can end in +an \grammarterm{attribute-specifier-seq}, +which collides with +the \grammarterm{attribute-specifier-seq} in \grammarterm{lambda-expression}. +In such cases, +any attributes are treated as +\grammarterm{attribute-specifier-seq} in \grammarterm{lambda-expression}. +\begin{note} +Such ambiguous cases cannot have valid semantics +because the constraint expression would not have type \keyword{bool}. +\begin{example} +\begin{codeblock} +auto x = [] requires T::operator int [[some_attribute]] (int) { } +\end{codeblock} +\end{example} +\end{note} + +\pnum +A \grammarterm{lambda-specifier-seq} +shall contain at most one of each \grammarterm{lambda-specifier} and +shall not contain both \keyword{constexpr} and \keyword{consteval}. +If the \grammarterm{lambda-declarator} contains +an explicit object parameter\iref{dcl.fct}, +then no \grammarterm{lambda-specifier} in the \grammarterm{lambda-specifier-seq} +shall be \keyword{mutable} or \keyword{static}. +The \grammarterm{lambda-specifier-seq} shall not contain +both \keyword{mutable} and \keyword{static}. +If the \grammarterm{lambda-specifier-seq} contains \keyword{static}, +there shall be no \grammarterm{lambda-capture}. +\begin{note} +The trailing \grammarterm{requires-clause} is described in \ref{dcl.decl}. +\end{note} + +\pnum +A \grammarterm{lambda-expression}{'s} \grammarterm{parameter-declaration-clause} +is the \grammarterm{parameter-declaration-clause} of +the \grammarterm{lambda-expression}{'s} \grammarterm{lambda-declarator}, if any, +or empty otherwise. +If the \grammarterm{lambda-declarator} +does not include a \grammarterm{trailing-return-type}, +it is considered to be \tcode{-> \keyword{auto}}. +\begin{note} +In that case, the return type is deduced from \keyword{return} statements +as described in \ref{dcl.spec.auto}. +\end{note} +\begin{example} +\begin{codeblock} +auto x1 = [](int i) { return i; }; // OK, return type is \tcode{int} +auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from \grammarterm{braced-init-list} +int j; +auto x3 = [&]()->auto&& { return j; }; // OK, return type is \tcode{int\&} +\end{codeblock} +\end{example} \pnum -\indextext{expression!type~identification}% -\indextext{\idxcode{typeid}}% -The result of a \tcode{typeid} expression is an lvalue of static type -\indextext{\idxcode{type_info}}% -\indexlibrary{\idxcode{type_info}}% -\tcode{const} \tcode{std::type_info}~(\ref{type.info}) and dynamic type \tcode{const} -\tcode{std::type_info} or \tcode{const} \term{name} where \term{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}.\footnote{The recommended name for such a class is -\tcode{extended_type_info}.} -The lifetime of the object referred to by the lvalue extends to the end -of the program. Whether or not the destructor is called for the -\tcode{std::type_info} object at the end of the program is unspecified. +A lambda is a \defn{generic lambda} +if the \grammarterm{lambda-expression} +has any generic parameter type placeholders\iref{dcl.spec.auto}, or +if the lambda has a \grammarterm{template-parameter-list}. +\begin{example} +\begin{codeblock} +auto x = [](int i, auto a) { return i; }; // OK, a generic lambda +auto y = [](this auto self, int i) { return i; }; // OK, a generic lambda +auto z = [](int i) { return i; }; // OK, a generic lambda +\end{codeblock} +\end{example} + +\rSec3[expr.prim.lambda.closure]{Closure types}% \pnum -When \tcode{typeid} is applied to a glvalue expression whose type is a -polymorphic class type~(\ref{class.virtual}), the result refers to a -\tcode{std::type_info} object representing the type of the most derived -object~(\ref{intro.object}) (that is, the dynamic type) to which the -glvalue refers. If the glvalue expression is obtained by applying the -unary \tcode{*} operator to a pointer\footnote{If \tcode{p} is an expression of -pointer type, then \tcode{*p}, -\tcode{(*p)}, \tcode{*(p)}, \tcode{((*p))}, \tcode{*((p))}, and so on -all meet this requirement.} -and the pointer is a null pointer value~(\ref{conv.ptr}), the -\tcode{typeid} expression throws an exception~(\ref{except.throw}) of -a type that would match a handler of type -\indextext{\idxcode{bad_typeid}}% -\indexlibrary{\idxcode{bad_typeid}}% -\tcode{std::bad_typeid} -exception~(\ref{bad.typeid}). +The type of a \grammarterm{lambda-expression} (which is also the type of the +closure object) is a unique, unnamed non-union class type, +called the \defn{closure type}, +whose properties are described below. \pnum -When \tcode{typeid} is applied to an expression other than a glvalue of -a polymorphic class type, the result refers to a \tcode{std::type_info} -object representing the static type of the expression. -Lvalue-to-rvalue~(\ref{conv.lval}), array-to-pointer~(\ref{conv.array}), -and function-to-pointer~(\ref{conv.func}) conversions are not applied to -the expression. -\indextext{type!incomplete}% -If the type of the expression is a class type, the class shall be -completely-defined. The expression is an unevaluated operand -(Clause~\ref{expr}). +The closure type is incomplete +until the end of its corresponding \grammarterm{compound-statement}. \pnum -When \tcode{typeid} is applied to a \grammarterm{type-id}, the result -refers to a \tcode{std::type_info} object representing the type of the -\grammarterm{type-id}. If the type of the \grammarterm{type-id} is a reference -to a possibly \cvqual{cv}-qualified type, the result of the -\tcode{typeid} expression refers to a \tcode{std::type_info} object -representing the \cvqual{cv}-unqualified referenced type. If the type of -the \grammarterm{type-id} is a class type or a reference to a class type, -the class shall be completely-defined. +The closure type is declared in the smallest block +scope, class scope, or namespace scope that contains the corresponding +\grammarterm{lambda-expression}. +\begin{note} +This determines the set of namespaces and +classes associated with the closure type\iref{basic.lookup.argdep}. The parameter +types of a \grammarterm{lambda-declarator} do not affect these associated namespaces and +classes. +\end{note} \pnum -If the type of the expression or \grammarterm{type-id} is a -cv-qualified type, the result of the \tcode{typeid} expression refers -to a \tcode{std::type_info} object representing the cv-unqualified +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 +is described below provided this does not alter the observable behavior of the program +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} + +An implementation shall not add members of rvalue reference type to the closure type. -\enterexample +\pnum +The closure type for a \grammarterm{lambda-expression} has a public +inline function call operator (for a non-generic lambda) or +function call operator template (for a generic lambda)\iref{over.call} +whose parameters and return type +are those of the \grammarterm{lambda-expression}{'s} +\grammarterm{parameter-declaration-clause} and \grammarterm{trailing-return-type} +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. +The trailing \grammarterm{requires-clause} of the function call operator +or operator template is the \grammarterm{requires-clause} +of the \grammarterm{lambda-declarator}, if any. +\begin{note} +The function call operator template for a generic lambda can be +an abbreviated function template\iref{dcl.fct}. +\end{note} +\begin{example} \begin{codeblock} -class D @\tcode{\{ /* ... */ \}}@; -D d1; -const D d2; +auto glambda = [](auto a, auto&& b) { return a < b; }; +bool b = glambda(3, 3.14); // OK -typeid(d1) == typeid(d2); // yields \tcode{true} -typeid(D) == typeid(const D); // yields \tcode{true} -typeid(D) == typeid(d2); // yields \tcode{true} -typeid(D) == typeid(const D&); // yields \tcode{true} -\end{codeblock} -\exitexample +auto vglambda = [](auto printer) { + return [=](auto&& ... ts) { // OK, \tcode{ts} is a function parameter pack + printer(std::forward(ts)...); -\pnum -If the header \tcode{}~(\ref{type.info}) is not included prior -to a use of \tcode{typeid}, the program is ill-formed. + return [=]() { + printer(ts ...); + }; + }; +}; +auto p = vglambda( [](auto v1, auto v2, auto v3) + { std::cout << v1 << v2 << v3; } ); +auto q = p(1, 'a', 3.14); // OK, outputs \tcode{1a3.14} +q(); // OK, outputs \tcode{1a3.14} + +auto fact = [](this auto self, int n) -> int { // OK, explicit object parameter + return (n <= 1) ? 1 : n * self(n-1); +}; +std::cout << fact(5); // OK, outputs 120 +\end{codeblock} +\end{example} \pnum -\enternote -\ref{class.cdtor} describes the behavior of \tcode{typeid} applied to an -object under construction or destruction. -\exitnote +Given a lambda with a \grammarterm{lambda-capture}, +the type of the explicit object parameter, if any, +of the lambda's function call operator +(possibly instantiated from a function call operator template) +shall be either: +\begin{itemize} +\item +the closure type, +\item +a class type publicly and unambiguously derived from the closure type, or +\item +a reference to a possibly cv-qualified such type. +\end{itemize} +\begin{example} +\begin{codeblock} +struct C { + template + C(T); +}; -\rSec2[expr.static.cast]{Static cast} +void func(int i) { + int x = [=](this auto&&) { return i; }(); // OK + int y = [=](this C) { return i; }(); // error + int z = [](this C) { return 42; }(); // OK +} +\end{codeblock} +\end{example} \pnum -\indextext{expression!static~cast}% -\indextext{cast!static}% -The result of the expression \tcode{static_cast(v)} is the result of -converting the expression \tcode{v} to type \tcode{T}. -\indextext{cast!static!lvalue}% -\indextext{cast!lvalue}% -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 \tcode{static_cast} operator shall not cast -away constness~(\ref{expr.const.cast}). +The function call operator or operator template is +a static member function or static member function template\iref{class.static.mfct} +if the \grammarterm{lambda-expression}'s +\grammarterm{parameter-declaration-clause} is followed by \keyword{static}. +Otherwise, it is +a non-static member function or member function template\iref{class.mfct.non.static} +that is declared +\keyword{const}\iref{class.mfct.non.static} if and only if the +\grammarterm{lambda-expression}'s \grammarterm{parameter-declaration-clause} is not +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} 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. +An \grammarterm{attribute-specifier-seq} in a \grammarterm{lambda-expression} +preceding a \grammarterm{lambda-declarator} +appertains to the corresponding function call operator or operator template. +The function call operator or any given operator template specialization +is a constexpr function if either +the corresponding \grammarterm{lambda-expression}{'s} +\grammarterm{parameter-declaration-clause} +is followed by \keyword{constexpr} or \keyword{consteval}, or +it is constexpr-suitable\iref{dcl.constexpr}. +It is an immediate function\iref{dcl.constexpr} +if the corresponding \grammarterm{lambda-expression}{'s} +\grammarterm{parameter-declaration-clause} is followed by \keyword{consteval}. +\begin{example} +\begin{codeblock} +auto ID = [](auto a) { return a; }; +static_assert(ID(3) == 3); // OK -\pnum -\indextext{cast!static!reference}% -\indextext{cast!reference}% -An lvalue of type ``\cvqual{cv1} \tcode{B},'' where \tcode{B} is a class -type, can be cast to type ``reference to \cvqual{cv2} \tcode{D},'' where -\tcode{D} is a class derived (Clause~\ref{class.derived}) from -\tcode{B}, if a valid standard conversion from ``pointer to \tcode{D}'' -to ``pointer to \tcode{B}'' exists~(\ref{conv.ptr}), \cvqual{cv2} is the -same cv-qualification as, or greater cv-qualification than, -\cvqual{cv1}, and \tcode{B} is neither a virtual base class of \tcode{D} -nor a base class of a virtual base class of \tcode{D}. The result has -type ``\cvqual{cv2} \tcode{D}.'' An xvalue of type -``\cvqual{cv1} \tcode{B}'' may be cast to type ``rvalue reference to -\cvqual{cv2} \tcode{D}'' with the same constraints as for an lvalue of -type ``\cvqual{cv1} \tcode{B}.'' If the object -of type ``\cvqual{cv1} \tcode{B}'' is actually a subobject of an object -of type \tcode{D}, the result refers to the enclosing object of type -\tcode{D}. Otherwise, the behavior is undefined. -\enterexample +struct NonLiteral { + NonLiteral(int n) : n(n) { } + int n; +}; +static_assert(ID(NonLiteral{3}).n == 3); // error +\end{codeblock} +\end{example} +\pnum +\begin{example} \begin{codeblock} -struct B { }; -struct D : public B { }; -D d; -B &br = d; - -static_cast(br); // produces lvalue to the original \tcode{d} object +auto monoid = [](auto v) { return [=] { return v; }; }; +auto add = [](auto m1) constexpr { + auto ret = m1(); + return [=](auto m2) mutable { + auto m1val = m1(); + auto plus = [=](auto m2val) mutable constexpr + { return m1val += m2val; }; + ret = plus(m2()); + return monoid(ret); + }; +}; +constexpr auto zero = monoid(0); +constexpr auto one = monoid(1); +static_assert(add(one)(zero)() == one()); // OK + +// Since \tcode{two} below is not declared \keyword{constexpr}, an evaluation of its \tcode{constexpr} member function call operator +// cannot perform an lvalue-to-rvalue conversion on one of its subobjects (that represents its capture) +// in a constant expression. +auto two = monoid(2); +assert(two() == 2); // OK, not a constant expression. +static_assert(add(one)(one)() == two()); // error: \tcode{two()} is not a constant expression +static_assert(add(one)(one)() == monoid(2)()); // OK \end{codeblock} -\exitexample +\end{example} \pnum -A glvalue, class prvalue, or array prvalue -of type ``\cvqual{cv1} \tcode{T1}'' can be cast to type ``rvalue -reference to \cvqual{cv2} \tcode{T2}'' if ``\cvqual{cv2} \tcode{T2}'' is -reference-compatible with ``\cvqual{cv1} -\tcode{T1}''~(\ref{dcl.init.ref}). If the value is not a bit-field, -the result refers to the object or the specified base class subobject -thereof; otherwise, the lvalue-to-rvalue conversion~(\ref{conv.lval}) -is applied to the bit-field and the resulting prvalue is used as the -\grammarterm{expression} of the \tcode{static_cast} for the remainder of this section. -If \tcode{T2} is an inaccessible (Clause~\ref{class.access}) or -ambiguous~(\ref{class.member.lookup}) base class of \tcode{T1}, -a program that necessitates such a cast is ill-formed. +\begin{note} +The function call operator or operator template can be constrained\iref{temp.constr.decl} +by a \grammarterm{type-constraint}\iref{temp.param}, +a \grammarterm{requires-clause}\iref{temp.pre}, +or a trailing \grammarterm{requires-clause}\iref{dcl.decl}. +\begin{example} +\begin{codeblock} +template concept C1 = @\commentellip@; +template concept C2 = @\commentellip@; +template concept C3 = @\commentellip@; + +auto f = [] requires C2 + (T1 a1, T1 b1, T2 a2, auto a3, auto a4) requires C3 { + // \tcode{T2} is constrained by a \grammarterm{type-constraint}. + // \tcode{T1} and \tcode{T2} are constrained by a \grammarterm{requires-clause}, and + // \tcode{T2} and the type of \tcode{a4} are constrained by a trailing \grammarterm{requires-clause}. +}; +\end{codeblock} +\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; -\pnum -An expression \tcode{e} can be explicitly converted to a type -\tcode{T} using a \tcode{static_cast} of the form -\tcode{static_cast(e)} if the declaration \tcode{T t(e);} is -well-formed, for some invented temporary variable -\tcode{t}~(\ref{dcl.init}). The effect of such an explicit conversion is -the same as performing the declaration and initialization and then using -the temporary variable as the result of the conversion. The expression -\tcode{e} is used as a glvalue if and -only if the initialization uses it as a glvalue. +void test() { + auto f1 = [=] pre(i > 0) {}; // OK, no local entities are captured. -\pnum -Otherwise, the \tcode{static_cast} shall perform one of the conversions -listed below. No other conversion shall be performed explicitly using a -\tcode{static_cast}. + 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. -\pnum -Any expression can be explicitly converted to type \cv\ -\tcode{void}, in which case it becomes a discarded-value -expression (Clause~\ref{expr}). -\enternote -however, if the value is in a temporary -object~(\ref{class.temporary}), the destructor for that -object is -not executed until the usual time, and the value of the object is -preserved for the purpose of executing the destructor. -\exitnote + 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; + }; -\pnum -The inverse of any standard conversion sequence (Clause~\ref{conv}) not containing an -lvalue-to-rvalue~(\ref{conv.lval}), -array-to-pointer~(\ref{conv.array}), -function-to-pointer~(\ref{conv.func}), -null pointer~(\ref{conv.ptr}), null member pointer~(\ref{conv.mem}), or -boolean~(\ref{conv.bool}) -conversion, can be performed explicitly using \tcode{static_cast}. A -program is ill-formed if it uses \tcode{static_cast} to perform the -inverse of an ill-formed standard conversion sequence. -\enterexample -\begin{codeblock} -struct B { }; -struct D : private B { }; -void f() { - static_cast((B*)0); // Error: B is a private base of D. - static_cast((int D::*)0); // Error: B is a private base of D. + 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} -\exitexample +\end{example} -\pnum -The lvalue-to-rvalue~(\ref{conv.lval}), -array-to-pointer~(\ref{conv.array}), and -function-to-pointer~(\ref{conv.func}) conversions are applied to the -operand. Such a \tcode{static_cast} is subject to the restriction that -the explicit conversion does not cast away -constness~(\ref{expr.const.cast}), and the following additional rules -for specific cases: \pnum -A value of a scoped enumeration type~(\ref{dcl.enum}) can be explicitly converted to an -integral type. When that type is \cv\ \tcode{bool}, the resulting value is -\tcode{false} if the original value is zero and \tcode{true} for all other -values. For the remaining integral types, the value is unchanged if the -original value can be represented by the -specified type. Otherwise, the resulting value is unspecified. -A value of a scoped enumeration type can also be explicitly converted to a -floating-point type; the result is the same as that of converting from the original -value to the floating-point type. +The closure type for a non-generic \grammarterm{lambda-expression} with no +\grammarterm{lambda-capture} +and no explicit object parameter\iref{dcl.fct} +whose constraints (if any) are satisfied +has a conversion function to pointer to +function with \Cpp{} language linkage\iref{dcl.link} having +the same parameter and return types as the closure type's function call operator. +The conversion is to ``pointer to \keyword{noexcept} function'' +if the function call operator +has a non-throwing exception specification. +If the function call operator is a static member function, +then the value returned by this conversion function is +a pointer to the function call operator. +Otherwise, the value returned by this conversion function +is a pointer to a function \tcode{F} that, when invoked, +has the same effect as invoking the closure type's function call operator +on a default-constructed instance of the closure type. +\tcode{F} is a constexpr function +if the function call operator is a constexpr function +and is an immediate function +if the function call operator is an immediate function. + +\pnum +For a generic lambda with no \grammarterm{lambda-capture} +and no explicit object parameter\iref{dcl.fct}, +the closure type has a +conversion function template to +pointer to function. The conversion function template has the same invented +template parameter list, and the pointer to function has the same +parameter types, as the function call operator template. The return type of +the pointer to function shall behave as if it were a +\grammarterm{decltype-specifier} denoting the return type of the corresponding +function call operator template specialization. \pnum -\indextext{enumeration~type!conversion~to}% -\indextext{enumeration~type!\idxcode{static_cast}!conversion~to}% -A value of integral or enumeration type can be explicitly converted to -a complete enumeration type. The value is unchanged if the original value is -within the range of the enumeration values~(\ref{dcl.enum}). Otherwise, -the behavior is undefined. -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~(\ref{conv.fpint}), and subsequently to -the enumeration type. +\begin{note} +If the generic lambda has no \grammarterm{trailing-return-type} or +the \grammarterm{trailing-return-type} contains a placeholder type, return type +deduction of the corresponding function call operator template specialization +has to be done. The corresponding specialization is that instantiation of the +function call operator template with the same template arguments as those +deduced for the conversion function template. Consider the following: +\begin{codeblock} +auto glambda = [](auto a) { return a; }; +int (*fp)(int) = glambda; +\end{codeblock} +The behavior of the conversion function of \tcode{glambda} above is like +that of the following conversion function: +\begin{codeblock} +struct Closure { + template auto operator()(T t) const { @\commentellip@ } + template static auto lambda_call_operator_invoker(T a) { + // forwards execution to \tcode{operator()(a)} and therefore has + // the same return type deduced + @\commentellip@ + } + template using fptr_t = + decltype(lambda_call_operator_invoker(declval())) (*)(T); -\pnum -\indextext{cast!base~class}% -\indextext{cast!derived~class}% -A prvalue of type ``pointer to \cvqual{cv1} \tcode{B},'' where \tcode{B} -is a class type, can be converted to a prvalue of type ``pointer to -\cvqual{cv2} \tcode{D},'' where \tcode{D} is a class derived -(Clause~\ref{class.derived}) from \tcode{B}, if a valid standard -conversion from ``pointer to \tcode{D}'' to ``pointer to \tcode{B}'' -exists~(\ref{conv.ptr}), \cvqual{cv2} is the same cv-qualification as, -or greater cv-qualification than, \cvqual{cv1}, and \tcode{B} is neither -a virtual base class of \tcode{D} nor a base class of a virtual base -class of \tcode{D}. The null pointer value~(\ref{conv.ptr}) is converted -to the null pointer value of the destination type. If the prvalue of type -``pointer to \cvqual{cv1} \tcode{B}'' points to a \tcode{B} that is -actually a 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. + template operator fptr_t() const + { return &lambda_call_operator_invoker; } +}; +\end{codeblock} +\end{note} -\pnum -\indextext{cast!pointer-to-member}% -A prvalue of type ``pointer to member of \tcode{D} of type \cvqual{cv1} -\tcode{T}'' can be converted to a prvalue of type ``pointer to member of -\tcode{B}'' of type \cvqual{cv2} \tcode{T}, where \tcode{B} is a base -class (Clause~\ref{class.derived}) of \tcode{D}, if a valid standard -conversion from ``pointer to member of \tcode{B} of type \tcode{T}'' to -``pointer to member of \tcode{D} of type \tcode{T}'' -exists~(\ref{conv.mem}), and \cvqual{cv2} is the same cv-qualification -as, or greater cv-qualification than, \cvqual{cv1}.\footnote{Function types -(including those used in pointer to member function -types) are never cv-qualified; see~\ref{dcl.fct}.} -The null member pointer value~(\ref{conv.mem}) is converted to the null -member pointer value of the destination type. If class \tcode{B} -contains the original member, or is a base or derived class of the class -containing the original member, the resulting pointer to member points -to the original member. Otherwise, the behavior is undefined. -\enternote -although class \tcode{B} need not contain the original member, the -dynamic type of the object with which indirection through the pointer -to member is performed must contain the original member; -see~\ref{expr.mptr.oper}. -\exitnote +\begin{example} +\begin{codeblock} +void f1(int (*)(int)) { } +void f2(char (*)(int)) { } -\pnum -A prvalue of type ``pointer to \cvqual{cv1} \tcode{void}'' can be -converted to a prvalue of type ``pointer to \cvqual{cv2} \tcode{T},'' -where \tcode{T} is an object type and \cvqual{cv2} is the same -cv-qualification as, or greater cv-qualification than, \cvqual{cv1}. The -null pointer value is converted to the null pointer value of the -destination type. If the original pointer value represents the address -\tcode{A} of a byte in memory and \tcode{A} satisfies the alignment -requirement of \tcode{T}, then the resulting pointer value represents the same -address as the original pointer value, that is, \tcode{A}. The result of any -other such pointer conversion is unspecified. -A value of type pointer to object converted to -``pointer to \cvqual{cv} \tcode{void}'' and back, possibly with -different cv-qualification, shall have its original value. -\enterexample +void g(int (*)(int)) { } // \#1 +void g(char (*)(char)) { } // \#2 -\begin{codeblock} -T* p1 = new T; -const T* p2 = static_cast(static_cast(p1)); -bool b = p1 == p2; // \tcode{b} will have the value \tcode{true}. -\end{codeblock} -\exitexample +void h(int (*)(int)) { } // \#3 +void h(char (*)(int)) { } // \#4 -\rSec2[expr.reinterpret.cast]{Reinterpret cast} +auto glambda = [](auto a) { return a; }; +f1(glambda); // OK +f2(glambda); // error: ID is not convertible +g(glambda); // error: ambiguous +h(glambda); // OK, calls \#3 since it is convertible from ID +int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK +\end{codeblock} +\end{example} \pnum -\indextext{expression!reinterpret~cast} -\indextext{cast!reinterpret}% -The result of the expression \tcode{reinterpret_cast(v)} is the -result of converting the expression \tcode{v} to type \tcode{T}. -\indextext{cast!reinterpret!lvalue}% -\indextext{cast!lvalue}% -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 and the -lvalue-to-rvalue~(\ref{conv.lval}), array-to-pointer~(\ref{conv.array}), -and function-to-pointer~(\ref{conv.func}) standard conversions are -performed on the expression \tcode{v}. Conversions that can be performed explicitly -using \tcode{reinterpret_cast} are listed below. No other conversion can -be performed explicitly using \tcode{reinterpret_cast}. +If the function call operator template is a static member function template, +then the value returned by +any given specialization of this conversion function template is +a pointer to the corresponding function call operator template specialization. +Otherwise, +the value returned by any given specialization of this conversion function +template is a pointer to a function \tcode{F} that, when invoked, has the same +effect as invoking the generic lambda's corresponding function call operator +template specialization on a default-constructed instance of the closure type. +\tcode{F} is a constexpr function +if the corresponding specialization is a constexpr function and +\tcode{F} is an immediate function +if the function call operator template specialization is an immediate function. +\begin{note} +This will result in the implicit instantiation of the generic lambda's body. +The instantiated generic lambda's return type and parameter types need to match +the return type and parameter types of the pointer to function. +\end{note} +\begin{example} +\begin{codeblock} +auto GL = [](auto a) { std::cout << a; return a; }; +int (*GL_int)(int) = GL; // OK, through conversion function template +GL_int(3); // OK, same as \tcode{GL(3)} +\end{codeblock} +\end{example} \pnum -The \tcode{reinterpret_cast} operator shall not cast away constness~(\ref{expr.const.cast}). -An expression of integral, enumeration, pointer, or pointer-to-member type -can be explicitly converted to its own type; such a cast yields the value of -its operand. +The conversion function or conversion function template is public, +constexpr, non-virtual, non-explicit, const, and has a non-throwing exception +specification\iref{except.spec}. +\begin{example} +\begin{codeblock} +auto Fwd = [](int (*fp)(int), auto a) { return fp(a); }; +auto C = [](auto a) { return a; }; -\pnum -\enternote -The mapping performed by \tcode{reinterpret_cast} might, or might not, produce a -representation different from the original value. -\exitnote +static_assert(Fwd(C,3) == 3); // OK -\pnum -\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 it. -\indextext{conversion!implementation~defined pointer integer}% -The mapping function is implementa\-tion-defined. -\enternote -It is intended to be unsurprising to those who know the addressing -structure of the underlying machine. -\exitnote A value of type \tcode{std::nullptr_t} can be converted to an integral -type; the conversion has the same meaning and validity as a conversion of -\tcode{(void*)0} to the integral type. \enternote A \tcode{reinterpret_cast} -cannot be used to convert a value of any type to the type -\tcode{std::nullptr_t}. \exitnote +// No specialization of the function call operator template can be constexpr (due to the local static). +auto NC = [](auto a) { static int s; return a; }; +static_assert(Fwd(NC,3) == 3); // error +\end{codeblock} +\end{example} \pnum -\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; -\indextext{conversion!implementation~defined pointer integer}% -mappings between pointers and integers are otherwise -\impldef{conversions between pointers and integers}. -\enternote Except as described in \ref{basic.stc.dynamic.safety}, the result of -such a conversion will not be a safely-derived pointer value. \exitnote +The \grammarterm{lambda-expression}'s \grammarterm{compound-statement} yields +the \grammarterm{function-body}\iref{dcl.fct.def} of the function call operator, +but it is not within the scope of the closure type. +\begin{example} +\begin{codeblock} +struct S1 { + int x, y; + int operator()(int); + void f() { + [=]()->int { + return operator()(this->x + y); // equivalent to \tcode{S1::operator()(this->x + (*this).y)} + // \keyword{this} has type \tcode{S1*} + }; + } +}; +\end{codeblock} +\end{example} +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}. \pnum -\indextext{cast!reinterpret!pointer-to-function}% -\indextext{cast!pointer-to-function}% -\indextext{cast!undefined pointer-to-function}% -A function pointer can be explicitly converted -to a function pointer of a different type. -\indextext{function~call!undefined}% -The effect of calling a function through a pointer to a function -type~(\ref{dcl.fct}) that is not the same as the type used in the -definition of the function is undefined. 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. -\enternote -see also~\ref{conv.ptr} for more details of pointer conversions. -\exitnote +The closure type associated with a \grammarterm{lambda-expression} has no +default constructor +if the \grammarterm{lambda-expression} has a \grammarterm{lambda-capture} +and a defaulted default constructor otherwise. +It has a defaulted copy constructor and a defaulted move constructor\iref{class.copy.ctor}. +It has a deleted copy assignment operator if the \grammarterm{lambda-expression} +has a \grammarterm{lambda-capture} and defaulted copy and move assignment +operators otherwise\iref{class.copy.assign}. +\begin{note} +These special member functions are implicitly defined as +usual, which can result in them being defined as deleted. +\end{note} \pnum -An object pointer -can be explicitly converted to an object pointer of a different type.\footnote{The -types may have different \cv-qualifiers, subject to -the overall -restriction that a \tcode{reinterpret_cast} cannot cast away constness.} -When a prvalue \tcode{v} of object pointer type is converted to -the object pointer type ``pointer to \cv\ \tcode{T}'', the result is \tcode{static_cast<\cv\ T*>(static_cast<\cv\ -void*>(v))}. -Converting a prvalue of type ``pointer to \tcode{T1}'' to -the type ``pointer to \tcode{T2}'' (where \tcode{T1} and \tcode{T2} are -object types and where the alignment requirements of \tcode{T2} are no -stricter than those of \tcode{T1}) and back to its original type yields -the original pointer value. +The closure type associated with a \grammarterm{lambda-expression} has an +implicitly-declared destructor\iref{class.dtor}. \pnum -Converting a function pointer to an object pointer -type or vice versa is -conditionally-supported. The meaning of such a conversion is -\impldef{converting function pointer to object pointer and vice versa}, -except that if an implementation -supports conversions in both directions, converting a prvalue of one type to the other -type and back, possibly with different cv-qualification, shall yield the original -pointer value. +A member of a closure type shall not be +explicitly instantiated\iref{temp.explicit}, +explicitly specialized\iref{temp.expl.spec}, or +named in a friend declaration\iref{class.friend}. + +\rSec3[expr.prim.lambda.capture]{Captures}% + +\begin{bnf} +\nontermdef{lambda-capture}\br + capture-default\br + capture-list\br + capture-default \terminal{,} capture-list +\end{bnf} + +\begin{bnf} +\nontermdef{capture-default}\br + \terminal{\&}\br + \terminal{=} +\end{bnf} + +\begin{bnf} +\nontermdef{capture-list}\br + capture\br + capture-list \terminal{,} capture +\end{bnf} + +\begin{bnf} +\nontermdef{capture}\br + simple-capture\br + init-capture +\end{bnf} + +\begin{bnf} +\nontermdef{simple-capture}\br + identifier \opt{\terminal{...}}\br + \terminal{\&} identifier \opt{\terminal{...}}\br + \keyword{this}\br + \terminal{*} \keyword{this} +\end{bnf} + +\begin{bnf} +\nontermdef{init-capture}\br + \opt{\terminal{...}} identifier initializer\br + \terminal{\&} \opt{\terminal{...}} identifier initializer +\end{bnf} \pnum -The null pointer value~(\ref{conv.ptr}) is converted to the null pointer value -of the destination type. -\enternote -A null pointer constant of type \tcode{std::nullptr_t} cannot be converted to a -pointer type, and a null pointer constant of integral type is not necessarily -converted to a null pointer value. -\exitnote +The body of a \grammarterm{lambda-expression} may refer to local entities +of enclosing scopes by capturing those entities, as described +below. \pnum -\indextext{cast!reinterpret!pointer-to-member}% -\indextext{cast!pointer-to-member}% -A prvalue of type ``pointer to member of \tcode{X} of type \tcode{T1}'' -can be explicitly converted to a prvalue of a different type ``pointer to member of -\tcode{Y} of type \tcode{T2}'' if \tcode{T1} and \tcode{T2} are both -function types or both object types.\footnote{\tcode{T1} and \tcode{T2} may have -different \cv-qualifiers, subject to -the overall restriction that a \tcode{reinterpret_cast} cannot cast away -constness.} The null member pointer value~(\ref{conv.mem}) is converted to the -null member pointer value of the destination type. The result of this -conversion is unspecified, except in the following cases: +If a \grammarterm{lambda-capture} includes a \grammarterm{capture-default} that +is \tcode{\&}, no identifier in a \grammarterm{simple-capture} of that +\grammarterm{lambda-capture} shall be preceded +by \tcode{\&}. If a \grammarterm{lambda-capture} includes a +\grammarterm{capture-default} that is \tcode{=}, each +\grammarterm{simple-capture} of that \grammarterm{lambda-capture} shall +be of the form +``\tcode{\&} \grammarterm{identifier} \opt{\tcode{...}}'', +``\keyword{this}'', +or ``\tcode{* \keyword{this}}''. +\begin{note} +The form \tcode{[\&,\keyword{this}]} is redundant but accepted +for compatibility with \CppXIV{}. +\end{note} +Ignoring appearances in +\grammarterm{initializer}{s} of \grammarterm{init-capture}{s}, an identifier or +\keyword{this} shall not appear more than once in a +\grammarterm{lambda-capture}. +\begin{example} +\begin{codeblock} +struct S2 { void f(int i); }; +void S2::f(int i) { + [&, i]{ }; // OK + [&, this, i]{ }; // OK, equivalent to \tcode{[\&, i]} + [&, &i]{ }; // error: \tcode{i} preceded by \tcode{\&} when \tcode{\&} is the default + [=, *this]{ }; // OK + [=, this]{ }; // OK, equivalent to \tcode{[=]} + [i, i]{ }; // error: \tcode{i} repeated + [this, *this]{ }; // error: \keyword{this} appears twice +} +\end{codeblock} +\end{example} +\pnum +A \grammarterm{lambda-expression} shall not have +a \grammarterm{capture-default} or \grammarterm{simple-capture} +in its \grammarterm{lambda-introducer} +unless \begin{itemize} -\item converting a prvalue of type ``pointer to member function'' to a -different pointer to member function type and back to its original type -yields the original pointer to member value. - -\item converting a prvalue of type ``pointer to data member of \tcode{X} -of type \tcode{T1}'' to the type ``pointer to data member of \tcode{Y} -of type \tcode{T2}'' (where the alignment requirements of \tcode{T2} are -no stricter than those of \tcode{T1}) and back to its original type -yields the original pointer to member value. +\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}, 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 -\indextext{cast!reinterpret!reference}% -\indextext{cast!reference}% -A glvalue expression of type \tcode{T1} can be cast to the type -``reference to \tcode{T2}'' if an expression of type ``pointer to -\tcode{T1}'' can be explicitly converted to the type ``pointer to -\tcode{T2}'' using a \tcode{reinterpret_cast}. The result refers to -the same object as the source glvalue, but with the specified -type. \enternote That is, for lvalues, a reference cast -\tcode{reinterpret_cast(x)} has the same effect as the conversion -\tcode{*reinterpret_cast(\&x)} with the built-in \tcode{\&} and -\tcode{*} operators (and similarly for -\tcode{reinterpret_cast(x)}). \exitnote No -temporary is created, no copy is made, and -constructors~(\ref{class.ctor}) or conversion -functions~(\ref{class.conv}) are not called.\footnote{\indextext{type~pun}This -is sometimes referred to as a \term{type pun}.} - -\rSec2[expr.const.cast]{Const cast} - -\pnum -\indextext{expression!const~cast}% -\indextext{cast!const}% -The result of the expression \tcode{const_cast(v)} is of type -\tcode{T}. If \tcode{T} is an lvalue reference to object 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 and the -lvalue-to-rvalue~(\ref{conv.lval}), array-to-pointer~(\ref{conv.array}), -and function-to-pointer~(\ref{conv.func}) standard conversions are -performed on the expression \tcode{v}. Conversions that can be performed explicitly using -\tcode{const_cast} are listed below. No other conversion shall be -performed explicitly using \tcode{const_cast}. +The \grammarterm{identifier} in a \grammarterm{simple-capture} +shall denote a local entity\iref{basic.lookup.unqual,basic.pre}. +The \grammarterm{simple-capture}{s} \keyword{this} and \tcode{* \keyword{this}} +denote the local entity \tcode{*\keyword{this}}. +An entity that is designated by a +\grammarterm{simple-capture} +is said to be \defn{explicitly captured}. \pnum -\enternote -Subject to the restrictions in this section, an expression may be cast -to its own type using a \tcode{const_cast} operator. -\exitnote +If an \grammarterm{identifier} in a \grammarterm{capture} appears +as the \grammarterm{declarator-id} of a parameter of +the \grammarterm{lambda-declarator}'s \grammarterm{parameter-declaration-clause} +or as the name of a template parameter of +the \grammarterm{lambda-expression}'s \grammarterm{template-parameter-list}, +the program is ill-formed. +\begin{example} +\begin{codeblock} +void f() { + int x = 0; + auto g = [x](int x) { return 0; }; // error: parameter and \grammarterm{capture} have the same name + auto h = [y = 0](y) { return 0; }; // error: template parameter and \grammarterm{capture} + // have the same name +} +\end{codeblock} +\end{example} \pnum -For two similar types \tcode{T1} and \tcode{T2}~(\ref{conv.qual}), -a prvalue of type \tcode{T1} may be explicitly -converted to the type \tcode{T2} using a \tcode{const_cast}. The result -of a \tcode{const_cast} refers to the original entity. -\enterexample +An \grammarterm{init-capture} inhabits +the lambda scope\iref{basic.scope.lambda} +of the \grammarterm{lambda-expression}. +An \grammarterm{init-capture} without ellipsis +behaves as if it declares and explicitly captures a variable of +the form ``\keyword{auto} \grammarterm{init-capture} \tcode{;}'', except that: +\begin{itemize} +\item if the capture is by copy (see below), the non-static data member +declared for the capture and the variable are treated as two different ways +of referring to the same object, which has the lifetime of the non-static +data member, and no additional copy and destruction is performed, and +\item if the capture is by reference, the variable's lifetime ends when the +closure object's lifetime ends. +\end{itemize} +\begin{note} +This enables an \grammarterm{init-capture} like +``\tcode{x = std::move(x)}''; the second ``\tcode{x}'' must bind to a +declaration in the surrounding context. +\end{note} +\begin{example} \begin{codeblock} -typedef int *A[3]; // array of 3 pointer to \tcode{int} -typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int} +int x = 4; +auto y = [&r = x, x = x+1]()->int { + r += 2; + return x+2; + }(); // Updates \tcode{::x} to 6, and initializes \tcode{y} to 7. -CA &&r = A{}; // OK, reference binds to temporary array object after qualification conversion to type \tcode{CA} -A &&r1 = const_cast(CA{}); // error: temporary array decayed to pointer -A &&r2 = const_cast(CA{}); // OK +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++; +}; \end{codeblock} -\exitexample +\end{example} \pnum -For two object types \tcode{T1} and \tcode{T2}, if a pointer to \tcode{T1} can -be explicitly converted to the type ``pointer to \tcode{T2}'' using a -\tcode{const_cast}, then the following conversions can also be made: +For the purposes of lambda capture, +an expression potentially references local entities as follows: \begin{itemize} -\item an lvalue of type \tcode{T1} can be explicitly converted to an lvalue -of type \tcode{T2} using the cast \tcode{const_cast}; +\item +An \grammarterm{id-expression} that names a local entity +potentially references that entity; +an \grammarterm{id-expression} that names +one or more non-static class members +and does not form a pointer to member\iref{expr.unary.op} +potentially references \tcode{*\keyword{this}}. +\begin{note} +This occurs even if overload resolution +selects a static member function for the \grammarterm{id-expression}. +\end{note} -\item a glvalue of type \tcode{T1} can be explicitly converted to an xvalue -of type \tcode{T2} using the cast \tcode{const_cast}; and +\item +A \keyword{this} expression potentially references \tcode{*\keyword{this}}. -\item if \tcode{T1} is a class type, a prvalue of type \tcode{T1} can be -explicitly converted to an xvalue of type \tcode{T2} using the cast -\tcode{const_cast}. +\item +A \grammarterm{lambda-expression} potentially references +the local entities named by its \grammarterm{simple-capture}{s}. \end{itemize} -The result of a reference \tcode{const_cast} refers -to the original object. +If an expression potentially references a local entity +within a scope in which it is odr-usable\iref{basic.def.odr}, +and the expression would be potentially evaluated +if the effect of any enclosing \keyword{typeid} expressions\iref{expr.typeid} were ignored, +the entity is said to be \defnx{implicitly captured}{capture!implicit} +by each intervening \grammarterm{lambda-expression} with an associated +\grammarterm{capture-default} that does not explicitly capture it. +The implicit capture of \tcode{*\keyword{this}} is deprecated when the +\grammarterm{capture-default} is \tcode{=}; see \ref{depr.capture.this}. +\begin{example} +\begin{codeblock} +void f(int, const int (&)[2] = {}); // \#1 +void f(const int&, const int (&)[1]); // \#2 +void test() { + const int x = 17; + auto g = [](auto a) { + f(x); // OK, calls \#1, does not capture \tcode{x} + }; + + auto g1 = [=](auto a) { + f(x); // OK, calls \#1, captures \tcode{x} + }; + + auto g2 = [=](auto a) { + int selector[sizeof(a) == 1 ? 1 : 2]{}; + f(x, selector); // OK, captures \tcode{x}, can call \#1 or \#2 + }; + + auto g3 = [=](auto a) { + typeid(a + x); // captures \tcode{x} regardless of whether \tcode{a + x} is an unevaluated operand + }; +} +\end{codeblock} +Within \tcode{g1}, an implementation can optimize away +the capture of \tcode{x} as it is not odr-used. +\end{example} +\begin{note} +The set of captured entities is determined syntactically, +and entities are implicitly captured +even if the expression denoting a local entity +is within a discarded statement\iref{stmt.if}. +\begin{example} +\begin{codeblock} +template +void f(int n) { + [=](auto a) { + if constexpr (B && sizeof(a) > 4) { + (void)n; // captures \tcode{n} regardless of the value of \tcode{B} and \tcode{sizeof(int)} + } + }(0); +} +\end{codeblock} +\end{example} +\end{note} + +\pnum +An entity is \defn{captured} if it is captured explicitly or implicitly. An entity +captured by a \grammarterm{lambda-expression} is odr-used\iref{term.odr.use} by +the \grammarterm{lambda-expression}. +\begin{note} +As a consequence, if a \grammarterm{lambda-expression} +explicitly captures an entity that is not odr-usable, +the program is ill-formed\iref{basic.def.odr}. +\end{note} +\begin{example} +\indextext{Bond!James Bond}% +\begin{codeblock} +void f1(int i) { + int const N = 20; + auto m1 = [=]{ + int const M = 30; + auto m2 = [i]{ + int x[N][M]; // OK, \tcode{N} and \tcode{M} are not odr-used + x[0][0] = i; // OK, \tcode{i} is explicitly captured by \tcode{m2} and implicitly captured by \tcode{m1} + }; + }; + struct s1 { + int f; + void work(int n) { + int m = n*n; + int j = 40; + auto m3 = [this,m] { + auto m4 = [&,j] { // error: \tcode{j} not odr-usable due to intervening lambda \tcode{m3} + int x = n; // error: \tcode{n} is odr-used but not odr-usable due to intervening lambda \tcode{m3} + x += m; // OK, \tcode{m} implicitly captured by \tcode{m4} and explicitly captured by \tcode{m3} + x += i; // error: \tcode{i} is odr-used but not odr-usable + // due to intervening function and class scopes + x += f; // OK, \keyword{this} captured implicitly by \tcode{m4} and explicitly by \tcode{m3} + }; + }; + } + }; +} + +struct s2 { + double ohseven = .007; + auto f() { + return [this] { + return [*this] { + return ohseven; // OK + }; + }(); + } + auto g() { + return [] { + return [*this] { }; // error: \tcode{*this} not captured by outer \grammarterm{lambda-expression} + }(); + } +}; +\end{codeblock} +\end{example} + +\pnum +\begin{note} +Because local entities are not +odr-usable within a default argument\iref{basic.def.odr}, +a \grammarterm{lambda-expression} appearing in a default argument +cannot implicitly or explicitly capture any local entity. +Such a \grammarterm{lambda-expression} +can still have an \grammarterm{init-capture} if +any full-expression in its \grammarterm{initializer} +satisfies the constraints of an expression appearing in +a default argument\iref{dcl.fct.default}. +\end{note} +\begin{example} +\begin{codeblock} +void f2() { + int i = 1; + void g1(int = ([i]{ return i; })()); // error + void g2(int = ([i]{ return 0; })()); // error + void g3(int = ([=]{ return i; })()); // error + void g4(int = ([=]{ return 0; })()); // OK + void g5(int = ([]{ return sizeof i; })()); // OK + void g6(int = ([x=1]{ return x; })()); // OK + void g7(int = ([x=i]{ return x; })()); // error +} +\end{codeblock} +\end{example} + +\pnum +An entity is \defnx{captured by copy}{captured!by copy} if +\begin{itemize} +\item +it is implicitly captured, +the \grammarterm{capture-default} is \tcode{=}, and +the captured entity is not \tcode{*\keyword{this}}, or +\item +it is explicitly captured with a capture that is not of the form +\keyword{this}, +\tcode{\&} \grammarterm{identifier} \opt{\tcode{...}}, or +\tcode{\&} \opt{\tcode{...}} \grammarterm{identifier} \grammarterm{initializer}. +\end{itemize} +For each entity captured by copy, an +unnamed non-static data member is declared in the closure type. The declaration order of +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. +A member of an anonymous union shall not be captured by copy. + +\pnum +Every \grammarterm{id-expression} within the \grammarterm{compound-statement} of a +\grammarterm{lambda-expression} that is an odr-use\iref{term.odr.use} of an +entity captured by copy is transformed into an access to the corresponding unnamed data +member of the closure type. +\begin{note} +An \grammarterm{id-expression} that is not an odr-use refers to +the original entity, never to a member of the closure type. +However, such +an \grammarterm{id-expression} can still cause the implicit capture of the +entity. +\end{note} +If \tcode{*\keyword{this}} is captured by copy, each expression that odr-uses \tcode{*\keyword{this}} is +transformed to instead refer to the corresponding unnamed data member of the closure type. +\begin{example} +\begin{codeblock} +void f(const int*); +void g() { + const int N = 10; + [=] { + int arr[N]; // OK, not an odr-use, refers to variable with automatic storage duration + f(&N); // OK, causes \tcode{N} to be captured; \tcode{\&N} points to + // the corresponding member of the closure type + }; +} +\end{codeblock} +\end{example} + +\pnum +An entity is \defnx{captured by reference}{captured!by reference} if it is implicitly or explicitly +captured but not captured by copy. It is unspecified whether additional unnamed +non-static data members are declared in the closure type for entities captured by +reference. +If declared, such non-static data members shall be of literal type. +\begin{example} +\begin{codeblock} +// The inner closure type must be a literal type regardless of how reference captures are represented. +static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4); +\end{codeblock} +\end{example} +A bit-field or a member of an anonymous union +shall not be captured by reference. + +\pnum +An \grammarterm{id-expression} within +the \grammarterm{compound-statement} of a \grammarterm{lambda-expression} +that is an odr-use of a reference captured by reference +refers to the entity to which the captured reference is bound and +not to the captured reference. +\begin{note} +The validity of such captures is determined by +the lifetime of the object to which the reference refers, +not by the lifetime of the reference itself. +\end{note} +\begin{example} +\begin{codeblock} +auto h(int &r) { + return [&] { + ++r; // Valid after \tcode{h} returns if the lifetime of the + // object to which \tcode{r} is bound has not ended + }; +} +\end{codeblock} +\end{example} + +\pnum +If a \grammarterm{lambda-expression} \tcode{m2} captures an entity and that entity is +captured by an immediately enclosing \grammarterm{lambda-expression} +\tcode{m1}, then +\tcode{m2}'s capture is transformed as follows: +\begin{itemize} +\item If \tcode{m1} captures the entity by copy, +\tcode{m2} captures the corresponding +non-static data member of \tcode{m1}'s closure type; +if \tcode{m1} is not \keyword{mutable}, the non-static data member is considered to be const-qualified. +\item If \tcode{m1} captures the entity by reference, +\tcode{m2} captures the same +entity captured by \tcode{m1}. +\end{itemize} +\begin{example} +The nested \grammarterm{lambda-expression}s and invocations below will output +\tcode{123234}. +\begin{codeblock} +int a = 1, b = 1, c = 1; +auto m1 = [a, &b, &c]() mutable { + auto m2 = [a, b, &c]() mutable { + std::cout << a << b << c; + a = 4; b = 4; c = 4; + }; + a = 3; b = 3; c = 3; + m2(); +}; +a = 2; b = 2; c = 2; +m1(); +std::cout << a << b << c; +\end{codeblock} +\end{example} + +\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 +when the \grammarterm{lambda-expression} is evaluated and +in the (unspecified) order in which the non-static data members are declared. +\begin{note} +This ensures that the destructions will occur in the reverse order of the constructions. +\end{note} + +\pnum +\begin{note} +If a non-reference entity is implicitly or explicitly captured by reference, +invoking the function call operator of the corresponding \grammarterm{lambda-expression} +after the lifetime of the entity has ended is likely to result in undefined behavior. +\end{note} + +\pnum +A \grammarterm{simple-capture} containing an ellipsis is a pack +expansion\iref{temp.variadic}. +\indextext{init-capture pack@\fakegrammarterm{init-capture} pack}% +An \grammarterm{init-capture} containing an ellipsis is a pack +expansion that declares an +\grammarterm{init-capture} pack\iref{temp.variadic}. +\begin{example} +\begin{codeblock} +template +void f(Args... args) { + auto lm = [&, args...] { return g(args...); }; + lm(); + + auto lm2 = [...xs=std::move(args)] { return g(xs...); }; + lm2(); +} +\end{codeblock} +\end{example} +\indextext{expression!lambda|)} + +\rSec2[expr.prim.fold]{Fold expressions}% +\indextext{expression!fold|(} + +\pnum +A fold expression performs a fold of a +pack\iref{temp.variadic} over a binary operator. + +\begin{bnf} +\nontermdef{fold-expression}\br + \terminal{(} cast-expression fold-operator \terminal{...} \terminal{)}\br + \terminal{(} \terminal{...} fold-operator cast-expression \terminal{)}\br + \terminal{(} cast-expression fold-operator \terminal{...} fold-operator cast-expression \terminal{)} +\end{bnf} + +\begin{bnf} +%% Ed. note: character protrusion would misalign operators with leading `-`. +\microtypesetup{protrusion=false} +\nontermdef{fold-operator} \textnormal{one of}\br + \terminal{+ }\quad\terminal{- }\quad\terminal{* }\quad\terminal{/ }\quad\terminal{\% }\quad\terminal{\caret{} }\quad\terminal{\& }\quad\terminal{| }\quad\terminal{<< }\quad\terminal{>> }\br + \terminal{+=}\quad\terminal{-=}\quad\terminal{*=}\quad\terminal{/=}\quad\terminal{\%=}\quad\terminal{\caret=}\quad\terminal{\&=}\quad\terminal{|=}\quad\terminal{<<=}\quad\terminal{>>=}\quad\terminal{=}\br + \terminal{==}\quad\terminal{!=}\quad\terminal{< }\quad\terminal{> }\quad\terminal{<=}\quad\terminal{>=}\quad\terminal{\&\&}\quad\terminal{||}\quad\terminal{, }\quad\terminal{.* }\quad\terminal{->*} +\end{bnf} + +\pnum +\indextext{fold!unary}% +An expression of the form +\tcode{(...} \placeholder{op} \tcode{e)} +where \placeholder{op} is a \grammarterm{fold-operator} +is called a \defn{unary left fold}. +An expression of the form +\tcode{(e} \placeholder{op} \tcode{...)} +where \placeholder{op} is a \grammarterm{fold-operator} +is called a \defn{unary right fold}. +Unary left folds and unary right folds +are collectively called \defnx{unary folds}{unary fold}. +In a unary fold, +the \grammarterm{cast-expression} +shall contain an unexpanded pack\iref{temp.variadic}. + +\pnum +\indextext{fold!binary}% +An expression of the form +\tcode{(e1} \placeholder{op1} \tcode{...} \placeholder{op2} \tcode{e2)} +where \placeholder{op1} and \placeholder{op2} are \grammarterm{fold-operator}{s} +is called a \defn{binary fold}. +In a binary fold, +\placeholder{op1} and \placeholder{op2} +shall be the same \grammarterm{fold-operator}, +and either \tcode{e1} +shall contain an unexpanded pack +or \tcode{e2} +shall contain an unexpanded pack, +but not both. +If \tcode{e2} contains an unexpanded pack, +the expression is called a \defn{binary left fold}. +If \tcode{e1} contains an unexpanded pack, +the expression is called a \defn{binary right fold}. +\begin{example} +\begin{codeblock} +template +bool f(Args ...args) { + return (true && ... && args); // OK +} + +template +bool f(Args ...args) { + return (args + ... + args); // error: both operands contain unexpanded packs +} +\end{codeblock} +\end{example} + +\pnum +A fold expression is a pack expansion. +\indextext{expression!fold|)}% + +\rSec2[expr.prim.req]{Requires expressions} + +\rSec3[expr.prim.req.general]{General} +\indextext{expression!requires|(}% + +\pnum +A \grammarterm{requires-expression} provides a concise way to express +requirements on template arguments +that can be checked by name lookup\iref{basic.lookup} +or by checking properties of types and expressions. + +\begin{bnf} +\nontermdef{requires-expression}\br + \keyword{requires} \opt{requirement-parameter-list} requirement-body +\end{bnf} + +\begin{bnf} +\nontermdef{requirement-parameter-list}\br + \terminal{(} parameter-declaration-clause \terminal{)} +\end{bnf} + +\begin{bnf} +\microtypesetup{protrusion=false} +\nontermdef{requirement-body}\br + \terminal{\{} requirement-seq \terminal{\}} +\end{bnf} + +\begin{bnf} +\nontermdef{requirement-seq}\br + requirement \opt{requirement-seq} +\end{bnf} + +\begin{bnf} +\nontermdef{requirement}\br + simple-requirement\br + type-requirement\br + compound-requirement\br + nested-requirement +\end{bnf} + +\pnum +A \grammarterm{requires-expression} is a prvalue of type \tcode{bool} +whose value is described below. + +\pnum +\begin{example} +A common use of \grammarterm{requires-expression}s is to define +requirements in concepts such as the one below: +\begin{codeblock} +template + concept R = requires (T i) { + typename T::type; + {*i} -> std::@\libconcept{convertible_to}@; + }; +\end{codeblock} +A \grammarterm{requires-expression} can also be used in a +\grammarterm{requires-clause}\iref{temp.pre} as a way of writing ad hoc +constraints on template arguments such as the one below: +\begin{codeblock} +template + requires requires (T x) { x + x; } + T add(T a, T b) { return a + b; } +\end{codeblock} +The first \keyword{requires} introduces the +\grammarterm{requires-clause}, and the second +introduces the \grammarterm{requires-expression}. +\end{example} + +\pnum +A \grammarterm{requires-expression} may introduce local parameters using a +\grammarterm{parameter-declaration-clause}. +A local parameter of a \grammarterm{requires-expression} shall not have a +default argument. +The type of such a parameter is determined as specified for +a function parameter in~\ref{dcl.fct}. +These parameters have no linkage, storage, or lifetime; they are only used +as notation for the purpose of defining \grammarterm{requirement}s. +The \grammarterm{parameter-declaration-clause} of a +\grammarterm{requirement-parameter-list} +shall not terminate with an ellipsis. +\begin{example} +\begin{codeblock} +template +concept C = requires(T t, ...) { // error: terminates with an ellipsis + t; +}; +template +concept C2 = requires(T p[2]) { + (decltype(p))nullptr; // OK, \tcode{p} has type ``pointer to \tcode{T}'' +}; +\end{codeblock} +\end{example} + +\pnum +The substitution of template arguments into a \grammarterm{requires-expression} +can result in +the formation of invalid types or expressions in the immediate context of +its \grammarterm{requirement}s\iref{temp.deduct.general} or +the violation of the semantic constraints of those \grammarterm{requirement}s. +In such cases, the \grammarterm{requires-expression} evaluates to \keyword{false}; +it does not cause the program to be ill-formed. +The substitution and semantic constraint checking +proceeds in lexical order and stops when a condition that +determines the result of the \grammarterm{requires-expression} is encountered. +If substitution (if any) and semantic constraint checking succeed, +the \grammarterm{requires-expression} evaluates to \keyword{true}. +\begin{note} +If a \grammarterm{requires-expression} contains invalid types or expressions in +its \grammarterm{requirement}s, and it does not appear within the declaration of a templated +entity, then the program is ill-formed. +\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. +\begin{example} +\begin{codeblock} +template concept C = +requires { + new decltype((void)T{}); // ill-formed, no diagnostic required +}; +\end{codeblock} +\end{example} + +\rSec3[expr.prim.req.simple]{Simple requirements} +\indextext{requirement!simple}% + +\begin{bnf} +\nontermdef{simple-requirement}\br + expression \terminal{;} +\end{bnf} + +\pnum +A \grammarterm{simple-requirement} asserts +the validity of an \grammarterm{expression}. +The \grammarterm{expression} is an unevaluated operand. +\begin{note} +The enclosing \grammarterm{requires-expression} will evaluate to \keyword{false} +if substitution of template arguments into the \grammarterm{expression} fails. +\end{note} +\begin{example} +\begin{codeblock} +template concept C = + requires (T a, T b) { + a + b; // \tcode{C} is \tcode{true} if \tcode{a + b} is a valid expression + }; +\end{codeblock} +\end{example} + +\pnum +A \grammarterm{requirement} that starts with a \keyword{requires} token +is never interpreted as a \grammarterm{simple-requirement}. +\begin{note} +This simplifies distinguishing between a \grammarterm{simple-requirement} +and a \grammarterm{nested-requirement}. +\end{note} + +\rSec3[expr.prim.req.type]{Type requirements} +\indextext{requirement!type}% + +\begin{bnf} +\nontermdef{type-requirement}\br + \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} (if any). +\begin{note} +The enclosing \grammarterm{requires-expression} will evaluate to \keyword{false} +if substitution of template arguments fails. +\end{note} +\begin{example} +\begin{codeblock} +template struct S; +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 \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} + +\pnum +A \grammarterm{type-requirement} that names a class template specialization +does not require that type to be complete\iref{term.incomplete.type}. + +\rSec3[expr.prim.req.compound]{Compound requirements} +\indextext{requirement!compound}% + +\begin{bnf} +\nontermdef{compound-requirement}\br + \terminal{\{} expression \terminal{\}} \opt{\keyword{noexcept}} \opt{return-type-requirement} \terminal{;} +\end{bnf} + +\begin{bnf} +\nontermdef{return-type-requirement}\br + \terminal{->} type-constraint +\end{bnf} + +\pnum +A \grammarterm{compound-requirement} asserts properties +of the \grammarterm{expression} $E$. +The \grammarterm{expression} is an unevaluated operand. +Substitution +of template arguments (if any) and verification of +semantic properties proceed in the following order: + +\begin{itemize} +\item +Substitution of template arguments (if any) +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}. + +\item +If the \grammarterm{return-type-requirement} is present, then: + +\begin{itemize} +\item +Substitution of template arguments (if any) +into the \grammarterm{return-type-requirement} is performed. + +\item +The immediately-declared constraint\iref{temp.param} +of the \grammarterm{type-constraint} for \tcode{\keyword{decltype}((E))} +shall be satisfied. +\end{itemize} +\begin{example} +Given concepts \tcode{C} and \tcode{D}, +\begin{codeblock} +requires { + { E1 } -> C; + { E2 } -> @D@; +}; +\end{codeblock} +is equivalent to +\begin{codeblock} +requires { + E1; requires C; + E2; requires @D@; +}; +\end{codeblock} +(including in the case where $n$ is zero). +\end{example} +\end{itemize} +\pnum +\begin{example} +\begin{codeblock} +template concept C1 = requires(T x) { + {x++}; +}; +\end{codeblock} +The \grammarterm{compound-requirement} in \tcode{C1} +requires that \tcode{x++} is a valid expression. +It is equivalent to the \grammarterm{simple-requirement} +\tcode{x++;}. + +\begin{codeblock} +template concept C2 = requires(T x) { + {*x} -> std::@\libconcept{same_as}@; +}; +\end{codeblock} + +The \grammarterm{compound-requirement} in \tcode{C2} +requires that \tcode{*x} is a valid expression, +that \tcode{typename T::inner} is a valid type, and +that \tcode{std::\libconcept{same_as}} is satisfied. + +\begin{codeblock} +template concept C3 = + requires(T x) { + {g(x)} noexcept; + }; +\end{codeblock} + +The \grammarterm{compound-requirement} in \tcode{C3} +requires that \tcode{g(x)} is a valid expression and +that \tcode{g(x)} is non-throwing. +\end{example} + +\rSec3[expr.prim.req.nested]{Nested requirements} +\indextext{requirement!nested}% + +\begin{bnf} +\nontermdef{nested-requirement}\br + \keyword{requires} constraint-expression \terminal{;} +\end{bnf} + +\pnum +A \grammarterm{nested-requirement} can be used +to specify additional constraints in terms of local parameters. +The \grammarterm{constraint-expression} +shall be satisfied\iref{temp.constr.decl} +by the substituted template arguments, if any. +Substitution of template arguments into a \grammarterm{nested-requirement} +does not result in substitution into the \grammarterm{constraint-expression} +other than as specified in \ref{temp.constr.constr}. +\begin{example} +\begin{codeblock} +template concept C = sizeof(U) == 1; + +template concept D = requires (T t) { + requires C; +}; +\end{codeblock} +\tcode{D} is satisfied if \tcode{sizeof(decltype (+t)) == 1}\iref{temp.constr.atomic}. +\end{example} +\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}% + +\rSec3[expr.post.general]{General}% +\indextext{expression!postfix|(} + +\pnum +Postfix expressions group left-to-right. + +\begin{bnf} +\nontermdef{postfix-expression}\br + primary-expression\br + postfix-expression \terminal{[} \opt{expression-list} \terminal{]}\br + postfix-expression \terminal{(} \opt{expression-list} \terminal{)}\br + simple-type-specifier \terminal{(} \opt{expression-list} \terminal{)}\br + typename-specifier \terminal{(} \opt{expression-list} \terminal{)}\br + simple-type-specifier braced-init-list\br + typename-specifier braced-init-list\br + 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 + \keyword{static_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br + \keyword{reinterpret_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br + \keyword{const_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br + \keyword{typeid} \terminal{(} expression \terminal{)}\br + \keyword{typeid} \terminal{(} type-id \terminal{)} +\end{bnf} + +\begin{bnf} +\nontermdef{expression-list}\br + initializer-list +\end{bnf} + +\pnum +\begin{note} +The \tcode{>} token following the +\grammarterm{type-id} in a \keyword{dynamic_cast}, +\keyword{static_cast}, \keyword{reinterpret_cast}, or +\keyword{const_cast} can be the product of replacing a +\tcode{>>} token by two consecutive \tcode{>} +tokens\iref{temp.names}. +\end{note} + +\rSec3[expr.sub]{Subscripting} + +\pnum +\indextext{operator!subscripting}% +\indextext{\idxcode{[]}|see{operator, subscripting}}% +A \defnadj{subscript}{expression} is a postfix expression +followed by square brackets containing +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\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\iref{dcl.fct.default}. +The initialization of a non-object parameter of +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}. + +\pnum +With the built-in subscript operator, +an \grammarterm{expression-list} shall be present, +consisting of a single \grammarterm{assignment-expression}. +One of the expressions shall be a glvalue of type ``array of +\tcode{T}'' or a prvalue of type ``pointer +to \tcode{T}'' and the other shall be a prvalue of unscoped enumeration or integral type. +The result is of type ``\tcode{T}''. +\indextext{type!incomplete}% +The type ``\tcode{T}'' shall be a completely-defined object type.% +\begin{footnote} +This +is true even if the subscript operator is used in the following common idiom: +\tcode{\&x[0]}. +\end{footnote} +The expression \tcode{E1[E2]} is identical (by definition) to +\tcode{*((E1)+(E2))}, +except that in the case of an array operand, the result is an lvalue +if that operand is an lvalue and an xvalue otherwise. + +\pnum +\begin{note} +Despite its asymmetric appearance, subscripting is a commutative +operation except for sequencing. +See~\ref{expr.unary} and~\ref{expr.add} for details of \tcode{*} and +\tcode{+} and~\ref{dcl.array} for details of array types. +\end{note} + +\rSec3[expr.call]{Function call} + +\pnum +\indextext{expression!function call}% +\indextext{operator!function call}% +\indextext{\idxcode{()}|see{operator, function call}}% +A function call is a postfix expression followed by parentheses +containing a possibly empty, comma-separated list of +\grammarterm{initializer-clause}{s} which +constitute the arguments to the function. +\begin{note} +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} +The postfix expression shall +have function type or function pointer type. +For a call to a non-member function or to a static member function, +the postfix expression shall be either an lvalue that refers to a +function (in which case the function-to-pointer standard +conversion\iref{conv.func} is suppressed on the postfix expression), +or a prvalue of function pointer type. + +\pnum +If the selected +function is non-virtual, or if the \grammarterm{id-expression} in the class +member access expression is a \grammarterm{qualified-id}, that function is +called. Otherwise, its final overrider\iref{class.virtual} in the dynamic type +of the object expression is called; such a call is referred to as a +\defnx{virtual function call}{function!virtual function call}. +\begin{note} +The dynamic type is the type of the object referred to by the +current value of the object expression. \ref{class.cdtor}~describes the +behavior of virtual function calls when the object expression +refers to +an object under construction or destruction. +\end{note} + +\pnum +\begin{note} +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. +\end{note} + +\pnum +If the \grammarterm{postfix-expression} names +a destructor or pseudo-destructor\iref{expr.prim.id.dtor}, +the type of the function call expression is \keyword{void}; otherwise, the +type of the function call expression is the return type of the +statically chosen function (i.e., ignoring the \keyword{virtual} keyword), +even if the type of the function actually called is different. +\indextext{type!incomplete}% +If the \grammarterm{postfix-expression} names a pseudo-destructor +(in which case the \grammarterm{postfix-expression} +is a possibly-parenthesized class member access), +the function call destroys +the object of scalar type +denoted by the object expression +of the class member access\iref{expr.ref,basic.life}. + +\pnum +A type $\tcode{T}_\text{call}$ is +\defn{call-compatible} with a function type $\tcode{T}_\text{func}$ +if $\tcode{T}_\text{call}$ is the same type as $\tcode{T}_\text{func}$ or +if the type ``pointer to $\tcode{T}_\text{func}$'' can be +converted to type ``pointer to $\tcode{T}_\text{call}$'' +via a function pointer conversion\iref{conv.fctptr}. +Calling a function through an +expression whose function type +is not call-compatible with the +type of the called function's +definition results in undefined behavior. +\begin{note} +This requirement allows the case +when the expression has the type of a +potentially-throwing function, but the called function has +a non-throwing exception specification, +and the function types are otherwise the same. +\end{note} + +\pnum +\indextext{function argument|see{argument}}% +\indextext{function parameter|see{parameter}}% +\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, +and each precondition assertion of the function +is evaluated\iref{dcl.contract.func}. +If the function is an explicit object member function and +there is an implied object argument\iref{over.call.func}, +the list of provided arguments is preceded by the implied object argument +for the purposes of this correspondence. +If there is no corresponding argument, +the default argument for the parameter is used. +\begin{example} +\begin{codeblock} +template int f(int n = 0, T ...t); +int x = f(); // error: no argument for second function parameter +\end{codeblock} +\end{example} +If the function is an implicit object member +function, +the object expression of the class member access shall be a glvalue and +the implicit object parameter of the function\iref{over.match.funcs} +is initialized with that glvalue, +converted as if by an explicit type conversion\iref{expr.cast}. +\begin{note} +There is no access or ambiguity checking on this conversion; the access +checking and disambiguation are done as part of the (possibly implicit) +class member access operator. +See~\ref{class.member.lookup}, \ref{class.access.base}, +and~\ref{expr.ref}. +\end{note} +When a function is called, the type of any parameter +shall not be a class type that is either incomplete or abstract. +\begin{note} +This still allows a parameter to be a pointer or reference to such +a type. However, it prevents a passed-by-value parameter +to have an incomplete or abstract class type. +\end{note} +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, 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 +within the context of the full-expression\iref{intro.execution} +where the function call appears. +\begin{example} +The access\iref{class.access.general} of the +constructor, conversion functions, or destructor is +checked at the point of call. If a constructor +or destructor for a function parameter throws an exception, +any \grammarterm{function-try-block}\iref{except.pre} +of the called function +with a handler that can handle the exception +is not considered. +\end{example} + +\pnum +\indextext{evaluation!order of argument}% +\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} +and any default argument. +The initialization of a parameter or, +if the implementation introduces any temporary objects +to hold the values of function parameters\iref{class.temporary}, +the initialization of those temporaries, +including every associated value computation and side effect, +is indeterminately sequenced with respect to that of any other parameter. +These evaluations are +sequenced before +the evaluation of the precondition assertions of the function, +which are evaluated in sequence\iref{dcl.contract.func}. +For any temporaries +introduced to hold the values of function parameters, +the initialization of the parameter objects from those temporaries +is indeterminately sequenced with respect to +the evaluation of each precondition assertion. +\begin{note} +All side effects of +argument evaluations are sequenced before the function is +entered (see~\ref{intro.execution}). +\end{note} +\begin{example} +\begin{codeblock} +void f() { + std::string s = "but I have heard it works even if you don't believe in it"; + s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, ""); + assert(s == "I have heard it works only if you believe in it"); // OK +} +\end{codeblock} +\end{example} +\begin{note} +If an operator function is invoked +using operator notation, +argument evaluation is sequenced +as specified for the built-in operator; +see~\ref{over.match.oper}. +\end{note} +\begin{example} +\begin{codeblock} +struct S { + S(int); +}; +int operator<<(S, int); +int i, j; +int x = S(i=1) << (i=2); +int y = operator<<(S(j=1), j=2); +\end{codeblock} +After performing the initializations, +the value of \tcode{i} is 2 (see~\ref{expr.shift}), +but it is unspecified whether the value of \tcode{j} is 1 or 2. +\end{example} + +\pnum +The result of a function call is the result of the possibly-converted operand +of the \keyword{return} statement\iref{stmt.return} +that transferred control out of the called function (if any), +except in a virtual function call if the return type of the +final overrider is different from the return type of the statically +chosen function, the value returned from the final overrider is +converted to the return type of the statically chosen function. + +\pnum +When the called function exits normally\iref{stmt.return,expr.await}, +all postcondition assertions of the function +are evaluated in sequence\iref{dcl.contract.func}. +If the implementation introduces any temporary objects +to hold the result value as specified in \ref{class.temporary}, +the evaluation of each postcondition assertion +is indeterminately sequenced with respect to +the initialization of any of those temporaries or the result object. +These evaluations, in turn, are sequenced before +the destruction of any function parameters. + +\pnum +\begin{note} +\indextext{type checking!argument}% +\indextext{function call}% +\indextext{argument passing}% +\indextext{value!call by}% +\indextext{reference!call by}% +\indextext{argument!reference}% +A function can change the values of its non-const parameters, but these +changes cannot affect the values of the arguments except where a +parameter is of a reference type\iref{dcl.ref}; if the reference is to +a const-qualified type, \keyword{const_cast} needs to be used to +cast away the constness in order to modify the argument's value. Where a +parameter is of \keyword{const} reference type a temporary object is +introduced if +needed\iref{dcl.type,lex.literal,lex.string,dcl.array,class.temporary}. +In addition, it is possible to modify the values of non-constant objects through +pointer parameters. +\end{note} + +\pnum +\indextext{declaration!ellipsis in function}% +\indextext{parameter list!variable}% +A function can be declared to accept fewer arguments (by declaring default +arguments\iref{dcl.fct.default}) or more arguments (by using the ellipsis, +\tcode{...}, or a function parameter pack\iref{dcl.fct}) than the number of +parameters in the function definition\iref{dcl.fct.def}. +\begin{note} +This implies that, except where the ellipsis (\tcode{...}) or a function +parameter pack is used, a parameter is available for each argument. +\end{note} + +\pnum +\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 \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}, +thus each such argument has a corresponding parameter when a function template +specialization is actually called. +\end{note} +The +lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, +and function-to-pointer\iref{conv.func} standard conversions are +performed on the argument expression. +An argument that has type \cv{}~\tcode{std::nullptr_t} is converted +to type \tcode{\keyword{void}*}\iref{conv.ptr}. +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 +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}, +an eligible non-trivial move constructor, or +a non-trivial destructor\iref{class.dtor}, +with no corresponding parameter, is conditionally-supported with +\impldef{passing argument of class type through ellipsis} semantics. If the argument has +integral or enumeration type that is subject to the integral +promotions\iref{conv.prom}, or a floating-point type that is subject to the +floating-point promotion\iref{conv.fpprom}, the value of the argument is converted to the +promoted type before the call. These promotions are referred to as +the \defnx{default argument promotions}{promotion!default argument promotion}. + +\pnum +\indextext{function call!recursive}% +Recursive calls are permitted, except to the \tcode{main} +function\iref{basic.start.main}. + +\pnum +A function call is an lvalue +if the result type is an lvalue reference type or an rvalue reference to function type, +an xvalue if the result type is an rvalue reference to object type, and a prvalue +otherwise. +If it is a non-void prvalue, +the type of the function call expression shall be complete, +except as specified in \ref{dcl.type.decltype}. + +\rSec3[expr.type.conv]{Explicit type conversion (functional notation)} + +\pnum +\indextext{expression!cast}% +\indextext{explicit type conversion|see{casting}}% +\indextext{type conversion, explicit|see{casting}}% +\indextext{conversion explicit type|see{casting}}% +\indextext{casting}% +A \grammarterm{simple-type-specifier}\iref{dcl.type.simple} or +\grammarterm{typename-specifier}\iref{temp.res} followed +by a parenthesized optional \grammarterm{expression-list} or +by a \grammarterm{braced-init-list} +(the initializer) +constructs a value of the specified type +given the initializer. +\indextext{deduction!class template arguments}% +If the type is a placeholder +for a deduced class type, +it is replaced by the return type +of the function selected by overload resolution +for class template deduction\iref{over.match.class.deduct} +for the remainder of this subclause. +Otherwise, if the type contains a placeholder type, +it is replaced by the type +determined by placeholder type deduction\iref{dcl.type.auto.deduct}. +Let \tcode{T} denote the resulting type. +Then: + +\begin{itemize} +\item +If the initializer is a parenthesized single expression, +the type conversion expression is equivalent +to the corresponding cast +expression\iref{expr.cast}. + +\item +\indextext{type!incomplete}% +Otherwise, if \tcode{T} is \cv{}~\keyword{void}, +the initializer shall be \tcode{()} or \tcode{\{\}} +(after pack expansion, if any), and +the expression is a prvalue of type \keyword{void} +that performs no initialization. + +\item +Otherwise, if \tcode{T} is a reference type, +the expression has the same effect as +direct-initializing an invented variable \tcode{t} of type \tcode{T} from +the initializer and then +using \tcode{t} as the result of the expression; +the result is an lvalue if +\tcode{T} is an lvalue reference type or +an rvalue reference to function type and +an xvalue otherwise. + +\item +Otherwise, +the expression is a prvalue of type \tcode{T} +whose result object is direct-initialized\iref{dcl.init} +with the initializer. +\end{itemize} + +If the initializer is a parenthesized optional \grammarterm{expression-list}, +\tcode{T} shall not be an array type. +\begin{example} +\begin{codeblock} +struct A {}; +void f(A&); // \#1 +void f(A&&); // \#2 +A& g(); +void h() { + f(g()); // calls \#1 + f(A(g())); // calls \#2 with a temporary object + f(auto(g())); // calls \#2 with a temporary object +} +\end{codeblock} +\end{example} + +\rSec3[expr.ref]{Class member access} + +\pnum +\indextext{expression!class member access}% +\indextext{access control!class member}% +\indextext{syntax!class member}% +\indextext{semantics!class member}% +\indextext{operator!class member access}% +\indextext{\idxcode{.}|see{operator, class member access}}% +\indextext{dot operator|see{operator, class member access}}% +\indextext{operator!class member access}% +\indextext{\idxcode{->}|see{operator, class member access}}% +\indextext{arrow operator|see{operator, class member access}}% +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} or a \grammarterm{splice-expression}, +is a postfix expression. +\begin{note} +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}. +\end{note} + +\pnum +\indextext{type!incomplete}% +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 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. +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 form using a dot. +\begin{footnote} +Note that +\tcode{(*(E1))} is an lvalue. +\end{footnote} + +\pnum +The postfix expression before the dot is evaluated; +\begin{footnote} +If the class member +access expression is evaluated, the subexpression evaluation happens even if the +result is unnecessary to determine +the value of the entire postfix expression, for example if the +\grammarterm{id-expression} denotes a static member. +\end{footnote} +the result of that evaluation, +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} 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 +of that same type (ignoring cv-qualifications) and +\tcode{E1.E2} is a prvalue of type ``function of () returning \keyword{void}''. +\begin{note} +This value can only be used +for a notional function call\iref{expr.prim.id.dtor}. +\end{note} + +\pnum +Otherwise, the object expression shall be of class type. +The class type shall be complete +unless the class member access appears in the definition of that class. +\begin{note} +The program is ill-formed if the result differs from that +when the class is complete\iref{class.member.lookup}. +\end{note} +\begin{note} +\ref{basic.lookup.qual} describes how names are looked up after the +\tcode{.} and \tcode{->} operators. +\end{note} + +\pnum +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 +either \keyword{volatile} or the absence of \keyword{volatile}. \cvqual{cv} +represents an arbitrary set of cv-qualifiers, as defined +in~\ref{basic.type.qualifier}. + +\pnum +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}. +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} 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 +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 \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 +\cvqual{vq1} and \cvqual{vq2}; that is, if \cvqual{vq1} or \cvqual{vq2} +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 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 +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, +\tcode{E1.E2} is an lvalue. +\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 +is ignored\iref{expr.prim.paren}. +\end{note} +\end{itemize} + +\item +Otherwise, if \tcode{E2} designates a nested type, +the expression \tcode{E1.E2} is ill-formed. + +\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} 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} 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. +\begin{example} +\begin{codeblock} +struct A { int i; }; +struct B { int j; }; +struct D : A, B {}; +void f() { + D d; + static_cast(d).j; // OK, object expression designates the \tcode{B} subobject of \tcode{d} + reinterpret_cast(d).j; // undefined behavior +} +\end{codeblock} +\end{example} + +\rSec3[expr.post.incr]{Increment and decrement} + +\pnum +\indextext{expression!increment}% +\indextext{operator!increment}% +\indextext{\idxcode{++}|see{operator, increment}}% +\indextext{postfix \tcode{++}}% +The value of a postfix \tcode{++} expression is the value obtained by +applying the lvalue-to-rvalue conversion\iref{conv.lval} to its operand. +\begin{note} +The value obtained is a copy of the original value. +\end{note} +The operand shall be a modifiable lvalue. The type of the operand shall +be an arithmetic type other than \cv{}~\keyword{bool}, +or a pointer to a complete object type. +An operand with volatile-qualified type is deprecated; +see~\ref{depr.volatile.type}. +The value of the operand object is modified\iref{defns.access} +as if it were the operand of the prefix \tcode{++} operator\iref{expr.pre.incr}. +The +\indextext{value computation}% +value computation of the \tcode{++} expression is sequenced before the +modification of the operand object. With respect to an +indeterminately-sequenced function call, the operation of postfix +\tcode{++} is +a single evaluation. +\begin{note} +Therefore, a function call cannot intervene between the +lvalue-to-rvalue conversion and the side effect associated with any +single postfix \tcode{++} operator. +\end{note} +The result is a prvalue. The type of the result is the cv-unqualified +version of the type of the operand. + +\pnum +\indextext{expression!decrement}% +\indextext{operator!decrement}% +\indextext{\idxcode{--}|see{operator, decrement}}% +\indextext{postfix \tcode{--}}% +The operand of postfix \tcode{--} is decremented analogously to the +postfix \tcode{++} operator. +\begin{note} +For prefix increment and decrement, see~\ref{expr.pre.incr}. +\end{note} + +\rSec3[expr.dynamic.cast]{Dynamic cast} + +\pnum +\indextext{expression!dynamic cast}% +\indextext{cast!dynamic}% +The result of the expression \tcode{\keyword{dynamic_cast}(v)} is the result of +converting the expression \tcode{v} to type \tcode{T}. +\indextext{type!incomplete}% +\tcode{T} shall be a pointer or reference to a complete class type, or +``pointer to \cv{} \keyword{void}''. The \keyword{dynamic_cast} operator shall not cast +away constness\iref{expr.const.cast}. + +\pnum +If \tcode{T} is a pointer type, \tcode{v} shall be a prvalue of a +pointer to complete class type, and the result is a prvalue of type +\tcode{T}. If \tcode{T} is an lvalue reference type, \tcode{v} shall be +an lvalue of a complete class type, and the result is an lvalue of the +type referred to by \tcode{T}. If \tcode{T} is an rvalue reference type, +\tcode{v} shall be a glvalue having a complete class type, and the +result is an xvalue of the type referred to by \tcode{T}. + +\pnum +If the type of \tcode{v} is the same as \tcode{T} (ignoring cv-qualifications), +the result is +\tcode{v} (converted if necessary). + +\pnum +If \tcode{T} is ``pointer to \cvqual{cv1} \tcode{B}'' and \tcode{v} has +type ``pointer to \cvqual{cv2} \tcode{D}'' such that \tcode{B} is a base +class of \tcode{D}, the result is a pointer to the unique \tcode{B} +subobject of the \tcode{D} object pointed to by \tcode{v}, or +a null pointer value if \tcode{v} is a null pointer value. +Similarly, if +\tcode{T} is ``reference to \cvqual{cv1} \tcode{B}'' and \tcode{v} has +type \cvqual{cv2} \tcode{D} such that \tcode{B} is a base class of +\tcode{D}, the result is the unique \tcode{B} subobject of the \tcode{D} +object referred to by \tcode{v}. +\begin{footnote} +The most derived +object\iref{intro.object} pointed or referred to by +\tcode{v} can contain other \tcode{B} objects as base classes, but these +are ignored. +\end{footnote} +In both the pointer and +reference cases, the program is ill-formed if \tcode{B} is an inaccessible or +ambiguous base class of \tcode{D}. +\begin{example} +\begin{codeblock} +struct B { }; +struct D : B { }; +void foo(D* dp) { + B* bp = dynamic_cast(dp); // equivalent to \tcode{B* bp = dp;} +} +\end{codeblock} +\end{example} + +\pnum +Otherwise, \tcode{v} shall be a pointer to or a glvalue of a polymorphic +type\iref{class.virtual}. + +\pnum +If \tcode{v} is a null pointer value, the result is a null pointer value. + +\pnum +If \tcode{v} has type ``pointer to \cv{}~\tcode{U}'' and +\tcode{v} does not point to an object +whose type is similar\iref{conv.qual} to \tcode{U} and +that is +within its lifetime or +within its period of construction or destruction\iref{class.cdtor}, +the behavior is undefined. +If \tcode{v} is a glvalue of type \tcode{U} and +\tcode{v} does not refer to an object +whose type is similar to \tcode{U} and +that is +within its lifetime or +within its period of construction or destruction, +the behavior is undefined. + +\pnum +If \tcode{T} is ``pointer to \cv{} \keyword{void}'', then the result +is a pointer to the most derived object pointed to by \tcode{v}. +Otherwise, a runtime check is applied to see if the object pointed or +referred to by \tcode{v} can be converted to the type pointed or +referred to by \tcode{T}. + +\pnum +Let \tcode{C} be the class type to which \tcode{T} points or refers. The runtime +check logically executes as follows: + +\begin{itemize} +\item If, in the most derived object pointed (referred) to by \tcode{v}, +\tcode{v} points (refers) to a public base class subobject of a +\tcode{C} object, and if only one object of type \tcode{C} is derived +from the subobject pointed (referred) to by \tcode{v}, +the result points (refers) to that \tcode{C} object. + +\item Otherwise, if \tcode{v} points (refers) to a public base +class subobject of the most derived object, and the type of the most +derived object has a base class, of type \tcode{C}, that is unambiguous +and public, the result points (refers) to the +\tcode{C} subobject of the most derived object. + +\item Otherwise, the +runtime check \term{fails}. +\end{itemize} + +\pnum +The value of a failed cast to pointer type is the null pointer value of +the required result type. A failed cast to reference type throws +an exception\iref{except.throw} of a type that would match a +handler\iref{except.handle} of type \tcode{std::bad_cast}\iref{bad.cast}. + +\indextext{\idxcode{bad_cast}}% +\indexlibraryglobal{bad_cast}% +\begin{example} +\begin{codeblock} +class A { virtual void f(); }; +class B { virtual void g(); }; +class D : public virtual A, private B { }; +void g() { + D d; + B* bp = (B*)&d; // cast needed to break protection + A* ap = &d; // public derivation, no cast needed + D& dr = dynamic_cast(*bp); // fails + ap = dynamic_cast(bp); // fails + bp = dynamic_cast(ap); // fails + ap = dynamic_cast(&d); // succeeds + bp = dynamic_cast(&d); // ill-formed (not a runtime check) +} + +class E : public D, public B { }; +class F : public E, public D { }; +void h() { + F f; + A* ap = &f; // succeeds: finds unique \tcode{A} + D* dp = dynamic_cast(ap); // fails: yields null; \tcode{f} has two \tcode{D} subobjects + E* ep = (E*)ap; // error: cast from virtual base + E* ep1 = dynamic_cast(ap); // succeeds +} +\end{codeblock} +\end{example} +\begin{note} +Subclause \ref{class.cdtor} describes the behavior of a \keyword{dynamic_cast} +applied to an object under construction or destruction. +\end{note} + +\rSec3[expr.typeid]{Type identification} + +\pnum +\indextext{expression!type identification}% +\indextext{\idxcode{typeid}}% +The result of a \keyword{typeid} expression is an lvalue of static type +\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} \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}. +\begin{footnote} +The recommended name for such a class is +\tcode{extended_type_info}. +\end{footnote} +The lifetime of the object referred to by the lvalue extends to the end +of the program. Whether or not the destructor is called for the +\tcode{std::type_info} object at the end of the program is unspecified. + +\pnum +If the type of the \grammarterm{expression} or \grammarterm{type-id} operand is +a (possibly cv-qualified) class type or +a reference to (possibly cv-qualified) class type, +that class shall be completely defined. + +\pnum +If an \grammarterm{expression} operand of \keyword{typeid} is +a possibly-parenthesized \grammarterm{unary-expression} +whose \grammarterm{unary-operator} is \tcode{*} and +whose operand evaluates to a null pointer value\iref{basic.compound}, +the \keyword{typeid} expression throws an exception\iref{except.throw} +of a type that would match a handler of type +\indextext{\idxcode{bad_typeid}}% +\indexlibraryglobal{bad_typeid}% +\tcode{std::bad_typeid}\iref{bad.typeid}. +\begin{note} +In other contexts, evaluating such a \grammarterm{unary-expression} +results in undefined behavior\iref{expr.unary.op}. +\end{note} + +\pnum +When \keyword{typeid} is applied to a glvalue whose type is a +polymorphic class type\iref{class.virtual}, the result refers to a +\tcode{std::type_info} object representing the type of the most derived +object\iref{intro.object} (that is, the dynamic type) to which the +glvalue refers. + +\pnum +When \keyword{typeid} is applied to an expression other than a glvalue of +a polymorphic class type, the result refers to a \tcode{std::type_info} +object representing the static type of the expression. +Lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, +and function-to-pointer\iref{conv.func} conversions are not applied to +the expression. +If the expression is a prvalue, +the temporary materialization conversion\iref{conv.rval} +is applied. +The expression is an unevaluated operand\iref{term.unevaluated.operand}. + +\pnum +When \keyword{typeid} is applied to a \grammarterm{type-id}, the result +refers to a \tcode{std::type_info} object representing the type of the +\grammarterm{type-id}. If the type of the \grammarterm{type-id} is a reference +to a possibly cv-qualified type, the result of the +\keyword{typeid} expression refers to a \tcode{std::type_info} object +representing the cv-unqualified referenced type. +\begin{note} +The \grammarterm{type-id} cannot denote a function type with +a \grammarterm{cv-qualifier-seq} or a \grammarterm{ref-qualifier}\iref{dcl.fct}. +\end{note} + +\pnum +If the type of the expression or \grammarterm{type-id} is a +cv-qualified type, the result of the \keyword{typeid} expression refers +to a \tcode{std::type_info} object representing the cv-unqualified +type. +\begin{example} +\begin{codeblock} +class D { @\commentellip@ }; +D d1; +const D d2; + +typeid(d1) == typeid(d2); // yields \tcode{true} +typeid(D) == typeid(const D); // yields \tcode{true} +typeid(D) == typeid(d2); // yields \tcode{true} +typeid(D) == typeid(const D&); // yields \tcode{true} +\end{codeblock} +\end{example} + +\pnum +The type \tcode{std::type_info}\iref{type.info} is not predefined; +if a standard library declaration\iref{typeinfo.syn,std.modules} of +\tcode{std::type_info} does not precede\iref{basic.lookup.general} +a \tcode{typeid} expression, the program is ill-formed. + +\pnum +\begin{note} +Subclause \ref{class.cdtor} describes the behavior of \keyword{typeid} +applied to an object under construction or destruction. +\end{note} + +\rSec3[expr.static.cast]{Static cast} + +\pnum +\indextext{expression!static cast}% +\indextext{cast!static}% +The result of the expression \tcode{\keyword{static_cast}(v)} is the result of +converting the expression \tcode{v} to type \tcode{T}. +\indextext{cast!static!lvalue}% +\indextext{cast!lvalue}% +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. + +\pnum +\indextext{cast!static!reference}% +\indextext{cast!reference}% +An lvalue of type ``\cvqual{cv1} \tcode{B}'', where \tcode{B} is a class +type, can be cast to type ``reference to \cvqual{cv2} \tcode{D}'', where +\tcode{D} is a complete class derived\iref{class.derived} from \tcode{B}, +if \cvqual{cv2} is the +same cv-qualification as, or greater cv-qualification than, +\cvqual{cv1}. If \tcode{B} is a virtual base class of \tcode{D} +or a base class of a virtual base class of \tcode{D}, +or if no valid standard conversion from ``pointer to \tcode{D}'' +to ``pointer to \tcode{B}'' exists\iref{conv.ptr}, the program is ill-formed. +An xvalue of type +``\cvqual{cv1} \tcode{B}'' can be cast to type ``rvalue reference to +\cvqual{cv2} \tcode{D}'' with the same constraints as for an lvalue of +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. +\begin{example} +\begin{codeblock} +struct B { }; +struct D : public B { }; +D d; +B &br = d; + +static_cast(br); // produces lvalue denoting the original \tcode{d} object +\end{codeblock} +\end{example} + +\pnum +An lvalue +of type \tcode{T1} can be cast to type ``rvalue +reference to \tcode{T2}'' if \tcode{T2} is reference-compatible with +\tcode{T1}\iref{dcl.init.ref}. If the value is not a bit-field, +the result refers to the object or the specified base class subobject +thereof; otherwise, the lvalue-to-rvalue conversion\iref{conv.lval} +is applied to the bit-field and the resulting prvalue is used as the +operand of the \keyword{static_cast} for the remainder of this subclause. +If \tcode{T2} is an inaccessible\iref{class.access} or +ambiguous\iref{class.member.lookup} base class of \tcode{T1}, +a program that necessitates such a cast is ill-formed. + +\pnum +Any expression can be explicitly converted to type \cv{}~\keyword{void}, +in which case the operand is a discarded-value expression\iref{expr.prop}. +\begin{note} +Such a \keyword{static_cast} has no result +as it is a prvalue of type \keyword{void}; see~\ref{basic.lval}. +\end{note} +\begin{note} +However, if the value is in a temporary +object\iref{class.temporary}, the destructor for that +object is +not executed until the usual time, and the value of the object is +preserved for the purpose of executing the destructor. +\end{note} + +\pnum +Otherwise, an expression $E$ can be explicitly converted to a type \tcode{T} +if there is an implicit conversion sequence\iref{over.best.ics} +from $E$ to \tcode{T}, +if overload resolution for a direct-initialization\iref{dcl.init} +of an object or reference of type \tcode{T} from $E$ +would find at least one viable function\iref{over.match.viable}, or +if \tcode{T} is an aggregate type\iref{dcl.init.aggr} +having a first element \tcode{x} and +there is an implicit conversion sequence +from $E$ to the type of \tcode{x}. +If \tcode{T} is a reference type, the effect is +the same as performing the declaration and initialization +\begin{codeblock} +T t(@$E$@); +\end{codeblock} +for some invented temporary variable \tcode{t}\iref{dcl.init} +and then using the temporary variable as the result of the conversion. +Otherwise, the result object is direct-initialized from $E$. +\begin{note} +The conversion is ill-formed when attempting to convert an +expression of class type to an inaccessible or ambiguous base class. +\end{note} +\begin{note} +If \tcode{T} is ``array of unknown bound of \tcode{U}'', +this direct-initialization defines the type of the expression as \tcode{U[1]}. +\end{note} + +\pnum +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, 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} +can be explicitly converted to an integral type; +the result is the same as that of converting +to the enumeration's underlying type and then to the destination type. +A value of a scoped enumeration type +can also be explicitly converted to a floating-point type; +the result is the same as that of converting +from the original value to the floating-point type. + +\pnum +\indextext{enumeration type!conversion to}% +\indextext{enumeration type!\idxcode{static_cast}!conversion to}% +A value of integral or enumeration type can be explicitly converted to +a complete enumeration type. +If the enumeration type has a fixed underlying type, +the value is first converted to that type +by +integral promotion\iref{conv.prom} or integral conversion\iref{conv.integral}, +if necessary, and +then to the enumeration type. +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. +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 +the enumeration type. + +\pnum +A prvalue of floating-point type can be explicitly converted to +any other floating-point type. +If the source value can be exactly represented in the destination type, +the result of the conversion has 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. + +\pnum +\indextext{cast!base class}% +\indextext{cast!derived class}% +A prvalue of type ``pointer to \cvqual{cv1} \tcode{B}'', where \tcode{B} +is a class type, can be converted to a prvalue of type ``pointer to +\cvqual{cv2} \tcode{D}'', +where \tcode{D} is a complete class derived\iref{class.derived} +from \tcode{B}, +if \cvqual{cv2} is the same cv-qualification as, +or greater cv-qualification than, \cvqual{cv1}. +If \tcode{B} is a virtual base class of \tcode{D} or +a base class of a virtual base class of \tcode{D}, or +if no valid standard conversion from ``pointer to \tcode{D}'' +to ``pointer to \tcode{B}'' exists\iref{conv.ptr}, the program is ill-formed. +The null pointer value\iref{basic.compound} is converted +to the null pointer value of the destination type. If the prvalue of type +``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. + +\pnum +\indextext{cast!pointer-to-member}% +A prvalue of type ``pointer to member of \tcode{D} of type \cvqual{cv1} +\tcode{T}'' can be converted to a prvalue of type ``pointer to member of +\tcode{B} of type \cvqual{cv2} \tcode{T}'', where +\tcode{D} is a complete class type and +\tcode{B} is a base class\iref{class.derived} of \tcode{D}, +if \cvqual{cv2} is the same cv-qualification +as, or greater cv-qualification than, \cvqual{cv1}. +\begin{note} +Function types (including those used in pointer-to-member-function types) +are never cv-qualified\iref{dcl.fct}. +\end{note} +If no valid standard conversion +from ``pointer to member of \tcode{B} of type \tcode{T}'' +to ``pointer to member of \tcode{D} of type \tcode{T}'' +exists\iref{conv.mem}, the program is ill-formed. +The null member pointer value\iref{conv.mem} is converted to the null +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. +\begin{note} +Although class \tcode{B} need not contain the original member, the +dynamic type of the object with which indirection through the pointer +to member is performed must contain the original member; +see~\ref{expr.mptr.oper}. +\end{note} + +\pnum +A prvalue of type ``pointer to \cvqual{cv1} \keyword{void}'' can be +converted to a prvalue of type ``pointer to \cvqual{cv2} \tcode{T}'', +where \tcode{T} is an object type and \cvqual{cv2} is the same +cv-qualification as, or greater cv-qualification than, \cvqual{cv1}. +If the original pointer value represents the address +\tcode{A} of a byte in memory and +\tcode{A} does not satisfy the alignment requirement of \tcode{T}, +then the resulting pointer value\iref{basic.compound} is unspecified. +Otherwise, if the original pointer value points to an object \placeholder{a}, +and there is an object \placeholder{b} of type similar to \tcode{T} +that is pointer-interconvertible\iref{basic.compound} with \placeholder{a}, +the result is a pointer to \placeholder{b}. +Otherwise, the pointer value is unchanged by the conversion. +\begin{example} +\begin{codeblock} +T* p1 = new T; +const T* p2 = static_cast(static_cast(p1)); +bool b = p1 == p2; // \tcode{b} will have the value \tcode{true}. +\end{codeblock} +\end{example} + +\rSec3[expr.reinterpret.cast]{Reinterpret cast} + +\pnum +\indextext{expression!reinterpret cast}% +\indextext{cast!reinterpret}% +The result of the expression \tcode{\keyword{reinterpret_cast}(v)} is the +result of converting the expression \tcode{v} to type \tcode{T}. +\indextext{cast!reinterpret!lvalue}% +\indextext{cast!lvalue}% +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 and the +lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, +and function-to-pointer\iref{conv.func} standard conversions are +performed on the expression \tcode{v}. Conversions that can be performed explicitly +using \keyword{reinterpret_cast} are listed below. No other conversion can +be performed explicitly using \keyword{reinterpret_cast}. + +\pnum +The \keyword{reinterpret_cast} operator shall not cast away constness\iref{expr.const.cast}. +An expression of integral, enumeration, pointer, or pointer-to-member type +can be explicitly converted to its own type; such a cast yields the value of +its operand. + +\pnum +\begin{note} +The mapping performed by \keyword{reinterpret_cast} might, or might not, produce a +representation different from the original value. +\end{note} + +\pnum +\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. +\indextext{conversion!implementation-defined pointer integer}% +The mapping function is \impldef{mapping of pointer to integer}. +\begin{note} +It is intended to be unsurprising to those who know the addressing +structure of the underlying machine. +\end{note} +A value of type \tcode{std::nullptr_t} can be converted to an integral +type; the conversion has the same meaning and validity as a conversion of +\tcode{(\keyword{void}*)0} to the integral type. +\begin{note} +A \keyword{reinterpret_cast} +cannot be used to convert a value of any type to the type +\tcode{std::nullptr_t}. +\end{note} + +\pnum +\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}; +\indextext{conversion!implementation-defined pointer integer}% +mappings between pointers and integers are otherwise +\impldef{conversions between pointers and integers}. + +\pnum +\indextext{cast!reinterpret!pointer-to-function}% +\indextext{cast!pointer-to-function}% +\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 call-compatible with the type used in the +definition of the function is undefined\iref{expr.call}. +\end{note} + +\pnum +An object pointer +can be explicitly converted to an object pointer of a different type. +\begin{footnote} +The +types can have different \cv-qualifiers, subject to +the overall +restriction that a \keyword{reinterpret_cast} cannot cast away constness. +\end{footnote} +When a prvalue \tcode{v} of object pointer type is converted to +the object pointer type ``pointer to \cv{}~\tcode{T}'', the result is \tcode{\keyword{static_cast}<\cv{} T*>(\keyword{static_cast}<\cv{}~\keyword{void}*>(v))}. +\begin{note} +Converting a pointer of type ``pointer to \tcode{T1}'' +that points to an object of type \tcode{T1} +to the type ``pointer to \tcode{T2}'' +(where \tcode{T2} is an object type +and the alignment requirements of \tcode{T2} +are no stricter than those of \tcode{T1}) +and back to its original type yields the original pointer value. +\end{note} + +\pnum +Converting a function pointer to an object pointer +type or vice versa is +conditionally-supported. The meaning of such a conversion is +\impldef{converting function pointer to object pointer and vice versa}, +except that if an implementation +supports conversions in both directions, converting a prvalue of one type to the other +type and back, possibly with different cv-qualification, shall yield the original +pointer value. + +\pnum +The null pointer value\iref{basic.compound} is converted to the null pointer value +of the destination type. +\begin{note} +A null pointer constant of type \tcode{std::nullptr_t} cannot be converted to a +pointer type, and a null pointer constant of integral type is not necessarily +converted to a null pointer value. +\end{note} + +\pnum +\indextext{cast!reinterpret!pointer-to-member}% +\indextext{cast!pointer-to-member}% +A prvalue of type ``pointer to member of \tcode{X} of type \tcode{T1}'' +can be explicitly converted to a prvalue of a different type ``pointer to member of +\tcode{Y} of type \tcode{T2}'' if \tcode{T1} and \tcode{T2} are both +function types or both object types. +\begin{footnote} +\tcode{T1} and \tcode{T2} can have +different \cv-qualifiers, subject to +the overall restriction that a \keyword{reinterpret_cast} cannot cast away +constness. +\end{footnote} +The null member pointer value\iref{conv.mem} is converted to the +null member pointer value of the destination type. The result of this +conversion is unspecified, except in the following cases: + +\begin{itemize} +\item Converting a prvalue of type ``pointer to member function'' to a +different pointer-to-member-function type and back to its original type +yields the original pointer-to-member value. + +\item Converting a prvalue of type ``pointer to data member of \tcode{X} +of type \tcode{T1}'' to the type ``pointer to data member of \tcode{Y} +of type \tcode{T2}'' (where the alignment requirements of \tcode{T2} are +no stricter than those of \tcode{T1}) and back to its original type +yields the original pointer-to-member value. +\end{itemize} + +\pnum +\indextext{cast!reinterpret!reference}% +\indextext{cast!reference}% +\indextext{type pun}% +If \tcode{v} is a glvalue of type \tcode{T1}, +designating an object or function \placeholder{x}, +it can be cast to the type ``reference to \tcode{T2}'' +if an expression of type ``pointer to \tcode{T1}'' +can be explicitly converted to the type ``pointer to \tcode{T2}'' +using a \keyword{reinterpret_cast}. +The result is that of \tcode{*reinterpret_cast(p)} +where \tcode{p} is a pointer to \placeholder{x} +of type ``pointer to \tcode{T1}''. +\begin{note} +No temporary is materialized\iref{conv.rval} or created, +no copy is made, and +no constructors\iref{class.ctor} or conversion +functions\iref{class.conv} are called. +\begin{footnote} +This is sometimes referred to as a type pun +when the result refers to the same object as the source glvalue. +\end{footnote} +\end{note} + +\rSec3[expr.const.cast]{Const cast} + +\pnum +\indextext{expression!const cast}% +\indextext{cast!const}% +The result of the expression \tcode{\keyword{const_cast}(v)} is of type +\tcode{T}. If \tcode{T} is an lvalue reference to object 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 and the +lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, +and function-to-pointer\iref{conv.func} standard conversions are +performed on the expression \tcode{v}. +The temporary materialization conversion\iref{conv.rval} is not +performed on \tcode{v}, other than as specified below. +Conversions that can be performed explicitly using +\keyword{const_cast} are listed below. No other conversion shall be +performed explicitly using \keyword{const_cast}. + +\pnum +\begin{note} +Subject to the restrictions in this subclause, an expression can be cast +to its own type using a \keyword{const_cast} operator. +\end{note} + +\pnum +For two similar object pointer or pointer to data member types +\tcode{T1} and \tcode{T2}\iref{conv.qual}, +a prvalue of type \tcode{T1} can be explicitly +converted to the type \tcode{T2} using a \keyword{const_cast} +if, considering the qualification-decompositions of both types, +each $P^1_i$ is the same as $P^2_i$ for all $i$. +If \tcode{v} is a null pointer or null member pointer, +the result is a null pointer or null member pointer, respectively. +Otherwise, the result points to or past the end of the same object, or +points to the same member, respectively, as \tcode{v}. + +\pnum +For two object types \tcode{T1} and \tcode{T2}, if a pointer to \tcode{T1} can +be explicitly converted to the type ``pointer to \tcode{T2}'' using a +\keyword{const_cast}, then the following conversions can also be made: +\begin{itemize} +\item an lvalue of type \tcode{T1} can be explicitly converted to an lvalue +of type \tcode{T2} using the cast \tcode{\keyword{const_cast}}; + +\item a glvalue of type \tcode{T1} can be explicitly converted to an xvalue +of type \tcode{T2} using the cast \tcode{\keyword{const_cast}}; and + +\item if \tcode{T1} is a class or array type, +a prvalue of type \tcode{T1} can be +explicitly converted to an xvalue of type \tcode{T2} using the cast +\tcode{\keyword{const_cast}}. +The temporary materialization conversion is performed on \tcode{v}. +\end{itemize} + +The result refers to the same object as the (possibly converted) operand. +\begin{example} +\begin{codeblock} +typedef int *A[3]; // array of 3 pointer to \tcode{int} +typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int} + +auto &&r2 = const_cast(CA{}); // OK, temporary materialization conversion is performed +\end{codeblock} +\end{example} + +\pnum +\begin{note} +Depending on the type of the object, a write operation through the +pointer, lvalue or pointer to data member resulting from a +\keyword{const_cast} that casts away a const-qualifier +\begin{footnote} +\keyword{const_cast} +is not limited to conversions that cast away a +const-qualifier. +\end{footnote} +can produce undefined behavior\iref{dcl.type.cv}. +\end{note} + +\pnum +\indextext{\idxcode{const}!cast away}% +A conversion from a type \tcode{T1} to a type \tcode{T2} +\defnx{casts away constness}{casting away constness} +if \tcode{T1} and \tcode{T2} are different, +there is a qualification-decomposition\iref{conv.qual} of \tcode{T1} +yielding \placeholder{n} such that +\tcode{T2} has a qualification-decomposition of the form +\begin{indented} +$\cv{}_0^2$ $P_0^2$ $\cv{}_1^2$ $P_1^2$ $\cdots$ $\cv{}_{n-1}^2$ $P_{n-1}^2$ $\cv{}_n^2$ $\mathtt{U}_2$, +\end{indented} +and there is no qualification conversion that converts \tcode{T1} to +\begin{indented} +$\cv{}_0^2$ $P_0^1$ $\cv{}_1^2$ $P_1^1$ $\cdots$ $\cv{}_{n-1}^2$ $P_{n-1}^1$ $\cv{}_n^2$ $\mathtt{U}_1$. +\end{indented} + +\pnum +Casting from an lvalue of type \tcode{T1} to an lvalue of type +\tcode{T2} using an lvalue reference cast +or casting from an expression of type \tcode{T1} to an xvalue of type \tcode{T2} using +an rvalue reference cast +casts away constness if a cast from a prvalue of type ``pointer to \tcode{T1}'' to the type ``pointer to +\tcode{T2}'' casts away constness. + +\pnum +\begin{note} +Some conversions which involve only changes in cv-qualification cannot +be done using \keyword{const_cast}. For instance, conversions between +pointers to functions are not covered because such conversions lead to +values whose use causes undefined behavior. For the same reasons, +conversions between pointers to member functions, and in particular, the +conversion from a pointer to a const member function to a pointer to a +non-const member function, are not covered. +\end{note} +\indextext{expression!postfix|)} + +\rSec2[expr.unary]{Unary expressions} + +\rSec3[expr.unary.general]{General} + +\pnum +\indextext{expression!unary|(}% +Expressions with unary operators group right-to-left. + +\indextext{expression!unary}% +\indextext{operator!unary}% +\indextext{operator!\idxcode{sizeof}}% +\indextext{operator!cast}% +% +\begin{bnf} +%% Ed. note: character protrusion would misalign operators. +\microtypesetup{protrusion=false} +\nontermdef{unary-expression}\br + postfix-expression\br + unary-operator cast-expression\br + \terminal{++} cast-expression\br + \terminal{--} cast-expression\br + await-expression\br + \keyword{sizeof} unary-expression\br + \keyword{sizeof} \terminal{(} type-id \terminal{)}\br + \keyword{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br + \keyword{alignof} \terminal{(} type-id \terminal{)}\br + noexcept-expression\br + new-expression\br + delete-expression\br + reflect-expression +\end{bnf} + +\indextext{operator!indirection}% +\indextext{\idxcode{*}|see{operator, indirection}}% +\indextext{operator!address-of}% +\indextext{\idxcode{\&}|see{operator, address-of}}% +\indextext{operator!unary minus}% +\indextext{\idxcode{-}|see{operator, unary minus}}% +\indextext{operator!unary plus}% +\indextext{\idxcode{+}|see{operator, unary plus}}% +\indextext{operator!logical negation}% +\indextext{\idxcode{"!}|see{operator, logical negation}}% +\indextext{operator!ones' complement}% +\indextext{~@\tcode{\~}|see{operator, ones' complement}}% +\indextext{operator!increment}% +\indextext{operator!decrement}% +% +\begin{bnf} +%% Ed. note: character protrusion would misalign operators. +\microtypesetup{protrusion=false} +\nontermdef{unary-operator} \textnormal{one of}\br + \terminal{* \& + - ! \~} +\end{bnf} + +\rSec3[expr.unary.op]{Unary operators} + +\pnum +\indextext{expression!unary operator}% +\indextext{operator!unary}% +The unary \tcode{*} operator performs \defn{indirection}. +\indextext{dereferencing|see{indirection}}% +Its operand shall be a prvalue of type ``pointer to \tcode{T}'', +where \tcode{T} is an object or function type. +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}. +\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 +\cv{} \keyword{void}) is valid. The lvalue thus obtained can be +used in limited ways (to initialize a reference, for example); this +lvalue must not be converted to a prvalue, see~\ref{conv.lval}. +\end{note} + +\pnum +Each of the following unary operators yields a prvalue. + +\pnum +\indextext{name!address of cv-qualified}% +\indextext{expression!pointer-to-member constant}% +The operand of the unary \tcode{\&} operator +shall be an lvalue of some type \tcode{T}. +\begin{itemize} +\item +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 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}''. +\end{note} +\end{itemize} +\begin{example} +\begin{codeblock} +struct A { int i; }; +struct B : A { }; +... &B::i ... // has type \tcode{int A::*} +int a; +int* p1 = &a; +int* p2 = p1 + 1; // defined behavior +bool b = p2 > p1; // defined behavior, with value \tcode{true} +\end{codeblock} +\end{example} +\begin{note} +A pointer to member formed from a \keyword{mutable} non-static data +member\iref{dcl.stc} does not reflect the \keyword{mutable} specifier +associated with the non-static data member. +\end{note} + +\pnum +A pointer to member is only formed when an explicit \tcode{\&} is used +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 +expression of type ``pointer to member''. Neither does +\tcode{qualified-id}, because there is no implicit conversion from a +\grammarterm{qualified-id} for a non-static member function to the type +``pointer to member function'' as there is from an lvalue of function +type to the type ``pointer to function''\iref{conv.func}. Nor is +\tcode{\&unqualified-id} a pointer to member, even within the scope of +the \grammarterm{unqualified-id}'s class. +\end{note} + +\pnum +If \tcode{\&} is applied to an lvalue of incomplete class type and the +complete type declares \tcode{\keyword{operator}\&()}, it is unspecified whether +the operator has the built-in meaning or the operator function is +called. The operand of \tcode{\&} shall not be a bit-field. + +\pnum +\indextext{overloaded function!address of}% +\begin{note} +The address of an overload set\iref{over} can be taken +only in a context that uniquely determines +which function is referred to (see~\ref{over.over}). +Since the context can affect whether the operand is a static or +non-static member function, the context can also affect whether the +expression has type ``pointer to function'' or ``pointer to member +function''. +\end{note} + +\pnum +\indextext{operator!unary plus}% +The operand of the unary \tcode{+} operator shall be a prvalue of +arithmetic, unscoped +enumeration, or pointer type and the result is the value of the +argument. Integral promotion is performed on integral or enumeration +operands. The type of the result is the type of the promoted operand. + +\pnum +\indextext{operator!unary minus}% +The operand of the unary \tcode{-} operator shall be a prvalue of +arithmetic or unscoped +enumeration type and the result is the negative of its operand. Integral +promotion is performed on integral or enumeration operands. The negative +of an unsigned quantity is computed by subtracting its value from $2^n$, +where $n$ is the number of bits in the promoted operand. The type of the +result is the type of the promoted operand. +\begin{note} +The result is the two's complement of the operand +(where operand and result are considered as unsigned). +\end{note} + +\pnum +\indextext{operator!logical negation}% +The operand of the logical negation operator \tcode{!} is contextually +converted to \keyword{bool}\iref{conv}; +its value is \keyword{true} +if the converted operand is \keyword{false} and \keyword{false} otherwise. +The type of the result is \keyword{bool}. + +\pnum +\indextext{operator!ones' complement}% +The operand of the \tcode{\~{}} operator shall be a prvalue of +integral or unscoped enumeration type. +Integral promotions are performed. +The type of the result is the type of the promoted operand. +% FIXME: [basic.fundamental]/p5 uses $x_i$; [expr] uses $\tcode{x}_i$. +Given the coefficients $\tcode{x}_i$ +of the base-2 representation\iref{basic.fundamental} +of the promoted operand \tcode{x}, +the coefficient $\tcode{r}_i$ +of the base-2 representation of the result \tcode{r} +is 1 if $\tcode{x}_i$ is 0, and 0 otherwise. +\begin{note} +The result is the ones' complement of the operand +(where operand and result are considered as unsigned). +\end{note} +There is an ambiguity +in the grammar when \tcode{\~{}} is followed by +a \grammarterm{type-name} or \grammarterm{computed-type-specifier}. +The ambiguity is resolved by treating \tcode{\~{}} as the +operator rather than as the start of an \grammarterm{unqualified-id} +naming a destructor. +\begin{note} +Because the grammar does not permit an operator to follow the +\tcode{.}, \tcode{->}, or \tcode{::} tokens, a \tcode{\~{}} followed by +a \grammarterm{type-name} or \grammarterm{computed-type-specifier} in a +member access expression or \grammarterm{qualified-id} is +unambiguously parsed as a destructor name. +\end{note} + +\rSec3[expr.pre.incr]{Increment and decrement} + +\pnum +\indextext{expression!increment}% +\indextext{expression!decrement}% +\indextext{operator!increment}% +\indextext{operator!decrement}% +\indextext{prefix \tcode{++}}% +\indextext{prefix \tcode{--}}% +The operand of prefix \tcode{++} or \tcode{--} +shall not be of type \cv{}~\tcode{bool}. +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.assign}. +\begin{note} +For postfix increment and decrement, see~\ref{expr.post.incr}. +\end{note} + +\rSec3[expr.await]{Await} +\indextext{expression!await}% +\indextext{\idxcode{co_await}}% + +\pnum +The \keyword{co_await} expression is used to suspend evaluation of a +coroutine\iref{dcl.fct.def.coroutine} while awaiting completion of +the computation represented by the operand expression. +Suspending the evaluation of a coroutine +transfers control to its caller or resumer. + +\begin{bnf} +\nontermdef{await-expression}\br + \keyword{co_await} cast-expression +\end{bnf} + +\pnum +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 +outside of a \grammarterm{handler}\iref{except.pre}. +In a \grammarterm{declaration-statement} or in the +\grammarterm{simple-declaration} (if any) +of an \grammarterm{init-statement}, an \grammarterm{await-expression} +shall appear only in an \grammarterm{initializer} of that +\grammarterm{declaration-statement} or \grammarterm{simple-declaration}. +An \grammarterm{await-expression} shall not appear in a +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. + +\pnum +Evaluation of an \grammarterm{await-expression} involves the following +auxiliary types, expressions, and objects: + +\begin{itemize} +\item +\placeholder{p} is an lvalue naming the promise +object\iref{dcl.fct.def.coroutine} +of the enclosing coroutine and \tcode{P} is the type of that object. + +\item Unless +the \grammarterm{await-expression} was implicitly produced by +a \grammarterm{yield-expression}\iref{expr.yield}, +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}. +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{)}}; +otherwise, \placeholder{a} is the \grammarterm{cast-expression}. + +\item +\placeholder{o} is determined by enumerating the applicable +\tcode{\keyword{operator} \keyword{co_await}} functions for an argument +\placeholder{a}\iref{over.match.oper}, and choosing the best one through +overload resolution\iref{over.match}. If overload resolution is ambiguous, +the program is ill-formed. +If no viable functions are found, \placeholder{o} is \placeholder{a}. +Otherwise, \placeholder{o} is a call to the selected function +with the argument \placeholder{a}. +If \placeholder{o} would be a prvalue, +the temporary materialization conversion\iref{conv.rval} is applied. + +\item +\placeholder{e} is an lvalue +referring to the result of evaluating +the (possibly-converted) \placeholder{o}. + +\item +% FIXME: h needs to be an expression so we can use it as an argument +% to await_suspend. What should its value category be? +% Don't forget to remove "and objects" from the intro sentence when +% this is fixed. +\placeholder{h} is an object of type +\tcode{std::coroutine_handle

} +referring to the enclosing coroutine. + +\item +\placeholder{await-ready} is the expression +\placeholder{e}\tcode{.await_ready()}, +contextually converted to \tcode{bool}. + +\item +\placeholder{await-suspend} is the expression +\placeholder{e}\tcode{.await_suspend(}\placeholder{h}\tcode{)}, +which shall be a prvalue of type \keyword{void}, \keyword{bool}, or +\tcode{std::coroutine_handle} for some type \tcode{Z}. + +\item +\placeholder{await-resume} is the expression +\placeholder{e}\tcode{.await_resume()}. +\end{itemize} + +\pnum +The \grammarterm{await-expression} has the same type and value category +as the \placeholder{await-resume} expression. + +\pnum +The \grammarterm{await-expression} evaluates +the (possibly-converted) \placeholder{o} expression and +the \placeholder{await-ready} expression, then: +\begin{itemize} +\item +If the result of \placeholder{await-ready} is \keyword{false}, +the coroutine is considered suspended. +Then: +\begin{itemize} +\item +If the type of \placeholder{await-suspend} +is \tcode{std::coroutine_handle}, +\placeholder{await-suspend}\tcode{.resume()} is evaluated. +\begin{note} +This resumes the coroutine referred to +by the result of \placeholder{await-suspend}. +Any number of coroutines can be successively resumed in this fashion, +eventually returning control flow to the current coroutine caller or +resumer\iref{dcl.fct.def.coroutine}. +\end{note} + +\item +Otherwise, if the type of \placeholder{await-suspend} +is \keyword{bool}, +\placeholder{await-suspend} is evaluated, +and the coroutine is resumed if the result is \keyword{false}. + +\item +Otherwise, \placeholder{await-suspend} is evaluated. +\end{itemize} +If the evaluation of \placeholder{await-suspend} +exits via an exception, the exception is caught, +the coroutine is resumed, and the exception is immediately +rethrown\iref{except.throw}. Otherwise, control flow returns +to the current coroutine caller or resumer\iref{dcl.fct.def.coroutine} +without exiting any scopes\iref{stmt.jump}. +\indextext{coroutine!suspend point}% +The point in the coroutine +immediately prior to control returning to its caller or resumer +is a coroutine \defn{suspend point}. + +\item +If the result of \placeholder{await-ready} is \keyword{true}, +or when the coroutine is resumed +other than by rethrowing an exception from \placeholder{await-suspend}, +the \placeholder{await-resume} expression is evaluated, and +its result is the result of the \grammarterm{await-expression}. +\end{itemize} +\begin{note} +With respect to sequencing, +an \grammarterm{await-expression} is indivisible\iref{intro.execution}. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +template +struct my_future { + @\commentellip@ + bool await_ready(); + void await_suspend(std::coroutine_handle<>); + T await_resume(); +}; + +template +auto operator co_await(std::chrono::duration d) { + struct awaiter { + std::chrono::system_clock::duration duration; + @\commentellip@ + awaiter(std::chrono::system_clock::duration d) : duration(d) {} + bool await_ready() const { return duration.count() <= 0; } + void await_resume() {} + void await_suspend(std::coroutine_handle<> h) { @\commentellip@ } + }; + return awaiter{d}; +} + +using namespace std::chrono; + +my_future h(); + +my_future g() { + std::cout << "just about to go to sleep...\n"; + co_await 10ms; + std::cout << "resumed\n"; + co_await h(); +} + +auto f(int x = co_await h()); // error: \grammarterm{await-expression} outside of function suspension context +int a[] = { co_await h() }; // error: \grammarterm{await-expression} outside of function suspension context +\end{codeblock} +\end{example} + +\rSec3[expr.sizeof]{Sizeof} + +\pnum +\indextext{expression!\idxcode{sizeof}}% +\indextext{operator!\idxcode{sizeof}}% +\indextext{byte}% +The \keyword{sizeof} operator yields the number of bytes +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}. +\indextext{type!incomplete}% +The \keyword{sizeof} operator shall not be applied to an expression that +has function or incomplete type, +to the parenthesized name of such +types, or to a glvalue that designates a bit-field. +The result of \keyword{sizeof} +applied to any of the narrow character types is \tcode{1}. +The result of +\keyword{sizeof} applied to any other fundamental +type\iref{basic.fundamental} is \impldef{\tcode{sizeof} applied to +fundamental types +other than \tcode{char}, \tcode{signed char}, and \tcode{unsigned char}}. +\begin{note} +In particular, the values of \tcode{\keyword{sizeof}(\keyword{bool})}, \tcode{\keyword{sizeof}(\keyword{char16_t})}, +\tcode{\keyword{sizeof}(\keyword{char32_t})}, and \tcode{\keyword{sizeof}(\keyword{wchar_t})} are +implementation-defined. +\begin{footnote} +\tcode{\keyword{sizeof}(\keyword{bool})} is not required to be \tcode{1}. +\end{footnote} +\end{note} +\begin{note} +See~\ref{intro.memory} for the definition of byte +and~\ref{term.object.representation} for the definition of object representation. +\end{note} + +\pnum +\indextext{reference!\idxcode{sizeof}}% +When applied to a reference type, the result is the size +of the referenced type. +\indextext{class object!\idxcode{sizeof}}% +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. +\begin{footnote} +The actual size of a potentially-overlapping subobject +can be less than the result of +applying \keyword{sizeof} to the subobject, due to virtual base classes +and less strict padding requirements on potentially-overlapping subobjects. +\end{footnote} +\indextext{array!\idxcode{sizeof}}% +When applied to an array, the result is the total number of bytes in the +array. This implies that the size of an array of $n$ elements is +$n$ times the size of an element. + +\pnum +The lvalue-to-rvalue\iref{conv.lval}, +array-to-pointer\iref{conv.array}, and +function-to-pointer\iref{conv.func} standard conversions are not +applied to the operand of \keyword{sizeof}. +If the operand is a prvalue, +the temporary materialization conversion\iref{conv.rval} +is applied. + +\pnum +The \grammarterm{identifier} in a \tcode{\keyword{sizeof}...} expression shall name a +pack. The \tcode{\keyword{sizeof}...} operator yields the number of elements +in the pack\iref{temp.variadic}. +A \tcode{\keyword{sizeof}...} expression is a pack expansion\iref{temp.variadic}. +\begin{example} +\begin{codeblock} +template +struct count { + static constexpr std::size_t value = sizeof...(Types); +}; +\end{codeblock} +\end{example} + +\pnum +\indextext{\idxcode{size_t}}% +\indexlibraryglobal{size_t}% +The result of \keyword{sizeof} and \tcode{\keyword{sizeof}...} is a prvalue of type +\tcode{std::size_t}. +\begin{note} +A \keyword{sizeof} expression +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} + +\rSec3[expr.alignof]{Alignof} + +\pnum +\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} +representing a complete object type, or an array thereof, or a reference +to one of those types. + +\pnum +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.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} + +\pnum +When \keyword{alignof} is applied to a reference type, the result +is the alignment of the referenced type. When \keyword{alignof} +is applied to an array type, the result is the alignment of the +element type. + +\rSec3[expr.unary.noexcept]{\tcode{noexcept} operator} + +\indextext{\idxcode{noexcept}}% +\indextext{expression!\idxcode{noexcept}}% + +\begin{bnf} +\nontermdef{noexcept-expression}\br + \keyword{noexcept} \terminal{(} expression \terminal{)} +\end{bnf} + +\pnum +The operand of the \keyword{noexcept} operator +is an unevaluated operand\iref{term.unevaluated.operand}. +If the operand is a prvalue, +the temporary materialization conversion\iref{conv.rval} is applied. + +\pnum +The result of the \keyword{noexcept} operator is a prvalue of type \keyword{bool}. +The result is \tcode{false} if +the full-expression of the operand is potentially-throwing\iref{except.spec}, and +\tcode{true} otherwise. +\begin{note} +A \grammarterm{noexcept-expression} +is an integral constant expression\iref{expr.const.const}. +\end{note} +\indextext{expression!unary|)} + +\rSec3[expr.new]{New} + +\pnum +\indextext{expression!\idxcode{new}}% +\indextext{free store|seealso{\tcode{new}}}% +\indextext{free store|seealso{\tcode{delete}}}% +\indextext{memory management|see{\tcode{new}}}% +\indextext{memory management|see{\tcode{delete}}}% +\indextext{storage management|see{\tcode{new}}}% +\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 +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}, +but not an abstract class type\iref{class.abstract} or array +thereof\iref{intro.object}. +\begin{note} +Because references are not objects, references cannot be created by +\grammarterm{new-expression}{s}. +\end{note} +\begin{note} +The \grammarterm{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} +\end{bnf} + +\indextext{\idxcode{new}!storage allocation}% +% +\begin{bnf} +\nontermdef{new-placement}\br + \terminal{(} expression-list \terminal{)} +\end{bnf} + +\begin{bnf} +\nontermdef{new-type-id}\br + type-specifier-seq \opt{new-declarator} +\end{bnf} + +\begin{bnf} +\nontermdef{new-declarator}\br + ptr-operator \opt{new-declarator} \br + noptr-new-declarator +\end{bnf} + +\begin{bnf} +\nontermdef{noptr-new-declarator}\br + \terminal{[} \opt{expression} \terminal{]} \opt{attribute-specifier-seq}\br + noptr-new-declarator \terminal{[} constant-expression \terminal{]} \opt{attribute-specifier-seq} +\end{bnf} + +\begin{bnf} +\nontermdef{new-initializer}\br + \terminal{(} \opt{expression-list} \terminal{)}\br + braced-init-list +\end{bnf} + +\pnum +If a placeholder type\iref{dcl.spec.auto} or +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}, +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 +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}: + +\begin{codeblock} +T x @\textrm{\placeholder{init}}@ ; +\end{codeblock} + +\begin{example} +\begin{codeblock} +new auto(1); // allocated type is \tcode{int} +auto x = new auto('a'); // allocated type is \tcode{char}, \tcode{x} is of type \tcode{char*} + +template struct A { A(T, T); }; +auto y = new A{1, 2}; // allocated type is \tcode{A} +\end{codeblock} +\end{example} + +\pnum +The \grammarterm{new-type-id} in a \grammarterm{new-expression} is the longest +possible sequence of \grammarterm{new-declarator}{s}. +\begin{note} +This prevents ambiguities between the declarator operators \tcode{\&}, \tcode{\&\&}, +\tcode{*}, and \tcode{[]} and their expression counterparts. +\end{note} +\begin{example} +\begin{codeblock} +new int * i; // syntax error: parsed as \tcode{(new int*) i}, not as \tcode{(new int)*i} +\end{codeblock} +The \tcode{*} is the pointer declarator and not the multiplication +operator. +\end{example} + +\pnum +\begin{note} +\indextext{ambiguity!parentheses and}% +Parentheses in a \grammarterm{new-type-id} of a \grammarterm{new-expression} +can have surprising effects. +\begin{example} +\begin{codeblock} +new int(*[10])(); // error +\end{codeblock} +is ill-formed because the binding is +\begin{codeblock} +(new int) (*[10])(); // error +\end{codeblock} + +Instead, the explicitly parenthesized version of the \keyword{new} +operator can be used to create objects of compound +types\iref{basic.compound}: + +\begin{codeblock} +new (int (*[10])()); +\end{codeblock} +allocates an array of \tcode{10} pointers to functions (taking no +argument and returning \tcode{int}). +\end{example} +\end{note} + +\pnum +The \grammarterm{attribute-specifier-seq} in a \grammarterm{noptr-new-declarator} appertains +to the associated array type. + +\pnum +Every \grammarterm{constant-expression} in a +\grammarterm{noptr-new-declarator} shall be a converted constant +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}, +\tcode{new float[n][5]} is well-formed (because \tcode{n} is the +\grammarterm{expression} of a \grammarterm{noptr-new-declarator}), but +\tcode{new float[5][n]} is ill-formed (because \tcode{n} is not a +constant expression). +Furthermore, +\tcode{new float[0]} is well-formed +(because \tcode{0} is the \grammarterm{expression} +of a \grammarterm{noptr-new-declarator}, +where a value of zero results in the allocation of an array with no elements), +but \tcode{new float[n][0]} is ill-formed +(because \tcode{0} is the \grammarterm{constant-expression} +of a \grammarterm{noptr-new-declarator}, +where only values greater than zero are allowed). +\end{example} + +\pnum +If the \grammarterm{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, +where \tcode{n} is determined from the number of initial elements +supplied in +the \grammarterm{new-initializer}\iref{dcl.init.aggr,dcl.init.string}. + +\pnum +\indextext{\idxcode{new}}% +If the \grammarterm{expression} in a \grammarterm{noptr-new-declarator} +is present, it is implicitly converted to \tcode{std::size_t}. +\indextext{function!allocation}% +The value of the \grammarterm{expression} is invalid if +\begin{itemize} +\item +the expression is of non-class type and its value before converting to +\tcode{std::size_t} is less than zero; + +\item +the expression is of class type and its value before application of the second +standard conversion\iref{over.ics.user} +\begin{footnote} +If the conversion function +returns a signed integer type, the second standard conversion converts to the +unsigned type \tcode{std::size_t} and thus thwarts any attempt to detect a +negative value afterwards. +\end{footnote} +is less than zero; + +\item +its value is such that the size of the allocated object would exceed the +\impldef{maximum size of an allocated object} limit\iref{implimits}; or + +\item +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. +\end{itemize} + +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, +the program is ill-formed; +\item +otherwise, an allocation function is not called; instead +\begin{itemize} +\item +if the allocation function that would have been called +has a non-throwing exception specification\iref{except.spec}, +the value of the \grammarterm{new-expression} +is the null pointer value of the required result type; +\item +otherwise, the \grammarterm{new-expression} terminates by throwing an +exception of a type that would match a handler\iref{except.handle} of type +\tcode{std::bad_array_new_length}\iref{new.badlength}. +\end{itemize} +\end{itemize} +When the value of the \grammarterm{expression} is zero, the allocation +function is called to allocate an array with no elements. + +\pnum +If the allocated type is an array, +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 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{new-initializer}, +requiring initialization of the remainder of the array elements as appropriate. +\end{note} + +\pnum +\indextext{storage duration!dynamic}% +Objects created by a \grammarterm{new-expression} have dynamic storage +duration\iref{basic.stc.dynamic}. +\begin{note} +\indextext{\idxcode{new}!scoping and}% +The lifetime of such an object is not necessarily restricted to the +scope in which it is created. +\end{note} + +\pnum +\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), +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; +the \grammarterm{new-expression} +is a prvalue of type ``pointer to T'' +that points to the object created. +\begin{note} +Both \tcode{\keyword{new} \keyword{int}} and \tcode{\keyword{new} \keyword{int}[10]} have type \tcode{\keyword{int}*} and +the type of \tcode{\keyword{new} \keyword{int}[i][10]} is \tcode{\keyword{int} (*)[10]}. +\end{note} + +\pnum +A \grammarterm{new-expression} may obtain storage for the object by calling an +allocation function\iref{basic.stc.dynamic.allocation}. If +the \grammarterm{new-expression} terminates by throwing an exception, it +may release storage by calling a deallocation +function\iref{basic.stc.dynamic.deallocation}. If the allocated type +is a non-array type, the allocation function's name is +\indextext{\idxcode{operator new}}% +\indextext{\idxcode{operator delete}}% +\tcode{\keyword{operator} \keyword{new}} and the deallocation function's name is +\tcode{\keyword{operator} \keyword{delete}}. If the allocated type is an array type, the +allocation function's name is +\indextext{\idxcode{operator new}}% +\indextext{\idxcode{operator delete}}% +\tcode{\keyword{operator} \keyword{new}[]} +and the deallocation function's name is +\tcode{\keyword{operator} \keyword{delete}[]}. +\begin{note} +An implementation is expected to provide default definitions for the global +allocation +functions\iref{basic.stc.dynamic,new.delete.single,new.delete.array}. +A \Cpp{} program can provide alternative definitions of +these functions\iref{replacement.functions} and/or class-specific +versions\iref{class.free}. +The set of allocation and deallocation functions that can be called +by a \grammarterm{new-expression} +can include functions that do not perform allocation or deallocation; +for example, see \ref{new.delete.placement}. +\end{note} + +\pnum +\indextext{operator!scope resolution}% +If the \grammarterm{new-expression} +does not begin with a unary \tcode{::} operator and +the allocated type is a class type \tcode{T} or array thereof, +a search is performed for the allocation function's name in the scope +of \tcode{T}\iref{class.member.lookup}. +Otherwise, or if nothing is found, +the allocation function's name is looked up by +searching for it in the global scope. + +\pnum +An implementation is allowed to omit a call to a replaceable global allocation +function\iref{new.delete.single,new.delete.array}. When it does so, +the storage is instead provided by the implementation or provided by extending +the allocation of another \grammarterm{new-expression}. + +\pnum +During an evaluation of a constant expression, +a call to a replaceable allocation function is always omitted\iref{expr.const.core}. + +\pnum +The implementation may +extend the allocation of a \grammarterm{new-expression} \tcode{e1} to provide +storage for a \grammarterm{new-expression} \tcode{e2} if the +following would be true were the allocation not extended: +\begin{itemize} +\item the evaluation of \tcode{e1} is sequenced before the evaluation of +\tcode{e2}, and + +\item \tcode{e2} is evaluated whenever \tcode{e1} obtains storage, and + +\item both \tcode{e1} and \tcode{e2} invoke the same replaceable global +allocation function, and + +\item if the allocation function invoked by \tcode{e1} and \tcode{e2} is +throwing, any exceptions thrown in the evaluation of either \tcode{e1} or +\tcode{e2} would be first caught in the same handler, and + +\item the pointer values produced by \tcode{e1} and \tcode{e2} are operands to +evaluated \grammarterm{delete-expression}{s}, and + +\item the evaluation of \tcode{e2} is sequenced before the evaluation of the +\grammarterm{delete-expression} whose operand is the pointer value produced +by \tcode{e1}. +\end{itemize} + +\begin{example} +\begin{codeblock} +void can_merge(int x) { + // These allocations are safe for merging: + std::unique_ptr a{new (std::nothrow) char[8]}; + std::unique_ptr b{new (std::nothrow) char[8]}; + std::unique_ptr c{new (std::nothrow) char[x]}; + + g(a.get(), b.get(), c.get()); +} + +void cannot_merge(int x) { + std::unique_ptr a{new char[8]}; + try { + // Merging this allocation would change its catch handler. + std::unique_ptr b{new char[x]}; + } catch (const std::bad_alloc& e) { + std::cerr << "Allocation failed: " << e.what() << std::endl; + throw; + } +} +\end{codeblock} +\end{example} + +\pnum +When a \grammarterm{new-expression} calls an allocation function and that +allocation has not been extended, the +\grammarterm{new-expression} passes the amount of space requested to the +allocation function as the first argument of type +\tcode{std::size_t}. That argument shall be no less than the size +of the object being created; it may be greater than the size of the +object being created only if the object is an array and +the allocation function is not a non-allocating form\iref{new.delete.placement}. +For arrays of +\keyword{char}, \tcode{\keyword{unsigned} \keyword{char}}, and \tcode{std::byte}, +the difference between the +result of the \grammarterm{new-expression} and the address returned by the +allocation function shall be an integral multiple of the +strictest fundamental +alignment requirement\iref{basic.align} of any object type whose size +is no greater than the size of the array being created. +\begin{note} +\indextext{allocation!alignment storage}% +Because allocation functions are assumed to return pointers to storage +that is appropriately aligned for objects of any type +with fundamental alignment, this constraint +on array allocation overhead permits the common idiom of allocating +character arrays into which objects of other types will later be placed. +\end{note} + +\pnum +When a \grammarterm{new-expression} calls an allocation function and that +allocation has been extended, the size argument to the allocation call shall +be no greater than the sum of the sizes for the omitted calls as specified +above, plus the size for the extended call had it not been extended, plus any +padding necessary to align the allocated objects within the allocated memory. + +\pnum +\indextext{placement new-expression@placement \gterm{new-expression}|see{\gterm{new-expression}, placement}}% +The \grammarterm{new-placement} syntax is used to supply additional +arguments to an allocation function; such an expression is called +a \defnx{placement \grammarterm{new-expression}}{\idxgram{new-expression}!placement}. + +\pnum +Overload resolution is +performed on a function call created by assembling an argument list. +The first argument is +the amount of space requested, +and has type \tcode{std::size_t}. +If the type of the allocated object has new-extended alignment, +the next argument is +the type's alignment, +and has type \tcode{std::align_val_t}. +If the \grammarterm{new-placement} syntax is used, +the \grammarterm{initializer-clause}{s} +in its \grammarterm{expression-list} +are the succeeding arguments. +If no matching function is found then +\begin{itemize} + +\item +if the allocated object type has new-extended alignment, +the alignment argument is removed from the argument list; + +\item +otherwise, an argument that +is the type's alignment and has type \tcode{std::align_val_t} +is added into the argument list immediately after the first argument; + +\end{itemize} +and then overload resolution is performed again. + +\pnum +\begin{example} +\begin{itemize} +\item \tcode{new T} results in one of the following calls: +\begin{codeblock} +operator new(sizeof(T)) +operator new(sizeof(T), std::align_val_t(alignof(T))) +\end{codeblock} +\item \tcode{new(2,f) T} results in one of the following calls: +\begin{codeblock} +operator new(sizeof(T), 2, f) +operator new(sizeof(T), std::align_val_t(alignof(T)), 2, f) +\end{codeblock} +\item \tcode{new T[5]} results in one of the following calls: +\begin{codeblock} +operator new[](sizeof(T) * 5 + x) +operator new[](sizeof(T) * 5 + x, std::align_val_t(alignof(T))) +\end{codeblock} +\item \tcode{new(2,f) T[5]} results in one of the following calls: +\begin{codeblock} +operator new[](sizeof(T) * 5 + x, 2, f) +operator new[](sizeof(T) * 5 + x, std::align_val_t(alignof(T)), 2, f) +\end{codeblock} +\end{itemize} +Here, each instance of \tcode{x} is a non-negative unspecified value +representing array allocation overhead; the result of the +\grammarterm{new-expression} will be offset by this amount from the value +returned by \tcode{operator new[]}. This overhead may be applied in all +array \grammarterm{new-expression}{s}, including those referencing +a placement allocation function, except when referencing +the library function \tcode{operator new[](std::size_t, void*)}. +The amount of overhead may vary from one +invocation of \keyword{new} to another. +\end{example} + +\pnum +\begin{note} +Unless an allocation function has a non-throwing +exception specification\iref{except.spec}, +it indicates failure to allocate storage by throwing a +\indextext{\idxcode{bad_alloc}}% +\indexlibraryglobal{bad_alloc}% +\tcode{std::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 +and a non-null pointer otherwise. +\end{note} +If the allocation function is a non-allocating +form\iref{new.delete.placement} that returns null, +the behavior is undefined. +Otherwise, +if the allocation function returns null, initialization shall not be +done, the deallocation function shall not be called, and the value of +the \grammarterm{new-expression} shall be null. + +\pnum +\begin{note} +When the allocation function returns a value other than null, it must be +a pointer to a block of storage in which space for the object has been +reserved. The block of storage is assumed to be +appropriately aligned\iref{basic.align} +and of the requested size. The address of the created object will not +necessarily be the same as that of the block if the object is an array. +\end{note} + +\pnum +\indextext{\idxcode{new}!array of class objects and}% +\indextext{\idxcode{new}!initialization and}% +\indextext{\idxcode{new}!constructor and}% +\indextext{\idxcode{new}!default constructor and}% +A \grammarterm{new-expression} that creates an object of type \tcode{T} +initializes that object as follows: + +\begin{itemize} +\item If the \grammarterm{new-initializer} is omitted, the object is +default-initialized\iref{dcl.init}. +\begin{note} +If no initialization +is performed, the object has an indeterminate value. +\end{note} + +\item Otherwise, the \grammarterm{new-initializer} is interpreted according to +the initialization rules of~\ref{dcl.init} for direct-initialization. +\end{itemize} + +\pnum +\indextext{\idxcode{new}!unspecified order of evaluation}% +\indextext{\idxcode{new}!unspecified constructor and}% +The invocation of the allocation function is sequenced before +the evaluations of expressions in the \grammarterm{new-initializer}. Initialization of +the allocated object is sequenced before the +\indextext{value computation}% +value computation of the +\grammarterm{new-expression}. + +\pnum +If the \grammarterm{new-expression} +creates an array of objects of class type, the destructor is potentially +invoked\iref{class.dtor}. + +\pnum +\indextext{\idxcode{new}!exception and}% +If any part of the object initialization described above% +\begin{footnote} +This can +include evaluating a \grammarterm{new-initializer} and/or calling +a constructor. +\end{footnote} +terminates by throwing an exception and a suitable deallocation function +can be found, the deallocation function is called to free the memory in +which the object was being constructed, after which the exception +continues to propagate in the context of the \grammarterm{new-expression}. +If no unambiguous matching deallocation function can be found, +propagating the exception does not cause the object's memory to be +freed. +\begin{note} +This is appropriate when the called allocation function does not +allocate memory; otherwise, it is likely to result in a memory leak. +\end{note} + +\pnum +If the \grammarterm{new-expression} does not begin with +a unary \tcode{::} operator and +the allocated type is a class type \tcode{T} or an array thereof, +a search is performed for the deallocation function's name +in the scope of \tcode{T}. +Otherwise, or if nothing is found, +the deallocation function's name is looked up by +searching for it in the global scope. + +\pnum +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 -A null pointer value~(\ref{conv.ptr}) is converted to the null pointer -value of the destination type. The null member pointer -value~(\ref{conv.mem}) is converted to the null member pointer value of -the destination type. +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 { + // Placement allocation function: + static void* operator new(std::size_t, std::size_t); + + // Usual (non-placement) deallocation function: + static void operator delete(void*, std::size_t); +}; + +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 -\enternote -Depending on the type of the object, a write operation through the -pointer, lvalue or pointer to data member resulting from a -\tcode{const_cast} that casts away a const-qualifier\footnote{\tcode{const_cast} -is not limited to conversions that cast away a -const-qualifier.} -may produce undefined behavior~(\ref{dcl.type.cv}). -\exitnote +If a \grammarterm{new-expression} calls a deallocation function, it passes +the value returned from the allocation function call as the first +argument of type \tcode{\keyword{void}*}. If a placement deallocation function is +called, it is passed the same additional arguments as were passed to the +placement allocation function, that is, the same arguments as those +specified with the \grammarterm{new-placement} syntax. +If the implementation is allowed +to introduce a temporary object or make a copy of any argument +as part of the call to the allocation function, +it is unspecified whether the same object is used in the call +to both the allocation and deallocation functions. + +\rSec3[expr.delete]{Delete} \pnum -\indextext{\idxcode{const}!cast away}% -A conversion from a type \tcode{T1} to a type \tcode{T2} -\defnx{casts away constness}{casting away constness} -if \tcode{T1} and \tcode{T2} are different, -there is a cv-decomposition~(\ref{conv.qual}) of \tcode{T1} -yielding \placeholder{n} such that -\tcode{T2} has a cv-decomposition of the form +\indextext{expression!\idxcode{delete}}% +\indextext{\idxcode{delete}}% +The \grammarterm{delete-expression} operator destroys a most derived +object\iref{intro.object} or array created by a +\grammarterm{new-expression}. -\begin{indented} -$cv_0^2$ $P_0^2$ $cv_1^2$ $P_1^2$ $\cdots$ $cv_{n-1}^2$ $P_{n-1}^2$ $cv_n^2$ $\mathtt{U}_2$, -\end{indented} +\begin{bnf} +\nontermdef{delete-expression}\br + \opt{\terminal{::}} \keyword{delete} cast-expression\br + \opt{\terminal{::}} \keyword{delete} \terminal{[} \terminal{]} cast-expression +\end{bnf} -and there is no qualification conversion that converts \tcode{T1} to +The first alternative is a +\defnx{single-object delete expression}{delete!single-object}, and the +second is an \defnx{array delete expression}{delete!array}. +Whenever the \keyword{delete} keyword is immediately followed by empty square +brackets, it shall be interpreted as the second alternative. +\begin{footnote} +A +\grammarterm{lambda-expression} with a \grammarterm{lambda-introducer} +that consists of empty square brackets can follow the \keyword{delete} keyword +if the \grammarterm{lambda-expression} is enclosed in parentheses. +\end{footnote} +If the operand is of +class type, it is contextually implicitly converted\iref{conv} +to a pointer to object +type +and the converted operand is used in place of the original operand +for the remainder of this subclause. +Otherwise, it shall be a prvalue of pointer to object type. +The \grammarterm{delete-expression} has type +\keyword{void}. + +\pnum +\indextext{\idxcode{delete}!single-object}% +In a single-object delete expression, the value of the operand of +\keyword{delete} may be a null pointer value, +a pointer value +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. +\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 +a previous array \grammarterm{new-expression} whose +allocation function was not a non-allocating form\iref{new.delete.placement}. +\begin{footnote} +For nonzero-length +arrays, this is the same as a pointer to the first +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. +\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 +\grammarterm{new-expression}. +\end{note} +\begin{note} +A pointer to a \keyword{const} type can be the operand of a +\grammarterm{delete-expression}; it is not necessary to cast away the +constness\iref{expr.const.cast} of the pointer expression before it is +used as the operand of the \grammarterm{delete-expression}. +\end{note} -\begin{indented} -$cv_0^2$ $P_0^1$ $cv_1^2$ $P_1^1$ $\cdots$ $cv_{n-1}^2$ $P_{n-1}^1$ $cv_n^2$ $\mathtt{U}_1$. -\end{indented} +\pnum +\indextext{\idxcode{delete}!undefined}% +In a single-object delete expression, if the static type of the object to be +deleted is not similar\iref{conv.qual} to its dynamic type +and the selected deallocation function (see below) +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 +expression, if the dynamic type of the object to be deleted is not similar to +its static type, the behavior is undefined. \pnum -Casting from an lvalue of type \tcode{T1} to an lvalue of type -\tcode{T2} using an lvalue reference cast -or casting from an expression of type \tcode{T1} to an xvalue of type \tcode{T2} using -an rvalue reference cast -casts away constness if a cast from a prvalue of type ``pointer to \tcode{T1}'' to the type ``pointer to -\tcode{T2}'' casts away constness. +\indextext{type!incomplete}% +If the object being deleted has incomplete class type at the point of deletion, +the program is ill-formed. \pnum -\enternote -some conversions which involve only changes in cv-qualification cannot -be done using \tcode{const_cast.} For instance, conversions between -pointers to functions are not covered because such conversions lead to -values whose use causes undefined behavior. For the same reasons, -conversions between pointers to member functions, and in particular, the -conversion from a pointer to a const member function to a pointer to a -non-const member function, are not covered. -\exitnote% -\indextext{expression!postfix|)} +\indextext{\idxcode{delete}!destructor and}% +If the value of the operand of the \grammarterm{delete-expression} is not a +null pointer value +and the selected deallocation function (see below) +is not a destroying operator delete, +evaluating the \grammarterm{delete-expression} invokes the +destructor (if any) for the object or the elements of the array being +deleted. +The destructor shall be accessible from the point where +the \grammarterm{delete-expression} appears. +In the case of an array, the elements are destroyed in +order of decreasing address (that is, in reverse order of the completion +of their constructor; see~\ref{class.base.init}). + +\pnum +If the value of the operand of the \grammarterm{delete-expression} is not a +null pointer value, then: + +\begin{itemize} +\item +If the allocation call for the \grammarterm{new-expression} for the object to +be deleted was not omitted and the allocation was not extended\iref{expr.new}, the +\grammarterm{delete-expression} shall call a deallocation +function\iref{basic.stc.dynamic.deallocation}. The value returned from the +allocation call of the \grammarterm{new-expression} shall be passed as the +first argument to the deallocation function. + +\item +Otherwise, if the allocation was extended or was provided by extending the +allocation of another \grammarterm{new-expression}, and the +\grammarterm{delete-expression} for every other pointer value produced by a +\grammarterm{new-expression} that had storage provided by the extended +\grammarterm{new-expression} has been evaluated, the +\grammarterm{delete-expression} shall call a deallocation function. The value +returned from the allocation call of the extended \grammarterm{new-expression} +shall be passed as the first argument to the deallocation function. -\rSec1[expr.unary]{Unary expressions} +\item +Otherwise, the \grammarterm{delete-expression} will not call a +deallocation function. +\end{itemize} +\begin{note} +The deallocation function is called regardless of whether the destructor +for the object or some element of the array throws an exception. +\end{note} +If the value of the operand of the \grammarterm{delete-expression} is a +null pointer value, it is unspecified whether a deallocation function will be +called as described above. \pnum -\indextext{expression!unary|(}% -Expressions with unary operators group right-to-left. +If a deallocation function is called, +it is \tcode{\keyword{operator} \keyword{delete}} for a single-object delete expression or +\tcode{\keyword{operator} \keyword{delete}[]} for an array delete expression. +\begin{note} +\indextext{\idxcode{operator delete}}% +An implementation provides default definitions of the global +deallocation functions\iref{new.delete.single,new.delete.array}. +A \Cpp{} program can provide alternative definitions of these +functions\iref{replacement.functions}, and/or class-specific +versions\iref{class.free}. +\end{note} + +\pnum +If the keyword \keyword{delete} in a \grammarterm{delete-expression} +is not preceded by the unary \tcode{::} operator and the type of the operand is +a pointer to a (possibly cv-qualified) class type \tcode{T} +or (possibly multidimensional) array thereof: +\begin{itemize} +\item +For a single-object delete expression, +if the operand is a pointer to \cv{} \tcode{T} and +\tcode{T} has a virtual destructor, +the deallocation function is the one selected at the point of definition of +the dynamic type's virtual destructor\iref{class.dtor}. +\item +Otherwise, +a search is performed for the deallocation function's name +in the scope of \tcode{T}. +\end{itemize} +Otherwise, or if nothing is found, +the deallocation function's name is looked up by +searching for it in the global scope. +In any case, any declarations +other than of usual deallocation functions\iref{basic.stc.dynamic.deallocation} +are discarded. +\begin{note} +If only a placement deallocation function is found in a class, +the program is ill-formed because the lookup set is empty\iref{basic.lookup}. +\end{note} + +\pnum +The deallocation function to be called is selected as follows: +\begin{itemize} +\item +If any of the deallocation functions is a destroying operator delete, +all deallocation functions that are not destroying operator deletes +are eliminated from further consideration. +\item +If the type has new-extended alignment, +a function with a parameter of type \tcode{std::align_val_t} is preferred; +otherwise a function without such a parameter is preferred. +If any preferred functions are found, +all non-preferred functions are eliminated from further consideration. +\item +If exactly one function remains, +that function is selected and the selection process terminates. +\item +If the deallocation functions belong to a class scope, +the one without a parameter of type \tcode{std::size_t} is selected. +\item +If the type is complete +and if, for an array delete expression only, +the operand is a pointer to a class type with a +non-trivial destructor or a (possibly multidimensional) array thereof, +the function with a parameter of type \tcode{std::size_t} is selected. +\item +Otherwise, it is unspecified +whether a deallocation function with a parameter of type \tcode{std::size_t} +is selected. +\end{itemize} +Unless the deallocation function is selected +at the point of definition of the dynamic type's virtual destructor, +the selected deallocation function shall be accessible +from the point where the \grammarterm{delete-expression} appears. + +\pnum +For a single-object delete expression, +the deleted object is +the object $A$ pointed to by the operand +if the static type of $A$ does not have a virtual destructor, +and the most-derived object of $A$ otherwise. +\begin{note} +If the deallocation function is not a destroying operator delete +and the deleted object is not the most derived object in the former case, +the behavior is undefined, +as stated above. +\end{note} +For an array delete expression, +the deleted object is +the array object. +When a \grammarterm{delete-expression} +is executed, the selected deallocation function shall be called with +the address of the deleted object +in a single-object delete expression, or +the address of the deleted object +suitably adjusted for the array allocation +overhead\iref{expr.new} in an array delete expression, +as its first argument. +\begin{note} +Any cv-qualifiers in the type of the deleted object +are ignored when forming this argument. +\end{note} +If a destroying operator delete is used, +an unspecified value +is passed as the argument +corresponding to the parameter of type \tcode{std::destroying_delete_t}. +If a deallocation function +with a parameter of type \tcode{std::align_val_t} +is used, +the alignment of the type of the deleted object +is passed as the corresponding argument. +If a deallocation function +with a parameter of type \tcode{std::size_t} is used, +the size of the deleted object +in a single-object delete expression, or +of the array plus allocation overhead +in an array delete expression, +is passed as the corresponding argument. +\begin{note} +If this results in a call to a replaceable deallocation function, +and either +the first argument was not the result of +a prior call to a replaceable allocation function or +the second or third argument was not the corresponding argument in said call, +the behavior is undefined\iref{new.delete.single,new.delete.array}. +\end{note} + +\rSec3[expr.reflect]{The reflection operator} -\indextext{expression!unary}% -\indextext{operator!unary}% -\indextext{operator!\idxcode{sizeof}}% -\indextext{operator!cast}% -% \begin{bnf} -\nontermdef{unary-expression}\br - postfix-expression\br - \terminal{++} cast-expression\br - \terminal{-{-}} cast-expression\br - unary-operator cast-expression\br - \terminal{sizeof} unary-expression\br - \terminal{sizeof (} type-id \terminal{)}\br - \terminal{sizeof ...} \terminal{(} identifier \terminal{)}\br - \terminal{alignof (} type-id \terminal{)}\br - noexcept-expression\br - new-expression\br - delete-expression +\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} -\indextext{operator!indirection}% -\indextext{\idxcode{*}|see{operator, indirection}}% -\indextext{operator!address-of}% -\indextext{\idxcode{\&}|see{operator, address-of}}% -\indextext{operator!unary~minus}% -\indextext{\idxcode{-}|see{operator, unary~minus}}% -\indextext{operator!unary~plus}% -\indextext{\idxcode{+}|see{operator, unary~plus}}% -\indextext{operator!logical negation}% -\indextext{\idxcode{"!}|see{operator, logical~negation}}% -\indextext{operator!one's~complement}% -\indextext{~@\tcode{\tilde}|see{operator, one's~complement}}% -\indextext{operator!increment}% -\indextext{operator!decrement}% -% \begin{bnf} -\nontermdef{unary-operator} \textnormal{one of}\br - \terminal{* \& + - ! \tilde} +\nontermdef{reflection-name}\br + \opt{nested-name-specifier} identifier\br + nested-name-specifier \keyword{template} identifier \end{bnf} -\rSec2[expr.unary.op]{Unary operators} +\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 -\indextext{expression!unary~operator}% -\indextext{operator!unary}% -The unary \tcode{*} operator performs \term{indirection}: -\indextext{dereferencing|seealso{indirection}}% -\indextext{indirection}% -the expression to which it is applied shall be a pointer to an object -type, or a pointer to a function type and the result is an lvalue -referring to the object or function to which the expression points. If -the type of the expression is ``pointer to \tcode{T},'' the type of the -result is ``\tcode{T}.'' -\enternote -\indextext{type!incomplete}% -indirection through a pointer to an incomplete type (other than -\cvqual{cv} \tcode{void}) is valid. The lvalue thus obtained can be -used in limited ways (to initialize a reference, for example); this -lvalue must not be converted to a prvalue, see~\ref{conv.lval}. -\exitnote - -\pnum -The result of each of the following unary operators is a prvalue. - -\pnum -\indextext{name!address~of cv-qualified}% -\indextext{expression!pointer~to~member constant}% -The result of the unary \tcode{\&} operator is a pointer to its operand. -The operand shall be an lvalue or a \grammarterm{qualified-id}. -If the operand is a \grammarterm{qualified-id} naming a non-static or variant member \tcode{m} -of some class \tcode{C} with type \tcode{T}, the result has type ``pointer to member -of class \tcode{C} of type \tcode{T}'' and is a prvalue designating \tcode{C::m}. -Otherwise, if the type of the expression is \tcode{T}, the result has type ``pointer to -\tcode{T}'' and is a prvalue that is the address of the designated object~(\ref{intro.memory}) -or a pointer to the designated function. \enternote In particular, the address of an -object of type ``\cv\ \tcode{T}'' is ``pointer to \cv\ \tcode{T}'', with the same -cv-qualification. \exitnote -For purposes of pointer arithmetic~(\ref{expr.add}) and -comparison~(\ref{expr.rel}, \ref{expr.eq}), -an object that is not an array element whose -address is taken in this way is considered to belong to an array with one -element of type \tcode{T}. -\enterexample +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} -struct A { int i; }; -struct B : A { }; -... &B::i ... // has type \tcode{int A::*} -int a; -int* p1 = &a; -int* p2 = p1 + 1; // defined behavior -bool b = p2 > p1; // defined behavior, with value \tcode{true} +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} -\exitexample -\enternote -a pointer to member formed from a \tcode{mutable} non-static data -member~(\ref{dcl.stc}) does not reflect the \tcode{mutable} specifier -associated with the non-static data member. -\exitnote +\end{example} \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. -\enternote -that is, the expression \tcode{\&(qualified-id)}, where the -\grammarterm{qualified-id} is enclosed in parentheses, does not form an -expression of type ``pointer to member.'' Neither does -\tcode{qualified-id}, because there is no implicit conversion from a -\grammarterm{qualified-id} for a non-static member function to the type -``pointer to member function'' as there is from an lvalue of function -type to the type ``pointer to function''~(\ref{conv.func}). Nor is -\tcode{\&unqualified-id} a pointer to member, even within the scope of -the \grammarterm{unqualified-id}'s class. -\exitnote +A \grammarterm{reflect-expression} of the form \tcode{\caret\caret ::} +represents the global namespace. \pnum -If \tcode{\&} is applied to an lvalue of incomplete class type and the -complete type declares \tcode{operator\&()}, it is unspecified whether -the operator has the built-in meaning or the operator function is -called. The operand of \tcode{\&} shall not be a bit-field. +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}, +$R$ represents that 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 $A$, +$R$ represents the underlying entity of $A$ +if $A$ was introduced by the declaration of a template parameter; +otherwise, $R$ represents $A$. +\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 -\indextext{overloaded~function!address~of}% -The address of an overloaded function (Clause~\ref{over}) can be taken -only in a context that uniquely determines which version of the -overloaded function is referred to (see~\ref{over.over}). -\enternote -since the context might determine whether the operand is a static or -non-static member function, the context can also affect whether the -expression has type ``pointer to function'' or ``pointer to member -function.'' -\exitnote +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 -\indextext{operator!unary~plus}% -The operand of the unary \tcode{+} operator shall have arithmetic, unscoped -enumeration, or pointer type and the result is the value of the -argument. Integral promotion is performed on integral or enumeration -operands. The type of the result is the type of the promoted operand. +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$, +overload resolution for the expression \tcode{\&S} with no target +shall select a unique function\iref{over.over}; +$R$ represents that function. +\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)); -\pnum -\indextext{operator!unary~minus}% -The operand of the unary \tcode{-} operator shall have arithmetic or unscoped -enumeration type and the result is the negation of its operand. Integral -promotion is performed on integral or enumeration operands. The negative -of an unsigned quantity is computed by subtracting its value from $2^n$, -where $n$ is the number of bits in the promoted operand. The type of the -result is the type of the promoted operand. +constexpr std::meta::info a = ^^fn; // OK +constexpr std::meta::info b = ^^fn; // error: ambiguous -\pnum -\indextext{operator!logical negation}% -The operand of the logical negation operator \tcode{!} is contextually -converted to \tcode{bool} -(Clause~\ref{conv}); its value is \tcode{true} -if the converted operand is \tcode{false} and \tcode{false} otherwise. -The type of the result is \tcode{bool}. - -\pnum -\indextext{operator!one's~complement}% -The operand of \tcode{\~{}} shall have integral or unscoped enumeration type; the -result is the one's complement of its operand. Integral promotions are -performed. The type of the result is the type of the promoted operand. -There is an ambiguity in the \grammarterm{unary-expression} -\tcode{\~{}X()}, where \tcode{X} is a \grammarterm{class-name} or \grammarterm{decltype-specifier}. -The -ambiguity is resolved in favor of treating \tcode{\~{}} as a unary -complement rather than treating \tcode{\~{}X} as referring to a -destructor. +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); -\rSec2[expr.pre.incr]{Increment and decrement} +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} -\pnum -\indextext{expression!increment}% -\indextext{expression!decrement}% -The operand of prefix \tcode{++} -\indextext{operator!increment}% -\indextext{prefix~\tcode{++}}% -is modified by adding \tcode{1}, -\indextext{increment!\idxcode{bool}}% -\indextext{prefix~\tcode{\dcr}}% -\indextext{deprecated~features}% -or set to \tcode{true} if it is \tcode{bool} (this use is deprecated). -The operand shall be a modifiable lvalue. The type of the operand shall -be an arithmetic type or a pointer to a completely-defined object type. -The result is the updated operand; it is an lvalue, and it is a -bit-field if the operand is a bit-field. If \tcode{x} is not of type -\tcode{bool}, the expression \tcode{++x} is equivalent to \tcode{x+=1} -\indextext{operator!\idxcode{+=}}% -\enternote -See the discussions of addition~(\ref{expr.add}) and assignment -operators~(\ref{expr.ass}) for information on conversions. -\exitnote +\rSec2[expr.cast]{Explicit type conversion (cast notation)}% +\indextext{expression!cast|(} \pnum -The operand of prefix -\indextext{operator!decrement}% -\tcode{\dcr} is modified by subtracting \tcode{1}. The operand shall not -be of type \tcode{bool}. The requirements on the operand of prefix -\tcode{\dcr} and the properties of its result are otherwise the same as -those of prefix \tcode{++}. -\enternote -For postfix increment and decrement, see~\ref{expr.post.incr}. -\exitnote - -\rSec2[expr.sizeof]{Sizeof} +The result of the expression \tcode{(T)} \grammarterm{cast-expression} is +of type \tcode{T}. The result is an lvalue if \tcode{T} is an lvalue +reference type or an rvalue reference to function type and an xvalue if \tcode{T} +is an rvalue reference to object type; otherwise the result is a prvalue. +\begin{note} +If \tcode{T} is a non-class type that is cv-qualified, the +\grammarterm{cv-qualifier}{s} are discarded when determining the type of the +resulting prvalue; see \ref{expr.prop}. +\end{note} \pnum -\indextext{expression!\idxcode{sizeof}}% -\indextext{operator!\idxcode{sizeof}}% -\indextext{byte}% -The \tcode{sizeof} operator yields the number of bytes in the object -representation of its operand. The operand is either an expression, -which is an unevaluated operand (Clause~\ref{expr}), or a parenthesized -\grammarterm{type-id}. -\indextext{type!incomplete}% -The \tcode{sizeof} operator shall not be applied to an expression that -has function or incomplete type, -to the parenthesized name of such -types, or to a glvalue that designates a bit-field. -\tcode{sizeof(char)}, \tcode{sizeof(signed char)} and -\tcode{sizeof(unsigned char)} are \tcode{1}. The result of -\tcode{sizeof} applied to any other fundamental -type~(\ref{basic.fundamental}) is \impldef{sizeof applied@\tcode{sizeof} applied to -fundamental types -other than \tcode{char}, \tcode{signed char}, and \tcode{unsigned char}}. -\enternote -in particular, \tcode{sizeof(bool)}, \tcode{sizeof(char16_t)}, -\tcode{sizeof(char32_t)}, and \tcode{sizeof(wchar_t)} are -implementation-defined.\footnote{\tcode{sizeof(bool)} is not required to be \tcode{1}.} -\exitnote -\enternote -See~\ref{intro.memory} for the definition of \term{byte} -and~\ref{basic.types} for the definition of \term{object representation}. -\exitnote +An explicit type conversion can be expressed using functional +notation\iref{expr.type.conv}, a type conversion operator +(\keyword{dynamic_cast}, \keyword{static_cast}, \keyword{reinterpret_cast}, +\keyword{const_cast}), or the \term{cast} notation. + +\begin{bnf} +\nontermdef{cast-expression}\br + unary-expression\br + \terminal{(} type-id \terminal{)} cast-expression +\end{bnf} \pnum -\indextext{reference!\idxcode{sizeof}}% -When applied to a reference or a reference type, the result is the size -of the referenced type. -\indextext{class~object!\idxcode{sizeof}}% -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 size of a most derived class shall be greater than -zero~(\ref{intro.object}). The result of applying \tcode{sizeof} to a -base class subobject is the size of the base class type.\footnote{The actual -size of a base class subobject may be less than the result of -applying \tcode{sizeof} to the subobject, due to virtual base classes -and less strict padding requirements on base class subobjects.} -\indextext{array!\idxcode{sizeof}}% -When applied to an array, the result is the total number of bytes in the -array. This implies that the size of an array of \term{n} elements is -\term{n} times the size of an element. +Any type conversion not mentioned below and not explicitly defined by +the user\iref{class.conv} is ill-formed. \pnum -The \tcode{sizeof} operator can be applied to a pointer to a function, -but shall not be applied directly to a function. +The conversions performed by +\begin{itemize} +\indextext{cast!const}% +\indextext{cast!static}% +\indextext{cast!reinterpret}% +\item a \keyword{const_cast}\iref{expr.const.cast}, +\item a \keyword{static_cast}\iref{expr.static.cast}, +\item a \keyword{static_cast} followed by a \keyword{const_cast}, +\item a \keyword{reinterpret_cast}\iref{expr.reinterpret.cast}, or +\item a \keyword{reinterpret_cast} followed by a \keyword{const_cast}, +\end{itemize} +can be performed using the cast notation of explicit type conversion. +The same semantic restrictions and behaviors apply, with the exception +that in performing a \keyword{static_cast} in the following situations the +conversion is valid even if the base class is inaccessible: +\begin{itemize} +\item a pointer to an object of derived class type or an lvalue or +rvalue of derived class type may be explicitly converted to a pointer or +reference to an unambiguous base class type, respectively; -\pnum -The lvalue-to-rvalue~(\ref{conv.lval}), -array-to-pointer~(\ref{conv.array}), and -function-to-pointer~(\ref{conv.func}) standard conversions are not -applied to the operand of \tcode{sizeof}. +\item a pointer to member of derived class type may be explicitly +converted to a pointer to member of an unambiguous non-virtual base +class type; -\pnum -The identifier in a \tcode{sizeof...} expression shall name a parameter -pack. The \tcode{sizeof...} operator yields the number of arguments -provided for the parameter pack \grammarterm{identifier}. -A \tcode{sizeof...} expression is a pack expansion~(\ref{temp.variadic}). -\enterexample +\item a pointer to an object of an unambiguous non-virtual base class +type, a glvalue of an unambiguous non-virtual base class type, +or a pointer to member of an unambiguous non-virtual base class type may +be explicitly converted to a pointer, a reference, or a pointer to +member of a derived class type, respectively. +\end{itemize} +If a conversion can be interpreted in more than one of the ways listed +above, the interpretation that appears first in the list is used, even +if a cast resulting from that interpretation is ill-formed. If a +\keyword{static_cast} followed by a \keyword{const_cast} is used and +the conversion can be interpreted in more than one way as such, +the conversion is +ill-formed. +\begin{example} \begin{codeblock} -template -struct count { - static const std::size_t value = sizeof...(Types); +struct A { }; +struct I1 : A { }; +struct I2 : A { }; +struct D : I1, I2 { }; +A* foo( D* p ) { + return (A*)( p ); // ill-formed \keyword{static_cast} interpretation +} + +int*** ptr = 0; +auto t = (int const*const*const*)ptr; // OK, \keyword{const_cast} interpretation + +struct S { + operator const int*(); + operator volatile int*(); }; +int *p = (int*)S(); // error: two possible interpretations using \keyword{static_cast} followed by \keyword{const_cast} \end{codeblock} -\exitexample +\end{example} \pnum -The result of \tcode{sizeof} and \tcode{sizeof...} is a constant of type -\tcode{std::size_t}. -\enternote -\indextext{\idxcode{size_t}}% -\indexlibrary{\idxcode{size_t}}% -\tcode{std::size_t} is defined in the standard header -\indextext{\idxhdr{cstddef}}% -\tcode{}~(\ref{support.types}). -\exitnote +\indextext{class!cast to incomplete}% +The operand of a cast using the cast notation can be a prvalue of type +``pointer to incomplete class type''. The destination type of a cast +using the cast notation can be ``pointer to incomplete class type''. If +both the operand and destination types are class types and one or both +are incomplete, it is unspecified whether the \keyword{static_cast} or the +\keyword{reinterpret_cast} interpretation is used, even if there is an +inheritance relationship between the two classes. +\begin{note} +For example, if the classes were defined later in the translation unit, +a multi-pass compiler could validly interpret a cast between +pointers to the classes as if the class types were complete at the point +of the cast. +\end{note} +\indextext{expression!cast|)} -\rSec2[expr.new]{New} +\rSec2[expr.mptr.oper]{Pointer-to-member operators} \pnum -\indextext{expression!\idxcode{new}}% -\indextext{free~store|seealso{\tcode{new},~\tcode{delete}}}% -\indextext{memory~management|seealso{\tcode{new},~\tcode{delete}}}% -\indextext{storage~management|see{\tcode{new},~\tcode{delete}}}% -\indextext{\idxcode{new}}% -The \grammarterm{new-expression} attempts to create an object of the -\grammarterm{type-id}~(\ref{dcl.name}) or \grammarterm{new-type-id} to which -it is applied. The type of that object is the \term{allocated type}. -\indextext{type!incomplete}% -This type shall be a complete object type, but not an abstract class -type or array -thereof~(\ref{intro.object},~\ref{basic.types},~\ref{class.abstract}). -It is \impldef{support for over-aligned types} whether over-aligned types are -supported~(\ref{basic.align}). -\enternote -because references are not objects, references cannot be created by -\grammarterm{new-expression}{s}. -\exitnote -\enternote -the \grammarterm{type-id} may be a cv-qualified type, in which case the -object created by the \grammarterm{new-expression} has a cv-qualified type. -\exitnote - -\begin{bnf} -\nontermdef{new-expression}\br - \terminal{::}\opt \terminal{new} new-placement\opt new-type-id new-initializer\opt \br - \terminal{::}\opt \terminal{new} new-placement\opt \terminal{(} type-id \terminal{)} new-initializer\opt -\end{bnf} - -\indextext{\idxcode{new}!storage allocation}% -% -\begin{bnf} -\nontermdef{new-placement}\br - \terminal{(} expression-list \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{new-type-id}\br - type-specifier-seq new-declarator\opt -\end{bnf} - -\begin{bnf} -\nontermdef{new-declarator}\br - ptr-operator new-declarator\opt \br - noptr-new-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{noptr-new-declarator}\br - \terminal{[} expression \terminal{]} attribute-specifier-seq\opt\br - noptr-new-declarator \terminal{[} constant-expression \terminal{]} attribute-specifier-seq\opt -\end{bnf} +\indextext{expression!pointer-to-member}% +\indextext{pointer to member}% +\indextext{operator!pointer to member}% +\indextext{\idxcode{.*}|see{operator, pointer to member}}% +\indextext{operator!pointer to member}% +\indextext{\idxcode{->*}|see{operator, pointer to member}}% +The pointer-to-member operators \tcode{->*} and \tcode{.*} group +left-to-right. \begin{bnf} -\nontermdef{new-initializer}\br - \terminal{(} expression-list\opt \terminal{)}\br - braced-init-list +\nontermdef{pm-expression}\br + cast-expression\br + pm-expression \terminal{.*} cast-expression\br + pm-expression \terminal{->*} cast-expression \end{bnf} -\indextext{storage~duration!dynamic}% -Entities created by a \grammarterm{new-expression} have dynamic storage -duration~(\ref{basic.stc.dynamic}). -\enternote -\indextext{\idxcode{new}!scoping~and}% -the lifetime of such an entity is not necessarily restricted to the -scope in which it is created. -\exitnote -If the entity is a non-array object, the \grammarterm{new-expression} -returns a pointer to the object created. If it is an array, the -\grammarterm{new-expression} returns a pointer to the initial element of -the array. - -\pnum -If a placeholder type~(\ref{dcl.spec.auto}) appears in the -\nonterminal{type-specifier-seq} of a \nonterminal{new-type-id} or -\nonterminal{type-id} of a \nonterminal{new-expression}, -the \nonterminal{new-expression} shall contain a -\nonterminal{new-initializer} of the form - -\begin{ncsimplebnf} -\terminal{(} assignment-expression \terminal{)} -\end{ncsimplebnf} - -The allocated type is deduced from the \nonterminal{new-initializer} as -follows: Let \tcode{e} be the \grammarterm{assignment-expression} in the \nonterminal{new-initializer} and -\tcode{T} be the \nonterminal{new-type-id} or \nonterminal{type-id} of -the \nonterminal{new-expression}, then the allocated type is the type -deduced for the variable \tcode{x} in the invented -declaration~(\ref{dcl.spec.auto}): - -\begin{codeblock} -T x(e); -\end{codeblock} +\pnum +The binary operator \tcode{.*} binds its second operand, which shall be +a prvalue +of type ``pointer to member of \tcode{T}'' to its first operand, which shall be +a glvalue +of +class \tcode{T} or of a class of which \tcode{T} is an unambiguous and +accessible base class. The result is an object or a function of the type +specified by the second operand. -\enterexample -\begin{codeblock} -new auto(1); // allocated type is \tcode{int} -auto x = new auto('a'); // allocated type is \tcode{char}, \tcode{x} is of type \tcode{char*} -\end{codeblock} -\exitexample +\pnum +The binary operator \tcode{->*} binds its second operand, which shall be +a prvalue +of type ``pointer to member of \tcode{T}'' to its first operand, which shall be of +type ``pointer to \tcode{U}'' +where \tcode{U} is either \tcode{T} or +a class of which \tcode{T} +is an unambiguous and accessible base class. +The expression \tcode{E1->*E2} is converted into the equivalent form +\tcode{(*(E1)).*E2}. \pnum -The \grammarterm{new-type-id} in a \grammarterm{new-expression} is the longest -possible sequence of \grammarterm{new-declarator}{s}. -\enternote -this prevents ambiguities between the declarator operators \tcode{\&}, \tcode{\&\&}, -\tcode{*}, and \tcode{[]} and their expression counterparts. -\exitnote -\enterexample +Abbreviating \grammarterm{pm-expression}\tcode{.*}\grammarterm{cast-expression} as \tcode{E1.*E2}, \tcode{E1} +is called the \defn{object expression}. +If the result of \tcode{E1} is an object +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. +The expression \tcode{E1} is sequenced before the expression \tcode{E2}. +\pnum +The restrictions on cv-qualification, and the manner in which +the cv-qualifiers of the operands are combined to produce the +cv-qualifiers of the result, are the same as the rules for +\tcode{E1.E2} given in~\ref{expr.ref}. +\begin{note} +It is not possible to use a pointer to member that refers to a +\keyword{mutable} member to modify a const class object. For +example, \begin{codeblock} -new int * i; // syntax error: parsed as \tcode{(new int*) i}, not as \tcode{(new int)*i} +struct S { + S() : i(0) { } + mutable int i; +}; +void f() +{ + const S cs; + int S::* pm = &S::i; // \tcode{pm} refers to \keyword{mutable} member \tcode{S::i} + cs.*pm = 88; // error: \tcode{cs} is a const object +} \end{codeblock} -The \tcode{*} is the pointer declarator and not the multiplication -operator. -\exitexample +\end{note} \pnum -\enternote -\indextext{ambiguity!parentheses~and}% -parentheses in a \grammarterm{new-type-id} of a \grammarterm{new-expression} -can have surprising effects. -\enterexample - +\indextext{function!pointer to member}% +If the result of \tcode{.*} or \tcode{->*} is a function, then that +result can be used only as the operand for the function call operator +\tcode{()}. +\begin{example} \begin{codeblock} -new int(*[10])(); // error +(ptr_to_obj->*ptr_to_mfct)(10); \end{codeblock} +calls the member function denoted by \tcode{ptr_to_mfct} for the object +pointed to by \tcode{ptr_to_obj}. +\end{example} +In a \tcode{.*} expression whose object expression is an rvalue, the program is +ill-formed if the second operand is a pointer to member function +whose \grammarterm{ref-qualifier} is \tcode{\&}, +unless its \grammarterm{cv-qualifier-seq} is \keyword{const}. +In a \tcode{.*} +expression whose object expression is an lvalue, the program is ill-formed if the second +operand is +a pointer to member function +whose \grammarterm{ref-qualifier} is \tcode{\&\&}. +The result of a \tcode{.*} expression +whose second operand is a pointer to a data member is an lvalue if the first +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. -is ill-formed because the binding is - -\begin{codeblock} -(new int) (*[10])(); // error -\end{codeblock} +\rSec2[expr.mul]{Multiplicative operators}% +\indextext{expression!multiplicative operators}% +\indextext{operator!multiplicative} -Instead, the explicitly parenthesized version of the \tcode{new} -operator can be used to create objects of compound -types~(\ref{basic.compound}): +\pnum +The multiplicative operators \tcode{*}, \tcode{/}, and \tcode{\%} group +left-to-right. -\begin{codeblock} -new (int (*[10])()); -\end{codeblock} +\indextext{operator!multiplication}% +\indextext{\idxcode{*}|see{operator, multiplication}}% +\indextext{operator!division}% +\indextext{\idxcode{/}|see{operator, division}}% +\indextext{operator!remainder}% +\indextext{\idxcode{\%}|see{operator, remainder}}% +\indextext{remainder operator|see{operator, remainder}}% +% +\begin{bnf} +\nontermdef{multiplicative-expression}\br + pm-expression\br + multiplicative-expression \terminal{*} pm-expression\br + multiplicative-expression \terminal{/} pm-expression\br + multiplicative-expression \terminal{\%} pm-expression +\end{bnf} -allocates an array of \tcode{10} pointers to functions (taking no -argument and returning \tcode{int}. -\exitexample -\exitnote +\pnum +The operands of \tcode{*} and \tcode{/} shall have arithmetic or unscoped +enumeration type; the operands of \tcode{\%} shall have integral or unscoped +enumeration type. The usual arithmetic conversions\iref{expr.arith.conv} are performed on the +operands and determine the type of the result. \pnum -\indextext{array!\idxcode{new}}% -When the allocated object is an array (that is, the -\grammarterm{noptr-new-declarator} syntax is used or the -\grammarterm{new-type-id} or \grammarterm{type-id} denotes an array type), the -\grammarterm{new-expression} yields a pointer to the initial element (if -any) of the array. -\enternote -both \tcode{new int} and \tcode{new int[10]} have type \tcode{int*} and -the type of \tcode{new int[i][10]} is \tcode{int (*)[10]} -\exitnote -The \grammarterm{attribute-specifier-seq} in a \grammarterm{noptr-new-declarator} appertains -to the associated array type. +The binary \tcode{*} operator indicates multiplication. \pnum -Every \grammarterm{constant-expression} in a -\grammarterm{noptr-new-declarator} shall be a converted constant -expression~(\ref{expr.const}) of type \tcode{std\colcol{}size_t} and -shall evaluate to a strictly positive value. -\indextext{\idxcode{new}}% -The \grammarterm{expression} in a \grammarterm{noptr-new-declarator}is -implicitly converted to \tcode{std\colcol{}size_t}. -\enterexample -given the definition \tcode{int n = 42}, -\tcode{new float[n][5]} is well-formed (because \tcode{n} is the -\grammarterm{expression} of a \grammarterm{noptr-new-declarator}), but -\tcode{new float[5][n]} is ill-formed (because \tcode{n} is not a -constant expression). -\exitexample +The binary \tcode{/} operator yields the quotient, and the binary +\tcode{\%} operator yields the remainder from the division of the first +expression by the second. +\indextext{zero!undefined division by}% +If the second operand of \tcode{/} or \tcode{\%} is zero, the behavior is +undefined. +For integral operands, the \tcode{/} operator yields the algebraic quotient with +any fractional part discarded; +\begin{footnote} +This is often called truncation towards zero. +\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. + +\rSec2[expr.add]{Additive operators}% +\indextext{expression!additive operators}% +\indextext{operator!additive} \pnum -\indextext{function!allocation}% -The \grammarterm{expression} in a \grammarterm{noptr-new-declarator} is -erroneous if: +The additive operators \tcode{+} and \tcode{-} group left-to-right. +Each operand shall be a prvalue. +If both operands have arithmetic or unscoped enumeration type, +the usual arithmetic conversions\iref{expr.arith.conv} are performed. +Otherwise, if one operand has arithmetic or unscoped enumeration type, +integral promotion is applied\iref{conv.prom} to that operand. +A converted or promoted operand is used in place of +the corresponding original operand for the remainder of this section. + +\indextext{operator!addition}% +\indextext{addition operator|see{operator, addition}}% +\indextext{\idxcode{+}|see{operator, addition}}% +\indextext{operator!subtraction}% +\indextext{subtraction operator|see{operator, subtraction}}% +\indextext{\idxcode{-}|see{operator, subtraction}}% +% +\begin{bnf} +\nontermdef{additive-expression}\br + multiplicative-expression\br + additive-expression \terminal{+} multiplicative-expression\br + additive-expression \terminal{-} multiplicative-expression +\end{bnf} -\begin{itemize} -\item -the expression is of non-class type and its value before converting to -\tcode{std::size_t} is less than zero; +\indextext{incomplete}% +For addition, either both operands shall have arithmetic +type, or one operand shall be a pointer to a completely-defined object +type and the other shall have integral type. -\item -the expression is of class type and its value before application of the second -standard conversion~(\ref{over.ics.user})\footnote{If the conversion function -returns a signed integer type, the second standard conversion converts to the -unsigned type \tcode{std::size_t} and thus thwarts any attempt to detect a -negative value afterwards.} is less than zero; +\pnum +For subtraction, one of the following shall hold: +\begin{itemize} +\item both operands have arithmetic type; or \item -its value is such that the size of the allocated object would exceed the -implementation-defined limit (annex~\ref{implimits}); or +\indextext{arithmetic!pointer}% +both operands are pointers to cv-qualified or cv-unqualified +versions of the same completely-defined object type; or -\item -the \grammarterm{new-initializer} is a \grammarterm{braced-init-list} and the -number of array elements for which initializers are provided (including the -terminating \tcode{'\textbackslash 0'} in a string literal~(\ref{lex.string})) exceeds the -number of elements to initialize. +\item the left operand is a pointer to a completely-defined object type +and the right operand has integral type. \end{itemize} -If the \grammarterm{expression}, after converting to \tcode{std::size_t}, is a -core constant expression and the expression is erroneous, the program is -ill-formed. Otherwise, a \grammarterm{new-expression} with an erroneous -expression does not call an allocation function and terminates by throwing an -exception of a type that would match a handler~(\ref{except.handle}) of type -\tcode{std::bad_array_new_length}~(\ref{new.badlength}). -When the value of the \grammarterm{expression} is zero, the allocation -function is called to allocate an array with no elements. - -\pnum -A \grammarterm{new-expression} may obtain storage for the object by calling an -\term{allocation function}~(\ref{basic.stc.dynamic.allocation}). If -the \grammarterm{new-expression} terminates by throwing an exception, it -may release storage by calling a deallocation -function~(\ref{basic.stc.dynamic.deallocation}). If the allocated type -is a non-array type, the allocation function's name is -\indextext{\idxcode{operator new}}% -\indextext{\idxcode{operator delete}}% -\tcode{operator new} and the deallocation function's name is -\tcode{operator delete}. If the allocated type is an array type, the -allocation function's name is -\indextext{\idxcode{operator new}}% -\indextext{\idxcode{operator delete}}% -\tcode{operator new[]} -and the deallocation function's name is -\tcode{operator delete[]}. -\enternote -an implementation shall provide default definitions for the global -allocation -functions~(\ref{basic.stc.dynamic},~\ref{new.delete.single},~\ref{new.delete.array}). -A \Cpp program can provide alternative definitions of -these functions~(\ref{replacement.functions}) and/or class-specific -versions~(\ref{class.free}). -\exitnote - \pnum -\indextext{operator!scope~resolution}% -If the \grammarterm{new-expression} begins with a unary \tcode{::} -operator, the allocation function's name is looked up in the global -scope. Otherwise, if the allocated type is a class type \tcode{T} or -array thereof, the allocation function's name is looked up in the scope -of \tcode{T}. If this lookup fails to find the name, or if the allocated -type is not a class type, the allocation function's name is looked up in -the global scope. +The result of the binary \tcode{+} operator is the sum of the operands. +The result of the binary \tcode{-} operator is the difference resulting +from the subtraction of the second operand from the first. \pnum -An implementation is allowed to omit a call to a replaceable global allocation -function~(\ref{new.delete.single}, \ref{new.delete.array}). When it does so, -the storage is instead provided by the implementation or provided by extending -the allocation of another \grammarterm{new-expression}. The implementation may -extend the allocation of a \grammarterm{new-expression} \tcode{e1} to provide -storage for a \grammarterm{new-expression} \tcode{e2} if the -following would be true were the allocation not extended: - +\indextext{arithmetic!pointer}% +When an expression \tcode{J} that has integral type +is added to or subtracted from an expression \tcode{P} of pointer type, +the result has the type of \tcode{P}. \begin{itemize} -\item the evaluation of \tcode{e1} is sequenced before the evaluation of -\tcode{e2}, and - -\item \tcode{e2} is evaluated whenever \tcode{e1} obtains storage, and - -\item both \tcode{e1} and \tcode{e2} invoke the same replaceable global -allocation function, and - -\item if the allocation function invoked by \tcode{e1} and \tcode{e2} is -throwing, any exceptions thrown in the evaluation of either \tcode{e1} or -\tcode{e2} would be first caught in the same handler, and - -\item the pointer values produced by \tcode{e1} and \tcode{e2} are operands to -evaluated \grammarterm{delete-expression}{s}, and - -\item the evaluation of \tcode{e2} is sequenced before the evaluation of the -\grammarterm{delete-expression} whose operand is the pointer value produced -by \tcode{e1}. +\item If \tcode{P} evaluates to a null pointer value and +\tcode{J} evaluates to 0, the result is a null pointer value. +\item Otherwise, if \tcode{P} points to a (possibly-hypothetical) array element $i$ +of an array object \tcode{x} with $n$ elements\iref{dcl.array}, +\begin{footnote} +As specified in \ref{basic.compound}, +an object that is not an array element +is considered to belong to a single-element array for this purpose and +a pointer past the last element of an array of $n$ elements +is considered to be equivalent to a pointer to a hypothetical array element +$n$ for this purpose. +\end{footnote} +the expressions \tcode{P + J} and \tcode{J + P} +(where \tcode{J} has the value $j$) +point to the (possibly-hypothetical) array element +$i + j$ of \tcode{x} if $0 \le i + j \le n$ +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. \end{itemize} +\begin{note} +Adding a value other than $0$ or $1$ +to a pointer to a base class subobject, a member subobject, +or a complete object results in undefined behavior. +\end{note} -\enterexample -\begin{codeblock} - void mergeable(int x) { - // These allocations are safe for merging: - std::unique_ptr a{new (std::nothrow) char[8]}; - std::unique_ptr b{new (std::nothrow) char[8]}; - std::unique_ptr c{new (std::nothrow) char[x]}; - - g(a.get(), b.get(), c.get()); - } +\pnum +\indextext{\idxcode{ptrdiff_t}}% +\indextext{comparison!undefined pointer}% +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 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}, +the expression \tcode{P - Q} has the value $i - j$. +\begin{note} +If the value $i - j$ +is not in the range of representable values +of type \tcode{std::ptrdiff_t}, +the behavior is undefined\iref{expr.pre}. +\end{note} +\item Otherwise, the behavior is undefined. +\end{itemize} - void unmergeable(int x) { - std::unique_ptr a{new char[8]}; - try { - // Merging this allocation would change its catch handler. - std::unique_ptr b{new char[x]}; - } catch (const std::bad_alloc& e) { - std::cerr << "Allocation failed: " << e.what() << std::endl; - throw; - } - } +\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. +\begin{example} +\begin{codeblock} +int arr[5] = {1, 2, 3, 4, 5}; +unsigned int *p = reinterpret_cast(arr + 1); +unsigned int k = *p; // OK, value of \tcode{k} is $2$\iref{conv.lval} +unsigned int *q = p + 1; // undefined behavior: \tcode{p} points to an \tcode{int}, not an \tcode{unsigned int} object \end{codeblock} -\exitexample +\end{example} -\pnum -When a \grammarterm{new-expression} calls an allocation function and that -allocation has not been extended, the -\grammarterm{new-expression} passes the amount of space requested to the -allocation function as the first argument of type -\tcode{std\colcol{}size_t}. That argument shall be no less than the size -of the object being created; it may be greater than the size of the -object being created only if the object is an array. For arrays of -\tcode{char} and \tcode{unsigned char}, the difference between the -result of the \grammarterm{new-expression} and the address returned by the -allocation function shall be an integral multiple of the -strictest fundamental -alignment requirement~(\ref{basic.align}) of any object type whose size -is no greater than the size of the array being created. -\enternote -\indextext{allocation!alignment~storage}% -Because allocation functions are assumed to return pointers to storage -that is appropriately aligned for objects of any type -with fundamental alignment, this constraint -on array allocation overhead permits the common idiom of allocating -character arrays into which objects of other types will later be placed. -\exitnote +\rSec2[expr.shift]{Shift operators} \pnum -When a \grammarterm{new-expression} calls an allocation function and that -allocation has been extended, the size argument to the allocation call shall -be no greater than the sum of the sizes for the omitted calls as specified -above, plus the size for the extended call had it not been extended, plus any -padding necessary to align the allocated objects within the allocated memory. - +\indextext{expression!left-shift-operator}% +\indextext{expression!right-shift-operator}% +\indextext{shift operator!left|see{operator, left shift}}% +\indextext{shift operator!right|see{operator, right shift}}% +\indextext{right shift operator|see{operator, right shift}}% +\indextext{left shift operator|see{operator, left shift}}% +The shift operators \tcode{<<} and \tcode{>>} group left-to-right. + +\indextext{operator!left shift}% +\indextext{\idxcode{<<}|see{operator, left shift}}% +\indextext{operator!right shift}% +\indextext{\idxcode{>>}|see{operator, right shift}}% +% +\begin{bnf} +\nontermdef{shift-expression}\br + additive-expression\br + shift-expression \terminal{<<} additive-expression\br + shift-expression \terminal{>>} additive-expression +\end{bnf} +The operands shall be prvalues of integral or unscoped enumeration type and integral +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 +than or equal to the width of the promoted left operand. \pnum -\indextext{placement~syntax!\idxcode{new}}% -The \grammarterm{new-placement} syntax is used to supply additional -arguments to an allocation function. If used, overload resolution is -performed on a function call created by assembling an argument list -consisting of the amount of space requested (the first argument) and the -expressions in the \grammarterm{new-placement} part of the -\grammarterm{new-expression} (the second and succeeding arguments). The -first of these arguments has type \tcode{std::size_t} and the remaining -arguments have the corresponding types of the expressions in the -\grammarterm{new-placement}; such an expression is called a -\defnx{placement \grammarterm{new-expression}}{placement~new-expression@placement \grammarterm{new-expression}}. +The value of \tcode{E1 << E2} is the unique value congruent to +$\tcode{E1} \times 2^\tcode{E2}$ modulo $2^N$, +where $N$ is the width of the type of the result. +\begin{note} +\tcode{E1} is left-shifted \tcode{E2} bit positions; +vacated bits are zero-filled. +\end{note} \pnum -\enterexample +The value of \tcode{E1 >> E2} is $\tcode{E1} / 2^\tcode{E2}$, +rounded towards negative infinity. +\begin{note} +\tcode{E1} is right-shifted \tcode{E2} bit positions. +Right-shift on signed integral types is an arithmetic right shift, +which performs sign-extension. +\end{note} -\begin{itemize} -\item \tcode{new T} results in a call of \tcode{operator -new(sizeof(T))}, +\pnum +The expression \tcode{E1} is sequenced before the expression \tcode{E2}. -\item \tcode{new(2,f) T} results in a call of \tcode{operator -new(sizeof(T),2,f)}, +\rSec2[expr.spaceship]{Three-way comparison operator} +\indextext{expression!three-way comparison}% +\indextext{expression!spaceship}% -\item \tcode{new T[5]} results in a call of \tcode{operator -new[](sizeof(T)*5+x)}, and +\pnum +The three-way comparison operator groups left-to-right. -\item \tcode{new(2,f) T[5]} results in a call of \tcode{operator -new[](sizeof(T)*5+y,2,f)}. -\end{itemize} +\indextext{\idxcode{<=>}|see{operator, three-way comparison}}% +\indextext{operator!three-way comparison}% +\indextext{operator!spaceship}% -Here, \tcode{x} and \tcode{y} are non-negative unspecified values -representing array allocation overhead; the result of the -\grammarterm{new-expression} will be offset by this amount from the value -returned by \tcode{operator new[]}. This overhead may be applied in all -array \grammarterm{new-expression}{s}, including those referencing the -library function \tcode{operator new[](std::size_t, void*)} and other -placement allocation functions. The amount of overhead may vary from one -invocation of \tcode{new} to another. -\exitexample +\begin{bnf} +\nontermdef{compare-expression}\br + shift-expression\br + compare-expression \terminal{<=>} shift-expression +\end{bnf} \pnum -\enternote -unless an allocation function has a non-throwing -exception specification~(\ref{except.spec}), -it indicates failure to allocate storage by throwing a -\indextext{\idxcode{bad_alloc}}% -\indexlibrary{\idxcode{bad_alloc}}% -\tcode{std::bad_alloc} exception~(\ref{basic.stc.dynamic.allocation}, -Clause~\ref{except},~\ref{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 -and a non-null pointer otherwise. -\exitnote -If the allocation function is a reserved placement allocation -function~(\ref{new.delete.placement}) that returns null, -the behavior is undefined. -Otherwise, -if the allocation function returns null, initialization shall not be -done, the deallocation function shall not be called, and the value of -the \grammarterm{new-expression} shall be null. +The expression \tcode{p <=> q} is a prvalue indicating whether +\tcode{p} is less than, equal to, greater than, or incomparable with +\tcode{q}. \pnum -\enternote -when the allocation function returns a value other than null, it must be -a pointer to a block of storage in which space for the object has been -reserved. The block of storage is assumed to be appropriately aligned -and of the requested size. The address of the created object will not -necessarily be the same as that of the block if the object is an array. -\exitnote +If one of the operands is of type \keyword{bool} +and the other is not, the program is ill-formed. \pnum -\indextext{\idxcode{new}!array~of class~objects~and}% -\indextext{\idxcode{new}!initialization~and}% -\indextext{\idxcode{new}!constructor~and}% -\indextext{\idxcode{new}!default~constructor~and}% -\indextext{constructor, default|see{default~constructor}}% -\indextext{trivial~type}% -\indextext{trivial~class~type}% -A \grammarterm{new-expression} that creates an object of type \tcode{T} -initializes that object as follows: +If both operands have arithmetic types, +or one operand has integral type and +the other operand has unscoped enumeration type, +the usual arithmetic conversions\iref{expr.arith.conv} are applied to the operands. +Then: \begin{itemize} -\item If the \grammarterm{new-initializer} is omitted, the object is -default-initialized~(\ref{dcl.init}). \enternote If no initialization -is performed, the object has an indeterminate value. \exitnote +\item +If a narrowing conversion\iref{dcl.init.list} is required, +other than from an integral type to a floating-point type, +the program is ill-formed. -\item Otherwise, the \grammarterm{new-initializer} is interpreted according to -the initialization rules of~\ref{dcl.init} for direct-initialization. +\item +Otherwise, if the operands have integral type, +the result is of type \tcode{std::strong_ordering}. +The result is +\tcode{std::strong_ordering::equal} +if both operands are arithmetically equal, +\tcode{std::strong_ordering::less} +if the first operand is arithmetically +less than the second operand, +and +\tcode{std::strong_ordering::greater} +otherwise. +\item +Otherwise, the operands have floating-point type, and +the result is of type \tcode{std::partial_ordering}. +The expression \tcode{a <=> b} yields +\tcode{std::partial_ordering::less} +if \tcode{a} is less than \tcode{b}, +\tcode{std::partial_ordering::greater} +if \tcode{a} is greater than \tcode{b}, +\tcode{std::partial_ordering::equivalent} +if \tcode{a} is equivalent to \tcode{b}, +and +\tcode{std::partial_ordering::unordered} otherwise. \end{itemize} \pnum -\indextext{\idxcode{new}!unspecified order~of evaluation}% -\indextext{\idxcode{new}!unspecified constructor~and}% -The invocation of the allocation function is indeterminately sequenced with respect to -the evaluations of expressions in the \grammarterm{new-initializer}. Initialization of -the allocated object is sequenced before the -\indextext{value computation}% -value computation of the -\grammarterm{new-expression}. -\indextext{constructor!unspecified argument~to}% -It is unspecified whether expressions in the \grammarterm{new-initializer} are -evaluated if the allocation function returns the null pointer or exits -using an exception. +If both operands have the same enumeration type \tcode{E}, +the operator yields the result of +converting the operands to the underlying type of \tcode{E} +and applying \tcode{<=>} to the converted operands. + +\pnum +If at least one of the operands is of object pointer type and +the other operand is of object pointer or array type, +array-to-pointer conversions\iref{conv.array}, +pointer conversions\iref{conv.ptr}, +and +qualification conversions\iref{conv.qual} +are performed on both operands +to bring them to their composite pointer type\iref{expr.type}. +After the conversions, the operands shall have the same type. +\begin{note} +If both of the operands are arrays, +array-to-pointer conversions\iref{conv.array} are not applied. +\end{note} +In this case, +\tcode{p <=> q} is of type \tcode{std::strong_ordering} and +the result is defined by the following rules: +\begin{itemize} +\item +If two pointer operands \tcode{p} and \tcode{q} compare equal\iref{expr.eq}, +\tcode{p <=> q} yields \tcode{std::strong_ordering::equal}; +\item +otherwise, if \tcode{p} and \tcode{q} compare unequal, +\tcode{p <=> q} yields +\tcode{std::strong_ordering::less} +if \tcode{q} compares greater than \tcode{p} +and +\tcode{std::strong_ordering::greater} +if \tcode{p} compares greater than \tcode{q}\iref{expr.rel}; +\item +otherwise, the result is unspecified. +\end{itemize} \pnum -If the \grammarterm{new-expression} creates an object or an array of -objects of class type, access and ambiguity control are done for the -allocation function, the deallocation function~(\ref{class.free}), and -the constructor~(\ref{class.ctor}). If the \grammarterm{new-expression} -creates an array of objects of class type, the destructor is potentially -invoked~(\ref{class.dtor}). +Otherwise, the program is ill-formed. \pnum -\indextext{\idxcode{new}!exception~and}% -If any part of the object initialization described above\footnote{This may -include evaluating a \grammarterm{new-initializer} and/or calling -a constructor.} -terminates by throwing an exception, storage has been obtained for the -object, and a suitable deallocation function -can be found, the deallocation function is called to free the memory in -which the object was being constructed, after which the exception -continues to propagate in the context of the \grammarterm{new-expression}. -If no unambiguous matching deallocation function can be found, -propagating the exception does not cause the object's memory to be -freed. -\enternote -This is appropriate when the called allocation function does not -allocate memory; otherwise, it is likely to result in a memory leak. -\exitnote - -\pnum -If the \grammarterm{new-expression} begins with a unary \tcode{::} -operator, the deallocation function's name is looked up in the global -scope. Otherwise, if the allocated type is a class type \tcode{T} or an -array thereof, the deallocation function's name is looked up in the -scope of \tcode{T}. If this lookup fails to find the name, or if the -allocated type is not a class type or array thereof, the deallocation -function's name is looked up 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~(\ref{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 the two-parameter form of a usual deallocation -function~(\ref{basic.stc.dynamic.deallocation}) 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 -function lookup is used to find the matching deallocation -function~(\ref{expr.delete}) -\enterexample +The three comparison category types\iref{cmp.categories} +(the types +\tcode{std::strong_ordering}, +\tcode{std::weak_ordering}, and +\tcode{std::partial_ordering}) +are not predefined; +if a standard library declaration\iref{compare.syn,std.modules} +of such a class type does not precede\iref{basic.lookup.general} +a use of that type --- +even an implicit use in which the type is not named +(e.g., via the \keyword{auto} specifier\iref{dcl.spec.auto} +in a defaulted three-way comparison\iref{class.spaceship} +or use of the built-in operator) --- the program is ill-formed. -\begin{codeblock} -struct S { - // Placement allocation function: - static void* operator new(std::size_t, std::size_t); +\rSec2[expr.rel]{Relational operators}% +\indextext{expression!relational operators}% +\indextext{operator!relational} - // Usual (non-placement) deallocation function: - static void operator delete(void*, std::size_t); -}; +\pnum +The relational operators group left-to-right. +\begin{example} +\tcode{a}|see{operator, greater than}}% +\indextext{operator!less than or equal to}% +\indextext{\idxcode{<=}|see{operator, less than or equal to}}% +\indextext{operator!greater than or equal to}% +\indextext{\idxcode{>=}|see{operator, greater than or equal to}}% +% +\begin{bnf} +\nontermdef{relational-expression}\br + compare-expression\br + relational-expression \terminal{<} compare-expression\br + relational-expression \terminal{>} compare-expression\br + relational-expression \terminal{<=} compare-expression\br + relational-expression \terminal{>=} compare-expression +\end{bnf} +% +The +lvalue-to-rvalue\iref{conv.lval} +and function-to-pointer\iref{conv.func} +standard conversions are performed on the operands. +If one of the operands is a pointer, the +array-to-pointer conversion\iref{conv.array} is performed on the other operand. -S* p = new (0) S; // ill-formed: non-placement deallocation function matches - // placement allocation function -\end{codeblock} +\pnum +The converted operands shall have arithmetic, enumeration, or pointer type. +The +operators \tcode{<} (less than), \tcode{>} (greater than), \tcode{<=} +(less than or equal to), and \tcode{>=} (greater than or equal to) all +yield \keyword{false} or \keyword{true}. The type of the result is +\keyword{bool}. -\exitexample +\pnum +The usual arithmetic conversions\iref{expr.arith.conv} are performed on operands of arithmetic +or enumeration type. If both converted operands are pointers, +pointer conversions\iref{conv.ptr}, +function pointer conversions\iref{conv.fctptr}, and +qualification conversions\iref{conv.qual} +are performed to bring +them to their composite pointer type\iref{expr.type}. +After conversions, the operands shall have the same type. \pnum -If a \grammarterm{new-expression} calls a deallocation function, it passes -the value returned from the allocation function call as the first -argument of type \tcode{void*}. If a placement deallocation function is -called, it is passed the same additional arguments as were passed to the -placement allocation function, that is, the same arguments as those -specified with the \grammarterm{new-placement} syntax. If the -implementation is allowed to make a copy of any argument as part of the -call to the allocation function, it is allowed to make a copy (of the -same original value) as part of the call to the deallocation function or -to reuse the copy made as part of the call to the allocation function. -If the copy is elided in one place, it need not be elided in the other. +The result of comparing unequal pointers to objects +\begin{footnote} +As specified in \ref{basic.compound}, +an object that is not an array element +is considered to belong to a +single-element array for this purpose and +a pointer past the last element of an array of $n$ elements +is considered to be equivalent to a pointer to a hypothetical array element +$n$ for this purpose. +\end{footnote} +is defined in terms of a partial order consistent with the following rules: + +\begin{itemize} +\item If two pointers point to different elements of the same array, or to +subobjects thereof, the pointer to the element with the higher subscript +is required to compare greater. + +\item If two pointers point to different non-static data members of the same +object, or to subobjects of such members, recursively, +the pointer to the later declared member is required to compare greater provided +neither member is a subobject of zero size +and their class is not a union. + +\item Otherwise, neither pointer is required to compare greater than the other. -\rSec2[expr.delete]{Delete} +\end{itemize} \pnum -\indextext{expression!\idxcode{delete}}% -\indextext{\idxcode{delete}}% -The \grammarterm{delete-expression} operator destroys a most derived -object~(\ref{intro.object}) or array created by a -\grammarterm{new-expression}. +If two operands \tcode{p} and \tcode{q} compare equal\iref{expr.eq}, +\tcode{p<=q} and \tcode{p>=q} both yield \keyword{true} and \tcode{pq} both yield \keyword{false}. Otherwise, if a pointer to object \tcode{p} +compares greater than a pointer \tcode{q}, \tcode{p>=q}, \tcode{p>q}, +\tcode{q<=p}, and \tcode{q=p}, and \tcode{q>p} all yield \keyword{false}. +Otherwise, the result of each of the operators is unspecified. +\begin{note} +A relational operator applied +to unequal function pointers +yields an unspecified result. +A pointer value of type ``pointer to \cv{}~\keyword{void}'' +can point to an object\iref{basic.compound}. +\end{note} + +\pnum +If both operands (after conversions) are of arithmetic or enumeration type, each +of the operators shall yield \keyword{true} if the specified relationship is true +and \keyword{false} if it is false. + +\rSec2[expr.eq]{Equality operators}% +\indextext{expression!equality operators}% +\indextext{operator!equality}% +\indextext{operator!inequality} \begin{bnf} -\nontermdef{delete-expression}\br - \terminal{::}\opt \terminal{delete} cast-expression\br - \terminal{::}\opt \terminal{delete [ ]} cast-expression +\nontermdef{equality-expression}\br + relational-expression\br + equality-expression \terminal{==} relational-expression\br + equality-expression \terminal{!=} relational-expression \end{bnf} -The first alternative is for non-array objects, and the second is for arrays. Whenever -the \tcode{delete} keyword is immediately followed by empty square brackets, it shall be -interpreted as the second alternative.\footnote{A lambda expression with a -\grammarterm{lambda-introducer} that consists of -empty square brackets can follow the \tcode{delete} keyword if the lambda expression is -enclosed in parentheses.} -The operand shall be of pointer to object type or of class type. If of -class type, the operand is contextually implicitly converted -(Clause~\ref{conv}) to a pointer to object -type.\footnote{This implies that an object -cannot be deleted using a pointer of type -\tcode{void*} because \tcode{void} is not an object type.} -The \grammarterm{delete-expression}'s result has type -\tcode{void}. - -\pnum -\indextext{\idxcode{delete}!object} -If the operand has a class type, the operand is converted to a pointer -type by calling the above-mentioned conversion function, and the -converted operand is used in place of the original operand for the -remainder of this section. -\indextext{object!delete}% -In the first alternative -(\term{delete object}), the value of the operand of \tcode{delete} may -be a null pointer value, a pointer to a non-array object -created by a previous \grammarterm{new-expression}, -or a pointer to a -subobject~(\ref{intro.object}) representing a base class of such an -object (Clause~\ref{class.derived}). If not, the behavior is undefined. -\indextext{array!\idxcode{delete}}% -\indextext{\idxcode{delete}!array}% -In the second alternative (\term{delete array}), the value of the -operand of \tcode{delete} -may be a null pointer value or a pointer value -that resulted from -a previous array \grammarterm{new-expression}.\footnote{For non-zero-length -arrays, this is the same as a pointer to the first -element of the array created by that \grammarterm{new-expression}. -Zero-length arrays do not have a first element.} -If not, the behavior is undefined. -\enternote -this means that the syntax of the \grammarterm{delete-expression} must -match the type of the object allocated by \tcode{new}, not the syntax of the -\grammarterm{new-expression}. -\exitnote -\enternote -a pointer to a \tcode{const} type can be the operand of a -\grammarterm{delete-expression}; it is not necessary to cast away the -constness~(\ref{expr.const.cast}) of the pointer expression before it is -used as the operand of the \grammarterm{delete-expression}. -\exitnote - \pnum -\indextext{\idxcode{delete}!undefined}% -In the first alternative (\term{delete object}), if the static type of -the object to be deleted is different from its dynamic type, 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 the second -alternative (\term{delete array}) if the dynamic type of the object to -be deleted differs from its static type, the behavior is undefined. +The \tcode{==} (equal to) and the \tcode{!=} (not equal to) operators +group left-to-right. +The +lvalue-to-rvalue\iref{conv.lval} +and function-to-pointer\iref{conv.func} +standard conversions are performed on the operands. +If one of the operands is a pointer or a null pointer constant\iref{conv.ptr}, +the array-to-pointer conversion\iref{conv.array} is performed +on the other operand. \pnum -The \grammarterm{cast-expression} in a \grammarterm{delete-expression} shall -be evaluated exactly once. +The converted operands shall have scalar type. The operators +\tcode{==} and \tcode{!=} both yield \keyword{true} or \keyword{false}, i.e., a +result of type \keyword{bool}. In each case below, the operands shall have the +same type after the specified conversions have been applied. \pnum -\indextext{type!incomplete}% -If the object being deleted has incomplete class type at the point of -deletion and the complete class has a non-trivial destructor or a -deallocation function, the behavior is undefined. +\indextext{comparison!pointer}% +\indextext{comparison!pointer to function}% +If at least one of the converted operands is a pointer, +pointer conversions\iref{conv.ptr}, +function pointer conversions\iref{conv.fctptr}, and +qualification conversions\iref{conv.qual} +are performed on both operands to bring them to their composite pointer type\iref{expr.type}. +Comparing pointers is defined as follows: -\pnum -\indextext{\idxcode{delete}!destructor~and}% -If the value of the operand of the \grammarterm{delete-expression} is not a -null pointer value, the \grammarterm{delete-expression} will invoke the -destructor (if any) for the object or the elements of the array being -deleted. In the case of an array, the elements will be destroyed in -order of decreasing address (that is, in reverse order of the completion -of their constructor; see~\ref{class.base.init}). +\begin{itemize} +\item +If one pointer represents the address of a complete object, and another +pointer represents the address one past the last element of a different +complete object, +\begin{footnote} +As specified in \ref{basic.compound}, +an object that is not an array element is +considered to belong to a single-element array for this purpose. +\end{footnote} +the result of the comparison is unspecified. +\item +Otherwise, if the pointers are both null, both point to the same +\indextext{address}% +function, or both represent the same address\iref{basic.compound}, +they compare equal. +\item +Otherwise, the pointers compare unequal. +\end{itemize} \pnum -If the value of the operand of the \grammarterm{delete-expression} is not a -null pointer value, then: +If at least one of the operands is a pointer to member, +pointer-to-member conversions\iref{conv.mem}, +function pointer conversions\iref{conv.fctptr}, and +qualification conversions\iref{conv.qual} +are performed on both operands to bring them to +their composite pointer type\iref{expr.type}. +Comparing pointers to members is defined as follows: \begin{itemize} \item -If the allocation call for the \grammarterm{new-expression} for the object to -be deleted was not omitted and the allocation was not extended~(\ref{expr.new}), the -\grammarterm{delete-expression} shall call a deallocation -function~(\ref{basic.stc.dynamic.deallocation}). The value returned from the -allocation call of the \grammarterm{new-expression} shall be passed as the -first argument to the deallocation function. +If two pointers to members are both the null member pointer value, they compare +equal. \item -Otherwise, if the allocation was extended or was provided by extending the -allocation of another \grammarterm{new-expression}, and the -\grammarterm{delete-expression} for every other pointer value produced by a -\grammarterm{new-expression} that had storage provided by the extended -\grammarterm{new-expression} has been evaluated, the -\grammarterm{delete-expression} shall call a deallocation function. The value -returned from the allocation call of the extended \grammarterm{new-expression} -shall be passed as the first argument to the deallocation function. +If only one of two pointers to members is the null member pointer value, they +compare unequal. \item -Otherwise, the \grammarterm{delete-expression} will not call a -\indextext{function!deallocation}% -\indextext{deallocation|see{\tcode{delete}}}% -\indextext{\idxcode{delete}}% -\term{deallocation function}~(\ref{basic.stc.dynamic.deallocation}). -\end{itemize} +If either is a pointer to a virtual member function, the result is unspecified. -Otherwise, it is unspecified whether the deallocation function will be -called. -\enternote -The deallocation function is called regardless of whether the destructor -for the object or some element of the array throws an exception. -\exitnote +\item +If one refers to a member of class \tcode{C1} and the other refers to a member +of a different class \tcode{C2}, where neither is a base class of the other, +the result is unspecified. +\begin{example} +\begin{codeblock} +struct A {}; +struct B : A { int x; }; +struct C : A { int x; }; -\pnum -\enternote -An implementation provides default definitions of the global -deallocation functions \tcode{operator delete()} for -non-arrays~(\ref{new.delete.single}) and -\indextext{operator~|see{\tcode{delete}}}% -\indextext{\idxcode{operator delete}}% -\tcode{operator delete[]()} for arrays~(\ref{new.delete.array}). A \Cpp -program can provide alternative definitions of these -functions~(\ref{replacement.functions}), and/or class-specific -versions~(\ref{class.free}). -\exitnote +int A::*bx = (int(A::*))&B::x; +int A::*cx = (int(A::*))&C::x; -\pnum -When the keyword \tcode{delete} in a \grammarterm{delete-expression} is -preceded by the unary \tcode{::} operator, the deallocation function's name is looked -up in global scope. Otherwise, the lookup considers class-specific deallocation -functions~(\ref{class.free}). If no class-specific deallocation function is found, -the deallocation function's name is looked up in global scope. +bool b1 = (bx == cx); // unspecified +\end{codeblock} +\end{example} -\pnum -If deallocation function lookup finds both a usual -deallocation function with only a pointer parameter and a usual deallocation -function with both a pointer parameter and a size parameter, -the function to be called is selected as follows: -\begin{itemize} -\item -If the type is complete and if, for the second alternative (delete -array) only, the operand is a pointer to a class type with a -non-trivial destructor or a (possibly multi-dimensional) array thereof, -the function with two parameters is selected. \item -Otherwise, it is unspecified which of the two deallocation functions -is selected. -\end{itemize} - -\pnum -When a \grammarterm{delete-expression} -is executed, the selected deallocation function shall be called with -the address of the block of storage to be reclaimed as its first argument and -(if the two-parameter deallocation function is used) the size of the block as its -second argument.\footnote{If the static type of the object to be deleted is complete -and is different from the dynamic type, and the destructor is not virtual, the size might -be incorrect, but that case is already undefined, as stated above.} +If both refer to (possibly different) members of the same union\iref{class.union}, +they compare equal. -\pnum -Access and ambiguity control are done for both the deallocation function -and the destructor~(\ref{class.dtor},~\ref{class.free}). +\item +Otherwise, two pointers to members compare equal if they would refer to the same member of +the same most derived object\iref{intro.object} or the same subobject if +indirection with a hypothetical object of the associated +class type were performed, otherwise they compare unequal. +\begin{example} +\begin{codeblock} +struct B { + int f(); +}; +struct L : B { }; +struct R : B { }; +struct D : L, R { }; -\rSec2[expr.alignof]{Alignof} +int (B::*pb)() = &B::f; +int (L::*pl)() = pb; +int (R::*pr)() = pb; +int (D::*pdl)() = pl; +int (D::*pdr)() = pr; +bool x = (pdl == pdr); // \tcode{false} +bool y = (pb == pl); // \tcode{true} +\end{codeblock} +\end{example} +\end{itemize} \pnum -\indextext{expression!\idxcode{alignof}}% -An \tcode{alignof} expression yields the alignment requirement -of its operand type. The operand shall be a \grammarterm{type-id} -representing a complete object type, or an array thereof, or a reference -to one of those types. +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 -The result is an integral constant of type -\tcode{std::size_t}. +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 -When \tcode{alignof} is applied to a reference type, the result -is the alignment of the referenced type. When \tcode{alignof} -is applied to an array type, the result is the alignment of the -element type. - -\rSec2[expr.unary.noexcept]{\tcode{noexcept} operator} +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. \pnum -\indextext{expression!\idxcode{noexcept}}% -The \tcode{noexcept} operator determines whether the evaluation of its operand, -which is an unevaluated operand (Clause~\ref{expr}), can throw an -exception~(\ref{except.throw}). +If both operands are of arithmetic or enumeration type, the usual arithmetic +conversions\iref{expr.arith.conv} are performed on both operands; each of the operators shall yield +\keyword{true} if the specified relationship is true and \keyword{false} if it is +false. + +\rSec2[expr.bit.and]{Bitwise AND operator}% +\indextext{expression!bitwise AND}% +\indextext{operator!bitwise}% +\indextext{operator!bitwise AND}% +\indextext{\idxcode{\&}|see{operator, bitwise AND}}% \begin{bnf} -\nontermdef{noexcept-expression}\br - \terminal{noexcept} \terminal{(} expression \terminal{)} +\nontermdef{and-expression}\br + equality-expression\br + and-expression \terminal{\&} equality-expression \end{bnf} \pnum -The result of the \tcode{noexcept} operator is a constant of type \tcode{bool} -and is a prvalue. - -\pnum -The result of the \tcode{noexcept} operator is \tcode{true} if -the set of potential exceptions of the expression~(\ref{except.spec}) -is empty, and \tcode{false} otherwise.% -\indextext{expression!unary|)} +The \tcode{\&} operator groups left-to-right. +The operands shall be of integral or unscoped enumeration type. +The usual arithmetic conversions\iref{expr.arith.conv} are performed. +Given the coefficients $\tcode{x}_i$ and $\tcode{y}_i$ +of the base-2 representation\iref{basic.fundamental} +of the converted operands \tcode{x} and \tcode{y}, +the coefficient $\tcode{r}_i$ +of the base-2 representation of the result \tcode{r} +is 1 if both $\tcode{x}_i$ and $\tcode{y}_i$ are 1, and 0 otherwise. +\begin{note} +The result is the bitwise \logop{and} function of the operands. +\end{note} + +\rSec2[expr.xor]{Bitwise exclusive OR operator}% +\indextext{expression!bitwise exclusive OR}% +\indextext{operator!bitwise exclusive OR}% +\indextext{\idxcode{\caret}|see{operator, bitwise exclusive OR}} -\rSec1[expr.cast]{Explicit type conversion (cast notation)}% -\indextext{expression!cast|(} +\begin{bnf} +\nontermdef{exclusive-or-expression}\br + and-expression\br + exclusive-or-expression \terminal{\caret} and-expression +\end{bnf} \pnum -The result of the expression \tcode{(T)} \grammarterm{cast-expression} is -of type \tcode{T}. The result is an lvalue if \tcode{T} is an lvalue -reference type or an rvalue reference to function type and an xvalue if \tcode{T} -is an rvalue reference to object type; otherwise the result is a prvalue. -\enternote -if \tcode{T} is a non-class type that is cv-qualified, the -\grammarterm{cv-qualifiers} are discarded when determining the type of the -resulting prvalue; see Clause~\ref{expr}. -\exitnote +The \tcode{\caret} operator groups left-to-right. +The operands shall be of integral or unscoped enumeration type. +The usual arithmetic conversions\iref{expr.arith.conv} are performed. +Given the coefficients $\tcode{x}_i$ and $\tcode{y}_i$ +of the base-2 representation\iref{basic.fundamental} +of the converted operands \tcode{x} and \tcode{y}, +the coefficient $\tcode{r}_i$ +of the base-2 representation of the result \tcode{r} +is 1 if either (but not both) of $\tcode{x}_i$ and $\tcode{y}_i$ is 1, +and 0 otherwise. +\begin{note} +The result is the bitwise exclusive \logop{or} function of the operands. +\end{note} + +\rSec2[expr.or]{Bitwise inclusive OR operator}% +\indextext{expression!bitwise inclusive OR}% +\indextext{operator!bitwise inclusive OR}% +\indextext{\idxcode{"|}|see{operator, bitwise inclusive OR}} + +\begin{bnf} +\nontermdef{inclusive-or-expression}\br + exclusive-or-expression\br + inclusive-or-expression \terminal{|} exclusive-or-expression +\end{bnf} \pnum -An explicit type conversion can be expressed using functional -notation~(\ref{expr.type.conv}), a type conversion operator -(\tcode{dynamic_cast}, \tcode{static_cast}, \tcode{reinterpret_cast}, -\tcode{const_cast}), or the \term{cast} notation. +The \tcode{|} operator groups left-to-right. +The operands shall be of integral or unscoped enumeration type. +The usual arithmetic conversions\iref{expr.arith.conv} are performed. +Given the coefficients $\tcode{x}_i$ and $\tcode{y}_i$ +of the base-2 representation\iref{basic.fundamental} +of the converted operands \tcode{x} and \tcode{y}, +the coefficient $\tcode{r}_i$ +of the base-2 representation of the result \tcode{r} +is 1 if at least one of $\tcode{x}_i$ and $\tcode{y}_i$ is 1, and 0 otherwise. +\begin{note} +The result is the bitwise inclusive \logop{or} function of the operands. +\end{note} + +\rSec2[expr.log.and]{Logical AND operator}% +\indextext{expression!logical AND}% +\indextext{operator!logical AND}% +\indextext{\idxcode{\&\&}|see{operator, logical AND}}% \begin{bnf} -\nontermdef{cast-expression}\br - unary-expression\br - \terminal{(} type-id \terminal{)} cast-expression +\nontermdef{logical-and-expression}\br + inclusive-or-expression\br + logical-and-expression \terminal{\&\&} inclusive-or-expression \end{bnf} \pnum -Any type conversion not mentioned below and not explicitly defined by -the user~(\ref{class.conv}) is ill-formed. +The \tcode{\&\&} operator groups left-to-right. The operands are both +contextually converted to \keyword{bool}\iref{conv}. +The +result is \keyword{true} if both operands are \keyword{true} and +\keyword{false} otherwise. Unlike \tcode{\&}, \tcode{\&\&} guarantees +left-to-right evaluation: the second operand is not evaluated if the +first operand is \keyword{false}. \pnum -The conversions performed by - -\begin{itemize} -\indextext{cast!const}% -\indextext{cast!static}% -\indextext{cast!reinterpret}% -\item a \tcode{const_cast}~(\ref{expr.const.cast}), -\item a \tcode{static_cast}~(\ref{expr.static.cast}), -\item a \tcode{static_cast} followed by a \tcode{const_cast}, -\item a \tcode{reinterpret_cast}~(\ref{expr.reinterpret.cast}), or -\item a \tcode{reinterpret_cast} followed by a \tcode{const_cast}, -\end{itemize} - -can be performed using the cast notation of explicit type conversion. -The same semantic restrictions and behaviors apply, with the exception -that in performing a \tcode{static_cast} in the following situations the -conversion is valid even if the base class is inaccessible: - -\begin{itemize} -\item a pointer to an object of derived class type or an lvalue or -rvalue of derived class type may be explicitly converted to a pointer or -reference to an unambiguous base class type, respectively; - -\item a pointer to member of derived class type may be explicitly -converted to a pointer to member of an unambiguous non-virtual base -class type; - -\item a pointer to an object of an unambiguous non-virtual base class -type, a glvalue of an unambiguous non-virtual base class type, -or a pointer to member of an unambiguous non-virtual base class type may -be explicitly converted to a pointer, a reference, or a pointer to -member of a derived class type, respectively. -\end{itemize} +The result is a \tcode{bool}. +\indextext{operator!side effects and logical AND}% +If the second expression is evaluated, +the first expression is sequenced before +the second expression\iref{intro.execution}. -If a conversion can be interpreted in more than one of the ways listed -above, the interpretation that appears first in the list is used, even -if a cast resulting from that interpretation is ill-formed. If a -conversion can be interpreted in more than one way as a -\tcode{static_cast} followed by a \tcode{const_cast}, the conversion is -ill-formed. -\enterexample +\rSec2[expr.log.or]{Logical OR operator}% +\indextext{expression!logical OR}% +\indextext{operator!logical OR}% +\indextext{\idxcode{"|"|}|see{operator, logical OR}}% -\begin{codeblock} -struct A { }; -struct I1 : A { }; -struct I2 : A { }; -struct D : I1, I2 { }; -A* foo( D* p ) { - return (A*)( p ); // ill-formed \tcode{static_cast} interpretation -} -\end{codeblock} -\exitexample +\begin{bnf} +\nontermdef{logical-or-expression}\br + logical-and-expression\br + logical-or-expression \terminal{||} logical-and-expression +\end{bnf} \pnum -\indextext{class!cast~to incomplete}% -The operand of a cast using the cast notation can be a prvalue of type -``pointer to incomplete class type''. The destination type of a cast -using the cast notation can be ``pointer to incomplete class type''. If -both the operand and destination types are class types and one or both -are incomplete, it is unspecified whether the \tcode{static_cast} or the -\tcode{reinterpret_cast} interpretation is used, even if there is an -inheritance relationship between the two classes. -\enternote -For example, if the classes were defined later in the translation unit, -a multi-pass compiler would be permitted to interpret a cast between -pointers to the classes as if the class types were complete at the point -of the cast. -\exitnote% -\indextext{expression!cast|)} - -\rSec1[expr.mptr.oper]{Pointer-to-member operators} +The \tcode{||} operator groups left-to-right. The operands are both +contextually converted to \keyword{bool}\iref{conv}. +The result is +\keyword{true} if either of its operands is \keyword{true}, and +\keyword{false} otherwise. Unlike \tcode{|}, \tcode{||} guarantees +left-to-right evaluation; moreover, the second operand is not evaluated +if the first operand evaluates to \keyword{true}. \pnum -\indextext{expression!pointer-to-member}% -\indextext{pointer~to~member}% -\indextext{operator!pointer~to~member}% -\indextext{\idxcode{.*}|see{pointer~to~member~operator}}% -\indextext{operator!pointer~to~member}% -\indextext{\idxcode{->*}|see{pointer~to~member~operator}}% -The pointer-to-member operators \tcode{->*} and \tcode{.*} group -left-to-right. +The result is a \keyword{bool}. +\indextext{operator!side effects and logical OR}% +If the second expression is evaluated, +the first expression is sequenced before +the second expression\iref{intro.execution}. + +\rSec2[expr.cond]{Conditional operator}% +\indextext{expression!conditional operator}% +\indextext{operator!conditional expression}% +\indextext{\idxcode{?:}|see{operator, conditional expression}}% \begin{bnf} -\nontermdef{pm-expression}\br - cast-expression\br - pm-expression \terminal{.*} cast-expression\br - pm-expression \terminal{->*} cast-expression +\nontermdef{conditional-expression}\br + logical-or-expression\br + logical-or-expression \terminal{?} expression \terminal{:} assignment-expression \end{bnf} \pnum -The binary operator \tcode{.*} binds its second operand, which shall be -of type ``pointer to member of \tcode{T}'' to its first operand, which shall be of -class \tcode{T} or of a class of which \tcode{T} is an unambiguous and -accessible base class. The result is an object or a function of the type -specified by the second operand. +Conditional expressions group right-to-left. The first expression is +contextually converted to \keyword{bool}\iref{conv}. +It is +evaluated and if it is \keyword{true}, the result of the conditional +expression is the value of the second expression, otherwise that of the +third expression. Only one of the second and third expressions is +evaluated. +The first expression is sequenced before +the second or third expression\iref{intro.execution}. \pnum -The binary operator \tcode{->*} binds its second operand, which shall be -of type ``pointer to member of \tcode{T}'' to its first operand, which shall be of -type ``pointer to \tcode{T}'' or ``pointer to a class of which \tcode{T} -is an unambiguous and accessible base class.'' -The expression \tcode{E1->*E2} is converted into the equivalent form -\tcode{(*(E1)).*E2}. +If either the second or the third operand has type \keyword{void}, +one of the following shall hold: +\begin{itemize} +\item +\indextext{conditional-expression!throw-expression in}% +The second or the third operand (but not both) is a (possibly +parenthesized) \grammarterm{throw-expression}\iref{expr.throw}; the result +is of the type and value category of the other. +The \grammarterm{conditional-expression} +is a bit-field if that operand is a bit-field. -\pnum -Abbreviating \term{pm-expression}{}\tcode{.*}\term{cast-expression} as \tcode{E1.*E2}, \tcode{E1} -is called the \term{object expression}. -If the dynamic type of \tcode{E1} does not -contain the member to which -\tcode{E2} refers, the behavior is undefined. +\item Both the second and the third operands have type \keyword{void}; the +result is of type \keyword{void} and is a prvalue. +\begin{note} +This +includes the case where both operands are \grammarterm{throw-expression}{s}. +\end{note} +\end{itemize} \pnum -The restrictions on \cvqual{cv-}qualification, and the manner in which -the \cvqual{cv-}qualifiers of the operands are combined to produce the -\cvqual{cv-}qualifiers of the result, are the same as the rules for -\tcode{E1.E2} given in~\ref{expr.ref}. -\enternote -it is not possible to use a pointer to member that refers to a -\tcode{mutable} member to modify a \tcode{const} class object. For -example, - -\begin{codeblock} -struct S { - S() : i(0) { } - mutable int i; -}; -void f() -{ -const S cs; -int S::* pm = &S::i; // \tcode{pm} refers to \tcode{mutable} member \tcode{S::i} -cs.*pm = 88; // ill-formed: \tcode{cs} is a \tcode{const} object -} -\end{codeblock} -\exitnote +Otherwise, if the second and third operand are glvalue bit-fields +of the same value category and +of types \cvqual{cv1} \tcode{T} and \cvqual{cv2} \tcode{T}, respectively, +the operands are considered to be of type \cv{} \tcode{T} +for the remainder of this subclause, +where \cv{} is the union of \cvqual{cv1} and \cvqual{cv2}. \pnum -\indextext{function!pointer~to~member}% -If the result of \tcode{.*} or \tcode{->*} is a function, then that -result can be used only as the operand for the function call operator -\tcode{()}. -\enterexample - -\begin{codeblock} -(ptr_to_obj->*ptr_to_mfct)(10); -\end{codeblock} +Otherwise, if the second and third operand have different types and +either has (possibly cv-qualified) class type, or if both +are glvalues of the same value category and the same type except for +cv-qualification, an attempt is made to +form an implicit conversion sequence\iref{over.best.ics} from +each of those operands to the type of the other. +\begin{note} +Properties such as access, whether an operand is a bit-field, or whether +a conversion function is deleted are ignored for that determination. +\end{note} +Attempts are made to form an implicit conversion sequence +from an operand expression \tcode{E1} of type \tcode{T1} +to a target type related to the type \tcode{T2} +of the operand expression \tcode{E2} as follows: -calls the member function denoted by \tcode{ptr_to_mfct} for the object -pointed to by \tcode{ptr_to_obj}. -\exitexample -In a \tcode{.*} expression whose object expression is an rvalue, the program is -ill-formed if the second operand is a pointer to member function with -\grammarterm{ref-qualifier} \tcode{\&}. -In a \tcode{.*} -expression whose object expression is an lvalue, the program is ill-formed if the second -operand is a pointer to member function with \grammarterm{ref-qualifier} \tcode{\&\&}. -The result of a \tcode{.*} expression -whose second operand is a pointer to a data member is an lvalue if the first -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 -pointer to member value~(\ref{conv.mem}), the behavior is undefined. +\begin{itemize} +\item If \tcode{E2} is an lvalue, the target type is +``lvalue reference to \tcode{T2}'', +but an implicit conversion sequence can only be formed +if the reference would bind directly\iref{dcl.init.ref} +to a glvalue. + +\item If \tcode{E2} is an xvalue, the target type is +``rvalue reference to \tcode{T2}'', +but an implicit conversion sequence can only be formed +if the reference would bind directly. + +\item If \tcode{E2} is a prvalue or if neither of the conversion sequences above can be +formed and at least one of the operands has (possibly cv-qualified) class type: +\begin{itemize} +\item if \tcode{T1} and \tcode{T2} are the same class type +(ignoring cv-qualification): + \begin{itemize} + \item + if \tcode{T2} is at least as cv-qualified as \tcode{T1}, + the target type is \tcode{T2}, + \item + otherwise, no conversion sequence is formed for this operand; + \end{itemize} -\rSec1[expr.mul]{Multiplicative operators}% -\indextext{expression!multiplicative~operators}% -\indextext{operator!multiplicative} +\item otherwise, if \tcode{T2} is a base class of \tcode{T1}, +the target type is \cvqual{cv1} \tcode{T2}, where \cvqual{cv1} +denotes the cv-qualifiers of \tcode{T1}; -\pnum -The multiplicative operators \tcode{*}, \tcode{/}, and \tcode{\%} group -left-to-right. +\item otherwise, the target type is the type that \tcode{E2} would have +after applying the +lvalue-to-rvalue\iref{conv.lval}, +array-to-pointer\iref{conv.array}, and +function-to-pointer\iref{conv.func} +standard conversions. +\end{itemize} +\end{itemize} -\indextext{operator!multiplication}% -\indextext{\idxcode{*}|see{multiplication~operator}}% -\indextext{operator!division}% -\indextext{\idxcode{/}|see{division~operator}}% -\indextext{operator!remainder}% -\indextext{\idxcode{\%}|see{remainder~operator}}% -\indextext{remainder~operator|see{remainder~operator}}% -% -\begin{bnf} -\nontermdef{multiplicative-expression}\br - pm-expression\br - multiplicative-expression \terminal{*} pm-expression\br - multiplicative-expression \terminal{/} pm-expression\br - multiplicative-expression \terminal{\%} pm-expression -\end{bnf} +Using this process, it is determined whether an implicit conversion +sequence can be formed from the second operand +to the target type determined for the third operand, and vice versa, +with the following outcome: +\begin{itemize} +\item If both sequences can be formed, or one can be formed but it is the +ambiguous conversion sequence, the program is ill-formed. +\item If no conversion sequence can be formed, the operands are left unchanged +and further checking is performed as described below. +\item Otherwise, if exactly one conversion sequence can be formed, +that conversion is applied to the chosen operand +and the converted operand is used in place of the original operand for +the remainder of this subclause. +\begin{note} +The conversion might be ill-formed even if an implicit conversion +sequence could be formed. +\end{note} +\end{itemize} \pnum -The operands of \tcode{*} and \tcode{/} shall have arithmetic or unscoped -enumeration type; the operands of \tcode{\%} shall have integral or unscoped -enumeration type. The usual arithmetic conversions are performed on the -operands and determine the type of the result. +If the second and third operands are glvalues of the same value category +and have the same type, the +result is of that type and value category and it is a bit-field if the +second or the third operand is a bit-field, or if both are bit-fields. \pnum -The binary \tcode{*} operator indicates multiplication. +Otherwise, the result is a prvalue. If the second and third operands do +not have the same type, and either has (possibly cv-qualified) class +type, overload resolution is used to determine the conversions (if any) +to be applied to the operands\iref{over.match.oper,over.built}. +If the overload resolution fails, the program is ill-formed. Otherwise, +the conversions thus determined are applied, and the converted operands +are used in place of the original operands for the remainder of this +subclause. \pnum -The binary \tcode{/} operator yields the quotient, and the binary -\tcode{\%} operator yields the remainder from the division of the first -expression by the second. -\indextext{zero!undefined division~by}% -If the second operand of \tcode{/} or \tcode{\%} is zero the behavior is -undefined. -For integral operands the \tcode{/} operator yields the algebraic quotient with -any fractional part discarded;\footnote{This is often called truncation towards -zero.} 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. +Array-to-pointer\iref{conv.array} +and function-to-pointer\iref{conv.func} standard conversions are +performed on the second and third operands. After those conversions, one +of the following shall hold: -\rSec1[expr.add]{Additive operators}% -\indextext{expression!additive~operators}% -\indextext{operator!additive} +\begin{itemize} +\item The second and third operands have the same type; the result is of +that type and the result is copy-initialized using the selected operand. -\pnum -The additive operators \tcode{+} and \tcode{-} group left-to-right. The -usual arithmetic conversions are performed for operands of arithmetic or -enumeration type. +\item The second and third operands have arithmetic or enumeration type; +the usual arithmetic conversions\iref{expr.arith.conv} are performed to bring them to a common +type, and the result is of that type. + +\item One or both of the second and third operands have pointer type; +lvalue-to-rvalue\iref{conv.lval}, +pointer\iref{conv.ptr}, +function pointer\iref{conv.fctptr}, and +qualification conversions\iref{conv.qual} +are performed to bring them to their +composite pointer type\iref{expr.type}. The result is of the composite +pointer type. + +\item One or both of the second and third operands have pointer-to-member type; +lvalue-to-rvalue\iref{conv.lval}, +pointer to member\iref{conv.mem}, +function pointer\iref{conv.fctptr}, and +qualification conversions\iref{conv.qual} +are performed to bring them to their composite +pointer type\iref{expr.type}. The result is of the composite pointer type. + +\item +Both the second and third operands have type \tcode{std::nullptr_t} or one has +that type and the other is a null pointer constant. The result is of type +\tcode{std::nullptr_t}. + +\end{itemize} + +\rSec2[expr.yield]{Yielding a value}% +\indextext{expression!yield}% +\indextext{\idxcode{co_yield}}% -\indextext{addition~operator}% -\indextext{\idxcode{+}|see{addition~operator}}% -\indextext{subtraction~operator}% -\indextext{\idxcode{-}|see{subtraction~operator}}% -% \begin{bnf} -\nontermdef{additive-expression}\br - multiplicative-expression\br - additive-expression \terminal{+} multiplicative-expression\br - additive-expression \terminal{-} multiplicative-expression + \nontermdef{yield-expression}\br + \keyword{co_yield} assignment-expression\br + \keyword{co_yield} braced-init-list \end{bnf} -\indextext{incomplete}% -For addition, either both operands shall have arithmetic or unscoped enumeration -type, or one operand shall be a pointer to a completely-defined object -type and the other shall have integral or unscoped enumeration type. - \pnum -For subtraction, one of the following shall hold: +A \grammarterm{yield-expression} shall appear only within a suspension context +of a function\iref{expr.await}. +Let \placeholder{e} be the operand of the \grammarterm{yield-expression} and +\placeholder{p} be an lvalue naming the promise object of the enclosing +coroutine\iref{dcl.fct.def.coroutine}, then the \grammarterm{yield-expression} +is equivalent to the expression +\tcode{\keyword{co_await} \placeholder{p}.yield_value(\placeholder{e})}. -\begin{itemize} -\item both operands have arithmetic or unscoped enumeration type; or - -\indextext{arithmetic!pointer}% -\item both operands are pointers to cv-qualified or cv-unqualified -versions of the same completely-defined object type; or +\begin{example} +\begin{codeblock} +template +struct my_generator { + struct promise_type { + T current_value; + @\commentellip@ + auto yield_value(T v) { + current_value = std::move(v); + return std::suspend_always{}; + } + }; + struct iterator { @\commentellip@ }; + iterator begin(); + iterator end(); +}; -\item the left operand is a pointer to a completely-defined object type -and the right operand has integral or unscoped enumeration type. -\end{itemize} +my_generator> g1() { + for (int i = 0; i < 10; ++i) co_yield {i,i}; +} +my_generator> g2() { + for (int i = 0; i < 10; ++i) co_yield make_pair(i,i); +} -\pnum -The result of the binary \tcode{+} operator is the sum of the operands. -The result of the binary \tcode{-} operator is the difference resulting -from the subtraction of the second operand from the first. +auto f(int x = co_yield 5); // error: \grammarterm{yield-expression} outside of function suspension context +int a[] = { co_yield 1 }; // error: \grammarterm{yield-expression} outside of function suspension context -\pnum -\indextext{arithmetic!pointer}% -When an expression that has integral type is added to or subtracted from -a pointer, the result has the type of the pointer operand. If the -pointer operand points to an element of an array object% -\footnote{An object that is not an array element is considered to belong to a -single-element array for this purpose; see~\ref{expr.unary.op}.}, and the array -is large enough, the result points to an element offset from the -original element such that the difference of the subscripts of the -resulting and original array elements equals the integral expression. In -other words, if the expression \tcode{P} points to the $i$-th element of -an array object, the expressions \tcode{(P)+N} (equivalently, -\tcode{N+(P)}) and \tcode{(P)-N} (where \tcode{N} has the value $n$) -point to, respectively, the $i+n$-th and $i-n$-th elements of the array -object, provided they exist. Moreover, if the expression \tcode{P} -points to the last element of an array object, the expression -\tcode{(P)+1} points one past the last element of the array object, and -if the expression \tcode{Q} points one past the last element of an array -object, the expression \tcode{(Q)-1} points to the last element of the -array object. If both the pointer operand and the result point to -elements of the same array object, or one past the last element of the -array object, the evaluation shall not produce an overflow; otherwise, -the behavior is undefined. +int main() { + auto r1 = g1(); + auto r2 = g2(); + assert(std::equal(r1.begin(), r1.end(), r2.begin(), r2.end())); +} +\end{codeblock} +\end{example} + +\rSec2[expr.throw]{Throwing an exception}% +\indextext{expression!\idxcode{throw}}% +\indextext{exception handling!throwing}% +\indextext{\idxcode{throw}}% +% +\begin{bnf} +\nontermdef{throw-expression}\br + \keyword{throw} \opt{assignment-expression} +\end{bnf} \pnum -\indextext{\idxcode{ptrdiff_t}!implementation~defined type~of}% -\indextext{subtraction!implementation~defined pointer}% -\indextext{\idxcode{ptrdiff_t}}% -\indextext{\idxhdr{cstddef}}% -\indextext{comparison!undefined pointer}% -When two pointers to elements of the same array object are subtracted, -the result is the difference of the subscripts of the two array -elements. 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 \tcode{} -header~(\ref{support.types}). As with any other arithmetic overflow, if -the result does not fit in the space provided, the behavior is -undefined. In other words, if the expressions \tcode{P} and \tcode{Q} -point to, respectively, the $i$-th and $j$-th elements of an array -object, the expression \tcode{(P)-(Q)} has the value $i-j$ provided the -value fits in an object of type \tcode{std::ptrdiff_t}. Moreover, if the -expression \tcode{P} points either to an element of an array object or -one past the last element of an array object, and the expression -\tcode{Q} points to the last element of the same array object, the -expression \tcode{((Q)+1)-(P)} has the same value as \tcode{((Q)-(P))+1} -and as \tcode{-((P)-((Q)+1))}, and has the value zero if the expression -\tcode{P} points one past the last element of the array object, even -though the expression \tcode{(Q)+1} does not point to an element of the -array object. Unless both pointers point to elements of the same array -object, or one past the last element of the array object, the behavior -is undefined.\footnote{Another way to approach pointer arithmetic is first to convert the -pointer(s) to character pointer(s): In this scheme the integral value of -the expression added to or subtracted from the converted pointer is -first multiplied by the size of the object originally pointed to, and -the resulting pointer is converted back to the original type. For -pointer subtraction, the result of the difference between the character -pointers is similarly divided by the size of the object originally -pointed to. - -When viewed in this way, an implementation need only provide one extra -byte (which might overlap another object in the program) just after the -end of the object in order to satisfy the ``one past the last element'' -requirements.} +A \grammarterm{throw-expression} is of type \keyword{void}. \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~(\ref{conv.qual}), the behavior is undefined. -\enternote In particular, a pointer to a base class cannot be used for -pointer arithmetic when the array contains objects of a derived class type. -\exitnote +A \grammarterm{throw-expression} with an operand throws an +exception\iref{except.throw}. +The array-to-pointer\iref{conv.array} and function-to-pointer\iref{conv.func} +standard conversions are performed on the operand. +The type of the exception object is determined by removing +any top-level \grammarterm{cv-qualifier}{s} from the type of the +(possibly converted) operand. +The exception object is copy-initialized\iref{dcl.init.general} +from the (possibly converted) operand. \pnum -If the value 0 is added to or subtracted from a pointer value, the -result compares equal to the original pointer value. If two pointers -point to the same object or both point one past the end of the same -array or both are null, and the two pointers are subtracted, the result -compares equal to the value 0 converted to the type -\tcode{std::ptrdiff_t}. +\indextext{exception handling!rethrow}% +A +\grammarterm{throw-expression} +with no operand rethrows the currently handled exception\iref{except.handle}. +\indextext{exception handling!terminate called@\tcode{terminate} called}% +\indextext{\idxcode{terminate}!called}% +If no exception is presently being handled, +the function \tcode{std::terminate} is invoked\iref{except.terminate}. +Otherwise, the exception is reactivated with the existing exception object; +no new exception object is created. +The exception is no longer considered to be caught. +\begin{example} +An exception handler that cannot completely handle the exception itself +can be written like this: +\begin{codeblock} +try { + // ... +} catch (...) { // catch all exceptions + // respond (partially) to exception + throw; // pass the exception to some other handler +} +\end{codeblock} +\end{example} -\rSec1[expr.shift]{Shift operators} +\rSec2[expr.assign]{Assignment and compound assignment operators}% +\indextext{expression!assignment and compound assignment} \pnum -\indextext{expression!left-shift-operator}% -\indextext{expression!right-shift-operator}% -\indextext{shift~operator|see{left~shift~operator,~right~shift~operator}}% -\indextext{operator~right~shift|see{right~shift~operator}}% -\indextext{operator~left~shift|see{left~shift~operator}}% -The shift operators \tcode{\shl} and \tcode{\shr} group left-to-right. - -\indextext{left~shift~operator}% -\indextext{\idxcode{\shl}|see{left~shift~operator}}% -\indextext{right~shift~operator}% -\indextext{\idxcode{\shr}|see{right~shift~operator}}% -% +\indextext{operator!assignment}% +\indextext{\idxcode{=}|see{assignment operator}}% +\indextext{operator!\idxcode{+=}}% +\indextext{operator!\idxcode{-=}}% +\indextext{operator!\idxcode{*=}}% +\indextext{operator!\idxcode{/=}}% +\indextext{operator!\idxcode{\%=}}% +\indextext{operator!\idxcode{>>=}}% +\indextext{operator!\idxcode{<<=}}% +\indextext{operator!\idxcode{\&=}}% +\indextext{operator!\idxcode{\caret=}}% +\indextext{operator!\idxcode{"|=}}% +The assignment operator (\tcode{=}) and the compound assignment +operators all group right-to-left. +\indextext{assignment!and lvalue}% +All +require a modifiable lvalue as their left operand; their result is an lvalue +of the type of the left operand, referring to the left operand. The result in all cases is a bit-field if +the left operand is a bit-field. In all cases, the assignment is +sequenced after the +\indextext{value computation}% +value computation of the right and left operands, +and before the +value computation of the assignment expression. +The right operand is sequenced before the left operand. +With +respect to an indeterminately-sequenced function call, the operation of +a compound assignment is a single evaluation. +\begin{note} +Therefore, a function call cannot intervene between the +lvalue-to-rvalue conversion and the side effect associated with any +single compound assignment operator. +\end{note} + \begin{bnf} -\nontermdef{shift-expression}\br - additive-expression\br - shift-expression \terminal{\shl} additive-expression\br - shift-expression \terminal{\shr} additive-expression +\nontermdef{assignment-expression}\br + conditional-expression\br + yield-expression\br + throw-expression\br + logical-or-expression assignment-operator initializer-clause \end{bnf} -The operands shall be of integral or unscoped enumeration type and integral -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 -than or equal to the length in bits of the promoted left operand. +\begin{bnf} +\nontermdef{assignment-operator} \textnormal{one of}\br + \terminal{= *= /= \%= += -= >>= <<= \&= \caret= |=} +\end{bnf} \pnum -The value of \tcode{E1 \shl\ E2} is \tcode{E1} left-shifted \tcode{E2} bit positions; vacated bits are -zero-filled. If \tcode{E1} has an unsigned type, the value of the result -is $\mathrm{E1}\times2^\mathrm{E2}$, reduced modulo -one more than the maximum value representable in the result type. Otherwise, if -\tcode{E1} has a signed type and non-negative value, and $\mathrm{E1}\times2^\mathrm{E2}$ is -representable in the corresponding unsigned type of the result type, then -that value, converted to the result type, is the resulting value; otherwise, the -behavior is undefined. +In simple assignment (\tcode{=}), +let \tcode{V} be the result of the right operand; +the object referred to by the left operand is +modified\iref{defns.access} by replacing its value +with \tcode{V} or, +if the object is of integer type, +with the value congruent\iref{basic.fundamental} to \tcode{V}. \pnum -The value of \tcode{E1 \shr\ E2} is \tcode{E1} right-shifted \tcode{E2} -bit positions. If \tcode{E1} has an unsigned type or if \tcode{E1} has a -signed type and a non-negative value, the value of the result is the -integral part of the quotient of $\mathrm{E1}/2^\mathrm{E2}$. If \tcode{E1} -\indextext{right~shift!implementation~defined}% -has a signed type and a negative value, the resulting value is -\impldef{result of right shift of negative value}. +\indextext{assignment!conversion by}% +If the right operand is an expression, it is implicitly +converted\iref{conv} to the cv-unqualified type of the left +operand. -\rSec1[expr.rel]{Relational operators}% -\indextext{expression!relational operators}% -\indextext{operator!relational} +\pnum +\indextext{reference!assignment to}% +When the left operand of an assignment operator +is a bit-field that cannot represent the value of the expression, the +resulting value of the bit-field is +\impldefplain{value of bit-field that cannot represent!assigned value}. \pnum -The relational operators group left-to-right. -\enterexample -\tcode{a}|see{greater~than~operator}}% -\indextext{operator!less~than~or~equal~to}% -\indextext{\idxcode{<=}|see{less~than~or~equal~to~operator}}% -\indextext{operator!greater~than~or~equal~to}% -\indextext{\idxcode{>=}|see{greater~than~or~equal~operator}}% -% -\begin{bnf} -\nontermdef{relational-expression}\br - shift-expression\br - relational-expression \terminal{<} shift-expression\br - relational-expression \terminal{>} shift-expression\br - relational-expression \terminal{<=} shift-expression\br - relational-expression \terminal{>=} shift-expression -\end{bnf} +An assignment whose left operand is of +a volatile-qualified type is deprecated\iref{depr.volatile.type} +unless the (possibly parenthesized) assignment is a discarded-value expression or +an unevaluated operand\iref{term.unevaluated.operand}. -The operands shall have arithmetic, enumeration, or pointer type. The -operators \tcode{<} (less than), \tcode{>} (greater than), \tcode{<=} -(less than or equal to), and \tcode{>=} (greater than or equal to) all -yield \tcode{false} or \tcode{true}. The type of the result is -\tcode{bool}. +\pnum +The behavior of an expression of the form \tcode{E1 \placeholder{op}= E2} +is equivalent to \tcode{E1 = E1 \placeholder{op} E2} except +that \tcode{E1} is evaluated only once. +\begin{note} +The object designated by \tcode{E1} is accessed twice. +\end{note} +For \tcode{+=} and \tcode{-=}, +\tcode{E1} shall either have arithmetic type or be a pointer to a +possibly cv-qualified completely-defined object type. In all other +cases, \tcode{E1} shall have arithmetic type. \pnum -The usual arithmetic conversions are performed on operands of arithmetic -or enumeration type. If both operands are pointers, pointer -conversions~(\ref{conv.ptr}) and qualification conversions~(\ref{conv.qual}) -are performed to bring -them to their composite pointer type (Clause~\ref{expr}). -After conversions, the operands shall have the same type. +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. +\begin{note} +This restriction applies to the relationship +between the left and right sides of the assignment operation; it is not a +statement about how the target of the assignment can be aliased in general. +See~\ref{basic.lval}. +\end{note} \pnum -Comparing pointers to objects% -\footnote{An object that is not an array element is considered to belong to a -single-element array for this purpose; see~\ref{expr.unary.op}.} -is defined as follows: +A \grammarterm{braced-init-list} $B$ may appear on the right-hand side of \begin{itemize} -\item If two pointers point to different elements of the same array, or to -subobjects thereof, the pointer to the element with the higher subscript -compares greater. +\item +an assignment to a scalar of type \tcode{T}, in which case $B$ +shall have at most a single element. +The meaning of \tcode{x = $B$} is \tcode{x = t}, +where \tcode{t} is an invented temporary variable +declared and initialized as \tcode{T t = $B$}. -\item If one pointer points to an element of an array, or to a subobject -thereof, and another pointer points one past the last element of the array, the -latter pointer compares greater. +\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.assign,over.match}. +\end{itemize} -\item If two pointers point to different non-static data members of the same -object, or to subobjects of such members, recursively, -the pointer to the later declared member compares greater provided the -two members -have the same access control (Clause~\ref{class.access}) -and provided their class is not a union. +\begin{example} +\begin{codeblock} +complex z; +z = { 1,2 }; // meaning \tcode{z.operator=(\{1,2\})} +z += { 1, 2 }; // meaning \tcode{z.operator+=(\{1,2\})} +int a, b; +a = b = { 1 }; // meaning \tcode{a=b=1;} +a = { 1 } = b; // syntax error +\end{codeblock} +\end{example} -\end{itemize} +\rSec2[expr.comma]{Comma operator}% +\indextext{expression!comma}% +\indextext{operator!comma}% +\indextext{comma operator|see{operator, comma}}% +\indextext{\idxcode{,}|see{operator, comma}}% +\indextext{sequencing operator|see{operator, comma}}% \pnum -If two operands \tcode{p} and \tcode{q} compare equal~(\ref{expr.eq}), -\tcode{p<=q} and \tcode{p>=q} both yield \tcode{true} and \tcode{pq} both yield \tcode{false}. Otherwise, if a pointer \tcode{p} -compares greater than a pointer \tcode{q}, \tcode{p>=q}, \tcode{p>q}, -\tcode{q<=p}, and \tcode{q=p}, and \tcode{q>p} all yield \tcode{false}. -Otherwise, the result of each of the operators is unspecified. +The comma operator groups left-to-right. + +\begin{bnf} +\nontermdef{expression}\br + assignment-expression\br + expression \terminal{,} assignment-expression +\end{bnf} + +A pair of expressions separated by a comma is evaluated left-to-right; +the left expression is +a discarded-value expression\iref{expr.prop}. +The left expression is sequenced before +the right expression\iref{intro.execution}. +\indextext{operator!side effects and comma}% +The type and value of the +result are the type and value of the right operand; the result is of the same +value category as its right operand, and is a bit-field if its +right operand is a bit-field. \pnum -If both operands (after conversions) are of arithmetic or enumeration type, each -of the operators shall yield \tcode{true} if the specified relationship is true -and \tcode{false} if it is false. +\begin{note} +In contexts where the comma token is given special meaning +(e.g., function calls\iref{expr.call}, +subscript expressions\iref{expr.sub}, +lists of initializers\iref{dcl.init}, +or \grammarterm{template-argument-list}{s}\iref{temp.names}), +the comma operator as described in this subclause can appear only in parentheses. +\begin{example} +\begin{codeblock} +f(a, (t=3, t+2), c); +\end{codeblock} +has three arguments, the second of which has the value +\tcode{5}. +\end{example} +\end{note} -\rSec1[expr.eq]{Equality operators}% -\indextext{expression!equality~operators}% -\indextext{operator!equality}% -\indextext{operator!inequality} +\rSec1[expr.const]{Constant evaluation}% +\indextext{expression!constant} + +\rSec2[expr.const.general]{General} \begin{bnf} -\nontermdef{equality-expression}\br - relational-expression\br - equality-expression \terminal{==} relational-expression\br - equality-expression \terminal{!=} relational-expression +\nontermdef{constant-expression}\br + conditional-expression \end{bnf} \pnum -The \tcode{==} (equal to) and the \tcode{!=} (not equal to) operators -group left-to-right. The operands shall have arithmetic, enumeration, pointer, -or pointer to member type, or type \tcode{std::nullptr_t}. The operators -\tcode{==} and \tcode{!=} both yield \tcode{true} or \tcode{false}, i.e., a -result of type \tcode{bool}. In each case below, the operands shall have the -same type after the specified conversions have been applied. +Certain contexts require expressions that satisfy additional +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 constant expressions. +\begin{note} +Certain constant expressions are evaluated during translation\iref{lex.phases}. +\end{note} + +\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} -\indextext{comparison!pointer}% -\indextext{comparison!pointer~to function}% -\pnum -If at least one of the operands is a pointer, pointer -conversions~(\ref{conv.ptr}) and qualification conversions~(\ref{conv.qual}) -are performed on both operands to bring them to their composite pointer type -(Clause~\ref{expr}). Comparing pointers is defined as follows: -Two pointers compare equal if they are both null, both point to the same -\indextext{address}% -function, or both represent the same address~(\ref{basic.compound}), otherwise -they compare unequal. +\rSec2[expr.const.core]{Core constant expressions} \pnum -If at least one of the operands is a pointer to member, pointer to member -conversions~(\ref{conv.mem}) and qualification -conversions~(\ref{conv.qual}) are performed on both operands to bring them to -their composite pointer type (Clause~\ref{expr}). -Comparing pointers to members is defined as follows: +\indextext{type!constexpr-unknown representation}% +A type has \defnadj{constexpr-unknown}{representation} if it +\begin{itemize} +\item is a union, +\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 +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 -If two pointers to members are both the null member pointer value, they compare -equal. +\keyword{this}\iref{expr.prim.this}, except +\begin{itemize} +\item +in a constexpr function\iref{dcl.constexpr} +that is being evaluated as part of $E$ or +\item +when appearing as the \grammarterm{postfix-expression} of +an implicit or explicit class member access expression\iref{expr.ref}; +\end{itemize} \item -If only one of two pointers to members is the null member pointer value, they -compare unequal. +a control flow that passes through +a declaration of a block variable\iref{basic.scope.block} with +static\iref{basic.stc.static} or +thread\iref{basic.stc.thread} storage duration, +unless that variable is usable in constant expressions; +\begin{example} +\begin{codeblock} +constexpr char test() { + static const int x = 5; + static constexpr char c[] = "Hello World"; + return *(c + x); +} +static_assert(' ' == test()); +\end{codeblock} +\end{example} \item -If either is a pointer to a virtual member function, the result is unspecified. +an invocation of a non-constexpr function; +\begin{footnote} +Overload resolution\iref{over.match} +is applied as usual. +\end{footnote} \item -If one refers to a member of class \tcode{C1} and the other refers to a member -of a different class \tcode{C2}, where neither is a base class of the other, -the result is unspecified. -\enterexample -\begin{codeblock} -struct A {}; -struct B : A { int x; }; -struct C : A { int x; }; +an invocation of an undefined constexpr function; -int A::*bx = (int(A::*))&B::x; -int A::*cx = (int(A::*))&C::x; +\item +an invocation of an instantiated constexpr function +that is not constexpr-suitable; -bool b1 = (bx == cx); // unspecified -\end{codeblock} -\exitexample +\item +an invocation of a virtual function\iref{class.virtual} +for an object whose dynamic type is constexpr-unknown; \item -If both refer to (possibly different) members of the same union~(\ref{class.union}), -they compare equal. +an expression that would exceed the implementation-defined +limits (see \ref{implimits}); \item -Otherwise, two pointers to members compare equal if they would refer to the same member of -the same most derived object~(\ref{intro.object}) or the same subobject if -indirection with a hypothetical object of the associated -class type were performed, otherwise they compare unequal. -\enterexample +an operation that would have undefined or erroneous behavior +as specified in \ref{intro} through \ref{\lastcorechapter}; +\begin{footnote} +This includes, +for example, signed integer overflow\iref{expr.pre}, certain +pointer arithmetic\iref{expr.add}, division by +zero\iref{expr.mul}, or certain shift operations\iref{expr.shift}. +\end{footnote} -\begin{codeblock} -struct B { - int f(); -}; -struct L : B { }; -struct R : B { }; -struct D : L, R { }; +\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}, -int (B::*pb)() = &B::f; -int (L::*pl)() = pb; -int (R::*pr)() = pb; -int (D::*pdl)() = pl; -int (D::*pdr)() = pr; -bool x = (pdl == pdr); // \tcode{false} -bool y = (pb == pl); // \tcode{true} -\end{codeblock} -\exitexample + \item + a non-volatile glvalue that refers to an object that is + usable in constant expressions, or + + \item + a non-volatile glvalue of literal type that refers to a non-volatile object + whose lifetime began within the evaluation of $E$; \end{itemize} -\pnum -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. +\item +an lvalue-to-rvalue conversion +that is applied to a glvalue +that refers to a non-active member of a union or a subobject thereof; -\pnum -If two operands compare equal, the result is \tcode{true} for -the \tcode{==} operator and \tcode{false} for the \tcode{!=} operator. If two operands -compare unequal, the result is \tcode{false} for the \tcode{==} operator and -\tcode{true} for the \tcode{!=} operator. Otherwise, the result of each of the -operators is unspecified. +\item +an lvalue-to-rvalue conversion that is applied to +an object with an indeterminate value\iref{basic.indet}; -\pnum -If both operands are of arithmetic or enumeration type, the usual arithmetic -conversions are performed on both operands; each of the operators shall yield -\tcode{true} if the specified relationship is true and \tcode{false} if it is -false. +\item +an invocation of an implicitly-defined copy/move constructor or +copy/move assignment operator +for a union whose active member (if any) is mutable, +unless the lifetime of the union object began within the evaluation of $E$; -\rSec1[expr.bit.and]{Bitwise AND operator}% -\indextext{expression!bitwise~AND}% -\indextext{operator!bitwise}% -\indextext{operator!bitwise AND}% -\indextext{\idxcode{\&}|see{bitwise~AND~operator}}% +\item +in a \grammarterm{lambda-expression}, +a reference to \keyword{this} or to a variable with +automatic storage duration defined outside that +\grammarterm{lambda-expression}, where +the reference would be an odr-use\iref{term.odr.use,expr.prim.lambda}; +\begin{example} +\begin{codeblock} +void g() { + const int n = 0; + [=] { + constexpr int i = n; // OK, \tcode{n} is not odr-used here + constexpr int j = *&n; // error: \tcode{\&n} would be an odr-use of \tcode{n} + }; +} +\end{codeblock} +\end{example} +\begin{note} +If the odr-use occurs in an invocation +of a function call operator of a closure type, +it no longer refers to \keyword{this} or to an enclosing +variable with automatic storage duration +due to the transformation\iref{expr.prim.lambda.capture} +of the \grammarterm{id-expression} into +an access of the corresponding data member. +\begin{example} +\begin{codeblock} +auto monad = [](auto v) { return [=] { return v; }; }; +auto bind = [](auto m) { + return [=](auto fvm) { return fvm(m()); }; +}; -\begin{bnf} -\nontermdef{and-expression}\br - equality-expression\br - and-expression \terminal{\&} equality-expression -\end{bnf} +// OK to capture objects with automatic storage duration created during constant expression evaluation. +static_assert(bind(monad(2))(monad)() == monad(2)()); +\end{codeblock} +\end{example} +\end{note} -\pnum -The usual arithmetic conversions are performed; the result is the -bitwise \logop{AND} function of the operands. The operator -applies only to integral or unscoped enumeration operands. +\item +a conversion +from a prvalue \tcode{P} of type ``pointer to \cv{}~\keyword{void}'' +to a type ``\cvqual{cv1} pointer to \tcode{T}'', +where \tcode{T} is not \cvqual{cv2}~\keyword{void}, +unless \tcode{P} +is a null pointer value or +points to an object whose type is similar to \tcode{T}; + +\item +a \keyword{reinterpret_cast}\iref{expr.reinterpret.cast}; -\rSec1[expr.xor]{Bitwise exclusive OR operator}% -\indextext{expression!bitwise~exclusive~OR}% -\indextext{operator!bitwise~exclusive OR}% -\indextext{\idxcode{\exor}|see{bitwise~exclusive~OR~operator}} +\item +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$; -\begin{bnf} -\nontermdef{exclusive-or-expression}\br - and-expression\br - exclusive-or-expression \terminal{\^{}} and-expression -\end{bnf} +\item +an invocation of a destructor\iref{class.dtor} or a function call +whose \grammarterm{postfix-expression} names a pseudo-destructor\iref{expr.call}, +in either case for an object whose lifetime did not begin within the evaluation of $E$; -\pnum -The usual arithmetic conversions are performed; the result is the -bitwise exclusive \logop{OR} function of the operands. The -operator applies only to integral or unscoped enumeration operands. +\item +a \grammarterm{new-expression}\iref{expr.new}, +unless either +\begin{itemize} +\item +the selected allocation function is +a replaceable global allocation function\iref{new.delete.single,new.delete.array} and +the allocated storage is deallocated within the evaluation of $E$, or +\item +the selected allocation function is +a non-allocating form\iref{new.delete.placement} +with an allocated type \tcode{T}, where +\begin{itemize} +\item +the placement argument to the \grammarterm{new-expression} points +to an object 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$; +\end{itemize} +\end{itemize} -\rSec1[expr.or]{Bitwise inclusive OR operator}% -\indextext{expression!bitwise~inclusive~OR}% -\indextext{operator!bitwise~inclusive OR}% -\indextext{\idxcode{"|}|see{bitwise~inclusive~OR~operator}} +\item +a \grammarterm{delete-expression}\iref{expr.delete}, +unless it deallocates a region of storage +allocated within the evaluation of $E$; -\begin{bnf} -\nontermdef{inclusive-or-expression}\br - exclusive-or-expression\br - inclusive-or-expression \terminal{|} exclusive-or-expression -\end{bnf} +\item +a call to an instance of +\tcode{std::allocator::allocate}\iref{allocator.members}, +unless the allocated storage is deallocated within the evaluation of $E$; -\pnum -The usual arithmetic conversions are performed; the result is the -bitwise inclusive \logop{OR} function of its operands. The -operator applies only to integral or unscoped enumeration operands. +\item +a call to an instance of +\tcode{std::allocator::deallocate}\iref{allocator.members}, +unless it deallocates a region of storage +allocated within the evaluation of $E$; -\rSec1[expr.log.and]{Logical AND operator}% -\indextext{expression!logical~AND}% -\indextext{operator!logical AND}% -\indextext{\idxcode{\&\&}|see{logical~AND~operator}}% +\item +a construction of an exception object, +unless the exception object and +all of its implicit copies created by invocations of +\tcode{std::current_exception} or \tcode{std::rethrow_exception}\iref{propagation} +are destroyed within the evaluation of $E$; -\begin{bnf} -\nontermdef{logical-and-expression}\br - inclusive-or-expression\br - logical-and-expression \terminal{\&\&} inclusive-or-expression -\end{bnf} +\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$; -\pnum -The \tcode{\&\&} operator groups left-to-right. The operands are both -contextually converted to \tcode{bool} -(Clause~\ref{conv}). The -result is \tcode{true} if both operands are \tcode{true} and -\tcode{false} otherwise. Unlike \tcode{\&}, \tcode{\&\&} guarantees -left-to-right evaluation: the second operand is not evaluated if the -first operand is \tcode{false}. +\item +an \grammarterm{await-expression}\iref{expr.await}; -\pnum -The result is a \tcode{bool}. -\indextext{operator!side~effects~and logical AND}% -If the second expression is evaluated, every -\indextext{value computation}% -value computation and -\indextext{side effects} -side -effect associated with the first expression is sequenced before every -value computation and side effect associated with the second expression. - -\rSec1[expr.log.or]{Logical OR operator}% -\indextext{expression!logical~OR}% -\indextext{operator!logical OR}% -\indextext{\idxcode{"|"|}|see{logical~OR~operator}}% +\item +a \grammarterm{yield-expression}\iref{expr.yield}; -\begin{bnf} -\nontermdef{logical-or-expression}\br - logical-and-expression\br - logical-or-expression \terminal{$||$} logical-and-expression -\end{bnf} +\item +a three-way comparison\iref{expr.spaceship}, +relational\iref{expr.rel}, or equality\iref{expr.eq} +operator where the result is unspecified; -\pnum -The \tcode{$||$} operator groups left-to-right. The operands are both -contextually converted to \tcode{bool} -(Clause~\ref{conv}). It returns -\tcode{true} if either of its operands is \tcode{true}, and -\tcode{false} otherwise. Unlike \tcode{$|$}, \tcode{$||$} guarantees -left-to-right evaluation; moreover, the second operand is not evaluated -if the first operand evaluates to \tcode{true}. +\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} -\pnum -The result is a \tcode{bool}. -\indextext{operator!side~effects~and logical OR}% -If the second expression is evaluated, every -\indextext{value computation}% -value computation and -\indextext{side effects}% -side effect -associated with the first expression is sequenced before every value computation -and side effect associated with the second expression. +\item +a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or +\keyword{typeid}\iref{expr.typeid} expression +on a glvalue that refers to an object +whose dynamic type is constexpr-unknown; -\rSec1[expr.cond]{Conditional operator}% -\indextext{expression!conditional~operator}% -\indextext{operator!conditional~expression}% -\indextext{\idxcode{?:}|see{conditional~expression~operator}}% +\item +a \tcode{dynamic_cast}\iref{expr.dynamic.cast} expression, +\tcode{typeid}\iref{expr.typeid} expression, or +\tcode{new-expression}\iref{expr.new} +that would throw an exception +where no definition of the exception type is reachable; -\begin{bnf} -\nontermdef{conditional-expression}\br - logical-or-expression\br - logical-or-expression \terminal{?} expression \terminal{:} assignment-expression -\end{bnf} +\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}; -\pnum -Conditional expressions group right-to-left. The first expression is -contextually converted to \tcode{bool} -(Clause~\ref{conv}). It is -evaluated and if it is \tcode{true}, the result of the conditional -expression is the value of the second expression, otherwise that of the -third expression. Only one of the second and third expressions is -evaluated. Every -\indextext{value computation}% -value computation and side effect associated with the -first expression is sequenced before every value computation and side -effect associated with the second or third expression. +\item +an \grammarterm{asm-declaration}\iref{dcl.asm}; -\pnum -If either the second or the third operand has type \tcode{void}, -one of the following shall hold: +\item +an invocation of the \libmacro{va_arg} macro\iref{cstdarg.syn}; -\begin{itemize} -\indextext{conditional-expression!throw-expression~in}% -\item The second or the third operand (but not both) is a (possibly -parenthesized) \grammarterm{throw-expression}~(\ref{expr.throw}); the result -is of the type and value category of the other. -The \grammarterm{conditional-expression} -is a bit-field if that operand is a bit-field. +\item +a non-constant library call\iref{defns.nonconst.libcall}; +or -\item Both the second and the third operands have type \tcode{void}; the -result is of type \tcode{void} and is a prvalue. \enternote This -includes the case where both operands are \grammarterm{throw-expression}{s}. -\exitnote +\item +a \keyword{goto} statement\iref{stmt.goto}. +\begin{note} +A \keyword{goto} statement introduced by equivalence\iref{stmt} +is not in scope. +For example, a \keyword{while} statement\iref{stmt.while} +can be executed during constant evaluation. +\end{note} \end{itemize} \pnum -Otherwise, if the second and third operand have different types and -either has (possibly cv-qualified) class type, or if both -are glvalues of the same value category and the same type except for -cv-qualification, an attempt is made to -convert each of those operands to the type of the other. The process for -determining whether an operand expression \tcode{E1} of type \tcode{T1} -can be converted to match an operand expression \tcode{E2} of type -\tcode{T2} is defined as follows: +It is +\impldef{whether an expression is a core constant expression} +whether $E$ is a core constant expression +if $E$ satisfies the constraints of a core constant expression, but +evaluation of $E$ has runtime-undefined behavior. +\pnum +It is unspecified whether $E$ is a core constant expression +if $E$ satisfies the constraints of a core constant expression, but +evaluation of $E$ would evaluate \begin{itemize} -\item If \tcode{E2} is an lvalue: \tcode{E1} can be converted to match -\tcode{E2} if \tcode{E1} can be implicitly converted (Clause~\ref{conv}) -to the type ``lvalue reference to \tcode{T2}'', subject to the -constraint that in the conversion the reference must bind -directly~(\ref{dcl.init.ref}) to an lvalue. +\item +an operation that has undefined behavior +as specified in \ref{library} through \ref{\lastlibchapter} or +\item +an invocation of the \libmacro{va_start} macro\iref{cstdarg.syn}. +\end{itemize} -\item If \tcode{E2} is an xvalue: \tcode{E1} can be converted to match \tcode{E2} -if \tcode{E1} can be implicitly converted to the type ``rvalue reference to \tcode{T2}'', -subject to the constraint that the reference must bind directly. +\pnum +\begin{example} +\begin{codeblock} +int x; // not constant +struct A { + constexpr A(bool b) : m(b?42:x) { } + int m; +}; +constexpr int v = A(true).m; // OK, constructor call initializes \tcode{m} with the value \tcode{42} -\item If \tcode{E2} is a prvalue or if neither of the conversions above can be -done and at least one of the operands has (possibly cv-qualified) class type: +constexpr int w = A(false).m; // error: initializer for \tcode{m} is \tcode{x}, which is non-constant -\begin{itemize} -\item if \tcode{E1} and \tcode{E2} have class type, and the underlying -class types are the same or one is a base class of the other: \tcode{E1} -can be converted to match \tcode{E2} if the class of \tcode{T2} is the -same type as, or a base class of, the class of \tcode{T1}, and the -cv-qualification of \tcode{T2} is the same cv-qualification as, or a -greater cv-qualification than, the cv-qualification of \tcode{T1}. If -the conversion is applied, \tcode{E1} is changed to a prvalue of type -\tcode{T2} by copy-initializing a temporary of type \tcode{T2} from -\tcode{E1} and using that temporary as the converted operand. - -\item Otherwise (if \tcode{E1} or \tcode{E2} has a non-class type, -or if they both have class types but the underlying classes are not -the same and neither is a base class of the other): \tcode{E1} can be -converted to match \tcode{E2} if \tcode{E1} can be implicitly converted -to the type that \tcode{E2} would have -after applying the -lvalue-to-rvalue~(\ref{conv.lval}), -array-to-pointer~(\ref{conv.array}), and -function-to-pointer~(\ref{conv.func}) -standard conversions. -\end{itemize} -\end{itemize} +constexpr int f1(int k) { + constexpr int x = k; // error: \tcode{x} is not initialized by a constant expression + // because lifetime of \tcode{k} began outside the initializer of \tcode{x} + return x; +} +constexpr int f2(int k) { + int x = k; // OK, not required to be a constant expression + // because \tcode{x} is not \keyword{constexpr} + return x; +} -Using this process, it is determined whether the second operand can be -converted to match the third operand, and whether the third operand can -be converted to match the second operand. If both can be converted, or -one can be converted but the conversion is ambiguous, the program is -ill-formed. If neither can be converted, the operands are left unchanged -and further checking is performed as described below. If exactly one -conversion is possible, that conversion is applied to the chosen operand -and the converted operand is used in place of the original operand for -the remainder of this section. +constexpr int incr(int &n) { + return ++n; +} +constexpr int g(int k) { + constexpr int x = incr(k); // error: \tcode{incr(k)} is not a core constant expression + // because lifetime of \tcode{k} began outside the expression \tcode{incr(k)} + return x; +} +constexpr int h(int k) { + int x = incr(k); // OK, \tcode{incr(k)} is not required to be a core constant expression + return x; +} +constexpr int y = h(1); // OK, initializes \tcode{y} with the value \tcode{2} + // \tcode{h(1)} is a core constant expression because + // the lifetime of \tcode{k} begins inside \tcode{h(1)} +\end{codeblock} +\end{example} \pnum -If the second and third operands are glvalues of the same value category -and have the same type, the -result is of that type and value category and it is a bit-field if the -second or the third operand is a bit-field, or if both are bit-fields. +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}, is ignored. \pnum -Otherwise, the result is a prvalue. If the second and third operands do -not have the same type, and either has (possibly cv-qualified) class -type, overload resolution is used to determine the conversions (if any) -to be applied to the operands~(\ref{over.match.oper},~\ref{over.built}). -If the overload resolution fails, the program is ill-formed. Otherwise, -the conversions thus determined are applied, and the converted operands -are used in place of the original operands for the remainder of this -section. +For the purposes of determining whether $E$ is a core constant expression, +the evaluation of a call to +a trivial copy/move constructor or copy/move assignment operator of a union +is considered to copy/move the active member of the union, if any. +\begin{note} +The copy/move of the active member is trivial. +\end{note} \pnum -Lvalue-to-rvalue~(\ref{conv.lval}), array-to-pointer~(\ref{conv.array}), -and function-to-pointer~(\ref{conv.func}) standard conversions are -performed on the second and third operands. After those conversions, one -of the following shall hold: - +For the purposes of determining whether $E$ is a core constant expression, +the evaluation of an \grammarterm{id-expression} +that names a structured binding \tcode{v}\iref{dcl.struct.bind} has the +following semantics: \begin{itemize} -\item The second and third operands have the same type; the result is of -that type. If the operands have class type, the result is a prvalue -temporary of the result type, which is copy-initialized from either the -second operand or the third operand depending on the value of the first -operand. +\item +If \tcode{v} is an lvalue referring to the object bound to an invented reference \tcode{r}, +the behavior is as if \tcode{r} were nominated. +\item +Otherwise, if \tcode{v} names an array element or class member, +the behavior is that of +evaluating \tcode{$e$[$i$]} or \tcode{$e$.$m$}, respectively, +where $e$ is the name of the variable +initialized from the initializer of the structured binding declaration, and +$i$ is the index of the element referred to by \tcode{v} or +$m$ is the name of the member referred to by \tcode{v}, respectively. +\end{itemize} +\begin{example} +\begin{codeblock} +#include +struct S { + mutable int m; + constexpr S(int m): m(m) {} + virtual int g() const; +}; +void f(std::tuple t) { + auto [r] = t; + static_assert(r.g() >= 0); // error: dynamic type is constexpr-unknown + constexpr auto [m] = S(1); + static_assert(m == 1); // error: lvalue-to-rvalue conversion on mutable + // subobject \tcode{e.m}, where \tcode{e} is a constexpr object of type \tcode{S} + using A = int[2]; + constexpr auto [v0, v1] = A{2, 3}; + static_assert(v0 + v1 == 5); // OK, equivalent to \tcode{e[0] + e[1]} where \tcode{e} is a constexpr array +} +\end{codeblock} +\end{example} + +\pnum +During the evaluation of an expression $E$ as a core constant expression, +all \grammarterm{id-expression}s, \grammarterm{splice-expression}s, and +uses of \tcode{*\keyword{this}} +that refer to an object or reference +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. +For such an object that is not usable in constant expressions, +the dynamic type of the object is \defn{constexpr-unknown}. +For such a reference that is not usable in constant expressions, +the reference is treated as binding to +an unspecified object of the referenced type +whose lifetime and that of all subobjects includes +the entire constant evaluation and whose dynamic type is constexpr-unknown. +\begin{example} +\begin{codeblock} +template +constexpr size_t array_size(T (&)[N]) { + return N; +} -\item The second and third operands have arithmetic or enumeration type; -the usual arithmetic conversions are performed to bring them to a common -type, and the result is of that type. +void use_array(int const (&gold_medal_mel)[2]) { + constexpr auto gold = array_size(gold_medal_mel); // OK +} -\item One or both of the second and third operands have pointer type; pointer -conversions~(\ref{conv.ptr}) and qualification -conversions~(\ref{conv.qual}) are performed to bring them to their -composite pointer type (Clause~\ref{expr}). The result is of the composite -pointer type. +constexpr auto olympic_mile() { + const int ledecky = 1500; + return []{ return ledecky; }; +} +static_assert(olympic_mile()() == 1500); // OK -\item One or both of the second and third operands have pointer to member type; -pointer to member conversions~(\ref{conv.mem}) and qualification -conversions~(\ref{conv.qual}) are performed to bring them to their composite -pointer type (Clause~\ref{expr}). The result is of the composite pointer type. +struct Swim { + constexpr int phelps() { return 28; } + virtual constexpr int lochte() { return 12; } + int coughlin = 12; +}; -\item -Both the second and third operands have type \tcode{std::nullptr_t} or one has -that type and the other is a null pointer constant. The result is of type -\tcode{std::nullptr_t}. +constexpr int how_many(Swim& swam) { + Swim* p = &swam; + return (p + 1 - 1)->phelps(); +} -\end{itemize} +void splash(Swim& swam) { + static_assert(swam.phelps() == 28); // OK + static_assert((&swam)->phelps() == 28); // OK -\rSec1[expr.throw]{Throwing an exception}% -\indextext{expression!\idxcode{throw}}% -\indextext{exception handling!throwing}% -\indextext{\idxcode{throw}}% -% -\begin{bnf} -\nontermdef{throw-expression}\br - \terminal{throw} assignment-expression\opt -\end{bnf} + Swim* pswam = &swam; + static_assert(pswam->phelps() == 28); // error: lvalue-to-rvalue conversion on a pointer + // not usable in constant expressions -\pnum -A \grammarterm{throw-expression} is of type \tcode{void}. + static_assert(how_many(swam) == 28); // OK + static_assert(Swim().lochte() == 12); // OK -\pnum -Evaluating a \grammarterm{throw-expression} with an operand throws an -exception~(\ref{except.throw}); the type of the exception object is determined by removing -any top-level \grammarterm{cv-qualifiers} from the static type of the -operand and adjusting the type from ``array of \tcode{T}'' or ``function -returning \tcode{T}'' to ``pointer to \tcode{T}'' or ``pointer to function returning -\tcode{T},'' respectively. + static_assert(swam.lochte() == 12); // error: invoking virtual function on reference + // with constexpr-unknown dynamic type -\pnum -\indextext{exception handling!rethrow}% -A -\grammarterm{throw-expression} -with no operand rethrows the currently handled exception~(\ref{except.handle}). -The exception is reactivated with the existing exception object; -no new exception object is created. -The exception is no longer considered to be caught. -\enterexample -Code that must be executed because of an exception, but cannot -completely handle the exception itself, can be written like this: -\begin{codeblock} -try { - // ... -} catch (...) { // catch all exceptions - // respond (partially) to exception - throw; // pass the exception to some - // other handler + static_assert(swam.coughlin == 12); // error: lvalue-to-rvalue conversion on an object + // not usable in constant expressions } + +extern Swim dc; +extern Swim& trident; + +constexpr auto& sandeno = typeid(dc); // OK, can only be \tcode{typeid(Swim)} +constexpr auto& gallagher = typeid(trident); // error: constexpr-unknown dynamic type \end{codeblock} -\exitexample +\end{example} + +\rSec2[expr.const.const]{Constant expressions} \pnum -\indextext{exception handling!rethrow}% -\indextext{exception handling!terminate called@\tcode{terminate()} called}% -\indextext{\idxcode{terminate()}!called}% -If no exception is presently being handled, -evaluating a -\grammarterm{throw-expression} -with no operand calls -\tcode{std\colcol{}terminate()}~(\ref{except.terminate}). +A \defnadj{constant}{expression} is either +\begin{itemize} +\item +a glvalue core constant expression $E$ for which +\begin{itemize} +\item +$E$ refers to a non-immediate function, +\item +$E$ designates an object \tcode{o}, and +if the complete object of \tcode{o} is of consteval-only type then so is $E$, +\begin{example} +\begin{codeblock} +struct Base { }; +struct Derived : Base { std::meta::info r; }; -\rSec1[expr.ass]{Assignment and compound assignment operators}% -\indextext{expression!assignment and compound assignment} +consteval const Base& fn(const Derived& derived) { return derived; } -\pnum -\indextext{operator!assignment}% -\indextext{\idxcode{=}|see{assignment~operator}}% -\indextext{operator!\idxcode{+=}}% -\indextext{operator!\idxcode{-=}}% -\indextext{operator!\idxcode{*=}}% -\indextext{operator!\idxcode{/=}}% -\indextext{operator!\idxcode{\%=}}% -\indextext{operator!\idxcode{\shr=}}% -\indextext{operator!\idxcode{\shl=}}% -\indextext{operator!\idxcode{\&=}}% -\indextext{operator!\idxcode{\^{}=}}% -\indextext{operator!\idxcode{"|=}}% -The assignment operator (\tcode{=}) and the compound assignment -operators all group right-to-left. -\indextext{assignment!and lvalue}% -All -require a modifiable lvalue as their left operand and return an lvalue -referring to the left operand. The result in all cases is a bit-field if -the left operand is a bit-field. In all cases, the assignment is -sequenced after the -\indextext{value computation}% -value computation of the right and left operands, -and before the -value computation of the assignment expression. With -respect to an indeterminately-sequenced function call, the operation of -a compound assignment is a single evaluation. -\enternote -Therefore, a function call shall not intervene between the -lvalue-to-rvalue conversion and the side effect associated with any -single compound assignment operator. -\exitnote +constexpr Derived obj{.r=^^::}; // OK +constexpr const Derived& d = obj; // OK +constexpr const Base& b = fn(obj); // error: not a constant expression because \tcode{Derived} + // is a consteval-only type but \tcode{Base} is not. +\end{codeblock} +\end{example} +\end{itemize} +or +\item +a prvalue core constant expression whose result object\iref{basic.lval} (if any) +satisfies the following constraints: +\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}, +\item +no constituent value of pointer-to-member type designates an immediate function, and +\item +unless the value is of consteval-only type, +\begin{itemize} +\item +no constituent value of pointer-to-member type points to +a direct member of a consteval-only class type, +\item +no constituent value of pointer type points to or past an object +whose complete object is of consteval-only type, and +\item +no constituent reference refers to an object +whose complete object is of consteval-only type. +\end{itemize} +\end{itemize} +\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 -\begin{bnf} -\nontermdef{assignment-expression}\br - conditional-expression\br - logical-or-expression assignment-operator initializer-clause\br - throw-expression -\end{bnf} +struct S { + int x; + constexpr S() {} +}; +int i() { + constexpr S s; // error: \tcode{s.x} has erroneous value +} +\end{codeblock} +\end{example} -\begin{bnf} -\nontermdef{assignment-operator} \textnormal{one of}\br - \terminal{= *= /= \%= += -= \shr= \shl= \&= \^{}= |=} -\end{bnf} +\pnum +An \defnadj{integral constant}{expression} +is an expression of integral or +unscoped enumeration type, implicitly converted to a prvalue, where the converted expression is a core constant expression. +\begin{note} +Such expressions can be +used as bit-field lengths\iref{class.bit}, as enumerator +initializers if the underlying type is not fixed\iref{dcl.enum}, +and as alignments\iref{dcl.align}. +\end{note} \pnum -In simple assignment (\tcode{=}), the value of the expression replaces -that of the object referred to by the left operand. +If an expression of literal class type is used in a context where an +integral constant expression is required, then that expression is +contextually implicitly converted\iref{conv} to an integral or unscoped +enumeration type +and the selected conversion function shall be \keyword{constexpr}. +\begin{example} +\begin{codeblock} +struct A { + constexpr A(int i) : val(i) { } + constexpr operator int() const { return val; } + constexpr operator long() const { return 42; } +private: + int val; +}; +constexpr A a = alignof(int); +alignas(a) int n; // error: ambiguous conversion +struct B { int n : a; }; // error: ambiguous conversion +\end{codeblock} +\end{example} \pnum -\indextext{assignment!conversion~by}% -If the left operand is not of class type, the expression is implicitly -converted (Clause~\ref{conv}) to the cv-unqualified type of the left -operand. +A \defnadj{converted constant}{expression} +of type \tcode{T} is an +expression, implicitly converted to type \tcode{T}, where +the converted expression is a constant expression and the +implicit conversion sequence contains only +\begin{itemize} +\item user-defined conversions, +\item lvalue-to-rvalue conversions\iref{conv.lval}, +\item array-to-pointer conversions\iref{conv.array}, +\item function-to-pointer conversions\iref{conv.func}, +\item qualification conversions\iref{conv.qual}, +\item integral promotions\iref{conv.prom}, +\item integral conversions\iref{conv.integral} other than narrowing conversions\iref{dcl.init.list}, +\item floating-point promotions\iref{conv.fpprom}, +\item floating-point conversions\iref{conv.double} where + the source value can be represented exactly in the destination type, +\item null pointer conversions\iref{conv.ptr} from \tcode{std::nullptr_t}, +\item null member pointer conversions\iref{conv.mem} from \tcode{std::nullptr_t}, and +\item function pointer conversions\iref{conv.fctptr}, +\end{itemize} +and where the reference binding (if any) binds directly. +\begin{note} +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}, +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 -\indextext{class~object!assignment~to}% -\indextext{type!incomplete}% -If the left operand is of class type, the class shall be complete. -Assignment to objects of a class is defined by the copy/move assignment -operator~(\ref{class.copy},~\ref{over.ass}). +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. -\pnum -\enternote -For class objects, assignment is not in general the same as -initialization~(\ref{dcl.init},~\ref{class.ctor},~\ref{class.init},~\ref{class.copy}). -\exitnote +\rSec2[expr.const.init]{Constant initialization} \pnum -\indextext{reference!assignment~to}% -When the left operand of an assignment operator -is a bit-field that cannot represent the value of the expression, the -resulting value of the bit-field is -\impldef{value of bit-field that cannot represent!assigned value}. +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\iref{intro.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 -The behavior of an expression of the form \tcode{E1} \term{op}\tcode{=} -\tcode{E2} is equivalent to \tcode{E1 = E1} \term{op} \tcode{E2} except -that \tcode{E1} is evaluated only once. In \tcode{+=} and \tcode{-=}, -\tcode{E1} shall either have arithmetic type or be a pointer to a -possibly cv-qualified completely-defined object type. In all other -cases, \tcode{E1} shall have arithmetic type. +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 -If the value being stored in an object is accessed from 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. \enternote This restriction applies to the relationship -between the left and right sides of the assignment operation; it is not a -statement about how the target of the assignment may be aliased in general. -See~\ref{basic.lval}. \exitnote +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 \grammarterm{braced-init-list} may appear on the right-hand side of - +\indextext{contract evaluation semantics!ignore} +A variable \tcode{v} is \defn{constant-initializable} if \begin{itemize} -\item an assignment to a scalar, in which case the initializer list shall have -at most a single element. The meaning of \tcode{x=\{v\}}, where \tcode{T} is the -scalar type of the expression \tcode{x}, is that of \tcode{x=T\{v\}}. The meaning of -\tcode{x=\{\}} is \tcode{x=T\{\}}. - -\item an assignment to an object of class type, in which case the initializer -list is passed as the argument to the assignment operator function selected by -overload resolution~(\ref{over.ass}, \ref{over.match}). +\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} +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, +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} -\enterexample +\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} -complex z; -z = { 1,2 }; // meaning \tcode{z.operator=(\{1,2\})} -z += { 1, 2 }; // meaning \tcode{z.operator+=(\{1,2\})} -int a, b; -a = b = { 1 }; // meaning \tcode{a=b=1;} -a = { 1 } = b; // syntax error +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} -\exitexample - -\rSec1[expr.comma]{Comma operator}% -\indextext{expression!comma}% -\indextext{operator!comma}% -\indextext{\idxcode{,}|see{comma~operator}}% -\indextext{sequencing~operator|see{comma~operator}}% +\end{example} \pnum -The comma operator groups left-to-right. +A variable is \defn{potentially-constant} if +it is constexpr or +it has reference or non-volatile const-qualified integral or enumeration type. -\begin{bnf} -\nontermdef{expression}\br - assignment-expression\br - expression \terminal{,} assignment-expression -\end{bnf} - -A pair of expressions separated by a comma is evaluated left-to-right; -the left expression is -a discarded-value expression (Clause~\ref{expr}).\footnote{However, an -invocation of an overloaded comma operator is an ordinary function call; hence, -the evaluations of its argument expressions are unsequenced relative to one -another~(see \ref{intro.execution}).} -Every -\indextext{value computation}% -value computation and side effect -associated with the left expression is sequenced before every value -computation and side effect associated with the right expression. -\indextext{operator!side~effects~and comma}% -The type and value of the -result are the type and value of the right operand; the result is of the same -value category as its right operand, and is a bit-field if its -right operand is a glvalue and a bit-field. -If the value of the right operand is a temporary~(\ref{class.temporary}), -the result is that temporary. +\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 -In contexts where comma is given a special meaning, \enterexample in -lists of arguments to functions~(\ref{expr.call}) and lists of -initializers~(\ref{dcl.init}) \exitexample the comma operator as -described in Clause~\ref{expr} can appear only in parentheses. -\enterexample +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} -f(a, (t=3, t+2), c); +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} -has three arguments, the second of which has the value -\tcode{5}. -\exitexample - -\rSec1[expr.const]{Constant expressions}% -\indextext{expression!constant} +\rSec2[expr.const.imm]{Immediate functions} \pnum -Certain contexts require expressions that satisfy additional -requirements as detailed in this sub-clause; other contexts have different -semantics depending on whether or not an expression satisfies these requirements. -Expressions that satisfy these requirements are called -\term{constant expressions}. \enternote Constant expressions can be evaluated -during translation.\exitnote - -\begin{bnf} -\nontermdef{constant-expression}\br - conditional-expression -\end{bnf} +An expression or conversion is in an \defn{immediate function context} +if it is potentially evaluated and either: +\begin{itemize} +\item +its innermost enclosing non-block scope is +a function parameter scope of an immediate function, +\item +it is a subexpression of a manifestly constant-evaluated expression +or conversion, 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 +an immediate function and +is not in an immediate function context. +An aggregate initialization is an immediate invocation +if it evaluates a default member initializer +that has a subexpression that is an immediate-escalating expression. + +\pnum +\indexdefn{expression!immediate-escalating}% +\indexdefn{conversion!immediate-escalating}% +\indexdefn{immediate-escalating!expression|see{expression, immediate-escalating}}% +\indexdefn{immediate-escalating!conversion|see{conversion, immediate-escalating}}% +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 +it is an \grammarterm{id-expression} or \grammarterm{splice-expression} +that designates an immediate function, +\item +it is an immediate invocation that is not a constant expression, or +\item +it is of consteval-only type\iref{basic.types.general}. +\end{itemize} \pnum -A \grammarterm{conditional-expression} \tcode{e} is a \term{core constant expression} -unless the evaluation of \tcode{e}, following the rules of the abstract -machine~(\ref{intro.execution}), would evaluate one of the following expressions: - +\indexdefn{immediate-escalating!function|see{function, immediate-escalating}}% +An \defnx{immediate-escalating}{function!immediate-escalating} function is \begin{itemize} \item -\tcode{this}~(\ref{expr.prim.general}), except in a \tcode{constexpr} -function or a \tcode{constexpr} constructor that is being evaluated as part -of \tcode{e}; - +the call operator of a lambda that is not declared +with the \keyword{consteval} specifier, \item -an invocation of a function other than -a \tcode{constexpr} constructor for a literal class, -a \tcode{constexpr} function, -or an implicit invocation of a trivial destructor~(\ref{class.dtor}) -\enternote Overload resolution~(\ref{over.match}) -is applied as usual \exitnote; - +a non-user-provided defaulted function +that is not declared with the \keyword{consteval} specifier, or \item -an invocation of an undefined \tcode{constexpr} function or an -undefined \tcode{constexpr} constructor; +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 that is +\begin{itemize} \item -an expression that would exceed the implementation-defined -limits (see Annex~\ref{implimits}); - +declared with the \keyword{consteval} specifier, \item -an operation that would have undefined behavior \enternote including, -for example, signed integer overflow~(Clause \ref{expr}), certain -pointer arithmetic~(\ref{expr.add}), division by -zero~(\ref{expr.mul}), or certain shift operations~(\ref{expr.shift}) -\exitnote; - +an immediate-escalating function +whose type is consteval-only\iref{basic.types.general}, or \item -a \grammarterm{lambda-expression}~(\ref{expr.prim.lambda}); +an immediate-escalating function \tcode{\placeholder{F}} +whose function body contains either +\begin{itemize} +\item an immediate-escalating expression or +\item a definition of a non-constexpr variable with consteval-only type +\end{itemize} +whose innermost enclosing non-block scope +is \tcode{\placeholder{F}}'s function parameter scope. +\begin{tailnote} +Default member initializers used to initialize +a base or member subobject\iref{class.base.init} +are considered to be part of the function body\iref{dcl.fct.def.general}. +\end{tailnote} +\end{itemize} -\item -an lvalue-to-rvalue conversion~(\ref{conv.lval}) unless -it is applied to +\pnum +\begin{example} +\begin{codeblock} +consteval int id(int i) { return i; } +constexpr char id(char c) { return c; } -\begin{itemize} - \item - a non-volatile glvalue of integral or enumeration type that refers - to a complete non-volatile const object with a preceding initialization, - initialized with a constant expression, or +template +constexpr int f(T t) { + return t + id(t); +} - \item - a non-volatile glvalue that refers to a subobject of a string - literal~(\ref{lex.string}), or +auto a = &f; // OK, \tcode{f} is not an immediate function +auto b = &f; // error: \tcode{f} is an immediate function - \item - a non-volatile glvalue that refers to a non-volatile object - defined with \tcode{constexpr}, or that refers to a non-mutable sub-object - of such an object, or +static_assert(f(3) == 6); // OK - \item - a non-volatile glvalue of literal type that refers to a non-volatile object - whose lifetime began within the evaluation of \tcode{e}; -\end{itemize} +template +constexpr int g(T t) { // \tcode{g} is not an immediate function + return t + id(42); // because \tcode{id(42)} is already a constant +} -\item -an lvalue-to-rvalue conversion~(\ref{conv.lval}) or -modification~(\ref{expr.ass}, \ref{expr.post.incr}, \ref{expr.pre.incr}) -that is applied to a glvalue -that refers to a non-active member of a union or a subobject thereof; +template +constexpr bool is_not(T t, F f) { + return not f(t); +} -\item -an \grammarterm{id-expression} that refers to a variable or -data member of reference type -unless the reference has a preceding initialization and either +consteval bool is_even(int i) { return i % 2 == 0; } -\begin{itemize} - \item - it is initialized with a constant expression or +static_assert(is_not(5, is_even)); // OK - \item - it is a non-static data member of an object whose lifetime - began within the evaluation of \tcode{e}; -\end{itemize} +int x = 0; -\item -in a \grammarterm{lambda-expression}, -a reference to \tcode{this} or to a variable with -automatic storage duration defined outside that -\grammarterm{lambda-expression}, where -the reference would be an odr-use~(\ref{basic.def.odr}, \ref{expr.prim.lambda}); +template +constexpr T h(T t = id(x)) { // \tcode{h} is not an immediate function + // \tcode{id(x)} is not evaluated when parsing the default argument\iref{dcl.fct.default,temp.inst} + return t; +} -\item -a conversion from type \cv{} \tcode{void *} to a pointer-to-object type; +template +constexpr T hh() { // \tcode{hh} is an immediate function because of the invocation + return h(); // of the immediate function \tcode{id} in the default argument of \tcode{h} +} -\item -a dynamic cast~(\ref{expr.dynamic.cast}); +int i = hh(); // error: \tcode{hh()} is an immediate-escalating expression + // outside of an immediate-escalating function -\item -a \tcode{reinterpret_cast}~(\ref{expr.reinterpret.cast}); +struct A { + int x; + int y = id(x); +}; -\item -a pseudo-destructor call~(\ref{expr.pseudo}); +template +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 +} -\item -modification of an object~(\ref{expr.ass}, \ref{expr.post.incr}, -\ref{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 \tcode{e}; +constexpr int l(int c) pre(c >= 2) { + return (c % 2 == 0) ? c / 0 : c; +} -\item -a typeid expression~(\ref{expr.typeid}) whose operand is a glvalue of a -polymorphic class type; +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} -\item -a \grammarterm{new-expression}~(\ref{expr.new}); +\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 -a \grammarterm{delete-expression}~(\ref{expr.delete}); - +an associated \defnadj{synthesized}{point}, +which follows the last non-synthesized program point +in the translation unit containing that declaration, and \item -a relational~(\ref{expr.rel}) or equality~(\ref{expr.eq}) -operator where the result is unspecified; or - +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 -a \grammarterm{throw-expression}~(\ref{expr.throw}). +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} -\enterexample +\pnum +\begin{example} \begin{codeblock} -int x; // not constant -struct A { - constexpr A(bool b) : m(b?42:x) { } - int m; +struct S0 { + consteval { + std::meta::define_aggregate(^^S0, {}); // error: scope associated with \tcode{S0} encloses the consteval block + } }; -constexpr int v = A(true).m; // OK: constructor call initializes - // \tcode{m} with the value \tcode{42} -constexpr int w = A(false).m; // error: initializer for \tcode{m} is - // \tcode{x}, which is non-constant -constexpr int f1(int k) { - constexpr int x = k; // error: \tcode{x} is not initialized by a - // constant expression because lifetime of \tcode{k} - // began outside the initializer of \tcode{x} - return x; -} -constexpr int f2(int k) { - int x = k; // OK: not required to be a constant expression - // because \tcode{x} is not \tcode{constexpr} - return x; -} +struct S1; +consteval { std::meta::define_aggregate(^^S1, {}); } // OK -constexpr int incr(int &n) { - return ++n; +template consteval void tfn1() { + std::meta::define_aggregate(R, {}); } -constexpr int g(int k) { - constexpr int x = incr(k); // error: \tcode{incr(k)} is not a core constant - // expression because lifetime of \tcode{k} - // began outside the expression \tcode{incr(k)} - return x; + +struct S2; +consteval { tfn1<^^S2>(); } // OK + +template consteval void tfn2() { + consteval { std::meta::define_aggregate(R, {}); } } -constexpr int h(int k) { - int x = incr(k); // OK: \tcode{incr(k)} is not required to be a core - // constant expression - return x; + +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} + } } -constexpr int y = h(1); // OK: initializes \tcode{y} with the value \tcode{2} - // \tcode{h(1)} is a core constant expression because - // the lifetime of \tcode{k} begins inside \tcode{h(1)} \end{codeblock} -\exitexample +\end{example} \pnum -An \term{integral constant expression} is an expression of integral or -unscoped enumeration type, implicitly converted to a prvalue, where the converted expression is a core constant expression. -\enternote -Such expressions may be -used as array bounds~(\ref{dcl.array}, \ref{expr.new}), -as bit-field lengths~(\ref{class.bit}), as enumerator -initializers if the underlying type is not fixed~(\ref{dcl.enum}), -and as alignments~(\ref{dcl.align}). -\exitnote +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} -\pnum -A \term{converted constant expression} of type \tcode{T} is an -expression, implicitly converted to type \tcode{T}, where -the converted expression is a constant expression and the -implicit conversion sequence contains only +\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 user-defined conversions, -\item lvalue-to-rvalue conversions~(\ref{conv.lval}), -\item array-to-pointer conversions~(\ref{conv.array}), -\item function-to-pointer conversions~(\ref{conv.func}), -\item qualification conversions~(\ref{conv.qual}), -\item integral promotions~(\ref{conv.prom}), -\item integral conversions~(\ref{conv.integral}) other than narrowing conversions~(\ref{dcl.init.list}), -\item null pointer conversions~(\ref{conv.ptr}) from \tcode{std::nullptr_t}, and -\item null member pointer conversions~(\ref{conv.mem}) from \tcode{std::nullptr_t}, +\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; +} -and where the reference binding (if any) binds directly. -\enternote -such expressions may be used in \tcode{new} -expressions~(\ref{expr.new}), as case expressions~(\ref{stmt.switch}), -as enumerator initializers if the underlying type is -fixed~(\ref{dcl.enum}), as array bounds~(\ref{dcl.array}), and -as non-type template -arguments~(\ref{temp.arg}). -\exitnote +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 +\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 +\item the initializer of a variable +that is usable in constant expressions or +has constant initialization\iref{basic.start.static}. +\begin{footnote} +Testing this condition +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} +template struct X {}; +X x; // type \tcode{X} +int y; +const int a = std::is_constant_evaluated() ? y : 1; // dynamic initialization to 1 +double z[a]; // error: \tcode{a} is not usable + // in constant expressions +const int b = std::is_constant_evaluated() ? 2 : y; // static initialization to 2 +int c = y + (std::is_constant_evaluated() ? 2 : y); // dynamic initialization to \tcode{y+y} + +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] = {}; // \tcode{char[13]} + return m + sizeof(arr); +} +int p = f(); // \tcode{m} is 13; initialized to 26 +int q = p + f(); // \tcode{m} is 17 for this call; initialized to 56 +\end{codeblock} +\end{example} +\end{itemize} +\begin{note} +Except for a \grammarterm{static_assert-message}, +a manifestly constant-evaluated expression +is evaluated even in an unevaluated operand\iref{term.unevaluated.operand}. +\end{note} \pnum -A \term{constant expression} is either -a glvalue core constant expression whose value refers to -an entity that is a permitted result of a constant expression (as defined below), or -a prvalue core constant expression whose value is an object where, for that -object and its subobjects: - +\indextext{expression!potentially constant evaluated}% +An expression or conversion is \defn{potentially constant evaluated} +if it is: \begin{itemize} - \item - each non-static data member of reference type refers to - an entity that is a permitted result of a constant expression, and +\item +a manifestly constant-evaluated expression, - \item - if the object or subobject is of pointer type, it contains - the address of an object with static storage duration, - the address past the end of such an object~(\ref{expr.add}), - the address of a function, - or a null pointer value. +\item +a potentially evaluated expression\iref{basic.def.odr}, + +\item +an immediate subexpression of a \grammarterm{braced-init-list}, +\begin{footnote} +In some cases, constant evaluation is needed to determine whether a narrowing conversion is performed\iref{dcl.init.list}. +\end{footnote} + +\item +an expression of the form \tcode{\&} \grammarterm{cast-expression} +that occurs within a templated entity, +\begin{footnote} +In some cases, constant evaluation is needed to determine whether such an expression is value-dependent\iref{temp.dep.constexpr}. +\end{footnote} +or + +\item +a potentially-evaluated subexpression\iref{intro.execution} of one of the above. \end{itemize} -\indextext{constant expression!permitted result of}% -An entity is a \term{permitted result of a constant expression} if it is an -object with static storage duration that is either not a temporary object or is -a temporary object whose value satisfies the above constraints, or it is a -function. -\pnum -\enternote Since this International Standard -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.\footnote{Nonetheless, implementations are encouraged to provide consistent results, -irrespective of whether the evaluation was performed during translation and/or during program -execution.} \enterexample +\indextext{function!needed for constant evaluation}% +\indextext{variable!needed for constant evaluation}% +A function or variable is +\defn{needed for constant evaluation} +if it is: +\begin{itemize} +\item +a constexpr function that is named by an expression\iref{basic.def.odr} +that is potentially constant evaluated, or -\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}. -\exitexample \exitnote +\item +a potentially-constant variable named by a potentially constant evaluated expression. +\end{itemize} \pnum -If an expression of literal class type is used in a context where an -integral constant expression is required, then that expression is -contextually implicitly converted (Clause~\ref{conv}) to an integral or unscoped -enumeration type -and the selected conversion function shall be \tcode{constexpr}. \enterexample -\begin{codeblock} -struct A { - constexpr A(int i) : val(i) { } - constexpr operator int() const { return val; } - constexpr operator long() const { return 43; } -private: - int val; -}; -template struct X { }; -constexpr A a = 42; -X x; // OK: unique conversion to \tcode{int} -int ary[a]; // error: ambiguous conversion -\end{codeblock} -\exitexample% +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/figdag.pdf b/source/figdag.pdf deleted file mode 100644 index e3d535caf2..0000000000 Binary files a/source/figdag.pdf and /dev/null differ diff --git a/source/figname.pdf b/source/figname.pdf deleted file mode 100644 index 5a603c462f..0000000000 Binary files a/source/figname.pdf and /dev/null differ diff --git a/source/fignonvirt.pdf b/source/fignonvirt.pdf deleted file mode 100644 index 3e55e71c65..0000000000 Binary files a/source/fignonvirt.pdf and /dev/null differ diff --git a/source/figstreampos.dot b/source/figstreampos.dot deleted file mode 100644 index 819d246236..0000000000 --- a/source/figstreampos.dot +++ /dev/null @@ -1,23 +0,0 @@ -digraph figstreampos -{ - traits_pos_type_char [label="char_traits\n::pos_type"]; - traits_pos_type_wchar_t [label="char_traits\n::pos_type"]; - traits_pos_type_char -> streampos [label=" iostreams.limits.pos"]; - traits_pos_type_wchar_t -> wstreampos [label=" iostreams.limits.pos"]; - streampos -> fpos [label=" iostream.forward"]; - fpos [label="fpos"]; - - traits_off_type_char [label="char_traits\n::off_type"]; - traits_off_type_wchar_t [label="char_traits\n::off_type"]; - traits_off_type_char -> streamoff [label=" iostreams.limits.pos"]; - traits_off_type_wchar_t -> streamoff [label=" iostreams.limits.pos"]; - wstreampos -> fpos [label=" iostream.forward"]; - - streamoff -> streamoff_type [label=" stream.types"]; - streamoff_type [label="signed integer type\nsufficient for\n O/S maximum file size"]; - - streamsize -> streamsize_type [label=" stream.types"]; - streamsize_type [label="signed integer type\nrepresents characters xfered\nor buffer sizes"]; - - -} diff --git a/source/figstreampos.pdf b/source/figstreampos.pdf deleted file mode 100644 index eb07ca7b7f..0000000000 Binary files a/source/figstreampos.pdf and /dev/null differ diff --git a/source/figvirt.pdf b/source/figvirt.pdf deleted file mode 100644 index 931e6a6097..0000000000 Binary files a/source/figvirt.pdf and /dev/null differ diff --git a/source/figvirtnonvirt.pdf b/source/figvirtnonvirt.pdf deleted file mode 100644 index ccfc2da16d..0000000000 Binary files a/source/figvirtnonvirt.pdf and /dev/null differ diff --git a/source/front.tex b/source/front.tex index 224a573902..5396b6397d 100644 --- a/source/front.tex +++ b/source/front.tex @@ -3,7 +3,7 @@ % \input{cover-reg} %%-------------------------------------------------- -%% The table of contents, list of tables, and list of figures +%% The table of contents \markboth{\contentsname}{} %%-------------------------------------------------- @@ -12,11 +12,21 @@ \renewcommand\@pnumwidth{2.5em} \makeatother -\tableofcontents +% Disable indexing within the table of contents +\newcommand{\indexoff}[2][generalindex]{} +\let\oindex\index +\let\index\indexoff + +%% Include table of contents. Do not list "Contents" +%% within it (per ISO request) but do include a +%% bookmark for it in the PDF. +\phantomsection +\pdfbookmark{\contentsname}{toctarget} +\hypertarget{toctarget}{\tableofcontents*} + +% Restore indexing +\let\index\oindex + \setcounter{tocdepth}{5} -\newpage -\listoftables -\newpage -\listoffigures -%\input{preface} +\input{preface} diff --git a/source/future.tex b/source/future.tex index a96681c3fd..72dbeabbc5 100644 --- a/source/future.tex +++ b/source/future.tex @@ -1,1387 +1,1053 @@ %!TEX root = std.tex \normannex{depr}{Compatibility features} +\rSec1[depr.general]{General} + \pnum -This Clause describes features of the \Cpp Standard that are specified for compatibility with -existing implementations. +This Annex describes features of this document +that are specified for compatibility with existing implementations. \pnum These are deprecated features, where \term{deprecated} is defined as: -Normative for the current edition of the Standard, +Normative for the current revision of \Cpp{}, but having been identified as a candidate for removal from future revisions. -An implementation may declare library names and entities described in this section with the -\tcode{deprecated} attribute~(\ref{dcl.attr.deprecated}). +An implementation may declare library names and entities described in this Clause with the +\tcode{deprecated} attribute\iref{dcl.attr.deprecated}. -\rSec1[depr.incr.bool]{Increment operator with \tcode{bool} operand} +\rSec1[depr.local]{Non-local use of TU-local entities} \pnum -The use of an operand of type -\tcode{bool} -with the -\tcode{++} -operator is deprecated (see~\ref{expr.pre.incr} and~\ref{expr.post.incr}). +A declaration of a non-TU-local entity that is an exposure\iref{basic.link} +is deprecated. +\begin{note} +Such a declaration in an importable module unit is ill-formed. +\end{note} +\begin{example} +\begin{codeblock} +namespace { + struct A { + void f() {} + }; +} +A h(); // deprecated: not internal linkage +inline void g() {A().f();} // deprecated: inline and not internal linkage +\end{codeblock} +\end{example} -\rSec1[depr.register]{\tcode{register} keyword} +\rSec1[depr.capture.this]{Implicit capture of \tcode{*this} by reference} \pnum -The use of the \tcode{register} keyword as a -\grammarterm{storage-class-specifier}~(\ref{dcl.stc}) is deprecated. +For compatibility with prior revisions of \Cpp{}, +a \grammarterm{lambda-expression} with \grammarterm{capture-default} +\tcode{=}\iref{expr.prim.lambda.capture} may implicitly capture +\tcode{*this} by reference. +\begin{example} +\begin{codeblock} +struct X { + int x; + void foo(int n) { + auto f = [=]() { x = n; }; // deprecated: \tcode{x} means \tcode{this->x}, not a copy thereof + auto g = [=, this]() { x = n; }; // recommended replacement + } +}; +\end{codeblock} +\end{example} -\rSec1[depr.impldec]{Implicit declaration of copy functions} +\rSec1[depr.volatile.type]{Deprecated \tcode{volatile} types} \pnum -The implicit definition of a copy constructor -as defaulted -is deprecated if the class has a -user-declared copy assignment operator or a user-declared destructor. The implicit -definition of a copy assignment operator -as defaulted is deprecated if the class has a user-declared -copy constructor or a user-declared destructor (\ref{class.dtor},~\ref{class.copy}). -In a future revision of this International Standard, these implicit definitions -could become deleted~(\ref{dcl.fct.def}). - -\rSec1[depr.except.spec]{Dynamic exception specifications} - -\pnum -The use of \grammarterm{dynamic-exception-specification}{s} is deprecated. - -\rSec1[depr.c.headers]{C standard library headers} - -\pnum -For compatibility with the -\indextext{library!C standard}% -C standard library and the C Unicode TR, the \Cpp standard library provides -the 26 \textit{C headers}, as shown in Table~\ref{tab:future.c.headers}. - -\begin{floattable}{C headers}{tab:future.c.headers} -{lllll} -\topline - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ - -\end{floattable} - -\pnum -Every C header, each of which has a name of the form -\indextext{header!C}% -\tcode{name.h}, -behaves as if each name placed in the standard library namespace by -the corresponding -\tcode{c\textit{name}} -header is placed within -the global namespace scope. It is unspecified whether these names are first declared or defined within -namespace scope~(\ref{basic.scope.namespace}) of the namespace -\tcode{std} and are then injected into the global namespace scope by -explicit \grammarterm{using-declaration}{s}~(\ref{namespace.udecl}). -\indextext{namespace}% - -\pnum -\enterexample -The header -\indexlibrary{\idxhdr{cstdlib}}% -\indexlibrary{\idxhdr{stdlib.h}}% -\tcode{} assuredly -provides its declarations and definitions within the namespace -\tcode{std}. It may also provide these names within the -global namespace. -The header -\tcode{} -assuredly provides the same declarations and definitions within -the global namespace, -much as in the C Standard. It may also provide these names within -the namespace \tcode{std}. -\exitexample - -\rSec1[depr.ios.members]{Old iostreams members} - -\pnum -The following member names are in addition to names specified in -Clause~\ref{input.output}: +Postfix \tcode{++} and \tcode{--} expressions\iref{expr.post.incr} and +prefix \tcode{++} and \tcode{--} expressions\iref{expr.pre.incr} +of volatile-qualified arithmetic and pointer types are deprecated. +\begin{example} \begin{codeblock} -namespace std { - class ios_base { - public: - typedef @\textit{T1}@ io_state; - typedef @\textit{T2}@ open_mode; - typedef @\textit{T3}@ seek_dir; - typedef @\impdef@ streamoff; - typedef @\impdef@ streampos; - // remainder unchanged - }; -} +volatile int velociraptor; +++velociraptor; // deprecated \end{codeblock} +\end{example} -\pnum -The type \tcode{io_state} is a synonym for an integer type -(indicated here as \tcode{T1} ) that permits certain member functions to -overload others on parameters of type \tcode{iostate} and provide the -same behavior. \pnum -The type \tcode{open_mode} is a synonym for an integer type -(indicated here as \tcode{T2} ) that permits certain member functions to -overload others on parameters of type \tcode{openmode} and provide the -same behavior. +Certain assignments +where the left operand is a volatile-qualified non-class type +are deprecated; see~\ref{expr.assign}. -\pnum -The type \tcode{seek_dir} is a synonym for an integer type -(indicated here as \tcode{T3} ) that permits certain member functions to -overload others on parameters of type \tcode{seekdir} and provide the -same behavior. +\begin{example} +\begin{codeblock} +int neck, tail; +volatile int brachiosaur; +brachiosaur = neck; // OK +tail = brachiosaur; // OK +tail = brachiosaur = neck; // deprecated +brachiosaur += neck; // OK +\end{codeblock} +\end{example} -\pnum -The type -\indexlibrary{\idxcode{streamoff}}% -\tcode{streamoff} -is an -\impldef{type of \tcode{ios_base::streamoff}} type -that satisfies the requirements of -off_type in~\ref{iostreams.limits.pos}. \pnum -The type -\tcode{streampos} -is an -\impldef{type of \tcode{ios_base::streampos}} type -that satisfies the requirements of -pos_type in~\ref{iostreams.limits.pos}. +A function type\iref{dcl.fct} +with a parameter with volatile-qualified type or +with a volatile-qualified return type is deprecated. + +\begin{example} +\begin{codeblock} +volatile struct amber jurassic(); // deprecated +void trex(volatile short left_arm, volatile short right_arm); // deprecated +void fly(volatile struct pterosaur* pteranodon); // OK +\end{codeblock} +\end{example} + \pnum -An implementation may provide the following additional member function, which has the -effect of calling -\tcode{sbumpc()}~(\ref{streambuf.pub.get}): +A structured binding\iref{dcl.struct.bind} of a volatile-qualified type +is deprecated. +\begin{example} \begin{codeblock} -namespace std { - template > - class basic_streambuf { - public: - void stossc(); - // remainder unchanged - }; +struct linhenykus { short forelimb; }; +void park(linhenykus alvarezsauroid) { + volatile auto [what_is_this] = alvarezsauroid; // deprecated + // ... } \end{codeblock} +\end{example} -\pnum -An implementation may provide the following member functions that overload signatures -specified in Clause~\ref{input.output}: +\rSec1[depr.ellipsis.comma]{Non-comma-separated ellipsis parameters} +A \grammarterm{parameter-declaration-clause} +of the form +\grammarterm{parameter-declaration-list} \tcode{...} +is deprecated\iref{dcl.fct}. +\begin{example} \begin{codeblock} -namespace std { - template class basic_ios { - public: - void clear(io_state state); - void setstate(io_state state); - void exceptions(io_state); - // remainder unchanged - }; +void f(int...); // deprecated +void g(auto...); // OK, declares a function parameter pack +void h(auto......); // deprecated +\end{codeblock} +\end{example} - class ios_base { - public: - // remainder unchanged - }; +\rSec1[depr.impldec]{Implicit declaration of copy functions} - template > - class basic_streambuf { - public: - pos_type pubseekoff(off_type off, ios_base::seek_dir way, - ios_base::open_mode which = ios_base::in | ios_base::out); - pos_type pubseekpos(pos_type sp, - ios_base::open_mode which); - // remainder unchanged - }; +\pnum +The implicit definition of a copy constructor\iref{class.copy.ctor} +as defaulted is deprecated if the class has +a user-declared copy assignment operator or +a user-declared destructor\iref{class.dtor}. +The implicit definition of a copy assignment operator\iref{class.copy.assign} +as defaulted is deprecated if the class has +a user-declared copy constructor or +a user-declared destructor. +It is possible that future versions of \Cpp{} will specify +that these implicit definitions are deleted\iref{dcl.fct.def.delete}. - template > - class basic_filebuf : public basic_streambuf { - public: - basic_filebuf* open - (const char* s, ios_base::open_mode mode); - // remainder unchanged - }; +\rSec1[depr.static.constexpr]{Redeclaration of \tcode{static constexpr} data members} - template > - class basic_ifstream : public basic_istream { - public: - void open(const char* s, ios_base::open_mode mode); - // remainder unchanged - }; +\pnum +For compatibility with prior revisions of \Cpp{}, a \keyword{constexpr} +static data member may be redundantly redeclared outside the class with no +initializer\iref{basic.def,class.static.data}. +This usage is deprecated. +\begin{example} +\begin{codeblock} +struct A { + static constexpr int n = 5; // definition (declaration in \CppXIV{}) +}; - template > - class basic_ofstream : public basic_ostream { - public: - void open(const char* s, ios_base::open_mode mode); - // remainder unchanged - }; -} +constexpr int A::n; // redundant declaration (definition in \CppXIV{}) \end{codeblock} +\end{example} + +\rSec1[depr.lit]{Literal operator function declarations using an identifier} \pnum -The effects of these functions is to call the corresponding member function specified -in Clause~\ref{input.output}. +A \grammarterm{literal-operator-id}\iref{over.literal} of the form +\begin{codeblock} +operator @\grammarterm{unevaluated-string}@ @\grammarterm{identifier}@ +\end{codeblock} +is deprecated. -\rSec1[depr.str.strstreams]{\tcode{char*} streams} +\rSec1[depr.template.template]{\tcode{template} keyword before qualified names} \pnum -The header -\tcode{} -defines three types that associate stream buffers with -character array objects and assist reading and writing such objects. +The use of the keyword \keyword{template} +before the qualified name of a class or alias template +without a template argument list is deprecated\iref{temp.names}. -\rSec2[depr.strstreambuf]{Class \tcode{strstreambuf}} +\rSec1[depr.numeric.limits.has.denorm]{\tcode{has_denorm} members in \tcode{numeric_limits}} -\indexlibrary{\idxcode{strstreambuf}}% +\pnum +The following type is defined +in addition to those specified in \libheaderref{limits}: \begin{codeblock} namespace std { - class strstreambuf : public basic_streambuf { - public: - explicit strstreambuf(streamsize alsize_arg = 0); - strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*)); - strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = 0); - strstreambuf(const char* gnext_arg, streamsize n); - - strstreambuf(signed char* gnext_arg, streamsize n, - signed char* pbeg_arg = 0); - strstreambuf(const signed char* gnext_arg, streamsize n); - strstreambuf(unsigned char* gnext_arg, streamsize n, - unsigned char* pbeg_arg = 0); - strstreambuf(const unsigned char* gnext_arg, streamsize n); - - virtual ~strstreambuf(); - - void freeze(bool freezefl = true); - char* str(); - int pcount(); - - protected: - virtual int_type overflow (int_type c = EOF); - virtual int_type pbackfail(int_type c = EOF); - virtual int_type underflow(); - virtual pos_type seekoff(off_type off, ios_base::seekdir way, - ios_base::openmode which - = ios_base::in | ios_base::out); - virtual pos_type seekpos(pos_type sp, ios_base::openmode which - = ios_base::in | ios_base::out); - virtual streambuf* setbuf(char* s, streamsize n); - - private: - typedef T1 strstate; // \expos - static const strstate allocated; // \expos - static const strstate constant; // \expos - static const strstate dynamic; // \expos - static const strstate frozen; // \expos - strstate strmode; // \expos - streamsize alsize; // \expos - void* (*palloc)(size_t); // \expos - void (*pfree)(void*); // \expos + enum @\libglobal{float_denorm_style}@ { + @\libmember{denorm_indeterminate}{float_denorm_style}@ = -1, + @\libmember{denorm_absent}{float_denorm_style}@ = 0, + @\libmember{denorm_present}{float_denorm_style}@ = 1 }; } \end{codeblock} \pnum -The class -\tcode{strstreambuf} -associates the input sequence, and possibly the output sequence, with an object of some -\textit{character} -array type, whose elements store arbitrary values. -The array object has several attributes. +\indextext{denormalized value|see{number, subnormal}}% +\indextext{value!denormalized|see{number, subnormal}}% +\indextext{subnormal number|see{number, subnormal}}% +\indextext{number!subnormal}% +The following members are defined +in addition to those specified in \ref{numeric.limits.general}: +\begin{codeblock} +static constexpr float_denorm_style has_denorm = denorm_absent; +static constexpr bool has_denorm_loss = false; +\end{codeblock} \pnum -\enternote -For the sake of exposition, these are represented as elements of a bitmask type -(indicated here as \tcode{T1}) called \tcode{strstate}. -The elements are: -\begin{itemize} -\item -\tcode{allocated}, set when a dynamic array object has been -allocated, and hence should be freed by the destructor for the -\tcode{strstreambuf} object; -\item -\tcode{constant}, set when the array object has -\tcode{const} elements, so the output sequence cannot be written; -\item -\tcode{dynamic}, set when the array object is allocated -(or reallocated) -as necessary to hold a character sequence that can change in length; -\item -\tcode{frozen}, set when the program has requested that the -array object not be altered, reallocated, or freed. -\end{itemize} -\exitnote +The values of \tcode{has_denorm} and \tcode{has_denorm_loss} of +specializations of \tcode{numeric_limits} are unspecified. \pnum -\enternote -For the sake of exposition, the maintained data is presented here as: -\begin{itemize} -\item -\tcode{strstate strmode}, the attributes of the array object -associated with the \tcode{strstreambuf} object; -\item -\tcode{int alsize}, the suggested minimum size for a -dynamic array object; -\item -\tcode{void* (*palloc)(size_t)}, points to the function -to call to allocate a dynamic array object; -\item -\tcode{void (*pfree)(void*)}, points to the function to -call to free a dynamic array object. -\end{itemize} -\exitnote +The following members of the specialization \tcode{numeric_limits} are defined +in addition to those specified in \ref{numeric.special}: +\indexlibrarymember{float_denorm_style}{numeric_limits}% +\indexlibrarymember{has_denorm_loss}{numeric_limits}% +\begin{codeblock} +static constexpr float_denorm_style has_denorm = denorm_absent; +static constexpr bool has_denorm_loss = false; +\end{codeblock} + +\rSec1[depr.c.macros]{Deprecated C macros} \pnum -Each object of class -\tcode{strstreambuf} -has a -\term{seekable area}, -delimited by the pointers \tcode{seeklow} and \tcode{seekhigh}. -If \tcode{gnext} is a null pointer, the seekable area is undefined. -Otherwise, \tcode{seeklow} equals \tcode{gbeg} and -\tcode{seekhigh} is either \tcode{pend}, -if \tcode{pend} is not a null pointer, or \tcode{gend}. +The header \libheaderref{cfloat} has the following macros: +\begin{codeblock} +#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}. -\rSec3[depr.strstreambuf.cons]{\tcode{strstreambuf} constructors} +\xrefc{5.3.5.3.3, 7.33.6} -\indexlibrary{\idxcode{strstreambuf}!\tcode{strstreambuf}}% -\begin{itemdecl} -explicit strstreambuf(streamsize alsize_arg = 0); -\end{itemdecl} +\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} -\begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{strstreambuf}, -initializing the base class with -\tcode{streambuf()}. -The postconditions of this function are indicated in Table~\ref{tab:future.strstreambuf.effects}. -\end{itemdescr} +The header \libheaderref{stdbool.h} has the following macro: +\begin{codeblock} +#define @\libxmacro{bool_true_false_are_defined}@ 1 +\end{codeblock} -\begin{libtab2}{\tcode{strstreambuf(streamsize)} effects}{tab:future.strstreambuf.effects} -{ll} -{Element}{Value} -\tcode{strmode} & \tcode{dynamic} \\ -\tcode{alsize} & \tcode{alsize_arg} \\ -\tcode{palloc} & a null pointer \\ -\tcode{pfree} & a null pointer \\ -\end{libtab2} +\xrefc{7.19} -\indexlibrary{\idxcode{strstreambuf}}% -\begin{itemdecl} -strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*)); -\end{itemdecl} +\rSec1[depr.cerrno]{Deprecated error numbers} -\begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{strstreambuf}, -initializing the base class with -\tcode{streambuf()}. -The postconditions of this function are indicated in Table~\ref{tab:future.strstreambuf1.effects}. - -\begin{libtab2}{\tcode{strstreambuf(void* (*)(size_t), void (*)(void*))} effects} -{tab:future.strstreambuf1.effects} -{ll} -{Element}{Value} -\tcode{strmode} & \tcode{dynamic} \\ -\tcode{alsize} & an unspecified value \\ -\tcode{palloc} & \tcode{palloc_arg} \\ -\tcode{pfree} & \tcode{pfree_arg} \\ -\end{libtab2} -\end{itemdescr} +The header \libheaderref{cerrno} has the following additional macros: -\indextext{unspecified}% -\begin{itemdecl} -strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = 0); -strstreambuf(signed char* gnext_arg, streamsize n, - signed char* pbeg_arg = 0); -strstreambuf(unsigned char* gnext_arg, streamsize n, - unsigned char* pbeg_arg = 0); -\end{itemdecl} +\begin{codeblock} +#define @\libmacro{ENODATA}@ @\seebelow@ +#define @\libmacro{ENOSR}@ @\seebelow@ +#define @\libmacro{ENOSTR}@ @\seebelow@ +#define @\libmacro{ETIME}@ @\seebelow@ +\end{codeblock} -\begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{strstreambuf}, -initializing the base class with -\tcode{streambuf()}. -The postconditions of this function are indicated in Table~\ref{tab:future.strstreambuf2.effects}. - -\begin{libtab2}{\tcode{strstreambuf(charT*, streamsize, charT*)} effects} -{tab:future.strstreambuf2.effects} -{ll} -{Element}{Value} -\tcode{strmode} & 0 \\ -\tcode{alsize} & an unspecified value \\ -\tcode{palloc} & a null pointer \\ -\tcode{pfree} & a null pointer \\ -\end{libtab2} - -\pnum -\tcode{gnext_arg} shall point to the first element of an array -object whose number of elements \tcode{N} is determined as follows: -\begin{itemize} -\item -If -\tcode{n > 0}, -\tcode{N} is \tcode{n}. -\item -If -\tcode{n == 0}, -\tcode{N} is -\tcode{std::strlen(gnext_arg)}. -\indexlibrary{\idxcode{strlen}}% -\item -If -\tcode{n < 0}, -\tcode{N} is -\tcode{INT_MAX}.\footnote{The function signature -\tcode{strlen(const char*)} -is declared in -\tcode{}. -\indexlibrary{\idxcode{strlen}}% -\indexlibrary{\idxhdr{cstring}}% -(\ref{c.strings}). -The macro -\tcode{INT_MAX} -is defined in -\tcode{}~(\ref{support.limits}). -\indexlibrary{\idxhdr{climits}}} -\end{itemize} +The meaning of these macros is defined by the POSIX standard. \pnum -If \tcode{pbeg_arg} is a null pointer, the function executes: +The following \tcode{enum errc} enumerators are defined +in addition to those specified in \ref{system.error.syn}: -\indexlibrary{\idxcode{strstreambuf}!\idxcode{setg}}% -\indexlibrary{\idxcode{setg}!\idxcode{strstreambuf}}% -\begin{itemdecl} -setg(gnext_arg, gnext_arg, gnext_arg + N); -\end{itemdecl} +\begin{codeblock} +@\libmember{no_message_available}{errc}@, // \tcode{ENODATA} +@\libmember{no_stream_resources}{errc}@, // \tcode{ENOSR} +@\libmember{not_a_stream}{errc}@, // \tcode{ENOSTR} +@\libmember{stream_timeout}{errc}@, // \tcode{ETIME} +\end{codeblock} \pnum -Otherwise, the function executes: +The value of each \tcode{enum errc} enumerator above +is the same as the value of the \libheader{cerrno} macro +shown in the above synopsis. -\begin{codeblock} -setg(gnext_arg, gnext_arg, pbeg_arg); -setp(pbeg_arg, pbeg_arg + N); +\rSec1[depr.meta.types]{Deprecated type traits} + +\pnum +The header \libheaderrefx{type_traits}{meta.type.synop} +has the following addition: -strstreambuf(const char* gnext_arg, streamsize n); -strstreambuf(const signed char* gnext_arg, streamsize n); -strstreambuf(const unsigned char* gnext_arg, streamsize n); +\begin{codeblock} +namespace std { + template struct is_trivial; + template constexpr bool is_trivial_v = is_trivial::value; + template struct is_pod; + template constexpr bool is_pod_v = is_pod::value; + template // \seebelow + struct aligned_storage; + template // \seebelow + using @\libglobal{aligned_storage_t}@ = aligned_storage::type; + template + struct aligned_union; + template + using @\libglobal{aligned_union_t}@ = aligned_union::type; +} \end{codeblock} \pnum -\effects -Behaves the same as -\tcode{strstreambuf((char*)gnext_arg,n)}, -except that the constructor also sets \tcode{constant} in \tcode{strmode}. -\end{itemdescr} +The behavior of a program that adds specializations for +any of the templates defined in this subclause is undefined, +unless explicitly permitted by the specification of the corresponding template. -\indexlibrary{\idxcode{strstreambuf}!destructor}% -\begin{itemdecl} -virtual ~strstreambuf(); -\end{itemdecl} - -\begin{itemdescr} \pnum -\effects -Destroys an object of class -\tcode{strstreambuf}. -The function frees the dynamically allocated array object only if -\tcode{strmode \& allocated != 0} -and -\tcode{strmode \& frozen == 0}.~(\ref{depr.strstreambuf.virtuals} describes how a dynamically allocated array object is freed.) -\end{itemdescr} +\label{term.trivial.type}% +A \defnadj{trivial}{class} is a class that is trivially copyable and +has one or more eligible default constructors, all of which are trivial. +\begin{note} +In particular, +a trivial class does not have virtual functions or virtual base classes. +\end{note} +A \defnadj{trivial}{type} is a scalar type, a trivial class, +an array of such a type, or a cv-qualified version of one of these types. -\rSec3[depr.strstreambuf.members]{Member functions} +\pnum +\indextext{POD}% +A \term{POD class} is a class that is both a trivial class and a +standard-layout class, and has no non-static data members of type non-POD class +(or array thereof). A \term{POD type} is a scalar type, a POD class, an array +of such a type, or a cv-qualified version of one of these types. -\indexlibrary{\idxcode{freeze}!\idxcode{strstreambuf}}% +\indexlibraryglobal{is_trivial}% \begin{itemdecl} -void freeze(bool freezefl = true); +template struct is_trivial; \end{itemdecl} \begin{itemdescr} \pnum -\effects -If \tcode{strmode} \& \tcode{dynamic} is non-zero, alters the -freeze status of the dynamic array object as follows: -\begin{itemize} -\item -If \tcode{freezefl} is -\tcode{true}, -the function sets \tcode{frozen} in \tcode{strmode}. -\item -Otherwise, it clears \tcode{frozen} in \tcode{strmode}. -\end{itemize} +\expects +\tcode{remove_all_extents_t} shall be a complete type or \cv{} \keyword{void}. + +\pnum +\remarks +\tcode{is_trivial} is a \oldconcept{UnaryTypeTrait}\iref{meta.rqmts} +with a base characteristic of \tcode{true_type} +if \tcode{T} is a trivial type, +and \tcode{false_type} otherwise. + +\pnum +\begin{note} +It is unspecified +whether a closure type\iref{expr.prim.lambda.closure} is a trivial type. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{str}!\idxcode{strstreambuf}}% +\indexlibraryglobal{is_pod}% \begin{itemdecl} -char* str(); +template struct is_pod; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Calls -\tcode{freeze()}, -then returns the beginning pointer for the input sequence, \tcode{gbeg}. +\expects +\tcode{remove_all_extents_t} shall be a complete type or \cv{} \keyword{void}. \pnum -\notes -The return value can be a null pointer. +\remarks +\tcode{is_pod} is a \oldconcept{UnaryTypeTrait}\iref{meta.rqmts} +with a base characteristic of \tcode{true_type} +if \tcode{T} is a POD type, +and \tcode{false_type} otherwise. + +\pnum +\begin{note} +It is unspecified whether a closure type\iref{expr.prim.lambda.closure} is a POD type. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{pcount}!\idxcode{strstreambuf}}% +\indexlibraryglobal{aligned_storage}% \begin{itemdecl} -int pcount() const; +template + struct aligned_storage; \end{itemdecl} \begin{itemdescr} \pnum -\effects -If the next pointer for the output sequence, \tcode{pnext}, is -a null pointer, returns zero. -Otherwise, returns the current -effective length of the array object as the next pointer minus the beginning -pointer for the output sequence, \tcode{pnext} - \tcode{pbeg}. -\end{itemdescr} +The value of \exposid{default-alignment} is the most +stringent alignment requirement for any object type whose size +is no greater than \tcode{Len}\iref{basic.types}. -\rSec3[depr.strstreambuf.virtuals]{\tcode{strstreambuf} overridden virtual functions} +\pnum +\mandates +\tcode{Len} is not zero. +\tcode{Align} is equal to \tcode{alignof(T)} for some type \tcode{T} or +to \exposid{default-alignment}. -\indexlibrary{\idxcode{overflow}!\idxcode{strstreambuf}}% -\begin{itemdecl} -int_type overflow(int_type c = EOF); -\end{itemdecl} +\pnum +The member typedef \tcode{type} denotes a trivial standard-layout type +suitable for use as uninitialized storage for any object +whose size is at most \tcode{Len} and +whose alignment is a divisor of \tcode{Align}. -\begin{itemdescr} \pnum -\effects -Appends the character designated by \tcode{c} to the output -sequence, if possible, in one of two ways: -\begin{itemize} -\item -If -\tcode{c != EOF} -and if either the output sequence has a write position available or -the function makes a write position available -(as described below), -assigns \tcode{c} to -\tcode{*pnext++}. - -Returns -\tcode{(unsigned char)c}. - -\item -If -\tcode{c == EOF}, -there is no character to append. - -Returns a value other than \tcode{EOF}. -\end{itemize} +\begin{note} +Uses of \tcode{aligned_storage::type} can be replaced +by an array \tcode{std::byte[Len]} declared with \tcode{alignas(Align)}. +\end{note} \pnum -Returns -\tcode{EOF} -to indicate failure. - -\pnum -\notes -The function can alter the number of write positions available as a -result of any call. - -\pnum -To make a write position available, the function reallocates -(or initially allocates) -an array object with a sufficient number of elements -\tcode{n} to hold the current array object (if any), -plus at least one additional write position. -How many additional write positions are made -available is otherwise unspecified.% -\indextext{unspecified}% -\footnote{An implementation should consider \tcode{alsize} in making this -decision.} -If \tcode{palloc} is not a null pointer, the function calls -\tcode{(*palloc)(n)} -to allocate the new dynamic array object. -Otherwise, it evaluates the expression -\tcode{new charT[n]}. -In either case, if the allocation fails, the function returns -\tcode{EOF}. -Otherwise, it sets \tcode{allocated} in \tcode{strmode}. - -\pnum -To free a previously existing dynamic array object whose first -element address is \tcode{p}: -If \tcode{pfree} is not a null pointer, -the function calls -\tcode{(*pfree)(p)}. -Otherwise, it evaluates the expression \tcode{delete[]p}. - -\pnum -If -\tcode{strmode \& dynamic == 0}, -or if -\tcode{strmode \& frozen != 0}, -the function cannot extend the array (reallocate it with greater length) to make a write position available. +\begin{note} +A typical implementation would define \tcode{aligned_storage} as: +\begin{codeblock} +template +struct aligned_storage { + typedef struct { + alignas(Alignment) unsigned char __data[Len]; + } type; +}; +\end{codeblock} +\end{note} + \end{itemdescr} -\indexlibrary{\idxcode{pbackfail}!\idxcode{strstreambuf}}% +\indexlibraryglobal{aligned_union}% \begin{itemdecl} -int_type pbackfail(int_type c = EOF); +template + struct aligned_union; \end{itemdecl} \begin{itemdescr} \pnum -Puts back the character designated by \tcode{c} to the input -sequence, if possible, in one of three ways: -\begin{itemize} -\item -If -\tcode{c != EOF}, -if the input sequence has a putback position available, and if -\tcode{(char)c == gnext[-1]}, -assigns -\tcode{gnext - 1} -to \tcode{gnext}. - -Returns \tcode{c}. -\item -If -\tcode{c != EOF}, -if the input sequence has a putback position available, and if -\tcode{strmode} \& \tcode{constant} is zero, -assigns \tcode{c} to -\tcode{*\dcr{}gnext}. - -Returns -\tcode{c}. -\item -If -\tcode{c == EOF} -and if the input sequence has a putback position available, -assigns -\tcode{gnext - 1} -to \tcode{gnext}. - -Returns a value other than -\tcode{EOF}. -\end{itemize} +\mandates +At least one type is provided. +Each type in the template parameter pack \tcode{Types} +is a complete object type. \pnum -Returns -\tcode{EOF} -to indicate failure. +The member typedef \tcode{type} denotes a trivial standard-layout type +suitable for use as uninitialized storage for any object +whose type is listed in \tcode{Types}; +its size shall be at least \tcode{Len}. +The static member \tcode{alignment_value} +is an integral constant of type \tcode{size_t} +whose value is the strictest alignment of all types listed in \tcode{Types}. +\end{itemdescr} + +\rSec1[depr.relops]{Relational operators}% +\indexlibraryglobal{rel_ops}% \pnum -\notes -If the function can succeed in more than one of these ways, it is -unspecified which way is chosen. -\indextext{unspecified}% -The function can alter the number of putback -positions available as a result of any call. -\end{itemdescr} +The header \libheaderref{utility} has the following additions: -\indexlibrary{\idxcode{underflow}!\idxcode{strstreambuf}}% +\begin{codeblock} +namespace std::rel_ops { + template bool operator!=(const T&, const T&); + template bool operator> (const T&, const T&); + template bool operator<=(const T&, const T&); + template bool operator>=(const T&, const T&); +} +\end{codeblock} + +\pnum +To avoid redundant definitions of \tcode{operator!=} out of \tcode{operator==} +and operators \tcode{>}, \tcode{<=}, and \tcode{>=} out of \tcode{operator<}, +the library provides the following: + +\indexlibrary{\idxcode{operator"!=}}% \begin{itemdecl} -int_type underflow(); +template bool operator!=(const T& x, const T& y); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Reads a character from the -\term{input sequence}, -if possible, without moving the stream position past it, as follows: -\begin{itemize} -\item -If the input sequence has a read position available, the function -signals success by returning -\tcode{(unsigned char)\brk*gnext}. -\item -Otherwise, if -the current write next pointer \tcode{pnext} is not a null pointer and -is greater than the current read end pointer \tcode{gend}, -makes a -\term{read position} -available by -assigning to \tcode{gend} a value greater than \tcode{gnext} and -no greater than \tcode{pnext}. - -Returns \tcode{(unsigned char*)gnext}. -\end{itemize} - -\pnum -Returns -\tcode{EOF} -to indicate failure. +\expects +\tcode{T} meets the \oldconcept{EqualityComparable} requirements (\tref{cpp17.equalitycomparable}). \pnum -\notes -The function can alter the number of read positions available as a -result of any call. +\returns +\tcode{!(x == y)}. \end{itemdescr} -\indexlibrary{\idxcode{seekoff}!\idxcode{strstreambuf}}% +\indexlibraryglobal{operator>}% \begin{itemdecl} -pos_type seekoff(off_type off, seekdir way, openmode which = in | out); +template bool operator>(const T& x, const T& y); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Alters the stream position within one of the -controlled sequences, if possible, as indicated in Table~\ref{tab:future.seekoff.positioning}. - -\begin{libtab2}{\tcode{seekoff} positioning}{tab:future.seekoff.positioning} -{p{2.5in}l}{Conditions}{Result} -\tcode{(which \& ios::in) != 0} & - positions the input sequence \\ \rowsep -\tcode{(which \& ios::out) != 0} & - positions the output sequence \\ \rowsep -\tcode{(which \& (ios::in |}\br -\tcode{ios::out)) == (ios::in |}\br -\tcode{ios::out))} and\br -\tcode{way ==} either\br -\tcode{ios::beg} or\br -\tcode{ios::end} & - positions both the input and the output sequences \\ \rowsep -Otherwise & - the positioning operation fails. \\ -\end{libtab2} - -\pnum -For a sequence to be positioned, if its next pointer is a null pointer, -the positioning operation fails. -Otherwise, the function determines \tcode{newoff} as indicated in -Table~\ref{tab:future.newoff.values}. - -\begin{libtab2}{\tcode{newoff} values}{tab:future.newoff.values} -{p{2.0in}p{2.0in}}{Condition}{\tcode{newoff} Value} -\tcode{way == ios::beg} & - 0 \\ \rowsep -\tcode{way == ios::cur} & - the next pointer minus the beginning pointer (\tcode{xnext - xbeg}). \\ \rowsep -\tcode{way == ios::end} & - \tcode{seekhigh} minus the beginning pointer (\tcode{seekhigh - xbeg}). \\ -\end{libtab2} - -\pnum -If \tcode{(newoff + off) < (seeklow - xbeg)} -or \tcode{(seekhigh - xbeg) < (newoff + off)}, -the positioning operation fails. -Otherwise, the function assigns -\tcode{xbeg + newoff + off} -to the next pointer \tcode{xnext}. +\expects +\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). \pnum \returns -\tcode{pos_type(newoff)}, -constructed from the resultant offset -\tcode{newoff} (of type -\tcode{off_type}), -that stores the resultant stream position, if possible. -If the positioning operation fails, or -if the constructed object cannot represent the resultant stream position, -the return value is -\tcode{pos_type(off_type(-1))}. +\tcode{y < x}. \end{itemdescr} -\indexlibrary{\idxcode{seekpos}!\idxcode{strstreambuf}}% +\indexlibrary{\idxcode{operator<=}}% \begin{itemdecl} -pos_type seekpos(pos_type sp, ios_base::openmode which - = ios_base::in | ios_base::out); +template bool operator<=(const T& x, const T& y); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Alters the stream position within one of the -controlled sequences, if possible, to correspond to the -stream position stored in \tcode{sp} -(as described below). -\begin{itemize} -\item -If -\tcode{(which \& ios::in) != 0}, -positions the input sequence. -\item -If -\tcode{(which \& ios::out) != 0}, -positions the output sequence. -\item -If the function positions neither sequence, the positioning operation fails. -\end{itemize} - -\pnum -For a sequence to be positioned, if its next pointer is a null pointer, -the positioning operation fails. -Otherwise, the function determines \tcode{newoff} from -\tcode{sp.offset()}: -\begin{itemize} -\item -If \tcode{newoff} is an invalid stream position, -has a negative value, or -has a value greater than (\tcode{seekhigh} - \tcode{seeklow}), -the positioning operation fails -\item -Otherwise, the function -adds \tcode{newoff} to the beginning pointer \tcode{xbeg} and -stores the result in the next pointer \tcode{xnext}. -\end{itemize} +\expects +\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). \pnum \returns -\tcode{pos_type(newoff)}, -constructed from the resultant offset \tcode{newoff} -(of type -\tcode{off_type}), -that stores the resultant stream position, if possible. -If the positioning operation fails, or -if the constructed object cannot represent the resultant stream position, -the return value is -\tcode{pos_type(off_type(-1))}. +\tcode{!(y < x)}. \end{itemdescr} -\indexlibrary{\idxcode{setbuf}!\idxcode{strstreambuf}}% +\indexlibrary{\idxcode{operator>=}}% \begin{itemdecl} -streambuf* setbuf(char* s, streamsize n); +template bool operator>=(const T& x, const T& y); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Implementation defined, except that -\tcode{setbuf(0, 0)} -has no effect.% -\indexlibrary{\idxcode{setbuf}!\idxcode{streambuf}} +\expects +\tcode{T} meets the \oldconcept{LessThanComparable} requirements (\tref{cpp17.lessthancomparable}). + +\pnum +\returns +\tcode{!(x < y)}. \end{itemdescr} -\rSec2[depr.istrstream]{Class \tcode{istrstream}} +\rSec1[depr.tuple]{Tuple} + +\pnum +The header \libheaderref{tuple} has the following additions: -\indexlibrary{\idxcode{istrstream}}% \begin{codeblock} namespace std { - class istrstream : public basic_istream { - public: - explicit istrstream(const char* s); - explicit istrstream(char* s); - istrstream(const char* s, streamsize n); - istrstream(char* s, streamsize n); - virtual ~istrstream(); - - strstreambuf* rdbuf() const; - char* str(); - private: - strstreambuf sb; // \expos - }; + template struct tuple_size; + template struct tuple_size; + + template struct tuple_element; + template struct tuple_element; } \end{codeblock} -\pnum -The class -\tcode{istrstream} -supports the reading of objects of class -\tcode{strstreambuf}. -It supplies a -\tcode{strstreambuf} -object to control the associated array object. -For the sake of exposition, the maintained data is presented here as: - -\begin{itemize} -\item -\tcode{sb}, the \tcode{strstreambuf} object. -\end{itemize} - -\rSec3[depr.istrstream.cons]{\tcode{istrstream} constructors} - -\indexlibrary{\idxcode{istrstream}!\idxcode{istrstream}}% \begin{itemdecl} -explicit istrstream(const char* s); -explicit istrstream(char* s); +template struct tuple_size; +template struct tuple_size; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{istrstream}, -initializing the base class with -\tcode{istream(\&sb)} -and initializing \tcode{sb} with -\tcode{strstreambuf(s,0))}. -\tcode{s} shall designate the first element of an \ntbs.% -\indextext{NTBS} +Let \tcode{TS} denote \tcode{tuple_size} of the cv-unqualified type \tcode{T}. +If the expression \tcode{TS::value} is well-formed +when treated as an unevaluated operand\iref{term.unevaluated.operand}, +then specializations of each of the two templates meet +the \oldconcept{TransformationTrait} requirements with a base characteristic of +\tcode{integral_constant}. +Otherwise, they have no member \tcode{value}. + +\pnum +Access checking is performed as if +in a context unrelated to \tcode{TS} and \tcode{T}. +Only the validity of the immediate context of the expression is considered. + +\pnum +In addition to being available via inclusion of the \libheaderref{tuple} header, +the two templates are available when any of the headers +\libheaderref{array}, +\libheaderref{ranges}, or +\libheaderref{utility} +are included. \end{itemdescr} -\indexlibrary{\idxcode{istrstream}!constructor}% \begin{itemdecl} -istrstream(const char* s, streamsize n); +template struct tuple_element; +template struct tuple_element; \end{itemdecl} \begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{istrstream}, -initializing the base class with -\tcode{istream(\&sb)} -and initializing \tcode{sb} with -\tcode{strstreambuf(s,n))}. -\tcode{s} shall designate the first element of an array whose length is -\tcode{n} elements, and \tcode{n} shall be greater than zero. +Let \tcode{TE} denote \tcode{tuple_element_t} +of the cv-unqualified type \tcode{T}. +Then specializations of each of the two templates meet +the \oldconcept{TransformationTrait} requirements +with a member typedef \tcode{type} that names the following type: +\begin{itemize} +\item for the first specialization, \tcode{volatile TE}, and +\item for the second specialization, \tcode{const volatile TE}. +\end{itemize} + +\pnum +In addition to being available via inclusion of the \libheaderref{tuple} header, +the two templates are available when any of the headers +\libheaderref{array}, +\libheaderref{ranges}, or +\libheaderref{utility} +are included. \end{itemdescr} -\rSec3[depr.istrstream.members]{Member functions} +\rSec1[depr.variant]{Variant} + +\pnum +The header \libheaderref{variant} has the following additions: + +\begin{codeblock} +namespace std { + template struct variant_size; + template struct variant_size; + + template struct variant_alternative; + template struct variant_alternative; +} +\end{codeblock} -\indexlibrary{\idxcode{rdbuf}!\idxcode{istrstream}}% \begin{itemdecl} -strstreambuf* rdbuf() const; +template struct variant_size; +template struct variant_size; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{const_cast(\&sb)}. +Let \tcode{VS} denote \tcode{variant_size} +of the cv-unqualified type \tcode{T}. +Then specializations of each of the two templates meet +the \oldconcept{UnaryTypeTrait} requirements +with a base characteristic of \tcode{integral_constant}. \end{itemdescr} -\indexlibrary{\idxcode{str}!\idxcode{istrstream}}% \begin{itemdecl} -char* str(); +template struct variant_alternative; +template struct variant_alternative; \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{rdbuf()->str()}. +Let \tcode{VA} denote \tcode{variant_alternative} +of the cv-unqualified type \tcode{T}. +Then specializations of each of the two templates meet +the \oldconcept{TransformationTrait} requirements +with a member typedef \tcode{type} that names the following type: +\begin{itemize} +\item for the first specialization, \tcode{volatile VA::type}, and +\item for the second specialization, \tcode{const volatile VA::type}. +\end{itemize} \end{itemdescr} -\rSec2[depr.ostrstream]{Class \tcode{ostrstream}} +\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}: -\indexlibrary{\idxcode{ostrstream}}% \begin{codeblock} namespace std { - class ostrstream : public basic_ostream { + template class vector { public: - ostrstream(); - ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out); - virtual ~ostrstream(); - - strstreambuf* rdbuf() const; - void freeze(bool freezefl = true); - char* str(); - int pcount() const; - private: - strstreambuf sb; // \expos + static constexpr void swap(reference x, reference y) noexcept; }; } \end{codeblock} -\pnum -The class -\tcode{ostrstream} -supports the writing of objects of class -\tcode{strstreambuf}. -It supplies a -\tcode{strstreambuf} -object to control the associated array object. -For the sake of exposition, the maintained data is presented here as: - -\begin{itemize} -\item -\tcode{sb}, the \tcode{strstreambuf} object. -\end{itemize} - -\rSec3[depr.ostrstream.cons]{\tcode{ostrstream} constructors} - -\indexlibrary{\idxcode{ostrstream}!\idxcode{ostrstream}}% +\indexlibrarymember{swap}{vector}% \begin{itemdecl} - ostrstream(); +static constexpr void swap(reference x, reference y) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Constructs an object of class -\tcode{ostrstream}, -initializing the base class with -\tcode{ostream(\&sb)} -and initializing \tcode{sb} with -\tcode{strstreambuf())}. +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} -\indexlibrary{\idxcode{ostrstream}!constructor}% -\begin{itemdecl} -ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out); -\end{itemdecl} +\rSec1[depr.iterator]{Deprecated \tcode{iterator} class template} -\begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{ostrstream}, -initializing the base class with -\tcode{ostream(\&sb)}, -and initializing \tcode{sb} with one of two constructors: +The header \libheaderrefx{iterator}{iterator.synopsis} has the following addition: -\begin{itemize} -\item -If -\tcode{(mode \& app) == 0}, -then \tcode{s} shall designate the first element of an array of \tcode{n} elements. - -The constructor is -\tcode{strstreambuf(s, n, s)}. -\item -If -\tcode{(mode \& app) != 0}, -then \tcode{s} shall designate the first element of an array of \tcode{n} elements that -contains an \ntbs whose first element is designated by \tcode{s}. -\indextext{NTBS}% -The constructor is -\tcode{strstreambuf(s, n, s + std::strlen(s))}.\footnote{The function signature -\tcode{strlen(const char*)} -is declared in -\tcode{} -\indexlibrary{\idxcode{strlen}}% -\indexlibrary{\idxhdr{cstring}}% -(\ref{c.strings}).} -\end{itemize} -\end{itemdescr} +\indexlibraryglobal{iterator}% +\begin{codeblock} +namespace std { + template + struct iterator { + using iterator_category = Category; + using value_type = T; + using difference_type = Distance; + using pointer = Pointer; + using reference = Reference; + }; +} +\end{codeblock} -\rSec3[depr.ostrstream.members]{Member functions} +\pnum +The +\tcode{iterator} +template may be used as a base class to ease the definition of required types +for new iterators. -\indexlibrary{\idxcode{rdbuf}!\idxcode{ostrstream}}% -\begin{itemdecl} -strstreambuf* rdbuf() const; -\end{itemdecl} +\pnum +\begin{note} +If the new iterator type is a class template, then these aliases +will not be visible from within the iterator class's template definition, but +only to callers of that class. +\end{note} -\begin{itemdescr} \pnum -\returns -\tcode{(strstreambuf*)\&sb }. -\end{itemdescr} +\begin{example} +If a \Cpp{} program wants to define a bidirectional iterator for some data +structure containing \tcode{double} and such that it works on a large memory +model of the implementation, it can do so with: -\indexlibrary{\idxcode{freeze}!\idxcode{ostrstream}}% -\begin{itemdecl} -void freeze(bool freezefl = true); -\end{itemdecl} +\begin{codeblock} +class MyIterator : + public iterator { + // code implementing \tcode{++}, etc. +}; +\end{codeblock} +\end{example} + +\rSec1[depr.move.iter.elem]{Deprecated \tcode{move_iterator} access} -\begin{itemdescr} \pnum -\effects -Calls -\tcode{rdbuf()->freeze(freezefl)}. -\end{itemdescr} +The following member is declared in addition to those members +specified in \ref{move.iter.elem}: -\indexlibrary{\idxcode{str}!\idxcode{ostrstream}}% +\begin{codeblock} +namespace std { + template + class move_iterator { + public: + constexpr pointer operator->() const; + }; +} +\end{codeblock} + +\indexlibrarymember{operator->}{move_iterator}% \begin{itemdecl} -char* str(); +constexpr pointer operator->() const; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{rdbuf()->str()}. +\tcode{current}. \end{itemdescr} -\indexlibrary{\idxcode{pcount}!\idxcode{ostrstream}}% -\begin{itemdecl} -int pcount() const; -\end{itemdecl} +\rSec1[depr.locale.category]{Deprecated locale category facets} -\begin{itemdescr} \pnum -\returns -\tcode{rdbuf()->pcount()}. -\end{itemdescr} +The \tcode{ctype} locale category includes the following facets +as if they were specified +in \tref{locale.category.facets} of \ref{locale.category}. + +\begin{codeblock} +codecvt +codecvt +codecvt +codecvt +\end{codeblock} -\rSec2[depr.strstream]{Class \tcode{strstream}} +\pnum +The \tcode{ctype} locale category includes the following facets +as if they were specified +in \tref{locale.spec} of \ref{locale.category}. -\indexlibrary{\idxcode{strstream}}% \begin{codeblock} -namespace std { - class strstream - : public basic_iostream { - public: - // Types - typedef char char_type; - typedef typename char_traits::int_type int_type; - typedef typename char_traits::pos_type pos_type; - typedef typename char_traits::off_type off_type; - - // constructors/destructor - strstream(); - strstream(char* s, int n, - ios_base::openmode mode = ios_base::in|ios_base::out); - virtual ~strstream(); - - // Members: - strstreambuf* rdbuf() const; - void freeze(bool freezefl = true); - int pcount() const; - char* str(); - - private: - strstreambuf sb; // \expos - }; -} +codecvt_byname +codecvt_byname +codecvt_byname +codecvt_byname \end{codeblock} \pnum -The class -\tcode{strstream} -supports reading and writing from objects of class -\tcode{strstreambuf}. -It supplies a -\tcode{strstreambuf} -object to control the associated array object. -For the sake of exposition, the maintained data is presented here as: +The following class template specializations are required +in addition to those specified in~\ref{locale.codecvt}. +\indextext{UTF-8}% +\indextext{UTF-16}% +The specializations \tcode{codecvt} and +\tcode{codecvt} +convert between the UTF-16 and UTF-8 encoding forms, and +\indextext{UTF-32}% +the specializations \tcode{codecvt} and +\tcode{codecvt} +convert between the UTF-32 and UTF-8 encoding forms. -\begin{itemize} -\item -\tcode{sb}, the \tcode{strstreambuf} object. -\end{itemize} +\rSec1[depr.format]{Deprecated formatting} -\rSec3[depr.strstream.cons]{\tcode{strstream} constructors} +\rSec2[depr.format.syn]{Header \tcode{} synopsis} + +\pnum +The header \libheaderref{format} has the following additions: -\indexlibrary{\idxcode{strstream}!\idxcode{strstream}}% +\begin{codeblock} +namespace std { + template + decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg arg); +} +\end{codeblock} + +\rSec2[depr.format.arg]{Formatting arguments} + +\indexlibraryglobal{visit_format_arg}% \begin{itemdecl} -strstream(); +template + decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg arg); \end{itemdecl} \begin{itemdescr} \pnum \effects -Constructs an object of class -\tcode{strstream}, -initializing the base class with -\tcode{iostream(\&sb)}. +Equivalent to: \tcode{return visit(std::forward(vis), arg.\exposid{value_});} \end{itemdescr} -\indexlibrary{\idxcode{strstream}!\idxcode{strstream}}% -\begin{itemdecl} -strstream(char* s, int n, - ios_base::openmode mode = ios_base::in|ios_base::out); -\end{itemdecl} +\rSec1[depr.ctime]{Deprecated time formatting} -\begin{itemdescr} \pnum -\effects -Constructs an object of class -\tcode{strstream}, -initializing the base class with -\tcode{iostream(\&sb)} -and initializing \tcode{sb} with one of the two constructors: -\begin{itemize} -\item -If -\tcode{(mode \& app) == 0}, -then \tcode{s} shall designate the first element of an array of \tcode{n} elements. -The constructor is -\tcode{strstreambuf(s,n,s)}. -\item -If -\tcode{(mode \& app) != 0}, -then \tcode{s} shall -designate the first element of an array of \tcode{n} elements that contains -an \ntbs whose first element is designated by \tcode{s}. -The constructor is -\tcode{strstreambuf(s,n,s + std::strlen(s))}. -\indexlibrary{\idxcode{strstream}!destructor}% -\end{itemize} -\end{itemdescr} +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}. -\rSec3[depr.strstream.dest]{\tcode{strstream} destructor} +\xrefc{7.29} -\indexlibrary{\idxcode{strstream}!destructor}% -\begin{itemdecl} -virtual ~strstream(); -\end{itemdecl} +\rSec1[depr.filesystems]{Deprecated file systems} + +\rSec2[depr.fs.path.factory]{Deprecated filesystem path factory functions} -\begin{itemdescr} \pnum -\effects -Destroys an object of class -\tcode{strstream}. -\end{itemdescr} +The header \libheaderrefx{filesystem}{fs.filesystem.syn} has the following additions: -\indexlibrary{\idxcode{rdbuf}!\idxcode{strstream}}% +\indexlibraryglobal{u8path}% \begin{itemdecl} -strstreambuf* rdbuf() const; +template + path u8path(const Source& source); +template + path u8path(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum -\returns -\tcode{\&sb}. -\end{itemdescr} +\mandates +The value type of \tcode{Source} and \tcode{InputIterator} is +\tcode{char} or \keyword{char8_t}. -\rSec3[depr.strstream.oper]{\tcode{strstream} operations} +\pnum +\expects +The \tcode{source} and \range{first}{last} sequences are UTF-8 encoded. +\tcode{Source} meets the requirements specified in \ref{fs.path.req}. -\indexlibrary{\idxcode{freeze}!\idxcode{strstream}}% -\begin{itemdecl} -void freeze(bool freezefl = true); -\end{itemdecl} +\pnum +\returns +\begin{itemize} +\item If \tcode{path::value_type} is \tcode{char} and the current native + narrow encoding\iref{fs.path.type.cvt} is UTF-8, + return \tcode{path(source)} or \tcode{path(first, last)}; + otherwise, +\item if \tcode{path::value_type} is \keyword{wchar_t} and the + native wide encoding is UTF-16, or + if \tcode{path::value_type} is \keyword{char16_t} or \keyword{char32_t}, + convert \tcode{source} or \range{first}{last} + to a temporary, \tcode{tmp}, of type \tcode{path::string_type} and + return \tcode{path(tmp)}; + otherwise, +\item convert \tcode{source} or \range{first}{last} + to a temporary, \tcode{tmp}, of type \tcode{u32string} and + return \tcode{path(tmp)}. +\end{itemize} -\begin{itemdescr} \pnum -\effects -Calls -\tcode{rdbuf()->freeze(freezefl)}. +\remarks +Argument format conversion\iref{fs.path.fmt.cvt} applies to the + arguments for these functions. How Unicode encoding conversions are performed is + unspecified. + +\pnum +\begin{example} +A string is to be read from a database that is encoded in UTF-8, and used + to create a directory using the native encoding for filenames: +\begin{codeblock} +namespace fs = std::filesystem; +std::string utf8_string = read_utf8_data(); +fs::create_directory(fs::u8path(utf8_string)); +\end{codeblock} + +For POSIX-based operating systems with the native narrow encoding set + to UTF-8, no encoding or type conversion occurs. + +For POSIX-based operating systems with the native narrow encoding not + set to UTF-8, a conversion to UTF-32 occurs, followed by a conversion to the + current native narrow encoding. Some Unicode characters may have no native character + set representation. + +For Windows-based operating systems a conversion from UTF-8 to + UTF-16 occurs. +\end{example} +\begin{note} +The example above is representative of +a historical use of \tcode{filesystem::u8path}. +To indicate a UTF-8 encoding, +passing a \tcode{std::u8string} to \tcode{path}'s constructor is preferred +as it is consistent with \tcode{path}'s handling of other encodings. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{str}!\idxcode{strstream}}% +\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} -char* str(); +std::string string() const; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{rdbuf()->str()}. +\tcode{native_encoded_string()}. \end{itemdescr} -\indexlibrary{\idxcode{pcount}!\idxcode{strstream}}% +\indexlibrarymember{generic_string}{path}% \begin{itemdecl} -int pcount() const; +std::string generic_string() const; \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{rdbuf()->pcount()}. +\tcode{generic_native_encoded_string()}. \end{itemdescr} -\rSec1[exception.unexpected]{Violating \grammarterm{exception-specification}{s}} - -\rSec2[unexpected.handler]{Type \tcode{unexpected_handler}} +\rSec1[depr.atomics]{Deprecated atomic operations} -\indexlibrary{\idxcode{unexpected_handler}}% -\begin{itemdecl} -typedef void (*unexpected_handler)(); -\end{itemdecl} +\rSec2[depr.atomics.general]{General} -\begin{itemdescr} \pnum -The type of a -\term{handler function} -to be called by -\tcode{unexpected()} -when a function attempts to throw an exception not listed in its -\grammarterm{dynamic-exception-specification}. +The header \libheaderrefx{atomic}{atomics.syn} has the following additions. -\pnum -\required -An -\tcode{unexpected_handler} -shall not return. -See also~\ref{except.unexpected}. +\begin{codeblock} +namespace std { + template + 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 @\libmacro{ATOMIC_VAR_INIT}@(value) @\seebelow@ +} +\end{codeblock} + +\rSec2[depr.atomics.volatile]{Volatile access} \pnum -\default -The implementation's default \tcode{unexpected_handler} calls -\tcode{std::terminate()}. -\indexlibrary{\idxcode{terminate}} -\end{itemdescr} +If an \tcode{atomic}\iref{atomics.types.generic} specialization has one of the following overloads, +then that overload participates in overload resolution +even if \tcode{atomic::is_always_lock_free} is \tcode{false}: +\begin{codeblock} +void store(T desired, memory_order order = memory_order::seq_cst) volatile noexcept; +T operator=(T desired) volatile noexcept; +T load(memory_order order = memory_order::seq_cst) const volatile noexcept; +operator T() const volatile noexcept; +T exchange(T desired, memory_order order = memory_order::seq_cst) volatile noexcept; +bool compare_exchange_weak(T& expected, T desired, + memory_order success, memory_order failure) volatile noexcept; +bool compare_exchange_strong(T& expected, T desired, + memory_order success, memory_order failure) volatile noexcept; +bool compare_exchange_weak(T& expected, T desired, + memory_order order = memory_order::seq_cst) volatile noexcept; +bool compare_exchange_strong(T& expected, T desired, + memory_order order = memory_order::seq_cst) volatile noexcept; +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; +\end{codeblock} -\rSec2[set.unexpected]{\tcode{set_unexpected}} +\rSec2[depr.atomics.nonmembers]{Non-member functions} -\indexlibrary{\idxcode{set_unexpected}}% +\indexlibraryglobal{atomic_init}% \begin{itemdecl} -unexpected_handler set_unexpected(unexpected_handler f) noexcept; +template + void atomic_init(volatile atomic* object, typename atomic::value_type desired) noexcept; +template + void atomic_init(atomic* object, typename atomic::value_type desired) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects -Establishes the function designated by \tcode{f} as the current -\tcode{unexpected_handler}. - -\pnum -\remark It is unspecified whether a null pointer value designates the default -\tcode{unexpected_handler}. - -\pnum -\returns -The previous \tcode{unexpected_handler}. +Equivalent to: \tcode{atomic_store_explicit(object, desired, memory_order::relaxed);} \end{itemdescr} -\rSec2[get.unexpected]{\tcode{get_unexpected}} +\rSec2[depr.atomics.types.operations]{Operations on atomic types} +\indexlibraryglobal{ATOMIC_VAR_INIT}% \begin{itemdecl} -unexpected_handler get_unexpected() noexcept; +#define @\libmacro{ATOMIC_VAR_INIT}@(value) @\seebelow@ \end{itemdecl} \begin{itemdescr} \pnum -\returns The current \tcode{unexpected_handler}. -\enternote This may be a null pointer value. \exitnote +The macro expands to a token sequence suitable for constant initialization of +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. +\end{note} +Concurrent access to the variable being initialized, +even via an atomic operation, +constitutes a data race. +\begin{example} +\begin{codeblock} +atomic v = ATOMIC_VAR_INIT(5); +\end{codeblock} +\end{example} \end{itemdescr} -\rSec2[unexpected]{\tcode{unexpected}} - -\indexlibrary{\idxcode{unexpected}}% -\begin{itemdecl} -[[noreturn]] void unexpected(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -Called by the implementation when a function exits via an exception not allowed by its -\grammarterm{exception-specification}~(\ref{except.unexpected}), in -effect after evaluating the throw-expression~(\ref{unexpected.handler}). -May also be called directly by the program. +\rSec2[depr.atomics.order]{\tcode{memory_order::consume}} +\indexlibraryglobal{memory_order}% +\indexlibrarymember{consume}{memory_order}% \pnum -\effects -Calls the current \tcode{unexpected_handler} function. -\enternote A default \tcode{unexpected_handler} is always considered a callable handler in -this context. \exitnote -\end{itemdescr} - -\rSec1[depr.uncaught]{\tcode{uncaught_exception}} +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. -\indexlibrary{\idxcode{uncaught_exception}}% \begin{itemdecl} -bool uncaught_exception() noexcept; +template constexpr T kill_dependency(T y) noexcept; \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{uncaught_exceptions() > 0}. +\returns +\tcode{y}. \end{itemdescr} diff --git a/source/generalindex.ist b/source/generalindex.ist new file mode 100644 index 0000000000..20892a73ae --- /dev/null +++ b/source/generalindex.ist @@ -0,0 +1,3 @@ +headings_flag 1 +heading_prefix "\\rSecindex{general}{" +heading_suffix "}\n" diff --git a/source/grammar.tex b/source/grammar.tex index b2295b786b..db27a2f510 100644 --- a/source/grammar.tex +++ b/source/grammar.tex @@ -1,1841 +1,61 @@ \infannex{gram}{Grammar summary} -\begin{paras} +\rSec1[gram.general]{General} \pnum -\index{grammar}% -\index{summary, syntax}% -This summary of \Cpp\ syntax is intended to be an aid to comprehension. +\indextext{grammar}% +\indextext{summary!syntax}% +This summary of \Cpp{} grammar is intended to be an aid to comprehension. It is not an exact statement of the language. In particular, the grammar described here accepts -a superset of valid \Cpp\ constructs. -Disambiguation rules (\ref{stmt.ambig}, \ref{dcl.spec}, \ref{class.member.lookup}) -must be applied to distinguish expressions from declarations. -Further, access control, ambiguity, and type rules must be used +a superset of valid \Cpp{} constructs. +Disambiguation rules\iref{stmt.ambig,dcl.spec,class.member.lookup} +are applied to distinguish expressions from declarations. +Further, access control, ambiguity, and type rules are used to weed out syntactically valid but meaningless constructs. \rSec1[gram.key]{Keywords} \pnum -\index{keyword}% +\indextext{keyword}% New context-dependent keywords are introduced into a program by -\tcode{typedef}~(\ref{dcl.typedef}), -\tcode{namespace}~(\ref{namespace.def}), -class~(Clause \ref{class}), enumeration~(\ref{dcl.enum}), and -\tcode{template}~(Clause \ref{temp}) +\tcode{typedef}\iref{dcl.typedef}, +\tcode{namespace}\iref{namespace.def}, +class\iref{class}, enumeration\iref{dcl.enum}, and +\keyword{template}\iref{temp} declarations. -\begin{bnf} +\begin{ncbnf} typedef-name:\br - identifier -\end{bnf} + identifier\br + simple-template-id +\end{ncbnf} -\begin{bnf} +\begin{ncbnf} namespace-name:\br - original-namespace-name\br + identifier\br namespace-alias +\end{ncbnf} -original-namespace-name:\br - identifier - +\begin{ncbnf} namespace-alias:\br identifier -\end{bnf} +\end{ncbnf} -\begin{bnf} +\begin{ncbnf} class-name:\br identifier\br simple-template-id -\end{bnf} +\end{ncbnf} -\begin{bnf} +\begin{ncbnf} enum-name:\br identifier -\end{bnf} +\end{ncbnf} -\begin{bnf} +\begin{ncbnf} template-name:\br identifier -\end{bnf} - -Note that a -\grammarterm{typedef-name}\ -naming a class is also a -\grammarterm{class-name}\ -(\ref{class.name}). - -\end{paras} - -% machine generated after this line; do not edit -\rSec1[gram.lex]{Lexical conventions} - -\begin{bnf} -\nontermdef{hex-quad}\br - hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit -\end{bnf} - -\begin{bnf} -\nontermdef{universal-character-name}\br - \terminal{\textbackslash u} hex-quad\br - \terminal{\textbackslash U} hex-quad hex-quad -\end{bnf} - -\begin{bnf} -\indextext{token!preprocessing|(}% -\nontermdef{preprocessing-token}\br - header-name\br - identifier\br - pp-number\br - character-literal\br - user-defined-character-literal\br - string-literal\br - user-defined-string-literal\br - preprocessing-op-or-punc\br - \textnormal{each non-white-space character that cannot be one of the above} -\end{bnf} - -\begin{bnf} -\nontermdef{token}\br - identifier\br - keyword\br - literal\br - operator\br - punctuator -\end{bnf} - -\begin{bnf} -\nontermdef{header-name}\br - \terminal{<} h-char-sequence \terminal{>}\br - \terminal{"} q-char-sequence \terminal{"} -\end{bnf} - -\begin{bnf} -\nontermdef{h-char-sequence}\br - h-char\br - h-char-sequence h-char -\end{bnf} - -\begin{bnf} -\nontermdef{h-char}\br - \textnormal{any member of the source character set except new-line and \terminal{>}} -\end{bnf} - -\begin{bnf} -\nontermdef{q-char-sequence}\br - q-char\br - q-char-sequence q-char -\end{bnf} - -\begin{bnf} -\nontermdef{q-char}\br - \textnormal{any member of the source character set except new-line and \terminal{"}} -\end{bnf} - -\begin{bnf} -\nontermdef{pp-number}\br - digit\br - \terminal{.} digit\br - pp-number digit\br - pp-number identifier-nondigit\br - pp-number \terminal{'} digit\br - pp-number \terminal{'} nondigit\br - pp-number \terminal{e} sign\br - pp-number \terminal{E} sign\br - pp-number \terminal{.} -\end{bnf} - -\begin{bnf} -\nontermdef{identifier}\br - identifier-nondigit\br - identifier identifier-nondigit\br - identifier digit -\end{bnf} - -\begin{bnf} -\nontermdef{identifier-nondigit}\br - nondigit\br - universal-character-name\br - \textnormal{other implementation-defined characters} -\end{bnf} - -\begin{bnf} -\nontermdef{nondigit} \textnormal{one of}\br - \terminal{a b c d e f g h i j k l m}\br - \terminal{n o p q r s t u v w x y z}\br - \terminal{A B C D E F G H I J K L M}\br - \terminal{N O P Q R S T U V W X Y Z _} -\end{bnf} - -\begin{bnf} -\nontermdef{digit} \textnormal{one of}\br - \terminal{0 1 2 3 4 5 6 7 8 9} -\end{bnf} - -\begin{bnfkeywordtab} -\nontermdef{preprocessing-op-or-punc} \textnormal{one of}\br -\>\{ \>\} \>[ \>] \>\# \>\#\# \>( \>)\br -\><: \>:> \><\% \>\%> \>\%: \>\%:\%: \>; \>: \>.{..}\br -\>new \>delete \>? \>:: \>. \>.*\br -\>+ \>- \>* \>/ \>\% \>\^{} \>\& \>| \>\tilde\br -\>! \>= \>< \>> \>+= \>-= \>*= \>/= \>\%=\br -\>\^{}= \>\&= \>|= \>\shl \>\shr \>\shr= \>\shl= \>== \>!=\br -\><= \>>= \>\&\& \>|| \>++ \>-{-} \>, \>->* \>->\br -\>and \>and_eq \>bitand \>bitor \>compl \>not \>not_eq\br -\>or \>or_eq \>xor \>xor_eq -\end{bnfkeywordtab} - -\begin{bnf} -\nontermdef{literal}\br - integer-literal\br - character-literal\br - floating-literal\br - string-literal\br - boolean-literal\br - pointer-literal\br - user-defined-literal -\end{bnf} - -\begin{bnf} -\nontermdef{integer-literal}\br - binary-literal integer-suffix\opt\br - octal-literal integer-suffix\opt\br - decimal-literal integer-suffix\opt\br - hexadecimal-literal integer-suffix\opt -\end{bnf} - -\begin{bnf} -\nontermdef{binary-literal}\br - \terminal{0b} binary-digit\br - \terminal{0B} binary-digit\br - binary-literal \terminal{'}\opt binary-digit -\end{bnf} - -\begin{bnf} -\nontermdef{octal-literal}\br - \terminal{0}\br - octal-literal \terminal{'}\opt octal-digit -\end{bnf} - -\begin{bnf} -\nontermdef{decimal-literal}\br - nonzero-digit\br - decimal-literal \terminal{'}\opt digit -\end{bnf} - -\begin{bnf} -\nontermdef{hexadecimal-literal}\br - \terminal{0x} hexadecimal-digit\br - \terminal{0X} hexadecimal-digit\br - hexadecimal-literal \terminal{'}\opt hexadecimal-digit -\end{bnf} - -\begin{bnf} -\nontermdef{binary-digit}\br - \terminal{0}\br - \terminal{1} -\end{bnf} - -\begin{bnf} -\nontermdef{octal-digit} \textnormal{one of}\br - \terminal{0 1 2 3 4 5 6 7} -\end{bnf} - -\begin{bnf} -\nontermdef{nonzero-digit} \textnormal{one of}\br - \terminal{1 2 3 4 5 6 7 8 9} -\end{bnf} - -\begin{bnf} -\nontermdef{hexadecimal-digit} \textnormal{one of}\br - \terminal{0 1 2 3 4 5 6 7 8 9}\br - \terminal{a b c d e f}\br - \terminal{A B C D E F} -\end{bnf} - -\begin{bnf} -\nontermdef{integer-suffix}\br - unsigned-suffix long-suffix\opt \br - unsigned-suffix long-long-suffix\opt \br - long-suffix unsigned-suffix\opt \br - long-long-suffix unsigned-suffix\opt -\end{bnf} - -\begin{bnf} -\nontermdef{unsigned-suffix} \textnormal{one of}\br - \terminal{u U} -\end{bnf} - -\begin{bnf} -\nontermdef{long-suffix} \textnormal{one of}\br - \terminal{l L} -\end{bnf} - -\begin{bnf} -\nontermdef{long-long-suffix} \textnormal{one of}\br - \terminal{ll LL} -\end{bnf} - -\begin{bnf} -\nontermdef{character-literal}\br - encoding-prefix\opt \terminal{'} c-char-sequence \terminal{'} -\end{bnf} - -\begin{bnf} -\nontermdef{encoding-prefix} \textnormal{one of}\br - \terminal{u8}\quad\terminal{u}\quad\terminal{U}\quad\terminal{L} -\end{bnf} - -\begin{bnf} -\nontermdef{c-char-sequence}\br - c-char\br - c-char-sequence c-char -\end{bnf} - -\begin{bnftab} -\nontermdef{c-char}\br -\>\textnormal{any member of the source character set except}\br -\>\>\textnormal{the single-quote \terminal{'}, backslash \terminal{\textbackslash}, or new-line character}\br -\>escape-sequence\br -\>universal-character-name -\end{bnftab} - -\begin{bnf} -\nontermdef{escape-sequence}\br - simple-escape-sequence\br - octal-escape-sequence\br - hexadecimal-escape-sequence -\end{bnf} - -\begin{bnf} -\nontermdef{simple-escape-sequence} \textnormal{one of}\br - \terminal{\textbackslash'}\quad\terminal{\textbackslash"}\quad\terminal{\textbackslash ?}\quad\terminal{\textbackslash\textbackslash}\br - \terminal{\textbackslash a}\quad\terminal{\textbackslash b}\quad\terminal{\textbackslash f}\quad\terminal{\textbackslash n}\quad\terminal{\textbackslash r}\quad\terminal{\textbackslash t}\quad\terminal{\textbackslash v} -\end{bnf} - -\begin{bnf} -\nontermdef{octal-escape-sequence}\br - \terminal{\textbackslash} octal-digit\br - \terminal{\textbackslash} octal-digit octal-digit\br - \terminal{\textbackslash} octal-digit octal-digit octal-digit -\end{bnf} - -\begin{bnf} -\nontermdef{hexadecimal-escape-sequence}\br - \terminal{\textbackslash x} hexadecimal-digit\br - hexadecimal-escape-sequence hexadecimal-digit -\end{bnf} - -\begin{bnf} -\nontermdef{floating-literal}\br - fractional-constant exponent-part\opt floating-suffix\opt\br - digit-sequence exponent-part floating-suffix\opt -\end{bnf} - -\begin{bnf} -\nontermdef{fractional-constant}\br - digit-sequence\opt \terminal{.} digit-sequence\br - digit-sequence \terminal{.} -\end{bnf} - -\begin{bnf} -\nontermdef{exponent-part}\br - \terminal{e} sign\opt digit-sequence\br - \terminal{E} sign\opt digit-sequence -\end{bnf} - -\begin{bnf} -\nontermdef{sign} \textnormal{one of}\br - \terminal{+ -} -\end{bnf} - -\begin{bnf} -\nontermdef{digit-sequence}\br - digit\br - digit-sequence \terminal{'}\opt digit -\end{bnf} - -\begin{bnf} -\nontermdef{floating-suffix} \textnormal{one of}\br - \terminal{f l F L} -\end{bnf} - -\begin{bnf} -\nontermdef{string-literal}\br - encoding-prefix\opt \terminal{"} s-char-sequence\opt \terminal{"}\br - encoding-prefix\opt \terminal{R} raw-string -\end{bnf} - -\begin{bnf} -\nontermdef{s-char-sequence}\br - s-char\br - s-char-sequence s-char -\end{bnf} - -\begin{bnftab} -\nontermdef{s-char}\br -\>\textnormal{any member of the source character set except}\br -\>\>\textnormal{the double-quote \terminal{"}, backslash \terminal{\textbackslash}, or new-line character}\br -\>escape-sequence\br -\>universal-character-name -\end{bnftab} - -\begin{bnf} -\nontermdef{raw-string}\br - \terminal{"} d-char-sequence\opt \terminal{(} r-char-sequence\opt \terminal{)} d-char-sequence\opt \terminal{"} -\end{bnf} - -\begin{bnf} -\nontermdef{r-char-sequence}\br - r-char\br - r-char-sequence r-char -\end{bnf} - -\begin{bnftab} -\nontermdef{r-char}\br -\>\textnormal{any member of the source character set, except}\br -\>\>\textnormal{a right parenthesis \terminal{)} followed by the initial \nonterminal{d-char-sequence}}\br -\>\>\textnormal{(which may be empty) followed by a double quote \terminal{"}.} -\end{bnftab} - -\begin{bnf} -\nontermdef{d-char-sequence}\br - d-char\br - d-char-sequence d-char -\end{bnf} - -\begin{bnftab} -\nontermdef{d-char}\br -\>\textnormal{any member of the basic source character set except:}\br -\>\>\textnormal{space, the left parenthesis \terminal{(}, the right parenthesis \terminal{)}, the backslash \terminal{\textbackslash},}\br -\>\>\textnormal{and the control characters representing horizontal tab,}\br -\>\>\textnormal{vertical tab, form feed, and newline.} -\end{bnftab} - -\begin{bnf} -\nontermdef{boolean-literal}\br - \terminal{false}\br - \terminal{true} -\end{bnf} - -\begin{bnf} -\nontermdef{pointer-literal}\br - \terminal{nullptr} -\end{bnf} - -\begin{bnf} -\nontermdef{user-defined-literal}\br - user-defined-integer-literal\br - user-defined-floating-literal\br - user-defined-string-literal\br - user-defined-character-literal -\end{bnf} - -\begin{bnf} -\nontermdef{user-defined-integer-literal}\br - decimal-literal ud-suffix\br - octal-literal ud-suffix\br - hexadecimal-literal ud-suffix\br - binary-literal ud-suffix -\end{bnf} - -\begin{bnf} -\nontermdef{user-defined-floating-literal}\br - fractional-constant exponent-part\opt ud-suffix\br - digit-sequence exponent-part ud-suffix -\end{bnf} - -\begin{bnf} -\nontermdef{user-defined-string-literal}\br - string-literal ud-suffix -\end{bnf} - -\begin{bnf} -\nontermdef{user-defined-character-literal}\br - character-literal ud-suffix -\end{bnf} - -\begin{bnf} -\nontermdef{ud-suffix}\br - identifier -\end{bnf} - -\rSec1[gram.basic]{Basic concepts} - -\begin{bnf} -\nontermdef{translation-unit}\br - declaration-seq\opt -\end{bnf} - -\rSec1[gram.expr]{Expressions} - -\begin{bnf} -\nontermdef{primary-expression}\br - literal\br - \terminal{this}\br - \terminal{(} expression \terminal{)}\br - id-expression\br - lambda-expression\br - fold-expression -\end{bnf} - -\begin{bnf} -\nontermdef{id-expression}\br - unqualified-id\br - qualified-id -\end{bnf} - -\begin{bnf} -\nontermdef{unqualified-id}\br - identifier\br - operator-function-id\br - conversion-function-id\br - literal-operator-id\br - \terminal{\tilde} class-name\br - \terminal{\tilde} decltype-specifier\br - template-id -\end{bnf} - -\begin{bnf} -\nontermdef{qualified-id}\br - nested-name-specifier \terminal{template}\opt unqualified-id -\end{bnf} - -\begin{bnf} -\nontermdef{nested-name-specifier}\br - \terminal{::}\br - type-name \terminal{::}\br - namespace-name \terminal{::}\br - decltype-specifier \terminal{::}\br - nested-name-specifier identifier \terminal{::}\br - nested-name-specifier \terminal{template}\opt simple-template-id \terminal{::} -\end{bnf} - -\begin{bnf} -\nontermdef{lambda-expression}\br - lambda-introducer lambda-declarator\opt compound-statement -\end{bnf} - -\begin{bnf} -\nontermdef{lambda-introducer}\br - \terminal{[} lambda-capture\opt \terminal{]} -\end{bnf} - -\begin{bnf} -\nontermdef{lambda-capture}\br - capture-default\br - capture-list\br - capture-default \terminal{,} capture-list -\end{bnf} - -\begin{bnf} -\nontermdef{capture-default}\br - \terminal{\&}\br - \terminal{=} -\end{bnf} - -\begin{bnf} -\nontermdef{capture-list}\br - capture \terminal{...\opt}\br - capture-list \terminal{,} capture \terminal{...\opt} -\end{bnf} - -\begin{bnf} -\nontermdef{capture}\br - simple-capture\br - init-capture -\end{bnf} - -\begin{bnf} -\nontermdef{simple-capture}\br - identifier\br - \terminal{\&} identifier\br - \terminal{this} -\end{bnf} - -\begin{bnf} -\nontermdef{init-capture}\br - identifier initializer\br - \terminal{\&} identifier initializer -\end{bnf} - -\begin{bnf} -\nontermdef{lambda-declarator}\br - \terminal{(} parameter-declaration-clause \terminal{)} \terminal{mutable}\opt\br - \hspace*{\bnfindentinc}exception-specification\opt attribute-specifier-seq\opt trailing-return-type\opt -\end{bnf} - -\begin{bnf} -\nontermdef{fold-expression}\br - \terminal{(} cast-expression fold-operator \terminal{...} \terminal{)}\br - \terminal{(} \terminal{...} fold-operator cast-expression \terminal{)}\br - \terminal{(} cast-expression fold-operator \terminal{...} fold-operator cast-expression \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{fold-operator} \textnormal{one of}\br - \terminal{+ }\quad\terminal{- }\quad\terminal{* }\quad\terminal{/ }\quad\terminal{\% }\quad\terminal{\^{} }\quad\terminal{\& }\quad\terminal{| }\quad\terminal{\shl\ }\quad\terminal{\shr }\br - \terminal{+=}\quad\terminal{-=}\quad\terminal{*=}\quad\terminal{/=}\quad\terminal{\%=}\quad\terminal{\^{}=}\quad\terminal{\&=}\quad\terminal{|=}\quad\terminal{\shl=}\quad\terminal{\shr=}\quad\terminal{=}\br - \terminal{==}\quad\terminal{!=}\quad\terminal{< }\quad\terminal{> }\quad\terminal{<=}\quad\terminal{>=}\quad\terminal{\&\&}\quad\terminal{||}\quad\terminal{, }\quad\terminal{.* }\quad\terminal{->*} -\end{bnf} - -\begin{bnf} -\nontermdef{postfix-expression}\br - primary-expression\br - postfix-expression \terminal{[} expression \terminal{]}\br - postfix-expression \terminal{[} braced-init-list \terminal{]}\br - postfix-expression \terminal{(} expression-list\opt \terminal{)}\br - simple-type-specifier \terminal{(} expression-list\opt \terminal{)}\br - typename-specifier \terminal{(} expression-list\opt \terminal{)}\br - simple-type-specifier braced-init-list\br - typename-specifier braced-init-list\br - postfix-expression \terminal{. template}\opt id-expression\br - postfix-expression \terminal{-> template}\opt id-expression\br - postfix-expression \terminal{.} pseudo-destructor-name\br - postfix-expression \terminal{->} pseudo-destructor-name\br - postfix-expression \terminal{++}\br - postfix-expression \terminal{-{-}}\br - \terminal{dynamic_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{static_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{reinterpret_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{const_cast <} type-id \terminal{> (} expression \terminal{)}\br - \terminal{typeid (} expression \terminal{)}\br - \terminal{typeid (} type-id \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{expression-list}\br - initializer-list -\end{bnf} - -\begin{bnf} -\nontermdef{pseudo-destructor-name}\br - nested-name-specifier\opt type-name \terminal{::\,\tilde} type-name\br - nested-name-specifier \terminal{template} simple-template-id \terminal{::\,\tilde} type-name\br - \terminal{\tilde} type-name\br - \terminal{\tilde} decltype-specifier -\end{bnf} - -\begin{bnf} -\nontermdef{unary-expression}\br - postfix-expression\br - \terminal{++} cast-expression\br - \terminal{-{-}} cast-expression\br - unary-operator cast-expression\br - \terminal{sizeof} unary-expression\br - \terminal{sizeof (} type-id \terminal{)}\br - \terminal{sizeof ...} \terminal{(} identifier \terminal{)}\br - \terminal{alignof (} type-id \terminal{)}\br - noexcept-expression\br - new-expression\br - delete-expression -\end{bnf} - -\begin{bnf} -\nontermdef{unary-operator} \textnormal{one of}\br - \terminal{* \& + - ! \tilde} -\end{bnf} - -\begin{bnf} -\nontermdef{new-expression}\br - \terminal{::}\opt \terminal{new} new-placement\opt new-type-id new-initializer\opt \br - \terminal{::}\opt \terminal{new} new-placement\opt \terminal{(} type-id \terminal{)} new-initializer\opt -\end{bnf} - -\begin{bnf} -\nontermdef{new-placement}\br - \terminal{(} expression-list \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{new-type-id}\br - type-specifier-seq new-declarator\opt -\end{bnf} - -\begin{bnf} -\nontermdef{new-declarator}\br - ptr-operator new-declarator\opt \br - noptr-new-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{noptr-new-declarator}\br - \terminal{[} expression \terminal{]} attribute-specifier-seq\opt\br - noptr-new-declarator \terminal{[} constant-expression \terminal{]} attribute-specifier-seq\opt -\end{bnf} - -\begin{bnf} -\nontermdef{new-initializer}\br - \terminal{(} expression-list\opt \terminal{)}\br - braced-init-list -\end{bnf} - -\begin{bnf} -\nontermdef{delete-expression}\br - \terminal{::}\opt \terminal{delete} cast-expression\br - \terminal{::}\opt \terminal{delete [ ]} cast-expression -\end{bnf} - -\begin{bnf} -\nontermdef{noexcept-expression}\br - \terminal{noexcept} \terminal{(} expression \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{cast-expression}\br - unary-expression\br - \terminal{(} type-id \terminal{)} cast-expression -\end{bnf} - -\begin{bnf} -\nontermdef{pm-expression}\br - cast-expression\br - pm-expression \terminal{.*} cast-expression\br - pm-expression \terminal{->*} cast-expression -\end{bnf} - -\begin{bnf} -\nontermdef{multiplicative-expression}\br - pm-expression\br - multiplicative-expression \terminal{*} pm-expression\br - multiplicative-expression \terminal{/} pm-expression\br - multiplicative-expression \terminal{\%} pm-expression -\end{bnf} - -\begin{bnf} -\nontermdef{additive-expression}\br - multiplicative-expression\br - additive-expression \terminal{+} multiplicative-expression\br - additive-expression \terminal{-} multiplicative-expression -\end{bnf} - -\begin{bnf} -\nontermdef{shift-expression}\br - additive-expression\br - shift-expression \terminal{\shl} additive-expression\br - shift-expression \terminal{\shr} additive-expression -\end{bnf} - -\begin{bnf} -\nontermdef{relational-expression}\br - shift-expression\br - relational-expression \terminal{<} shift-expression\br - relational-expression \terminal{>} shift-expression\br - relational-expression \terminal{<=} shift-expression\br - relational-expression \terminal{>=} shift-expression -\end{bnf} - -\begin{bnf} -\nontermdef{equality-expression}\br - relational-expression\br - equality-expression \terminal{==} relational-expression\br - equality-expression \terminal{!=} relational-expression -\end{bnf} - -\begin{bnf} -\nontermdef{and-expression}\br - equality-expression\br - and-expression \terminal{\&} equality-expression -\end{bnf} - -\begin{bnf} -\nontermdef{exclusive-or-expression}\br - and-expression\br - exclusive-or-expression \terminal{\^{}} and-expression -\end{bnf} - -\begin{bnf} -\nontermdef{inclusive-or-expression}\br - exclusive-or-expression\br - inclusive-or-expression \terminal{|} exclusive-or-expression -\end{bnf} - -\begin{bnf} -\nontermdef{logical-and-expression}\br - inclusive-or-expression\br - logical-and-expression \terminal{\&\&} inclusive-or-expression -\end{bnf} - -\begin{bnf} -\nontermdef{logical-or-expression}\br - logical-and-expression\br - logical-or-expression \terminal{$||$} logical-and-expression -\end{bnf} - -\begin{bnf} -\nontermdef{conditional-expression}\br - logical-or-expression\br - logical-or-expression \terminal{?} expression \terminal{:} assignment-expression -\end{bnf} - -\begin{bnf} -\nontermdef{throw-expression}\br - \terminal{throw} assignment-expression\opt -\end{bnf} - -\begin{bnf} -\nontermdef{assignment-expression}\br - conditional-expression\br - logical-or-expression assignment-operator initializer-clause\br - throw-expression -\end{bnf} - -\begin{bnf} -\nontermdef{assignment-operator} \textnormal{one of}\br - \terminal{= *= /= \%= += -= \shr= \shl= \&= \^{}= |=} -\end{bnf} - -\begin{bnf} -\nontermdef{expression}\br - assignment-expression\br - expression \terminal{,} assignment-expression -\end{bnf} - -\begin{bnf} -\nontermdef{constant-expression}\br - conditional-expression -\end{bnf} - -\rSec1[gram.stmt]{Statements} - -\begin{bnf} -\nontermdef{statement}\br - labeled-statement\br - attribute-specifier-seq\opt expression-statement\br - attribute-specifier-seq\opt compound-statement\br - attribute-specifier-seq\opt selection-statement\br - attribute-specifier-seq\opt iteration-statement\br - attribute-specifier-seq\opt jump-statement\br - declaration-statement\br - attribute-specifier-seq\opt try-block -\end{bnf} - -\begin{bnf} -\nontermdef{labeled-statement}\br - attribute-specifier-seq\opt identifier \terminal{:} statement\br - attribute-specifier-seq\opt \terminal{case} constant-expression \terminal{:} statement\br - attribute-specifier-seq\opt \terminal{default :} statement -\end{bnf} - -\begin{bnf} -\nontermdef{expression-statement}\br - expression\opt \terminal{;} -\end{bnf} - -\begin{bnf} -\nontermdef{compound-statement}\br - \terminal{\{} statement-seq\opt \terminal{\}} -\end{bnf} - -\begin{bnf} -\nontermdef{statement-seq}\br - statement\br - statement-seq statement -\end{bnf} - -\begin{bnf} -\nontermdef{selection-statement}\br - \terminal{if (} condition \terminal{)} statement\br - \terminal{if (} condition \terminal{)} statement \terminal{else} statement\br - \terminal{switch (} condition \terminal{)} statement -\end{bnf} - -\begin{bnf} -\nontermdef{condition}\br - expression\br - attribute-specifier-seq\opt decl-specifier-seq declarator \terminal{=} initializer-clause\br - attribute-specifier-seq\opt decl-specifier-seq declarator braced-init-list -\end{bnf} - -\begin{bnf} -\nontermdef{iteration-statement}\br - \terminal{while (} condition \terminal{)} statement\br - \terminal{do} statement \terminal{while (} expression \terminal{) ;}\br - \terminal{for (} for-init-statement condition\opt \terminal{;} expression\opt \terminal{)} statement\br - \terminal{for (} for-range-declaration \terminal{:} for-range-initializer \terminal{)} statement -\end{bnf} - -\begin{bnf} -\nontermdef{for-init-statement}\br - expression-statement\br - simple-declaration -\end{bnf} - -\begin{bnf} -\nontermdef{for-range-declaration}\br - attribute-specifier-seq\opt decl-specifier-seq declarator -\end{bnf} - -\begin{bnf} -\nontermdef{for-range-initializer}\br - expression\br - braced-init-list -\end{bnf} - -\begin{bnf} -\nontermdef{jump-statement}\br - \terminal{break ;}\br - \terminal{continue ;}\br - \terminal{return} expression\opt \terminal{;}\br - \terminal{return} braced-init-list \terminal{;}\br - \terminal{goto} identifier \terminal{;} -\end{bnf} - -\begin{bnf} -\nontermdef{declaration-statement}\br - block-declaration -\end{bnf} - -\rSec1[gram.dcl]{Declarations} - -\begin{bnf} -\nontermdef{declaration-seq}\br - declaration\br - declaration-seq declaration -\end{bnf} - -\begin{bnf} -\nontermdef{declaration}\br - block-declaration\br - function-definition\br - template-declaration\br - explicit-instantiation\br - explicit-specialization\br - linkage-specification\br - namespace-definition\br - empty-declaration\br - attribute-declaration -\end{bnf} - -\begin{bnf} -\nontermdef{block-declaration}\br - simple-declaration\br - asm-definition\br - namespace-alias-definition\br - using-declaration\br - using-directive\br - static_assert-declaration\br - alias-declaration\br - opaque-enum-declaration -\end{bnf} - -\begin{bnf} -\nontermdef{alias-declaration}\br - \terminal{using} identifier attribute-specifier-seq\opt \terminal{=} type-id \terminal{;} -\end{bnf} - -\begin{bnf} -\nontermdef{simple-declaration}\br - decl-specifier-seq\opt init-declarator-list\opt \terminal{;}\br - attribute-specifier-seq decl-specifier-seq\opt init-declarator-list \terminal{;} -\end{bnf} - -\begin{bnf} -\nontermdef{static_assert-declaration}\br - \terminal{static_assert} \terminal{(} constant-expression \terminal{)} \terminal{;}\br - \terminal{static_assert} \terminal{(} constant-expression \terminal{,} string-literal \terminal{)} \terminal{;} -\end{bnf} - -\begin{bnf} -\nontermdef{empty-declaration}\br - \terminal{;} -\end{bnf} - -\begin{bnf} -\nontermdef{attribute-declaration}\br - attribute-specifier-seq \terminal{;} -\end{bnf} - -\begin{bnf} -\nontermdef{decl-specifier}\br - storage-class-specifier\br - type-specifier\br - function-specifier\br - \terminal{friend}\br - \terminal{typedef}\br - \terminal{constexpr} -\end{bnf} - -\begin{bnf} -\nontermdef{decl-specifier-seq}\br - decl-specifier attribute-specifier-seq\opt\br - decl-specifier decl-specifier-seq -\end{bnf} - -\begin{bnf} -\nontermdef{storage-class-specifier}\br - \terminal{register}\br - \terminal{static}\br - \terminal{thread_local}\br - \terminal{extern}\br - \terminal{mutable} -\end{bnf} - -\begin{bnf} -\nontermdef{function-specifier}\br - \terminal{inline}\br - \terminal{virtual}\br - \terminal{explicit} -\end{bnf} - -\begin{bnf} -\nontermdef{typedef-name}\br - identifier -\end{bnf} - -\begin{bnf} -\nontermdef{type-specifier}\br - trailing-type-specifier\br - class-specifier\br - enum-specifier -\end{bnf} - -\begin{bnf} -\nontermdef{trailing-type-specifier}\br - simple-type-specifier\br - elaborated-type-specifier\br - typename-specifier\br - cv-qualifier -\end{bnf} - -\begin{bnf} -\nontermdef{type-specifier-seq}\br - type-specifier attribute-specifier-seq\opt\br - type-specifier type-specifier-seq -\end{bnf} - -\begin{bnf} -\nontermdef{trailing-type-specifier-seq}\br - trailing-type-specifier attribute-specifier-seq\opt\br - trailing-type-specifier trailing-type-specifier-seq -\end{bnf} - -\begin{bnf} -\nontermdef{simple-type-specifier}\br - nested-name-specifier\opt type-name\br - nested-name-specifier \terminal{template} simple-template-id\br - \terminal{char}\br - \terminal{char16_t}\br - \terminal{char32_t}\br - \terminal{wchar_t}\br - \terminal{bool}\br - \terminal{short}\br - \terminal{int}\br - \terminal{long}\br - \terminal{signed}\br - \terminal{unsigned}\br - \terminal{float}\br - \terminal{double}\br - \terminal{void}\br - \terminal{auto}\br - decltype-specifier -\end{bnf} - -\begin{bnf} -\nontermdef{type-name}\br - class-name\br - enum-name\br - typedef-name\br - simple-template-id -\end{bnf} - -\begin{bnf} -\nontermdef{decltype-specifier}\br - \terminal{decltype} \terminal{(} expression \terminal{)}\br - \terminal{decltype} \terminal{(} \terminal{auto} \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{elaborated-type-specifier}\br - class-key attribute-specifier-seq\opt nested-name-specifier\opt identifier\br - class-key simple-template-id\br - class-key nested-name-specifier \terminal{template}\opt simple-template-id\br - \terminal{enum} nested-name-specifier\opt identifier -\end{bnf} - -\begin{bnf} -\nontermdef{enum-name}\br - identifier -\end{bnf} - -\begin{bnf} -\nontermdef{enum-specifier}\br - enum-head \terminal{\{} enumerator-list\opt \terminal{\}}\br - enum-head \terminal{\{} enumerator-list \terminal{, \}} -\end{bnf} - -\begin{bnf} -\nontermdef{enum-head}\br - enum-key attribute-specifier-seq\opt identifier\opt enum-base\opt\br - enum-key attribute-specifier-seq\opt nested-name-specifier identifier\br -\hspace*{\bnfindentinc}enum-base\opt -\end{bnf} - -\begin{bnf} -\nontermdef{opaque-enum-declaration}\br - enum-key attribute-specifier-seq\opt identifier enum-base\opt \terminal{;} -\end{bnf} - -\begin{bnf} -\nontermdef{enum-key}\br - \terminal{enum}\br - \terminal{enum class}\br - \terminal{enum struct} -\end{bnf} - -\begin{bnf} -\nontermdef{enum-base}\br - \terminal{:} type-specifier-seq -\end{bnf} - -\begin{bnf} -\nontermdef{enumerator-list}\br - enumerator-definition\br - enumerator-list \terminal{,} enumerator-definition -\end{bnf} - -\begin{bnf} -\nontermdef{enumerator-definition}\br - enumerator\br - enumerator \terminal{=} constant-expression -\end{bnf} - -\begin{bnf} -\nontermdef{enumerator}\br - identifier attribute-specifier-seq\opt -\end{bnf} - -\begin{bnf} -\nontermdef{namespace-name}\br - identifier\br - namespace-alias -\end{bnf} - -\begin{bnf} -\nontermdef{namespace-definition}\br - named-namespace-definition\br - unnamed-namespace-definition\br - nested-namespace-definition -\end{bnf} - -\begin{bnf} -\nontermdef{named-namespace-definition}\br - \terminal{inline\opt} \terminal{namespace} attribute-specifier-seq\opt identifier \terminal{\{} namespace-body \terminal{\}} -\end{bnf} - -\begin{bnf} -\nontermdef{unnamed-namespace-definition}\br - \terminal{inline\opt} \terminal{namespace} attribute-specifier-seq\opt \terminal{\{} namespace-body \terminal{\}} -\end{bnf} - -\begin{bnf} -\nontermdef{nested-namespace-definition}\br - \terminal{namespace} enclosing-namespace-specifier \terminal{::} identifier \terminal{\{} namespace-body \terminal{\}} -\end{bnf} - -\begin{bnf} -\nontermdef{enclosing-namespace-specifier}\br - identifier\br - enclosing-namespace-specifier \terminal{::} identifier -\end{bnf} - -\begin{bnf} -\nontermdef{namespace-body}\br - declaration-seq\opt -\end{bnf} - -\begin{bnf} -\nontermdef{namespace-alias}\br - identifier -\end{bnf} - -\begin{bnf} -\nontermdef{namespace-alias-definition}\br - \terminal{namespace} identifier \terminal{=} qualified-namespace-specifier \terminal{;} -\end{bnf} - -\begin{bnf} -\nontermdef{qualified-namespace-specifier}\br - nested-name-specifier\opt namespace-name -\end{bnf} - -\begin{bnf} -\nontermdef{using-declaration}\br - \terminal{using typename\opt} nested-name-specifier unqualified-id \terminal{;}\br -\end{bnf} - -\begin{bnf} -\nontermdef{using-directive}\br - attribute-specifier-seq\opt \terminal{using namespace} nested-name-specifier\opt namespace-name \terminal{;} -\end{bnf} - -\begin{bnf} -\nontermdef{asm-definition}\br - \terminal{asm (} string-literal \terminal{) ;} -\end{bnf} - -\begin{bnf} -\nontermdef{linkage-specification}\br - \terminal{extern} string-literal \terminal{\{} declaration-seq\opt \terminal{\}}\br - \terminal{extern} string-literal declaration -\end{bnf} - -\begin{bnf} -\nontermdef{attribute-specifier-seq}\br - attribute-specifier-seq\opt attribute-specifier -\end{bnf} - -\begin{bnf} -\nontermdef{attribute-specifier}\br - \terminal{[} \terminal{[} attribute-list \terminal{]} \terminal{]}\br - alignment-specifier -\end{bnf} - -\begin{bnf} -\nontermdef{alignment-specifier}\br - \terminal{alignas (} type-id \terminal{...}\opt \terminal{)}\br - \terminal{alignas (} constant-expression \terminal{...}\opt \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{attribute-list}\br - attribute\opt\br - attribute-list \terminal{,} attribute\opt\br - attribute \terminal{...}\br - attribute-list \terminal{,} attribute \terminal{...} -\end{bnf} - -\begin{bnf} -\nontermdef{attribute}\br - attribute-token attribute-argument-clause\opt -\end{bnf} - -\begin{bnf} -\nontermdef{attribute-token}\br - identifier\br - attribute-scoped-token -\end{bnf} - -\begin{bnf} -\nontermdef{attribute-scoped-token}\br - attribute-namespace \terminal{::} identifier -\end{bnf} - -\begin{bnf} -\nontermdef{attribute-namespace}\br - identifier -\end{bnf} - -\begin{bnf} -\nontermdef{attribute-argument-clause}\br - \terminal{(} balanced-token-seq \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{balanced-token-seq}\br - balanced-token\opt\br - balanced-token-seq balanced-token -\end{bnf} - -\begin{bnf} -\nontermdef{balanced-token}\br - \terminal{(} balanced-token-seq \terminal{)}\br - \terminal{[} balanced-token-seq \terminal{]}\br - \terminal{\{} balanced-token-seq \terminal{\}}\br - \textnormal{any \grammarterm{token} other than a parenthesis, a bracket, or a brace} -\end{bnf} - -\rSec1[gram.decl]{Declarators} - -\begin{bnf} -\nontermdef{init-declarator-list}\br - init-declarator\br - init-declarator-list \terminal{,} init-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{init-declarator}\br - declarator initializer\opt -\end{bnf} - -\begin{bnf} -\nontermdef{declarator}\br - ptr-declarator\br - noptr-declarator parameters-and-qualifiers trailing-return-type -\end{bnf} - -\begin{bnf} -\nontermdef{ptr-declarator}\br - noptr-declarator\br - ptr-operator ptr-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{noptr-declarator}\br - declarator-id attribute-specifier-seq\opt\br - noptr-declarator parameters-and-qualifiers\br - noptr-declarator \terminal{[} constant-expression\opt \terminal{]} attribute-specifier-seq\opt\br - \terminal{(} ptr-declarator \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{parameters-and-qualifiers}\br - \terminal{(} parameter-declaration-clause \terminal{)} cv-qualifier-seq\opt\br -\hspace*{\bnfindentinc}ref-qualifier\opt exception-specification\opt attribute-specifier-seq\opt -\end{bnf} - -\begin{bnf} -\nontermdef{trailing-return-type}\br - \terminal{->} trailing-type-specifier-seq abstract-declarator\opt -\end{bnf} - -\begin{bnf} -\nontermdef{ptr-operator}\br - \terminal{*} attribute-specifier-seq\opt cv-qualifier-seq\opt\br - \terminal{\&} attribute-specifier-seq\opt\br - \terminal{\&\&} attribute-specifier-seq\opt\br - nested-name-specifier \terminal{*} attribute-specifier-seq\opt cv-qualifier-seq\opt -\end{bnf} - -\begin{bnf} -\nontermdef{cv-qualifier-seq}\br - cv-qualifier cv-qualifier-seq\opt -\end{bnf} - -\begin{bnf} -\nontermdef{cv-qualifier}\br - \terminal{const}\br - \terminal{volatile} -\end{bnf} - -\begin{bnf} -\nontermdef{ref-qualifier}\br - \terminal{\&}\br - \terminal{\&\&} -\end{bnf} - -\begin{bnf} -\nontermdef{declarator-id}\br - \terminal{...}\opt id-expression -\end{bnf} - -\begin{bnf} -\nontermdef{type-id}\br - type-specifier-seq abstract-declarator\opt -\end{bnf} - -\begin{bnf} -\nontermdef{abstract-declarator}\br - ptr-abstract-declarator\br - noptr-abstract-declarator\opt parameters-and-qualifiers trailing-return-type\br - abstract-pack-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{ptr-abstract-declarator}\br - noptr-abstract-declarator\br - ptr-operator ptr-abstract-declarator\opt -\end{bnf} - -\begin{bnf} -\nontermdef{noptr-abstract-declarator}\br - noptr-abstract-declarator\opt parameters-and-qualifiers\br - noptr-abstract-declarator\opt \terminal{[} constant-expression\opt{} \terminal{]} attribute-specifier-seq\opt\br - \terminal{(} ptr-abstract-declarator \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{abstract-pack-declarator}\br - noptr-abstract-pack-declarator\br - ptr-operator abstract-pack-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{noptr-abstract-pack-declarator}\br - noptr-abstract-pack-declarator parameters-and-qualifiers\br - noptr-abstract-pack-declarator \terminal{[} constant-expression\opt\ \terminal{]} attribute-specifier-seq\opt\br - \terminal{...} -\end{bnf} - -\begin{bnf} -\nontermdef{parameter-declaration-clause}\br - parameter-declaration-list\opt ...\opt\br - parameter-declaration-list \terminal{,} ... -\end{bnf} - -\begin{bnf} -\nontermdef{parameter-declaration-list}\br - parameter-declaration\br - parameter-declaration-list \terminal{,} parameter-declaration -\end{bnf} - -\begin{bnf} -\nontermdef{parameter-declaration}\br - attribute-specifier-seq\opt decl-specifier-seq declarator\br - attribute-specifier-seq\opt decl-specifier-seq declarator \terminal{=} initializer-clause\br - attribute-specifier-seq\opt decl-specifier-seq abstract-declarator\opt\br - attribute-specifier-seq\opt decl-specifier-seq abstract-declarator\opt \terminal{=} initializer-clause -\end{bnf} - -\begin{bnf} -\nontermdef{function-definition}\br - attribute-specifier-seq\opt decl-specifier-seq\opt declarator virt-specifier-seq\opt function-body -\end{bnf} - -\begin{bnf} -function-body:\br - ctor-initializer\opt compound-statement\br - function-try-block\br - \terminal{= default ;}\br - \terminal{= delete ;} -\end{bnf} - -\begin{bnf} -\nontermdef{initializer}\br - brace-or-equal-initializer\br - \terminal{(} expression-list \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{brace-or-equal-initializer}\br - \terminal{=} initializer-clause\br - braced-init-list -\end{bnf} - -\begin{bnf} -\nontermdef{initializer-clause}\br - assignment-expression\br - braced-init-list -\end{bnf} - -\begin{bnf} -\nontermdef{initializer-list}\br - initializer-clause \terminal{...}\opt\br - initializer-list \terminal{,} initializer-clause \terminal{...}\opt -\end{bnf} - -\begin{bnf} -\nontermdef{braced-init-list}\br - \terminal{\{} initializer-list \terminal{,\opt} \terminal{\}}\br - \terminal{\{} \terminal{\}} -\end{bnf} - -\rSec1[gram.class]{Classes} - -\begin{bnf} -\nontermdef{class-name}\br - identifier\br - simple-template-id -\end{bnf} - -\begin{bnf} -\nontermdef{class-specifier}\br - class-head \terminal{\{} member-specification\opt \terminal{\}} -\end{bnf} - -\begin{bnf} -\nontermdef{class-head}\br - class-key attribute-specifier-seq\opt class-head-name class-virt-specifier\opt base-clause\opt\br - class-key attribute-specifier-seq\opt base-clause\opt -\end{bnf} - -\begin{bnf} -\nontermdef{class-head-name}\br - nested-name-specifier\opt class-name -\end{bnf} - -\begin{bnf} -\nontermdef{class-virt-specifier}\br - \terminal{final} -\end{bnf} - -\begin{bnf} -\nontermdef{class-key}\br - \terminal{class}\br - \terminal{struct}\br - \terminal{union} -\end{bnf} - -\begin{bnf} -\nontermdef{member-specification}\br - member-declaration member-specification\opt\br - access-specifier \terminal{:} member-specification\opt -\end{bnf} - -\begin{bnf} -\nontermdef{member-declaration}\br - attribute-specifier-seq\opt decl-specifier-seq\opt member-declarator-list\opt \terminal{;}\br - function-definition\br - using-declaration\br - static_assert-declaration\br - template-declaration\br - alias-declaration\br - empty-declaration -\end{bnf} - -\begin{bnf} -\nontermdef{member-declarator-list}\br - member-declarator\br - member-declarator-list \terminal{,} member-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{member-declarator}\br - declarator virt-specifier-seq\opt pure-specifier\opt\br - declarator brace-or-equal-initializer\opt\br - identifier\opt attribute-specifier-seq\opt \terminal{:} constant-expression -\end{bnf} - -\begin{bnf} -\nontermdef{virt-specifier-seq}\br - virt-specifier\br - virt-specifier-seq virt-specifier -\end{bnf} - -\begin{bnf} -\nontermdef{virt-specifier}\br - \terminal{override}\br - \terminal{final} -\end{bnf} - -\begin{bnf} -\nontermdef{pure-specifier}\br - \terminal{= 0} -\end{bnf} - -\rSec1[gram.derived]{Derived classes} - -\begin{bnf} -\nontermdef{base-clause}\br - \terminal{:} base-specifier-list -\end{bnf} - -\begin{bnf} -\nontermdef{base-specifier-list}\br - base-specifier \terminal{...}\opt\br - base-specifier-list \terminal{,} base-specifier \terminal{...}\opt -\end{bnf} - -\begin{bnf} -\nontermdef{base-specifier}\br - attribute-specifier-seq\opt base-type-specifier\br - attribute-specifier-seq\opt \terminal{virtual} access-specifier\opt base-type-specifier\br - attribute-specifier-seq\opt access-specifier \terminal{virtual}\opt base-type-specifier -\end{bnf} - -\begin{bnf} -\nontermdef{class-or-decltype}\br - nested-name-specifier\opt class-name\br - decltype-specifier -\end{bnf} - -\begin{bnf} -\nontermdef{base-type-specifier}\br - class-or-decltype -\end{bnf} - -\begin{bnf} -\nontermdef{access-specifier}\br - \terminal{private}\br - \terminal{protected}\br - \terminal{public} -\end{bnf} - -\rSec1[gram.special]{Special member functions} - -\begin{bnf} -\nontermdef{conversion-function-id}\br - \terminal{operator} conversion-type-id -\end{bnf} - -\begin{bnf} -\nontermdef{conversion-type-id}\br - type-specifier-seq conversion-declarator\opt -\end{bnf} - -\begin{bnf} -\nontermdef{conversion-declarator}\br - ptr-operator conversion-declarator\opt -\end{bnf} - -\begin{bnf} -\nontermdef{ctor-initializer}\br - \terminal{:} mem-initializer-list -\end{bnf} - -\begin{bnf} -\nontermdef{mem-initializer-list}\br - mem-initializer \terminal{...}\opt\br - mem-initializer-list \terminal{,} mem-initializer \terminal{...}\opt -\end{bnf} - -\begin{bnf} -\nontermdef{mem-initializer}\br - mem-initializer-id \terminal{(} expression-list\opt \terminal{)}\br - mem-initializer-id braced-init-list -\end{bnf} - -\begin{bnf} -\nontermdef{mem-initializer-id}\br - class-or-decltype\br - identifier -\end{bnf} - -\rSec1[gram.over]{Overloading} - -\begin{bnf} -\nontermdef{operator-function-id}\br - \terminal{operator} operator -\end{bnf} - -\begin{bnfkeywordtab} -\nontermdef{operator} \textnormal{one of}\br -\>new\>delete\>new[]\>delete[]\br -\>+\>-\>*\>/\>\%\>\^{}\>\&\>|\>\~\br -\>!\>=\><\>>\>+=\>-=\>*=\>/=\>\%=\br -\>\^{}=\>\&=\>|=\>\shl\>\shr\>\shr=\>\shl=\>={=}\>!=\br -\><=\>>=\>\&\&\>|{|}\>++\>-{-}\>,\>->*\>->\br -\>(\,)\>[\,] -\end{bnfkeywordtab} - -\begin{bnf} -\nontermdef{literal-operator-id}\br - \terminal{operator} string-literal identifier\br - \terminal{operator} user-defined-string-literal -\end{bnf} - -\rSec1[gram.temp]{Templates} - -\begin{bnf} -\nontermdef{template-declaration}\br - \terminal{template <} template-parameter-list \terminal{>} declaration -\end{bnf} - -\begin{bnf} -\nontermdef{template-parameter-list}\br - template-parameter\br - template-parameter-list \terminal{,} template-parameter -\end{bnf} - -\begin{bnf} -\nontermdef{template-parameter}\br - type-parameter\br - parameter-declaration -\end{bnf} - -\begin{bnf} -\nontermdef{type-parameter}\br - type-parameter-key \terminal{...}\opt identifier\opt\br - type-parameter-key identifier\opt \terminal{=} type-id\br - \terminal{template <} template-parameter-list \terminal{>} type-parameter-key \terminal{...}\opt identifier\opt\br - \terminal{template <} template-parameter-list \terminal{>} type-parameter-key identifier\opt \terminal{=} id-expression -\end{bnf} - -\begin{bnf} -\nontermdef{type-parameter-key}\br - \terminal{class}\br - \terminal{typename} -\end{bnf} - -\begin{bnf} -\nontermdef{simple-template-id}\br - template-name \terminal{<} template-argument-list\opt \terminal{>} -\end{bnf} - -\begin{bnf} -\nontermdef{template-id}\br - simple-template-id\br - operator-function-id \terminal{<} template-argument-list\opt \terminal{>}\br - literal-operator-id \terminal{<} template-argument-list\opt \terminal{>} -\end{bnf} - -\begin{bnf} -\nontermdef{template-name}\br - identifier -\end{bnf} - -\begin{bnf} -\nontermdef{template-argument-list}\br - template-argument \terminal{...}\opt\br - template-argument-list \terminal{,} template-argument \terminal{...}\opt -\end{bnf} - -\begin{bnf} -\nontermdef{template-argument}\br - constant-expression\br - type-id\br - id-expression -\end{bnf} - -\begin{bnf} -\nontermdef{typename-specifier}\br - \terminal{typename} nested-name-specifier identifier\br - \terminal{typename} nested-name-specifier \terminal{template\opt} simple-template-id -\end{bnf} - -\begin{bnf} -\nontermdef{explicit-instantiation}\br - \terminal{extern\opt} \terminal{template} declaration -\end{bnf} - -\begin{bnf} -\nontermdef{explicit-specialization}\br - \terminal{template < >} declaration -\end{bnf} - -\rSec1[gram.except]{Exception handling} - -\begin{bnf} -\nontermdef{try-block}\br - \terminal{try} compound-statement handler-seq -\end{bnf} - -\begin{bnf} -\nontermdef{function-try-block}\br - \terminal{try} ctor-initializer\opt compound-statement handler-seq -\end{bnf} - -\begin{bnf} -\nontermdef{handler-seq}\br - handler handler-seq\opt -\end{bnf} - -\begin{bnf} -\nontermdef{handler}\br - \terminal{catch (} exception-declaration \terminal{)} compound-statement -\end{bnf} - -\begin{bnf} -\nontermdef{exception-declaration}\br - attribute-specifier-seq\opt type-specifier-seq declarator\br - attribute-specifier-seq\opt type-specifier-seq abstract-declarator\opt\br - \terminal{...} -\end{bnf} - -\begin{bnf} -\nontermdef{exception-specification}\br - dynamic-exception-specification\br - noexcept-specification -\end{bnf} - -\begin{bnf} -\nontermdef{dynamic-exception-specification}\br - \terminal{throw (} type-id-list\opt \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{type-id-list}\br - type-id \terminal{...}\opt\br - type-id-list \terminal{,} type-id \terminal{...}\opt -\end{bnf} - -\begin{bnf} -\nontermdef{noexcept-specification}\br - \terminal{noexcept} \terminal{(} constant-expression \terminal{)}\br - \terminal{noexcept} -\end{bnf} - -\rSec1[gram.cpp]{Preprocessing directives} - -\begin{bnf} -\nontermdef{preprocessing-file}\br - group\opt -\end{bnf} - -\begin{bnf} -\nontermdef{group}\br - group-part\br - group group-part -\end{bnf} - -\begin{bnf} -\nontermdef{group-part}\br - if-section\br - control-line\br - text-line\br - \terminal{\#} non-directive -\end{bnf} - -\begin{bnf} -\nontermdef{if-section}\br - if-group elif-groups\opt else-group\opt endif-line -\end{bnf} - -\begin{bnftab} -\nontermdef{if-group}\br -\>\terminal{\# if}\>\>constant-expression new-line group\opt\br -\>\terminal{\# ifdef}\>\>identifier new-line group\opt\br -\>\terminal{\# ifndef}\>\>identifier new-line group\opt -\end{bnftab} - -\begin{bnf} -\nontermdef{elif-groups}\br - elif-group\br - elif-groups elif-group -\end{bnf} - -\begin{bnftab} -\nontermdef{elif-group}\br -\>\terminal{\# elif}\>\>constant-expression new-line group\opt -\end{bnftab} - -\begin{bnftab} -\nontermdef{else-group}\br -\>\terminal{\# else}\>\>new-line group\opt -\end{bnftab} - -\begin{bnftab} -\nontermdef{endif-line}\br -\>\terminal{\# endif}\>\>new-line -\end{bnftab} - -\begin{bnftab} -\nontermdef{control-line}\br -\>\terminal{\# include}\>\>pp-tokens new-line\br -\>\terminal{\# define}\>\>identifier replacement-list new-line\br -\>\terminal{\# define}\>\>identifier lparen identifier-list\opt \terminal{)} replacement-list new-line\br -\>\terminal{\# define}\>\>identifier lparen \terminal{... )} replacement-list new-line\br -\>\terminal{\# define}\>\>identifier lparen identifier-list, \terminal{... )} replacement-list new-line\br -\>\terminal{\# undef}\>\>identifier new-line\br -\>\terminal{\# line}\>\>pp-tokens new-line\br -\>\terminal{\# error}\>\>pp-tokens\opt new-line\br -\>\terminal{\# pragma}\>\>pp-tokens\opt new-line\br -\>\terminal{\# }new-line -\end{bnftab} - -\begin{bnf} -\nontermdef{text-line}\br - pp-tokens\opt{} new-line -\end{bnf} - -\begin{bnf} -\nontermdef{non-directive}\br - pp-tokens new-line -\end{bnf} - -\begin{bnf} -\nontermdef{lparen}\br - \descr{a \terminal{(} character not immediately preceded by white-space} -\end{bnf} - -\begin{bnf} -\nontermdef{identifier-list}\br - identifier\br - identifier-list \terminal{,} identifier -\end{bnf} - -\begin{bnf} -\nontermdef{replacement-list}\br - pp-tokens\opt -\end{bnf} - -\begin{bnf} -\nontermdef{pp-tokens}\br - preprocessing-token\br - pp-tokens preprocessing-token -\end{bnf} - -\begin{bnf} -\nontermdef{new-line}\br - \descr{the new-line character} -\end{bnf} +\end{ncbnf} +\input{std-gram.ext} diff --git a/source/headers b/source/headers deleted file mode 100644 index e163259d6f..0000000000 --- a/source/headers +++ /dev/null @@ -1,54 +0,0 @@ -5 -algorithm -array -atomic -bitset -chrono -codecvt -complex -condition_variable -deque -exception -forward_list -fstream -functional -future -initializer_list -iomanip -ios -iosfwd -iostream -istream -iterator -limits -list -locale -map -memory -mutex -new -numeric -ostream -queue -random -ratio -regex -scoped_allocator -set -sstream -stack -stdexcept -streambuf -string -strstream -system_error -thread -tuple -type_traits -typeindex -typeinfo -unordered_map -unordered_set -utility -valarray -vector diff --git a/source/intro.tex b/source/intro.tex index c6142317f3..3e24d06dce 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -1,150 +1,239 @@ %!TEX root = std.tex -\rSec0[intro]{General} -\indextext{diagnostic message|see{message, diagnostic}}% -\indexdefn{conditionally-supported behavior!see{behavior, conditionally-supported}}% -\indextext{dynamic type|see{type, dynamic}}% -\indextext{static type|see{type, static}}% -\indextext{ill-formed program|see{program, ill-formed}}% -\indextext{well-formed program|see{program, well-formed}}% -\indextext{implementation-defined behavior|see{behavior, implemen\-tation-defined}}% -\indextext{undefined behavior|see{behavior, undefined}}% -\indextext{unspecified behavior|see{behavior, unspecified}}% -\indextext{implementation limits|see{limits, implementation}}% -\indextext{locale-specific behavior|see{behavior, locale-specific}}% -\indextext{multibyte character|see{character, multibyte}}% -\indextext{object|seealso{object model}}% -\indextext{subobject|seealso{object model}}% -\indextext{derived class!most|see{most derived class}}% -\indextext{derived object!most|see{most derived object}}% -\indextext{program execution!as-if rule|see{as-if~rule}}% -\indextext{observable behavior|see{behavior, observable}}% -\indextext{precedence of operator|see{operator, precedence of}}% -\indextext{order of evaluation in expression|see{expression, order of evaluation of}}% -\indextext{atomic operations|see{operation, atomic}}% -\indextext{multiple threads|see{threads, multiple}}% -\indextext{normative references|see{references, normative}} +\clearpage +\bigskip\noindent\textlarger{\textbf{Programming languages --- \Cpp{}}} +\bigskip\bigskip -\rSec1[intro.scope]{Scope} +\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 International Standard specifies requirements for implementations -of the \Cpp programming language. The first such requirement is that -they implement the language, and so this International Standard also -defines \Cpp. Other requirements and relaxations of the first -requirement appear at various places within this International Standard. - -\pnum -\Cpp is a general purpose programming language based on the C -programming language as described in ISO/IEC 9899:1999 -\doccite{Programming languages --- C} (hereinafter referred to as the -\indexdefn{C!standard}\term{C standard}). In addition to -the facilities provided by C, \Cpp provides additional data types, -classes, templates, exceptions, namespaces, operator -overloading, function name overloading, references, free store -management operators, and additional library facilities.% +This document specifies requirements for implementations +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. \indextext{scope|)} -\rSec1[intro.refs]{Normative references} +\rSec0[intro.refs]{Normative references}% +\indextext{normative references|see{references, normative}}% \pnum \indextext{references!normative|(}% -The following referenced documents are indispensable for the application +The following documents are referred to in the text +in such a way that some or all of their content +constitutes requirements of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies. - \begin{itemize} -\item Ecma International, \doccite{ECMAScript Language Specification}, +% ISO documents in numerical order. +\item ISO/IEC 2382, \doccite{Information technology --- Vocabulary} +\item ISO 8601-1:2019, \doccite{Date and time --- Representations for information interchange --- Part 1: Basic rules} +\item \IsoC{}, \doccite{Information technology --- Programming languages --- C} +\item \IsoPosix{}, \doccite{Information Technology --- Portable Operating System Interface (POSIX\textregistered)\begin{footnote} +POSIX\textregistered\ is a registered trademark of +the Institute of Electrical and Electronic Engineers, Inc. +This information is given for the convenience of users of this document and +does not constitute an endorsement by ISO or IEC of this product. +\end{footnote} +Base Specifications, Issue 7} +\item \IsoPosix{}/Cor 1:2013, \doccite{Information Technology --- Portable Operating System Interface +(POSIX\textregistered) Base Specifications, Issue 7 --- Technical Corrigendum 1} +\item \IsoPosix{}/Cor 2:2017, \doccite{Information Technology --- Portable Operating System Interface +(POSIX\textregistered) Base Specifications, Issue 7 --- Technical Corrigendum 2} +\item \IsoFloatUndated{}:2020, \doccite{Information technology --- Microprocessor Systems --- Floating-Point arithmetic} +\item ISO 80000-2:2019, \doccite{Quantities and units --- Part 2: Mathematics} +% Other international standards. +\item Ecma International, \doccite{ECMAScript +\begin{footnote} +ECMAScript\textregistered\ is a registered trademark of Ecma +International. +This information is given for the convenience of users of this document and +does not constitute an endorsement by ISO or IEC of this product. +\end{footnote} +Language Specification}, Standard Ecma-262, third edition, 1999. -\item ISO/IEC 2382 (all parts), \doccite{Information technology --- -Vocabulary} -\item ISO/IEC 9899:1999, \doccite{Programming languages --- C} -\item ISO/IEC 9899:1999/Cor.1:2001(E), \doccite{Programming languages --- C, -Technical Corrigendum 1} -\item ISO/IEC 9899:1999/Cor.2:2004(E), \doccite{Programming languages --- C, -Technical Corrigendum 2} -\item ISO/IEC 9899:1999/Cor.3:2007(E), \doccite{Programming languages --- C, -Technical Corrigendum 3} -\item ISO/IEC 9945:2003, \doccite{Information Technology --- Portable -Operating System Interface (POSIX)} -\item ISO/IEC 10646-1:1993, \doccite{Information technology --- -Universal Multiple-Octet Coded Character Set (UCS) --- Part 1: -Architecture and Basic Multilingual Plane} -\item ISO/IEC TR 19769:2004, \doccite{Information technology --- -Programming languages, their environments and system software interfaces ---- Extensions for the programming language C to support new character -data types} +\item +The Unicode Consortium. \doccite{The Unicode Standard}, Version 15.1. +Available from: \url{https://www.unicode.org/versions/Unicode15.1.0/} \end{itemize} - -\pnum -The library described in Clause 7 of ISO/IEC 9899:1999 and Clause 7 of -ISO/IEC 9899:1999/Cor.1:2001 and Clause 7 of ISO/IEC -9899:1999/Cor.2:2003 is hereinafter called the -\indexdefn{C!standard library}\term{C standard -library}.\footnote{With the qualifications noted in Clauses~\ref{\firstlibchapter} -through~\ref{\lastlibchapter} and in~\ref{diff.library}, the C standard -library is a subset of the \Cpp standard library.} - -\pnum -The library described in ISO/IEC TR 19769:2004 is hereinafter called the -\indexdefn{C!Unicode TR}\term{C Unicode TR}. - -\pnum -The operating system interface described in ISO/IEC 9945:2003 is -hereinafter called \defn{POSIX}. - -\pnum -The ECMAScript Language Specification described in Standard Ecma-262 is -hereinafter called \defn{ECMA-262}. \indextext{references!normative|)} -\rSec1[intro.defs]{Terms and definitions} +\rSec0[intro.defs]{Terms and definitions} \pnum \indextext{definitions|(}% -For the purposes of this document, the following definitions apply. +For the purposes of this document, +the terms and definitions +given in ISO/IEC 2382, ISO 80000-2:2019, +and the following apply. \pnum -\ref{definitions} -defines additional terms that are used only in Clauses~\ref{library} -through~\ref{\lastlibchapter} and Annex~\ref{depr}. +ISO and IEC maintain terminology databases +for use in standardization +at the following addresses: +\begin{itemize} +\item ISO Online browsing platform: available at \url{https://www.iso.org/obp} +\item IEC Electropedia: available at \url{https://www.electropedia.org/} +\end{itemize} -\pnum -Terms that are used only in a small portion of this International -Standard are defined where they are used and italicized where they are -defined. +\indexdefn{access}% +\definition{access}{defns.access} +\defncontext{execution-time action} +read or modify the value of an object + +\begin{defnote} +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.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}; +such invocations do not themselves constitute accesses, +although they may involve accesses of scalar subobjects. +\end{defnote} \indexdefn{argument}% \indexdefn{argument!function call expression} \definition{argument}{defns.argument} - 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}% \definition{argument}{defns.argument.macro} - sequence of preprocessing tokens in the +\defncontext{function-like macro} sequence of preprocessing tokens in the comma-separated list bounded by the parentheses \indexdefn{argument}% \indexdefn{argument!throw expression}% \definition{argument}{defns.argument.throw} - the operand of \tcode{throw} +\defncontext{throw expression} operand of \keyword{throw} \indexdefn{argument}% \indexdefn{argument!template instantiation}% \definition{argument}{defns.argument.templ} -